From: Lionel Landwerlin Date: Mon, 3 Dec 2018 14:33:35 +0000 (+0000) Subject: anv/query: flush render target before copying results X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9a7b3199037ac4b798974f561067cb3d66be8010;p=mesa.git anv/query: flush render target before copying results 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 Reviewed-by: Jason Ekstrand Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108909 Fixes: 37f9788e9a8e44 ("anv: flush pipeline before query result copies") Cc: mesa-stable@lists.freedesktop.org --- diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 62c563294f5..aff076a55d9 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -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 ( \ diff --git a/src/intel/vulkan/genX_blorp_exec.c b/src/intel/vulkan/genX_blorp_exec.c index 2035017ce0e..c573e890946 100644 --- a/src/intel/vulkan/genX_blorp_exec.c +++ b/src/intel/vulkan/genX_blorp_exec.c @@ -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; } diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index c7e5ef9596e..fb70cd2e386 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -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 diff --git a/src/intel/vulkan/genX_gpu_memcpy.c b/src/intel/vulkan/genX_gpu_memcpy.c index 81522986550..1bee1c6dc17 100644 --- a/src/intel/vulkan/genX_gpu_memcpy.c +++ b/src/intel/vulkan/genX_gpu_memcpy.c @@ -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; } diff --git a/src/intel/vulkan/genX_query.c b/src/intel/vulkan/genX_query.c index 4831c4ea334..71b7a1352f0 100644 --- a/src/intel/vulkan/genX_query.c +++ b/src/intel/vulkan/genX_query.c @@ -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;