summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2016-12-28 00:33:07 +0000
committerBas Nieuwenhuizen <[email protected]>2018-03-29 01:29:29 +0200
commitfe5d5d19b01bd5d1407943181d613d18a44aa42b (patch)
tree319559632c75722cc22fe07c930b4edb12e36ad5 /src
parent3e830a1af2dcd0a8e6c76ea04c50e814e550b244 (diff)
spirv: add support for SPV_AMD_shader_trinary_minmax
Co-authored-by: Daniel Schürmann <[email protected]> Signed-off-by: Dave Airlie <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/compiler/shader_info.h1
-rw-r--r--src/compiler/spirv/spirv_to_nir.c3
-rw-r--r--src/compiler/spirv/vtn_amd.c52
-rw-r--r--src/compiler/spirv/vtn_private.h2
4 files changed, 58 insertions, 0 deletions
diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h
index 0eeb2ca58ea..737e9cffa86 100644
--- a/src/compiler/shader_info.h
+++ b/src/compiler/shader_info.h
@@ -52,6 +52,7 @@ struct spirv_supported_capabilities {
bool subgroup_shuffle;
bool subgroup_vote;
bool gcn_shader;
+ bool trinary_minmax;
};
typedef struct shader_info {
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 7888e1b7463..4297622979e 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -378,6 +378,9 @@ vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
} else if ((strcmp((const char *)&w[2], "SPV_AMD_gcn_shader") == 0)
&& (b->options && b->options->caps.gcn_shader)) {
val->ext_handler = vtn_handle_amd_gcn_shader_instruction;
+ } else if ((strcmp((const char *)&w[2], "SPV_AMD_shader_trinary_minmax") == 0)
+ && (b->options && b->options->caps.trinary_minmax)) {
+ val->ext_handler = vtn_handle_amd_shader_trinary_minmax_instruction;
} else {
vtn_fail("Unsupported extension");
}
diff --git a/src/compiler/spirv/vtn_amd.c b/src/compiler/spirv/vtn_amd.c
index b2b3e055f0a..320e3b0586c 100644
--- a/src/compiler/spirv/vtn_amd.c
+++ b/src/compiler/spirv/vtn_amd.c
@@ -55,3 +55,55 @@ vtn_handle_amd_gcn_shader_instruction(struct vtn_builder *b, uint32_t ext_opcode
}
return true;
}
+
+bool
+vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, uint32_t ext_opcode,
+ const uint32_t *w, unsigned count)
+{
+ struct nir_builder *nb = &b->nb;
+ const struct glsl_type *dest_type =
+ vtn_value(b, w[1], vtn_value_type_type)->type->type;
+ struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+ val->ssa = vtn_create_ssa_value(b, dest_type);
+
+ unsigned num_inputs = count - 5;
+ assert(num_inputs == 3);
+ nir_ssa_def *src[3] = { NULL, };
+ for (unsigned i = 0; i < num_inputs; i++)
+ src[i] = vtn_ssa_value(b, w[i + 5])->def;
+
+ switch ((enum ShaderTrinaryMinMaxAMD)ext_opcode) {
+ case FMin3AMD:
+ val->ssa->def = nir_fmin3(nb, src[0], src[1], src[2]);
+ break;
+ case UMin3AMD:
+ val->ssa->def = nir_umin3(nb, src[0], src[1], src[2]);
+ break;
+ case SMin3AMD:
+ val->ssa->def = nir_imin3(nb, src[0], src[1], src[2]);
+ break;
+ case FMax3AMD:
+ val->ssa->def = nir_fmax3(nb, src[0], src[1], src[2]);
+ break;
+ case UMax3AMD:
+ val->ssa->def = nir_umax3(nb, src[0], src[1], src[2]);
+ break;
+ case SMax3AMD:
+ val->ssa->def = nir_imax3(nb, src[0], src[1], src[2]);
+ break;
+ case FMid3AMD:
+ val->ssa->def = nir_fmed3(nb, src[0], src[1], src[2]);
+ break;
+ case UMid3AMD:
+ val->ssa->def = nir_umed3(nb, src[0], src[1], src[2]);
+ break;
+ case SMid3AMD:
+ val->ssa->def = nir_imed3(nb, src[0], src[1], src[2]);
+ break;
+ default:
+ unreachable("unknown opcode\n");
+ break;
+ }
+
+ return true;
+}
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 70f660fbd48..bbc63ad20d6 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -735,4 +735,6 @@ vtn_u64_literal(const uint32_t *w)
bool vtn_handle_amd_gcn_shader_instruction(struct vtn_builder *b, uint32_t ext_opcode,
const uint32_t *words, unsigned count);
+bool vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, uint32_t ext_opcode,
+ const uint32_t *words, unsigned count);
#endif /* _VTN_PRIVATE_H_ */