From c869d1cb6293fc9124165679dc15b11198681e8b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Mon, 21 Nov 2022 12:56:37 +0100 Subject: [PATCH] microsoft/nir_to_dxil: Avoid emitting SampleCmpLevel prior to SM 6.7 if possible Part-of: --- src/microsoft/compiler/nir_to_dxil.c | 58 ++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c index 70fe678..55c14a1 100644 --- a/src/microsoft/compiler/nir_to_dxil.c +++ b/src/microsoft/compiler/nir_to_dxil.c @@ -4858,17 +4858,9 @@ emit_sample_cmp(struct ntd_context *ctx, struct texop_parameters *params) { const struct dxil_func *func; enum dxil_intr opcode; - int numparam; - if (ctx->mod.shader_kind == DXIL_PIXEL_SHADER) { - func = dxil_get_function(&ctx->mod, "dx.op.sampleCmp", DXIL_F32); - opcode = DXIL_INTR_SAMPLE_CMP; - numparam = 12; - } else { - func = dxil_get_function(&ctx->mod, "dx.op.sampleCmpLevelZero", DXIL_F32); - opcode = DXIL_INTR_SAMPLE_CMP_LVL_ZERO; - numparam = 11; - } + func = dxil_get_function(&ctx->mod, "dx.op.sampleCmp", DXIL_F32); + opcode = DXIL_INTR_SAMPLE_CMP; if (!func) return NULL; @@ -4881,7 +4873,30 @@ emit_sample_cmp(struct ntd_context *ctx, struct texop_parameters *params) params->cmp, params->min_lod }; - return dxil_emit_call(&ctx->mod, func, args, numparam); + return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args)); +} + +static const struct dxil_value * +emit_sample_cmp_level_zero(struct ntd_context *ctx, struct texop_parameters *params) +{ + const struct dxil_func *func; + enum dxil_intr opcode; + + func = dxil_get_function(&ctx->mod, "dx.op.sampleCmpLevelZero", DXIL_F32); + opcode = DXIL_INTR_SAMPLE_CMP_LVL_ZERO; + + if (!func) + return NULL; + + const struct dxil_value *args[11] = { + dxil_module_get_int32_const(&ctx->mod, opcode), + params->tex, params->sampler, + params->coord[0], params->coord[1], params->coord[2], params->coord[3], + params->offset[0], params->offset[1], params->offset[2], + params->cmp + }; + + return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args)); } static const struct dxil_value * @@ -5008,6 +5023,7 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr) unsigned coord_components = 0, offset_components = 0, dx_components = 0, dy_components = 0; params.overload = get_overload(instr->dest_type, 32); + bool lod_is_zero = false; for (unsigned i = 0; i < instr->num_srcs; i++) { nir_alu_type type = nir_tex_instr_src_type(instr, i); @@ -5048,6 +5064,9 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr) params.lod_or_sample = int_undef; if (!params.lod_or_sample) return false; + + if (nir_src_is_const(instr->src[i].src) && nir_src_as_float(instr->src[i].src) == 0.0f) + lod_is_zero = true; break; case nir_tex_src_min_lod: @@ -5148,12 +5167,21 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr) break; } params.lod_or_sample = dxil_module_get_float_const(&ctx->mod, 0); + lod_is_zero = true; FALLTHROUGH; case nir_texop_txl: - if (params.cmp != NULL) - sample = emit_sample_cmp_level(ctx, ¶ms); - else - sample = emit_sample_level(ctx, ¶ms); + if (lod_is_zero && params.cmp != NULL && ctx->opts->shader_model_max < SHADER_MODEL_6_7) { + /* Prior to SM 6.7, if the level is constant 0.0, ignore the LOD argument, + * so level-less DXIL instructions are used. This is needed to avoid emitting + * dx.op.sampleCmpLevel, which would not be available. + */ + sample = emit_sample_cmp_level_zero(ctx, ¶ms); + } else { + if (params.cmp != NULL) + sample = emit_sample_cmp_level(ctx, ¶ms); + else + sample = emit_sample_level(ctx, ¶ms); + } break; case nir_texop_txd: -- 2.7.4