Mesa (staging/22.1): zink: Fix spirv stream 0 vertex emit for multistream shaders

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jul 28 16:40:29 UTC 2022


Module: Mesa
Branch: staging/22.1
Commit: bb9054a85a0ae1844613436e3968a2a89e57e019
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bb9054a85a0ae1844613436e3968a2a89e57e019

Author: SoroushIMG <soroush.kashani at imgtec.com>
Date:   Wed Jul 13 11:59:05 2022 +0100

zink: Fix spirv stream 0 vertex emit for multistream shaders

Spirv spec does not allow the use of OpEmitVertex or OpEndPrimitive when there are multiple streams.
Instead emit the multi-stream version of these with stream set to 0.
This issue was seen when testing cts case KHR-GL46.transform_feedback.draw_xfb_stream_test

Fixes: 35e346f4280 ("zink: handle vertex streams")
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17513>
(cherry picked from commit 3dfd8e4d7dde2dfb749c4d115e7f37e5965d460c)

---

 .pick_status.json                                     |  2 +-
 src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c  |  6 ++++--
 src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c | 12 ++++++------
 src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h |  4 ++--
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 2e120ab9e25..6141cd65b33 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -3928,7 +3928,7 @@
         "description": "zink: Fix spirv stream 0 vertex emit for multistream shaders",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": "35e346f42808428661d95a7b8df3a414661136bc"
     },
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 8ca2aaee174..cbd1d55493e 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
@@ -2903,7 +2903,8 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
        */
       if (ctx->sinfo)
          emit_so_outputs(ctx, ctx->sinfo);
-      spirv_builder_emit_vertex(&ctx->builder, nir_intrinsic_stream_id(intr));
+      spirv_builder_emit_vertex(&ctx->builder, nir_intrinsic_stream_id(intr),
+                                ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
       break;
 
    case nir_intrinsic_set_vertex_and_primitive_count:
@@ -2911,7 +2912,8 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
       break;
 
    case nir_intrinsic_end_primitive_with_counter:
-      spirv_builder_end_primitive(&ctx->builder, nir_intrinsic_stream_id(intr));
+      spirv_builder_end_primitive(&ctx->builder, nir_intrinsic_stream_id(intr),
+                                  ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
       break;
 
    case nir_intrinsic_load_helper_invocation:
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 7c072072305..4b3a4442bca 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
@@ -255,32 +255,32 @@ spirv_builder_emit_builtin(struct spirv_builder *b, SpvId target,
 }
 
 void
-spirv_builder_emit_vertex(struct spirv_builder *b, uint32_t stream)
+spirv_builder_emit_vertex(struct spirv_builder *b, uint32_t stream, bool multistream)
 {
    unsigned words = 1;
    SpvOp op = SpvOpEmitVertex;
-   if (stream > 0) {
+   if (multistream) {
       op = SpvOpEmitStreamVertex;
       words++;
    }
    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
    spirv_buffer_emit_word(&b->instructions, op | (words << 16));
-   if (stream)
+   if (multistream)
       spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, stream));
 }
 
 void
-spirv_builder_end_primitive(struct spirv_builder *b, uint32_t stream)
+spirv_builder_end_primitive(struct spirv_builder *b, uint32_t stream, bool multistream)
 {
    unsigned words = 1;
    SpvOp op = SpvOpEndPrimitive;
-   if (stream > 0) {
+   if (multistream || 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)
+   if (multistream || stream > 0)
       spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, stream));
 }
 
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 9c7faaf5c8b..01833ceb2df 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
+++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
@@ -460,7 +460,7 @@ spirv_builder_get_words(struct spirv_builder *b, uint32_t *words,
                         uint32_t *tcs_vertices_out_word);
 
 void
-spirv_builder_emit_vertex(struct spirv_builder *b, uint32_t stream);
+spirv_builder_emit_vertex(struct spirv_builder *b, uint32_t stream, bool multistream);
 void
-spirv_builder_end_primitive(struct spirv_builder *b, uint32_t stream);
+spirv_builder_end_primitive(struct spirv_builder *b, uint32_t stream, bool multistream);
 #endif



More information about the mesa-commit mailing list