From 3af6631c6d1c88d7efc4709f7e0a52aff09758f3 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 7 Apr 2022 07:53:58 -0700 Subject: [PATCH] dzn: Add support for EXT_vertex_attribute_divisor Reviewed-by: Jesse Natalie Part-of: --- src/microsoft/vulkan/dzn_device.c | 26 ++++++++++++++++++++++++-- src/microsoft/vulkan/dzn_pipeline.c | 23 +++++++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/microsoft/vulkan/dzn_device.c b/src/microsoft/vulkan/dzn_device.c index 144ef1a77fb..f78904b6351 100644 --- a/src/microsoft/vulkan/dzn_device.c +++ b/src/microsoft/vulkan/dzn_device.c @@ -80,6 +80,7 @@ dzn_physical_device_get_extensions(struct dzn_physical_device *pdev) #ifdef DZN_USE_WSI_PLATFORM .KHR_swapchain = true, #endif + .EXT_vertex_attribute_divisor = true, }; } @@ -1159,7 +1160,18 @@ dzn_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, vk_get_physical_device_core_1_3_feature_ext(ext, &core_1_3)) continue; - dzn_debug_ignored_stype(ext->sType); + switch (ext->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: { + VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features = + (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext; + features->vertexAttributeInstanceRateDivisor = true; + features->vertexAttributeInstanceRateZeroDivisor = true; + break; + } + default: + dzn_debug_ignored_stype(ext->sType); + break; + } } } @@ -1474,7 +1486,17 @@ dzn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, vk_get_physical_device_core_1_3_property_ext(ext, &core_1_3)) continue; - dzn_debug_ignored_stype(ext->sType); + switch (ext->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: { + VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *attr_div = + (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext; + attr_div->maxVertexAttribDivisor = UINT32_MAX; + break; + } + default: + dzn_debug_ignored_stype(ext->sType); + break; + } } } diff --git a/src/microsoft/vulkan/dzn_pipeline.c b/src/microsoft/vulkan/dzn_pipeline.c index 11fd1a54b75..91f393f00a9 100644 --- a/src/microsoft/vulkan/dzn_pipeline.c +++ b/src/microsoft/vulkan/dzn_pipeline.c @@ -202,6 +202,9 @@ dzn_graphics_pipeline_translate_vi(struct dzn_graphics_pipeline *pipeline, container_of(pipeline->base.base.device, struct dzn_device, vk); const VkPipelineVertexInputStateCreateInfo *in_vi = in->pVertexInputState; + const VkPipelineVertexInputDivisorStateCreateInfoEXT *divisors = + (const VkPipelineVertexInputDivisorStateCreateInfoEXT *) + vk_find_struct_const(in_vi, PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT); if (!in_vi->vertexAttributeDescriptionCount) { out->InputLayout.pInputElementDescs = NULL; @@ -238,6 +241,17 @@ dzn_graphics_pipeline_translate_vi(struct dzn_graphics_pipeline *pipeline, for (uint32_t i = 0; i < in_vi->vertexAttributeDescriptionCount; i++) { const VkVertexInputAttributeDescription *attr = &in_vi->pVertexAttributeDescriptions[i]; + const VkVertexInputBindingDivisorDescriptionEXT *divisor = NULL; + + if (slot_class[attr->binding] == D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA && + divisors) { + for (uint32_t d = 0; d < divisors->vertexBindingDivisorCount; d++) { + if (attr->binding == divisors->pVertexBindingDivisors[d].binding) { + divisor = &divisors->pVertexBindingDivisors[d]; + break; + } + } + } /* nir_to_dxil() name all vertex inputs as TEXCOORDx */ inputs[i].SemanticName = "TEXCOORD"; @@ -245,8 +259,13 @@ dzn_graphics_pipeline_translate_vi(struct dzn_graphics_pipeline *pipeline, inputs[i].Format = dzn_buffer_get_dxgi_format(attr->format); inputs[i].InputSlot = attr->binding; inputs[i].InputSlotClass = slot_class[attr->binding]; - inputs[i].InstanceDataStepRate = - inputs[i].InputSlotClass == D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA ? 1 : 0; + if (divisor) { + assert(inputs[i].InputSlotClass == D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA); + inputs[i].InstanceDataStepRate = divisor->divisor; + } else { + inputs[i].InstanceDataStepRate = + inputs[i].InputSlotClass == D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA ? 1 : 0; + } inputs[i].AlignedByteOffset = attr->offset; }