Merge branch 'master' of ../mesa into vulkan
[mesa.git] / src / glsl / nir / spirv_glsl450_to_nir.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Jason Ekstrand (jason@jlekstrand.net)
25 *
26 */
27
28 #include "spirv_to_nir_private.h"
29 #include "spirv_glsl450.h"
30
31 static nir_ssa_def*
32 build_length(nir_builder *b, nir_ssa_def *vec)
33 {
34 switch (vec->num_components) {
35 case 1: return nir_fsqrt(b, nir_fmul(b, vec, vec));
36 case 2: return nir_fsqrt(b, nir_fdot2(b, vec, vec));
37 case 3: return nir_fsqrt(b, nir_fdot3(b, vec, vec));
38 case 4: return nir_fsqrt(b, nir_fdot4(b, vec, vec));
39 default:
40 unreachable("Invalid number of components");
41 }
42 }
43
44 static void
45 handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
46 const uint32_t *w, unsigned count)
47 {
48 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
49 val->ssa = rzalloc(b, struct vtn_ssa_value);
50 val->ssa->type = vtn_value(b, w[1], vtn_value_type_type)->type->type;
51
52 /* Collect the various SSA sources */
53 unsigned num_inputs = count - 5;
54 nir_ssa_def *src[3];
55 for (unsigned i = 0; i < num_inputs; i++)
56 src[i] = vtn_ssa_value(b, w[i + 5])->def;
57
58 nir_op op;
59 switch (entrypoint) {
60 case GLSLstd450Round: op = nir_op_fround_even; break; /* TODO */
61 case GLSLstd450RoundEven: op = nir_op_fround_even; break;
62 case GLSLstd450Trunc: op = nir_op_ftrunc; break;
63 case GLSLstd450FAbs: op = nir_op_fabs; break;
64 case GLSLstd450FSign: op = nir_op_fsign; break;
65 case GLSLstd450Floor: op = nir_op_ffloor; break;
66 case GLSLstd450Ceil: op = nir_op_fceil; break;
67 case GLSLstd450Fract: op = nir_op_ffract; break;
68 case GLSLstd450Radians:
69 val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 0.01745329251));
70 return;
71 case GLSLstd450Degrees:
72 val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 57.2957795131));
73 return;
74 case GLSLstd450Sin: op = nir_op_fsin; break;
75 case GLSLstd450Cos: op = nir_op_fcos; break;
76 case GLSLstd450Tan:
77 val->ssa->def = nir_fdiv(&b->nb, nir_fsin(&b->nb, src[0]),
78 nir_fcos(&b->nb, src[0]));
79 return;
80 case GLSLstd450Pow: op = nir_op_fpow; break;
81 case GLSLstd450Exp2: op = nir_op_fexp2; break;
82 case GLSLstd450Log2: op = nir_op_flog2; break;
83 case GLSLstd450Sqrt: op = nir_op_fsqrt; break;
84 case GLSLstd450InverseSqrt: op = nir_op_frsq; break;
85
86 case GLSLstd450Modf: op = nir_op_fmod; break;
87 case GLSLstd450FMin: op = nir_op_fmin; break;
88 case GLSLstd450FMax: op = nir_op_fmax; break;
89 case GLSLstd450Mix: op = nir_op_flrp; break;
90 case GLSLstd450Step:
91 val->ssa->def = nir_sge(&b->nb, src[1], src[0]);
92 return;
93
94 case GLSLstd450Fma: op = nir_op_ffma; break;
95 case GLSLstd450Ldexp: op = nir_op_ldexp; break;
96
97 /* Packing/Unpacking functions */
98 case GLSLstd450PackSnorm4x8: op = nir_op_pack_snorm_4x8; break;
99 case GLSLstd450PackUnorm4x8: op = nir_op_pack_unorm_4x8; break;
100 case GLSLstd450PackSnorm2x16: op = nir_op_pack_snorm_2x16; break;
101 case GLSLstd450PackUnorm2x16: op = nir_op_pack_unorm_2x16; break;
102 case GLSLstd450PackHalf2x16: op = nir_op_pack_half_2x16; break;
103 case GLSLstd450UnpackSnorm4x8: op = nir_op_unpack_snorm_4x8; break;
104 case GLSLstd450UnpackUnorm4x8: op = nir_op_unpack_unorm_4x8; break;
105 case GLSLstd450UnpackSnorm2x16: op = nir_op_unpack_snorm_2x16; break;
106 case GLSLstd450UnpackUnorm2x16: op = nir_op_unpack_unorm_2x16; break;
107 case GLSLstd450UnpackHalf2x16: op = nir_op_unpack_half_2x16; break;
108
109 case GLSLstd450Length:
110 val->ssa->def = build_length(&b->nb, src[0]);
111 return;
112 case GLSLstd450Distance:
113 val->ssa->def = build_length(&b->nb, nir_fsub(&b->nb, src[0], src[1]));
114 return;
115 case GLSLstd450Normalize:
116 val->ssa->def = nir_fdiv(&b->nb, src[0], build_length(&b->nb, src[0]));
117 return;
118
119 case GLSLstd450AddCarry: op = nir_op_uadd_carry; break;
120 case GLSLstd450SubBorrow: op = nir_op_usub_borrow; break;
121
122 case GLSLstd450Exp:
123 case GLSLstd450Log:
124 case GLSLstd450FClamp:
125 case GLSLstd450UClamp:
126 case GLSLstd450SClamp:
127 case GLSLstd450Asin:
128 case GLSLstd450Acos:
129 case GLSLstd450Atan:
130 case GLSLstd450Atan2:
131 case GLSLstd450Sinh:
132 case GLSLstd450Cosh:
133 case GLSLstd450Tanh:
134 case GLSLstd450Asinh:
135 case GLSLstd450Acosh:
136 case GLSLstd450Atanh:
137 case GLSLstd450SmoothStep:
138 case GLSLstd450Frexp:
139 case GLSLstd450PackDouble2x32:
140 case GLSLstd450UnpackDouble2x32:
141 case GLSLstd450Cross:
142 case GLSLstd450FaceForward:
143 case GLSLstd450Reflect:
144 case GLSLstd450Refract:
145 case GLSLstd450MulExtended:
146 default:
147 unreachable("Unhandled opcode");
148 }
149
150 nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
151 nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
152 glsl_get_vector_elements(val->ssa->type), val->name);
153 instr->dest.write_mask = (1 << instr->dest.dest.ssa.num_components) - 1;
154 val->ssa->def = &instr->dest.dest.ssa;
155
156 for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
157 instr->src[i].src = nir_src_for_ssa(src[i]);
158
159 nir_builder_instr_insert(&b->nb, &instr->instr);
160 }
161
162 bool
163 vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
164 const uint32_t *words, unsigned count)
165 {
166 switch ((enum GLSLstd450)ext_opcode) {
167 case GLSLstd450Determinant:
168 case GLSLstd450MatrixInverse:
169 case GLSLstd450InterpolateAtCentroid:
170 case GLSLstd450InterpolateAtSample:
171 case GLSLstd450InterpolateAtOffset:
172 unreachable("Unhandled opcode");
173
174 default:
175 handle_glsl450_alu(b, (enum GLSLstd450)ext_opcode, words, count);
176 }
177
178 return true;
179 }