microsoft/compiler: Put holes in driver_location based on I/O variable sizes
DXIL requires that each I/O variable has a unique semantic name, but when dealing with semantics that take up multiple slots, that variable implicitly takes up multiple names. So when assigning driver_location, we need to do the same. That means also updating outputs and patch constants to have a mapping from driver_location to a compacted index, since the metadata arrays *can't* have holes. This would be simpler if we could hang it off the nir_variable but there's not really any free fields to be able to do that. We only need this compacted mapping inside the DXIL backend anyway so we can just store the array in the module. Tested-by: Benjamin Otte <otte@gnome.org> Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/12128 Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32047>
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
spec@arb_gpu_shader_int64@execution@indirect-array-two-accesses,Fail
|
||||
spec@arb_separate_shader_objects@execution@layout-location-block-with-struct-member,Crash
|
||||
spec@arb_separate_shader_objects@execution@layout-location-struct-mixed-with-implicitly-assigned-varying,Crash
|
||||
spec@arb_shader_texture_lod@execution@glsl-fs-shadow2dgradarb-07,Fail
|
||||
spec@arb_shader_texture_lod@execution@glsl-fs-shadow2dgradarb-cumulative,Fail
|
||||
spec@arb_tessellation_shader@execution@gs-primitiveid-instanced,Fail
|
||||
|
||||
@@ -218,7 +218,9 @@ struct dxil_module {
|
||||
* should be allocated dynamically based on on the maximum
|
||||
* driver_location across all input vars.
|
||||
*/
|
||||
unsigned input_mappings[DXIL_SHADER_MAX_IO_ROWS * 4];
|
||||
uint8_t input_mappings[DXIL_SHADER_MAX_IO_ROWS * 4];
|
||||
uint8_t output_mappings[DXIL_SHADER_MAX_IO_ROWS * 4];
|
||||
uint8_t patch_mappings[DXIL_SHADER_MAX_IO_ROWS * 4];
|
||||
|
||||
struct dxil_psv_signature_element psv_inputs[DXIL_SHADER_MAX_IO_ROWS];
|
||||
struct dxil_psv_signature_element psv_outputs[DXIL_SHADER_MAX_IO_ROWS];
|
||||
|
||||
@@ -1621,8 +1621,13 @@ dxil_reassign_driver_locations(nir_shader* s, nir_variable_mode modes,
|
||||
unsigned driver_loc = 0, driver_patch_loc = 0;
|
||||
nir_foreach_variable_with_modes(var, s, modes) {
|
||||
/* Overlap patches with non-patch */
|
||||
var->data.driver_location = var->data.patch ?
|
||||
driver_patch_loc++ : driver_loc++;
|
||||
unsigned *loc = var->data.patch ? &driver_patch_loc : &driver_loc;
|
||||
var->data.driver_location = *loc;
|
||||
|
||||
const struct glsl_type *type = var->type;
|
||||
if (nir_is_arrayed_io(var, s->info.stage) && glsl_type_is_array(type))
|
||||
type = glsl_get_array_element(type);
|
||||
*loc += glsl_count_vec4_slots(type, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2324,7 +2329,7 @@ set_input_bits(struct dxil_module *mod, nir_intrinsic_instr *intr, BITSET_WORD *
|
||||
nir_src *row_src = intr->intrinsic == nir_intrinsic_load_per_vertex_input ? &intr->src[1] : &intr->src[0];
|
||||
bool is_patch_constant = mod->shader_kind == DXIL_DOMAIN_SHADER && intr->intrinsic == nir_intrinsic_load_input;
|
||||
const struct dxil_signature_record *sig_rec = is_patch_constant ?
|
||||
&mod->patch_consts[nir_intrinsic_base(intr)] :
|
||||
&mod->patch_consts[mod->patch_mappings[nir_intrinsic_base(intr)]] :
|
||||
&mod->inputs[mod->input_mappings[nir_intrinsic_base(intr)]];
|
||||
if (is_patch_constant) {
|
||||
/* Redirect to the second I/O table */
|
||||
@@ -2356,8 +2361,8 @@ set_output_bits(struct dxil_module *mod, nir_intrinsic_instr *intr, BITSET_WORD
|
||||
nir_src *row_src = intr->intrinsic == nir_intrinsic_store_per_vertex_output ? &intr->src[2] : &intr->src[1];
|
||||
bool is_patch_constant = mod->shader_kind == DXIL_HULL_SHADER && intr->intrinsic == nir_intrinsic_store_output;
|
||||
const struct dxil_signature_record *sig_rec = is_patch_constant ?
|
||||
&mod->patch_consts[nir_intrinsic_base(intr)] :
|
||||
&mod->outputs[nir_intrinsic_base(intr)];
|
||||
&mod->patch_consts[mod->patch_mappings[nir_intrinsic_base(intr)]] :
|
||||
&mod->outputs[mod->output_mappings[nir_intrinsic_base(intr)]];
|
||||
for (uint32_t component = 0; component < intr->num_components; ++component) {
|
||||
uint32_t base_element = 0;
|
||||
uint32_t num_elements = sig_rec->num_elements;
|
||||
|
||||
@@ -669,7 +669,7 @@ process_output_signature(struct dxil_module *mod, nir_shader *s)
|
||||
base_var->data.stream == var->data.stream)
|
||||
/* Combine fractional vars into any already existing row */
|
||||
get_additional_semantic_info(s, var, &semantic,
|
||||
mod->psv_outputs[base_var->data.driver_location].start_row,
|
||||
mod->psv_outputs[mod->output_mappings[base_var->data.driver_location]].start_row,
|
||||
s->info.clip_distance_array_size);
|
||||
else
|
||||
next_row = get_additional_semantic_info(s, var, &semantic, next_row, s->info.clip_distance_array_size);
|
||||
@@ -677,6 +677,7 @@ process_output_signature(struct dxil_module *mod, nir_shader *s)
|
||||
mod->info.has_out_position |= semantic.kind== DXIL_SEM_POSITION;
|
||||
mod->info.has_out_depth |= semantic.kind == DXIL_SEM_DEPTH;
|
||||
|
||||
mod->output_mappings[var->data.driver_location] = num_outputs;
|
||||
struct dxil_psv_signature_element *psv_elm = &mod->psv_outputs[num_outputs];
|
||||
|
||||
if (!fill_io_signature(mod, num_outputs, &semantic,
|
||||
@@ -752,8 +753,18 @@ process_patch_const_signature(struct dxil_module *mod, nir_shader *s)
|
||||
get_semantic_name(var, &semantic, type);
|
||||
|
||||
mod->patch_consts[num_consts].sysvalue = patch_sysvalue_name(var);
|
||||
next_row = get_additional_semantic_info(s, var, &semantic, next_row, 0);
|
||||
nir_variable *base_var = var;
|
||||
if (var->data.location_frac)
|
||||
base_var = nir_find_variable_with_location(s, mode, var->data.location);
|
||||
if (base_var != var)
|
||||
/* Combine fractional vars into any already existing row */
|
||||
get_additional_semantic_info(s, var, &semantic,
|
||||
mod->psv_patch_consts[mod->patch_mappings[base_var->data.driver_location]].start_row,
|
||||
0);
|
||||
else
|
||||
next_row = get_additional_semantic_info(s, var, &semantic, next_row, 0);
|
||||
|
||||
mod->patch_mappings[var->data.driver_location] = num_consts;
|
||||
struct dxil_psv_signature_element *psv_elm = &mod->psv_patch_consts[num_consts];
|
||||
|
||||
if (!fill_io_signature(mod, num_consts, &semantic,
|
||||
|
||||
@@ -3589,7 +3589,9 @@ emit_store_output_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *in
|
||||
|
||||
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, is_patch_constant ?
|
||||
DXIL_INTR_STORE_PATCH_CONSTANT : DXIL_INTR_STORE_OUTPUT);
|
||||
const struct dxil_value *output_id = dxil_module_get_int32_const(&ctx->mod, nir_intrinsic_base(intr));
|
||||
uint8_t *io_mappings = is_patch_constant ? ctx->mod.patch_mappings : ctx->mod.output_mappings;
|
||||
uint8_t io_index = io_mappings[nir_intrinsic_base(intr)];
|
||||
const struct dxil_value *output_id = dxil_module_get_int32_const(&ctx->mod, io_index);
|
||||
unsigned row_index = intr->intrinsic == nir_intrinsic_store_output ? 1 : 2;
|
||||
|
||||
/* NIR has these as 1 row, N cols, but DXIL wants them as N rows, 1 col. We muck with these in the signature
|
||||
@@ -3616,8 +3618,8 @@ emit_store_output_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *in
|
||||
|
||||
if (ctx->mod.minor_validator >= 5) {
|
||||
struct dxil_signature_record *sig_rec = is_patch_constant ?
|
||||
&ctx->mod.patch_consts[nir_intrinsic_base(intr)] :
|
||||
&ctx->mod.outputs[nir_intrinsic_base(intr)];
|
||||
&ctx->mod.patch_consts[io_index] :
|
||||
&ctx->mod.outputs[io_index];
|
||||
unsigned comp_size = intr->src[0].ssa->bit_size == 64 ? 2 : 1;
|
||||
unsigned comp_mask = 0;
|
||||
if (is_tess_level)
|
||||
@@ -3634,8 +3636,8 @@ emit_store_output_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *in
|
||||
|
||||
if (!nir_src_is_const(intr->src[row_index])) {
|
||||
struct dxil_psv_signature_element *psv_rec = is_patch_constant ?
|
||||
&ctx->mod.psv_patch_consts[nir_intrinsic_base(intr)] :
|
||||
&ctx->mod.psv_outputs[nir_intrinsic_base(intr)];
|
||||
&ctx->mod.psv_patch_consts[io_index] :
|
||||
&ctx->mod.psv_outputs[io_index];
|
||||
psv_rec->dynamic_mask_and_stream |= comp_mask;
|
||||
}
|
||||
}
|
||||
@@ -3701,10 +3703,12 @@ emit_load_input_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr
|
||||
if (!opcode)
|
||||
return false;
|
||||
|
||||
const struct dxil_value *input_id = dxil_module_get_int32_const(&ctx->mod,
|
||||
is_patch_constant || is_output_control_point ?
|
||||
nir_intrinsic_base(intr) :
|
||||
ctx->mod.input_mappings[nir_intrinsic_base(intr)]);
|
||||
uint8_t *io_mappings =
|
||||
is_patch_constant ? ctx->mod.patch_mappings :
|
||||
is_output_control_point ? ctx->mod.output_mappings :
|
||||
ctx->mod.input_mappings;
|
||||
uint8_t io_index = io_mappings[nir_intrinsic_base(intr)];
|
||||
const struct dxil_value *input_id = dxil_module_get_int32_const(&ctx->mod, io_index);
|
||||
if (!input_id)
|
||||
return false;
|
||||
|
||||
@@ -3760,8 +3764,8 @@ emit_load_input_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr
|
||||
!is_output_control_point &&
|
||||
intr->intrinsic != nir_intrinsic_load_output) {
|
||||
struct dxil_signature_record *sig_rec = is_patch_constant ?
|
||||
&ctx->mod.patch_consts[nir_intrinsic_base(intr)] :
|
||||
&ctx->mod.inputs[ctx->mod.input_mappings[nir_intrinsic_base(intr)]];
|
||||
&ctx->mod.patch_consts[io_index] :
|
||||
&ctx->mod.inputs[io_index];
|
||||
unsigned comp_size = intr->def.bit_size == 64 ? 2 : 1;
|
||||
unsigned comp_mask = (1 << (intr->num_components * comp_size)) - 1;
|
||||
comp_mask <<= (var_base_component * comp_size);
|
||||
@@ -3772,8 +3776,8 @@ emit_load_input_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr
|
||||
|
||||
if (!nir_src_is_const(intr->src[row_index])) {
|
||||
struct dxil_psv_signature_element *psv_rec = is_patch_constant ?
|
||||
&ctx->mod.psv_patch_consts[nir_intrinsic_base(intr)] :
|
||||
&ctx->mod.psv_inputs[ctx->mod.input_mappings[nir_intrinsic_base(intr)]];
|
||||
&ctx->mod.psv_patch_consts[io_index] :
|
||||
&ctx->mod.psv_inputs[io_index];
|
||||
psv_rec->dynamic_mask_and_stream |= comp_mask;
|
||||
}
|
||||
}
|
||||
@@ -3844,8 +3848,9 @@ emit_load_interpolated_input(struct ntd_context *ctx, nir_intrinsic_instr *intr)
|
||||
default:
|
||||
unreachable("Unsupported interpolation barycentric intrinsic");
|
||||
}
|
||||
uint8_t io_index = ctx->mod.input_mappings[nir_intrinsic_base(intr)];
|
||||
args[0] = dxil_module_get_int32_const(&ctx->mod, opcode_val);
|
||||
args[1] = dxil_module_get_int32_const(&ctx->mod, nir_intrinsic_base(intr));
|
||||
args[1] = dxil_module_get_int32_const(&ctx->mod, io_index);
|
||||
args[2] = get_src(ctx, &intr->src[1], 0, nir_type_int);
|
||||
|
||||
const struct dxil_func *func = dxil_get_function(&ctx->mod, func_name, DXIL_F32);
|
||||
@@ -3858,8 +3863,7 @@ emit_load_interpolated_input(struct ntd_context *ctx, nir_intrinsic_instr *intr)
|
||||
unsigned base_component = nir_intrinsic_component(intr) - var_base_component;
|
||||
|
||||
if (ctx->mod.minor_validator >= 5) {
|
||||
struct dxil_signature_record *sig_rec =
|
||||
&ctx->mod.inputs[ctx->mod.input_mappings[nir_intrinsic_base(intr)]];
|
||||
struct dxil_signature_record *sig_rec = &ctx->mod.inputs[io_index];
|
||||
unsigned comp_size = intr->def.bit_size == 64 ? 2 : 1;
|
||||
unsigned comp_mask = (1 << (intr->num_components * comp_size)) - 1;
|
||||
comp_mask <<= (var_base_component * comp_size);
|
||||
@@ -3867,8 +3871,7 @@ emit_load_interpolated_input(struct ntd_context *ctx, nir_intrinsic_instr *intr)
|
||||
sig_rec->elements[r].always_reads_mask |= (comp_mask & sig_rec->elements[r].mask);
|
||||
|
||||
if (!nir_src_is_const(intr->src[1])) {
|
||||
struct dxil_psv_signature_element *psv_rec =
|
||||
&ctx->mod.psv_inputs[ctx->mod.input_mappings[nir_intrinsic_base(intr)]];
|
||||
struct dxil_psv_signature_element *psv_rec = &ctx->mod.psv_inputs[io_index];
|
||||
psv_rec->dynamic_mask_and_stream |= comp_mask;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user