Mesa (master): zink: basic primitive restart support for strip/fan topologies

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Aug 7 11:26:57 UTC 2020


Module: Mesa
Branch: master
Commit: 5edaf081cdbdadfd027c2ba9ee5095f49b274f81
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5edaf081cdbdadfd027c2ba9ee5095f49b274f81

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Wed Jul  1 15:57:43 2020 -0400

zink: basic primitive restart support for strip/fan topologies

this conditionally handles rewriting the index buffer to use vk-compatible
restart indexes and then enables it in the pipeline for supported draw
modes

fixes #3174

Reviewed-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5912>

---

 src/gallium/drivers/zink/zink_draw.c     | 35 +++++++++++++++++++++++---------
 src/gallium/drivers/zink/zink_pipeline.c | 15 +++++++++++++-
 src/gallium/drivers/zink/zink_pipeline.h |  2 ++
 3 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c
index a9d6bcbf08c..32a1ea2f94d 100644
--- a/src/gallium/drivers/zink/zink_draw.c
+++ b/src/gallium/drivers/zink/zink_draw.c
@@ -11,6 +11,7 @@
 #include "util/u_helpers.h"
 #include "util/u_inlines.h"
 #include "util/u_prim.h"
+#include "util/u_prim_restart.h"
 
 static VkDescriptorSet
 allocate_descriptor_set(struct zink_screen *screen,
@@ -206,6 +207,7 @@ zink_draw_vbo(struct pipe_context *pctx,
    struct zink_so_target *so_target = zink_so_target(dinfo->count_from_stream_output);
    VkBuffer counter_buffers[PIPE_MAX_SO_OUTPUTS];
    VkDeviceSize counter_buffer_offsets[PIPE_MAX_SO_OUTPUTS] = {};
+   bool need_index_buffer_unref = false;
 
    if (dinfo->mode >= PIPE_PRIM_QUADS ||
        dinfo->mode == PIPE_PRIM_LINE_LOOP ||
@@ -222,6 +224,9 @@ zink_draw_vbo(struct pipe_context *pctx,
    if (!gfx_program)
       return;
 
+   /* this is broken for anything requiring primconvert atm */
+   ctx->gfx_pipeline_state.primitive_restart = !!dinfo->primitive_restart;
+
    VkPipeline pipeline = zink_get_gfx_pipeline(screen, gfx_program,
                                                &ctx->gfx_pipeline_state,
                                                dinfo->mode);
@@ -249,13 +254,19 @@ zink_draw_vbo(struct pipe_context *pctx,
    unsigned index_offset = 0;
    struct pipe_resource *index_buffer = NULL;
    if (dinfo->index_size > 0) {
-      if (dinfo->has_user_indices) {
-         if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset, 4)) {
-            debug_printf("util_upload_index_buffer() failed\n");
-            return;
-         }
-      } else
-         index_buffer = dinfo->index.resource;
+       uint32_t restart_index = util_prim_restart_index_from_size(dinfo->index_size);
+       if ((dinfo->primitive_restart && (dinfo->restart_index != restart_index))) {
+          util_translate_prim_restart_ib(pctx, dinfo, &index_buffer);
+          need_index_buffer_unref = true;
+       } else {
+          if (dinfo->has_user_indices) {
+             if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset, 4)) {
+                debug_printf("util_upload_index_buffer() failed\n");
+                return;
+             }
+          } else
+             index_buffer = dinfo->index.resource;
+       }
    }
 
    VkWriteDescriptorSet wds[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS + PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS];
@@ -424,7 +435,11 @@ zink_draw_vbo(struct pipe_context *pctx,
 
    if (dinfo->index_size > 0) {
       VkIndexType index_type;
-      switch (dinfo->index_size) {
+      unsigned index_size = dinfo->index_size;
+      if (need_index_buffer_unref)
+         /* index buffer will have been promoted from uint8 to uint16 in this case */
+         index_size = MAX2(index_size, 2);
+      switch (index_size) {
       case 1:
          assert(screen->have_EXT_index_type_uint8);
          index_type = VK_INDEX_TYPE_UINT8_EXT;
@@ -443,7 +458,7 @@ zink_draw_vbo(struct pipe_context *pctx,
       zink_batch_reference_resoure(batch, res);
       vkCmdDrawIndexed(batch->cmdbuf,
          dinfo->count, dinfo->instance_count,
-         dinfo->start, dinfo->index_bias, dinfo->start_instance);
+         need_index_buffer_unref ? 0 : dinfo->start, dinfo->index_bias, dinfo->start_instance);
    } else {
       if (so_target && screen->tf_props.transformFeedbackDraw) {
          zink_batch_reference_resoure(batch, zink_resource(so_target->counter_buffer));
@@ -455,7 +470,7 @@ zink_draw_vbo(struct pipe_context *pctx,
          vkCmdDraw(batch->cmdbuf, dinfo->count, dinfo->instance_count, dinfo->start, dinfo->start_instance);
    }
 
-   if (dinfo->index_size > 0 && dinfo->has_user_indices)
+   if (dinfo->index_size > 0 && (dinfo->has_user_indices || need_index_buffer_unref))
       pipe_resource_reference(&index_buffer, NULL);
 
    if (ctx->num_so_targets) {
diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c
index 261bdde5201..70f859fdd3f 100644
--- a/src/gallium/drivers/zink/zink_pipeline.c
+++ b/src/gallium/drivers/zink/zink_pipeline.c
@@ -49,7 +49,20 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
    VkPipelineInputAssemblyStateCreateInfo primitive_state = {};
    primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    primitive_state.topology = primitive_topology;
-   primitive_state.primitiveRestartEnable = VK_FALSE;
+   switch (primitive_topology) {
+   case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
+   case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
+   case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
+   case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
+   case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
+   case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
+      if (state->primitive_restart)
+         debug_printf("restart_index set with unsupported primitive topology %u\n", primitive_topology);
+      primitive_state.primitiveRestartEnable = VK_FALSE;
+      break;
+   default:
+      primitive_state.primitiveRestartEnable = state->primitive_restart ? VK_TRUE : VK_FALSE;
+   }
 
    VkPipelineColorBlendStateCreateInfo blend_state = {};
    blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
diff --git a/src/gallium/drivers/zink/zink_pipeline.h b/src/gallium/drivers/zink/zink_pipeline.h
index d65bce21ffb..757bae6266f 100644
--- a/src/gallium/drivers/zink/zink_pipeline.h
+++ b/src/gallium/drivers/zink/zink_pipeline.h
@@ -51,6 +51,8 @@ struct zink_gfx_pipeline_state {
 
    VkSampleMask sample_mask;
    uint8_t rast_samples;
+
+   bool primitive_restart;
 };
 
 VkPipeline



More information about the mesa-commit mailing list