diff options
-rw-r--r-- | src/compiler/shader_info.h | 1 | ||||
-rw-r--r-- | src/compiler/spirv/spirv_to_nir.c | 3 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_amd.c | 52 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_private.h | 2 |
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_ */ |