[Mesa-dev] [PATCH 12/17] intel: Rework intel_miptree_create_for_region() to wrap a BO.

Eric Anholt eric at anholt.net
Fri May 24 13:56:50 PDT 2013


I needed to do this for the PBO blit cases to use intel_miptree_blit().
But this also actually partially fixes a bug in EGLImage handling: We
can't share regions across contexts, because regions have a refcount that
isn't protected by a mutex, and different contexts can be simulataneously
accessed from multiple threads.  Now we just need to get regions out of
__DRIImage.  There was also a missing use of image->offset in the EGLImage
renderbuffer storage code.
---
 src/mesa/drivers/dri/intel/intel_fbo.c         | 12 +++--
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 65 ++++++++++++++++++++------
 src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 14 ++++--
 3 files changed, 67 insertions(+), 24 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 73ed91d..cbbd31c 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -293,10 +293,14 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx,
 
    irb = intel_renderbuffer(rb);
    intel_miptree_release(&irb->mt);
-   irb->mt = intel_miptree_create_for_region(intel,
-                                             GL_TEXTURE_2D,
-                                             image->format,
-                                             image->region);
+   irb->mt = intel_miptree_create_for_bo(intel,
+                                         image->region->bo,
+                                         image->format,
+                                         image->offset,
+                                         image->region->width,
+                                         image->region->height,
+                                         image->region->pitch,
+                                         image->region->tiling);
    if (!irb->mt)
       return;
 
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index dd0b9ce..443791c 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -124,8 +124,8 @@ compute_msaa_layout(struct intel_context *intel, gl_format format, GLenum target
 
 
 /**
- * @param for_region Indicates that the caller is
- *        intel_miptree_create_for_region(). If true, then do not create
+ * @param for_bo Indicates that the caller is
+ *        intel_miptree_create_for_bo(). If true, then do not create
  *        \c stencil_mt.
  */
 struct intel_mipmap_tree *
@@ -137,7 +137,7 @@ intel_miptree_create_layout(struct intel_context *intel,
                             GLuint width0,
                             GLuint height0,
                             GLuint depth0,
-                            bool for_region,
+                            bool for_bo,
                             GLuint num_samples)
 {
    struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
@@ -250,7 +250,7 @@ intel_miptree_create_layout(struct intel_context *intel,
    mt->physical_height0 = height0;
    mt->physical_depth0 = depth0;
 
-   if (!for_region &&
+   if (!for_bo &&
        _mesa_get_format_base_format(format) == GL_DEPTH_STENCIL &&
        (intel->must_use_separate_stencil ||
 	(intel->has_separate_stencil &&
@@ -485,21 +485,50 @@ intel_miptree_create(struct intel_context *intel,
 }
 
 struct intel_mipmap_tree *
-intel_miptree_create_for_region(struct intel_context *intel,
-				GLenum target,
-				gl_format format,
-				struct intel_region *region)
+intel_miptree_create_for_bo(struct intel_context *intel,
+                            drm_intel_bo *bo,
+                            gl_format format,
+                            uint32_t offset,
+                            uint32_t width,
+                            uint32_t height,
+                            int pitch,
+                            uint32_t tiling)
 {
    struct intel_mipmap_tree *mt;
 
-   mt = intel_miptree_create_layout(intel, target, format,
-				      0, 0,
-				      region->width, region->height, 1,
-				      true, 0 /* num_samples */);
+   struct intel_region *region = calloc(1, sizeof(*region));
+   if (!region)
+      return NULL;
+
+   /* Nothing will be able to use this miptree with the BO if the offset isn't
+    * aligned.
+    */
+   if (tiling != I915_TILING_NONE)
+      assert(offset % 4096 == 0);
+
+   /* miptrees can't handle negative pitch.  If you need flipping of images,
+    * that's outside of the scope of the mt.
+    */
+   assert(pitch >= 0);
+
+   mt = intel_miptree_create_layout(intel, GL_TEXTURE_2D, format,
+                                    0, 0,
+                                    width, height, 1,
+                                    true, 0 /* num_samples */);
    if (!mt)
       return mt;
 
-   intel_region_reference(&mt->region, region);
+   region->cpp = mt->cpp;
+   region->width = width;
+   region->height = height;
+   region->pitch = pitch;
+   region->refcount = 1;
+   drm_intel_bo_reference(bo);
+   region->bo = bo;
+   region->tiling = tiling;
+
+   mt->region = region;
+   mt->offset = offset;
 
    return mt;
 }
@@ -531,8 +560,14 @@ intel_miptree_create_for_dri2_buffer(struct intel_context *intel,
    assert(_mesa_get_format_base_format(format) == GL_RGB ||
           _mesa_get_format_base_format(format) == GL_RGBA);
 
-   singlesample_mt = intel_miptree_create_for_region(intel, GL_TEXTURE_2D,
-                                                     format, region);
+   singlesample_mt = intel_miptree_create_for_bo(intel,
+                                                 region->bo,
+                                                 format,
+                                                 0,
+                                                 region->width,
+                                                 region->height,
+                                                 region->pitch,
+                                                 region->tiling);
    if (!singlesample_mt)
       return NULL;
 
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 71675f4..efd8b71 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -410,14 +410,18 @@ intel_miptree_create_layout(struct intel_context *intel,
                             GLuint width0,
                             GLuint height0,
                             GLuint depth0,
-                            bool for_region,
+                            bool for_bo,
                             GLuint num_samples);
 
 struct intel_mipmap_tree *
-intel_miptree_create_for_region(struct intel_context *intel,
-				GLenum target,
-				gl_format format,
-				struct intel_region *region);
+intel_miptree_create_for_bo(struct intel_context *intel,
+                            drm_intel_bo *bo,
+                            gl_format format,
+                            uint32_t offset,
+                            uint32_t width,
+                            uint32_t height,
+                            int pitch,
+                            uint32_t tiling);
 
 struct intel_mipmap_tree*
 intel_miptree_create_for_dri2_buffer(struct intel_context *intel,
-- 
1.8.3.rc0



More information about the mesa-dev mailing list