iris: Update fast clear colors on Gen9 with direct immediate writes.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 19 Aug 2019 20:57:46 +0000 (13:57 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 23 Aug 2019 01:31:14 +0000 (18:31 -0700)
Gen11 stores the fast clear color in an "indirect clear buffer", as
a packed pixel value.  Gen9 hardware stores it as a float or integer
value, which is interpreted via the format.  We were trying to store
that in a buffer, for similarity with Icelake, and MI_COPY_MEM_MEM
it from there to the actual SURFACE_STATE bytes where it's stored.

This unfortunately doesn't work for blorp_copy(), which does bit-for-bit
copies, and overrides the format to a CCS-compatible UINT format.  This
causes the clear color to be interpreted in the overridden format.

Normally, we provide the clear color on the CPU, and blorp_blit.c:2611
converts it to a packed pixel value in the original format, then unpacks
it in the overridden format, so the clear color we use expands to the
bits we originally desired.

However, BLORP doesn't support this pack/unpack with an indirect clear
buffer, as it would need to do the math on the GPU.  On Gen11+, it isn't
necessary, as the hardware does the right thing.

This patch changes Gen9 to stop using an indirect clear buffer and
simply do PIPE_CONTROLs with post-sync write immediate operations
to store the new color over the surface states for regular drawing.
BLORP continues streaming out surface states, and handles fast clear
colors on the CPU.

Fixes: 53c484ba8ac ("iris: blorp using resolve hooks")
Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
src/gallium/drivers/iris/iris_resource.c
src/gallium/drivers/iris/iris_state.c

index 387fd7f2c915252a3d04e17fb4cbf1080a8f68e3..eb2430ecf4e068cf2532525cbb8302bbba5ded6f 100644 (file)
@@ -381,9 +381,7 @@ static unsigned
 iris_get_aux_clear_color_state_size(struct iris_screen *screen)
 {
    const struct gen_device_info *devinfo = &screen->devinfo;
-   return
-      (devinfo->gen >= 10 ? screen->isl_dev.ss.clear_color_state_size :
-       (devinfo->gen >= 9 ? screen->isl_dev.ss.clear_value_size : 0));
+   return devinfo->gen >= 10 ? screen->isl_dev.ss.clear_color_state_size : 0;
 }
 
 /**
index baa67bcb7708f69bea5979d731ac7e5bc7338acf..02b8683487e4483007b466a7a2d3f80ef3f3cf7b 100644 (file)
@@ -4011,17 +4011,36 @@ surf_state_update_clear_value(struct iris_batch *batch,
 {
    struct isl_device *isl_dev = &batch->screen->isl_dev;
    struct iris_bo *state_bo = iris_resource_bo(state->res);
-   uint64_t real_offset = state->offset +
-      IRIS_MEMZONE_BINDER_START;
+   uint64_t real_offset = state->offset + IRIS_MEMZONE_BINDER_START;
    uint32_t offset_into_bo = real_offset - state_bo->gtt_offset;
    uint32_t clear_offset = offset_into_bo +
       isl_dev->ss.clear_value_offset +
       surf_state_offset_for_aux(res, aux_modes, aux_usage);
+   uint32_t *color = res->aux.clear_color.u32;
 
-   batch->vtbl->copy_mem_mem(batch, state_bo, clear_offset,
-                             res->aux.clear_color_bo,
-                             res->aux.clear_color_offset,
-                             isl_dev->ss.clear_value_size);
+   assert(isl_dev->ss.clear_value_size == 16);
+
+   if (aux_usage == ISL_AUX_USAGE_HIZ) {
+      iris_emit_pipe_control_write(batch, "update fast clear value (Z)",
+                                   PIPE_CONTROL_WRITE_IMMEDIATE,
+                                   state_bo, clear_offset, color[0]);
+   } else {
+      iris_emit_pipe_control_write(batch, "update fast clear color (RG__)",
+                                   PIPE_CONTROL_WRITE_IMMEDIATE,
+                                   state_bo, clear_offset,
+                                   (uint64_t) color[0] |
+                                   (uint64_t) color[1] << 32);
+      iris_emit_pipe_control_write(batch, "update fast clear color (__BA)",
+                                   PIPE_CONTROL_WRITE_IMMEDIATE,
+                                   state_bo, clear_offset + 8,
+                                   (uint64_t) color[2] |
+                                   (uint64_t) color[3] << 32);
+   }
+
+   iris_emit_pipe_control_flush(batch,
+                                "update fast clear: state cache invalidate",
+                                PIPE_CONTROL_FLUSH_ENABLE |
+                                PIPE_CONTROL_STATE_CACHE_INVALIDATE);
 }
 
 static void