diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index d5a1d479de3..42b757822c0 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -3,3 +3,4 @@ d3d12 ARB_robust_buffer_access_behavior VK_EXT_robustness2 for lavapipe VK_EXT_image_2d_view_of_3d on RADV zink GL_EXT_memory_object_win32 and GL_EXT_semaphore_win32 support +vertexAttributeInstanceRateZeroDivisor support for lavapipe diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index a963c38bc1d..333674bc208 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -780,11 +780,12 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2( 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->vertexAttributeInstanceRateZeroDivisor = true; features->vertexAttributeInstanceRateDivisor = true; } else { features->vertexAttributeInstanceRateDivisor = false; + features->vertexAttributeInstanceRateZeroDivisor = false; } break; } diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 73f8c17d2dc..2253744778f 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -3495,13 +3495,13 @@ static void handle_set_vertex_input(struct vk_cmd_queue_entry *cmd, state->velem.velems[location].vertex_buffer_index = attrs[i].binding; state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(attrs[i].format); state->vb[attrs[i].binding].stride = binding->stride; - + uint32_t d = binding->divisor; switch (binding->inputRate) { case VK_VERTEX_INPUT_RATE_VERTEX: state->velem.velems[location].instance_divisor = 0; break; case VK_VERTEX_INPUT_RATE_INSTANCE: - state->velem.velems[location].instance_divisor = binding->divisor; + state->velem.velems[location].instance_divisor = d ? d : UINT32_MAX; break; default: assert(0); diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c index edf3e59a27e..738411f6c8b 100644 --- a/src/gallium/frontends/lavapipe/lvp_pipeline.c +++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c @@ -143,17 +143,26 @@ deep_copy_vertex_input_state(void *mem_ctx, 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); - + const VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_src = (VkPipelineVertexInputDivisorStateCreateInfoEXT *)ext; + unsigned n = ext_src->vertexBindingDivisorCount; + if (!n) + continue; + size_t offset = sizeof(VkPipelineVertexInputDivisorStateCreateInfoEXT); + char *p = (char *) ralloc_size(mem_ctx, offset + n * sizeof(VkVertexInputBindingDivisorDescriptionEXT)); + if (!p) + return VK_ERROR_OUT_OF_HOST_MEMORY; + VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_dst = (VkPipelineVertexInputDivisorStateCreateInfoEXT *)p; + VkVertexInputBindingDivisorDescriptionEXT *dst_divisors = (VkVertexInputBindingDivisorDescriptionEXT *)(p + offset); 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); - + ext_dst->pNext = NULL; + ext_dst->vertexBindingDivisorCount = n; + ext_dst->pVertexBindingDivisors = dst_divisors; + const VkVertexInputBindingDivisorDescriptionEXT *src_divisors = ext_src->pVertexBindingDivisors; + for (unsigned i = 0; i < n; ++i) { + uint32_t d = src_divisors[i].divisor; + dst_divisors[i].divisor = d ? d : UINT32_MAX; + dst_divisors[i].binding = src_divisors[i].binding; + } dst->pNext = ext_dst; break; }