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 "spirv_to_nir_private.h"
32 vtn_ssa_value(struct vtn_builder
*b
, uint32_t value_id
)
34 return vtn_value(b
, value_id
, vtn_value_type_ssa
)->ssa
;
38 vtn_string_literal(struct vtn_builder
*b
, const uint32_t *words
,
41 return ralloc_strndup(b
, (char *)words
, (word_count
- 2) * sizeof(*words
));
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
)
48 const uint32_t *w
= start
;
50 SpvOp opcode
= w
[0] & SpvOpCodeMask
;
51 unsigned count
= w
[0] >> SpvWordCountShift
;
52 assert(count
>= 1 && w
+ count
<= end
);
54 if (!handler(b
, opcode
, w
, count
))
64 vtn_handle_extension(struct vtn_builder
*b
, SpvOp opcode
,
65 const uint32_t *w
, unsigned count
)
68 case SpvOpExtInstImport
:
69 /* Do nothing for the moment */
74 unreachable("Unhandled opcode");
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
)
84 for (struct vtn_decoration
*dec
= value
->decoration
; dec
; dec
= dec
->next
) {
86 assert(dec
->group
->value_type
== vtn_value_type_decoration_group
);
87 _foreach_decoration_helper(b
, base_value
, dec
->group
, cb
, data
);
89 cb(b
, base_value
, dec
, data
);
94 /** Iterates (recursively if needed) over all of the decorations on a value
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.
101 vtn_foreach_decoration(struct vtn_builder
*b
, struct vtn_value
*value
,
102 vtn_decoration_foreach_cb cb
, void *data
)
104 _foreach_decoration_helper(b
, value
, value
, cb
, data
);
108 vtn_handle_decoration(struct vtn_builder
*b
, SpvOp opcode
,
109 const uint32_t *w
, unsigned count
)
112 case SpvOpDecorationGroup
:
113 vtn_push_value(b
, w
[1], vtn_value_type_undef
);
116 case SpvOpDecorate
: {
117 struct vtn_value
*val
= &b
->values
[w
[1]];
119 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
120 dec
->decoration
= w
[2];
121 dec
->literals
= &w
[3];
123 /* Link into the list */
124 dec
->next
= val
->decoration
;
125 val
->decoration
= dec
;
129 case SpvOpGroupDecorate
: {
130 struct vtn_value
*group
= &b
->values
[w
[1]];
131 assert(group
->value_type
== vtn_value_type_decoration_group
);
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
);
138 /* Link into the list */
139 dec
->next
= val
->decoration
;
140 val
->decoration
= dec
;
145 case SpvOpGroupMemberDecorate
:
146 assert(!"Bad instruction. Khronos Bug #13513");
150 unreachable("Unhandled opcode");
154 static const struct glsl_type
*
155 vtn_handle_type(struct vtn_builder
*b
, SpvOp opcode
,
156 const uint32_t *args
, unsigned count
)
160 return glsl_void_type();
162 return glsl_bool_type();
164 return glsl_int_type();
166 return glsl_float_type();
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];
173 assert(glsl_type_is_scalar(base
));
174 return glsl_vector_type(glsl_get_base_type(base
), elems
);
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];
182 assert(glsl_type_is_vector(base
));
183 return glsl_matrix_type(glsl_get_base_type(base
),
184 glsl_get_vector_elements(base
),
189 return glsl_array_type(b
->values
[args
[0]].type
, args
[1]);
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;
204 return glsl_struct_type(fields
, count
, "struct");
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
;
214 params
[i
- 1].in
= true;
215 params
[i
- 1].out
= true;
217 return glsl_function_type(return_type
, params
, count
- 1);
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
225 return vtn_value(b
, args
[1], vtn_value_type_type
)->type
;
227 case SpvOpTypeSampler
:
228 case SpvOpTypeRuntimeArray
:
229 case SpvOpTypeOpaque
:
231 case SpvOpTypeDeviceEvent
:
232 case SpvOpTypeReserveId
:
236 unreachable("Unhandled opcode");
241 vtn_handle_constant(struct vtn_builder
*b
, SpvOp opcode
,
242 const uint32_t *w
, unsigned count
)
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
);
248 case SpvOpConstantTrue
:
249 assert(val
->type
== glsl_bool_type());
250 val
->constant
->value
.u
[0] = NIR_TRUE
;
252 case SpvOpConstantFalse
:
253 assert(val
->type
== glsl_bool_type());
254 val
->constant
->value
.u
[0] = NIR_FALSE
;
257 assert(glsl_type_is_scalar(val
->type
));
258 val
->constant
->value
.u
[0] = w
[3];
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
;
266 switch (glsl_get_base_type(val
->type
)) {
269 case GLSL_TYPE_FLOAT
:
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
];
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];
286 case GLSL_TYPE_STRUCT
:
287 case GLSL_TYPE_ARRAY
:
288 ralloc_steal(val
->constant
, elems
);
289 val
->constant
->elements
= elems
;
293 unreachable("Unsupported type for constants");
299 unreachable("Unhandled opcode");
304 var_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
,
305 const struct vtn_decoration
*dec
, void *void_var
)
307 assert(val
->value_type
== vtn_value_type_deref
);
308 assert(val
->deref
->deref
.child
== NULL
);
309 assert(val
->deref
->var
== void_var
);
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
;
320 case SpvDecorationNoperspective
:
321 var
->data
.interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
323 case SpvDecorationFlat
:
324 var
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
326 case SpvDecorationCentroid
:
327 var
->data
.centroid
= true;
329 case SpvDecorationSample
:
330 var
->data
.sample
= true;
332 case SpvDecorationInvariant
:
333 var
->data
.invariant
= true;
335 case SpvDecorationConstant
:
336 assert(var
->constant_initializer
!= NULL
);
337 var
->data
.read_only
= true;
339 case SpvDecorationNonwritable
:
340 var
->data
.read_only
= true;
342 case SpvDecorationLocation
:
343 var
->data
.explicit_location
= true;
344 var
->data
.location
= dec
->literals
[0];
346 case SpvDecorationComponent
:
347 var
->data
.location_frac
= dec
->literals
[0];
349 case SpvDecorationIndex
:
350 var
->data
.explicit_index
= true;
351 var
->data
.index
= dec
->literals
[0];
353 case SpvDecorationBinding
:
354 var
->data
.explicit_binding
= true;
355 var
->data
.binding
= dec
->literals
[0];
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
:
389 unreachable("Unhandled variable decoration");
394 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
395 const uint32_t *w
, unsigned count
)
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
);
403 nir_variable
*var
= ralloc(b
->shader
, nir_variable
);
406 var
->name
= ralloc_strdup(var
, val
->name
);
408 switch ((SpvStorageClass
)w
[3]) {
409 case SpvStorageClassUniformConstant
:
410 var
->data
.mode
= nir_var_uniform
;
411 var
->data
.read_only
= true;
413 case SpvStorageClassInput
:
414 var
->data
.mode
= nir_var_shader_in
;
415 var
->data
.read_only
= true;
417 case SpvStorageClassOutput
:
418 var
->data
.mode
= nir_var_shader_out
;
420 case SpvStorageClassPrivateGlobal
:
421 var
->data
.mode
= nir_var_global
;
423 case SpvStorageClassFunction
:
424 var
->data
.mode
= nir_var_local
;
426 case SpvStorageClassUniform
:
427 case SpvStorageClassWorkgroupLocal
:
428 case SpvStorageClassWorkgroupGlobal
:
429 case SpvStorageClassGeneric
:
430 case SpvStorageClassPrivate
:
431 case SpvStorageClassAtomicCounter
:
433 unreachable("Unhandled variable storage class");
438 var
->constant_initializer
=
439 vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
442 if (var
->data
.mode
== nir_var_local
) {
443 exec_list_push_tail(&b
->impl
->locals
, &var
->node
);
445 exec_list_push_tail(&b
->shader
->globals
, &var
->node
);
448 val
->deref
= nir_deref_var_create(b
->shader
, var
);
450 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
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
));
460 nir_deref
*tail
= &val
->deref
->deref
;
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]];
468 enum glsl_base_type base_type
= glsl_get_base_type(tail
->type
);
472 case GLSL_TYPE_FLOAT
:
473 case GLSL_TYPE_DOUBLE
:
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
);
482 assert(glsl_type_is_vector(tail
->type
));
483 deref_arr
->deref
.type
= glsl_scalar_type(base_type
);
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
;
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]));
496 tail
->child
= &deref_arr
->deref
;
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
;
509 unreachable("Invalid type for deref");
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
;
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
));
525 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
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
));
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
,
542 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
543 val
->type
= src_type
;
544 val
->ssa
= &load
->dest
.ssa
;
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
);
560 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
562 assert(src_val
->value_type
== vtn_value_type_constant
);
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
);
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
);
575 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
580 case SpvOpVariableArray
:
581 case SpvOpCopyMemorySized
:
582 case SpvOpArrayLength
:
583 case SpvOpImagePointer
:
585 unreachable("Unhandled opcode");
590 vtn_handle_function_call(struct vtn_builder
*b
, SpvOp opcode
,
591 const uint32_t *w
, unsigned count
)
593 unreachable("Unhandled opcode");
597 vtn_handle_texture(struct vtn_builder
*b
, SpvOp opcode
,
598 const uint32_t *w
, unsigned count
)
600 unreachable("Unhandled opcode");
604 vtn_handle_matrix_alu(struct vtn_builder
*b
, SpvOp opcode
,
605 const uint32_t *w
, unsigned count
)
607 unreachable("Matrix math not handled");
611 vtn_handle_alu(struct vtn_builder
*b
, SpvOp opcode
,
612 const uint32_t *w
, unsigned count
)
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
;
617 /* Collect the various SSA sources */
618 unsigned num_inputs
= count
- 3;
620 for (unsigned i
= 0; i
< num_inputs
; i
++)
621 src
[i
] = vtn_ssa_value(b
, w
[i
+ 3]);
623 /* Indicates that the first two arguments should be swapped. This is
624 * used for implementing greater-than and less-than-or-equal.
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;
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;
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;
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;
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;
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;
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;
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;
719 op
= nir_op_imov
; /* TODO: NIR is 32-bit only; these are no-ops. */
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;
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])));
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])));
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])));
748 case SpvOpVectorTimesScalar
:
749 /* The builder will take care of splatting for us. */
750 val
->ssa
= nir_fmul(&b
->nb
, src
[0], src
[1]);
755 unreachable("No NIR equivalent");
761 case SpvOpSignBitSet
:
762 case SpvOpLessOrGreater
:
766 unreachable("Unhandled opcode");
770 nir_ssa_def
*tmp
= src
[0];
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
;
780 for (unsigned i
= 0; i
< nir_op_infos
[op
].num_inputs
; i
++)
781 instr
->src
[i
].src
= nir_src_for_ssa(src
[i
]);
783 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
787 vtn_handle_preamble_instruction(struct vtn_builder
*b
, SpvOp opcode
,
788 const uint32_t *w
, unsigned count
)
792 case SpvOpSourceExtension
:
793 case SpvOpCompileFlag
:
795 case SpvOpExtInstImport
:
796 /* Unhandled, but these are for debug so that's ok. */
799 case SpvOpMemoryModel
:
800 assert(w
[1] == SpvAddressingModelLogical
);
801 assert(w
[2] == SpvMemoryModelGLSL450
);
804 case SpvOpEntryPoint
:
805 assert(b
->entry_point
== NULL
);
806 b
->entry_point
= &b
->values
[w
[2]];
807 b
->execution_model
= w
[1];
810 case SpvOpExecutionMode
:
811 unreachable("Execution modes not yet implemented");
815 vtn_push_value(b
, w
[1], vtn_value_type_string
)->str
=
816 vtn_string_literal(b
, &w
[2], count
- 2);
820 b
->values
[w
[1]].name
= vtn_string_literal(b
, &w
[2], count
- 2);
823 case SpvOpMemberName
:
828 break; /* Ignored for now */
830 case SpvOpDecorationGroup
:
832 case SpvOpMemberDecorate
:
833 case SpvOpGroupDecorate
:
834 case SpvOpGroupMemberDecorate
:
835 vtn_handle_decoration(b
, opcode
, w
, count
);
842 case SpvOpTypeVector
:
843 case SpvOpTypeMatrix
:
844 case SpvOpTypeSampler
:
846 case SpvOpTypeRuntimeArray
:
847 case SpvOpTypeStruct
:
848 case SpvOpTypeOpaque
:
849 case SpvOpTypePointer
:
850 case SpvOpTypeFunction
:
852 case SpvOpTypeDeviceEvent
:
853 case SpvOpTypeReserveId
:
856 vtn_push_value(b
, w
[1], vtn_value_type_type
)->type
=
857 vtn_handle_type(b
, opcode
, &w
[2], count
- 2);
860 case SpvOpConstantTrue
:
861 case SpvOpConstantFalse
:
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
);
875 vtn_handle_variables(b
, opcode
, w
, count
);
879 return false; /* End of preamble */
886 vtn_handle_first_cfg_pass_instruction(struct vtn_builder
*b
, SpvOp opcode
,
887 const uint32_t *w
, unsigned count
)
890 case SpvOpFunction
: {
891 assert(b
->func
== NULL
);
892 b
->func
= rzalloc(b
, struct vtn_function
);
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
;
900 assert(glsl_get_function_return_type(func_type
) == result_type
);
903 nir_function_create(b
->shader
, ralloc_strdup(b
->shader
, val
->name
));
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
;
915 overload
->params
[i
].param_type
= nir_parameter_inout
;
917 overload
->params
[i
].param_type
= nir_parameter_in
;
921 overload
->params
[i
].param_type
= nir_parameter_out
;
923 assert(!"Parameter is neither in nor out");
927 b
->func
->overload
= overload
;
931 case SpvOpFunctionEnd
:
935 case SpvOpFunctionParameter
:
936 break; /* Does nothing */
939 assert(b
->block
== NULL
);
940 b
->block
= rzalloc(b
, struct vtn_block
);
942 vtn_push_value(b
, w
[1], vtn_value_type_block
)->block
= b
->block
;
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.
949 b
->func
->start_block
= b
->block
;
950 exec_list_push_tail(&b
->functions
, &b
->func
->node
);
956 case SpvOpBranchConditional
:
960 case SpvOpReturnValue
:
961 case SpvOpUnreachable
:
963 b
->block
->branch
= w
;
968 /* Continue on as per normal */
976 vtn_handle_body_instruction(struct vtn_builder
*b
, SpvOp opcode
,
977 const uint32_t *w
, unsigned count
)
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
));
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
;
998 vtn_push_value(b
, w
[2], vtn_value_type_undef
);
1002 vtn_handle_extension(b
, opcode
, w
, count
);
1006 case SpvOpVariableArray
:
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
);
1018 case SpvOpFunctionCall
:
1019 vtn_handle_function_call(b
, opcode
, w
, count
);
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
);
1055 case SpvOpConvertFToU
:
1056 case SpvOpConvertFToS
:
1057 case SpvOpConvertSToF
:
1058 case SpvOpConvertUToF
:
1062 case SpvOpConvertPtrToU
:
1063 case SpvOpConvertUToPtr
:
1064 case SpvOpPtrCastToGeneric
:
1065 case SpvOpGenericCastToPtr
:
1071 case SpvOpSignBitSet
:
1072 case SpvOpLessOrGreater
:
1074 case SpvOpUnordered
:
1089 case SpvOpVectorTimesScalar
:
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
:
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
:
1128 case SpvOpFwidthFine
:
1129 case SpvOpDPdxCoarse
:
1130 case SpvOpDPdyCoarse
:
1131 case SpvOpFwidthCoarse
:
1132 vtn_handle_alu(b
, opcode
, w
, count
);
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
);
1145 unreachable("Unhandled opcode");
1152 vtn_walk_blocks(struct vtn_builder
*b
, struct vtn_block
*start
,
1153 struct vtn_block
*end
)
1155 struct vtn_block
*block
= start
;
1156 while (block
!= end
) {
1157 vtn_foreach_instruction(b
, block
->label
, block
->branch
,
1158 vtn_handle_body_instruction
);
1160 const uint32_t *w
= block
->branch
;
1161 SpvOp branch_op
= w
[0] & SpvOpCodeMask
;
1162 switch (branch_op
) {
1164 assert(vtn_value(b
, w
[1], vtn_value_type_block
)->block
== end
);
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
;
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
);
1180 struct exec_list
*old_list
= b
->nb
.cf_node_list
;
1182 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->then_list
);
1183 vtn_walk_blocks(b
, then_block
, merge_block
);
1185 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->else_list
);
1186 vtn_walk_blocks(b
, else_block
, merge_block
);
1188 nir_builder_insert_after_cf_list(&b
->nb
, old_list
);
1189 block
= merge_block
;
1196 case SpvOpReturnValue
:
1197 case SpvOpUnreachable
:
1199 unreachable("Unhandled opcode");
1205 spirv_to_nir(const uint32_t *words
, size_t word_count
,
1206 const nir_shader_compiler_options
*options
)
1208 const uint32_t *word_end
= words
+ word_count
;
1210 /* Handle the SPIR-V header (first 4 dwords) */
1211 assert(word_count
> 5);
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);
1221 nir_shader
*shader
= nir_shader_create(NULL
, options
);
1223 /* Initialize the stn_builder object */
1224 struct vtn_builder
*b
= rzalloc(NULL
, struct vtn_builder
);
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
);
1230 /* Handle all the preamble instructions */
1231 words
= vtn_foreach_instruction(b
, words
, word_end
,
1232 vtn_handle_preamble_instruction
);
1234 /* Do a very quick CFG analysis pass */
1235 vtn_foreach_instruction(b
, words
, word_end
,
1236 vtn_handle_first_cfg_pass_instruction
);
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
);