From 8c3392e274f59446f89682b33a2b4af60243ea0b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 May 2013 10:54:36 -0700 Subject: [PATCH] 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 Acked-by: Paul Berry --- src/mesa/drivers/dri/intel/intel_fbo.c | 12 ++-- .../drivers/dri/intel/intel_mipmap_tree.c | 65 ++++++++++++++----- .../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 f75b6350c2a..82dd0a4148b 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 30ac470fb13..5f1e171d0cc 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 2055d1da4f1..cac518cc749 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, -- 2.30.2