Mesa (main): lavapipe: implement multidraw ext

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 24 01:48:07 UTC 2021


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Thu Mar 25 14:06:41 2021 -0400

lavapipe: implement multidraw ext

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

---

 src/gallium/frontends/lavapipe/lvp_cmd_buffer.c | 66 +++++++++++++++++++++++++
 src/gallium/frontends/lavapipe/lvp_device.c     | 11 +++++
 src/gallium/frontends/lavapipe/lvp_execute.c    |  1 +
 src/gallium/frontends/lavapipe/lvp_private.h    |  1 +
 4 files changed, 79 insertions(+)

diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
index aac580fc443..39148241248 100644
--- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
+++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
@@ -498,6 +498,36 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdDraw(
    cmd_buf_queue(cmd_buffer, cmd);
 }
 
+VKAPI_ATTR void VKAPI_CALL lvp_CmdDrawMultiEXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    drawCount,
+    const VkMultiDrawInfoEXT                   *pVertexInfo,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstInstance,
+    uint32_t                                    stride)
+{
+   LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+   struct lvp_cmd_buffer_entry *cmd;
+
+   uint32_t cmd_size = drawCount * sizeof(struct pipe_draw_start_count_bias);
+   cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_DRAW);
+   if (!cmd)
+      return;
+
+   cmd->u.draw.instance_count = instanceCount;
+   cmd->u.draw.first_instance = firstInstance;
+   cmd->u.draw.draw_count = drawCount;
+   if (stride == sizeof(struct pipe_draw_start_count_bias))
+      memcpy(cmd->u.draw.draws, pVertexInfo, cmd_size);
+   else {
+      unsigned i = 0;
+      vk_foreach_multi_draw(draw, i, pVertexInfo, drawCount, stride)
+         memcpy(cmd->u.draw.draws, draw, sizeof(struct pipe_draw_start_count_bias));
+   }
+
+   cmd_buf_queue(cmd_buffer, cmd);
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_CmdEndRenderPass2(
    VkCommandBuffer                             commandBuffer,
    const VkSubpassEndInfo*                     pSubpassEndInfo)
@@ -752,6 +782,42 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdDrawIndexed(
    cmd_buf_queue(cmd_buffer, cmd);
 }
 
+VKAPI_ATTR void VKAPI_CALL lvp_CmdDrawMultiIndexedEXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    drawCount,
+    const VkMultiDrawIndexedInfoEXT            *pIndexInfo,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstInstance,
+    uint32_t                                    stride,
+    const int32_t                              *pVertexOffset)
+{
+   LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+   struct lvp_cmd_buffer_entry *cmd;
+
+   uint32_t cmd_size = drawCount * sizeof(struct pipe_draw_start_count_bias);
+   cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_DRAW_INDEXED);
+   if (!cmd)
+      return;
+
+   cmd->u.draw_indexed.instance_count = instanceCount;
+   cmd->u.draw_indexed.first_instance = firstInstance;
+   cmd->u.draw_indexed.draw_count = drawCount;
+   cmd->u.draw_indexed.vertex_offset_changes = !pVertexOffset;
+   if (stride == sizeof(struct pipe_draw_start_count_bias))
+      memcpy(cmd->u.draw_indexed.draws, pIndexInfo, cmd_size);
+   else {
+      unsigned i = 0;
+      vk_foreach_multi_draw_indexed(draw, i, pIndexInfo, drawCount, stride)
+         memcpy(cmd->u.draw_indexed.draws, draw, sizeof(struct pipe_draw_start_count_bias));
+   }
+   /* only the first member is read if vertex_offset_changes is true */
+   if (pVertexOffset)
+      cmd->u.draw_indexed.draws[0].index_bias = *pVertexOffset;
+   cmd->u.draw_indexed.calc_start = true;
+
+   cmd_buf_queue(cmd_buffer, cmd);
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_CmdDrawIndirect(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    _buffer,
diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c
index 7b6859507a4..33f3f30043b 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -128,6 +128,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported =
    .EXT_extended_dynamic_state            = true,
    .EXT_host_query_reset                  = true,
    .EXT_index_type_uint8                  = true,
+   .EXT_multi_draw                        = true,
    .EXT_post_depth_coverage               = true,
    .EXT_private_data                      = true,
    .EXT_sampler_filter_minmax             = true,
@@ -644,6 +645,11 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(
          features->transformFeedbackPreservesProvokingVertex = true;
          break;
       }
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT: {
+         VkPhysicalDeviceMultiDrawFeaturesEXT *features = (VkPhysicalDeviceMultiDrawFeaturesEXT *)ext;
+         features->multiDraw = true;
+         break;
+      }
       default:
          break;
       }
@@ -968,6 +974,11 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties2(
          properties->transformFeedbackPreservesTriangleFanProvokingVertex = true;
          break;
       }
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: {
+         VkPhysicalDeviceMultiDrawPropertiesEXT *props = (VkPhysicalDeviceMultiDrawPropertiesEXT *)ext;
+         props->maxMultiDrawCount = 2048;
+         break;
+      }
       default:
          break;
       }
diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c
index 6987a43a8c8..4a119c09f19 100644
--- a/src/gallium/frontends/lavapipe/lvp_execute.c
+++ b/src/gallium/frontends/lavapipe/lvp_execute.c
@@ -2127,6 +2127,7 @@ static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd,
          cmd->u.draw_indexed.draws[i].start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.draws[i].start;
       cmd->u.draw_indexed.calc_start = false;
    }
+   state->info.index_bias_varies = cmd->u.draw_indexed.vertex_offset_changes;
    state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, cmd->u.draw_indexed.draws, cmd->u.draw_indexed.draw_count);
 }
 
diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h
index 86004ba4be6..e3aeab01cc0 100644
--- a/src/gallium/frontends/lavapipe/lvp_private.h
+++ b/src/gallium/frontends/lavapipe/lvp_private.h
@@ -755,6 +755,7 @@ struct lvp_cmd_draw_indexed {
    uint32_t first_instance;
    bool calc_start;
    uint32_t draw_count;
+   bool vertex_offset_changes;
    struct pipe_draw_start_count_bias draws[0];
 };
 



More information about the mesa-commit mailing list