mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
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: 35e346f428 ("zink: handle vertex streams")
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17513>
This commit is contained in:
parent
9ecc26ff27
commit
3dfd8e4d7d
3 changed files with 12 additions and 10 deletions
|
|
@ -3060,7 +3060,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:
|
||||
|
|
@ -3068,7 +3069,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:
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue