From fe5d5d19b01bd5d1407943181d613d18a44aa42b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 28 Dec 2016 00:33:07 +0000 Subject: [PATCH] spirv: add support for SPV_AMD_shader_trinary_minmax MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Schürmann Signed-off-by: Dave Airlie Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Samuel Pitoiset --- src/compiler/shader_info.h | 1 + src/compiler/spirv/spirv_to_nir.c | 3 +++ src/compiler/spirv/vtn_amd.c | 52 +++++++++++++++++++++++++++++++++++++++ src/compiler/spirv/vtn_private.h | 2 ++ 4 files changed, 58 insertions(+) diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h index 0eeb2ca..737e9cf 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 7888e1b..4297622 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 b2b3e05..320e3b0 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 70f660f..bbc63ad 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_ */ -- 2.7.4