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

Ander Conselvan de Oliveira conselvan2 at gmail.com
Wed Nov 13 07:27:00 PST 2013


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 filed into
intel_region.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>
---
 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    |   54 +++++++++++----------------
 src/mesa/drivers/dri/i965/intel_tex_image.c |    7 ++--
 6 files changed, 70 insertions(+), 45 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index bee98e3..ffbfb43 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -1387,8 +1387,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,
@@ -1396,8 +1396,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 ddecb2b..ae978f1 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.c
+++ b/src/mesa/drivers/dri/i965/intel_fbo.c
@@ -291,7 +291,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 3920f4f..8ad6129 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 05dfef3..58a6dd1 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 6bcfe2c..6765e9a 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -297,7 +297,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 &&
@@ -322,6 +321,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);
 
@@ -330,26 +331,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;
 }
 
@@ -407,7 +408,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);
@@ -577,11 +577,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;
 
@@ -732,7 +727,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;
@@ -768,15 +763,10 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
        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;
+    cpp = _mesa_get_format_bytes(image->format);
+    image->region = intel_region_alloc_subregion(parent->region, cpp,
+                                                 width, height, stride,
+                                                 offset, 0, 0);
     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 cc50f84..9e87003 100644
--- a/src/mesa/drivers/dri/i965/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i965/intel_tex_image.c
@@ -375,9 +375,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.7.9.5



More information about the mesa-dev mailing list