2 * Copyright © 2015 Intel Corporation
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:
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
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
24 * Jason Ekstrand (jason@jlekstrand.net)
28 #include "nir_spirv.h"
32 struct vtn_decoration
;
35 vtn_value_type_invalid
= 0,
37 vtn_value_type_string
,
38 vtn_value_type_decoration_group
,
40 vtn_value_type_constant
,
42 vtn_value_type_function
,
48 enum vtn_value_type value_type
;
50 struct vtn_decoration
*decoration
;
54 const struct glsl_type
*type
;
55 nir_constant
*constant
;
57 nir_function_impl
*impl
;
63 struct vtn_decoration
{
64 struct vtn_decoration
*next
;
65 const uint32_t *literals
;
66 struct vtn_value
*group
;
67 SpvDecoration decoration
;
72 nir_function_impl
*impl
;
73 struct exec_list
*cf_list
;
75 unsigned value_id_bound
;
76 struct vtn_value
*values
;
78 SpvExecutionModel execution_model
;
79 struct vtn_value
*entry_point
;
82 static struct vtn_value
*
83 vtn_push_value(struct vtn_builder
*b
, uint32_t value_id
,
84 enum vtn_value_type value_type
)
86 assert(value_id
< b
->value_id_bound
);
87 assert(b
->values
[value_id
].value_type
== vtn_value_type_invalid
);
89 b
->values
[value_id
].value_type
= value_type
;
91 return &b
->values
[value_id
];
94 static struct vtn_value
*
95 vtn_value(struct vtn_builder
*b
, uint32_t value_id
,
96 enum vtn_value_type value_type
)
98 assert(value_id
< b
->value_id_bound
);
99 assert(b
->values
[value_id
].value_type
== value_type
);
100 return &b
->values
[value_id
];
104 vtn_string_literal(struct vtn_builder
*b
, const uint32_t *words
,
107 return ralloc_strndup(b
, (char *)words
, (word_count
- 2) * sizeof(*words
));
111 vtn_handle_extension(struct vtn_builder
*b
, SpvOp opcode
,
112 const uint32_t *w
, unsigned count
)
115 case SpvOpExtInstImport
:
116 /* Do nothing for the moment */
121 unreachable("Unhandled opcode");
125 typedef void (*decoration_foreach_cb
)(struct vtn_builder
*,
127 const struct vtn_decoration
*,
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
)
136 for (struct vtn_decoration
*dec
= value
->decoration
; dec
; dec
= dec
->next
) {
138 assert(dec
->group
->value_type
== vtn_value_type_decoration_group
);
139 _foreach_decoration_helper(b
, base_value
, dec
->group
, cb
, data
);
141 cb(b
, base_value
, dec
, data
);
146 /** Iterates (recursively if needed) over all of the decorations on a value
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.
153 vtn_foreach_decoration(struct vtn_builder
*b
, struct vtn_value
*value
,
154 decoration_foreach_cb cb
, void *data
)
156 _foreach_decoration_helper(b
, value
, value
, cb
, data
);
160 vtn_handle_decoration(struct vtn_builder
*b
, SpvOp opcode
,
161 const uint32_t *w
, unsigned count
)
164 case SpvOpDecorationGroup
:
165 vtn_push_value(b
, w
[1], vtn_value_type_undef
);
168 case SpvOpDecorate
: {
169 struct vtn_value
*val
= &b
->values
[w
[1]];
171 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
172 dec
->decoration
= w
[2];
173 dec
->literals
= &w
[3];
175 /* Link into the list */
176 dec
->next
= val
->decoration
;
177 val
->decoration
= dec
;
181 case SpvOpGroupDecorate
: {
182 struct vtn_value
*group
= &b
->values
[w
[1]];
183 assert(group
->value_type
== vtn_value_type_decoration_group
);
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
);
190 /* Link into the list */
191 dec
->next
= val
->decoration
;
192 val
->decoration
= dec
;
197 case SpvOpGroupMemberDecorate
:
198 assert(!"Bad instruction. Khronos Bug #13513");
202 unreachable("Unhandled opcode");
206 static const struct glsl_type
*
207 vtn_handle_type(struct vtn_builder
*b
, SpvOp opcode
,
208 const uint32_t *args
, unsigned count
)
212 return glsl_void_type();
214 return glsl_bool_type();
216 return glsl_int_type();
218 return glsl_float_type();
220 case SpvOpTypeVector
: {
221 const struct glsl_type
*base
=
222 vtn_value(b
, args
[0], vtn_value_type_type
)->type
;
223 unsigned elems
= args
[1];
225 assert(glsl_type_is_scalar(base
));
226 return glsl_vector_type(glsl_get_base_type(base
), elems
);
229 case SpvOpTypeMatrix
: {
230 const struct glsl_type
*base
=
231 vtn_value(b
, args
[0], vtn_value_type_type
)->type
;
232 unsigned columns
= args
[1];
234 assert(glsl_type_is_vector(base
));
235 return glsl_matrix_type(glsl_get_base_type(base
),
236 glsl_get_vector_elements(base
),
241 return glsl_array_type(b
->values
[args
[0]].type
, args
[1]);
243 case SpvOpTypeStruct
: {
244 NIR_VLA(struct glsl_struct_field
, fields
, count
);
245 for (unsigned i
= 0; i
< count
; i
++) {
246 /* TODO: Handle decorators */
247 fields
[i
].type
= vtn_value(b
, args
[i
], vtn_value_type_type
)->type
;
248 fields
[i
].name
= ralloc_asprintf(b
, "field%d", i
);
249 fields
[i
].location
= -1;
250 fields
[i
].interpolation
= 0;
251 fields
[i
].centroid
= 0;
252 fields
[i
].sample
= 0;
253 fields
[i
].matrix_layout
= 2;
254 fields
[i
].stream
= -1;
256 return glsl_struct_type(fields
, count
, "struct");
259 case SpvOpTypeFunction
: {
260 const struct glsl_type
*return_type
= b
->values
[args
[0]].type
;
261 NIR_VLA(struct glsl_function_param
, params
, count
- 1);
262 for (unsigned i
= 1; i
< count
; i
++) {
263 params
[i
- 1].type
= vtn_value(b
, args
[i
], vtn_value_type_type
)->type
;
266 params
[i
- 1].in
= true;
267 params
[i
- 1].out
= true;
269 return glsl_function_type(return_type
, params
, count
- 1);
272 case SpvOpTypePointer
:
273 /* FIXME: For now, we'll just do the really lame thing and return
274 * the same type. The validator should ensure that the proper number
275 * of dereferences happen
277 return vtn_value(b
, args
[1], vtn_value_type_type
)->type
;
279 case SpvOpTypeSampler
:
280 case SpvOpTypeRuntimeArray
:
281 case SpvOpTypeOpaque
:
283 case SpvOpTypeDeviceEvent
:
284 case SpvOpTypeReserveId
:
288 unreachable("Unhandled opcode");
293 vtn_handle_constant(struct vtn_builder
*b
, SpvOp opcode
,
294 const uint32_t *w
, unsigned count
)
296 const struct glsl_type
*type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
297 nir_constant
*constant
= ralloc(b
, nir_constant
);
299 case SpvOpConstantTrue
:
300 assert(type
== glsl_bool_type());
301 constant
->value
.u
[0] = NIR_TRUE
;
303 case SpvOpConstantFalse
:
304 assert(type
== glsl_bool_type());
305 constant
->value
.u
[0] = NIR_FALSE
;
308 assert(glsl_type_is_scalar(type
));
309 constant
->value
.u
[0] = w
[3];
311 case SpvOpConstantComposite
: {
312 unsigned elem_count
= count
- 3;
313 nir_constant
**elems
= ralloc_array(b
, nir_constant
*, elem_count
);
314 for (unsigned i
= 0; i
< elem_count
; i
++)
315 elems
[i
] = vtn_value(b
, w
[i
+ 3], vtn_value_type_constant
)->constant
;
317 switch (glsl_get_base_type(type
)) {
320 case GLSL_TYPE_FLOAT
:
322 if (glsl_type_is_matrix(type
)) {
323 unsigned rows
= glsl_get_vector_elements(type
);
324 assert(glsl_get_matrix_columns(type
) == elem_count
);
325 for (unsigned i
= 0; i
< elem_count
; i
++)
326 for (unsigned j
= 0; j
< rows
; j
++)
327 constant
->value
.u
[rows
* i
+ j
] = elems
[i
]->value
.u
[j
];
329 assert(glsl_type_is_vector(type
));
330 assert(glsl_get_vector_elements(type
) == elem_count
);
331 for (unsigned i
= 0; i
< elem_count
; i
++)
332 constant
->value
.u
[i
] = elems
[i
]->value
.u
[0];
337 case GLSL_TYPE_STRUCT
:
338 case GLSL_TYPE_ARRAY
:
339 constant
->elements
= elems
;
343 unreachable("Unsupported type for constants");
349 unreachable("Unhandled opcode");
351 vtn_push_value(b
, w
[2], vtn_value_type_constant
)->constant
= constant
;
355 var_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
,
356 const struct vtn_decoration
*dec
, void *void_var
)
358 assert(val
->value_type
== vtn_value_type_deref
);
359 assert(val
->deref
->deref
.child
== NULL
);
360 assert(val
->deref
->var
== void_var
);
362 nir_variable
*var
= void_var
;
363 switch (dec
->decoration
) {
364 case SpvDecorationPrecisionLow
:
365 case SpvDecorationPrecisionMedium
:
366 case SpvDecorationPrecisionHigh
:
367 break; /* FIXME: Do nothing with these for now. */
368 case SpvDecorationSmooth
:
369 var
->data
.interpolation
= INTERP_QUALIFIER_SMOOTH
;
371 case SpvDecorationNoperspective
:
372 var
->data
.interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
374 case SpvDecorationFlat
:
375 var
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
377 case SpvDecorationCentroid
:
378 var
->data
.centroid
= true;
380 case SpvDecorationSample
:
381 var
->data
.sample
= true;
383 case SpvDecorationInvariant
:
384 var
->data
.invariant
= true;
386 case SpvDecorationConstant
:
387 assert(var
->constant_initializer
!= NULL
);
388 var
->data
.read_only
= true;
390 case SpvDecorationNonwritable
:
391 var
->data
.read_only
= true;
393 case SpvDecorationLocation
:
394 var
->data
.explicit_location
= true;
395 var
->data
.location
= dec
->literals
[0];
397 case SpvDecorationComponent
:
398 var
->data
.location_frac
= dec
->literals
[0];
400 case SpvDecorationIndex
:
401 var
->data
.explicit_index
= true;
402 var
->data
.index
= dec
->literals
[0];
404 case SpvDecorationBinding
:
405 var
->data
.explicit_binding
= true;
406 var
->data
.binding
= dec
->literals
[0];
408 case SpvDecorationBlock
:
409 case SpvDecorationBufferBlock
:
410 case SpvDecorationRowMajor
:
411 case SpvDecorationColMajor
:
412 case SpvDecorationGLSLShared
:
413 case SpvDecorationGLSLStd140
:
414 case SpvDecorationGLSLStd430
:
415 case SpvDecorationGLSLPacked
:
416 case SpvDecorationPatch
:
417 case SpvDecorationRestrict
:
418 case SpvDecorationAliased
:
419 case SpvDecorationVolatile
:
420 case SpvDecorationCoherent
:
421 case SpvDecorationNonreadable
:
422 case SpvDecorationUniform
:
423 /* This is really nice but we have no use for it right now. */
424 case SpvDecorationNoStaticUse
:
425 case SpvDecorationCPacked
:
426 case SpvDecorationSaturatedConversion
:
427 case SpvDecorationStream
:
428 case SpvDecorationDescriptorSet
:
429 case SpvDecorationOffset
:
430 case SpvDecorationAlignment
:
431 case SpvDecorationXfbBuffer
:
432 case SpvDecorationStride
:
433 case SpvDecorationBuiltIn
:
434 case SpvDecorationFuncParamAttr
:
435 case SpvDecorationFPRoundingMode
:
436 case SpvDecorationFPFastMathMode
:
437 case SpvDecorationLinkageAttributes
:
438 case SpvDecorationSpecId
:
440 unreachable("Unhandled variable decoration");
445 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
446 const uint32_t *w
, unsigned count
)
449 case SpvOpVariable
: {
450 const struct glsl_type
*type
=
451 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
452 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
454 nir_variable
*var
= ralloc(b
->shader
, nir_variable
);
457 var
->name
= ralloc_strdup(var
, val
->name
);
459 switch ((SpvStorageClass
)w
[3]) {
460 case SpvStorageClassUniformConstant
:
461 var
->data
.mode
= nir_var_uniform
;
462 var
->data
.read_only
= true;
464 case SpvStorageClassInput
:
465 var
->data
.mode
= nir_var_shader_in
;
466 var
->data
.read_only
= true;
468 case SpvStorageClassOutput
:
469 var
->data
.mode
= nir_var_shader_out
;
471 case SpvStorageClassPrivateGlobal
:
472 var
->data
.mode
= nir_var_global
;
474 case SpvStorageClassFunction
:
475 var
->data
.mode
= nir_var_local
;
477 case SpvStorageClassUniform
:
478 case SpvStorageClassWorkgroupLocal
:
479 case SpvStorageClassWorkgroupGlobal
:
480 case SpvStorageClassGeneric
:
481 case SpvStorageClassPrivate
:
482 case SpvStorageClassAtomicCounter
:
484 unreachable("Unhandled variable storage class");
489 var
->constant_initializer
=
490 vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
493 val
->deref
= nir_deref_var_create(b
->shader
, var
);
495 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
499 case SpvOpAccessChain
:
500 case SpvOpInBoundsAccessChain
: {
501 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
502 nir_deref_var
*base
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
503 val
->deref
= nir_deref_as_var(nir_copy_deref(b
, &base
->deref
));
505 nir_deref
*tail
= &val
->deref
->deref
;
509 for (unsigned i
= 0; i
< count
- 3; i
++) {
510 assert(w
[i
+ 3] < b
->value_id_bound
);
511 struct vtn_value
*idx_val
= &b
->values
[w
[i
+ 3]];
513 enum glsl_base_type base_type
= glsl_get_base_type(tail
->type
);
517 case GLSL_TYPE_FLOAT
:
518 case GLSL_TYPE_DOUBLE
:
520 case GLSL_TYPE_ARRAY
: {
521 nir_deref_array
*deref_arr
= nir_deref_array_create(b
);
522 if (base_type
== GLSL_TYPE_ARRAY
) {
523 deref_arr
->deref
.type
= glsl_get_array_element(tail
->type
);
524 } else if (glsl_type_is_matrix(tail
->type
)) {
525 deref_arr
->deref
.type
= glsl_get_column_type(tail
->type
);
527 assert(glsl_type_is_vector(tail
->type
));
528 deref_arr
->deref
.type
= glsl_scalar_type(base_type
);
531 if (idx_val
->value_type
== vtn_value_type_constant
) {
532 unsigned idx
= idx_val
->constant
->value
.u
[0];
533 deref_arr
->deref_array_type
= nir_deref_array_type_direct
;
534 deref_arr
->base_offset
= idx
;
536 assert(idx_val
->value_type
== vtn_value_type_ssa
);
537 deref_arr
->deref_array_type
= nir_deref_array_type_indirect
;
539 unreachable("Indirect array accesses not implemented");
541 tail
->child
= &deref_arr
->deref
;
545 case GLSL_TYPE_STRUCT
: {
546 assert(idx_val
->value_type
== vtn_value_type_constant
);
547 unsigned idx
= idx_val
->constant
->value
.u
[0];
548 nir_deref_struct
*deref_struct
= nir_deref_struct_create(b
, idx
);
549 deref_struct
->deref
.type
= glsl_get_struct_field(tail
->type
, idx
);
550 tail
->child
= &deref_struct
->deref
;
554 unreachable("Invalid type for deref");
561 case SpvOpVariableArray
:
564 case SpvOpCopyMemory
:
565 case SpvOpCopyMemorySized
:
566 case SpvOpArrayLength
:
567 case SpvOpImagePointer
:
569 unreachable("Unhandled opcode");
574 vtn_handle_functions(struct vtn_builder
*b
, SpvOp opcode
,
575 const uint32_t *w
, unsigned count
)
578 case SpvOpFunction
: {
579 assert(b
->impl
== NULL
);
581 const struct glsl_type
*result_type
=
582 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
583 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_function
);
584 const struct glsl_type
*func_type
=
585 vtn_value(b
, w
[4], vtn_value_type_type
)->type
;
587 assert(glsl_get_function_return_type(func_type
) == result_type
);
590 nir_function_create(b
->shader
, ralloc_strdup(b
->shader
, val
->name
));
592 nir_function_overload
*overload
= nir_function_overload_create(func
);
593 overload
->num_params
= glsl_get_length(func_type
);
594 overload
->params
= ralloc_array(overload
, nir_parameter
,
595 overload
->num_params
);
596 for (unsigned i
= 0; i
< overload
->num_params
; i
++) {
597 const struct glsl_function_param
*param
=
598 glsl_get_function_param(func_type
, i
);
599 overload
->params
[i
].type
= param
->type
;
602 overload
->params
[i
].param_type
= nir_parameter_inout
;
604 overload
->params
[i
].param_type
= nir_parameter_in
;
608 overload
->params
[i
].param_type
= nir_parameter_out
;
610 assert(!"Parameter is neither in nor out");
615 val
->impl
= b
->impl
= nir_function_impl_create(overload
);
616 b
->cf_list
= &b
->impl
->body
;
620 case SpvOpFunctionEnd
:
623 case SpvOpFunctionParameter
:
624 case SpvOpFunctionCall
:
626 unreachable("Unhandled opcode");
631 vtn_handle_texture(struct vtn_builder
*b
, SpvOp opcode
,
632 const uint32_t *w
, unsigned count
)
634 unreachable("Unhandled opcode");
638 vtn_handle_alu(struct vtn_builder
*b
, SpvOp opcode
,
639 const uint32_t *w
, unsigned count
)
641 unreachable("Unhandled opcode");
645 vtn_handle_instruction(struct vtn_builder
*b
, SpvOp opcode
,
646 const uint32_t *w
, unsigned count
)
650 case SpvOpSourceExtension
:
651 case SpvOpMemberName
:
654 /* Unhandled, but these are for debug so that's ok. */
658 b
->values
[w
[1]].name
= vtn_string_literal(b
, &w
[2], count
- 2);
662 vtn_push_value(b
, w
[1], vtn_value_type_string
)->str
=
663 vtn_string_literal(b
, &w
[2], count
- 2);
667 vtn_push_value(b
, w
[2], vtn_value_type_undef
);
670 case SpvOpMemoryModel
:
671 assert(w
[1] == SpvAddressingModelLogical
);
672 assert(w
[2] == SpvMemoryModelGLSL450
);
675 case SpvOpEntryPoint
:
676 assert(b
->entry_point
== NULL
);
677 b
->entry_point
= &b
->values
[w
[2]];
678 b
->execution_model
= w
[1];
682 struct exec_node
*list_tail
= exec_list_get_tail(b
->cf_list
);
683 nir_cf_node
*tail_node
= exec_node_data(nir_cf_node
, list_tail
, node
);
684 assert(tail_node
->type
== nir_cf_node_block
);
685 nir_block
*block
= nir_cf_node_as_block(tail_node
);
687 assert(exec_list_is_empty(&block
->instr_list
));
688 vtn_push_value(b
, w
[1], vtn_value_type_block
)->block
= block
;
692 case SpvOpExtInstImport
:
694 vtn_handle_extension(b
, opcode
, w
, count
);
701 case SpvOpTypeVector
:
702 case SpvOpTypeMatrix
:
703 case SpvOpTypeSampler
:
705 case SpvOpTypeRuntimeArray
:
706 case SpvOpTypeStruct
:
707 case SpvOpTypeOpaque
:
708 case SpvOpTypePointer
:
709 case SpvOpTypeFunction
:
711 case SpvOpTypeDeviceEvent
:
712 case SpvOpTypeReserveId
:
715 vtn_push_value(b
, w
[1], vtn_value_type_type
)->type
=
716 vtn_handle_type(b
, opcode
, &w
[2], count
- 2);
719 case SpvOpConstantTrue
:
720 case SpvOpConstantFalse
:
722 case SpvOpConstantComposite
:
723 case SpvOpConstantSampler
:
724 case SpvOpConstantNullPointer
:
725 case SpvOpConstantNullObject
:
726 case SpvOpSpecConstantTrue
:
727 case SpvOpSpecConstantFalse
:
728 case SpvOpSpecConstant
:
729 case SpvOpSpecConstantComposite
:
730 vtn_handle_constant(b
, opcode
, w
, count
);
734 case SpvOpVariableArray
:
737 case SpvOpCopyMemory
:
738 case SpvOpCopyMemorySized
:
739 case SpvOpAccessChain
:
740 case SpvOpInBoundsAccessChain
:
741 case SpvOpArrayLength
:
742 case SpvOpImagePointer
:
743 vtn_handle_variables(b
, opcode
, w
, count
);
746 case SpvOpDecorationGroup
:
748 case SpvOpMemberDecorate
:
749 case SpvOpGroupDecorate
:
750 case SpvOpGroupMemberDecorate
:
751 vtn_handle_decoration(b
, opcode
, w
, count
);
755 case SpvOpFunctionEnd
:
756 case SpvOpFunctionParameter
:
757 case SpvOpFunctionCall
:
758 vtn_handle_functions(b
, opcode
, w
, count
);
761 case SpvOpTextureSample
:
762 case SpvOpTextureSampleDref
:
763 case SpvOpTextureSampleLod
:
764 case SpvOpTextureSampleProj
:
765 case SpvOpTextureSampleGrad
:
766 case SpvOpTextureSampleOffset
:
767 case SpvOpTextureSampleProjLod
:
768 case SpvOpTextureSampleProjGrad
:
769 case SpvOpTextureSampleLodOffset
:
770 case SpvOpTextureSampleProjOffset
:
771 case SpvOpTextureSampleGradOffset
:
772 case SpvOpTextureSampleProjLodOffset
:
773 case SpvOpTextureSampleProjGradOffset
:
774 case SpvOpTextureFetchTexelLod
:
775 case SpvOpTextureFetchTexelOffset
:
776 case SpvOpTextureFetchSample
:
777 case SpvOpTextureFetchTexel
:
778 case SpvOpTextureGather
:
779 case SpvOpTextureGatherOffset
:
780 case SpvOpTextureGatherOffsets
:
781 case SpvOpTextureQuerySizeLod
:
782 case SpvOpTextureQuerySize
:
783 case SpvOpTextureQueryLod
:
784 case SpvOpTextureQueryLevels
:
785 case SpvOpTextureQuerySamples
:
786 vtn_handle_texture(b
, opcode
, w
, count
);
794 case SpvOpConvertFToU
:
795 case SpvOpConvertFToS
:
796 case SpvOpConvertSToF
:
797 case SpvOpConvertUToF
:
801 case SpvOpConvertPtrToU
:
802 case SpvOpConvertUToPtr
:
803 case SpvOpPtrCastToGeneric
:
804 case SpvOpGenericCastToPtr
:
811 case SpvOpSignBitSet
:
812 case SpvOpLessOrGreater
:
829 case SpvOpVectorTimesScalar
:
830 case SpvOpMatrixTimesScalar
:
831 case SpvOpVectorTimesMatrix
:
832 case SpvOpMatrixTimesVector
:
833 case SpvOpMatrixTimesMatrix
:
834 case SpvOpOuterProduct
:
836 case SpvOpShiftRightLogical
:
837 case SpvOpShiftRightArithmetic
:
838 case SpvOpShiftLeftLogical
:
840 case SpvOpLogicalXor
:
841 case SpvOpLogicalAnd
:
843 case SpvOpBitwiseXor
:
844 case SpvOpBitwiseAnd
:
848 case SpvOpFUnordEqual
:
850 case SpvOpFOrdNotEqual
:
851 case SpvOpFUnordNotEqual
:
854 case SpvOpFOrdLessThan
:
855 case SpvOpFUnordLessThan
:
856 case SpvOpUGreaterThan
:
857 case SpvOpSGreaterThan
:
858 case SpvOpFOrdGreaterThan
:
859 case SpvOpFUnordGreaterThan
:
860 case SpvOpULessThanEqual
:
861 case SpvOpSLessThanEqual
:
862 case SpvOpFOrdLessThanEqual
:
863 case SpvOpFUnordLessThanEqual
:
864 case SpvOpUGreaterThanEqual
:
865 case SpvOpSGreaterThanEqual
:
866 case SpvOpFOrdGreaterThanEqual
:
867 case SpvOpFUnordGreaterThanEqual
:
873 case SpvOpFwidthFine
:
874 case SpvOpDPdxCoarse
:
875 case SpvOpDPdyCoarse
:
876 case SpvOpFwidthCoarse
:
877 vtn_handle_alu(b
, opcode
, w
, count
);
881 unreachable("Unhandled opcode");
886 spirv_to_nir(const uint32_t *words
, size_t word_count
,
887 const nir_shader_compiler_options
*options
)
889 /* Handle the SPIR-V header (first 4 dwords) */
890 assert(word_count
> 5);
892 assert(words
[0] == SpvMagicNumber
);
893 assert(words
[1] == 99);
894 /* words[2] == generator magic */
895 unsigned value_id_bound
= words
[3];
896 assert(words
[4] == 0);
900 nir_shader
*shader
= nir_shader_create(NULL
, options
);
902 /* Initialize the stn_builder object */
903 struct vtn_builder
*b
= rzalloc(NULL
, struct vtn_builder
);
905 b
->value_id_bound
= value_id_bound
;
906 b
->values
= ralloc_array(b
, struct vtn_value
, value_id_bound
);
908 /* Start handling instructions */
909 const uint32_t *word_end
= words
+ word_count
;
910 while (words
< word_end
) {
911 SpvOp opcode
= words
[0] & SpvOpCodeMask
;
912 unsigned count
= words
[0] >> SpvWordCountShift
;
913 assert(words
+ count
<= word_end
);
915 vtn_handle_instruction(b
, opcode
, words
, count
);