spirv: add support for SPV_AMD_shader_trinary_minmax
authorDave Airlie <airlied@redhat.com>
Wed, 28 Dec 2016 00:33:07 +0000 (00:33 +0000)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Wed, 28 Mar 2018 23:29:29 +0000 (01:29 +0200)
Co-authored-by: Daniel Schürmann <daniel.schuermann@campus.tu-berlin.de>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/compiler/shader_info.h
src/compiler/spirv/spirv_to_nir.c
src/compiler/spirv/vtn_amd.c
src/compiler/spirv/vtn_private.h

index 0eeb2ca58eab5c0e8d3ccc1aa7b2ec63bd63240d..737e9cffa8628cb68145dd26b5096a91f9e09a01 100644 (file)
@@ -52,6 +52,7 @@ struct spirv_supported_capabilities {
    bool subgroup_shuffle;
    bool subgroup_vote;
    bool gcn_shader;
+   bool trinary_minmax;
 };
 
 typedef struct shader_info {
index 7888e1b746311f6b88670e18a4de76edc1eff96b..4297622979eb98cc225ef59b6f089cf3333cc8ab 100644 (file)
@@ -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");
       }
index b2b3e055f0addfcbab7282a6535baee1fbeeb37a..320e3b0586ca13ee4e12172c69b0e8b7d589898a 100644 (file)
@@ -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;
+}
index 70f660fbd489fd67f52269bc8c10557499b8d75b..bbc63ad20d664097d355f759d71227b50490b1ef 100644 (file)
@@ -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_ */