This change tracks render target writes in the pipeline and applies a
render target flush before copying the query results to make sure the
preceding operations have landed in memory before the command streamer
initiates the copy.
v2: Simplify logic in CopyQueryResults (Jason)
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108909
Fixes: 37f9788e9a
("anv: flush pipeline before query result copies")
Cc: mesa-stable@lists.freedesktop.org
tags/19.0-branchpoint
@@ -1747,6 +1747,13 @@ enum anv_pipe_bits { | |||
* we would have to CS stall on every flush which could be bad. | |||
*/ | |||
ANV_PIPE_NEEDS_CS_STALL_BIT = (1 << 21), | |||
/* This bit does not exist directly in PIPE_CONTROL. It means that render | |||
* target operations are ongoing. Some operations like copies on the | |||
* command streamer might need to be aware of this to trigger the | |||
* appropriate stall before they can proceed with the copy. | |||
*/ | |||
ANV_PIPE_RENDER_TARGET_WRITES = (1 << 22), | |||
}; | |||
#define ANV_PIPE_FLUSH_BITS ( \ |
@@ -263,4 +263,5 @@ genX(blorp_exec)(struct blorp_batch *batch, | |||
cmd_buffer->state.gfx.vb_dirty = ~0; | |||
cmd_buffer->state.gfx.dirty = ~0; | |||
cmd_buffer->state.push_constants_dirty = ~0; | |||
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_WRITES; | |||
} |
@@ -1766,6 +1766,12 @@ genX(cmd_buffer_apply_pipe_flushes)(struct anv_cmd_buffer *cmd_buffer) | |||
pipe.StallAtPixelScoreboard = true; | |||
} | |||
/* If a render target flush was emitted, then we can toggle off the bit | |||
* saying that render target writes are ongoing. | |||
*/ | |||
if (bits & ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT) | |||
bits &= ~(ANV_PIPE_RENDER_TARGET_WRITES); | |||
bits &= ~(ANV_PIPE_FLUSH_BITS | ANV_PIPE_CS_STALL_BIT); | |||
} | |||
@@ -2777,6 +2783,8 @@ void genX(CmdDraw)( | |||
prim.StartInstanceLocation = firstInstance; | |||
prim.BaseVertexLocation = 0; | |||
} | |||
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_WRITES; | |||
} | |||
void genX(CmdDrawIndexed)( | |||
@@ -2816,6 +2824,8 @@ void genX(CmdDrawIndexed)( | |||
prim.StartInstanceLocation = firstInstance; | |||
prim.BaseVertexLocation = vertexOffset; | |||
} | |||
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_WRITES; | |||
} | |||
/* Auto-Draw / Indirect Registers */ | |||
@@ -2949,6 +2959,8 @@ void genX(CmdDrawIndirect)( | |||
offset += stride; | |||
} | |||
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_WRITES; | |||
} | |||
void genX(CmdDrawIndexedIndirect)( | |||
@@ -2988,6 +3000,8 @@ void genX(CmdDrawIndexedIndirect)( | |||
offset += stride; | |||
} | |||
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_WRITES; | |||
} | |||
static VkResult |
@@ -302,4 +302,5 @@ genX(cmd_buffer_so_memcpy)(struct anv_cmd_buffer *cmd_buffer, | |||
} | |||
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE; | |||
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_WRITES; | |||
} |
@@ -729,6 +729,15 @@ void genX(CmdCopyQueryPoolResults)( | |||
ANV_FROM_HANDLE(anv_query_pool, pool, queryPool); | |||
ANV_FROM_HANDLE(anv_buffer, buffer, destBuffer); | |||
/* If render target writes are ongoing, request a render target cache flush | |||
* to ensure proper ordering of the commands from the 3d pipe and the | |||
* command streamer. | |||
*/ | |||
if (cmd_buffer->state.pending_pipe_bits & ANV_PIPE_RENDER_TARGET_WRITES) { | |||
cmd_buffer->state.pending_pipe_bits |= | |||
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT; | |||
} | |||
if ((flags & VK_QUERY_RESULT_WAIT_BIT) || | |||
(cmd_buffer->state.pending_pipe_bits & ANV_PIPE_FLUSH_BITS)) { | |||
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_CS_STALL_BIT; |