From ef7ecc9fa20e3100427484a61caac2d3a2e66190 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 12 Oct 2020 17:56:02 +0200 Subject: [PATCH] radv: fix ignoring the vertex attribute stride if set as dynamic The vertex attribute stride should be ignored, so make sure it's initialized to zero if dynamic to avoid computing a wrong offset. The fact that each element of pStrides must be greater than or equal to the maximum extent of all vertex input attributes fetched saves us one user SGPR for the dynamic stride. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3627 Cc: 20.2 Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Part-of: (cherry picked from commit 48b988e35fe1c45e77138d92d162637b1ffc4486) --- src/amd/vulkan/radv_pipeline.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 442f63f5462..e9901dad340 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -2334,6 +2334,7 @@ radv_generate_graphics_pipeline_key(struct radv_pipeline *pipeline, pCreateInfo->pVertexInputState; const VkPipelineVertexInputDivisorStateCreateInfoEXT *divisor_state = vk_find_struct_const(input_state->pNext, PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT); + bool uses_dynamic_stride = false; struct radv_pipeline_key key; memset(&key, 0, sizeof(key)); @@ -2359,6 +2360,16 @@ radv_generate_graphics_pipeline_key(struct radv_pipeline *pipeline, } } + if (pCreateInfo->pDynamicState) { + uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount; + for (uint32_t i = 0; i < count; i++) { + if (pCreateInfo->pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT) { + uses_dynamic_stride = true; + break; + } + } + } + for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; ++i) { const VkVertexInputAttributeDescription *desc = &input_state->pVertexAttributeDescriptions[i]; @@ -2382,7 +2393,26 @@ radv_generate_graphics_pipeline_key(struct radv_pipeline *pipeline, key.vertex_attribute_formats[location] = data_format | (num_format << 4); key.vertex_attribute_bindings[location] = desc->binding; key.vertex_attribute_offsets[location] = desc->offset; - key.vertex_attribute_strides[location] = radv_get_attrib_stride(input_state, desc->binding); + + if (!uses_dynamic_stride) { + /* From the Vulkan spec 1.2.157: + * + * "If the bound pipeline state object was created + * with the + * VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT + * dynamic state enabled then pStrides[i] specifies + * the distance in bytes between two consecutive + * elements within the corresponding buffer. In this + * case the VkVertexInputBindingDescription::stride + * state from the pipeline state object is ignored." + * + * Make sure the vertex attribute stride is zero to + * avoid computing a wrong offset if it's initialized + * to something else than zero. + */ + key.vertex_attribute_strides[location] = + radv_get_attrib_stride(input_state, desc->binding); + } if (pipeline->device->physical_device->rad_info.chip_class <= GFX8 && pipeline->device->physical_device->rad_info.family != CHIP_STONEY) {