zink: pre-populate locations in variables

These locations should match what we get out of the pre-existing pass,
and are currently unused. They will be used in a later commit in this
series, but is left like this because this code is fairly fragile.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9836>
This commit is contained in:
Erik Faye-Lund 2021-02-04 16:11:00 +01:00 committed by Marge Bot
parent 904b5eb2af
commit 2d98efd323
2 changed files with 62 additions and 0 deletions

View File

@ -495,6 +495,7 @@ emit_input(struct ntv_context *ctx, struct nir_variable *var)
default:
slot = handle_slot(ctx, slot, glsl_count_vec4_slots(var->type, false, false));
assert(var->data.driver_location == slot);
spirv_builder_emit_location(&ctx->builder, var_id, slot);
}
if (var->data.centroid)
@ -521,6 +522,7 @@ emit_input(struct ntv_context *ctx, struct nir_variable *var)
default:
slot = handle_handle_slot(ctx, var, false);
assert(var->data.driver_location == slot);
spirv_builder_emit_location(&ctx->builder, var_id, slot);
}
}
@ -571,6 +573,7 @@ emit_output(struct ntv_context *ctx, struct nir_variable *var)
default:
slot = handle_handle_slot(ctx, var, true);
assert(var->data.driver_location == slot);
spirv_builder_emit_location(&ctx->builder, var_id, slot);
}
/* tcs can't do xfb */

View File

@ -454,6 +454,62 @@ update_so_info(struct zink_shader *zs, const struct pipe_stream_output_info *so_
zs->streamout.have_xfb = !!zs->streamout.so_info.num_outputs;
}
static void
assign_io_locations(nir_shader *nir, unsigned char *shader_slot_map,
unsigned char *shader_slots_reserved)
{
unsigned reserved = 0;
unsigned char slot_map[VARYING_SLOT_MAX];
if (shader_slots_reserved) {
reserved = *shader_slots_reserved;
memcpy(slot_map, shader_slot_map, sizeof(slot_map));
}
nir_foreach_variable_with_modes(var, nir, nir_var_shader_in | nir_var_shader_out) {
if ((nir->info.stage == MESA_SHADER_VERTEX && var->data.mode == nir_var_shader_in) ||
(nir->info.stage == MESA_SHADER_FRAGMENT && var->data.mode == nir_var_shader_out))
continue;
unsigned slot = var->data.location;
switch (var->data.location) {
case VARYING_SLOT_POS:
case VARYING_SLOT_PNTC:
case VARYING_SLOT_PSIZ:
case VARYING_SLOT_LAYER:
case VARYING_SLOT_PRIMITIVE_ID:
case VARYING_SLOT_CLIP_DIST0:
case VARYING_SLOT_CULL_DIST0:
case VARYING_SLOT_VIEWPORT:
case VARYING_SLOT_FACE:
case VARYING_SLOT_TESS_LEVEL_OUTER:
case VARYING_SLOT_TESS_LEVEL_INNER:
/* SPIR-V builtins, nothing to do */
break;
default:
if (var->data.patch) {
assert(var->data.location >= VARYING_SLOT_PATCH0);
slot = var->data.location - VARYING_SLOT_PATCH0;
} else if ((var->data.mode == nir_var_shader_out &&
nir->info.stage == MESA_SHADER_TESS_CTRL) ||
(var->data.mode != nir_var_shader_out &&
nir->info.stage == MESA_SHADER_TESS_EVAL)) {
assert(var->data.location >= VARYING_SLOT_VAR0);
slot = var->data.location - VARYING_SLOT_VAR0;
} else {
if (slot_map[var->data.location] == 0xff) {
assert(reserved < MAX_VARYING);
slot_map[var->data.location] = reserved;
reserved += glsl_count_vec4_slots(var->type, false, false);
}
slot = slot_map[var->data.location];
assert(slot < MAX_VARYING);
}
var->data.driver_location = slot;
}
}
}
VkShaderModule
zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, struct zink_shader_key *key,
unsigned char *shader_slot_map, unsigned char *shader_slots_reserved)
@ -505,6 +561,9 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, struct z
}
}
NIR_PASS_V(nir, nir_convert_from_ssa, true);
assign_io_locations(nir, shader_slot_map, shader_slots_reserved);
struct spirv_shader *spirv = nir_to_spirv(nir, streamout, shader_slot_map, shader_slots_reserved);
if (!spirv)
goto done;