summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-05-21 14:21:44 -0700
committerPaul Berry <[email protected]>2013-06-12 11:10:07 -0700
commitef9142d4a37c28bf6ae3527f71b9aa1b57ba9eb0 (patch)
tree93014879985a9afbbd5bdcbd63cac2bf8349186d
parent67cd0f97030a358777c01ee6ad79926717dfdf42 (diff)
i965/gen7+: Disable fast color clears on shared regions.
In certain circumstances the memory region underlying a miptree is shared with other miptrees, or with other code outside Mesa's control. This happens, for instance, when an extension like GL_OES_EGL_image or GLX_EXT_texture_from_pixmap extension is used to associate a miptree with an image existing outside of Mesa. When this happens, we need to disable fast color clears on the miptree in question, since there's no good synchronization mechanism to ensure that deferred clear writes get performed by the time the buffer is examined from the other miptree, or from outside of Mesa. Fortunately, this should not be a performance hit for most applications, since most applications that use these extensions use them for importing textures into Mesa, rather than for exporting rendered images out of Mesa. So most of the time the miptrees involved will never experience a clear. v2: Rework based on the fact that we have decided not to use an accessor function to protect access to the region. Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c34
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h4
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c1
4 files changed, 42 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 4c98e905f29..5b767df070f 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -1475,6 +1475,40 @@ intel_miptree_resolve_color(struct intel_context *intel,
/**
+ * Make it possible to share the region backing the given miptree with another
+ * process or another miptree.
+ *
+ * Fast color clears are unsafe with shared buffers, so we need to resolve and
+ * then discard the MCS buffer, if present. We also set the mcs_state to
+ * INTEL_MCS_STATE_NONE to ensure that no MCS buffer gets allocated in the
+ * future.
+ */
+void
+intel_miptree_make_shareable(struct intel_context *intel,
+ struct intel_mipmap_tree *mt)
+{
+#ifdef I915
+ /* Nothing needs to be done for I915 */
+ (void) intel;
+ (void) mt;
+#else
+ /* MCS buffers are also used for multisample buffers, but we can't resolve
+ * away a multisample MCS buffer because it's an integral part of how the
+ * pixel data is stored. Fortunately this code path should never be
+ * reached for multisample buffers.
+ */
+ assert(mt->msaa_layout == INTEL_MSAA_LAYOUT_NONE);
+
+ if (mt->mcs_mt) {
+ intel_miptree_resolve_color(intel, mt);
+ intel_miptree_release(&mt->mcs_mt);
+ mt->mcs_state = INTEL_MCS_STATE_NONE;
+ }
+#endif
+}
+
+
+/**
* \brief Get pointer offset into stencil buffer.
*
* The stencil buffer is W tiled. Since the GTT is incapable of W fencing, we
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 8ea1befdd1c..6dab092c8f3 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -723,6 +723,10 @@ intel_miptree_resolve_color(struct intel_context *intel,
struct intel_mipmap_tree *mt);
void
+intel_miptree_make_shareable(struct intel_context *intel,
+ struct intel_mipmap_tree *mt);
+
+void
intel_miptree_downsample(struct intel_context *intel,
struct intel_mipmap_tree *mt);
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index b4758f93817..60a69a60648 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -300,6 +300,8 @@ intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *imag
unsigned int draw_x, draw_y;
uint32_t mask_x, mask_y;
+ intel_miptree_make_shareable(intel, mt);
+
intel_miptree_check_level_layer(mt, level, zoffset);
intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);
@@ -396,6 +398,7 @@ intel_create_image_from_renderbuffer(__DRIcontext *context,
}
irb = intel_renderbuffer(rb);
+ intel_miptree_make_shareable(intel, irb->mt);
image = calloc(1, sizeof *image);
if (image == NULL)
return NULL;
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index fba02c2b7d1..b91b2b5dccb 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -342,6 +342,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
_mesa_lock_texture(&intel->ctx, texObj);
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ intel_miptree_make_shareable(intel, rb->mt);
intel_set_texture_image_region(ctx, texImage, rb->mt->region, target,
internalFormat, texFormat, 0,
rb->mt->region->width,