lavapipe: implement VK_EXT_vertex_attribute_divisor (v2)

This is more or less just compile-tested, but this seems about right to
me. I see the extension being supported when running on top of Zink,
which makes me happy enough for now ;)

v2: fixed up to copy the structs on pipeline create [airlied]
gallium doesn't support the 0 divisor case yet.

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7930>
This commit is contained in:
Erik Faye-Lund
2020-12-04 20:21:51 +01:00
committed by Dave Airlie
parent 5b0b03733a
commit 3f0da800eb
4 changed files with 65 additions and 3 deletions

View File

@@ -347,6 +347,7 @@ void lvp_GetPhysicalDeviceFeatures2(
VkPhysicalDevice physicalDevice, VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2 *pFeatures) VkPhysicalDeviceFeatures2 *pFeatures)
{ {
LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
lvp_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features); lvp_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
vk_foreach_struct(ext, pFeatures->pNext) { vk_foreach_struct(ext, pFeatures->pNext) {
@@ -372,6 +373,19 @@ void lvp_GetPhysicalDeviceFeatures2(
features->privateData = true; features->privateData = true;
break; break;
} }
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
features->vertexAttributeInstanceRateZeroDivisor = false;
if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0) {
features->vertexAttributeInstanceRateDivisor = true;
} else {
features->vertexAttributeInstanceRateDivisor = false;
}
break;
}
default: default:
break; break;
} }
@@ -534,6 +548,7 @@ void lvp_GetPhysicalDeviceProperties2(
VkPhysicalDevice physicalDevice, VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2 *pProperties) VkPhysicalDeviceProperties2 *pProperties)
{ {
LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
lvp_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties); lvp_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
vk_foreach_struct(ext, pProperties->pNext) { vk_foreach_struct(ext, pProperties->pNext) {
@@ -569,6 +584,15 @@ void lvp_GetPhysicalDeviceProperties2(
properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES; properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
break; break;
} }
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0)
props->maxVertexAttribDivisor = UINT32_MAX;
else
props->maxVertexAttribDivisor = 1;
break;
}
default: default:
break; break;
} }

View File

@@ -40,6 +40,8 @@
#include "util/u_inlines.h" #include "util/u_inlines.h"
#include "util/format/u_format_zs.h" #include "util/format/u_format_zs.h"
#include "vk_util.h"
struct rendering_state { struct rendering_state {
struct pipe_context *pctx; struct pipe_context *pctx;
@@ -563,6 +565,9 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
{ {
const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState; const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState;
int i; int i;
const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state =
vk_find_struct_const(vi->pNext,
PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
for (i = 0; i < vi->vertexBindingDescriptionCount; i++) { for (i = 0; i < vi->vertexBindingDescriptionCount; i++) {
state->vb[i].stride = vi->pVertexBindingDescriptions[i].stride; state->vb[i].stride = vi->pVertexBindingDescriptions[i].stride;
@@ -580,7 +585,17 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
state->ve[location].instance_divisor = 0; state->ve[location].instance_divisor = 0;
break; break;
case VK_VERTEX_INPUT_RATE_INSTANCE: case VK_VERTEX_INPUT_RATE_INSTANCE:
state->ve[location].instance_divisor = 1; if (div_state) {
for (unsigned j = 0; j < div_state->vertexBindingDivisorCount; j++) {
const VkVertexInputBindingDivisorDescriptionEXT *desc =
&div_state->pVertexBindingDivisors[j];
if (desc->binding == state->ve[location].vertex_buffer_index) {
state->ve[location].instance_divisor = desc->divisor;
break;
}
}
} else
state->ve[location].instance_divisor = 1;
break; break;
default: default:
assert(0); assert(0);

View File

@@ -140,7 +140,7 @@ EXTENSIONS = [
Extension('VK_EXT_shader_subgroup_ballot', 1, False), Extension('VK_EXT_shader_subgroup_ballot', 1, False),
Extension('VK_EXT_shader_subgroup_vote', 1, False), Extension('VK_EXT_shader_subgroup_vote', 1, False),
Extension('VK_EXT_transform_feedback', 1, False), Extension('VK_EXT_transform_feedback', 1, False),
Extension('VK_EXT_vertex_attribute_divisor', 3, False), Extension('VK_EXT_vertex_attribute_divisor', 3, True),
Extension('VK_EXT_ycbcr_image_arrays', 1, False), Extension('VK_EXT_ycbcr_image_arrays', 1, False),
Extension('VK_GOOGLE_decorate_string', 1, True), Extension('VK_GOOGLE_decorate_string', 1, True),
Extension('VK_GOOGLE_hlsl_functionality1', 1, True), Extension('VK_GOOGLE_hlsl_functionality1', 1, True),

View File

@@ -22,7 +22,7 @@
*/ */
#include "lvp_private.h" #include "lvp_private.h"
#include "vk_util.h"
#include "glsl_types.h" #include "glsl_types.h"
#include "spirv/nir_spirv.h" #include "spirv/nir_spirv.h"
#include "nir/nir_builder.h" #include "nir/nir_builder.h"
@@ -165,6 +165,29 @@ deep_copy_vertex_input_state(void *mem_ctx,
VkVertexInputAttributeDescription, VkVertexInputAttributeDescription,
src->vertexAttributeDescriptionCount); src->vertexAttributeDescriptionCount);
if (src->pNext) {
vk_foreach_struct(ext, src->pNext) {
switch (ext->sType) {
case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT: {
VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_src = (VkPipelineVertexInputDivisorStateCreateInfoEXT *)ext;;
VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_dst = ralloc(mem_ctx, VkPipelineVertexInputDivisorStateCreateInfoEXT);
ext_dst->sType = ext_src->sType;
ext_dst->vertexBindingDivisorCount = ext_src->vertexBindingDivisorCount;
LVP_PIPELINE_DUP(ext_dst->pVertexBindingDivisors,
ext_src->pVertexBindingDivisors,
VkVertexInputBindingDivisorDescriptionEXT,
ext_src->vertexBindingDivisorCount);
dst->pNext = ext_dst;
break;
}
default:
break;
}
}
}
return VK_SUCCESS; return VK_SUCCESS;
} }