fix glsl450 for composites
[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->type = vtn_value(b, w[1], vtn_value_type_type)->type;
143 val->ssa = rzalloc(b, struct vtn_ssa_value);
144 val->ssa->type = val->type;
145
146 /* Collect the various SSA sources */
147 unsigned num_inputs = count - 5;
148 nir_ssa_def *src[3];
149 for (unsigned i = 0; i < num_inputs; i++)
150 src[i] = vtn_ssa_value(b, w[i + 5])->def;
151
152 nir_op op;
153 switch (entrypoint) {
154 case Round: op = nir_op_fround_even; break; /* TODO */
155 case RoundEven: op = nir_op_fround_even; break;
156 case Trunc: op = nir_op_ftrunc; break;
157 case Abs: op = nir_op_fabs; break;
158 case Sign: op = nir_op_fsign; break;
159 case Floor: op = nir_op_ffloor; break;
160 case Ceil: op = nir_op_fceil; break;
161 case Fract: op = nir_op_ffract; break;
162 case Radians:
163 val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 0.01745329251));
164 return;
165 case Degrees:
166 val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 57.2957795131));
167 return;
168 case Sin: op = nir_op_fsin; break;
169 case Cos: op = nir_op_fcos; break;
170 case Tan:
171 val->ssa->def = nir_fdiv(&b->nb, nir_fsin(&b->nb, src[0]),
172 nir_fcos(&b->nb, src[0]));
173 return;
174 case Pow: op = nir_op_fpow; break;
175 case Exp2: op = nir_op_fexp2; break;
176 case Log2: op = nir_op_flog2; break;
177 case Sqrt: op = nir_op_fsqrt; break;
178 case InverseSqrt: op = nir_op_frsq; break;
179
180 case Modf: op = nir_op_fmod; break;
181 case Min: op = nir_op_fmin; break;
182 case Max: op = nir_op_fmax; break;
183 case Mix: op = nir_op_flrp; break;
184 case Step:
185 val->ssa->def = nir_sge(&b->nb, src[1], src[0]);
186 return;
187
188 case FloatBitsToInt:
189 case FloatBitsToUint:
190 case IntBitsToFloat:
191 case UintBitsToFloat:
192 /* Probably going to be removed from the final version of the spec. */
193 val->ssa->def = src[0];
194 return;
195
196 case Fma: op = nir_op_ffma; break;
197 case Ldexp: op = nir_op_ldexp; break;
198
199 /* Packing/Unpacking functions */
200 case PackSnorm4x8: op = nir_op_pack_snorm_4x8; break;
201 case PackUnorm4x8: op = nir_op_pack_unorm_4x8; break;
202 case PackSnorm2x16: op = nir_op_pack_snorm_2x16; break;
203 case PackUnorm2x16: op = nir_op_pack_unorm_2x16; break;
204 case PackHalf2x16: op = nir_op_pack_half_2x16; break;
205 case UnpackSnorm4x8: op = nir_op_unpack_snorm_4x8; break;
206 case UnpackUnorm4x8: op = nir_op_unpack_unorm_4x8; break;
207 case UnpackSnorm2x16: op = nir_op_unpack_snorm_2x16; break;
208 case UnpackUnorm2x16: op = nir_op_unpack_unorm_2x16; break;
209 case UnpackHalf2x16: op = nir_op_unpack_half_2x16; break;
210
211 case Length:
212 val->ssa->def = build_length(&b->nb, src[0]);
213 return;
214 case Distance:
215 val->ssa->def = build_length(&b->nb, nir_fsub(&b->nb, src[0], src[1]));
216 return;
217 case Normalize:
218 val->ssa->def = nir_fdiv(&b->nb, src[0], build_length(&b->nb, src[0]));
219 return;
220
221 case UaddCarry: op = nir_op_uadd_carry; break;
222 case UsubBorrow: op = nir_op_usub_borrow; break;
223 case BitfieldExtract: op = nir_op_ubitfield_extract; break; /* TODO */
224 case BitfieldInsert: op = nir_op_bitfield_insert; break;
225 case BitfieldReverse: op = nir_op_bitfield_reverse; break;
226 case BitCount: op = nir_op_bit_count; break;
227 case FindLSB: op = nir_op_find_lsb; break;
228 case FindMSB: op = nir_op_ufind_msb; break; /* TODO */
229
230 case Exp:
231 case Log:
232 case Clamp:
233 case Asin:
234 case Acos:
235 case Atan:
236 case Atan2:
237 case Sinh:
238 case Cosh:
239 case Tanh:
240 case Asinh:
241 case Acosh:
242 case Atanh:
243 case SmoothStep:
244 case Frexp:
245 case PackDouble2x32:
246 case UnpackDouble2x32:
247 case Cross:
248 case Ftransform:
249 case FaceForward:
250 case Reflect:
251 case Refract:
252 case UmulExtended:
253 case ImulExtended:
254 default:
255 unreachable("Unhandled opcode");
256 }
257
258 nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
259 nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
260 glsl_get_vector_elements(val->type), val->name);
261 val->ssa->def = &instr->dest.dest.ssa;
262
263 for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
264 instr->src[i].src = nir_src_for_ssa(src[i]);
265
266 nir_builder_instr_insert(&b->nb, &instr->instr);
267 }
268
269 bool
270 vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
271 const uint32_t *words, unsigned count)
272 {
273 switch ((enum GLSL450Entrypoint)ext_opcode) {
274 case Determinant:
275 case MatrixInverse:
276 case InterpolateAtCentroid:
277 case InterpolateAtSample:
278 case InterpolateAtOffset:
279 unreachable("Unhandled opcode");
280
281 default:
282 handle_glsl450_alu(b, (enum GLSL450Entrypoint)ext_opcode, words, count);
283 }
284
285 return true;
286 }