From b2622843003ea0d4769947b02673ead1d5fa695a Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 13 Apr 2020 14:35:44 +0200 Subject: [PATCH] radv: add support for dynamic vertex input binding stride Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/amd/vulkan/radv_cmd_buffer.c | 40 ++++++++++++++++++++++++++++---- src/amd/vulkan/radv_pipeline.c | 10 ++++++-- src/amd/vulkan/radv_private.h | 3 +++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 91b1b0f2d80..bfae582d30c 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -2689,8 +2689,8 @@ radv_flush_vertex_descriptors(struct radv_cmd_buffer *cmd_buffer, uint32_t *desc = &((uint32_t *)vb_ptr)[i * 4]; uint32_t offset; struct radv_buffer *buffer = cmd_buffer->vertex_bindings[i].buffer; - uint32_t stride = cmd_buffer->state.pipeline->binding_stride[i]; unsigned num_records; + unsigned stride; if (!buffer) continue; @@ -2700,7 +2700,18 @@ radv_flush_vertex_descriptors(struct radv_cmd_buffer *cmd_buffer, offset = cmd_buffer->vertex_bindings[i].offset; va += offset + buffer->offset; - num_records = buffer->size - offset; + if (cmd_buffer->vertex_bindings[i].size) { + num_records = cmd_buffer->vertex_bindings[i].size; + } else { + num_records = buffer->size - offset; + } + + if (cmd_buffer->state.pipeline->graphics.uses_dynamic_stride) { + stride = cmd_buffer->vertex_bindings[i].stride; + } else { + stride = cmd_buffer->state.pipeline->binding_stride[i]; + } + if (cmd_buffer->device->physical_device->rad_info.chip_class != GFX8 && stride) num_records /= stride; @@ -3691,11 +3702,25 @@ VkResult radv_BeginCommandBuffer( } void radv_CmdBindVertexBuffers( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets) +{ + radv_CmdBindVertexBuffers2EXT(commandBuffer, firstBinding, + bindingCount, pBuffers, pOffsets, + NULL, NULL); +} + +void radv_CmdBindVertexBuffers2EXT( VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets) + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes, + const VkDeviceSize* pStrides) { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); struct radv_vertex_binding *vb = cmd_buffer->vertex_bindings; @@ -3708,15 +3733,22 @@ void radv_CmdBindVertexBuffers( for (uint32_t i = 0; i < bindingCount; i++) { RADV_FROM_HANDLE(radv_buffer, buffer, pBuffers[i]); uint32_t idx = firstBinding + i; + VkDeviceSize size = pSizes ? pSizes[i] : 0; + VkDeviceSize stride = pStrides ? pStrides[i] : 0; + /* pSizes and pStrides are optional. */ if (!changed && (vb[idx].buffer != buffer || - vb[idx].offset != pOffsets[i])) { + vb[idx].offset != pOffsets[i] || + vb[idx].size != size || + vb[idx].stride != stride)) { changed = true; } vb[idx].buffer = buffer; vb[idx].offset = pOffsets[i]; + vb[idx].size = size; + vb[idx].stride = stride; if (buffer) { radv_cs_add_buffer(cmd_buffer->device->ws, diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index ea1f92891ea..f6df654a54b 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -1293,6 +1293,8 @@ static unsigned radv_dynamic_state_mask(VkDynamicState state) return RADV_DYNAMIC_STENCIL_TEST_ENABLE; case VK_DYNAMIC_STATE_STENCIL_OP_EXT: return RADV_DYNAMIC_STENCIL_OP; + case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT: + return RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE; default: unreachable("Unhandled dynamic state"); } @@ -1304,10 +1306,11 @@ static uint32_t radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreat /* If rasterization is disabled we do not care about any of the * dynamic states, since they are all rasterization related only, - * except primitive topology. + * except primitive topology and vertex binding stride. */ if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable) - return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY; + return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY | + RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE; if (!pCreateInfo->pRasterizationState->depthBiasEnable) states &= ~RADV_DYNAMIC_DEPTH_BIAS; @@ -1559,6 +1562,9 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, dynamic->line_stipple.pattern = rast_line_info->lineStipplePattern; } + if (!(states & RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE)) + pipeline->graphics.uses_dynamic_stride = true; + pipeline->dynamic_state.mask = states; } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 359110eeec2..53fc176baa3 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1036,6 +1036,8 @@ enum radv_cmd_flush_bits { struct radv_vertex_binding { struct radv_buffer * buffer; VkDeviceSize offset; + VkDeviceSize size; + VkDeviceSize stride; }; struct radv_streamout_binding { @@ -1678,6 +1680,7 @@ struct radv_pipeline { unsigned tess_patch_control_points; unsigned pa_su_sc_mode_cntl; unsigned db_depth_control; + bool uses_dynamic_stride; /* Used for rbplus */ uint32_t col_format; -- 2.30.2