mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
microsoft/compiler: Handle input coverage
Note that GL requires input coverage for sample execution mode to be only the single bit corresponding to the executing sample, so rearrange things to understand during shader emitting if we're executing per-sample to emit the right coverage value. Reviewed-by: Sil Vilerino <sivileri@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14624>
This commit is contained in:
parent
777a42e309
commit
7748e4799d
3 changed files with 46 additions and 11 deletions
|
|
@ -80,6 +80,7 @@ static struct predefined_func_descr predefined_funcs[] = {
|
|||
{"dx.op.evalSnapped", "O", "iiicii", DXIL_ATTR_KIND_READ_NONE},
|
||||
{"dx.op.evalCentroid", "O", "iiic", DXIL_ATTR_KIND_READ_NONE},
|
||||
{"dx.op.evalSampleIndex", "O", "iiici", DXIL_ATTR_KIND_READ_NONE},
|
||||
{"dx.op.coverage", "i", "i", DXIL_ATTR_KIND_READ_NONE},
|
||||
};
|
||||
|
||||
struct func_descr {
|
||||
|
|
|
|||
|
|
@ -505,11 +505,6 @@ get_input_signature_group(struct dxil_module *mod, const struct dxil_mdnode **in
|
|||
mod->num_psv_inputs = MAX2(mod->num_psv_inputs,
|
||||
semantic.start_row + semantic.rows);
|
||||
|
||||
mod->info.has_per_sample_input |=
|
||||
semantic.kind == DXIL_SEM_SAMPLE_INDEX ||
|
||||
semantic.interpolation == DXIL_INTERP_LINEAR_SAMPLE ||
|
||||
semantic.interpolation == DXIL_INTERP_LINEAR_NOPERSPECTIVE_SAMPLE;
|
||||
|
||||
++num_inputs;
|
||||
assert(num_inputs < VARYING_SLOT_MAX);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,6 +264,7 @@ enum dxil_intr {
|
|||
DXIL_INTR_EVAL_CENTROID = 89,
|
||||
|
||||
DXIL_INTR_SAMPLE_INDEX = 90,
|
||||
DXIL_INTR_COVERAGE = 91,
|
||||
|
||||
DXIL_INTR_THREAD_ID = 93,
|
||||
DXIL_INTR_GROUP_ID = 94,
|
||||
|
|
@ -2463,10 +2464,10 @@ emit_load_local_workgroup_id(struct ntd_context *ctx,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
emit_load_unary_external_function(struct ntd_context *ctx,
|
||||
nir_intrinsic_instr *intr, const char *name,
|
||||
int32_t dxil_intr)
|
||||
static const struct dxil_value *
|
||||
call_unary_external_function(struct ntd_context *ctx,
|
||||
const char *name,
|
||||
int32_t dxil_intr)
|
||||
{
|
||||
const struct dxil_func *func =
|
||||
dxil_get_function(&ctx->mod, name, DXIL_I32);
|
||||
|
|
@ -2480,13 +2481,38 @@ emit_load_unary_external_function(struct ntd_context *ctx,
|
|||
|
||||
const struct dxil_value *args[] = {opcode};
|
||||
|
||||
const struct dxil_value *value =
|
||||
dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
|
||||
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
|
||||
}
|
||||
|
||||
static bool
|
||||
emit_load_unary_external_function(struct ntd_context *ctx,
|
||||
nir_intrinsic_instr *intr, const char *name,
|
||||
int32_t dxil_intr)
|
||||
{
|
||||
const struct dxil_value *value = call_unary_external_function(ctx, name, dxil_intr);
|
||||
store_dest_value(ctx, &intr->dest, 0, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
emit_load_sample_mask_in(struct ntd_context *ctx, nir_intrinsic_instr *intr)
|
||||
{
|
||||
const struct dxil_value *value = call_unary_external_function(ctx,
|
||||
"dx.op.coverage", DXIL_INTR_COVERAGE);
|
||||
|
||||
/* Mask coverage with (1 << sample index). Note, done as an AND to handle extrapolation cases. */
|
||||
if (ctx->mod.info.has_per_sample_input) {
|
||||
value = dxil_emit_binop(&ctx->mod, DXIL_BINOP_AND, value,
|
||||
dxil_emit_binop(&ctx->mod, DXIL_BINOP_SHL,
|
||||
dxil_module_get_int32_const(&ctx->mod, 1),
|
||||
call_unary_external_function(ctx, "dx.op.sampleIndex", DXIL_INTR_SAMPLE_INDEX), 0), 0);
|
||||
}
|
||||
|
||||
store_dest_value(ctx, &intr->dest, 0, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct dxil_value *
|
||||
get_int32_undef(struct dxil_module *m)
|
||||
{
|
||||
|
|
@ -3734,6 +3760,8 @@ emit_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr)
|
|||
case nir_intrinsic_load_sample_id:
|
||||
return emit_load_unary_external_function(ctx, intr, "dx.op.sampleIndex",
|
||||
DXIL_INTR_SAMPLE_INDEX);
|
||||
case nir_intrinsic_load_sample_mask_in:
|
||||
return emit_load_sample_mask_in(ctx, intr);
|
||||
case nir_intrinsic_load_shared_dxil:
|
||||
return emit_load_shared(ctx, intr);
|
||||
case nir_intrinsic_load_scratch_dxil:
|
||||
|
|
@ -4846,6 +4874,17 @@ emit_module(struct ntd_context *ctx, const struct nir_to_dxil_options *opts)
|
|||
return false;
|
||||
}
|
||||
|
||||
ctx->mod.info.has_per_sample_input =
|
||||
BITSET_TEST(ctx->shader->info.system_values_read, SYSTEM_VALUE_SAMPLE_ID);
|
||||
if (!ctx->mod.info.has_per_sample_input && ctx->shader->info.stage == MESA_SHADER_FRAGMENT) {
|
||||
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_shader_in | nir_var_system_value) {
|
||||
if (var->data.sample) {
|
||||
ctx->mod.info.has_per_sample_input = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nir_function_impl *entry = nir_shader_get_entrypoint(ctx->shader);
|
||||
nir_metadata_require(entry, nir_metadata_block_index);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue