Mesa (master): intel: Rework intel_miptree_create_for_region() to wrap a BO .

Eric Anholt anholt at kemper.freedesktop.org
Tue May 28 20:09:47 UTC 2013


Module: Mesa
Branch: master
Commit: 8c3392e274f59446f89682b33a2b4af60243ea0b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8c3392e274f59446f89682b33a2b4af60243ea0b

Author: Eric Anholt <eric at anholt.net>
Date:   Fri May 24 10:54:36 2013 -0700

intel: Rework intel_miptree_create_for_region() to wrap a BO.

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.

Reviewed-and-tested-by: Ian Romanick <ian.d.romanick at intel.com>
Acked-by: Paul Berry <stereotype441 at gmail.com>

---

 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 f75b635..82dd0a4 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 30ac470..5f1e171 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 &&
@@ -490,21 +490,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;
 }
@@ -536,8 +565,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 2055d1d..cac518c 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -414,14 +414,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,




More information about the mesa-commit mailing list