nir/spirv: Add support for declaring functions
[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 "nir_spirv.h"
29 #include "nir_vla.h"
30 #include "spirv.h"
31
32 struct vtn_decoration;
33
34 enum vtn_value_type {
35 vtn_value_type_invalid = 0,
36 vtn_value_type_undef,
37 vtn_value_type_string,
38 vtn_value_type_decoration_group,
39 vtn_value_type_type,
40 vtn_value_type_constant,
41 vtn_value_type_variable,
42 vtn_value_type_function,
43 vtn_value_type_ssa,
44 vtn_value_type_deref,
45 };
46
47 struct vtn_value {
48 enum vtn_value_type value_type;
49 const char *name;
50 struct vtn_decoration *decoration;
51 union {
52 void *ptr;
53 char *str;
54 const struct glsl_type *type;
55 nir_constant *constant;
56 nir_variable *var;
57 nir_function_impl *impl;
58 nir_ssa_def *ssa;
59 nir_deref_var *deref;
60 };
61 };
62
63 struct vtn_decoration {
64 struct vtn_decoration *next;
65 const uint32_t *literals;
66 struct vtn_value *group;
67 SpvDecoration decoration;
68 };
69
70 struct vtn_builder {
71 nir_shader *shader;
72 nir_function_impl *impl;
73 struct exec_list *cf_list;
74
75 unsigned value_id_bound;
76 struct vtn_value *values;
77
78 SpvExecutionModel execution_model;
79 struct vtn_value *entry_point;
80 };
81
82 static struct vtn_value *
83 vtn_push_value(struct vtn_builder *b, uint32_t value_id,
84 enum vtn_value_type value_type)
85 {
86 assert(value_id < b->value_id_bound);
87 assert(b->values[value_id].value_type == vtn_value_type_invalid);
88
89 b->values[value_id].value_type = value_type;
90
91 return &b->values[value_id];
92 }
93
94 static struct vtn_value *
95 vtn_value(struct vtn_builder *b, uint32_t value_id,
96 enum vtn_value_type value_type)
97 {
98 assert(value_id < b->value_id_bound);
99 assert(b->values[value_id].value_type == value_type);
100 return &b->values[value_id];
101 }
102
103 static char *
104 vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
105 unsigned word_count)
106 {
107 return ralloc_strndup(b, (char *)words, (word_count - 2) * sizeof(*words));
108 }
109
110 static void
111 vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
112 const uint32_t *w, unsigned count)
113 {
114 switch (opcode) {
115 case SpvOpExtInstImport:
116 /* Do nothing for the moment */
117 break;
118
119 case SpvOpExtInst:
120 default:
121 unreachable("Unhandled opcode");
122 }
123 }
124
125 typedef void (*decoration_foreach_cb)(struct vtn_builder *,
126 struct vtn_value *,
127 const struct vtn_decoration *,
128 void *);
129
130 static void
131 _foreach_decoration_helper(struct vtn_builder *b,
132 struct vtn_value *base_value,
133 struct vtn_value *value,
134 decoration_foreach_cb cb, void *data)
135 {
136 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
137 if (dec->group) {
138 assert(dec->group->value_type == vtn_value_type_decoration_group);
139 _foreach_decoration_helper(b, base_value, dec->group, cb, data);
140 } else {
141 cb(b, base_value, dec, data);
142 }
143 }
144 }
145
146 /** Iterates (recursively if needed) over all of the decorations on a value
147 *
148 * This function iterates over all of the decorations applied to a given
149 * value. If it encounters a decoration group, it recurses into the group
150 * and iterates over all of those decorations as well.
151 */
152 static void
153 vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
154 decoration_foreach_cb cb, void *data)
155 {
156 _foreach_decoration_helper(b, value, value, cb, data);
157 }
158
159 static void
160 vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
161 const uint32_t *w, unsigned count)
162 {
163 switch (opcode) {
164 case SpvOpDecorationGroup:
165 vtn_push_value(b, w[1], vtn_value_type_undef);
166 break;
167
168 case SpvOpDecorate: {
169 struct vtn_value *val = &b->values[w[1]];
170
171 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
172 dec->decoration = w[2];
173 dec->literals = &w[3];
174
175 /* Link into the list */
176 dec->next = val->decoration;
177 val->decoration = dec;
178 break;
179 }
180
181 case SpvOpGroupDecorate: {
182 struct vtn_value *group = &b->values[w[1]];
183 assert(group->value_type == vtn_value_type_decoration_group);
184
185 for (unsigned i = 2; i < count; i++) {
186 struct vtn_value *val = &b->values[w[i]];
187 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
188 dec->group = group;
189
190 /* Link into the list */
191 dec->next = val->decoration;
192 val->decoration = dec;
193 }
194 break;
195 }
196
197 case SpvOpGroupMemberDecorate:
198 assert(!"Bad instruction. Khronos Bug #13513");
199 break;
200
201 default:
202 unreachable("Unhandled opcode");
203 }
204 }
205
206 static const struct glsl_type *
207 vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
208 const uint32_t *args, unsigned count)
209 {
210 switch (opcode) {
211 case SpvOpTypeVoid:
212 return glsl_void_type();
213 case SpvOpTypeBool:
214 return glsl_bool_type();
215 case SpvOpTypeInt:
216 return glsl_int_type();
217 case SpvOpTypeFloat:
218 return glsl_float_type();
219
220 case SpvOpTypeVector: {
221 const struct glsl_type *base = b->values[args[0]].type;
222 unsigned elems = args[1];
223
224 assert(glsl_type_is_scalar(base));
225 return glsl_vector_type(glsl_get_base_type(base), elems);
226 }
227
228 case SpvOpTypeMatrix: {
229 const struct glsl_type *base = b->values[args[0]].type;
230 unsigned columns = args[1];
231
232 assert(glsl_type_is_vector(base));
233 return glsl_matrix_type(glsl_get_base_type(base),
234 glsl_get_vector_elements(base),
235 columns);
236 }
237
238 case SpvOpTypeArray:
239 return glsl_array_type(b->values[args[0]].type, args[1]);
240
241 case SpvOpTypeStruct: {
242 NIR_VLA(struct glsl_struct_field, fields, count);
243 for (unsigned i = 0; i < count; i++) {
244 /* TODO: Handle decorators */
245 fields[i].type = b->values[args[i]].type;
246 fields[i].name = ralloc_asprintf(b, "field%d", i);
247 fields[i].location = -1;
248 fields[i].interpolation = 0;
249 fields[i].centroid = 0;
250 fields[i].sample = 0;
251 fields[i].matrix_layout = 2;
252 fields[i].stream = -1;
253 }
254 return glsl_struct_type(fields, count, "struct");
255 }
256
257 case SpvOpTypeFunction: {
258 const struct glsl_type *return_type = b->values[args[0]].type;
259 NIR_VLA(struct glsl_function_param, params, count - 1);
260 for (unsigned i = 1; i < count; i++) {
261 params[i - 1].type = b->values[args[i]].type;
262
263 /* FIXME: */
264 params[i - 1].in = true;
265 params[i - 1].out = true;
266 }
267 return glsl_function_type(return_type, params, count - 1);
268 }
269
270 case SpvOpTypePointer:
271 /* FIXME: For now, we'll just do the really lame thing and return
272 * the same type. The validator should ensure that the proper number
273 * of dereferences happen
274 */
275 return b->values[args[0]].type;
276
277 case SpvOpTypeSampler:
278 case SpvOpTypeRuntimeArray:
279 case SpvOpTypeOpaque:
280 case SpvOpTypeEvent:
281 case SpvOpTypeDeviceEvent:
282 case SpvOpTypeReserveId:
283 case SpvOpTypeQueue:
284 case SpvOpTypePipe:
285 default:
286 unreachable("Unhandled opcode");
287 }
288 }
289
290 static void
291 vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
292 const uint32_t *w, unsigned count)
293 {
294 const struct glsl_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
295 nir_constant *constant = ralloc(b, nir_constant);
296 switch (opcode) {
297 case SpvOpConstantTrue:
298 assert(type == glsl_bool_type());
299 constant->value.u[0] = NIR_TRUE;
300 break;
301 case SpvOpConstantFalse:
302 assert(type == glsl_bool_type());
303 constant->value.u[0] = NIR_FALSE;
304 break;
305 case SpvOpConstant:
306 assert(glsl_type_is_scalar(type));
307 constant->value.u[0] = w[3];
308 break;
309 case SpvOpConstantComposite: {
310 unsigned elem_count = count - 3;
311 nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
312 for (unsigned i = 0; i < elem_count; i++)
313 elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
314
315 switch (glsl_get_base_type(type)) {
316 case GLSL_TYPE_UINT:
317 case GLSL_TYPE_INT:
318 case GLSL_TYPE_FLOAT:
319 case GLSL_TYPE_BOOL:
320 if (glsl_type_is_matrix(type)) {
321 unsigned rows = glsl_get_vector_elements(type);
322 assert(glsl_get_matrix_columns(type) == elem_count);
323 for (unsigned i = 0; i < elem_count; i++)
324 for (unsigned j = 0; j < rows; j++)
325 constant->value.u[rows * i + j] = elems[i]->value.u[j];
326 } else {
327 assert(glsl_type_is_vector(type));
328 assert(glsl_get_vector_elements(type) == elem_count);
329 for (unsigned i = 0; i < elem_count; i++)
330 constant->value.u[i] = elems[i]->value.u[0];
331 }
332 ralloc_free(elems);
333 break;
334
335 case GLSL_TYPE_STRUCT:
336 case GLSL_TYPE_ARRAY:
337 constant->elements = elems;
338 break;
339
340 default:
341 unreachable("Unsupported type for constants");
342 }
343 break;
344 }
345
346 default:
347 unreachable("Unhandled opcode");
348 }
349 vtn_push_value(b, w[2], vtn_value_type_constant)->constant = constant;
350 }
351
352 static void
353 var_decoration_cb(struct vtn_builder *b, struct vtn_value *val,
354 const struct vtn_decoration *dec, void *unused)
355 {
356 assert(val->value_type == vtn_value_type_variable);
357 nir_variable *var = val->var;
358 switch (dec->decoration) {
359 case SpvDecorationPrecisionLow:
360 case SpvDecorationPrecisionMedium:
361 case SpvDecorationPrecisionHigh:
362 break; /* FIXME: Do nothing with these for now. */
363 case SpvDecorationSmooth:
364 var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
365 break;
366 case SpvDecorationNoperspective:
367 var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
368 break;
369 case SpvDecorationFlat:
370 var->data.interpolation = INTERP_QUALIFIER_FLAT;
371 break;
372 case SpvDecorationCentroid:
373 var->data.centroid = true;
374 break;
375 case SpvDecorationSample:
376 var->data.sample = true;
377 break;
378 case SpvDecorationInvariant:
379 var->data.invariant = true;
380 break;
381 case SpvDecorationConstant:
382 assert(var->constant_initializer != NULL);
383 var->data.read_only = true;
384 break;
385 case SpvDecorationNonwritable:
386 var->data.read_only = true;
387 break;
388 case SpvDecorationLocation:
389 var->data.explicit_location = true;
390 var->data.location = dec->literals[0];
391 break;
392 case SpvDecorationComponent:
393 var->data.location_frac = dec->literals[0];
394 break;
395 case SpvDecorationIndex:
396 var->data.explicit_index = true;
397 var->data.index = dec->literals[0];
398 break;
399 case SpvDecorationBinding:
400 var->data.explicit_binding = true;
401 var->data.binding = dec->literals[0];
402 break;
403 case SpvDecorationBlock:
404 case SpvDecorationBufferBlock:
405 case SpvDecorationRowMajor:
406 case SpvDecorationColMajor:
407 case SpvDecorationGLSLShared:
408 case SpvDecorationGLSLStd140:
409 case SpvDecorationGLSLStd430:
410 case SpvDecorationGLSLPacked:
411 case SpvDecorationPatch:
412 case SpvDecorationRestrict:
413 case SpvDecorationAliased:
414 case SpvDecorationVolatile:
415 case SpvDecorationCoherent:
416 case SpvDecorationNonreadable:
417 case SpvDecorationUniform:
418 /* This is really nice but we have no use for it right now. */
419 case SpvDecorationNoStaticUse:
420 case SpvDecorationCPacked:
421 case SpvDecorationSaturatedConversion:
422 case SpvDecorationStream:
423 case SpvDecorationDescriptorSet:
424 case SpvDecorationOffset:
425 case SpvDecorationAlignment:
426 case SpvDecorationXfbBuffer:
427 case SpvDecorationStride:
428 case SpvDecorationBuiltIn:
429 case SpvDecorationFuncParamAttr:
430 case SpvDecorationFPRoundingMode:
431 case SpvDecorationFPFastMathMode:
432 case SpvDecorationLinkageAttributes:
433 case SpvDecorationSpecId:
434 default:
435 unreachable("Unhandled variable decoration");
436 }
437 }
438
439 static void
440 vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
441 const uint32_t *w, unsigned count)
442 {
443 switch (opcode) {
444 case SpvOpVariable: {
445 const struct glsl_type *type =
446 vtn_value(b, w[1], vtn_value_type_type)->type;
447 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_variable);
448
449 nir_variable *var = ralloc(b->shader, nir_variable);
450 val->var = var;
451
452 var->type = type;
453 var->name = ralloc_strdup(var, val->name);
454
455 switch ((SpvStorageClass)w[3]) {
456 case SpvStorageClassUniformConstant:
457 var->data.mode = nir_var_uniform;
458 var->data.read_only = true;
459 break;
460 case SpvStorageClassInput:
461 var->data.mode = nir_var_shader_in;
462 var->data.read_only = true;
463 break;
464 case SpvStorageClassOutput:
465 var->data.mode = nir_var_shader_out;
466 break;
467 case SpvStorageClassPrivateGlobal:
468 var->data.mode = nir_var_global;
469 break;
470 case SpvStorageClassFunction:
471 var->data.mode = nir_var_local;
472 break;
473 case SpvStorageClassUniform:
474 case SpvStorageClassWorkgroupLocal:
475 case SpvStorageClassWorkgroupGlobal:
476 case SpvStorageClassGeneric:
477 case SpvStorageClassPrivate:
478 case SpvStorageClassAtomicCounter:
479 default:
480 unreachable("Unhandled variable storage class");
481 }
482
483 if (count > 4) {
484 assert(count == 5);
485 var->constant_initializer =
486 vtn_value(b, w[4], vtn_value_type_constant)->constant;
487 }
488
489 vtn_foreach_decoration(b, val, var_decoration_cb, NULL);
490 break;
491 }
492
493 case SpvOpVariableArray:
494 case SpvOpLoad:
495 case SpvOpStore:
496 case SpvOpCopyMemory:
497 case SpvOpCopyMemorySized:
498 case SpvOpAccessChain:
499 case SpvOpInBoundsAccessChain:
500 case SpvOpArrayLength:
501 case SpvOpImagePointer:
502 default:
503 unreachable("Unhandled opcode");
504 }
505 }
506
507 static void
508 vtn_handle_functions(struct vtn_builder *b, SpvOp opcode,
509 const uint32_t *w, unsigned count)
510 {
511 switch (opcode) {
512 case SpvOpFunction: {
513 assert(b->impl == NULL);
514
515 const struct glsl_type *result_type =
516 vtn_value(b, w[1], vtn_value_type_type)->type;
517 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
518 const struct glsl_type *func_type =
519 vtn_value(b, w[4], vtn_value_type_type)->type;
520
521 assert(glsl_get_function_return_type(func_type) == result_type);
522
523 nir_function *func =
524 nir_function_create(b->shader, ralloc_strdup(b->shader, val->name));
525
526 nir_function_overload *overload = nir_function_overload_create(func);
527 overload->num_params = glsl_get_length(func_type);
528 overload->params = ralloc_array(overload, nir_parameter,
529 overload->num_params);
530 for (unsigned i = 0; i < overload->num_params; i++) {
531 const struct glsl_function_param *param =
532 glsl_get_function_param(func_type, i);
533 overload->params[i].type = param->type;
534 if (param->in) {
535 if (param->out) {
536 overload->params[i].param_type = nir_parameter_inout;
537 } else {
538 overload->params[i].param_type = nir_parameter_in;
539 }
540 } else {
541 if (param->out) {
542 overload->params[i].param_type = nir_parameter_out;
543 } else {
544 assert(!"Parameter is neither in nor out");
545 }
546 }
547 }
548
549 val->impl = b->impl = nir_function_impl_create(overload);
550 b->cf_list = &b->impl->body;
551
552 break;
553 }
554 case SpvOpFunctionEnd:
555 b->impl = NULL;
556 break;
557 case SpvOpFunctionParameter:
558 case SpvOpFunctionCall:
559 default:
560 unreachable("Unhandled opcode");
561 }
562 }
563
564 static void
565 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
566 const uint32_t *w, unsigned count)
567 {
568 unreachable("Unhandled opcode");
569 }
570
571 static void
572 vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
573 const uint32_t *w, unsigned count)
574 {
575 unreachable("Unhandled opcode");
576 }
577
578 static void
579 vtn_handle_instruction(struct vtn_builder *b, SpvOp opcode,
580 const uint32_t *w, unsigned count)
581 {
582 switch (opcode) {
583 case SpvOpSource:
584 case SpvOpSourceExtension:
585 case SpvOpMemberName:
586 case SpvOpLine:
587 case SpvOpExtension:
588 /* Unhandled, but these are for debug so that's ok. */
589 break;
590
591 case SpvOpName:
592 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
593 break;
594
595 case SpvOpString:
596 vtn_push_value(b, w[1], vtn_value_type_string)->str =
597 vtn_string_literal(b, &w[2], count - 2);
598 break;
599
600 case SpvOpUndef:
601 vtn_push_value(b, w[2], vtn_value_type_undef);
602 break;
603
604 case SpvOpMemoryModel:
605 assert(w[1] == SpvAddressingModelLogical);
606 assert(w[2] == SpvMemoryModelGLSL450);
607 break;
608
609 case SpvOpEntryPoint:
610 assert(b->entry_point == NULL);
611 b->entry_point = &b->values[w[2]];
612 b->execution_model = w[1];
613 break;
614
615 case SpvOpExtInstImport:
616 case SpvOpExtInst:
617 vtn_handle_extension(b, opcode, w, count);
618 break;
619
620 case SpvOpTypeVoid:
621 case SpvOpTypeBool:
622 case SpvOpTypeInt:
623 case SpvOpTypeFloat:
624 case SpvOpTypeVector:
625 case SpvOpTypeMatrix:
626 case SpvOpTypeSampler:
627 case SpvOpTypeArray:
628 case SpvOpTypeRuntimeArray:
629 case SpvOpTypeStruct:
630 case SpvOpTypeOpaque:
631 case SpvOpTypePointer:
632 case SpvOpTypeFunction:
633 case SpvOpTypeEvent:
634 case SpvOpTypeDeviceEvent:
635 case SpvOpTypeReserveId:
636 case SpvOpTypeQueue:
637 case SpvOpTypePipe:
638 vtn_push_value(b, w[1], vtn_value_type_type)->type =
639 vtn_handle_type(b, opcode, &w[2], count - 2);
640 break;
641
642 case SpvOpConstantTrue:
643 case SpvOpConstantFalse:
644 case SpvOpConstant:
645 case SpvOpConstantComposite:
646 case SpvOpConstantSampler:
647 case SpvOpConstantNullPointer:
648 case SpvOpConstantNullObject:
649 case SpvOpSpecConstantTrue:
650 case SpvOpSpecConstantFalse:
651 case SpvOpSpecConstant:
652 case SpvOpSpecConstantComposite:
653 vtn_handle_constant(b, opcode, w, count);
654 break;
655
656 case SpvOpVariable:
657 case SpvOpVariableArray:
658 case SpvOpLoad:
659 case SpvOpStore:
660 case SpvOpCopyMemory:
661 case SpvOpCopyMemorySized:
662 case SpvOpAccessChain:
663 case SpvOpInBoundsAccessChain:
664 case SpvOpArrayLength:
665 case SpvOpImagePointer:
666 vtn_handle_variables(b, opcode, w, count);
667 break;
668
669 case SpvOpDecorationGroup:
670 case SpvOpDecorate:
671 case SpvOpMemberDecorate:
672 case SpvOpGroupDecorate:
673 case SpvOpGroupMemberDecorate:
674 vtn_handle_decoration(b, opcode, w, count);
675 break;
676
677 case SpvOpFunction:
678 case SpvOpFunctionEnd:
679 case SpvOpFunctionParameter:
680 case SpvOpFunctionCall:
681 vtn_handle_functions(b, opcode, w, count);
682 break;
683
684 case SpvOpTextureSample:
685 case SpvOpTextureSampleDref:
686 case SpvOpTextureSampleLod:
687 case SpvOpTextureSampleProj:
688 case SpvOpTextureSampleGrad:
689 case SpvOpTextureSampleOffset:
690 case SpvOpTextureSampleProjLod:
691 case SpvOpTextureSampleProjGrad:
692 case SpvOpTextureSampleLodOffset:
693 case SpvOpTextureSampleProjOffset:
694 case SpvOpTextureSampleGradOffset:
695 case SpvOpTextureSampleProjLodOffset:
696 case SpvOpTextureSampleProjGradOffset:
697 case SpvOpTextureFetchTexelLod:
698 case SpvOpTextureFetchTexelOffset:
699 case SpvOpTextureFetchSample:
700 case SpvOpTextureFetchTexel:
701 case SpvOpTextureGather:
702 case SpvOpTextureGatherOffset:
703 case SpvOpTextureGatherOffsets:
704 case SpvOpTextureQuerySizeLod:
705 case SpvOpTextureQuerySize:
706 case SpvOpTextureQueryLod:
707 case SpvOpTextureQueryLevels:
708 case SpvOpTextureQuerySamples:
709 vtn_handle_texture(b, opcode, w, count);
710 break;
711
712 case SpvOpSNegate:
713 case SpvOpFNegate:
714 case SpvOpNot:
715 case SpvOpAny:
716 case SpvOpAll:
717 case SpvOpConvertFToU:
718 case SpvOpConvertFToS:
719 case SpvOpConvertSToF:
720 case SpvOpConvertUToF:
721 case SpvOpUConvert:
722 case SpvOpSConvert:
723 case SpvOpFConvert:
724 case SpvOpConvertPtrToU:
725 case SpvOpConvertUToPtr:
726 case SpvOpPtrCastToGeneric:
727 case SpvOpGenericCastToPtr:
728 case SpvOpBitcast:
729 case SpvOpTranspose:
730 case SpvOpIsNan:
731 case SpvOpIsInf:
732 case SpvOpIsFinite:
733 case SpvOpIsNormal:
734 case SpvOpSignBitSet:
735 case SpvOpLessOrGreater:
736 case SpvOpOrdered:
737 case SpvOpUnordered:
738 case SpvOpIAdd:
739 case SpvOpFAdd:
740 case SpvOpISub:
741 case SpvOpFSub:
742 case SpvOpIMul:
743 case SpvOpFMul:
744 case SpvOpUDiv:
745 case SpvOpSDiv:
746 case SpvOpFDiv:
747 case SpvOpUMod:
748 case SpvOpSRem:
749 case SpvOpSMod:
750 case SpvOpFRem:
751 case SpvOpFMod:
752 case SpvOpVectorTimesScalar:
753 case SpvOpMatrixTimesScalar:
754 case SpvOpVectorTimesMatrix:
755 case SpvOpMatrixTimesVector:
756 case SpvOpMatrixTimesMatrix:
757 case SpvOpOuterProduct:
758 case SpvOpDot:
759 case SpvOpShiftRightLogical:
760 case SpvOpShiftRightArithmetic:
761 case SpvOpShiftLeftLogical:
762 case SpvOpLogicalOr:
763 case SpvOpLogicalXor:
764 case SpvOpLogicalAnd:
765 case SpvOpBitwiseOr:
766 case SpvOpBitwiseXor:
767 case SpvOpBitwiseAnd:
768 case SpvOpSelect:
769 case SpvOpIEqual:
770 case SpvOpFOrdEqual:
771 case SpvOpFUnordEqual:
772 case SpvOpINotEqual:
773 case SpvOpFOrdNotEqual:
774 case SpvOpFUnordNotEqual:
775 case SpvOpULessThan:
776 case SpvOpSLessThan:
777 case SpvOpFOrdLessThan:
778 case SpvOpFUnordLessThan:
779 case SpvOpUGreaterThan:
780 case SpvOpSGreaterThan:
781 case SpvOpFOrdGreaterThan:
782 case SpvOpFUnordGreaterThan:
783 case SpvOpULessThanEqual:
784 case SpvOpSLessThanEqual:
785 case SpvOpFOrdLessThanEqual:
786 case SpvOpFUnordLessThanEqual:
787 case SpvOpUGreaterThanEqual:
788 case SpvOpSGreaterThanEqual:
789 case SpvOpFOrdGreaterThanEqual:
790 case SpvOpFUnordGreaterThanEqual:
791 case SpvOpDPdx:
792 case SpvOpDPdy:
793 case SpvOpFwidth:
794 case SpvOpDPdxFine:
795 case SpvOpDPdyFine:
796 case SpvOpFwidthFine:
797 case SpvOpDPdxCoarse:
798 case SpvOpDPdyCoarse:
799 case SpvOpFwidthCoarse:
800 vtn_handle_alu(b, opcode, w, count);
801 break;
802
803 default:
804 unreachable("Unhandled opcode");
805 }
806 }
807
808 nir_shader *
809 spirv_to_nir(const uint32_t *words, size_t word_count,
810 const nir_shader_compiler_options *options)
811 {
812 /* Handle the SPIR-V header (first 4 dwords) */
813 assert(word_count > 5);
814
815 assert(words[0] == SpvMagicNumber);
816 assert(words[1] == 99);
817 /* words[2] == generator magic */
818 unsigned value_id_bound = words[3];
819 assert(words[4] == 0);
820
821 words+= 5;
822
823 nir_shader *shader = nir_shader_create(NULL, options);
824
825 /* Initialize the stn_builder object */
826 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
827 b->shader = shader;
828 b->value_id_bound = value_id_bound;
829 b->values = ralloc_array(b, struct vtn_value, value_id_bound);
830
831 /* Start handling instructions */
832 const uint32_t *word_end = words + word_count;
833 while (words < word_end) {
834 SpvOp opcode = words[0] & SpvOpCodeMask;
835 unsigned count = words[0] >> SpvWordCountShift;
836 assert(words + count <= word_end);
837
838 vtn_handle_instruction(b, opcode, words, count);
839
840 words += count;
841 }
842
843 ralloc_free(b);
844
845 return shader;
846 }