[Mesa-dev] [PATCH 1/4] i965: Support allocation of subregions of an intel_region

Ander Conselvan de Oliveira conselvan2 at gmail.com
Tue Feb 18 08:41:50 PST 2014


From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>

Both __DRIimage and intel_region have width and height fields. They
actually differ when an image is created for a texture but are the
same in all the other cases. For images created from a planar image,
a special intel_region that represents only a part of the storage used
by the image is used. It references the same bo but contains offset
information plus different dimensions and pitch.

This patch adds an entry point for creating an intel_region that
represents a sub region of another intel_region. This entry point is
then used when creating images from textures or from planar images.
This lets us remove the duplicate width and height fields from
__DRIimage and move the offset, tile_x and tile_y field into
intel_region.
---
 src/mesa/drivers/dri/i965/brw_context.c     |  8 ++--
 src/mesa/drivers/dri/i965/intel_fbo.c       |  2 +-
 src/mesa/drivers/dri/i965/intel_regions.c   | 28 ++++++++++++++
 src/mesa/drivers/dri/i965/intel_regions.h   | 16 +++++---
 src/mesa/drivers/dri/i965/intel_screen.c    | 60 ++++++++++++-----------------
 src/mesa/drivers/dri/i965/intel_tex_image.c |  7 ++--
 6 files changed, 72 insertions(+), 49 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 021287e..ae267d8 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -1402,8 +1402,8 @@ intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable)
                                         &images);
 
    if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
-      drawable->w = images.front->width;
-      drawable->h = images.front->height;
+      drawable->w = images.front->region->width;
+      drawable->h = images.front->region->height;
       intel_update_image_buffer(brw,
                                 drawable,
                                 front_rb,
@@ -1411,8 +1411,8 @@ intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable)
                                 __DRI_IMAGE_BUFFER_FRONT);
    }
    if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
-      drawable->w = images.back->width;
-      drawable->h = images.back->height;
+      drawable->w = images.back->region->width;
+      drawable->h = images.back->region->height;
       intel_update_image_buffer(brw,
                                 drawable,
                                 back_rb,
diff --git a/src/mesa/drivers/dri/i965/intel_fbo.c b/src/mesa/drivers/dri/i965/intel_fbo.c
index cd148f0..4c101f8 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.c
+++ b/src/mesa/drivers/dri/i965/intel_fbo.c
@@ -283,7 +283,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx,
    irb->mt = intel_miptree_create_for_bo(brw,
                                          image->region->bo,
                                          image->format,
-                                         image->offset,
+                                         image->region->offset,
                                          image->region->width,
                                          image->region->height,
                                          image->region->pitch,
diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c
index a845683..2ab36fc 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.c
+++ b/src/mesa/drivers/dri/i965/intel_regions.c
@@ -238,6 +238,34 @@ intel_region_alloc_for_fd(struct intel_screen *screen,
    return region;
 }
 
+struct intel_region *
+intel_region_alloc_subregion(struct intel_region *parent_region,
+                             GLuint cpp,
+                             GLuint width, GLuint height, GLuint pitch,
+                             GLuint offset, GLuint tile_x, GLuint tile_y)
+{
+   struct intel_region *region;
+
+   region = calloc(1, sizeof *region);
+   if (region == NULL)
+      return NULL;
+
+   region->bo = parent_region->bo;
+   drm_intel_bo_reference(region->bo);
+
+   region->cpp = cpp;
+   region->width = width;
+   region->height = height;
+   region->pitch = pitch;
+   region->refcount = 1;
+   region->tiling = parent_region->tiling;
+   region->offset = offset;
+   region->tile_x = tile_x;
+   region->tile_y = tile_y;
+
+   return region;
+}
+
 void
 intel_region_reference(struct intel_region **dst, struct intel_region *src)
 {
diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h
index c301f23..2d3f4d1 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.h
+++ b/src/mesa/drivers/dri/i965/intel_regions.h
@@ -70,6 +70,11 @@ struct intel_region
    uint32_t tiling; /**< Which tiling mode the region is in */
 
    uint32_t name; /**< Global name for the bo */
+
+   /** Describe the offset of the region within the bo */
+   uint32_t offset;
+   GLuint tile_x;
+   GLuint tile_y;
 };
 
 
@@ -95,6 +100,12 @@ intel_region_alloc_for_fd(struct intel_screen *screen,
                           GLuint size,
                           int fd, const char *name);
 
+struct intel_region *
+intel_region_alloc_subregion(struct intel_region *parent,
+                             GLuint cpp,
+                             GLuint width, GLuint height, GLuint pitch,
+                             GLuint offset, GLuint tile_x, GLuint tile_y);
+
 bool
 intel_region_flink(struct intel_region *region, uint32_t *name);
 
@@ -134,7 +145,6 @@ struct __DRIimageRec {
    GLenum internal_format;
    uint32_t dri_format;
    GLuint format;
-   uint32_t offset;
 
    /*
     * Need to save these here between calls to
@@ -145,10 +155,6 @@ struct __DRIimageRec {
    struct intel_image_format *planar_format;
 
    /* particular miptree level */
-   GLuint width;
-   GLuint height;
-   GLuint tile_x;
-   GLuint tile_y;
    bool has_depthstencil;
 
    /**
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index acdb5f3..c94882f 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -300,7 +300,6 @@ intel_allocate_image(int dri_format, void *loaderPrivate)
 	return NULL;
 
     image->dri_format = dri_format;
-    image->offset = 0;
 
     image->format = driImageFormatToGLFormat(dri_format);
     if (dri_format != __DRI_IMAGE_FORMAT_NONE &&
@@ -325,6 +324,8 @@ intel_setup_image_from_mipmap_tree(struct brw_context *brw, __DRIimage *image,
 {
    unsigned int draw_x, draw_y;
    uint32_t mask_x, mask_y;
+   uint32_t tile_x, tile_y, offset;
+   uint32_t width, height;
 
    intel_miptree_make_shareable(brw, mt);
 
@@ -333,26 +334,26 @@ intel_setup_image_from_mipmap_tree(struct brw_context *brw, __DRIimage *image,
    intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);
    intel_miptree_get_image_offset(mt, level, zoffset, &draw_x, &draw_y);
 
-   image->width = mt->level[level].width;
-   image->height = mt->level[level].height;
-   image->tile_x = draw_x & mask_x;
-   image->tile_y = draw_y & mask_y;
-
-   image->offset = intel_region_get_aligned_offset(mt->region,
-                                                   draw_x & ~mask_x,
-                                                   draw_y & ~mask_y,
-                                                   false);
-
-   intel_region_reference(&image->region, mt->region);
+   width = mt->level[level].width;
+   height = mt->level[level].height;
+   tile_x = draw_x & mask_x;
+   tile_y = draw_y & mask_y;
+
+   offset = intel_region_get_aligned_offset(mt->region,
+                                            draw_x & ~mask_x,
+                                            draw_y & ~mask_y,
+                                            false);
+
+   image->region = intel_region_alloc_subregion(mt->region,
+                                                mt->region->cpp,
+                                                width, height,
+                                                mt->region->pitch,
+                                                offset, tile_x, tile_y);
 }
 
 static void
 intel_setup_image_from_dimensions(__DRIimage *image)
 {
-   image->width    = image->region->width;
-   image->height   = image->region->height;
-   image->tile_x = 0;
-   image->tile_y = 0;
    image->has_depthstencil = false;
 }
 
@@ -410,7 +411,6 @@ intel_create_image_from_renderbuffer(__DRIcontext *context,
 
    image->internal_format = rb->InternalFormat;
    image->format = rb->Format;
-   image->offset = 0;
    image->data = loaderPrivate;
    intel_region_reference(&image->region, irb->mt->region);
    intel_setup_image_from_dimensions(image);
@@ -580,11 +580,6 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
    image->planar_format   = orig_image->planar_format;
    image->dri_format      = orig_image->dri_format;
    image->format          = orig_image->format;
-   image->offset          = orig_image->offset;
-   image->width           = orig_image->width;
-   image->height          = orig_image->height;
-   image->tile_x          = orig_image->tile_x;
-   image->tile_y          = orig_image->tile_y;
    image->has_depthstencil = orig_image->has_depthstencil;
    image->data            = loaderPrivate;
 
@@ -735,7 +730,7 @@ intel_create_image_from_dma_bufs(__DRIscreen *screen,
 static __DRIimage *
 intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
 {
-    int width, height, offset, stride, dri_format, index;
+    int width, height, offset, stride, dri_format, index, cpp;
     struct intel_image_format *f;
     uint32_t mask_x, mask_y;
     __DRIimage *image;
@@ -765,21 +760,14 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
        return NULL;
     }
 
-    image->region = calloc(sizeof(*image->region), 1);
+    cpp = _mesa_get_format_bytes(image->format);
+    image->region = intel_region_alloc_subregion(parent->region, cpp,
+                                                 width, height, stride,
+                                                 offset, 0, 0);
     if (image->region == NULL) {
-       free(image);
-       return 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->offset = offset;
     intel_setup_image_from_dimensions(image);
 
     intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false);
diff --git a/src/mesa/drivers/dri/i965/intel_tex_image.c b/src/mesa/drivers/dri/i965/intel_tex_image.c
index ee02e68..26d7cca 100644
--- a/src/mesa/drivers/dri/i965/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i965/intel_tex_image.c
@@ -410,9 +410,10 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
 
    intel_set_texture_image_region(ctx, texImage, image->region,
 				  target, image->internal_format,
-                                  image->format, image->offset,
-                                  image->width,  image->height,
-                                  image->tile_x, image->tile_y);
+                                  image->format, image->region->offset,
+                                  image->region->width, image->region->height,
+                                  image->region->tile_x,
+                                  image->region->tile_y);
 }
 
 void
-- 
1.8.3.2



More information about the mesa-dev mailing list