diff options
author | Samuel Pitoiset <[email protected]> | 2018-01-05 18:20:06 +0100 |
---|---|---|
committer | Samuel Pitoiset <[email protected]> | 2018-01-08 21:24:58 +0100 |
commit | be16bbe1d391d43cbccf4da2f1759ba52b016266 (patch) | |
tree | 7d8c77ffba256437065ae064657f5c1c96b5220f /src/amd/vulkan/radv_cmd_buffer.c | |
parent | b09b3f88341b7cd31eb8b1921d8d2b29fd0bfaa3 (diff) |
radv: avoid PS partial flushes when viewports/scissors don't change
For Vega10 and Raven that need a special workaround for the
scissor bug.
This seems to give a minor boost for Talos and Dota 2, at least.
To reduce the cost of memcmp, the driver checks if it's
really useful to do the comparison.
Signed-off-by: Samuel Pitoiset <[email protected]>
Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Diffstat (limited to 'src/amd/vulkan/radv_cmd_buffer.c')
-rw-r--r-- | src/amd/vulkan/radv_cmd_buffer.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 665ee876a9d..d8f780cfd76 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -2733,15 +2733,28 @@ void radv_CmdSetViewport( const VkViewport* pViewports) { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_cmd_state *state = &cmd_buffer->state; MAYBE_UNUSED const uint32_t total_count = firstViewport + viewportCount; assert(firstViewport < MAX_VIEWPORTS); assert(total_count >= 1 && total_count <= MAX_VIEWPORTS); - memcpy(cmd_buffer->state.dynamic.viewport.viewports + firstViewport, - pViewports, viewportCount * sizeof(*pViewports)); + if (cmd_buffer->device->physical_device->has_scissor_bug) { + /* Try to skip unnecessary PS partial flushes when the viewports + * don't change. + */ + if (!(state->dirty & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | + RADV_CMD_DIRTY_DYNAMIC_SCISSOR)) && + !memcmp(state->dynamic.viewport.viewports + firstViewport, + pViewports, viewportCount * sizeof(*pViewports))) { + return; + } + } + + memcpy(state->dynamic.viewport.viewports + firstViewport, pViewports, + viewportCount * sizeof(*pViewports)); - cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_VIEWPORT; + state->dirty |= RADV_CMD_DIRTY_DYNAMIC_VIEWPORT; } void radv_CmdSetScissor( @@ -2751,14 +2764,28 @@ void radv_CmdSetScissor( const VkRect2D* pScissors) { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_cmd_state *state = &cmd_buffer->state; MAYBE_UNUSED const uint32_t total_count = firstScissor + scissorCount; assert(firstScissor < MAX_SCISSORS); assert(total_count >= 1 && total_count <= MAX_SCISSORS); - memcpy(cmd_buffer->state.dynamic.scissor.scissors + firstScissor, - pScissors, scissorCount * sizeof(*pScissors)); - cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_SCISSOR; + if (cmd_buffer->device->physical_device->has_scissor_bug) { + /* Try to skip unnecessary PS partial flushes when the scissors + * don't change. + */ + if (!(state->dirty & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | + RADV_CMD_DIRTY_DYNAMIC_SCISSOR)) && + !memcmp(state->dynamic.scissor.scissors + firstScissor, + pScissors, scissorCount * sizeof(*pScissors))) { + return; + } + } + + memcpy(state->dynamic.scissor.scissors + firstScissor, pScissors, + scissorCount * sizeof(*pScissors)); + + state->dirty |= RADV_CMD_DIRTY_DYNAMIC_SCISSOR; } void radv_CmdSetLineWidth( |