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:
Jesse Natalie 2022-02-14 09:40:08 -08:00 committed by Marge Bot
parent e4c927545d
commit 252c3c409d
3 changed files with 55 additions and 59 deletions

View File

@ -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,

View File

@ -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
}

View File

@ -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);
}