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 bb5fd690b3e..2fee513f150 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 @@ -1184,7 +1184,8 @@ get_output_type(struct ntv_context *ctx, unsigned register_index, unsigned num_c /* for streamout create new outputs, as streamout can be done on individual components, from complete outputs, so we just can't use the created packed outputs */ static void -emit_so_info(struct ntv_context *ctx, const struct zink_so_info *so_info) +emit_so_info(struct ntv_context *ctx, const struct zink_so_info *so_info, + unsigned first_so) { unsigned output = 0; for (unsigned i = 0; i < so_info->so_info.num_outputs; i++) { @@ -1210,7 +1211,7 @@ emit_so_info(struct ntv_context *ctx, const struct zink_so_info *so_info) * so we need to ensure that the new xfb location slot doesn't conflict with any previously-emitted * outputs. */ - uint32_t location = ctx->shader_slots_reserved + output; + uint32_t location = first_so + i; assert(location < VARYING_SLOT_VAR0 && ctx->shader_slot_map[location] == SLOT_UNSET); spirv_builder_emit_location(&ctx->builder, var_id, location); @@ -3618,12 +3619,20 @@ nir_to_spirv(struct nir_shader *s, const struct zink_so_info *so_info, nir_foreach_shader_in_variable(var, s) emit_input(&ctx, var); - nir_foreach_shader_out_variable(var, s) + int max_output = -1; + nir_foreach_shader_out_variable(var, s) { + /* ignore SPIR-V built-ins, tagged with a sentinel value */ + if (var->data.driver_location != UINT_MAX) { + assert(var->data.driver_location < INT_MAX); + max_output = MAX2(max_output, (int)var->data.driver_location); + } emit_output(&ctx, var); + } if (so_info) - emit_so_info(&ctx, so_info); + emit_so_info(&ctx, so_info, max_output + 1); + /* we have to reverse iterate to match what's done in zink_compiler.c */ foreach_list_typed_reverse(nir_variable, var, node, &s->variables) if (_nir_shader_variable_has_mode(var, nir_var_uniform | diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 859c01b4f0f..82c96036dcc 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -483,7 +483,8 @@ assign_io_locations(nir_shader *nir, unsigned char *shader_slot_map, case VARYING_SLOT_FACE: case VARYING_SLOT_TESS_LEVEL_OUTER: case VARYING_SLOT_TESS_LEVEL_INNER: - /* SPIR-V builtins, nothing to do */ + /* use a sentinel value to avoid counting later */ + var->data.driver_location = UINT_MAX; break; default: