Mesa (main): lavapipe: implement EXT_vertex_input_dynamic_state

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jul 1 00:48:06 UTC 2021


Module: Mesa
Branch: main
Commit: 5951d2abacd3b42e5d9f5694ea5ae3f3c545aa96
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5951d2abacd3b42e5d9f5694ea5ae3f3c545aa96

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri May 28 16:19:20 2021 -0400

lavapipe: implement EXT_vertex_input_dynamic_state

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11231>

---

 docs/relnotes/new_features.txt                  |  1 +
 src/gallium/frontends/lavapipe/lvp_cmd_buffer.c | 23 +++++++++++++
 src/gallium/frontends/lavapipe/lvp_device.c     |  8 +++++
 src/gallium/frontends/lavapipe/lvp_execute.c    | 44 ++++++++++++++++++++++++-
 src/gallium/frontends/lavapipe/lvp_pipeline.c   | 15 +++++----
 src/gallium/frontends/lavapipe/lvp_private.h    | 10 ++++++
 6 files changed, 94 insertions(+), 7 deletions(-)

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;



More information about the mesa-commit mailing list