{
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;
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 *
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);
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:
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: