Merge remote-tracking branch 'mesa-public/master' 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
30 enum GLSL450Entrypoint {
31 Round = 0,
32 RoundEven = 1,
33 Trunc = 2,
34 Abs = 3,
35 Sign = 4,
36 Floor = 5,
37 Ceil = 6,
38 Fract = 7,
39
40 Radians = 8,
41 Degrees = 9,
42 Sin = 10,
43 Cos = 11,
44 Tan = 12,
45 Asin = 13,
46 Acos = 14,
47 Atan = 15,
48 Sinh = 16,
49 Cosh = 17,
50 Tanh = 18,
51 Asinh = 19,
52 Acosh = 20,
53 Atanh = 21,
54 Atan2 = 22,
55
56 Pow = 23,
57 Exp = 24,
58 Log = 25,
59 Exp2 = 26,
60 Log2 = 27,
61 Sqrt = 28,
62 InverseSqrt = 29,
63
64 Determinant = 30,
65 MatrixInverse = 31,
66
67 Modf = 32, // second argument needs the OpVariable = , not an OpLoad
68 Min = 33,
69 Max = 34,
70 Clamp = 35,
71 Mix = 36,
72 Step = 37,
73 SmoothStep = 38,
74
75 FloatBitsToInt = 39,
76 FloatBitsToUint = 40,
77 IntBitsToFloat = 41,
78 UintBitsToFloat = 42,
79
80 Fma = 43,
81 Frexp = 44,
82 Ldexp = 45,
83
84 PackSnorm4x8 = 46,
85 PackUnorm4x8 = 47,
86 PackSnorm2x16 = 48,
87 PackUnorm2x16 = 49,
88 PackHalf2x16 = 50,
89 PackDouble2x32 = 51,
90 UnpackSnorm2x16 = 52,
91 UnpackUnorm2x16 = 53,
92 UnpackHalf2x16 = 54,
93 UnpackSnorm4x8 = 55,
94 UnpackUnorm4x8 = 56,
95 UnpackDouble2x32 = 57,
96
97 Length = 58,
98 Distance = 59,
99 Cross = 60,
100 Normalize = 61,
101 Ftransform = 62,
102 FaceForward = 63,
103 Reflect = 64,
104 Refract = 65,
105
106 UaddCarry = 66,
107 UsubBorrow = 67,
108 UmulExtended = 68,
109 ImulExtended = 69,
110 BitfieldExtract = 70,
111 BitfieldInsert = 71,
112 BitfieldReverse = 72,
113 BitCount = 73,
114 FindLSB = 74,
115 FindMSB = 75,
116
117 InterpolateAtCentroid = 76,
118 InterpolateAtSample = 77,
119 InterpolateAtOffset = 78,
120
121 Count
122 };
123
124 static nir_ssa_def*
125 build_length(nir_builder *b, nir_ssa_def *vec)
126 {
127 switch (vec->num_components) {
128 case 1: return nir_fsqrt(b, nir_fmul(b, vec, vec));
129 case 2: return nir_fsqrt(b, nir_fdot2(b, vec, vec));
130 case 3: return nir_fsqrt(b, nir_fdot3(b, vec, vec));
131 case 4: return nir_fsqrt(b, nir_fdot4(b, vec, vec));
132 default:
133 unreachable("Invalid number of components");
134 }
135 }
136
137 static void
138 handle_glsl450_alu(struct vtn_builder *b, enum GLSL450Entrypoint entrypoint,
139 const uint32_t *w, unsigned count)
140 {
141 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
142 val->ssa = rzalloc(b, struct vtn_ssa_value);
143 val->ssa->type = vtn_value(b, w[1], vtn_value_type_type)->type->type;
144
145 /* Collect the various SSA sources */
146 unsigned num_inputs = count - 5;
147 nir_ssa_def *src[3];
148 for (unsigned i = 0; i < num_inputs; i++)
149 src[i] = vtn_ssa_value(b, w[i + 5])->def;
150
151 nir_op op;
152 switch (entrypoint) {
153 case Round: op = nir_op_fround_even; break; /* TODO */
154 case RoundEven: op = nir_op_fround_even; break;
155 case Trunc: op = nir_op_ftrunc; break;
156 case Abs: op = nir_op_fabs; break;
157 case Sign: op = nir_op_fsign; break;
158 case Floor: op = nir_op_ffloor; break;
159 case Ceil: op = nir_op_fceil; break;
160 case Fract: op = nir_op_ffract; break;
161 case Radians:
162 val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 0.01745329251));
163 return;
164 case Degrees:
165 val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 57.2957795131));
166 return;
167 case Sin: op = nir_op_fsin; break;
168 case Cos: op = nir_op_fcos; break;
169 case Tan:
170 val->ssa->def = nir_fdiv(&b->nb, nir_fsin(&b->nb, src[0]),
171 nir_fcos(&b->nb, src[0]));
172 return;
173 case Pow: op = nir_op_fpow; break;
174 case Exp2: op = nir_op_fexp2; break;
175 case Log2: op = nir_op_flog2; break;
176 case Sqrt: op = nir_op_fsqrt; break;
177 case InverseSqrt: op = nir_op_frsq; break;
178
179 case Modf: op = nir_op_fmod; break;
180 case Min: op = nir_op_fmin; break;
181 case Max: op = nir_op_fmax; break;
182 case Mix: op = nir_op_flrp; break;
183 case Step:
184 val->ssa->def = nir_sge(&b->nb, src[1], src[0]);
185 return;
186
187 case FloatBitsToInt:
188 case FloatBitsToUint:
189 case IntBitsToFloat:
190 case UintBitsToFloat:
191 /* Probably going to be removed from the final version of the spec. */
192 val->ssa->def = src[0];
193 return;
194
195 case Fma: op = nir_op_ffma; break;
196 case Ldexp: op = nir_op_ldexp; break;
197
198 /* Packing/Unpacking functions */
199 case PackSnorm4x8: op = nir_op_pack_snorm_4x8; break;
200 case PackUnorm4x8: op = nir_op_pack_unorm_4x8; break;
201 case PackSnorm2x16: op = nir_op_pack_snorm_2x16; break;
202 case PackUnorm2x16: op = nir_op_pack_unorm_2x16; break;
203 case PackHalf2x16: op = nir_op_pack_half_2x16; break;
204 case UnpackSnorm4x8: op = nir_op_unpack_snorm_4x8; break;
205 case UnpackUnorm4x8: op = nir_op_unpack_unorm_4x8; break;
206 case UnpackSnorm2x16: op = nir_op_unpack_snorm_2x16; break;
207 case UnpackUnorm2x16: op = nir_op_unpack_unorm_2x16; break;
208 case UnpackHalf2x16: op = nir_op_unpack_half_2x16; break;
209
210 case Length:
211 val->ssa->def = build_length(&b->nb, src[0]);
212 return;
213 case Distance:
214 val->ssa->def = build_length(&b->nb, nir_fsub(&b->nb, src[0], src[1]));
215 return;
216 case Normalize:
217 val->ssa->def = nir_fdiv(&b->nb, src[0], build_length(&b->nb, src[0]));
218 return;
219
220 case UaddCarry: op = nir_op_uadd_carry; break;
221 case UsubBorrow: op = nir_op_usub_borrow; break;
222 case BitfieldExtract: op = nir_op_ubitfield_extract; break; /* TODO */
223 case BitfieldInsert: op = nir_op_bitfield_insert; break;
224 case BitfieldReverse: op = nir_op_bitfield_reverse; break;
225 case BitCount: op = nir_op_bit_count; break;
226 case FindLSB: op = nir_op_find_lsb; break;
227 case FindMSB: op = nir_op_ufind_msb; break; /* TODO */
228
229 case Exp:
230 case Log:
231 case Clamp:
232 case Asin:
233 case Acos:
234 case Atan:
235 case Atan2:
236 case Sinh:
237 case Cosh:
238 case Tanh:
239 case Asinh:
240 case Acosh:
241 case Atanh:
242 case SmoothStep:
243 case Frexp:
244 case PackDouble2x32:
245 case UnpackDouble2x32:
246 case Cross:
247 case Ftransform:
248 case FaceForward:
249 case Reflect:
250 case Refract:
251 case UmulExtended:
252 case ImulExtended:
253 default:
254 unreachable("Unhandled opcode");
255 }
256
257 nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
258 nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
259 glsl_get_vector_elements(val->ssa->type), val->name);
260 val->ssa->def = &instr->dest.dest.ssa;
261
262 for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
263 instr->src[i].src = nir_src_for_ssa(src[i]);
264
265 nir_builder_instr_insert(&b->nb, &instr->instr);
266 }
267
268 bool
269 vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
270 const uint32_t *words, unsigned count)
271 {
272 switch ((enum GLSL450Entrypoint)ext_opcode) {
273 case Determinant:
274 case MatrixInverse:
275 case InterpolateAtCentroid:
276 case InterpolateAtSample:
277 case InterpolateAtOffset:
278 unreachable("Unhandled opcode");
279
280 default:
281 handle_glsl450_alu(b, (enum GLSL450Entrypoint)ext_opcode, words, count);
282 }
283
284 return true;
285 }