summaryrefslogtreecommitdiff
path: root/src/microsoft
diff options
context:
space:
mode:
authorJesse Natalie <jenatali@microsoft.com>2021-04-06 10:46:21 -0700
committerMarge Bot <eric+marge@anholt.net>2021-04-09 01:54:33 +0000
commit771c223f604a33497692cee77fe0bd010bd33122 (patch)
treee1b7bbec0d8792592aedfba34ec7b5c0673912a5 /src/microsoft
parent5578fdd2c49c06e34bce789343f587c666321975 (diff)
downloadmesa-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.c3
-rw-r--r--src/microsoft/compiler/dxil_function.h1
-rw-r--r--src/microsoft/compiler/dxil_module.c9
-rw-r--r--src/microsoft/compiler/dxil_module.h3
-rw-r--r--src/microsoft/compiler/nir_to_dxil.c65
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 */
;