diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index 356ec5501a3..2ea846ac586 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -7,3 +7,4 @@ VK_KHR_shader_subgroup_uniform_control_flow on Intel. 32-bit x86 builds now default disable x87 math and use sse2. GL ES 3.1 on GT21x hardware. VK_EXT_acquire_drm_display on RADV. +VK_EXT_vertex_input_dynamic_state on lavapipe diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c index 39148241248..7230b5ae660 100644 --- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c +++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c @@ -1925,6 +1925,29 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdSetCullModeEXT( cmd_buf_queue(cmd_buffer, cmd); } +VKAPI_ATTR void VKAPI_CALL lvp_CmdSetVertexInputEXT( + VkCommandBuffer commandBuffer, + uint32_t vertexBindingDescriptionCount, + const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, + uint32_t vertexAttributeDescriptionCount, + const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions) +{ + LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); + struct lvp_cmd_buffer_entry *cmd; + + size_t binding_size = vertexBindingDescriptionCount * sizeof(VkVertexInputBindingDescription2EXT); + size_t attr_size = vertexAttributeDescriptionCount * sizeof(VkVertexInputAttributeDescription2EXT); + cmd = cmd_buf_entry_alloc_size(cmd_buffer, binding_size + attr_size, LVP_CMD_SET_VERTEX_INPUT); + if (!cmd) + return; + + cmd->u.set_vertex_input.binding_count = vertexBindingDescriptionCount; + cmd->u.set_vertex_input.attr_count = vertexAttributeDescriptionCount; + memcpy(cmd->u.set_vertex_input.data, pVertexBindingDescriptions, binding_size); + memcpy(cmd->u.set_vertex_input.data + binding_size, pVertexAttributeDescriptions, attr_size); + cmd_buf_queue(cmd_buffer, cmd); +} + VKAPI_ATTR void VKAPI_CALL lvp_CmdSetFrontFaceEXT( VkCommandBuffer commandBuffer, VkFrontFace frontFace) diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index 33f3f30043b..9420b17ed40 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -137,6 +137,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported = .EXT_shader_viewport_index_layer = true, .EXT_transform_feedback = true, .EXT_vertex_attribute_divisor = true, + .EXT_vertex_input_dynamic_state = true, .EXT_custom_border_color = true, .EXT_provoking_vertex = true, .GOOGLE_decorate_string = true, @@ -556,6 +557,13 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2( features->indexTypeUint8 = true; break; } + + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT: { + VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *features = + (VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *)ext; + features->vertexInputDynamicState = true; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: { VkPhysicalDeviceTransformFeedbackFeaturesEXT *features = (VkPhysicalDeviceTransformFeedbackFeaturesEXT*)ext; diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 2b08c8d6d32..b9ee469b502 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -348,6 +348,8 @@ static int conv_dynamic_state_idx(VkDynamicState dyn_state) if (dyn_state >= VK_DYNAMIC_STATE_CULL_MODE_EXT && dyn_state <= VK_DYNAMIC_STATE_STENCIL_OP_EXT) return dyn_state - VK_DYNAMIC_STATE_CULL_MODE_EXT + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2; + if (dyn_state == VK_DYNAMIC_STATE_VERTEX_INPUT_EXT) + return (VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT) + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1; assert(0); return -1; } @@ -594,7 +596,7 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd, state->blend_dirty = true; } - { + if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)]) { const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState; int i; const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state = @@ -2820,6 +2822,43 @@ static void handle_end_conditional_rendering(struct rendering_state *state) state->pctx->render_condition_mem(state->pctx, NULL, 0, false); } +static void handle_set_vertex_input(struct lvp_cmd_buffer_entry *cmd, + struct rendering_state *state) +{ + const struct lvp_cmd_set_vertex_input *vertex_input = &cmd->u.set_vertex_input; + const struct VkVertexInputBindingDescription2EXT *bindings = (void*)vertex_input->data; + const struct VkVertexInputAttributeDescription2EXT *attrs = (void*)(vertex_input->data + + vertex_input->binding_count * + sizeof(struct VkVertexInputBindingDescription2EXT)); + int max_location = -1; + for (unsigned i = 0; i < vertex_input->attr_count; i++) { + const struct VkVertexInputBindingDescription2EXT *binding = &bindings[attrs[i].binding]; + unsigned location = attrs[i].location; + state->velem.velems[location].src_offset = attrs[i].offset; + state->velem.velems[location].vertex_buffer_index = attrs[i].binding; + state->velem.velems[location].src_format = vk_format_to_pipe(attrs[i].format); + state->vb[attrs[i].binding].stride = binding->stride; + + 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; + break; + default: + assert(0); + break; + } + + if ((int)location > max_location) + max_location = location; + } + state->velem.count = max_location + 1; + state->vb_dirty = true; + state->ve_dirty = true; +} + static void handle_set_cull_mode(struct lvp_cmd_buffer_entry *cmd, struct rendering_state *state) { @@ -3079,6 +3118,9 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer, case LVP_CMD_END_CONDITIONAL_RENDERING: handle_end_conditional_rendering(state); break; + case LVP_CMD_SET_VERTEX_INPUT: + handle_set_vertex_input(cmd, state); + break; case LVP_CMD_SET_CULL_MODE: handle_set_cull_mode(cmd, state); break; diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c index 5bc1ac46c2f..22312999129 100644 --- a/src/gallium/frontends/lavapipe/lvp_pipeline.c +++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c @@ -272,12 +272,15 @@ deep_copy_graphics_create_info(void *mem_ctx, dst->pStages = stages; /* pVertexInputState */ - vertex_input = ralloc(mem_ctx, VkPipelineVertexInputStateCreateInfo); - result = deep_copy_vertex_input_state(mem_ctx, vertex_input, - src->pVertexInputState); - if (result != VK_SUCCESS) - return result; - dst->pVertexInputState = vertex_input; + if (!dynamic_state_contains(src->pDynamicState, VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)) { + vertex_input = ralloc(mem_ctx, VkPipelineVertexInputStateCreateInfo); + result = deep_copy_vertex_input_state(mem_ctx, vertex_input, + src->pVertexInputState); + if (result != VK_SUCCESS) + return result; + dst->pVertexInputState = vertex_input; + } else + dst->pVertexInputState = NULL; /* pInputAssemblyState */ LVP_PIPELINE_DUP(dst->pInputAssemblyState, diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index c2b3cb9aa48..46b84ff28cb 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -670,6 +670,7 @@ enum lvp_cmds { LVP_CMD_DRAW_INDIRECT_BYTE_COUNT, LVP_CMD_BEGIN_CONDITIONAL_RENDERING, LVP_CMD_END_CONDITIONAL_RENDERING, + LVP_CMD_SET_VERTEX_INPUT, LVP_CMD_SET_CULL_MODE, LVP_CMD_SET_FRONT_FACE, LVP_CMD_SET_PRIMITIVE_TOPOLOGY, @@ -1012,6 +1013,14 @@ struct lvp_cmd_begin_conditional_rendering { bool inverted; }; +struct lvp_cmd_set_vertex_input { + uint32_t binding_count; + uint32_t attr_count; + uint8_t data[0]; + //VkVertexInputBindingDescription2EXT bindings[binding_count]; + //VkVertexInputAttributeDescription2EXT attrs[attr_count]; +}; + struct lvp_cmd_set_cull_mode { VkCullModeFlags cull_mode; }; @@ -1099,6 +1108,7 @@ struct lvp_cmd_buffer_entry { struct lvp_cmd_end_transform_feedback end_transform_feedback; struct lvp_cmd_draw_indirect_byte_count draw_indirect_byte_count; struct lvp_cmd_begin_conditional_rendering begin_conditional_rendering; + struct lvp_cmd_set_vertex_input set_vertex_input; struct lvp_cmd_set_cull_mode set_cull_mode; struct lvp_cmd_set_front_face set_front_face; struct lvp_cmd_set_primitive_topology set_primitive_topology;