iris: Flush for history at various moments
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 21 Nov 2018 09:03:48 +0000 (01:03 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:10 +0000 (10:26 -0800)
When we blit, transfer, or copy_resource to a buffer, we need to flush
to ensure any stale data for that buffer is invalidated in the caches.

bind_history will inform us which caches need to be flushed.

Also, for any push constant buffers, we need to flag those dirty so
that we re-emit 3DSTATE_CONSTANT_*, causing the data to be re-pushed.

src/gallium/drivers/iris/iris_blit.c
src/gallium/drivers/iris/iris_resource.c
src/gallium/drivers/iris/iris_resource.h

index 6e6f445607236e659942d02131b69281fd6b8050..c50e7958d246658c9cee7eaf9e6baad7b880dd09 100644 (file)
@@ -378,6 +378,9 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
    }
 
    blorp_batch_finish(&blorp_batch);
+
+   iris_flush_and_dirty_for_history(ice, batch, (struct iris_resource *)
+                                    info->dst.resource);
 }
 
 /**
@@ -432,6 +435,8 @@ iris_resource_copy_region(struct pipe_context *ctx,
    }
 
    blorp_batch_finish(&blorp_batch);
+
+   iris_flush_and_dirty_for_history(ice, batch, (struct iris_resource *) dst);
 }
 
 void
index 67586b22751099cef4db5e0ec79d3eff7b05a022..677bb0be1d169552666a79d40cd90e8ad392494e 100644 (file)
@@ -858,24 +858,41 @@ iris_transfer_map(struct pipe_context *ctx,
    return map->ptr;
 }
 
+static void
+iris_transfer_flush_region(struct pipe_context *ctx,
+                           struct pipe_transfer *xfer,
+                           const struct pipe_box *box)
+{
+   struct iris_context *ice = (struct iris_context *)ctx;
+   struct iris_resource *res = (struct iris_resource *) xfer->resource;
+
+
+   // XXX: don't emit flushes in both engines...? we may also need to flush
+   // even if there isn't a draw yet - may still be stale data in caches...
+   for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
+      if (ice->batches[i].contains_draw) {
+         iris_batch_maybe_flush(&ice->batches[i], 24);
+         iris_flush_and_dirty_for_history(ice, &ice->batches[i], res);
+      }
+   }
+}
+
 static void
 iris_transfer_unmap(struct pipe_context *ctx, struct pipe_transfer *xfer)
 {
    struct iris_context *ice = (struct iris_context *)ctx;
    struct iris_transfer *map = (void *) xfer;
    struct iris_resource *res = (struct iris_resource *) xfer->resource;
-   struct isl_surf *surf = &res->surf;
 
    if (map->unmap)
       map->unmap(map);
 
-   /* XXX: big ol' hack!  need to re-emit UBOs.  want bind_history? */
-   if (surf->tiling == ISL_TILING_LINEAR) {
-      ice->state.dirty |= IRIS_DIRTY_CONSTANTS_VS  | IRIS_DIRTY_BINDINGS_VS
-                       |  IRIS_DIRTY_CONSTANTS_TCS | IRIS_DIRTY_BINDINGS_TCS
-                       |  IRIS_DIRTY_CONSTANTS_TES | IRIS_DIRTY_BINDINGS_TES
-                       |  IRIS_DIRTY_CONSTANTS_GS  | IRIS_DIRTY_BINDINGS_GS
-                       |  IRIS_DIRTY_CONSTANTS_FS  | IRIS_DIRTY_BINDINGS_FS;
+   // XXX: don't emit flushes in both engines...?
+   for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
+      if (ice->batches[i].contains_draw) {
+         iris_batch_maybe_flush(&ice->batches[i], 24);
+         iris_flush_and_dirty_for_history(ice, &ice->batches[i], res);
+      }
    }
 
    pipe_resource_reference(&xfer->resource, NULL);
@@ -889,6 +906,7 @@ iris_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
 
 void
 iris_flush_and_dirty_for_history(struct iris_context *ice,
+                                 struct iris_batch *batch,
                                  struct iris_resource *res)
 {
    if (res->base.target != PIPE_BUFFER)
@@ -918,11 +936,7 @@ iris_flush_and_dirty_for_history(struct iris_context *ice,
    if (res->bind_history & (PIPE_BIND_SHADER_BUFFER | PIPE_BIND_SHADER_IMAGE))
       flush |= PIPE_CONTROL_DATA_CACHE_FLUSH;
 
-   // XXX: don't emit flushes in both engines...?
-   for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
-      if (ice->batches[i].contains_draw)
-         iris_emit_pipe_control_flush(&ice->batches[i], flush);
-   }
+   iris_emit_pipe_control_flush(batch, flush);
 
    ice->state.dirty |= dirty;
 }
@@ -939,7 +953,7 @@ static const struct u_transfer_vtbl transfer_vtbl = {
    .resource_destroy      = iris_resource_destroy,
    .transfer_map          = iris_transfer_map,
    .transfer_unmap        = iris_transfer_unmap,
-   .transfer_flush_region = u_default_transfer_flush_region,
+   .transfer_flush_region = iris_transfer_flush_region,
    .get_internal_format   = iris_resource_get_internal_format,
    .set_stencil           = iris_resource_set_separate_stencil,
    .get_stencil           = iris_resource_get_separate_stencil,
index cff0efe49ad069ae08a8723d08bf5483e4be3372..8a3c44fdf78dfcf0baa0ee81c852fb508014c4a5 100644 (file)
@@ -136,6 +136,7 @@ void iris_get_depth_stencil_resources(struct pipe_resource *res,
 void iris_init_screen_resource_functions(struct pipe_screen *pscreen);
 
 void iris_flush_and_dirty_for_history(struct iris_context *ice,
+                                      struct iris_batch *batch,
                                       struct iris_resource *res);
 
 #endif