aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2019-09-03 15:34:54 -0700
committerKenneth Graunke <[email protected]>2019-09-06 10:57:55 -0700
commit68be5ff8d0ee30bffef1af631ffe9070ab63f832 (patch)
tree98e11b8fba786931f2df686181725fab4bd36d04 /src/gallium/drivers
parent30ab3e39fd4d9cceb8a1a7d06dc3d99b0f477a72 (diff)
iris: Invalidate state/texture/constant caches after STATE_BASE_ADDRESS
Jason pointed out that the caches likely refer to offsets from dynamic and surface state base addresses, so when we change those, we need to invalidate the caches. Comment borrowed from src/intel/vulkan/genX_cmd_buffer.c.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/iris/iris_state.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 19e795355c0..525263174e0 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -391,7 +391,7 @@ emit_state(struct iris_batch *batch,
(!old_cso || memcmp(old_cso->x, new_cso->x, sizeof(old_cso->x)) != 0)
static void
-flush_for_state_base_change(struct iris_batch *batch)
+flush_before_state_base_change(struct iris_batch *batch)
{
/* Flush before emitting STATE_BASE_ADDRESS.
*
@@ -415,13 +415,60 @@ flush_for_state_base_change(struct iris_batch *batch)
* rendering. It's a bit of a big hammer but it appears to work.
*/
iris_emit_end_of_pipe_sync(batch,
- "change STATE_BASE_ADDRESS",
+ "change STATE_BASE_ADDRESS (flushes)",
PIPE_CONTROL_RENDER_TARGET_FLUSH |
PIPE_CONTROL_DEPTH_CACHE_FLUSH |
PIPE_CONTROL_DATA_CACHE_FLUSH);
}
static void
+flush_after_state_base_change(struct iris_batch *batch)
+{
+ /* After re-setting the surface state base address, we have to do some
+ * cache flusing so that the sampler engine will pick up the new
+ * SURFACE_STATE objects and binding tables. From the Broadwell PRM,
+ * Shared Function > 3D Sampler > State > State Caching (page 96):
+ *
+ * Coherency with system memory in the state cache, like the texture
+ * cache is handled partially by software. It is expected that the
+ * command stream or shader will issue Cache Flush operation or
+ * Cache_Flush sampler message to ensure that the L1 cache remains
+ * coherent with system memory.
+ *
+ * [...]
+ *
+ * Whenever the value of the Dynamic_State_Base_Addr,
+ * Surface_State_Base_Addr are altered, the L1 state cache must be
+ * invalidated to ensure the new surface or sampler state is fetched
+ * from system memory.
+ *
+ * The PIPE_CONTROL command has a "State Cache Invalidation Enable" bit
+ * which, according the PIPE_CONTROL instruction documentation in the
+ * Broadwell PRM:
+ *
+ * Setting this bit is independent of any other bit in this packet.
+ * This bit controls the invalidation of the L1 and L2 state caches
+ * at the top of the pipe i.e. at the parsing time.
+ *
+ * Unfortunately, experimentation seems to indicate that state cache
+ * invalidation through a PIPE_CONTROL does nothing whatsoever in
+ * regards to surface state and binding tables. In stead, it seems that
+ * invalidating the texture cache is what is actually needed.
+ *
+ * XXX: As far as we have been able to determine through
+ * experimentation, shows that flush the texture cache appears to be
+ * sufficient. The theory here is that all of the sampling/rendering
+ * units cache the binding table in the texture cache. However, we have
+ * yet to be able to actually confirm this.
+ */
+ iris_emit_end_of_pipe_sync(batch,
+ "change STATE_BASE_ADDRESS (invalidates)",
+ PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
+ PIPE_CONTROL_CONST_CACHE_INVALIDATE |
+ PIPE_CONTROL_STATE_CACHE_INVALIDATE);
+}
+
+static void
_iris_emit_lri(struct iris_batch *batch, uint32_t reg, uint32_t val)
{
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_IMM), lri) {
@@ -513,7 +560,7 @@ init_glk_barrier_mode(struct iris_batch *batch, uint32_t value)
static void
init_state_base_address(struct iris_batch *batch)
{
- flush_for_state_base_change(batch);
+ flush_before_state_base_change(batch);
/* We program most base addresses once at context initialization time.
* Each base address points at a 4GB memory zone, and never needs to
@@ -551,6 +598,8 @@ init_state_base_address(struct iris_batch *batch)
sba.InstructionBufferSize = 0xfffff;
sba.DynamicStateBufferSize = 0xfffff;
}
+
+ flush_after_state_base_change(batch);
}
static void
@@ -4568,7 +4617,7 @@ iris_update_surface_base_address(struct iris_batch *batch,
if (batch->last_surface_base_address == binder->bo->gtt_offset)
return;
- flush_for_state_base_change(batch);
+ flush_before_state_base_change(batch);
iris_emit_cmd(batch, GENX(STATE_BASE_ADDRESS), sba) {
sba.SurfaceStateBaseAddressModifyEnable = true;
@@ -4588,6 +4637,8 @@ iris_update_surface_base_address(struct iris_batch *batch,
#endif
}
+ flush_after_state_base_change(batch);
+
batch->last_surface_base_address = binder->bo->gtt_offset;
}