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:

committed by
Dave Airlie

parent
5b0b03733a
commit
3f0da800eb
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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,6 +585,16 @@ 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:
|
||||||
|
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;
|
state->ve[location].instance_divisor = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -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),
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user