dzn: Add support for EXT_vertex_attribute_divisor

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15915>
This commit is contained in:
Boris Brezillon 2022-04-07 07:53:58 -07:00
parent d01a149b8b
commit 3af6631c6d
2 changed files with 45 additions and 4 deletions

View file

@ -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;
}
}
}

View file

@ -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;
}