1/* 2 * Copyright © 2018 Valve Corporation 3 * Copyright © 2017 Red Hat 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 * 24 */ 25 26#include "vtn_private.h" 27#include "GLSL.ext.AMD.h" 28 29bool 30vtn_handle_amd_gcn_shader_instruction(struct vtn_builder *b, SpvOp ext_opcode, 31 const uint32_t *w, unsigned count) 32{ 33 const struct glsl_type *dest_type = 34 vtn_value(b, w[1], vtn_value_type_type)->type->type; 35 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); 36 val->ssa = vtn_create_ssa_value(b, dest_type); 37 38 switch ((enum GcnShaderAMD)ext_opcode) { 39 case CubeFaceIndexAMD: 40 val->ssa->def = nir_cube_face_index(&b->nb, vtn_ssa_value(b, w[5])->def); 41 break; 42 case CubeFaceCoordAMD: 43 val->ssa->def = nir_cube_face_coord(&b->nb, vtn_ssa_value(b, w[5])->def); 44 break; 45 case TimeAMD: { 46 nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->nb.shader, 47 nir_intrinsic_shader_clock); 48 nir_ssa_dest_init(&intrin->instr, &intrin->dest, 2, 32, NULL); 49 nir_builder_instr_insert(&b->nb, &intrin->instr); 50 val->ssa->def = nir_pack_64_2x32(&b->nb, &intrin->dest.ssa); 51 break; 52 } 53 default: 54 unreachable("Invalid opcode"); 55 } 56 return true; 57} 58 59bool 60vtn_handle_amd_shader_trinary_minmax_instruction(struct vtn_builder *b, SpvOp ext_opcode, 61 const uint32_t *w, unsigned count) 62{ 63 struct nir_builder *nb = &b->nb; 64 const struct glsl_type *dest_type = 65 vtn_value(b, w[1], vtn_value_type_type)->type->type; 66 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); 67 val->ssa = vtn_create_ssa_value(b, dest_type); 68 69 unsigned num_inputs = count - 5; 70 assert(num_inputs == 3); 71 nir_ssa_def *src[3] = { NULL, }; 72 for (unsigned i = 0; i < num_inputs; i++) 73 src[i] = vtn_ssa_value(b, w[i + 5])->def; 74 75 switch ((enum ShaderTrinaryMinMaxAMD)ext_opcode) { 76 case FMin3AMD: 77 val->ssa->def = nir_fmin3(nb, src[0], src[1], src[2]); 78 break; 79 case UMin3AMD: 80 val->ssa->def = nir_umin3(nb, src[0], src[1], src[2]); 81 break; 82 case SMin3AMD: 83 val->ssa->def = nir_imin3(nb, src[0], src[1], src[2]); 84 break; 85 case FMax3AMD: 86 val->ssa->def = nir_fmax3(nb, src[0], src[1], src[2]); 87 break; 88 case UMax3AMD: 89 val->ssa->def = nir_umax3(nb, src[0], src[1], src[2]); 90 break; 91 case SMax3AMD: 92 val->ssa->def = nir_imax3(nb, src[0], src[1], src[2]); 93 break; 94 case FMid3AMD: 95 val->ssa->def = nir_fmed3(nb, src[0], src[1], src[2]); 96 break; 97 case UMid3AMD: 98 val->ssa->def = nir_umed3(nb, src[0], src[1], src[2]); 99 break; 100 case SMid3AMD: 101 val->ssa->def = nir_imed3(nb, src[0], src[1], src[2]); 102 break; 103 default: 104 unreachable("unknown opcode\n"); 105 break; 106 } 107 108 return true; 109} 110