diff options
author | Jesse Natalie <jenatali@microsoft.com> | 2021-04-06 10:46:21 -0700 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-04-09 01:54:33 +0000 |
commit | 771c223f604a33497692cee77fe0bd010bd33122 (patch) | |
tree | e1b7bbec0d8792592aedfba34ec7b5c0673912a5 /src/microsoft | |
parent | 5578fdd2c49c06e34bce789343f587c666321975 (diff) | |
download | mesa-771c223f604a33497692cee77fe0bd010bd33122.tar.gz mesa-771c223f604a33497692cee77fe0bd010bd33122.tar.bz2 mesa-771c223f604a33497692cee77fe0bd010bd33122.zip |
microsoft/compiler: Implement new double pack/unpack alu ops
MakeDouble is pretty straightforward, but SplitDouble is interesting
since it returns a unique 2-element struct.
Reviewed-by: Enrico Galli <enrico.galli@intel.com>
Reviewed-by: Michael Tang <tangm@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10063>
Diffstat (limited to 'src/microsoft')
-rw-r--r-- | src/microsoft/compiler/dxil_function.c | 3 | ||||
-rw-r--r-- | src/microsoft/compiler/dxil_function.h | 1 | ||||
-rw-r--r-- | src/microsoft/compiler/dxil_module.c | 9 | ||||
-rw-r--r-- | src/microsoft/compiler/dxil_module.h | 3 | ||||
-rw-r--r-- | src/microsoft/compiler/nir_to_dxil.c | 65 |
5 files changed, 81 insertions, 0 deletions
diff --git a/src/microsoft/compiler/dxil_function.c b/src/microsoft/compiler/dxil_function.c index b87c4509eab..5be4f5dd0c0 100644 --- a/src/microsoft/compiler/dxil_function.c +++ b/src/microsoft/compiler/dxil_function.c @@ -69,6 +69,8 @@ static struct predefined_func_descr predefined_funcs[] = { {"dx.op.primitiveID", "i", "i", DXIL_ATTR_KIND_READ_NONE}, {"dx.op.legacyF16ToF32", "f", "ii", DXIL_ATTR_KIND_READ_ONLY}, {"dx.op.legacyF32ToF16", "i", "if", DXIL_ATTR_KIND_READ_ONLY}, +{"dx.op.makeDouble", "g", "iii", DXIL_ATTR_KIND_READ_NONE}, +{"dx.op.splitDouble", "G", "ig", DXIL_ATTR_KIND_READ_NONE}, }; struct func_descr { @@ -171,6 +173,7 @@ get_type_from_string(struct dxil_module *mod, const char *param_descr, case DXIL_FUNC_PARAM_RESRET: return dxil_module_get_resret_type(mod, overload); case DXIL_FUNC_PARAM_DIM: return dxil_module_get_dimret_type(mod); case DXIL_FUNC_PARAM_CBUF_RET: return dxil_module_get_cbuf_ret_type(mod, overload); + case DXIL_FUNC_PARAM_SPLIT_DOUBLE: return dxil_module_get_split_double_ret_type(mod); case DXIL_FUNC_PARAM_POINTER: { const struct dxil_type *target = get_type_from_string(mod, param_descr, overload, idx); return dxil_module_get_pointer_type(mod, target); diff --git a/src/microsoft/compiler/dxil_function.h b/src/microsoft/compiler/dxil_function.h index c615ab3e818..9a006a2ca50 100644 --- a/src/microsoft/compiler/dxil_function.h +++ b/src/microsoft/compiler/dxil_function.h @@ -40,6 +40,7 @@ #define DXIL_FUNC_PARAM_RESRET 'R' #define DXIL_FUNC_PARAM_CBUF_RET 'B' #define DXIL_FUNC_PARAM_DIM 'D' +#define DXIL_FUNC_PARAM_SPLIT_DOUBLE 'G' #include "dxil_module.h" #include "util/rb_tree.h" diff --git a/src/microsoft/compiler/dxil_module.c b/src/microsoft/compiler/dxil_module.c index e0e827c8132..09f2252df9f 100644 --- a/src/microsoft/compiler/dxil_module.c +++ b/src/microsoft/compiler/dxil_module.c @@ -728,6 +728,15 @@ dxil_module_get_cbuf_ret_type(struct dxil_module *mod, enum overload_type overlo return dxil_module_get_struct_type(mod, name, fields, num_fields); } +const struct dxil_type * +dxil_module_get_split_double_ret_type(struct dxil_module *mod) +{ + const struct dxil_type *int32_type = dxil_module_get_int_type(mod, 32); + const struct dxil_type *fields[2] = { int32_type, int32_type }; + + return dxil_module_get_struct_type(mod, "dx.types.splitDouble", fields, 2); +} + static const struct dxil_type * dxil_module_get_type_from_comp_type(struct dxil_module *m, enum dxil_component_type comp_type) { diff --git a/src/microsoft/compiler/dxil_module.h b/src/microsoft/compiler/dxil_module.h index 353492e4418..ca607f52cea 100644 --- a/src/microsoft/compiler/dxil_module.h +++ b/src/microsoft/compiler/dxil_module.h @@ -264,6 +264,9 @@ const struct dxil_type * dxil_module_get_cbuf_ret_type(struct dxil_module *mod, enum overload_type overload); const struct dxil_type * +dxil_module_get_split_double_ret_type(struct dxil_module *mod); + +const struct dxil_type * dxil_module_get_res_type(struct dxil_module *m, enum dxil_resource_kind kind, enum dxil_component_type comp_type, bool readwrite); diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c index 1768ef75e1d..0d71f3ffd96 100644 --- a/src/microsoft/compiler/nir_to_dxil.c +++ b/src/microsoft/compiler/nir_to_dxil.c @@ -250,6 +250,9 @@ enum dxil_intr { DXIL_INTR_EMIT_STREAM = 97, DXIL_INTR_CUT_STREAM = 98, + DXIL_INTR_MAKE_DOUBLE = 101, + DXIL_INTR_SPLIT_DOUBLE = 102, + DXIL_INTR_PRIMITIVE_ID = 108, DXIL_INTR_LEGACY_F32TOF16 = 130, @@ -1860,6 +1863,64 @@ emit_vec(struct ntd_context *ctx, nir_alu_instr *alu, unsigned num_inputs) } static bool +emit_make_double(struct ntd_context *ctx, nir_alu_instr *alu) +{ + const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.makeDouble", DXIL_F64); + if (!func) + return false; + + const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_MAKE_DOUBLE); + if (!opcode) + return false; + + const struct dxil_value *args[3] = { + opcode, + get_src(ctx, &alu->src[0].src, 0, nir_type_uint32), + get_src(ctx, &alu->src[0].src, 1, nir_type_uint32), + }; + if (!args[1] || !args[2]) + return false; + + const struct dxil_value *v = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args)); + if (!v) + return false; + store_dest(ctx, &alu->dest.dest, 0, v, nir_type_float64); + return true; +} + +static bool +emit_split_double(struct ntd_context *ctx, nir_alu_instr *alu) +{ + const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.splitDouble", DXIL_F64); + if (!func) + return false; + + const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_SPLIT_DOUBLE); + if (!opcode) + return false; + + const struct dxil_value *args[] = { + opcode, + get_src(ctx, &alu->src[0].src, 0, nir_type_float64) + }; + if (!args[1]) + return false; + + const struct dxil_value *v = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args)); + if (!v) + return false; + + const struct dxil_value *hi = dxil_emit_extractval(&ctx->mod, v, 0); + const struct dxil_value *lo = dxil_emit_extractval(&ctx->mod, v, 1); + if (!hi || !lo) + return false; + + store_dest_value(ctx, &alu->dest.dest, 0, hi); + store_dest_value(ctx, &alu->dest.dest, 1, lo); + return true; +} + +static bool emit_alu(struct ntd_context *ctx, nir_alu_instr *alu) { /* handle vec-instructions first; they are the only ones that produce @@ -1878,6 +1939,10 @@ emit_alu(struct ntd_context *ctx, nir_alu_instr *alu) alu->src->src.ssa, alu->src->swizzle[0])); return true; } + case nir_op_pack_double_2x32_dxil: + return emit_make_double(ctx, alu); + case nir_op_unpack_double_2x32_dxil: + return emit_split_double(ctx, alu); default: /* silence warnings */ ; |