i965: Always flush caches after blitting to a GL buffer object.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 29 Aug 2017 05:04:01 +0000 (22:04 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 30 Aug 2017 23:59:23 +0000 (16:59 -0700)
When we blit data into a buffer object, we may need to invalidate any
caches that might contain stale data, so the new data becomes visible.

For example, if the buffer object is bound as a vertex buffer, we need
to invalidate the vertex fetch cache.

While this flushing was missing, it usually happened implicitly for
non-obvious reasons: we're usually on the render ring, and calling
intel_emit_linear_blit() would require switching to the BLT ring,
causing an implicit flush.  This likely provoked the kernel to do
PIPE_CONTROLs on our behalf.  Although, Gen4-5 wouldn't have this
behavior.  At any rate, we should do it ourselves.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/mesa/drivers/dri/i965/intel_buffer_objects.c

index dd6fca1..01443c2 100644 (file)
@@ -298,6 +298,7 @@ brw_buffer_subdata(struct gl_context *ctx,
                                 intel_obj->buffer, offset,
                                 temp_bo, 0,
                                 size);
+         brw_emit_mi_flush(brw);
 
          brw_bo_unreference(temp_bo);
          mark_buffer_valid_data(intel_obj, offset, size);
@@ -541,6 +542,7 @@ brw_flush_mapped_buffer_range(struct gl_context *ctx,
    mark_buffer_gpu_usage(intel_obj,
                          obj->Mappings[index].Offset + offset,
                          length);
+   brw_emit_mi_flush(brw);
 }
 
 
@@ -570,6 +572,7 @@ brw_unmap_buffer(struct gl_context *ctx,
                                 obj->Mappings[index].Length);
          mark_buffer_gpu_usage(intel_obj, obj->Mappings[index].Offset,
                                obj->Mappings[index].Length);
+         brw_emit_mi_flush(brw);
       }
 
       /* Since we've emitted some blits to buffers that will (likely) be used
@@ -577,7 +580,6 @@ brw_unmap_buffer(struct gl_context *ctx,
        * flush.  Once again, we wish for a domain tracker in libdrm to cover
        * usage inside of a batchbuffer.
        */
-      brw_emit_mi_flush(brw);
 
       brw_bo_unreference(intel_obj->range_map_bo[index]);
       intel_obj->range_map_bo[index] = NULL;