Mesa (master): zink: handle vertex streams

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jan 5 13:36:05 UTC 2021


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Thu Jul 30 14:11:21 2020 -0400

zink: handle vertex streams

we already support all this, it's just a matter of slapping on some Stream
decoration flex tape

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

---

 .../drivers/zink/nir_to_spirv/nir_to_spirv.c       |  6 ++--
 .../drivers/zink/nir_to_spirv/spirv_builder.c      | 35 ++++++++++++++++++----
 .../drivers/zink/nir_to_spirv/spirv_builder.h      |  7 +++--
 src/gallium/drivers/zink/zink_screen.c             |  3 ++
 4 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
index 9d709e38a35..e003ce2c992 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
@@ -949,6 +949,8 @@ emit_so_info(struct ntv_context *ctx, const struct zink_so_info *so_info)
       spirv_builder_emit_offset(&ctx->builder, var_id, (so_output.dst_offset * 4));
       spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, so_output.output_buffer);
       spirv_builder_emit_xfb_stride(&ctx->builder, var_id, so_info->so_info.stride[so_output.output_buffer] * 4);
+      if (so_output.stream)
+         spirv_builder_emit_stream(&ctx->builder, var_id, so_output.stream);
 
       /* output location is incremented by VARYING_SLOT_VAR0 for non-builtins in vtn,
        * so we need to ensure that the new xfb location slot doesn't conflict with any previously-emitted
@@ -2056,7 +2058,7 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
        */
       if (ctx->so_info)
          emit_so_outputs(ctx, ctx->so_info);
-      spirv_builder_emit_vertex(&ctx->builder);
+      spirv_builder_emit_vertex(&ctx->builder, nir_intrinsic_stream_id(intr));
       break;
 
    case nir_intrinsic_set_vertex_and_primitive_count:
@@ -2064,7 +2066,7 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
       break;
 
    case nir_intrinsic_end_primitive_with_counter:
-      spirv_builder_end_primitive(&ctx->builder);
+      spirv_builder_end_primitive(&ctx->builder, nir_intrinsic_stream_id(intr));
       break;
 
    case nir_intrinsic_load_patch_vertices_in:
diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
index e384e945884..505423b0883 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
@@ -227,17 +227,33 @@ spirv_builder_emit_builtin(struct spirv_builder *b, SpvId target,
 }
 
 void
-spirv_builder_emit_vertex(struct spirv_builder *b)
+spirv_builder_emit_vertex(struct spirv_builder *b, uint32_t stream)
 {
-   spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
-   spirv_buffer_emit_word(&b->instructions, SpvOpEmitVertex | (1 << 16));
+   unsigned words = 1;
+   SpvOp op = SpvOpEmitVertex;
+   if (stream > 0) {
+      op = SpvOpEmitStreamVertex;
+      words++;
+   }
+   spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
+   spirv_buffer_emit_word(&b->instructions, op | (words << 16));
+   if (stream)
+      spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, stream));
 }
 
 void
-spirv_builder_end_primitive(struct spirv_builder *b)
+spirv_builder_end_primitive(struct spirv_builder *b, uint32_t stream)
 {
-   spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
-   spirv_buffer_emit_word(&b->instructions, SpvOpEndPrimitive | (1 << 16));
+   unsigned words = 1;
+   SpvOp op = SpvOpEndPrimitive;
+   if (stream > 0) {
+      op = SpvOpEndStreamPrimitive;
+      words++;
+   }
+   spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
+   spirv_buffer_emit_word(&b->instructions, op | (words << 16));
+   if (stream)
+      spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, stream));
 }
 
 void
@@ -296,6 +312,13 @@ spirv_builder_emit_index(struct spirv_builder *b, SpvId target, int index)
    emit_decoration(b, target, SpvDecorationIndex, args, ARRAY_SIZE(args));
 }
 
+void
+spirv_builder_emit_stream(struct spirv_builder *b, SpvId target, int stream)
+{
+   uint32_t args[] = { stream };
+   emit_decoration(b, target, SpvDecorationStream, args, ARRAY_SIZE(args));
+}
+
 static void
 emit_member_decoration(struct spirv_builder *b, SpvId target, uint32_t member,
                        SpvDecoration decoration, const uint32_t extra_operands[],
diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
index 6bcc650c83d..f3c8d5b4eb1 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
+++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
@@ -104,6 +104,9 @@ spirv_builder_emit_builtin(struct spirv_builder *b, SpvId target,
 void
 spirv_builder_emit_index(struct spirv_builder *b, SpvId target, int index);
 
+void
+spirv_builder_emit_stream(struct spirv_builder *b, SpvId target, int stream);
+
 void
 spirv_builder_emit_descriptor_set(struct spirv_builder *b, SpvId target,
                                   uint32_t descriptor_set);
@@ -381,7 +384,7 @@ spirv_builder_get_words(struct spirv_builder *b, uint32_t *words,
                         size_t num_words);
 
 void
-spirv_builder_emit_vertex(struct spirv_builder *b);
+spirv_builder_emit_vertex(struct spirv_builder *b, uint32_t stream);
 void
-spirv_builder_end_primitive(struct spirv_builder *b);
+spirv_builder_end_primitive(struct spirv_builder *b, uint32_t stream);
 #endif
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index 879e8e2490d..1aebd53744a 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -117,6 +117,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
       return screen->info.have_EXT_vertex_attribute_divisor;
 
+   case PIPE_CAP_MAX_VERTEX_STREAMS:
+      return screen->info.tf_props.maxTransformFeedbackStreams;
+
    case PIPE_CAP_INT64:
    case PIPE_CAP_INT64_DIVMOD:
    case PIPE_CAP_DOUBLES:



More information about the mesa-commit mailing list