[Mesa-dev] [v6 3/9] intel: replace single region with a vector of regions

Topi Pohjolainen topi.pohjolainen at intel.com
Tue May 28 02:17:46 PDT 2013


No functional change in preparation for supporting multiple planes
per image each having its own region.

v2 (Chad): Clarify how valid regions are detected. Originally I
           thought one could also support cases where one region
           is shared between multiple planes. This is not really
           needed as the dma-buf-importing already introduces
           duplicate regions with different offsets (where the
           regions represent the one and same buffer object).

           I also added utility for resolving the number of
           regions based on the image layout. This is not used
           yet but will be later in the series.

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/intel/intel_fbo.c       |  6 +--
 src/mesa/drivers/dri/intel/intel_regions.h   | 19 +++++++-
 src/mesa/drivers/dri/intel/intel_screen.c    | 69 ++++++++++++++--------------
 src/mesa/drivers/dri/intel/intel_tex_image.c |  2 +-
 4 files changed, 57 insertions(+), 39 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 7ccbaa8..dc45983 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -300,13 +300,13 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx,
    irb->mt = intel_miptree_create_for_region(intel,
                                              GL_TEXTURE_2D,
                                              image->format,
-                                             image->region);
+                                             image->regions[0]);
    if (!irb->mt)
       return;
 
    rb->InternalFormat = image->internal_format;
-   rb->Width = image->region->width;
-   rb->Height = image->region->height;
+   rb->Width = image->regions[0]->width;
+   rb->Height = image->regions[0]->height;
    rb->Format = image->format;
    rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
 					   image->internal_format);
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 1fb6b27..b20bdc2 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -129,8 +129,14 @@ struct intel_image_format {
    } planes[3];
 };
 
+/**
+ * An image may consist of multiple planes in which case there is always the
+ * corresponding details set: strides, offsets and the layout of the image
+ * (planar_format). In case the 'planar_format' in turn is NULL the image is
+ * implicitly in packed form having only one plane.
+ */
 struct __DRIimageRec {
-   struct intel_region *region;
+   struct intel_region *regions[3];
    GLenum internal_format;
    uint32_t dri_format;
    GLuint format;
@@ -154,6 +160,17 @@ struct __DRIimageRec {
    void *data;
 };
 
+static inline unsigned
+intel_image_get_region_count(const struct __DRIimageRec *image)
+{
+	/* Non-planar are always packed in one plane */
+	if (!image->planar_format)
+		return 1;
+
+	/* Otherwise there is a region per plane */
+	return image->planar_format->nplanes;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index cedfc2a..95e2d1a 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -315,14 +315,14 @@ intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *imag
                                                    draw_y & ~mask_y,
                                                    false);
 
-   intel_region_reference(&image->region, mt->region);
+   intel_region_reference(&image->regions[0], mt->region);
 }
 
 static void
 intel_setup_image_from_dimensions(__DRIimage *image)
 {
-   image->width    = image->region->width;
-   image->height   = image->region->height;
+   image->width    = image->regions[0]->width;
+   image->height   = image->regions[0]->height;
    image->tile_x = 0;
    image->tile_y = 0;
    image->has_depthstencil = false;
@@ -366,10 +366,10 @@ intel_create_image_from_name(__DRIscreen *screen,
        cpp = 1;
     else
        cpp = _mesa_get_format_bytes(image->format);
-    image->region = intel_region_alloc_for_handle(intelScreen,
+    image->regions[0] = intel_region_alloc_for_handle(intelScreen,
 						  cpp, width, height,
 						  pitch * cpp, name, "image");
-    if (image->region == NULL) {
+    if (image->regions[0] == NULL) {
        free(image);
        return NULL;
     }
@@ -404,7 +404,7 @@ intel_create_image_from_renderbuffer(__DRIcontext *context,
    image->format = rb->Format;
    image->offset = 0;
    image->data = loaderPrivate;
-   intel_region_reference(&image->region, irb->mt->region);
+   intel_region_reference(&image->regions[0], irb->mt->region);
    intel_setup_image_from_dimensions(image);
    image->dri_format = intel_dri_format(image->format);
    image->has_depthstencil = irb->mt->stencil_mt? true : false;
@@ -476,7 +476,7 @@ intel_create_image_from_texture(__DRIcontext *context, int target,
 static void
 intel_destroy_image(__DRIimage *image)
 {
-    intel_region_release(&image->region);
+    intel_region_release(&image->regions[0]);
     free(image);
 }
 
@@ -503,9 +503,10 @@ intel_create_image(__DRIscreen *screen,
       return NULL;
 
    cpp = _mesa_get_format_bytes(image->format);
-   image->region =
+
+   image->regions[0] =
       intel_region_alloc(intelScreen, tiling, cpp, width, height, true);
-   if (image->region == NULL) {
+   if (image->regions[0] == NULL) {
       free(image);
       return NULL;
    }
@@ -520,21 +521,21 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
 {
    switch (attrib) {
    case __DRI_IMAGE_ATTRIB_STRIDE:
-      *value = image->region->pitch;
+      *value = image->regions[0]->pitch;
       return true;
    case __DRI_IMAGE_ATTRIB_HANDLE:
-      *value = image->region->bo->handle;
+      *value = image->regions[0]->bo->handle;
       return true;
    case __DRI_IMAGE_ATTRIB_NAME:
-      return intel_region_flink(image->region, (uint32_t *) value);
+      return intel_region_flink(image->regions[0], (uint32_t *) value);
    case __DRI_IMAGE_ATTRIB_FORMAT:
       *value = image->dri_format;
       return true;
    case __DRI_IMAGE_ATTRIB_WIDTH:
-      *value = image->region->width;
+      *value = image->regions[0]->width;
       return true;
    case __DRI_IMAGE_ATTRIB_HEIGHT:
-      *value = image->region->height;
+      *value = image->regions[0]->height;
       return true;
    case __DRI_IMAGE_ATTRIB_COMPONENTS:
       if (image->planar_format == NULL)
@@ -542,7 +543,7 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
       *value = image->planar_format->components;
       return true;
    case __DRI_IMAGE_ATTRIB_FD:
-      if (drm_intel_bo_gem_export_to_prime(image->region->bo, value) == 0)
+      if (drm_intel_bo_gem_export_to_prime(image->regions[0]->bo, value) == 0)
          return true;
       return false;
   default:
@@ -559,8 +560,8 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
    if (image == NULL)
       return NULL;
 
-   intel_region_reference(&image->region, orig_image->region);
-   if (image->region == NULL) {
+   intel_region_reference(&image->regions[0], orig_image->regions[0]);
+   if (image->regions[0] == NULL) {
       free(image);
       return NULL;
    }
@@ -587,7 +588,7 @@ static GLboolean
 intel_validate_usage(__DRIimage *image, unsigned int use)
 {
    if (use & __DRI_IMAGE_USE_CURSOR) {
-      if (image->region->width != 64 || image->region->height != 64)
+      if (image->regions[0]->width != 64 || image->regions[0]->height != 64)
 	 return GL_FALSE;
    }
 
@@ -666,10 +667,10 @@ intel_create_image_from_fds(__DRIscreen *screen,
    if (image == NULL)
       return NULL;
 
-   image->region = intel_region_alloc_for_fd(intelScreen,
+   image->regions[0] = intel_region_alloc_for_fd(intelScreen,
                                              1, width, height,
                                              strides[0], fds[0], "image");
-   if (image->region == NULL) {
+   if (image->regions[0] == NULL) {
       free(image);
       return NULL;
    }
@@ -701,8 +702,8 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
     if (plane >= f->nplanes)
         return NULL;
 
-    width = parent->region->width >> f->planes[plane].width_shift;
-    height = parent->region->height >> f->planes[plane].height_shift;
+    width = parent->regions[0]->width >> f->planes[plane].width_shift;
+    height = parent->regions[0]->height >> f->planes[plane].height_shift;
     dri_format = f->planes[plane].dri_format;
     index = f->planes[plane].buffer_index;
     offset = parent->offsets[index];
@@ -712,30 +713,30 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
     if (image == NULL)
        return NULL;
 
-    if (offset + height * stride > parent->region->bo->size) {
+    if (offset + height * stride > parent->regions[0]->bo->size) {
        _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
        free(image);
        return NULL;
     }
 
-    image->region = calloc(sizeof(*image->region), 1);
-    if (image->region == NULL) {
+    image->regions[0] = calloc(sizeof(*image->regions[0]), 1);
+    if (image->regions[0] == NULL) {
        free(image);
        return NULL;
     }
 
-    image->region->cpp = _mesa_get_format_bytes(image->format);
-    image->region->width = width;
-    image->region->height = height;
-    image->region->pitch = stride;
-    image->region->refcount = 1;
-    image->region->bo = parent->region->bo;
-    drm_intel_bo_reference(image->region->bo);
-    image->region->tiling = parent->region->tiling;
+    image->regions[0]->cpp = _mesa_get_format_bytes(image->format);
+    image->regions[0]->width = width;
+    image->regions[0]->height = height;
+    image->regions[0]->pitch = stride;
+    image->regions[0]->refcount = 1;
+    image->regions[0]->bo = parent->regions[0]->bo;
+    drm_intel_bo_reference(image->regions[0]->bo);
+    image->regions[0]->tiling = parent->regions[0]->tiling;
     image->offset = offset;
     intel_setup_image_from_dimensions(image);
 
-    intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false);
+    intel_region_get_tile_masks(image->regions[0], &mask_x, &mask_y, false);
     if (offset & mask_x)
        _mesa_warning(NULL,
                      "intel_create_sub_image: offset not on tile boundary");
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index 4e307f8..a59d6b0 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -381,7 +381,7 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
       return;
    }
 
-   intel_set_texture_image_region(ctx, texImage, image->region,
+   intel_set_texture_image_region(ctx, texImage, image->regions[0],
 				  target, image->internal_format,
                                   image->format, image->offset,
                                   image->width,  image->height,
-- 
1.8.1.2



More information about the mesa-dev mailing list