nir/spirv: Split the core datastructures into a header file
[mesa.git] / src / glsl / nir / spirv_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 "nir_vla.h"
30
31 nir_ssa_def *
32 vtn_ssa_value(struct vtn_builder *b, uint32_t value_id)
33 {
34 return vtn_value(b, value_id, vtn_value_type_ssa)->ssa;
35 }
36
37 static char *
38 vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
39 unsigned word_count)
40 {
41 return ralloc_strndup(b, (char *)words, (word_count - 2) * sizeof(*words));
42 }
43
44 static const uint32_t *
45 vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
46 const uint32_t *end, vtn_instruction_handler handler)
47 {
48 const uint32_t *w = start;
49 while (w < end) {
50 SpvOp opcode = w[0] & SpvOpCodeMask;
51 unsigned count = w[0] >> SpvWordCountShift;
52 assert(count >= 1 && w + count <= end);
53
54 if (!handler(b, opcode, w, count))
55 return w;
56
57 w += count;
58 }
59 assert(w == end);
60 return w;
61 }
62
63 static void
64 vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
65 const uint32_t *w, unsigned count)
66 {
67 switch (opcode) {
68 case SpvOpExtInstImport:
69 /* Do nothing for the moment */
70 break;
71
72 case SpvOpExtInst:
73 default:
74 unreachable("Unhandled opcode");
75 }
76 }
77
78 static void
79 _foreach_decoration_helper(struct vtn_builder *b,
80 struct vtn_value *base_value,
81 struct vtn_value *value,
82 vtn_decoration_foreach_cb cb, void *data)
83 {
84 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
85 if (dec->group) {
86 assert(dec->group->value_type == vtn_value_type_decoration_group);
87 _foreach_decoration_helper(b, base_value, dec->group, cb, data);
88 } else {
89 cb(b, base_value, dec, data);
90 }
91 }
92 }
93
94 /** Iterates (recursively if needed) over all of the decorations on a value
95 *
96 * This function iterates over all of the decorations applied to a given
97 * value. If it encounters a decoration group, it recurses into the group
98 * and iterates over all of those decorations as well.
99 */
100 void
101 vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
102 vtn_decoration_foreach_cb cb, void *data)
103 {
104 _foreach_decoration_helper(b, value, value, cb, data);
105 }
106
107 static void
108 vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
109 const uint32_t *w, unsigned count)
110 {
111 switch (opcode) {
112 case SpvOpDecorationGroup:
113 vtn_push_value(b, w[1], vtn_value_type_undef);
114 break;
115
116 case SpvOpDecorate: {
117 struct vtn_value *val = &b->values[w[1]];
118
119 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
120 dec->decoration = w[2];
121 dec->literals = &w[3];
122
123 /* Link into the list */
124 dec->next = val->decoration;
125 val->decoration = dec;
126 break;
127 }
128
129 case SpvOpGroupDecorate: {
130 struct vtn_value *group = &b->values[w[1]];
131 assert(group->value_type == vtn_value_type_decoration_group);
132
133 for (unsigned i = 2; i < count; i++) {
134 struct vtn_value *val = &b->values[w[i]];
135 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
136 dec->group = group;
137
138 /* Link into the list */
139 dec->next = val->decoration;
140 val->decoration = dec;
141 }
142 break;
143 }
144
145 case SpvOpGroupMemberDecorate:
146 assert(!"Bad instruction. Khronos Bug #13513");
147 break;
148
149 default:
150 unreachable("Unhandled opcode");
151 }
152 }
153
154 static const struct glsl_type *
155 vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
156 const uint32_t *args, unsigned count)
157 {
158 switch (opcode) {
159 case SpvOpTypeVoid:
160 return glsl_void_type();
161 case SpvOpTypeBool:
162 return glsl_bool_type();
163 case SpvOpTypeInt:
164 return glsl_int_type();
165 case SpvOpTypeFloat:
166 return glsl_float_type();
167
168 case SpvOpTypeVector: {
169 const struct glsl_type *base =
170 vtn_value(b, args[0], vtn_value_type_type)->type;
171 unsigned elems = args[1];
172
173 assert(glsl_type_is_scalar(base));
174 return glsl_vector_type(glsl_get_base_type(base), elems);
175 }
176
177 case SpvOpTypeMatrix: {
178 const struct glsl_type *base =
179 vtn_value(b, args[0], vtn_value_type_type)->type;
180 unsigned columns = args[1];
181
182 assert(glsl_type_is_vector(base));
183 return glsl_matrix_type(glsl_get_base_type(base),
184 glsl_get_vector_elements(base),
185 columns);
186 }
187
188 case SpvOpTypeArray:
189 return glsl_array_type(b->values[args[0]].type, args[1]);
190
191 case SpvOpTypeStruct: {
192 NIR_VLA(struct glsl_struct_field, fields, count);
193 for (unsigned i = 0; i < count; i++) {
194 /* TODO: Handle decorators */
195 fields[i].type = vtn_value(b, args[i], vtn_value_type_type)->type;
196 fields[i].name = ralloc_asprintf(b, "field%d", i);
197 fields[i].location = -1;
198 fields[i].interpolation = 0;
199 fields[i].centroid = 0;
200 fields[i].sample = 0;
201 fields[i].matrix_layout = 2;
202 fields[i].stream = -1;
203 }
204 return glsl_struct_type(fields, count, "struct");
205 }
206
207 case SpvOpTypeFunction: {
208 const struct glsl_type *return_type = b->values[args[0]].type;
209 NIR_VLA(struct glsl_function_param, params, count - 1);
210 for (unsigned i = 1; i < count; i++) {
211 params[i - 1].type = vtn_value(b, args[i], vtn_value_type_type)->type;
212
213 /* FIXME: */
214 params[i - 1].in = true;
215 params[i - 1].out = true;
216 }
217 return glsl_function_type(return_type, params, count - 1);
218 }
219
220 case SpvOpTypePointer:
221 /* FIXME: For now, we'll just do the really lame thing and return
222 * the same type. The validator should ensure that the proper number
223 * of dereferences happen
224 */
225 return vtn_value(b, args[1], vtn_value_type_type)->type;
226
227 case SpvOpTypeSampler:
228 case SpvOpTypeRuntimeArray:
229 case SpvOpTypeOpaque:
230 case SpvOpTypeEvent:
231 case SpvOpTypeDeviceEvent:
232 case SpvOpTypeReserveId:
233 case SpvOpTypeQueue:
234 case SpvOpTypePipe:
235 default:
236 unreachable("Unhandled opcode");
237 }
238 }
239
240 static void
241 vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
242 const uint32_t *w, unsigned count)
243 {
244 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);
245 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
246 val->constant = ralloc(b, nir_constant);
247 switch (opcode) {
248 case SpvOpConstantTrue:
249 assert(val->type == glsl_bool_type());
250 val->constant->value.u[0] = NIR_TRUE;
251 break;
252 case SpvOpConstantFalse:
253 assert(val->type == glsl_bool_type());
254 val->constant->value.u[0] = NIR_FALSE;
255 break;
256 case SpvOpConstant:
257 assert(glsl_type_is_scalar(val->type));
258 val->constant->value.u[0] = w[3];
259 break;
260 case SpvOpConstantComposite: {
261 unsigned elem_count = count - 3;
262 nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
263 for (unsigned i = 0; i < elem_count; i++)
264 elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
265
266 switch (glsl_get_base_type(val->type)) {
267 case GLSL_TYPE_UINT:
268 case GLSL_TYPE_INT:
269 case GLSL_TYPE_FLOAT:
270 case GLSL_TYPE_BOOL:
271 if (glsl_type_is_matrix(val->type)) {
272 unsigned rows = glsl_get_vector_elements(val->type);
273 assert(glsl_get_matrix_columns(val->type) == elem_count);
274 for (unsigned i = 0; i < elem_count; i++)
275 for (unsigned j = 0; j < rows; j++)
276 val->constant->value.u[rows * i + j] = elems[i]->value.u[j];
277 } else {
278 assert(glsl_type_is_vector(val->type));
279 assert(glsl_get_vector_elements(val->type) == elem_count);
280 for (unsigned i = 0; i < elem_count; i++)
281 val->constant->value.u[i] = elems[i]->value.u[0];
282 }
283 ralloc_free(elems);
284 break;
285
286 case GLSL_TYPE_STRUCT:
287 case GLSL_TYPE_ARRAY:
288 ralloc_steal(val->constant, elems);
289 val->constant->elements = elems;
290 break;
291
292 default:
293 unreachable("Unsupported type for constants");
294 }
295 break;
296 }
297
298 default:
299 unreachable("Unhandled opcode");
300 }
301 }
302
303 static void
304 var_decoration_cb(struct vtn_builder *b, struct vtn_value *val,
305 const struct vtn_decoration *dec, void *void_var)
306 {
307 assert(val->value_type == vtn_value_type_deref);
308 assert(val->deref->deref.child == NULL);
309 assert(val->deref->var == void_var);
310
311 nir_variable *var = void_var;
312 switch (dec->decoration) {
313 case SpvDecorationPrecisionLow:
314 case SpvDecorationPrecisionMedium:
315 case SpvDecorationPrecisionHigh:
316 break; /* FIXME: Do nothing with these for now. */
317 case SpvDecorationSmooth:
318 var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
319 break;
320 case SpvDecorationNoperspective:
321 var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
322 break;
323 case SpvDecorationFlat:
324 var->data.interpolation = INTERP_QUALIFIER_FLAT;
325 break;
326 case SpvDecorationCentroid:
327 var->data.centroid = true;
328 break;
329 case SpvDecorationSample:
330 var->data.sample = true;
331 break;
332 case SpvDecorationInvariant:
333 var->data.invariant = true;
334 break;
335 case SpvDecorationConstant:
336 assert(var->constant_initializer != NULL);
337 var->data.read_only = true;
338 break;
339 case SpvDecorationNonwritable:
340 var->data.read_only = true;
341 break;
342 case SpvDecorationLocation:
343 var->data.explicit_location = true;
344 var->data.location = dec->literals[0];
345 break;
346 case SpvDecorationComponent:
347 var->data.location_frac = dec->literals[0];
348 break;
349 case SpvDecorationIndex:
350 var->data.explicit_index = true;
351 var->data.index = dec->literals[0];
352 break;
353 case SpvDecorationBinding:
354 var->data.explicit_binding = true;
355 var->data.binding = dec->literals[0];
356 break;
357 case SpvDecorationBlock:
358 case SpvDecorationBufferBlock:
359 case SpvDecorationRowMajor:
360 case SpvDecorationColMajor:
361 case SpvDecorationGLSLShared:
362 case SpvDecorationGLSLStd140:
363 case SpvDecorationGLSLStd430:
364 case SpvDecorationGLSLPacked:
365 case SpvDecorationPatch:
366 case SpvDecorationRestrict:
367 case SpvDecorationAliased:
368 case SpvDecorationVolatile:
369 case SpvDecorationCoherent:
370 case SpvDecorationNonreadable:
371 case SpvDecorationUniform:
372 /* This is really nice but we have no use for it right now. */
373 case SpvDecorationNoStaticUse:
374 case SpvDecorationCPacked:
375 case SpvDecorationSaturatedConversion:
376 case SpvDecorationStream:
377 case SpvDecorationDescriptorSet:
378 case SpvDecorationOffset:
379 case SpvDecorationAlignment:
380 case SpvDecorationXfbBuffer:
381 case SpvDecorationStride:
382 case SpvDecorationBuiltIn:
383 case SpvDecorationFuncParamAttr:
384 case SpvDecorationFPRoundingMode:
385 case SpvDecorationFPFastMathMode:
386 case SpvDecorationLinkageAttributes:
387 case SpvDecorationSpecId:
388 default:
389 unreachable("Unhandled variable decoration");
390 }
391 }
392
393 static void
394 vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
395 const uint32_t *w, unsigned count)
396 {
397 switch (opcode) {
398 case SpvOpVariable: {
399 const struct glsl_type *type =
400 vtn_value(b, w[1], vtn_value_type_type)->type;
401 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
402
403 nir_variable *var = ralloc(b->shader, nir_variable);
404
405 var->type = type;
406 var->name = ralloc_strdup(var, val->name);
407
408 switch ((SpvStorageClass)w[3]) {
409 case SpvStorageClassUniformConstant:
410 var->data.mode = nir_var_uniform;
411 var->data.read_only = true;
412 break;
413 case SpvStorageClassInput:
414 var->data.mode = nir_var_shader_in;
415 var->data.read_only = true;
416 break;
417 case SpvStorageClassOutput:
418 var->data.mode = nir_var_shader_out;
419 break;
420 case SpvStorageClassPrivateGlobal:
421 var->data.mode = nir_var_global;
422 break;
423 case SpvStorageClassFunction:
424 var->data.mode = nir_var_local;
425 break;
426 case SpvStorageClassUniform:
427 case SpvStorageClassWorkgroupLocal:
428 case SpvStorageClassWorkgroupGlobal:
429 case SpvStorageClassGeneric:
430 case SpvStorageClassPrivate:
431 case SpvStorageClassAtomicCounter:
432 default:
433 unreachable("Unhandled variable storage class");
434 }
435
436 if (count > 4) {
437 assert(count == 5);
438 var->constant_initializer =
439 vtn_value(b, w[4], vtn_value_type_constant)->constant;
440 }
441
442 if (var->data.mode == nir_var_local) {
443 exec_list_push_tail(&b->impl->locals, &var->node);
444 } else {
445 exec_list_push_tail(&b->shader->globals, &var->node);
446 }
447
448 val->deref = nir_deref_var_create(b->shader, var);
449
450 vtn_foreach_decoration(b, val, var_decoration_cb, var);
451 break;
452 }
453
454 case SpvOpAccessChain:
455 case SpvOpInBoundsAccessChain: {
456 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
457 nir_deref_var *base = vtn_value(b, w[3], vtn_value_type_deref)->deref;
458 val->deref = nir_deref_as_var(nir_copy_deref(b, &base->deref));
459
460 nir_deref *tail = &val->deref->deref;
461 while (tail->child)
462 tail = tail->child;
463
464 for (unsigned i = 0; i < count - 4; i++) {
465 assert(w[i + 4] < b->value_id_bound);
466 struct vtn_value *idx_val = &b->values[w[i + 4]];
467
468 enum glsl_base_type base_type = glsl_get_base_type(tail->type);
469 switch (base_type) {
470 case GLSL_TYPE_UINT:
471 case GLSL_TYPE_INT:
472 case GLSL_TYPE_FLOAT:
473 case GLSL_TYPE_DOUBLE:
474 case GLSL_TYPE_BOOL:
475 case GLSL_TYPE_ARRAY: {
476 nir_deref_array *deref_arr = nir_deref_array_create(b);
477 if (base_type == GLSL_TYPE_ARRAY) {
478 deref_arr->deref.type = glsl_get_array_element(tail->type);
479 } else if (glsl_type_is_matrix(tail->type)) {
480 deref_arr->deref.type = glsl_get_column_type(tail->type);
481 } else {
482 assert(glsl_type_is_vector(tail->type));
483 deref_arr->deref.type = glsl_scalar_type(base_type);
484 }
485
486 if (idx_val->value_type == vtn_value_type_constant) {
487 unsigned idx = idx_val->constant->value.u[0];
488 deref_arr->deref_array_type = nir_deref_array_type_direct;
489 deref_arr->base_offset = idx;
490 } else {
491 assert(idx_val->value_type == vtn_value_type_ssa);
492 deref_arr->deref_array_type = nir_deref_array_type_indirect;
493 deref_arr->base_offset = 0;
494 deref_arr->indirect = nir_src_for_ssa(vtn_ssa_value(b, w[1]));
495 }
496 tail->child = &deref_arr->deref;
497 break;
498 }
499
500 case GLSL_TYPE_STRUCT: {
501 assert(idx_val->value_type == vtn_value_type_constant);
502 unsigned idx = idx_val->constant->value.u[0];
503 nir_deref_struct *deref_struct = nir_deref_struct_create(b, idx);
504 deref_struct->deref.type = glsl_get_struct_field(tail->type, idx);
505 tail->child = &deref_struct->deref;
506 break;
507 }
508 default:
509 unreachable("Invalid type for deref");
510 }
511 tail = tail->child;
512 }
513 break;
514 }
515
516 case SpvOpCopyMemory: {
517 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
518 nir_deref_var *src = vtn_value(b, w[2], vtn_value_type_deref)->deref;
519
520 nir_intrinsic_instr *copy =
521 nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
522 copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
523 copy->variables[1] = nir_deref_as_var(nir_copy_deref(copy, &src->deref));
524
525 nir_builder_instr_insert(&b->nb, &copy->instr);
526 break;
527 }
528
529 case SpvOpLoad: {
530 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
531 nir_deref_var *src = vtn_value(b, w[3], vtn_value_type_deref)->deref;
532 const struct glsl_type *src_type = nir_deref_tail(&src->deref)->type;
533 assert(glsl_type_is_vector_or_scalar(src_type));
534
535 nir_intrinsic_instr *load =
536 nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
537 load->variables[0] = nir_deref_as_var(nir_copy_deref(load, &src->deref));
538 load->num_components = glsl_get_vector_elements(src_type);
539 nir_ssa_dest_init(&load->instr, &load->dest, load->num_components,
540 val->name);
541
542 nir_builder_instr_insert(&b->nb, &load->instr);
543 val->type = src_type;
544 val->ssa = &load->dest.ssa;
545 break;
546 }
547
548 case SpvOpStore: {
549 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
550 const struct glsl_type *dest_type = nir_deref_tail(&dest->deref)->type;
551 struct vtn_value *src_val = vtn_untyped_value(b, w[2]);
552 if (src_val->value_type == vtn_value_type_ssa) {
553 assert(glsl_type_is_vector_or_scalar(dest_type));
554 nir_intrinsic_instr *store =
555 nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
556 store->src[0] = nir_src_for_ssa(src_val->ssa);
557 store->variables[0] = nir_deref_as_var(nir_copy_deref(store, &dest->deref));
558 store->num_components = glsl_get_vector_elements(dest_type);
559
560 nir_builder_instr_insert(&b->nb, &store->instr);
561 } else {
562 assert(src_val->value_type == vtn_value_type_constant);
563
564 nir_variable *const_tmp = rzalloc(b->shader, nir_variable);
565 const_tmp->type = dest_type;
566 const_tmp->data.mode = nir_var_local;
567 const_tmp->data.read_only = true;
568 exec_list_push_tail(&b->impl->locals, &const_tmp->node);
569
570 nir_intrinsic_instr *copy =
571 nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
572 copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
573 copy->variables[1] = nir_deref_var_create(copy, const_tmp);
574
575 nir_builder_instr_insert(&b->nb, &copy->instr);
576 }
577 break;
578 }
579
580 case SpvOpVariableArray:
581 case SpvOpCopyMemorySized:
582 case SpvOpArrayLength:
583 case SpvOpImagePointer:
584 default:
585 unreachable("Unhandled opcode");
586 }
587 }
588
589 static void
590 vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
591 const uint32_t *w, unsigned count)
592 {
593 unreachable("Unhandled opcode");
594 }
595
596 static void
597 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
598 const uint32_t *w, unsigned count)
599 {
600 unreachable("Unhandled opcode");
601 }
602
603 static void
604 vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,
605 const uint32_t *w, unsigned count)
606 {
607 unreachable("Matrix math not handled");
608 }
609
610 static void
611 vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
612 const uint32_t *w, unsigned count)
613 {
614 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
615 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
616
617 /* Collect the various SSA sources */
618 unsigned num_inputs = count - 3;
619 nir_ssa_def *src[4];
620 for (unsigned i = 0; i < num_inputs; i++)
621 src[i] = vtn_ssa_value(b, w[i + 3]);
622
623 /* Indicates that the first two arguments should be swapped. This is
624 * used for implementing greater-than and less-than-or-equal.
625 */
626 bool swap = false;
627
628 nir_op op;
629 switch (opcode) {
630 /* Basic ALU operations */
631 case SpvOpSNegate: op = nir_op_ineg; break;
632 case SpvOpFNegate: op = nir_op_fneg; break;
633 case SpvOpNot: op = nir_op_inot; break;
634
635 case SpvOpAny:
636 switch (src[0]->num_components) {
637 case 1: op = nir_op_imov; break;
638 case 2: op = nir_op_bany2; break;
639 case 3: op = nir_op_bany3; break;
640 case 4: op = nir_op_bany4; break;
641 }
642 break;
643
644 case SpvOpAll:
645 switch (src[0]->num_components) {
646 case 1: op = nir_op_imov; break;
647 case 2: op = nir_op_ball2; break;
648 case 3: op = nir_op_ball3; break;
649 case 4: op = nir_op_ball4; break;
650 }
651 break;
652
653 case SpvOpIAdd: op = nir_op_iadd; break;
654 case SpvOpFAdd: op = nir_op_fadd; break;
655 case SpvOpISub: op = nir_op_isub; break;
656 case SpvOpFSub: op = nir_op_fsub; break;
657 case SpvOpIMul: op = nir_op_imul; break;
658 case SpvOpFMul: op = nir_op_fmul; break;
659 case SpvOpUDiv: op = nir_op_udiv; break;
660 case SpvOpSDiv: op = nir_op_idiv; break;
661 case SpvOpFDiv: op = nir_op_fdiv; break;
662 case SpvOpUMod: op = nir_op_umod; break;
663 case SpvOpSMod: op = nir_op_umod; break; /* FIXME? */
664 case SpvOpFMod: op = nir_op_fmod; break;
665
666 case SpvOpDot:
667 assert(src[0]->num_components == src[1]->num_components);
668 switch (src[0]->num_components) {
669 case 1: op = nir_op_fmul; break;
670 case 2: op = nir_op_fdot2; break;
671 case 3: op = nir_op_fdot3; break;
672 case 4: op = nir_op_fdot4; break;
673 }
674 break;
675
676 case SpvOpShiftRightLogical: op = nir_op_ushr; break;
677 case SpvOpShiftRightArithmetic: op = nir_op_ishr; break;
678 case SpvOpShiftLeftLogical: op = nir_op_ishl; break;
679 case SpvOpLogicalOr: op = nir_op_ior; break;
680 case SpvOpLogicalXor: op = nir_op_ixor; break;
681 case SpvOpLogicalAnd: op = nir_op_iand; break;
682 case SpvOpBitwiseOr: op = nir_op_ior; break;
683 case SpvOpBitwiseXor: op = nir_op_ixor; break;
684 case SpvOpBitwiseAnd: op = nir_op_iand; break;
685 case SpvOpSelect: op = nir_op_bcsel; break;
686 case SpvOpIEqual: op = nir_op_ieq; break;
687
688 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
689 case SpvOpFOrdEqual: op = nir_op_feq; break;
690 case SpvOpFUnordEqual: op = nir_op_feq; break;
691 case SpvOpINotEqual: op = nir_op_ine; break;
692 case SpvOpFOrdNotEqual: op = nir_op_fne; break;
693 case SpvOpFUnordNotEqual: op = nir_op_fne; break;
694 case SpvOpULessThan: op = nir_op_ult; break;
695 case SpvOpSLessThan: op = nir_op_ilt; break;
696 case SpvOpFOrdLessThan: op = nir_op_flt; break;
697 case SpvOpFUnordLessThan: op = nir_op_flt; break;
698 case SpvOpUGreaterThan: op = nir_op_ult; swap = true; break;
699 case SpvOpSGreaterThan: op = nir_op_ilt; swap = true; break;
700 case SpvOpFOrdGreaterThan: op = nir_op_flt; swap = true; break;
701 case SpvOpFUnordGreaterThan: op = nir_op_flt; swap = true; break;
702 case SpvOpULessThanEqual: op = nir_op_uge; swap = true; break;
703 case SpvOpSLessThanEqual: op = nir_op_ige; swap = true; break;
704 case SpvOpFOrdLessThanEqual: op = nir_op_fge; swap = true; break;
705 case SpvOpFUnordLessThanEqual: op = nir_op_fge; swap = true; break;
706 case SpvOpUGreaterThanEqual: op = nir_op_uge; break;
707 case SpvOpSGreaterThanEqual: op = nir_op_ige; break;
708 case SpvOpFOrdGreaterThanEqual: op = nir_op_fge; break;
709 case SpvOpFUnordGreaterThanEqual:op = nir_op_fge; break;
710
711 /* Conversions: */
712 case SpvOpConvertFToU: op = nir_op_f2u; break;
713 case SpvOpConvertFToS: op = nir_op_f2i; break;
714 case SpvOpConvertSToF: op = nir_op_i2f; break;
715 case SpvOpConvertUToF: op = nir_op_u2f; break;
716 case SpvOpBitcast: op = nir_op_imov; break;
717 case SpvOpUConvert:
718 case SpvOpSConvert:
719 op = nir_op_imov; /* TODO: NIR is 32-bit only; these are no-ops. */
720 break;
721 case SpvOpFConvert:
722 op = nir_op_fmov;
723 break;
724
725 /* Derivatives: */
726 case SpvOpDPdx: op = nir_op_fddx; break;
727 case SpvOpDPdy: op = nir_op_fddy; break;
728 case SpvOpDPdxFine: op = nir_op_fddx_fine; break;
729 case SpvOpDPdyFine: op = nir_op_fddy_fine; break;
730 case SpvOpDPdxCoarse: op = nir_op_fddx_coarse; break;
731 case SpvOpDPdyCoarse: op = nir_op_fddy_coarse; break;
732 case SpvOpFwidth:
733 val->ssa = nir_fadd(&b->nb,
734 nir_fabs(&b->nb, nir_fddx(&b->nb, src[0])),
735 nir_fabs(&b->nb, nir_fddx(&b->nb, src[1])));
736 return;
737 case SpvOpFwidthFine:
738 val->ssa = nir_fadd(&b->nb,
739 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[0])),
740 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[1])));
741 return;
742 case SpvOpFwidthCoarse:
743 val->ssa = nir_fadd(&b->nb,
744 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[0])),
745 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[1])));
746 return;
747
748 case SpvOpVectorTimesScalar:
749 /* The builder will take care of splatting for us. */
750 val->ssa = nir_fmul(&b->nb, src[0], src[1]);
751 return;
752
753 case SpvOpSRem:
754 case SpvOpFRem:
755 unreachable("No NIR equivalent");
756
757 case SpvOpIsNan:
758 case SpvOpIsInf:
759 case SpvOpIsFinite:
760 case SpvOpIsNormal:
761 case SpvOpSignBitSet:
762 case SpvOpLessOrGreater:
763 case SpvOpOrdered:
764 case SpvOpUnordered:
765 default:
766 unreachable("Unhandled opcode");
767 }
768
769 if (swap) {
770 nir_ssa_def *tmp = src[0];
771 src[0] = src[1];
772 src[1] = tmp;
773 }
774
775 nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
776 nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
777 glsl_get_vector_elements(val->type), val->name);
778 val->ssa = &instr->dest.dest.ssa;
779
780 for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
781 instr->src[i].src = nir_src_for_ssa(src[i]);
782
783 nir_builder_instr_insert(&b->nb, &instr->instr);
784 }
785
786 static bool
787 vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
788 const uint32_t *w, unsigned count)
789 {
790 switch (opcode) {
791 case SpvOpSource:
792 case SpvOpSourceExtension:
793 case SpvOpCompileFlag:
794 case SpvOpExtension:
795 case SpvOpExtInstImport:
796 /* Unhandled, but these are for debug so that's ok. */
797 break;
798
799 case SpvOpMemoryModel:
800 assert(w[1] == SpvAddressingModelLogical);
801 assert(w[2] == SpvMemoryModelGLSL450);
802 break;
803
804 case SpvOpEntryPoint:
805 assert(b->entry_point == NULL);
806 b->entry_point = &b->values[w[2]];
807 b->execution_model = w[1];
808 break;
809
810 case SpvOpExecutionMode:
811 unreachable("Execution modes not yet implemented");
812 break;
813
814 case SpvOpString:
815 vtn_push_value(b, w[1], vtn_value_type_string)->str =
816 vtn_string_literal(b, &w[2], count - 2);
817 break;
818
819 case SpvOpName:
820 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
821 break;
822
823 case SpvOpMemberName:
824 /* TODO */
825 break;
826
827 case SpvOpLine:
828 break; /* Ignored for now */
829
830 case SpvOpDecorationGroup:
831 case SpvOpDecorate:
832 case SpvOpMemberDecorate:
833 case SpvOpGroupDecorate:
834 case SpvOpGroupMemberDecorate:
835 vtn_handle_decoration(b, opcode, w, count);
836 break;
837
838 case SpvOpTypeVoid:
839 case SpvOpTypeBool:
840 case SpvOpTypeInt:
841 case SpvOpTypeFloat:
842 case SpvOpTypeVector:
843 case SpvOpTypeMatrix:
844 case SpvOpTypeSampler:
845 case SpvOpTypeArray:
846 case SpvOpTypeRuntimeArray:
847 case SpvOpTypeStruct:
848 case SpvOpTypeOpaque:
849 case SpvOpTypePointer:
850 case SpvOpTypeFunction:
851 case SpvOpTypeEvent:
852 case SpvOpTypeDeviceEvent:
853 case SpvOpTypeReserveId:
854 case SpvOpTypeQueue:
855 case SpvOpTypePipe:
856 vtn_push_value(b, w[1], vtn_value_type_type)->type =
857 vtn_handle_type(b, opcode, &w[2], count - 2);
858 break;
859
860 case SpvOpConstantTrue:
861 case SpvOpConstantFalse:
862 case SpvOpConstant:
863 case SpvOpConstantComposite:
864 case SpvOpConstantSampler:
865 case SpvOpConstantNullPointer:
866 case SpvOpConstantNullObject:
867 case SpvOpSpecConstantTrue:
868 case SpvOpSpecConstantFalse:
869 case SpvOpSpecConstant:
870 case SpvOpSpecConstantComposite:
871 vtn_handle_constant(b, opcode, w, count);
872 break;
873
874 case SpvOpVariable:
875 vtn_handle_variables(b, opcode, w, count);
876 break;
877
878 default:
879 return false; /* End of preamble */
880 }
881
882 return true;
883 }
884
885 static bool
886 vtn_handle_first_cfg_pass_instruction(struct vtn_builder *b, SpvOp opcode,
887 const uint32_t *w, unsigned count)
888 {
889 switch (opcode) {
890 case SpvOpFunction: {
891 assert(b->func == NULL);
892 b->func = rzalloc(b, struct vtn_function);
893
894 const struct glsl_type *result_type =
895 vtn_value(b, w[1], vtn_value_type_type)->type;
896 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
897 const struct glsl_type *func_type =
898 vtn_value(b, w[4], vtn_value_type_type)->type;
899
900 assert(glsl_get_function_return_type(func_type) == result_type);
901
902 nir_function *func =
903 nir_function_create(b->shader, ralloc_strdup(b->shader, val->name));
904
905 nir_function_overload *overload = nir_function_overload_create(func);
906 overload->num_params = glsl_get_length(func_type);
907 overload->params = ralloc_array(overload, nir_parameter,
908 overload->num_params);
909 for (unsigned i = 0; i < overload->num_params; i++) {
910 const struct glsl_function_param *param =
911 glsl_get_function_param(func_type, i);
912 overload->params[i].type = param->type;
913 if (param->in) {
914 if (param->out) {
915 overload->params[i].param_type = nir_parameter_inout;
916 } else {
917 overload->params[i].param_type = nir_parameter_in;
918 }
919 } else {
920 if (param->out) {
921 overload->params[i].param_type = nir_parameter_out;
922 } else {
923 assert(!"Parameter is neither in nor out");
924 }
925 }
926 }
927 b->func->overload = overload;
928 break;
929 }
930
931 case SpvOpFunctionEnd:
932 b->func = NULL;
933 break;
934
935 case SpvOpFunctionParameter:
936 break; /* Does nothing */
937
938 case SpvOpLabel: {
939 assert(b->block == NULL);
940 b->block = rzalloc(b, struct vtn_block);
941 b->block->label = w;
942 vtn_push_value(b, w[1], vtn_value_type_block)->block = b->block;
943
944 if (b->func->start_block == NULL) {
945 /* This is the first block encountered for this function. In this
946 * case, we set the start block and add it to the list of
947 * implemented functions that we'll walk later.
948 */
949 b->func->start_block = b->block;
950 exec_list_push_tail(&b->functions, &b->func->node);
951 }
952 break;
953 }
954
955 case SpvOpBranch:
956 case SpvOpBranchConditional:
957 case SpvOpSwitch:
958 case SpvOpKill:
959 case SpvOpReturn:
960 case SpvOpReturnValue:
961 case SpvOpUnreachable:
962 assert(b->block);
963 b->block->branch = w;
964 b->block = NULL;
965 break;
966
967 default:
968 /* Continue on as per normal */
969 return true;
970 }
971
972 return true;
973 }
974
975 static bool
976 vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
977 const uint32_t *w, unsigned count)
978 {
979 switch (opcode) {
980 case SpvOpLabel: {
981 struct vtn_block *block = vtn_value(b, w[1], vtn_value_type_block)->block;
982 struct exec_node *list_tail = exec_list_get_tail(b->nb.cf_node_list);
983 nir_cf_node *tail_node = exec_node_data(nir_cf_node, list_tail, node);
984 assert(tail_node->type == nir_cf_node_block);
985 block->block = nir_cf_node_as_block(tail_node);
986 assert(exec_list_is_empty(&block->block->instr_list));
987 break;
988 }
989
990 case SpvOpLoopMerge:
991 case SpvOpSelectionMerge:
992 assert(b->merge_block == NULL);
993 /* TODO: Selection Control */
994 b->merge_block = vtn_value(b, w[1], vtn_value_type_block)->block;
995 break;
996
997 case SpvOpUndef:
998 vtn_push_value(b, w[2], vtn_value_type_undef);
999 break;
1000
1001 case SpvOpExtInst:
1002 vtn_handle_extension(b, opcode, w, count);
1003 break;
1004
1005 case SpvOpVariable:
1006 case SpvOpVariableArray:
1007 case SpvOpLoad:
1008 case SpvOpStore:
1009 case SpvOpCopyMemory:
1010 case SpvOpCopyMemorySized:
1011 case SpvOpAccessChain:
1012 case SpvOpInBoundsAccessChain:
1013 case SpvOpArrayLength:
1014 case SpvOpImagePointer:
1015 vtn_handle_variables(b, opcode, w, count);
1016 break;
1017
1018 case SpvOpFunctionCall:
1019 vtn_handle_function_call(b, opcode, w, count);
1020 break;
1021
1022 case SpvOpTextureSample:
1023 case SpvOpTextureSampleDref:
1024 case SpvOpTextureSampleLod:
1025 case SpvOpTextureSampleProj:
1026 case SpvOpTextureSampleGrad:
1027 case SpvOpTextureSampleOffset:
1028 case SpvOpTextureSampleProjLod:
1029 case SpvOpTextureSampleProjGrad:
1030 case SpvOpTextureSampleLodOffset:
1031 case SpvOpTextureSampleProjOffset:
1032 case SpvOpTextureSampleGradOffset:
1033 case SpvOpTextureSampleProjLodOffset:
1034 case SpvOpTextureSampleProjGradOffset:
1035 case SpvOpTextureFetchTexelLod:
1036 case SpvOpTextureFetchTexelOffset:
1037 case SpvOpTextureFetchSample:
1038 case SpvOpTextureFetchTexel:
1039 case SpvOpTextureGather:
1040 case SpvOpTextureGatherOffset:
1041 case SpvOpTextureGatherOffsets:
1042 case SpvOpTextureQuerySizeLod:
1043 case SpvOpTextureQuerySize:
1044 case SpvOpTextureQueryLod:
1045 case SpvOpTextureQueryLevels:
1046 case SpvOpTextureQuerySamples:
1047 vtn_handle_texture(b, opcode, w, count);
1048 break;
1049
1050 case SpvOpSNegate:
1051 case SpvOpFNegate:
1052 case SpvOpNot:
1053 case SpvOpAny:
1054 case SpvOpAll:
1055 case SpvOpConvertFToU:
1056 case SpvOpConvertFToS:
1057 case SpvOpConvertSToF:
1058 case SpvOpConvertUToF:
1059 case SpvOpUConvert:
1060 case SpvOpSConvert:
1061 case SpvOpFConvert:
1062 case SpvOpConvertPtrToU:
1063 case SpvOpConvertUToPtr:
1064 case SpvOpPtrCastToGeneric:
1065 case SpvOpGenericCastToPtr:
1066 case SpvOpBitcast:
1067 case SpvOpIsNan:
1068 case SpvOpIsInf:
1069 case SpvOpIsFinite:
1070 case SpvOpIsNormal:
1071 case SpvOpSignBitSet:
1072 case SpvOpLessOrGreater:
1073 case SpvOpOrdered:
1074 case SpvOpUnordered:
1075 case SpvOpIAdd:
1076 case SpvOpFAdd:
1077 case SpvOpISub:
1078 case SpvOpFSub:
1079 case SpvOpIMul:
1080 case SpvOpFMul:
1081 case SpvOpUDiv:
1082 case SpvOpSDiv:
1083 case SpvOpFDiv:
1084 case SpvOpUMod:
1085 case SpvOpSRem:
1086 case SpvOpSMod:
1087 case SpvOpFRem:
1088 case SpvOpFMod:
1089 case SpvOpVectorTimesScalar:
1090 case SpvOpDot:
1091 case SpvOpShiftRightLogical:
1092 case SpvOpShiftRightArithmetic:
1093 case SpvOpShiftLeftLogical:
1094 case SpvOpLogicalOr:
1095 case SpvOpLogicalXor:
1096 case SpvOpLogicalAnd:
1097 case SpvOpBitwiseOr:
1098 case SpvOpBitwiseXor:
1099 case SpvOpBitwiseAnd:
1100 case SpvOpSelect:
1101 case SpvOpIEqual:
1102 case SpvOpFOrdEqual:
1103 case SpvOpFUnordEqual:
1104 case SpvOpINotEqual:
1105 case SpvOpFOrdNotEqual:
1106 case SpvOpFUnordNotEqual:
1107 case SpvOpULessThan:
1108 case SpvOpSLessThan:
1109 case SpvOpFOrdLessThan:
1110 case SpvOpFUnordLessThan:
1111 case SpvOpUGreaterThan:
1112 case SpvOpSGreaterThan:
1113 case SpvOpFOrdGreaterThan:
1114 case SpvOpFUnordGreaterThan:
1115 case SpvOpULessThanEqual:
1116 case SpvOpSLessThanEqual:
1117 case SpvOpFOrdLessThanEqual:
1118 case SpvOpFUnordLessThanEqual:
1119 case SpvOpUGreaterThanEqual:
1120 case SpvOpSGreaterThanEqual:
1121 case SpvOpFOrdGreaterThanEqual:
1122 case SpvOpFUnordGreaterThanEqual:
1123 case SpvOpDPdx:
1124 case SpvOpDPdy:
1125 case SpvOpFwidth:
1126 case SpvOpDPdxFine:
1127 case SpvOpDPdyFine:
1128 case SpvOpFwidthFine:
1129 case SpvOpDPdxCoarse:
1130 case SpvOpDPdyCoarse:
1131 case SpvOpFwidthCoarse:
1132 vtn_handle_alu(b, opcode, w, count);
1133 break;
1134
1135 case SpvOpTranspose:
1136 case SpvOpOuterProduct:
1137 case SpvOpMatrixTimesScalar:
1138 case SpvOpVectorTimesMatrix:
1139 case SpvOpMatrixTimesVector:
1140 case SpvOpMatrixTimesMatrix:
1141 vtn_handle_matrix_alu(b, opcode, w, count);
1142 break;
1143
1144 default:
1145 unreachable("Unhandled opcode");
1146 }
1147
1148 return true;
1149 }
1150
1151 static void
1152 vtn_walk_blocks(struct vtn_builder *b, struct vtn_block *start,
1153 struct vtn_block *end)
1154 {
1155 struct vtn_block *block = start;
1156 while (block != end) {
1157 vtn_foreach_instruction(b, block->label, block->branch,
1158 vtn_handle_body_instruction);
1159
1160 const uint32_t *w = block->branch;
1161 SpvOp branch_op = w[0] & SpvOpCodeMask;
1162 switch (branch_op) {
1163 case SpvOpBranch: {
1164 assert(vtn_value(b, w[1], vtn_value_type_block)->block == end);
1165 return;
1166 }
1167
1168 case SpvOpBranchConditional: {
1169 /* Gather up the branch blocks */
1170 struct vtn_block *then_block =
1171 vtn_value(b, w[2], vtn_value_type_block)->block;
1172 struct vtn_block *else_block =
1173 vtn_value(b, w[3], vtn_value_type_block)->block;
1174 struct vtn_block *merge_block = b->merge_block;
1175
1176 nir_if *if_stmt = nir_if_create(b->shader);
1177 if_stmt->condition = nir_src_for_ssa(vtn_ssa_value(b, w[1]));
1178 nir_cf_node_insert_end(b->nb.cf_node_list, &if_stmt->cf_node);
1179
1180 struct exec_list *old_list = b->nb.cf_node_list;
1181
1182 nir_builder_insert_after_cf_list(&b->nb, &if_stmt->then_list);
1183 vtn_walk_blocks(b, then_block, merge_block);
1184
1185 nir_builder_insert_after_cf_list(&b->nb, &if_stmt->else_list);
1186 vtn_walk_blocks(b, else_block, merge_block);
1187
1188 nir_builder_insert_after_cf_list(&b->nb, old_list);
1189 block = merge_block;
1190 continue;
1191 }
1192
1193 case SpvOpSwitch:
1194 case SpvOpKill:
1195 case SpvOpReturn:
1196 case SpvOpReturnValue:
1197 case SpvOpUnreachable:
1198 default:
1199 unreachable("Unhandled opcode");
1200 }
1201 }
1202 }
1203
1204 nir_shader *
1205 spirv_to_nir(const uint32_t *words, size_t word_count,
1206 const nir_shader_compiler_options *options)
1207 {
1208 const uint32_t *word_end = words + word_count;
1209
1210 /* Handle the SPIR-V header (first 4 dwords) */
1211 assert(word_count > 5);
1212
1213 assert(words[0] == SpvMagicNumber);
1214 assert(words[1] == 99);
1215 /* words[2] == generator magic */
1216 unsigned value_id_bound = words[3];
1217 assert(words[4] == 0);
1218
1219 words+= 5;
1220
1221 nir_shader *shader = nir_shader_create(NULL, options);
1222
1223 /* Initialize the stn_builder object */
1224 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
1225 b->shader = shader;
1226 b->value_id_bound = value_id_bound;
1227 b->values = ralloc_array(b, struct vtn_value, value_id_bound);
1228 exec_list_make_empty(&b->functions);
1229
1230 /* Handle all the preamble instructions */
1231 words = vtn_foreach_instruction(b, words, word_end,
1232 vtn_handle_preamble_instruction);
1233
1234 /* Do a very quick CFG analysis pass */
1235 vtn_foreach_instruction(b, words, word_end,
1236 vtn_handle_first_cfg_pass_instruction);
1237
1238 foreach_list_typed(struct vtn_function, func, node, &b->functions) {
1239 b->impl = nir_function_impl_create(func->overload);
1240 nir_builder_init(&b->nb, b->impl);
1241 nir_builder_insert_after_cf_list(&b->nb, &b->impl->body);
1242 vtn_walk_blocks(b, func->start_block, NULL);
1243 }
1244
1245 ralloc_free(b);
1246
1247 return shader;
1248 }