When binding a new pipeline, we applied all dynamic states without checking if they really need to be re-emitted. This doesn't seem to be useful for the meta operations because only the viewports/scissors are updated.
This should reduce the number of commands added to the IB when a new graphics pipeline is bound. Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com> --- src/amd/vulkan/radv_cmd_buffer.c | 100 +++++++++++++++++++++++++++++---------- src/amd/vulkan/radv_private.h | 7 +-- 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 561ca2fbce..9e76cf6c2c 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -78,43 +78,92 @@ const struct radv_dynamic_state default_dynamic_state = { }, }; -void +uint32_t radv_dynamic_state_copy(struct radv_dynamic_state *dest, const struct radv_dynamic_state *src, uint32_t copy_mask) { + uint32_t dest_mask = 0; + if (copy_mask & (1 << VK_DYNAMIC_STATE_VIEWPORT)) { - dest->viewport.count = src->viewport.count; - typed_memcpy(dest->viewport.viewports, src->viewport.viewports, - src->viewport.count); + if (memcmp(&dest->viewport, &src->viewport, + sizeof(src->viewport))) { + dest->viewport.count = src->viewport.count; + typed_memcpy(dest->viewport.viewports, + src->viewport.viewports, + src->viewport.count); + dest_mask |= 1 << VK_DYNAMIC_STATE_VIEWPORT; + } } if (copy_mask & (1 << VK_DYNAMIC_STATE_SCISSOR)) { - dest->scissor.count = src->scissor.count; - typed_memcpy(dest->scissor.scissors, src->scissor.scissors, - src->scissor.count); + if (memcmp(&dest->scissor, &src->scissor, + sizeof(src->scissor))) { + dest->scissor.count = src->scissor.count; + typed_memcpy(dest->scissor.scissors, + src->scissor.scissors, src->scissor.count); + dest_mask |= 1 << VK_DYNAMIC_STATE_SCISSOR; + } } - if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH)) - dest->line_width = src->line_width; + if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH)) { + if (dest->line_width != src->line_width) { + dest->line_width = src->line_width; + dest_mask |= 1 << VK_DYNAMIC_STATE_LINE_WIDTH; + } + } - if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) - dest->depth_bias = src->depth_bias; + if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) { + if (memcmp(&dest->depth_bias, &src->depth_bias, + sizeof(src->depth_bias))) { + dest->depth_bias = src->depth_bias; + dest_mask |= 1 << VK_DYNAMIC_STATE_DEPTH_BIAS; + } + } - if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS)) - typed_memcpy(dest->blend_constants, src->blend_constants, 4); + if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS)) { + if (memcmp(&dest->blend_constants, &src->blend_constants, + sizeof(src->blend_constants))) { + typed_memcpy(dest->blend_constants, + src->blend_constants, 4); + dest_mask |= 1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS; + } + } - if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) - dest->depth_bounds = src->depth_bounds; + if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) { + if (memcmp(&dest->depth_bounds, &src->depth_bounds, + sizeof(src->depth_bounds))) { + dest->depth_bounds = src->depth_bounds; + dest_mask |= 1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS; + } + } - if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) - dest->stencil_compare_mask = src->stencil_compare_mask; + if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) { + if (memcmp(&dest->stencil_compare_mask, + &src->stencil_compare_mask, + sizeof(src->stencil_compare_mask))) { + dest->stencil_compare_mask = src->stencil_compare_mask; + dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; + } + } - if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) - dest->stencil_write_mask = src->stencil_write_mask; + if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) { + if (memcmp(&dest->stencil_write_mask, &src->stencil_write_mask, + sizeof(src->stencil_write_mask))) { + dest->stencil_write_mask = src->stencil_write_mask; + dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; + } + } + + if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) { + if (memcmp(&dest->stencil_reference, &src->stencil_reference, + sizeof(src->stencil_reference))) { + dest->stencil_reference = src->stencil_reference; + dest_mask |= 1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE; + } + } - if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) - dest->stencil_reference = src->stencil_reference; + return dest_mask; } bool radv_cmd_buffer_uses_mec(struct radv_cmd_buffer *cmd_buffer) @@ -2445,6 +2494,7 @@ void radv_CmdBindPipeline( { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); RADV_FROM_HANDLE(radv_pipeline, pipeline, _pipeline); + uint32_t dirty_mask; radv_mark_descriptor_sets_dirty(cmd_buffer); @@ -2462,10 +2512,10 @@ void radv_CmdBindPipeline( cmd_buffer->push_constant_stages |= pipeline->active_stages; /* Apply the dynamic state from the pipeline */ - cmd_buffer->state.dirty |= pipeline->dynamic_state.mask; - radv_dynamic_state_copy(&cmd_buffer->state.dynamic, - &pipeline->dynamic_state, - pipeline->dynamic_state.mask); + dirty_mask = radv_dynamic_state_copy(&cmd_buffer->state.dynamic, + &pipeline->dynamic_state, + pipeline->dynamic_state.mask); + cmd_buffer->state.dirty |= dirty_mask; if (pipeline->graphics.esgs_ring_size > cmd_buffer->esgs_ring_size_needed) cmd_buffer->esgs_ring_size_needed = pipeline->graphics.esgs_ring_size; diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 0cebb3e7e1..9c67da49a2 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -747,9 +747,10 @@ struct radv_dynamic_state { extern const struct radv_dynamic_state default_dynamic_state; -void radv_dynamic_state_copy(struct radv_dynamic_state *dest, - const struct radv_dynamic_state *src, - uint32_t copy_mask); +uint32_t +radv_dynamic_state_copy(struct radv_dynamic_state *dest, + const struct radv_dynamic_state *src, + uint32_t copy_mask); const char * radv_get_debug_option_name(int id); -- 2.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev