<p dir="ltr">Reviewed-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>></p>
<div class="gmail_quote">On May 12, 2015 7:55 AM, "Francisco Jerez" <<a href="mailto:currojerez@riseup.net">currojerez@riseup.net</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This problem can easily be reproduced with a number of<br>
ARB_shader_image_load_store piglit tests, which use a buffer object as<br>
PBO for a pixel transfer operation and later on bind the same buffer<br>
to the pipeline as shader image -- The problem is not exclusive to<br>
images though, and is likely to affect other kinds of buffer objects<br>
that can be bound to the 3D pipeline, including vertex, index,<br>
uniform, atomic counter buffers, etc.<br>
<br>
CC: 10.5 <<a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.org</a>><br>
---<br>
 src/mesa/drivers/dri/i965/intel_pixel_read.c | 24 +++++++++++++++++++++++-<br>
 src/mesa/drivers/dri/i965/intel_tex_image.c  |  9 ++++++++-<br>
 2 files changed, 31 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_read.c b/src/mesa/drivers/dri/i965/intel_pixel_read.c<br>
index d3ca38b..3038057 100644<br>
--- a/src/mesa/drivers/dri/i965/intel_pixel_read.c<br>
+++ b/src/mesa/drivers/dri/i965/intel_pixel_read.c<br>
@@ -226,8 +226,30 @@ intelReadPixels(struct gl_context * ctx,<br>
<br>
    if (_mesa_is_bufferobj(pack->BufferObj)) {<br>
       if (_mesa_meta_pbo_GetTexSubImage(ctx, 2, NULL, x, y, 0, width, height, 1,<br>
-                                        format, type, pixels, pack))<br>
+                                        format, type, pixels, pack)) {<br>
+         /* _mesa_meta_pbo_GetTexSubImage() implements PBO transfers by<br>
+          * binding the user-provided BO as a fake framebuffer and rendering<br>
+          * to it.  This breaks the invariant of the GL that nothing is able<br>
+          * to render to a BO, causing nondeterministic corruption issues<br>
+          * because the render cache is not coherent with a number of other<br>
+          * caches that the BO could potentially be bound to afterwards.<br>
+          *<br>
+          * This could be solved in the same way that we guarantee texture<br>
+          * coherency after a texture is attached to a framebuffer and<br>
+          * rendered to, but that would involve checking *all* BOs bound to<br>
+          * the pipeline for the case we need to emit a cache flush due to<br>
+          * previous rendering to any of them -- Including vertex, index,<br>
+          * uniform, atomic counter, shader image, transform feedback,<br>
+          * indirect draw buffers, etc.<br>
+          *<br>
+          * That would increase the per-draw call overhead even though it's<br>
+          * very unlikely that any of the BOs bound to the pipeline has been<br>
+          * rendered to via a PBO at any point, so it seems better to just<br>
+          * flush here unconditionally.<br>
+          */<br>
+         intel_batchbuffer_emit_mi_flush(brw);<br>
          return;<br>
+      }<br>
<br>
       perf_debug("%s: fallback to CPU mapping in PBO case\n", __func__);<br>
    }<br>
diff --git a/src/mesa/drivers/dri/i965/intel_tex_image.c b/src/mesa/drivers/dri/i965/intel_tex_image.c<br>
index 7952ee5..85d3d04 100644<br>
--- a/src/mesa/drivers/dri/i965/intel_tex_image.c<br>
+++ b/src/mesa/drivers/dri/i965/intel_tex_image.c<br>
@@ -486,8 +486,15 @@ intel_get_tex_image(struct gl_context *ctx,<br>
       if (_mesa_meta_pbo_GetTexSubImage(ctx, 3, texImage, 0, 0, 0,<br>
                                         texImage->Width, texImage->Height,<br>
                                         texImage->Depth, format, type,<br>
-                                        pixels, &ctx->Pack))<br>
+                                        pixels, &ctx->Pack)) {<br>
+         /* Flush to guarantee coherency between the render cache and other<br>
+          * caches the PBO could potentially be bound to after this point.<br>
+          * See the related comment in intelReadPixels() for a more detailed<br>
+          * explanation.<br>
+          */<br>
+         intel_batchbuffer_emit_mi_flush(brw);<br>
          return;<br>
+      }<br>
<br>
       perf_debug("%s: fallback to CPU mapping in PBO case\n", __func__);<br>
    }<br>
--<br>
2.3.5<br>
<br>
</blockquote></div>