diff --git a/src/microsoft/compiler/dxil_function.c b/src/microsoft/compiler/dxil_function.c index f72ef1ff745..7f182ca48ed 100644 --- a/src/microsoft/compiler/dxil_function.c +++ b/src/microsoft/compiler/dxil_function.c @@ -24,7 +24,7 @@ #include "dxil_function.h" #include "dxil_module.h" -#define MAX_FUNC_PARAMS 17 +#define MAX_FUNC_PARAMS 18 struct predefined_func_descr { const char *base_name; @@ -62,6 +62,8 @@ static struct predefined_func_descr predefined_funcs[] = { {"dx.op.sampleCmp", "R", "i@@ffffiiiff", DXIL_ATTR_KIND_READ_ONLY}, {"dx.op.sampleCmpLevel", "R", "i@@ffffiiiff", DXIL_ATTR_KIND_READ_ONLY}, {"dx.op.sampleCmpLevelZero", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY}, +{"dx.op.sampleCmpBias", "R", "i@@ffffiiifff", DXIL_ATTR_KIND_READ_ONLY}, +{"dx.op.sampleCmpGrad", "R", "i@@ffffiiiffffffff", DXIL_ATTR_KIND_READ_ONLY}, {"dx.op.textureLoad", "R", "i@iiiiiii", DXIL_ATTR_KIND_READ_ONLY}, {"dx.op.textureGather", "R", "i@@ffffiii", DXIL_ATTR_KIND_READ_ONLY}, {"dx.op.textureGatherCmp", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY}, diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c index 5d14b8c823d..d44fbc1f111 100644 --- a/src/microsoft/compiler/nir_to_dxil.c +++ b/src/microsoft/compiler/nir_to_dxil.c @@ -388,6 +388,8 @@ enum dxil_intr { DXIL_INTR_IS_HELPER_LANE = 221, DXIL_INTR_SAMPLE_CMP_LEVEL = 224, + DXIL_INTR_SAMPLE_CMP_GRAD = 254, + DXIL_INTR_SAMPLE_CMP_BIAS = 255, }; enum dxil_atomic_op { @@ -5286,6 +5288,26 @@ emit_sample_cmp_level(struct ntd_context *ctx, struct texop_parameters *params) return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args)); } +static const struct dxil_value * +emit_sample_cmp_bias(struct ntd_context *ctx, struct texop_parameters *params) +{ + const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.sampleCmpBias", params->overload); + if (!func) + return NULL; + + assert(params->bias != NULL); + + const struct dxil_value *args[13] = { + dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_SAMPLE_CMP_BIAS), + 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, params->bias, params->min_lod + }; + + return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args)); +} + static const struct dxil_value * emit_sample_grad(struct ntd_context *ctx, struct texop_parameters *params) { @@ -5306,6 +5328,27 @@ emit_sample_grad(struct ntd_context *ctx, struct texop_parameters *params) return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args)); } +static const struct dxil_value * +emit_sample_cmp_grad(struct ntd_context *ctx, struct texop_parameters *params) +{ + const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.sampleCmpGrad", params->overload); + if (!func) + return false; + + const struct dxil_value *args[18] = { + dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_SAMPLE_CMP_GRAD), + 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, + params->dx[0], params->dx[1], params->dx[2], + params->dy[0], params->dy[1], params->dy[2], + params->min_lod + }; + + return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args)); +} + static const struct dxil_value * emit_texel_fetch(struct ntd_context *ctx, struct texop_parameters *params) { @@ -5535,7 +5578,10 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr) const struct dxil_value *sample = NULL; switch (instr->op) { case nir_texop_txb: - sample = emit_sample_bias(ctx, ¶ms); + if (params.cmp != NULL && ctx->mod.minor_version >= 8) + sample = emit_sample_cmp_bias(ctx, ¶ms); + else + sample = emit_sample_bias(ctx, ¶ms); break; case nir_texop_tex: @@ -5550,7 +5596,7 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr) lod_is_zero = true; FALLTHROUGH; case nir_texop_txl: - if (lod_is_zero && params.cmp != NULL && ctx->opts->shader_model_max < SHADER_MODEL_6_7) { + if (lod_is_zero && params.cmp != NULL && ctx->mod.minor_version < 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. @@ -5567,7 +5613,10 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr) case nir_texop_txd: PAD_SRC(ctx, params.dx, dx_components, float_undef); PAD_SRC(ctx, params.dy, dy_components,float_undef); - sample = emit_sample_grad(ctx, ¶ms); + if (params.cmp != NULL && ctx->mod.minor_version >= 8) + sample = emit_sample_cmp_grad(ctx, ¶ms); + else + sample = emit_sample_grad(ctx, ¶ms); break; case nir_texop_txf: