From 1fd2bc10dc7695378115a99d7566ee3859dd992c Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 24 Jun 2020 19:56:01 -0400 Subject: [PATCH] turnip: implement VK_EXT_vertex_attribute_divisor Signed-off-by: Jonathan Marek Part-of: --- src/freedreno/vulkan/tu_device.c | 14 +++++++++++++- src/freedreno/vulkan/tu_extensions.py | 1 + src/freedreno/vulkan/tu_pipeline.c | 16 +++++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index 63d33e531b4..225cfee3765 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -722,6 +722,13 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, features->indexTypeUint8 = true; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: { + VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features = + (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext; + features->vertexAttributeInstanceRateDivisor = true; + features->vertexAttributeInstanceRateZeroDivisor = true; + break; + } default: break; } @@ -964,7 +971,12 @@ tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, properties->quadOperationsInAllStages = false; break; } - + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: { + VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props = + (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext; + props->maxVertexAttribDivisor = UINT32_MAX; + break; + } default: break; } diff --git a/src/freedreno/vulkan/tu_extensions.py b/src/freedreno/vulkan/tu_extensions.py index 20539c7367e..9a14bb6c89f 100644 --- a/src/freedreno/vulkan/tu_extensions.py +++ b/src/freedreno/vulkan/tu_extensions.py @@ -80,6 +80,7 @@ EXTENSIONS = [ Extension('VK_IMG_filter_cubic', 1, 'device->gpu_id == 650'), Extension('VK_EXT_filter_cubic', 1, 'device->gpu_id == 650'), Extension('VK_EXT_index_type_uint8', 1, True), + Extension('VK_EXT_vertex_attribute_divisor', 1, True), ] MAX_API_VERSION = VkVersion(MAX_API_VERSION) diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 30c5361c56d..add032bcc74 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -1401,6 +1401,7 @@ tu6_emit_vertex_input(struct tu_cs *cs, { uint32_t vfd_decode_idx = 0; uint32_t binding_instanced = 0; /* bitmask of instanced bindings */ + uint32_t step_rate[MAX_VBS]; for (uint32_t i = 0; i < info->vertexBindingDescriptionCount; i++) { const VkVertexInputBindingDescription *binding = @@ -1413,6 +1414,17 @@ tu6_emit_vertex_input(struct tu_cs *cs, binding_instanced |= 1 << binding->binding; *bindings_used |= 1 << binding->binding; + step_rate[binding->binding] = 1; + } + + const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state = + vk_find_struct_const(info->pNext, PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT); + if (div_state) { + for (uint32_t i = 0; i < div_state->vertexBindingDivisorCount; i++) { + const VkVertexInputBindingDivisorDescriptionEXT *desc = + &div_state->pVertexBindingDivisors[i]; + step_rate[desc->binding] = desc->divisor; + } } /* TODO: emit all VFD_DECODE/VFD_DEST_CNTL in same (two) pkt4 */ @@ -1422,6 +1434,8 @@ tu6_emit_vertex_input(struct tu_cs *cs, &info->pVertexAttributeDescriptions[i]; uint32_t input_idx; + assert(*bindings_used & BIT(attr->binding)); + for (input_idx = 0; input_idx < vs->inputs_count; input_idx++) { if ((vs->inputs[input_idx].slot - VERT_ATTRIB_GENERIC0) == attr->location) break; @@ -1441,7 +1455,7 @@ tu6_emit_vertex_input(struct tu_cs *cs, .swap = format.swap, .unk30 = 1, ._float = !vk_format_is_int(attr->format)), - A6XX_VFD_DECODE_STEP_RATE(vfd_decode_idx, 1)); + A6XX_VFD_DECODE_STEP_RATE(vfd_decode_idx, step_rate[attr->binding])); tu_cs_emit_regs(cs, A6XX_VFD_DEST_CNTL_INSTR(vfd_decode_idx, -- 2.30.2