diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 407c72252f8..a7c5ba72032 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -903,7 +903,8 @@ lower_64bit_pack(nir_shader *shader) nir_shader * zink_create_quads_emulation_gs(const nir_shader_compiler_options *options, - const nir_shader *prev_stage) + const nir_shader *prev_stage, + int last_pv_vert_offset) { nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY, options, @@ -959,17 +960,24 @@ zink_create_quads_emulation_gs(const nir_shader_compiler_options *options, out_vars[num_vars++] = out; } - int mapping[] = {0, 1, 2, 0, 2, 3}; + int mapping_first[] = {0, 1, 2, 0, 2, 3}; + int mapping_last[] = {0, 1, 3, 1, 2, 3}; + nir_ssa_def *last_pv_vert_def = nir_load_ubo(&b, 1, 32, + nir_imm_int(&b, 0), nir_imm_int(&b, last_pv_vert_offset), + .align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0); + last_pv_vert_def = nir_ine_imm(&b, last_pv_vert_def, 0); for (unsigned i = 0; i < 6; ++i) { /* swap indices 2 and 3 */ - int idx = mapping[i]; + nir_ssa_def *idx = nir_bcsel(&b, last_pv_vert_def, + nir_imm_int(&b, mapping_last[i]), + nir_imm_int(&b, mapping_first[i])); /* Copy inputs to outputs. */ for (unsigned j = 0; j < num_vars; ++j) { if (in_vars[j]->data.location == VARYING_SLOT_EDGE) { continue; } /* no need to use copy_var to save a lower pass */ - nir_ssa_def *value = nir_load_array_var_imm(&b, in_vars[j], idx); + nir_ssa_def *value = nir_load_array_var(&b, in_vars[j], idx); nir_store_var(&b, out_vars[j], value, (1u << value->num_components) - 1); } diff --git a/src/gallium/drivers/zink/zink_compiler.h b/src/gallium/drivers/zink/zink_compiler.h index 97fc5dd75b9..31c2d9bf855 100644 --- a/src/gallium/drivers/zink/zink_compiler.h +++ b/src/gallium/drivers/zink/zink_compiler.h @@ -58,7 +58,8 @@ zink_tgsi_to_nir(struct pipe_screen *screen, const struct tgsi_token *tokens); nir_shader* zink_create_quads_emulation_gs(const nir_shader_compiler_options *options, - const nir_shader *prev_stage); + const nir_shader *prev_stage, + int last_pv_vert_offset); void zink_screen_init_compiler(struct zink_screen *screen); diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 4e8cd897bbd..5f0f10aadd6 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -2308,7 +2308,8 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) if (lower_filled_quad) { nir = zink_create_quads_emulation_gs( &screen->nir_options, - ctx->gfx_stages[prev_vertex_stage]->nir); + ctx->gfx_stages[prev_vertex_stage]->nir, + ZINK_INLINE_VAL_PV_LAST_VERT * 4); } else { nir = nir_create_passthrough_gs( &screen->nir_options, @@ -2371,7 +2372,8 @@ zink_create_primitive_emulation_gs(struct zink_context *ctx) if (lower_filled_quad) { nir = zink_create_quads_emulation_gs( &screen->nir_options, - ctx->gfx_stages[prev_vertex_stage]->nir); + ctx->gfx_stages[prev_vertex_stage]->nir, + ZINK_INLINE_VAL_PV_LAST_VERT * 4); } else { nir = nir_create_passthrough_gs( &screen->nir_options,