microsoft/compiler: Handle 'pull model' explicit interpolation intrinsics
Reviewed-by: Sil Vilerino <sivileri@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14624>
This commit is contained in:
@@ -76,6 +76,9 @@ static struct predefined_func_descr predefined_funcs[] = {
|
||||
{"dx.op.splitDouble", "G", "ig", DXIL_ATTR_KIND_READ_NONE},
|
||||
{"dx.op.texture2DMSGetSamplePosition", "S", "i@i", DXIL_ATTR_KIND_READ_ONLY},
|
||||
{"dx.op.renderTargetGetSamplePosition", "S", "ii", DXIL_ATTR_KIND_READ_ONLY},
|
||||
{"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},
|
||||
};
|
||||
|
||||
struct func_descr {
|
||||
|
@@ -109,6 +109,7 @@ nir_options = {
|
||||
.lower_unpack_snorm_4x8 = true,
|
||||
.lower_unpack_unorm_2x16 = true,
|
||||
.lower_unpack_unorm_4x8 = true,
|
||||
.lower_interpolate_at = true,
|
||||
.has_fsub = true,
|
||||
.has_isub = true,
|
||||
.use_scoped_barrier = true,
|
||||
@@ -257,6 +258,10 @@ enum dxil_intr {
|
||||
DXIL_INTR_DDX_FINE = 85,
|
||||
DXIL_INTR_DDY_FINE = 86,
|
||||
|
||||
DXIL_INTR_EVAL_SNAPPED = 87,
|
||||
DXIL_INTR_EVAL_SAMPLE_INDEX = 88,
|
||||
DXIL_INTR_EVAL_CENTROID = 89,
|
||||
|
||||
DXIL_INTR_SAMPLE_INDEX = 90,
|
||||
|
||||
DXIL_INTR_THREAD_ID = 93,
|
||||
@@ -2912,6 +2917,70 @@ emit_load_input_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
emit_load_interpolated_input(struct ntd_context *ctx, nir_intrinsic_instr *intr)
|
||||
{
|
||||
nir_intrinsic_instr *barycentric = nir_src_as_intrinsic(intr->src[0]);
|
||||
|
||||
const struct dxil_value *args[6] = { 0 };
|
||||
|
||||
unsigned opcode_val;
|
||||
const char *func_name;
|
||||
unsigned num_args;
|
||||
switch (barycentric->intrinsic) {
|
||||
case nir_intrinsic_load_barycentric_at_offset:
|
||||
opcode_val = DXIL_INTR_EVAL_SNAPPED;
|
||||
func_name = "dx.op.evalSnapped";
|
||||
num_args = 6;
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
const struct dxil_value *float_offset = get_src(ctx, &barycentric->src[0], i, nir_type_float);
|
||||
/* GLSL uses [-0.5f, 0.5f), DXIL uses (-8, 7) */
|
||||
const struct dxil_value *offset_16 = dxil_emit_binop(&ctx->mod,
|
||||
DXIL_BINOP_MUL, float_offset, dxil_module_get_float_const(&ctx->mod, 16.0f), 0);
|
||||
args[i + 4] = dxil_emit_cast(&ctx->mod, DXIL_CAST_FPTOSI,
|
||||
dxil_module_get_int_type(&ctx->mod, 32), offset_16);
|
||||
}
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_pixel:
|
||||
opcode_val = DXIL_INTR_EVAL_SNAPPED;
|
||||
func_name = "dx.op.evalSnapped";
|
||||
num_args = 6;
|
||||
args[4] = args[5] = dxil_module_get_int32_const(&ctx->mod, 0);
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_at_sample:
|
||||
opcode_val = DXIL_INTR_EVAL_SAMPLE_INDEX;
|
||||
func_name = "dx.op.evalSampleIndex";
|
||||
num_args = 5;
|
||||
args[4] = get_src(ctx, &barycentric->src[0], 0, nir_type_int);
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_centroid:
|
||||
opcode_val = DXIL_INTR_EVAL_CENTROID;
|
||||
func_name = "dx.op.evalCentroid";
|
||||
num_args = 4;
|
||||
break;
|
||||
default:
|
||||
unreachable("Unsupported interpolation barycentric intrinsic");
|
||||
}
|
||||
args[0] = dxil_module_get_int32_const(&ctx->mod, opcode_val);
|
||||
args[1] = dxil_module_get_int32_const(&ctx->mod, nir_intrinsic_base(intr));
|
||||
args[2] = get_src(ctx, &intr->src[1], 0, nir_type_int);
|
||||
|
||||
const struct dxil_func *func = dxil_get_function(&ctx->mod, func_name, DXIL_F32);
|
||||
|
||||
if (!func)
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < intr->num_components; ++i) {
|
||||
args[3] = dxil_module_get_int8_const(&ctx->mod, i + nir_intrinsic_component(intr));
|
||||
|
||||
const struct dxil_value *retval = dxil_emit_call(&ctx->mod, func, args, num_args);
|
||||
if (!retval)
|
||||
return false;
|
||||
store_dest(ctx, &intr->dest, i, retval, nir_type_float);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
emit_load_ptr(struct ntd_context *ctx, nir_intrinsic_instr *intr)
|
||||
{
|
||||
@@ -3776,6 +3845,16 @@ emit_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr)
|
||||
case nir_intrinsic_store_output:
|
||||
return emit_store_output_via_intrinsic(ctx, intr);
|
||||
|
||||
case nir_intrinsic_load_barycentric_at_offset:
|
||||
case nir_intrinsic_load_barycentric_at_sample:
|
||||
case nir_intrinsic_load_barycentric_centroid:
|
||||
case nir_intrinsic_load_barycentric_pixel:
|
||||
/* Emit nothing, we only support these as inputs to load_interpolated_input */
|
||||
return true;
|
||||
case nir_intrinsic_load_interpolated_input:
|
||||
return emit_load_interpolated_input(ctx, intr);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_vulkan_resource_index:
|
||||
return emit_vulkan_resource_index(ctx, intr);
|
||||
case nir_intrinsic_load_vulkan_descriptor:
|
||||
|
Reference in New Issue
Block a user