iris: Add texture cache flushing hacks for blit and resource_copy_region
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 5 Apr 2019 23:47:39 +0000 (16:47 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 16 Apr 2019 20:04:22 +0000 (13:04 -0700)
This is a port of Jason's 8379bff6c4456f8a77041eee225dcd44e5e00a76
from i965 to iris.  We can't find anything relevant in the documentation
and no one we've talked to has been able to help us pin down a solution.

Unfortunately, we have to put the hack in both iris_blit() and
iris_copy_region().  st/mesa's CopyImage() implementation sometimes
chooses to use pipe->blit() instead of pipe->resource_copy_region().
For blits, we only do the hack if the blit source format doesn't match
the underlying resource (i.e. it's reinterpreting the bits).  Hopefully
this should not be too common.

src/gallium/drivers/iris/iris_blit.c

index a5df1cc9d98122ff499e36aecd2bbd4e02fdbebf..8f5a9c984dae97aa041c8075cb100a470f584943 100644 (file)
@@ -274,6 +274,26 @@ iris_blorp_surf_for_resource(struct iris_vtable *vtbl,
    // XXX: ASTC
 }
 
+static void
+tex_cache_flush_hack(struct iris_batch *batch)
+{
+   /* The hardware seems to have issues with having a two different
+    * format views of the same texture in the sampler cache at the
+    * same time.  It's unclear exactly what the issue is but it hurts
+    * blits and copies particularly badly because they often reinterpret
+    * formats.  We badly need better understanding of the sampler issue
+    * and a better fix but this works for now and fixes CTS tests.
+    *
+    * If the BO hasn't been referenced yet this batch, we assume that the
+    * texture cache doesn't contain any relevant data nor need flushing.
+    *
+    * TODO: Remove this hack!
+    */
+   iris_emit_pipe_control_flush(batch,
+                                PIPE_CONTROL_CS_STALL |
+                                PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
+}
+
 /**
  * The pipe->blit() driver hook.
  *
@@ -403,6 +423,12 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
       filter = BLORP_FILTER_NEAREST;
    }
 
+   bool flush_hack = src_fmt.fmt != src_res->surf.format &&
+                     iris_batch_references(batch, src_res->bo);
+
+   if (flush_hack)
+      tex_cache_flush_hack(batch);
+
    struct blorp_batch blorp_batch;
    blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
 
@@ -454,6 +480,9 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
 
    blorp_batch_finish(&blorp_batch);
 
+   if (flush_hack)
+      tex_cache_flush_hack(batch);
+
    iris_resource_finish_write(ice, dst_res, info->dst.level, info->dst.box.z,
                               info->dst.box.depth, dst_aux_usage);
 
@@ -517,6 +546,10 @@ iris_copy_region(struct blorp_context *blorp,
    get_copy_region_aux_settings(devinfo, dst_res, &dst_aux_usage,
                                 &dst_clear_supported);
 
+   bool flush_hack = iris_batch_references(batch, src_res->bo);
+   if (flush_hack)
+      tex_cache_flush_hack(batch);
+
    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
       struct blorp_address src_addr = {
          .buffer = iris_resource_bo(src), .offset = src_box->x,
@@ -565,6 +598,9 @@ iris_copy_region(struct blorp_context *blorp,
       iris_resource_finish_write(ice, dst_res, dst_level, dstz,
                                  src_box->depth, dst_aux_usage);
    }
+
+   if (flush_hack)
+      tex_cache_flush_hack(batch);
 }