From: Dave Airlie <airl...@redhat.com> Signed-off-by: Dave Airlie <airl...@redhat.com> --- 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 b1e200070f..01a3060352 100644 --- a/src/compiler/shader_info.h +++ b/src/compiler/shader_info.h @@ -51,6 +51,7 @@ struct spirv_supported_capabilities { bool subgroup_quad; bool subgroup_shuffle; bool subgroup_vote; + bool AMD_shader_trinary_minmax; }; /* The supported extensions which add extended instructions */ diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 6a358c5973..ddd1b8fe79 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -376,6 +376,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->exts.AMD_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.AMD_shader_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 b2b3e055f0..313e015f41 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 a8fa612384..76bb7fa6b1 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.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev