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