[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