microsoft/compiler: Split signature processing into two parts
First, preprocess the signatures, strictly based on the variables in the nir shader. Then, later, after the actual shader contents have been processed, we emit the metadata. This lets shader processing rely on the pre-processed data (e.g. the row -> ID mapping needed for large VS inputs) while also allowing the signature data to rely on data gathered during the shader traversal (e.g. which components are actually used). Reviewed-by: Enrico Galli <enrico.galli@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17603>
This commit is contained in:
parent
e4c927545d
commit
252c3c409d
|
@ -533,7 +533,6 @@ fill_psv_signature_element(struct dxil_psv_signature_element *psv_elm,
|
|||
static bool
|
||||
fill_io_signature(struct dxil_module *mod, int id,
|
||||
struct semantic_info *semantic,
|
||||
const struct dxil_mdnode **io,
|
||||
struct dxil_signature_record *rec,
|
||||
struct dxil_psv_signature_element *psv_elm)
|
||||
{
|
||||
|
@ -543,14 +542,11 @@ fill_io_signature(struct dxil_module *mod, int id,
|
|||
|
||||
for (unsigned i = 0; i < semantic->rows; ++i)
|
||||
fill_signature_element(&rec->elements[i], semantic, i);
|
||||
if (!fill_psv_signature_element(psv_elm, semantic, mod))
|
||||
return false;
|
||||
*io = fill_SV_param_nodes(mod, id, rec, psv_elm);
|
||||
return true;
|
||||
return fill_psv_signature_element(psv_elm, semantic, mod);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_input_signature_group(struct dxil_module *mod, const struct dxil_mdnode **inputs,
|
||||
get_input_signature_group(struct dxil_module *mod,
|
||||
unsigned num_inputs,
|
||||
nir_shader *s, nir_variable_mode modes,
|
||||
semantic_info_proc get_semantics, unsigned *row_iter,
|
||||
|
@ -569,7 +565,7 @@ get_input_signature_group(struct dxil_module *mod, const struct dxil_mdnode **in
|
|||
struct dxil_psv_signature_element *psv_elm = &mod->psv_inputs[num_inputs];
|
||||
|
||||
if (!fill_io_signature(mod, num_inputs, &semantic,
|
||||
&inputs[num_inputs], &mod->inputs[num_inputs], psv_elm))
|
||||
&mod->inputs[num_inputs], psv_elm))
|
||||
return 0;
|
||||
|
||||
mod->num_psv_inputs = MAX2(mod->num_psv_inputs,
|
||||
|
@ -581,33 +577,24 @@ get_input_signature_group(struct dxil_module *mod, const struct dxil_mdnode **in
|
|||
return num_inputs;
|
||||
}
|
||||
|
||||
static const struct dxil_mdnode *
|
||||
get_input_signature(struct dxil_module *mod, nir_shader *s, unsigned input_clip_size)
|
||||
static void
|
||||
process_input_signature(struct dxil_module *mod, nir_shader *s, unsigned input_clip_size)
|
||||
{
|
||||
if (s->info.stage == MESA_SHADER_KERNEL)
|
||||
return NULL;
|
||||
|
||||
const struct dxil_mdnode *inputs[VARYING_SLOT_MAX];
|
||||
return;
|
||||
unsigned next_row = 0;
|
||||
|
||||
mod->num_sig_inputs = get_input_signature_group(mod, inputs, 0,
|
||||
mod->num_sig_inputs = get_input_signature_group(mod, 0,
|
||||
s, nir_var_shader_in,
|
||||
s->info.stage == MESA_SHADER_VERTEX ?
|
||||
get_semantic_vs_in_name : get_semantic_in_name,
|
||||
&next_row, input_clip_size);
|
||||
|
||||
mod->num_sig_inputs = get_input_signature_group(mod, inputs, mod->num_sig_inputs,
|
||||
mod->num_sig_inputs = get_input_signature_group(mod, mod->num_sig_inputs,
|
||||
s, nir_var_system_value,
|
||||
get_semantic_sv_name,
|
||||
&next_row, input_clip_size);
|
||||
|
||||
if (!mod->num_sig_inputs && !mod->num_sig_inputs)
|
||||
return NULL;
|
||||
|
||||
const struct dxil_mdnode *retval = mod->num_sig_inputs ?
|
||||
dxil_get_metadata_node(mod, inputs, mod->num_sig_inputs) : NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static const char *out_sysvalue_name(nir_variable *var)
|
||||
|
@ -627,10 +614,9 @@ static const char *out_sysvalue_name(nir_variable *var)
|
|||
}
|
||||
}
|
||||
|
||||
static const struct dxil_mdnode *
|
||||
get_output_signature(struct dxil_module *mod, nir_shader *s)
|
||||
static void
|
||||
process_output_signature(struct dxil_module *mod, nir_shader *s)
|
||||
{
|
||||
const struct dxil_mdnode *outputs[VARYING_SLOT_MAX];
|
||||
unsigned num_outputs = 0;
|
||||
unsigned next_row = 0;
|
||||
nir_foreach_variable_with_modes(var, s, nir_var_shader_out) {
|
||||
|
@ -656,8 +642,8 @@ get_output_signature(struct dxil_module *mod, nir_shader *s)
|
|||
struct dxil_psv_signature_element *psv_elm = &mod->psv_outputs[num_outputs];
|
||||
|
||||
if (!fill_io_signature(mod, num_outputs, &semantic,
|
||||
&outputs[num_outputs], &mod->outputs[num_outputs], psv_elm))
|
||||
return NULL;
|
||||
&mod->outputs[num_outputs], psv_elm))
|
||||
return;
|
||||
|
||||
/* This is fishy, logic suggests that the LHS should be 0xf, but from the
|
||||
* validation it needs to be 0xff */
|
||||
|
@ -668,16 +654,8 @@ get_output_signature(struct dxil_module *mod, nir_shader *s)
|
|||
|
||||
mod->num_psv_outputs[semantic.stream] = MAX2(mod->num_psv_outputs[semantic.stream],
|
||||
semantic.start_row + semantic.rows);
|
||||
|
||||
assert(num_outputs < ARRAY_SIZE(outputs));
|
||||
}
|
||||
|
||||
if (!num_outputs)
|
||||
return NULL;
|
||||
|
||||
const struct dxil_mdnode *retval = dxil_get_metadata_node(mod, outputs, num_outputs);
|
||||
mod->num_sig_outputs = num_outputs;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -712,14 +690,13 @@ patch_sysvalue_name(nir_variable *var)
|
|||
}
|
||||
}
|
||||
|
||||
static const struct dxil_mdnode *
|
||||
get_patch_const_signature(struct dxil_module *mod, nir_shader *s)
|
||||
static void
|
||||
process_patch_const_signature(struct dxil_module *mod, nir_shader *s)
|
||||
{
|
||||
if (s->info.stage != MESA_SHADER_TESS_CTRL &&
|
||||
s->info.stage != MESA_SHADER_TESS_EVAL)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
const struct dxil_mdnode *patch_consts[VARYING_SLOT_MAX];
|
||||
nir_variable_mode mode = s->info.stage == MESA_SHADER_TESS_CTRL ?
|
||||
nir_var_shader_out : nir_var_shader_in;
|
||||
unsigned num_consts = 0;
|
||||
|
@ -738,8 +715,8 @@ get_patch_const_signature(struct dxil_module *mod, nir_shader *s)
|
|||
struct dxil_psv_signature_element *psv_elm = &mod->psv_patch_consts[num_consts];
|
||||
|
||||
if (!fill_io_signature(mod, num_consts, &semantic,
|
||||
&patch_consts[num_consts], &mod->patch_consts[num_consts], psv_elm))
|
||||
return NULL;
|
||||
&mod->patch_consts[num_consts], psv_elm))
|
||||
return;
|
||||
|
||||
/* This is fishy, logic suggests that the LHS should be 0xf, but from the
|
||||
* validation it needs to be 0xff */
|
||||
|
@ -751,28 +728,45 @@ get_patch_const_signature(struct dxil_module *mod, nir_shader *s)
|
|||
|
||||
mod->num_psv_patch_consts = MAX2(mod->num_psv_patch_consts,
|
||||
semantic.start_row + semantic.rows);
|
||||
|
||||
assert(num_consts < ARRAY_SIZE(patch_consts));
|
||||
}
|
||||
|
||||
if (!num_consts)
|
||||
return NULL;
|
||||
|
||||
const struct dxil_mdnode *retval = dxil_get_metadata_node(mod, patch_consts, num_consts);
|
||||
mod->num_sig_patch_consts = num_consts;
|
||||
return retval;
|
||||
}
|
||||
|
||||
const struct dxil_mdnode *
|
||||
get_signatures(struct dxil_module *mod, nir_shader *s, unsigned input_clip_size)
|
||||
void
|
||||
preprocess_signatures(struct dxil_module *mod, nir_shader *s, unsigned input_clip_size)
|
||||
{
|
||||
/* DXC does the same: Add an empty string before everything else */
|
||||
mod->sem_string_table = _mesa_string_buffer_create(mod->ralloc_ctx, 1024);
|
||||
copy_semantic_name_to_string(mod->sem_string_table, "");
|
||||
|
||||
const struct dxil_mdnode *input_signature = get_input_signature(mod, s, input_clip_size);
|
||||
const struct dxil_mdnode *output_signature = get_output_signature(mod, s);
|
||||
const struct dxil_mdnode *patch_const_signature = get_patch_const_signature(mod, s);
|
||||
process_input_signature(mod, s, input_clip_size);
|
||||
process_output_signature(mod, s);
|
||||
process_patch_const_signature(mod, s);
|
||||
}
|
||||
|
||||
static const struct dxil_mdnode *
|
||||
get_signature_metadata(struct dxil_module *mod,
|
||||
const struct dxil_signature_record *recs,
|
||||
const struct dxil_psv_signature_element *psvs,
|
||||
unsigned num_elements)
|
||||
{
|
||||
if (num_elements == 0)
|
||||
return NULL;
|
||||
|
||||
const struct dxil_mdnode *nodes[VARYING_SLOT_MAX];
|
||||
for (unsigned i = 0; i < num_elements; ++i) {
|
||||
nodes[i] = fill_SV_param_nodes(mod, i, &recs[i], &psvs[i]);
|
||||
}
|
||||
|
||||
return dxil_get_metadata_node(mod, nodes, num_elements);
|
||||
}
|
||||
|
||||
const struct dxil_mdnode *
|
||||
get_signatures(struct dxil_module *mod)
|
||||
{
|
||||
const struct dxil_mdnode *input_signature = get_signature_metadata(mod, mod->inputs, mod->psv_inputs, mod->num_sig_inputs);
|
||||
const struct dxil_mdnode *output_signature = get_signature_metadata(mod, mod->outputs, mod->psv_outputs, mod->num_sig_outputs);
|
||||
const struct dxil_mdnode *patch_const_signature = get_signature_metadata(mod, mod->patch_consts, mod->psv_patch_consts, mod->num_sig_patch_consts);
|
||||
|
||||
const struct dxil_mdnode *SV_nodes[3] = {
|
||||
input_signature,
|
||||
|
|
|
@ -144,8 +144,11 @@ struct dxil_psv_runtime_info_1 {
|
|||
struct dxil_mdnode;
|
||||
struct dxil_module;
|
||||
|
||||
void
|
||||
preprocess_signatures(struct dxil_module *mod, nir_shader *s, unsigned input_clip_size);
|
||||
|
||||
const struct dxil_mdnode *
|
||||
get_signatures(struct dxil_module *mod, nir_shader *s, unsigned input_clip_size);
|
||||
get_signatures(struct dxil_module *mod);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1534,7 +1534,7 @@ emit_tag(struct ntd_context *ctx, enum dxil_shader_tag tag,
|
|||
}
|
||||
|
||||
static bool
|
||||
emit_metadata(struct ntd_context *ctx, const struct dxil_mdnode *signatures)
|
||||
emit_metadata(struct ntd_context *ctx)
|
||||
{
|
||||
/* DXIL versions are 1.x for shader model 6.x */
|
||||
assert(ctx->mod.major_version == 6);
|
||||
|
@ -1611,7 +1611,7 @@ emit_metadata(struct ntd_context *ctx, const struct dxil_mdnode *signatures)
|
|||
|
||||
nir_function_impl *entry_func_impl = nir_shader_get_entrypoint(ctx->shader);
|
||||
const struct dxil_mdnode *dx_entry_point = emit_entrypoint(ctx, main_func,
|
||||
entry_func_impl->function->name, signatures, resources_node, shader_properties);
|
||||
entry_func_impl->function->name, get_signatures(&ctx->mod), resources_node, shader_properties);
|
||||
if (!dx_entry_point)
|
||||
return false;
|
||||
|
||||
|
@ -5427,8 +5427,7 @@ emit_module(struct ntd_context *ctx, const struct nir_to_dxil_options *opts)
|
|||
|
||||
unsigned input_clip_size = ctx->mod.shader_kind == DXIL_PIXEL_SHADER ?
|
||||
ctx->shader->info.clip_distance_array_size : ctx->opts->input_clip_size;
|
||||
const struct dxil_mdnode *signatures = get_signatures(&ctx->mod, ctx->shader,
|
||||
input_clip_size);
|
||||
preprocess_signatures(&ctx->mod, ctx->shader, input_clip_size);
|
||||
|
||||
nir_foreach_function(func, ctx->shader) {
|
||||
if (!emit_function(ctx, func))
|
||||
|
@ -5451,7 +5450,7 @@ emit_module(struct ntd_context *ctx, const struct nir_to_dxil_options *opts)
|
|||
if (ctx->mod.feats.native_low_precision)
|
||||
ctx->mod.minor_version = MAX2(ctx->mod.minor_version, 2);
|
||||
|
||||
return emit_metadata(ctx, signatures) &&
|
||||
return emit_metadata(ctx) &&
|
||||
dxil_emit_module(&ctx->mod);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue