From 7748e4799d2fa6408a8baaa4d9c710988685566d Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Fri, 14 Jan 2022 16:16:31 -0800 Subject: [PATCH] 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 Part-of: --- src/microsoft/compiler/dxil_function.c | 1 + src/microsoft/compiler/dxil_signature.c | 5 --- src/microsoft/compiler/nir_to_dxil.c | 51 ++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/microsoft/compiler/dxil_function.c b/src/microsoft/compiler/dxil_function.c index 18507378400..a6d192a1d7d 100644 --- a/src/microsoft/compiler/dxil_function.c +++ b/src/microsoft/compiler/dxil_function.c @@ -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 { diff --git a/src/microsoft/compiler/dxil_signature.c b/src/microsoft/compiler/dxil_signature.c index df2c8794cbb..05df9d2d843 100644 --- a/src/microsoft/compiler/dxil_signature.c +++ b/src/microsoft/compiler/dxil_signature.c @@ -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); } diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c index f2e5a2f9dd6..494544cd0d0 100644 --- a/src/microsoft/compiler/nir_to_dxil.c +++ b/src/microsoft/compiler/nir_to_dxil.c @@ -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);