i965/gen7+: Disable fast color clears on shared regions.
authorPaul Berry <stereotype441@gmail.com>
Tue, 21 May 2013 21:21:44 +0000 (14:21 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 12 Jun 2013 18:10:07 +0000 (11:10 -0700)
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 <eric@anholt.net>
src/mesa/drivers/dri/intel/intel_mipmap_tree.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.h
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/intel/intel_tex_image.c

index 4c98e905f29e7a79e653039d10cdcb671f308871..5b767df070fcb166281e7196df136cff69d7a7c8 100644 (file)
@@ -1474,6 +1474,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.
  *
index 8ea1befdd1c075d86d0139557a9ffa871e742709..6dab092c8f3e6bcd6c199f194fb2e51332e65ddd 100644 (file)
@@ -722,6 +722,10 @@ void
 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);
index b4758f9381724d467f1fff6559373bbd97c7d290..60a69a60648c38ad36f926b89420c424c1586d2d 100644 (file)
@@ -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;
index fba02c2b7d14f2b2793ef50005ab945ff1d243ff..b91b2b5dccbd3084f3e10afb67429bf4ec584907 100644 (file)
@@ -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,