summaryrefslogtreecommitdiffstats
path: root/src/amd/vulkan/radv_cmd_buffer.c
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2018-01-05 18:20:06 +0100
committerSamuel Pitoiset <[email protected]>2018-01-08 21:24:58 +0100
commitbe16bbe1d391d43cbccf4da2f1759ba52b016266 (patch)
tree7d8c77ffba256437065ae064657f5c1c96b5220f /src/amd/vulkan/radv_cmd_buffer.c
parentb09b3f88341b7cd31eb8b1921d8d2b29fd0bfaa3 (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.c39
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(