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"
31 static struct vtn_ssa_value
*
32 vtn_const_ssa_value(struct vtn_builder
*b
, nir_constant
*constant
,
33 const struct glsl_type
*type
)
35 struct hash_entry
*entry
= _mesa_hash_table_search(b
->const_table
, constant
);
40 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
43 switch (glsl_get_base_type(type
)) {
48 case GLSL_TYPE_DOUBLE
:
49 if (glsl_type_is_vector_or_scalar(type
)) {
50 unsigned num_components
= glsl_get_vector_elements(val
->type
);
51 nir_load_const_instr
*load
=
52 nir_load_const_instr_create(b
->shader
, num_components
);
54 for (unsigned i
= 0; i
< num_components
; i
++)
55 load
->value
.u
[i
] = constant
->value
.u
[i
];
57 nir_instr_insert_before_cf_list(&b
->impl
->body
, &load
->instr
);
58 val
->def
= &load
->def
;
60 assert(glsl_type_is_matrix(type
));
61 unsigned rows
= glsl_get_vector_elements(val
->type
);
62 unsigned columns
= glsl_get_matrix_columns(val
->type
);
63 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, columns
);
65 for (unsigned i
= 0; i
< columns
; i
++) {
66 struct vtn_ssa_value
*col_val
= rzalloc(b
, struct vtn_ssa_value
);
67 col_val
->type
= glsl_get_column_type(val
->type
);
68 nir_load_const_instr
*load
=
69 nir_load_const_instr_create(b
->shader
, rows
);
71 for (unsigned j
= 0; j
< rows
; j
++)
72 load
->value
.u
[j
] = constant
->value
.u
[rows
* i
+ j
];
74 nir_instr_insert_before_cf_list(&b
->impl
->body
, &load
->instr
);
75 col_val
->def
= &load
->def
;
77 val
->elems
[i
] = col_val
;
82 case GLSL_TYPE_ARRAY
: {
83 unsigned elems
= glsl_get_length(val
->type
);
84 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
85 const struct glsl_type
*elem_type
= glsl_get_array_element(val
->type
);
86 for (unsigned i
= 0; i
< elems
; i
++)
87 val
->elems
[i
] = vtn_const_ssa_value(b
, constant
->elements
[i
],
92 case GLSL_TYPE_STRUCT
: {
93 unsigned elems
= glsl_get_length(val
->type
);
94 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
95 for (unsigned i
= 0; i
< elems
; i
++) {
96 const struct glsl_type
*elem_type
=
97 glsl_get_struct_field(val
->type
, i
);
98 val
->elems
[i
] = vtn_const_ssa_value(b
, constant
->elements
[i
],
105 unreachable("bad constant type");
111 struct vtn_ssa_value
*
112 vtn_ssa_value(struct vtn_builder
*b
, uint32_t value_id
)
114 struct vtn_value
*val
= vtn_untyped_value(b
, value_id
);
115 switch (val
->value_type
) {
116 case vtn_value_type_constant
:
117 return vtn_const_ssa_value(b
, val
->constant
, val
->type
);
119 case vtn_value_type_ssa
:
122 unreachable("Invalid type for an SSA value");
127 vtn_string_literal(struct vtn_builder
*b
, const uint32_t *words
,
130 return ralloc_strndup(b
, (char *)words
, word_count
* sizeof(*words
));
133 static const uint32_t *
134 vtn_foreach_instruction(struct vtn_builder
*b
, const uint32_t *start
,
135 const uint32_t *end
, vtn_instruction_handler handler
)
137 const uint32_t *w
= start
;
139 SpvOp opcode
= w
[0] & SpvOpCodeMask
;
140 unsigned count
= w
[0] >> SpvWordCountShift
;
141 assert(count
>= 1 && w
+ count
<= end
);
143 if (!handler(b
, opcode
, w
, count
))
153 vtn_handle_extension(struct vtn_builder
*b
, SpvOp opcode
,
154 const uint32_t *w
, unsigned count
)
157 case SpvOpExtInstImport
: {
158 struct vtn_value
*val
= vtn_push_value(b
, w
[1], vtn_value_type_extension
);
159 if (strcmp((const char *)&w
[2], "GLSL.std.450") == 0) {
160 val
->ext_handler
= vtn_handle_glsl450_instruction
;
162 assert(!"Unsupported extension");
168 struct vtn_value
*val
= vtn_value(b
, w
[3], vtn_value_type_extension
);
169 bool handled
= val
->ext_handler(b
, w
[4], w
, count
);
176 unreachable("Unhandled opcode");
181 _foreach_decoration_helper(struct vtn_builder
*b
,
182 struct vtn_value
*base_value
,
183 struct vtn_value
*value
,
184 vtn_decoration_foreach_cb cb
, void *data
)
186 for (struct vtn_decoration
*dec
= value
->decoration
; dec
; dec
= dec
->next
) {
188 assert(dec
->group
->value_type
== vtn_value_type_decoration_group
);
189 _foreach_decoration_helper(b
, base_value
, dec
->group
, cb
, data
);
191 cb(b
, base_value
, dec
, data
);
196 /** Iterates (recursively if needed) over all of the decorations on a value
198 * This function iterates over all of the decorations applied to a given
199 * value. If it encounters a decoration group, it recurses into the group
200 * and iterates over all of those decorations as well.
203 vtn_foreach_decoration(struct vtn_builder
*b
, struct vtn_value
*value
,
204 vtn_decoration_foreach_cb cb
, void *data
)
206 _foreach_decoration_helper(b
, value
, value
, cb
, data
);
210 vtn_handle_decoration(struct vtn_builder
*b
, SpvOp opcode
,
211 const uint32_t *w
, unsigned count
)
214 case SpvOpDecorationGroup
:
215 vtn_push_value(b
, w
[1], vtn_value_type_undef
);
218 case SpvOpDecorate
: {
219 struct vtn_value
*val
= &b
->values
[w
[1]];
221 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
222 dec
->decoration
= w
[2];
223 dec
->literals
= &w
[3];
225 /* Link into the list */
226 dec
->next
= val
->decoration
;
227 val
->decoration
= dec
;
231 case SpvOpGroupDecorate
: {
232 struct vtn_value
*group
= &b
->values
[w
[1]];
233 assert(group
->value_type
== vtn_value_type_decoration_group
);
235 for (unsigned i
= 2; i
< count
; i
++) {
236 struct vtn_value
*val
= &b
->values
[w
[i
]];
237 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
240 /* Link into the list */
241 dec
->next
= val
->decoration
;
242 val
->decoration
= dec
;
247 case SpvOpGroupMemberDecorate
:
248 assert(!"Bad instruction. Khronos Bug #13513");
252 unreachable("Unhandled opcode");
256 static const struct glsl_type
*
257 vtn_handle_type(struct vtn_builder
*b
, SpvOp opcode
,
258 const uint32_t *args
, unsigned count
)
262 return glsl_void_type();
264 return glsl_bool_type();
266 return glsl_int_type();
268 return glsl_float_type();
270 case SpvOpTypeVector
: {
271 const struct glsl_type
*base
=
272 vtn_value(b
, args
[0], vtn_value_type_type
)->type
;
273 unsigned elems
= args
[1];
275 assert(glsl_type_is_scalar(base
));
276 return glsl_vector_type(glsl_get_base_type(base
), elems
);
279 case SpvOpTypeMatrix
: {
280 const struct glsl_type
*base
=
281 vtn_value(b
, args
[0], vtn_value_type_type
)->type
;
282 unsigned columns
= args
[1];
284 assert(glsl_type_is_vector(base
));
285 return glsl_matrix_type(glsl_get_base_type(base
),
286 glsl_get_vector_elements(base
),
291 return glsl_array_type(b
->values
[args
[0]].type
, args
[1]);
293 case SpvOpTypeStruct
: {
294 NIR_VLA(struct glsl_struct_field
, fields
, count
);
295 for (unsigned i
= 0; i
< count
; i
++) {
296 /* TODO: Handle decorators */
297 fields
[i
].type
= vtn_value(b
, args
[i
], vtn_value_type_type
)->type
;
298 fields
[i
].name
= ralloc_asprintf(b
, "field%d", i
);
299 fields
[i
].location
= -1;
300 fields
[i
].interpolation
= 0;
301 fields
[i
].centroid
= 0;
302 fields
[i
].sample
= 0;
303 fields
[i
].matrix_layout
= 2;
304 fields
[i
].stream
= -1;
306 return glsl_struct_type(fields
, count
, "struct");
309 case SpvOpTypeFunction
: {
310 const struct glsl_type
*return_type
= b
->values
[args
[0]].type
;
311 NIR_VLA(struct glsl_function_param
, params
, count
- 1);
312 for (unsigned i
= 1; i
< count
; i
++) {
313 params
[i
- 1].type
= vtn_value(b
, args
[i
], vtn_value_type_type
)->type
;
316 params
[i
- 1].in
= true;
317 params
[i
- 1].out
= true;
319 return glsl_function_type(return_type
, params
, count
- 1);
322 case SpvOpTypePointer
:
323 /* FIXME: For now, we'll just do the really lame thing and return
324 * the same type. The validator should ensure that the proper number
325 * of dereferences happen
327 return vtn_value(b
, args
[1], vtn_value_type_type
)->type
;
329 case SpvOpTypeSampler
: {
330 const struct glsl_type
*sampled_type
=
331 vtn_value(b
, args
[0], vtn_value_type_type
)->type
;
333 assert(glsl_type_is_vector_or_scalar(sampled_type
));
335 enum glsl_sampler_dim dim
;
336 switch ((SpvDim
)args
[1]) {
337 case SpvDim1D
: dim
= GLSL_SAMPLER_DIM_1D
; break;
338 case SpvDim2D
: dim
= GLSL_SAMPLER_DIM_2D
; break;
339 case SpvDim3D
: dim
= GLSL_SAMPLER_DIM_3D
; break;
340 case SpvDimCube
: dim
= GLSL_SAMPLER_DIM_CUBE
; break;
341 case SpvDimRect
: dim
= GLSL_SAMPLER_DIM_RECT
; break;
342 case SpvDimBuffer
: dim
= GLSL_SAMPLER_DIM_BUF
; break;
344 unreachable("Invalid SPIR-V Sampler dimension");
347 /* TODO: Handle the various texture image/filter options */
350 bool is_array
= args
[3];
351 bool is_shadow
= args
[4];
353 assert(args
[5] == 0 && "FIXME: Handl multi-sampled textures");
355 return glsl_sampler_type(dim
, is_shadow
, is_array
,
356 glsl_get_base_type(sampled_type
));
359 case SpvOpTypeRuntimeArray
:
360 case SpvOpTypeOpaque
:
362 case SpvOpTypeDeviceEvent
:
363 case SpvOpTypeReserveId
:
367 unreachable("Unhandled opcode");
372 vtn_handle_constant(struct vtn_builder
*b
, SpvOp opcode
,
373 const uint32_t *w
, unsigned count
)
375 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_constant
);
376 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
377 val
->constant
= ralloc(b
, nir_constant
);
379 case SpvOpConstantTrue
:
380 assert(val
->type
== glsl_bool_type());
381 val
->constant
->value
.u
[0] = NIR_TRUE
;
383 case SpvOpConstantFalse
:
384 assert(val
->type
== glsl_bool_type());
385 val
->constant
->value
.u
[0] = NIR_FALSE
;
388 assert(glsl_type_is_scalar(val
->type
));
389 val
->constant
->value
.u
[0] = w
[3];
391 case SpvOpConstantComposite
: {
392 unsigned elem_count
= count
- 3;
393 nir_constant
**elems
= ralloc_array(b
, nir_constant
*, elem_count
);
394 for (unsigned i
= 0; i
< elem_count
; i
++)
395 elems
[i
] = vtn_value(b
, w
[i
+ 3], vtn_value_type_constant
)->constant
;
397 switch (glsl_get_base_type(val
->type
)) {
400 case GLSL_TYPE_FLOAT
:
402 if (glsl_type_is_matrix(val
->type
)) {
403 unsigned rows
= glsl_get_vector_elements(val
->type
);
404 assert(glsl_get_matrix_columns(val
->type
) == elem_count
);
405 for (unsigned i
= 0; i
< elem_count
; i
++)
406 for (unsigned j
= 0; j
< rows
; j
++)
407 val
->constant
->value
.u
[rows
* i
+ j
] = elems
[i
]->value
.u
[j
];
409 assert(glsl_type_is_vector(val
->type
));
410 assert(glsl_get_vector_elements(val
->type
) == elem_count
);
411 for (unsigned i
= 0; i
< elem_count
; i
++)
412 val
->constant
->value
.u
[i
] = elems
[i
]->value
.u
[0];
417 case GLSL_TYPE_STRUCT
:
418 case GLSL_TYPE_ARRAY
:
419 ralloc_steal(val
->constant
, elems
);
420 val
->constant
->elements
= elems
;
424 unreachable("Unsupported type for constants");
430 unreachable("Unhandled opcode");
435 var_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
,
436 const struct vtn_decoration
*dec
, void *void_var
)
438 assert(val
->value_type
== vtn_value_type_deref
);
439 assert(val
->deref
->deref
.child
== NULL
);
440 assert(val
->deref
->var
== void_var
);
442 nir_variable
*var
= void_var
;
443 switch (dec
->decoration
) {
444 case SpvDecorationPrecisionLow
:
445 case SpvDecorationPrecisionMedium
:
446 case SpvDecorationPrecisionHigh
:
447 break; /* FIXME: Do nothing with these for now. */
448 case SpvDecorationSmooth
:
449 var
->data
.interpolation
= INTERP_QUALIFIER_SMOOTH
;
451 case SpvDecorationNoperspective
:
452 var
->data
.interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
454 case SpvDecorationFlat
:
455 var
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
457 case SpvDecorationCentroid
:
458 var
->data
.centroid
= true;
460 case SpvDecorationSample
:
461 var
->data
.sample
= true;
463 case SpvDecorationInvariant
:
464 var
->data
.invariant
= true;
466 case SpvDecorationConstant
:
467 assert(var
->constant_initializer
!= NULL
);
468 var
->data
.read_only
= true;
470 case SpvDecorationNonwritable
:
471 var
->data
.read_only
= true;
473 case SpvDecorationLocation
:
474 var
->data
.explicit_location
= true;
475 var
->data
.location
= dec
->literals
[0];
477 case SpvDecorationComponent
:
478 var
->data
.location_frac
= dec
->literals
[0];
480 case SpvDecorationIndex
:
481 var
->data
.explicit_index
= true;
482 var
->data
.index
= dec
->literals
[0];
484 case SpvDecorationBinding
:
485 var
->data
.explicit_binding
= true;
486 var
->data
.binding
= dec
->literals
[0];
488 case SpvDecorationDescriptorSet
:
489 var
->data
.descriptor_set
= dec
->literals
[0];
491 case SpvDecorationBuiltIn
:
492 var
->data
.mode
= nir_var_system_value
;
493 var
->data
.read_only
= true;
494 switch ((SpvBuiltIn
)dec
->literals
[0]) {
495 case SpvBuiltInFrontFacing
:
496 var
->data
.location
= SYSTEM_VALUE_FRONT_FACE
;
498 case SpvBuiltInVertexId
:
499 var
->data
.location
= SYSTEM_VALUE_VERTEX_ID
;
501 case SpvBuiltInInstanceId
:
502 var
->data
.location
= SYSTEM_VALUE_INSTANCE_ID
;
504 case SpvBuiltInSampleId
:
505 var
->data
.location
= SYSTEM_VALUE_SAMPLE_ID
;
507 case SpvBuiltInSamplePosition
:
508 var
->data
.location
= SYSTEM_VALUE_SAMPLE_POS
;
510 case SpvBuiltInSampleMask
:
511 var
->data
.location
= SYSTEM_VALUE_SAMPLE_MASK_IN
;
513 case SpvBuiltInInvocationId
:
514 var
->data
.location
= SYSTEM_VALUE_INVOCATION_ID
;
516 case SpvBuiltInPrimitiveId
:
517 case SpvBuiltInPosition
:
518 case SpvBuiltInPointSize
:
519 case SpvBuiltInClipVertex
:
520 case SpvBuiltInClipDistance
:
521 case SpvBuiltInCullDistance
:
522 case SpvBuiltInLayer
:
523 case SpvBuiltInViewportIndex
:
524 case SpvBuiltInTessLevelOuter
:
525 case SpvBuiltInTessLevelInner
:
526 case SpvBuiltInTessCoord
:
527 case SpvBuiltInPatchVertices
:
528 case SpvBuiltInFragCoord
:
529 case SpvBuiltInPointCoord
:
530 case SpvBuiltInFragColor
:
531 case SpvBuiltInFragDepth
:
532 case SpvBuiltInHelperInvocation
:
533 case SpvBuiltInNumWorkgroups
:
534 case SpvBuiltInWorkgroupSize
:
535 case SpvBuiltInWorkgroupId
:
536 case SpvBuiltInLocalInvocationId
:
537 case SpvBuiltInGlobalInvocationId
:
538 case SpvBuiltInLocalInvocationIndex
:
539 case SpvBuiltInWorkDim
:
540 case SpvBuiltInGlobalSize
:
541 case SpvBuiltInEnqueuedWorkgroupSize
:
542 case SpvBuiltInGlobalOffset
:
543 case SpvBuiltInGlobalLinearId
:
544 case SpvBuiltInWorkgroupLinearId
:
545 case SpvBuiltInSubgroupSize
:
546 case SpvBuiltInSubgroupMaxSize
:
547 case SpvBuiltInNumSubgroups
:
548 case SpvBuiltInNumEnqueuedSubgroups
:
549 case SpvBuiltInSubgroupId
:
550 case SpvBuiltInSubgroupLocalInvocationId
:
551 unreachable("Unhandled builtin enum");
554 case SpvDecorationNoStaticUse
:
555 /* This can safely be ignored */
557 case SpvDecorationBlock
:
558 case SpvDecorationBufferBlock
:
559 case SpvDecorationRowMajor
:
560 case SpvDecorationColMajor
:
561 case SpvDecorationGLSLShared
:
562 case SpvDecorationGLSLStd140
:
563 case SpvDecorationGLSLStd430
:
564 case SpvDecorationGLSLPacked
:
565 case SpvDecorationPatch
:
566 case SpvDecorationRestrict
:
567 case SpvDecorationAliased
:
568 case SpvDecorationVolatile
:
569 case SpvDecorationCoherent
:
570 case SpvDecorationNonreadable
:
571 case SpvDecorationUniform
:
572 /* This is really nice but we have no use for it right now. */
573 case SpvDecorationCPacked
:
574 case SpvDecorationSaturatedConversion
:
575 case SpvDecorationStream
:
576 case SpvDecorationOffset
:
577 case SpvDecorationAlignment
:
578 case SpvDecorationXfbBuffer
:
579 case SpvDecorationStride
:
580 case SpvDecorationFuncParamAttr
:
581 case SpvDecorationFPRoundingMode
:
582 case SpvDecorationFPFastMathMode
:
583 case SpvDecorationLinkageAttributes
:
584 case SpvDecorationSpecId
:
587 unreachable("Unhandled variable decoration");
591 static struct vtn_ssa_value
*
592 _vtn_variable_load(struct vtn_builder
*b
,
593 nir_deref_var
*src_deref
, nir_deref
*src_deref_tail
)
595 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
596 val
->type
= src_deref_tail
->type
;
598 /* The deref tail may contain a deref to select a component of a vector (in
599 * other words, it might not be an actual tail) so we have to save it away
600 * here since we overwrite it later.
602 nir_deref
*old_child
= src_deref_tail
->child
;
604 if (glsl_type_is_vector_or_scalar(val
->type
)) {
605 nir_intrinsic_instr
*load
=
606 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_load_var
);
608 nir_deref_as_var(nir_copy_deref(load
, &src_deref
->deref
));
609 load
->num_components
= glsl_get_vector_elements(val
->type
);
610 nir_ssa_dest_init(&load
->instr
, &load
->dest
, load
->num_components
, NULL
);
612 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
614 if (src_deref
->var
->data
.mode
== nir_var_uniform
&&
615 glsl_get_base_type(val
->type
) == GLSL_TYPE_BOOL
) {
616 /* Uniform boolean loads need to be fixed up since they're defined
617 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
619 val
->def
= nir_ine(&b
->nb
, &load
->dest
.ssa
, nir_imm_int(&b
->nb
, 0));
621 val
->def
= &load
->dest
.ssa
;
623 } else if (glsl_get_base_type(val
->type
) == GLSL_TYPE_ARRAY
||
624 glsl_type_is_matrix(val
->type
)) {
625 unsigned elems
= glsl_get_length(val
->type
);
626 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
628 nir_deref_array
*deref
= nir_deref_array_create(b
);
629 deref
->deref_array_type
= nir_deref_array_type_direct
;
630 deref
->deref
.type
= glsl_get_array_element(val
->type
);
631 src_deref_tail
->child
= &deref
->deref
;
632 for (unsigned i
= 0; i
< elems
; i
++) {
633 deref
->base_offset
= i
;
634 val
->elems
[i
] = _vtn_variable_load(b
, src_deref
, &deref
->deref
);
637 assert(glsl_get_base_type(val
->type
) == GLSL_TYPE_STRUCT
);
638 unsigned elems
= glsl_get_length(val
->type
);
639 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
641 nir_deref_struct
*deref
= nir_deref_struct_create(b
, 0);
642 src_deref_tail
->child
= &deref
->deref
;
643 for (unsigned i
= 0; i
< elems
; i
++) {
645 deref
->deref
.type
= glsl_get_struct_field(val
->type
, i
);
646 val
->elems
[i
] = _vtn_variable_load(b
, src_deref
, &deref
->deref
);
650 src_deref_tail
->child
= old_child
;
656 _vtn_variable_store(struct vtn_builder
*b
, nir_deref_var
*dest_deref
,
657 nir_deref
*dest_deref_tail
, struct vtn_ssa_value
*src
)
659 nir_deref
*old_child
= dest_deref_tail
->child
;
661 if (glsl_type_is_vector_or_scalar(src
->type
)) {
662 nir_intrinsic_instr
*store
=
663 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_store_var
);
664 store
->variables
[0] =
665 nir_deref_as_var(nir_copy_deref(store
, &dest_deref
->deref
));
666 store
->src
[0] = nir_src_for_ssa(src
->def
);
668 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
669 } else if (glsl_get_base_type(src
->type
) == GLSL_TYPE_ARRAY
||
670 glsl_type_is_matrix(src
->type
)) {
671 unsigned elems
= glsl_get_length(src
->type
);
673 nir_deref_array
*deref
= nir_deref_array_create(b
);
674 deref
->deref_array_type
= nir_deref_array_type_direct
;
675 deref
->deref
.type
= glsl_get_array_element(src
->type
);
676 dest_deref_tail
->child
= &deref
->deref
;
677 for (unsigned i
= 0; i
< elems
; i
++) {
678 deref
->base_offset
= i
;
679 _vtn_variable_store(b
, dest_deref
, &deref
->deref
, src
->elems
[i
]);
682 assert(glsl_get_base_type(src
->type
) == GLSL_TYPE_STRUCT
);
683 unsigned elems
= glsl_get_length(src
->type
);
685 nir_deref_struct
*deref
= nir_deref_struct_create(b
, 0);
686 dest_deref_tail
->child
= &deref
->deref
;
687 for (unsigned i
= 0; i
< elems
; i
++) {
689 deref
->deref
.type
= glsl_get_struct_field(src
->type
, i
);
690 _vtn_variable_store(b
, dest_deref
, &deref
->deref
, src
->elems
[i
]);
694 dest_deref_tail
->child
= old_child
;
698 * Gets the NIR-level deref tail, which may have as a child an array deref
699 * selecting which component due to OpAccessChain supporting per-component
700 * indexing in SPIR-V.
704 get_deref_tail(nir_deref_var
*deref
)
706 nir_deref
*cur
= &deref
->deref
;
707 while (!glsl_type_is_vector_or_scalar(cur
->type
) && cur
->child
)
713 static nir_ssa_def
*vtn_vector_extract(struct vtn_builder
*b
,
714 nir_ssa_def
*src
, unsigned index
);
716 static nir_ssa_def
*vtn_vector_extract_dynamic(struct vtn_builder
*b
,
720 static struct vtn_ssa_value
*
721 vtn_variable_load(struct vtn_builder
*b
, nir_deref_var
*src
)
723 nir_deref
*src_tail
= get_deref_tail(src
);
724 struct vtn_ssa_value
*val
= _vtn_variable_load(b
, src
, src_tail
);
726 if (src_tail
->child
) {
727 nir_deref_array
*vec_deref
= nir_deref_as_array(src_tail
->child
);
728 assert(vec_deref
->deref
.child
== NULL
);
729 val
->type
= vec_deref
->deref
.type
;
730 if (vec_deref
->deref_array_type
== nir_deref_array_type_direct
)
731 val
->def
= vtn_vector_extract(b
, val
->def
, vec_deref
->base_offset
);
733 val
->def
= vtn_vector_extract_dynamic(b
, val
->def
,
734 vec_deref
->indirect
.ssa
);
740 static nir_ssa_def
* vtn_vector_insert(struct vtn_builder
*b
,
741 nir_ssa_def
*src
, nir_ssa_def
*insert
,
744 static nir_ssa_def
* vtn_vector_insert_dynamic(struct vtn_builder
*b
,
749 vtn_variable_store(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
752 nir_deref
*dest_tail
= get_deref_tail(dest
);
753 if (dest_tail
->child
) {
754 struct vtn_ssa_value
*val
= _vtn_variable_load(b
, dest
, dest_tail
);
755 nir_deref_array
*deref
= nir_deref_as_array(dest_tail
->child
);
756 assert(deref
->deref
.child
== NULL
);
757 if (deref
->deref_array_type
== nir_deref_array_type_direct
)
758 val
->def
= vtn_vector_insert(b
, val
->def
, src
->def
,
761 val
->def
= vtn_vector_insert_dynamic(b
, val
->def
, src
->def
,
762 deref
->indirect
.ssa
);
763 _vtn_variable_store(b
, dest
, dest_tail
, val
);
765 _vtn_variable_store(b
, dest
, dest_tail
, src
);
770 vtn_variable_copy(struct vtn_builder
*b
, nir_deref_var
*src
,
773 nir_deref
*src_tail
= get_deref_tail(src
);
775 if (src_tail
->child
) {
776 assert(get_deref_tail(dest
)->child
);
777 struct vtn_ssa_value
*val
= vtn_variable_load(b
, src
);
778 vtn_variable_store(b
, val
, dest
);
780 nir_intrinsic_instr
*copy
=
781 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
782 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
783 copy
->variables
[1] = nir_deref_as_var(nir_copy_deref(copy
, &src
->deref
));
785 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
790 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
791 const uint32_t *w
, unsigned count
)
794 case SpvOpVariable
: {
795 const struct glsl_type
*type
=
796 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
797 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
799 nir_variable
*var
= ralloc(b
->shader
, nir_variable
);
802 var
->name
= ralloc_strdup(var
, val
->name
);
804 switch ((SpvStorageClass
)w
[3]) {
805 case SpvStorageClassUniform
:
806 case SpvStorageClassUniformConstant
:
807 var
->data
.mode
= nir_var_uniform
;
808 var
->data
.read_only
= true;
809 var
->interface_type
= type
;
811 case SpvStorageClassInput
:
812 var
->data
.mode
= nir_var_shader_in
;
813 var
->data
.read_only
= true;
815 case SpvStorageClassOutput
:
816 var
->data
.mode
= nir_var_shader_out
;
818 case SpvStorageClassPrivateGlobal
:
819 var
->data
.mode
= nir_var_global
;
821 case SpvStorageClassFunction
:
822 var
->data
.mode
= nir_var_local
;
824 case SpvStorageClassWorkgroupLocal
:
825 case SpvStorageClassWorkgroupGlobal
:
826 case SpvStorageClassGeneric
:
827 case SpvStorageClassPrivate
:
828 case SpvStorageClassAtomicCounter
:
830 unreachable("Unhandled variable storage class");
835 var
->constant_initializer
=
836 vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
839 val
->deref
= nir_deref_var_create(b
, var
);
841 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
843 if (b
->execution_model
== SpvExecutionModelFragment
&&
844 var
->data
.mode
== nir_var_shader_out
) {
845 var
->data
.location
+= FRAG_RESULT_DATA0
;
846 } else if (b
->execution_model
== SpvExecutionModelVertex
&&
847 var
->data
.mode
== nir_var_shader_in
) {
848 var
->data
.location
+= VERT_ATTRIB_GENERIC0
;
849 } else if (var
->data
.mode
== nir_var_shader_in
||
850 var
->data
.mode
== nir_var_shader_out
) {
851 var
->data
.location
+= VARYING_SLOT_VAR0
;
854 switch (var
->data
.mode
) {
855 case nir_var_shader_in
:
856 exec_list_push_tail(&b
->shader
->inputs
, &var
->node
);
858 case nir_var_shader_out
:
859 exec_list_push_tail(&b
->shader
->outputs
, &var
->node
);
862 exec_list_push_tail(&b
->shader
->globals
, &var
->node
);
865 exec_list_push_tail(&b
->impl
->locals
, &var
->node
);
867 case nir_var_uniform
:
868 exec_list_push_tail(&b
->shader
->uniforms
, &var
->node
);
870 case nir_var_system_value
:
871 exec_list_push_tail(&b
->shader
->system_values
, &var
->node
);
877 case SpvOpAccessChain
:
878 case SpvOpInBoundsAccessChain
: {
879 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
880 nir_deref_var
*base
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
881 val
->deref
= nir_deref_as_var(nir_copy_deref(b
, &base
->deref
));
883 nir_deref
*tail
= &val
->deref
->deref
;
887 for (unsigned i
= 0; i
< count
- 4; i
++) {
888 assert(w
[i
+ 4] < b
->value_id_bound
);
889 struct vtn_value
*idx_val
= &b
->values
[w
[i
+ 4]];
891 enum glsl_base_type base_type
= glsl_get_base_type(tail
->type
);
895 case GLSL_TYPE_FLOAT
:
896 case GLSL_TYPE_DOUBLE
:
898 case GLSL_TYPE_ARRAY
: {
899 nir_deref_array
*deref_arr
= nir_deref_array_create(b
);
900 if (base_type
== GLSL_TYPE_ARRAY
) {
901 deref_arr
->deref
.type
= glsl_get_array_element(tail
->type
);
902 } else if (glsl_type_is_matrix(tail
->type
)) {
903 deref_arr
->deref
.type
= glsl_get_column_type(tail
->type
);
905 assert(glsl_type_is_vector(tail
->type
));
906 deref_arr
->deref
.type
= glsl_scalar_type(base_type
);
909 if (idx_val
->value_type
== vtn_value_type_constant
) {
910 unsigned idx
= idx_val
->constant
->value
.u
[0];
911 deref_arr
->deref_array_type
= nir_deref_array_type_direct
;
912 deref_arr
->base_offset
= idx
;
914 assert(idx_val
->value_type
== vtn_value_type_ssa
);
915 deref_arr
->deref_array_type
= nir_deref_array_type_indirect
;
916 deref_arr
->base_offset
= 0;
917 deref_arr
->indirect
=
918 nir_src_for_ssa(vtn_ssa_value(b
, w
[1])->def
);
920 tail
->child
= &deref_arr
->deref
;
924 case GLSL_TYPE_STRUCT
: {
925 assert(idx_val
->value_type
== vtn_value_type_constant
);
926 unsigned idx
= idx_val
->constant
->value
.u
[0];
927 nir_deref_struct
*deref_struct
= nir_deref_struct_create(b
, idx
);
928 deref_struct
->deref
.type
= glsl_get_struct_field(tail
->type
, idx
);
929 tail
->child
= &deref_struct
->deref
;
933 unreachable("Invalid type for deref");
940 case SpvOpCopyMemory
: {
941 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
942 nir_deref_var
*src
= vtn_value(b
, w
[2], vtn_value_type_deref
)->deref
;
944 vtn_variable_copy(b
, src
, dest
);
949 nir_deref_var
*src
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
950 const struct glsl_type
*src_type
= nir_deref_tail(&src
->deref
)->type
;
952 if (glsl_get_base_type(src_type
) == GLSL_TYPE_SAMPLER
) {
953 vtn_push_value(b
, w
[2], vtn_value_type_deref
)->deref
= src
;
957 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
958 val
->ssa
= vtn_variable_load(b
, src
);
963 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
964 struct vtn_ssa_value
*src
= vtn_ssa_value(b
, w
[2]);
965 vtn_variable_store(b
, src
, dest
);
969 case SpvOpVariableArray
:
970 case SpvOpCopyMemorySized
:
971 case SpvOpArrayLength
:
972 case SpvOpImagePointer
:
974 unreachable("Unhandled opcode");
979 vtn_handle_function_call(struct vtn_builder
*b
, SpvOp opcode
,
980 const uint32_t *w
, unsigned count
)
982 unreachable("Unhandled opcode");
986 vtn_tex_src(struct vtn_builder
*b
, unsigned index
, nir_tex_src_type type
)
989 src
.src
= nir_src_for_ssa(vtn_value(b
, index
, vtn_value_type_ssa
)->ssa
->def
);
995 vtn_handle_texture(struct vtn_builder
*b
, SpvOp opcode
,
996 const uint32_t *w
, unsigned count
)
998 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
999 nir_deref_var
*sampler
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
1001 nir_tex_src srcs
[8]; /* 8 should be enough */
1002 nir_tex_src
*p
= srcs
;
1004 unsigned coord_components
= 0;
1006 case SpvOpTextureSample
:
1007 case SpvOpTextureSampleDref
:
1008 case SpvOpTextureSampleLod
:
1009 case SpvOpTextureSampleProj
:
1010 case SpvOpTextureSampleGrad
:
1011 case SpvOpTextureSampleOffset
:
1012 case SpvOpTextureSampleProjLod
:
1013 case SpvOpTextureSampleProjGrad
:
1014 case SpvOpTextureSampleLodOffset
:
1015 case SpvOpTextureSampleProjOffset
:
1016 case SpvOpTextureSampleGradOffset
:
1017 case SpvOpTextureSampleProjLodOffset
:
1018 case SpvOpTextureSampleProjGradOffset
:
1019 case SpvOpTextureFetchTexelLod
:
1020 case SpvOpTextureFetchTexelOffset
:
1021 case SpvOpTextureFetchSample
:
1022 case SpvOpTextureFetchTexel
:
1023 case SpvOpTextureGather
:
1024 case SpvOpTextureGatherOffset
:
1025 case SpvOpTextureGatherOffsets
:
1026 case SpvOpTextureQueryLod
: {
1027 /* All these types have the coordinate as their first real argument */
1028 struct vtn_ssa_value
*coord
= vtn_ssa_value(b
, w
[4]);
1029 coord_components
= glsl_get_vector_elements(coord
->type
);
1030 p
->src
= nir_src_for_ssa(coord
->def
);
1031 p
->src_type
= nir_tex_src_coord
;
1042 case SpvOpTextureSample
:
1043 texop
= nir_texop_tex
;
1046 texop
= nir_texop_txb
;
1047 *p
++ = vtn_tex_src(b
, w
[5], nir_tex_src_bias
);
1051 case SpvOpTextureSampleDref
:
1052 case SpvOpTextureSampleLod
:
1053 case SpvOpTextureSampleProj
:
1054 case SpvOpTextureSampleGrad
:
1055 case SpvOpTextureSampleOffset
:
1056 case SpvOpTextureSampleProjLod
:
1057 case SpvOpTextureSampleProjGrad
:
1058 case SpvOpTextureSampleLodOffset
:
1059 case SpvOpTextureSampleProjOffset
:
1060 case SpvOpTextureSampleGradOffset
:
1061 case SpvOpTextureSampleProjLodOffset
:
1062 case SpvOpTextureSampleProjGradOffset
:
1063 case SpvOpTextureFetchTexelLod
:
1064 case SpvOpTextureFetchTexelOffset
:
1065 case SpvOpTextureFetchSample
:
1066 case SpvOpTextureFetchTexel
:
1067 case SpvOpTextureGather
:
1068 case SpvOpTextureGatherOffset
:
1069 case SpvOpTextureGatherOffsets
:
1070 case SpvOpTextureQuerySizeLod
:
1071 case SpvOpTextureQuerySize
:
1072 case SpvOpTextureQueryLod
:
1073 case SpvOpTextureQueryLevels
:
1074 case SpvOpTextureQuerySamples
:
1076 unreachable("Unhandled opcode");
1079 nir_tex_instr
*instr
= nir_tex_instr_create(b
->shader
, p
- srcs
);
1081 const struct glsl_type
*sampler_type
= nir_deref_tail(&sampler
->deref
)->type
;
1082 instr
->sampler_dim
= glsl_get_sampler_dim(sampler_type
);
1084 switch (glsl_get_sampler_result_type(sampler_type
)) {
1085 case GLSL_TYPE_FLOAT
: instr
->dest_type
= nir_type_float
; break;
1086 case GLSL_TYPE_INT
: instr
->dest_type
= nir_type_int
; break;
1087 case GLSL_TYPE_UINT
: instr
->dest_type
= nir_type_unsigned
; break;
1088 case GLSL_TYPE_BOOL
: instr
->dest_type
= nir_type_bool
; break;
1090 unreachable("Invalid base type for sampler result");
1094 memcpy(instr
->src
, srcs
, instr
->num_srcs
* sizeof(*instr
->src
));
1095 instr
->coord_components
= coord_components
;
1096 instr
->is_array
= glsl_sampler_type_is_array(sampler_type
);
1097 instr
->is_shadow
= glsl_sampler_type_is_shadow(sampler_type
);
1099 instr
->sampler
= nir_deref_as_var(nir_copy_deref(instr
, &sampler
->deref
));
1101 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
, 4, NULL
);
1102 val
->ssa
->def
= &instr
->dest
.ssa
;
1103 val
->ssa
->type
= val
->type
;
1105 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
1108 static struct vtn_ssa_value
*
1109 vtn_create_ssa_value(struct vtn_builder
*b
, const struct glsl_type
*type
)
1111 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
1114 if (!glsl_type_is_vector_or_scalar(type
)) {
1115 unsigned elems
= glsl_get_length(type
);
1116 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1117 for (unsigned i
= 0; i
< elems
; i
++) {
1118 const struct glsl_type
*child_type
;
1120 switch (glsl_get_base_type(type
)) {
1122 case GLSL_TYPE_UINT
:
1123 case GLSL_TYPE_BOOL
:
1124 case GLSL_TYPE_FLOAT
:
1125 case GLSL_TYPE_DOUBLE
:
1126 child_type
= glsl_get_column_type(type
);
1128 case GLSL_TYPE_ARRAY
:
1129 child_type
= glsl_get_array_element(type
);
1131 case GLSL_TYPE_STRUCT
:
1132 child_type
= glsl_get_struct_field(type
, i
);
1135 unreachable("unkown base type");
1138 val
->elems
[i
] = vtn_create_ssa_value(b
, child_type
);
1145 static nir_alu_instr
*
1146 create_vec(void *mem_ctx
, unsigned num_components
)
1149 switch (num_components
) {
1150 case 1: op
= nir_op_fmov
; break;
1151 case 2: op
= nir_op_vec2
; break;
1152 case 3: op
= nir_op_vec3
; break;
1153 case 4: op
= nir_op_vec4
; break;
1154 default: unreachable("bad vector size");
1157 nir_alu_instr
*vec
= nir_alu_instr_create(mem_ctx
, op
);
1158 nir_ssa_dest_init(&vec
->instr
, &vec
->dest
.dest
, num_components
, NULL
);
1163 static struct vtn_ssa_value
*
1164 vtn_transpose(struct vtn_builder
*b
, struct vtn_ssa_value
*src
)
1166 if (src
->transposed
)
1167 return src
->transposed
;
1169 struct vtn_ssa_value
*dest
=
1170 vtn_create_ssa_value(b
, glsl_transposed_type(src
->type
));
1172 for (unsigned i
= 0; i
< glsl_get_matrix_columns(dest
->type
); i
++) {
1173 nir_alu_instr
*vec
= create_vec(b
, glsl_get_matrix_columns(src
->type
));
1174 if (glsl_type_is_vector_or_scalar(src
->type
)) {
1175 vec
->src
[0].src
= nir_src_for_ssa(src
->def
);
1176 vec
->src
[0].swizzle
[0] = i
;
1178 for (unsigned j
= 0; j
< glsl_get_matrix_columns(src
->type
); j
++) {
1179 vec
->src
[j
].src
= nir_src_for_ssa(src
->elems
[j
]->def
);
1180 vec
->src
[j
].swizzle
[0] = i
;
1183 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
1184 dest
->elems
[i
]->def
= &vec
->dest
.dest
.ssa
;
1187 dest
->transposed
= src
;
1193 * Normally, column vectors in SPIR-V correspond to a single NIR SSA
1194 * definition. But for matrix multiplies, we want to do one routine for
1195 * multiplying a matrix by a matrix and then pretend that vectors are matrices
1196 * with one column. So we "wrap" these things, and unwrap the result before we
1200 static struct vtn_ssa_value
*
1201 vtn_wrap_matrix(struct vtn_builder
*b
, struct vtn_ssa_value
*val
)
1206 if (glsl_type_is_matrix(val
->type
))
1209 struct vtn_ssa_value
*dest
= rzalloc(b
, struct vtn_ssa_value
);
1210 dest
->type
= val
->type
;
1211 dest
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, 1);
1212 dest
->elems
[0] = val
;
1217 static struct vtn_ssa_value
*
1218 vtn_unwrap_matrix(struct vtn_ssa_value
*val
)
1220 if (glsl_type_is_matrix(val
->type
))
1223 return val
->elems
[0];
1226 static struct vtn_ssa_value
*
1227 vtn_matrix_multiply(struct vtn_builder
*b
,
1228 struct vtn_ssa_value
*_src0
, struct vtn_ssa_value
*_src1
)
1231 struct vtn_ssa_value
*src0
= vtn_wrap_matrix(b
, _src0
);
1232 struct vtn_ssa_value
*src1
= vtn_wrap_matrix(b
, _src1
);
1233 struct vtn_ssa_value
*src0_transpose
= vtn_wrap_matrix(b
, _src0
->transposed
);
1234 struct vtn_ssa_value
*src1_transpose
= vtn_wrap_matrix(b
, _src1
->transposed
);
1236 unsigned src0_rows
= glsl_get_vector_elements(src0
->type
);
1237 unsigned src0_columns
= glsl_get_matrix_columns(src0
->type
);
1238 unsigned src1_columns
= glsl_get_matrix_columns(src1
->type
);
1240 struct vtn_ssa_value
*dest
=
1241 vtn_create_ssa_value(b
, glsl_matrix_type(glsl_get_base_type(src0
->type
),
1242 src0_rows
, src1_columns
));
1244 dest
= vtn_wrap_matrix(b
, dest
);
1246 bool transpose_result
= false;
1247 if (src0_transpose
&& src1_transpose
) {
1248 /* transpose(A) * transpose(B) = transpose(B * A) */
1249 src1
= src0_transpose
;
1250 src0
= src1_transpose
;
1251 src0_transpose
= NULL
;
1252 src1_transpose
= NULL
;
1253 transpose_result
= true;
1256 if (src0_transpose
&& !src1_transpose
&&
1257 glsl_get_base_type(src0
->type
) == GLSL_TYPE_FLOAT
) {
1258 /* We already have the rows of src0 and the columns of src1 available,
1259 * so we can just take the dot product of each row with each column to
1263 for (unsigned i
= 0; i
< src1_columns
; i
++) {
1264 nir_alu_instr
*vec
= create_vec(b
, src0_rows
);
1265 for (unsigned j
= 0; j
< src0_rows
; j
++) {
1267 nir_src_for_ssa(nir_fdot(&b
->nb
, src0_transpose
->elems
[j
]->def
,
1268 src1
->elems
[i
]->def
));
1271 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
1272 dest
->elems
[i
]->def
= &vec
->dest
.dest
.ssa
;
1275 /* We don't handle the case where src1 is transposed but not src0, since
1276 * the general case only uses individual components of src1 so the
1277 * optimizer should chew through the transpose we emitted for src1.
1280 for (unsigned i
= 0; i
< src1_columns
; i
++) {
1281 /* dest[i] = sum(src0[j] * src1[i][j] for all j) */
1282 dest
->elems
[i
]->def
=
1283 nir_fmul(&b
->nb
, src0
->elems
[0]->def
,
1284 vtn_vector_extract(b
, src1
->elems
[i
]->def
, 0));
1285 for (unsigned j
= 1; j
< src0_columns
; j
++) {
1286 dest
->elems
[i
]->def
=
1287 nir_fadd(&b
->nb
, dest
->elems
[i
]->def
,
1288 nir_fmul(&b
->nb
, src0
->elems
[j
]->def
,
1289 vtn_vector_extract(b
,
1290 src1
->elems
[i
]->def
, j
)));
1295 dest
= vtn_unwrap_matrix(dest
);
1297 if (transpose_result
)
1298 dest
= vtn_transpose(b
, dest
);
1303 static struct vtn_ssa_value
*
1304 vtn_mat_times_scalar(struct vtn_builder
*b
,
1305 struct vtn_ssa_value
*mat
,
1306 nir_ssa_def
*scalar
)
1308 struct vtn_ssa_value
*dest
= vtn_create_ssa_value(b
, mat
->type
);
1309 for (unsigned i
= 0; i
< glsl_get_matrix_columns(mat
->type
); i
++) {
1310 if (glsl_get_base_type(mat
->type
) == GLSL_TYPE_FLOAT
)
1311 dest
->elems
[i
]->def
= nir_fmul(&b
->nb
, mat
->elems
[i
]->def
, scalar
);
1313 dest
->elems
[i
]->def
= nir_imul(&b
->nb
, mat
->elems
[i
]->def
, scalar
);
1320 vtn_handle_matrix_alu(struct vtn_builder
*b
, SpvOp opcode
,
1321 const uint32_t *w
, unsigned count
)
1323 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
1324 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1327 case SpvOpTranspose
: {
1328 struct vtn_ssa_value
*src
= vtn_ssa_value(b
, w
[3]);
1329 val
->ssa
= vtn_transpose(b
, src
);
1333 case SpvOpOuterProduct
: {
1334 struct vtn_ssa_value
*src0
= vtn_ssa_value(b
, w
[3]);
1335 struct vtn_ssa_value
*src1
= vtn_ssa_value(b
, w
[4]);
1337 val
->ssa
= vtn_matrix_multiply(b
, src0
, vtn_transpose(b
, src1
));
1341 case SpvOpMatrixTimesScalar
: {
1342 struct vtn_ssa_value
*mat
= vtn_ssa_value(b
, w
[3]);
1343 struct vtn_ssa_value
*scalar
= vtn_ssa_value(b
, w
[4]);
1345 if (mat
->transposed
) {
1346 val
->ssa
= vtn_transpose(b
, vtn_mat_times_scalar(b
, mat
->transposed
,
1349 val
->ssa
= vtn_mat_times_scalar(b
, mat
, scalar
->def
);
1354 case SpvOpVectorTimesMatrix
:
1355 case SpvOpMatrixTimesVector
:
1356 case SpvOpMatrixTimesMatrix
: {
1357 struct vtn_ssa_value
*src0
= vtn_ssa_value(b
, w
[3]);
1358 struct vtn_ssa_value
*src1
= vtn_ssa_value(b
, w
[4]);
1360 val
->ssa
= vtn_matrix_multiply(b
, src0
, src1
);
1364 default: unreachable("unknown matrix opcode");
1369 vtn_handle_alu(struct vtn_builder
*b
, SpvOp opcode
,
1370 const uint32_t *w
, unsigned count
)
1372 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
1373 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1374 val
->ssa
= vtn_create_ssa_value(b
, val
->type
);
1376 /* Collect the various SSA sources */
1377 unsigned num_inputs
= count
- 3;
1378 nir_ssa_def
*src
[4];
1379 for (unsigned i
= 0; i
< num_inputs
; i
++)
1380 src
[i
] = vtn_ssa_value(b
, w
[i
+ 3])->def
;
1382 /* Indicates that the first two arguments should be swapped. This is
1383 * used for implementing greater-than and less-than-or-equal.
1389 /* Basic ALU operations */
1390 case SpvOpSNegate
: op
= nir_op_ineg
; break;
1391 case SpvOpFNegate
: op
= nir_op_fneg
; break;
1392 case SpvOpNot
: op
= nir_op_inot
; break;
1395 switch (src
[0]->num_components
) {
1396 case 1: op
= nir_op_imov
; break;
1397 case 2: op
= nir_op_bany2
; break;
1398 case 3: op
= nir_op_bany3
; break;
1399 case 4: op
= nir_op_bany4
; break;
1404 switch (src
[0]->num_components
) {
1405 case 1: op
= nir_op_imov
; break;
1406 case 2: op
= nir_op_ball2
; break;
1407 case 3: op
= nir_op_ball3
; break;
1408 case 4: op
= nir_op_ball4
; break;
1412 case SpvOpIAdd
: op
= nir_op_iadd
; break;
1413 case SpvOpFAdd
: op
= nir_op_fadd
; break;
1414 case SpvOpISub
: op
= nir_op_isub
; break;
1415 case SpvOpFSub
: op
= nir_op_fsub
; break;
1416 case SpvOpIMul
: op
= nir_op_imul
; break;
1417 case SpvOpFMul
: op
= nir_op_fmul
; break;
1418 case SpvOpUDiv
: op
= nir_op_udiv
; break;
1419 case SpvOpSDiv
: op
= nir_op_idiv
; break;
1420 case SpvOpFDiv
: op
= nir_op_fdiv
; break;
1421 case SpvOpUMod
: op
= nir_op_umod
; break;
1422 case SpvOpSMod
: op
= nir_op_umod
; break; /* FIXME? */
1423 case SpvOpFMod
: op
= nir_op_fmod
; break;
1426 assert(src
[0]->num_components
== src
[1]->num_components
);
1427 switch (src
[0]->num_components
) {
1428 case 1: op
= nir_op_fmul
; break;
1429 case 2: op
= nir_op_fdot2
; break;
1430 case 3: op
= nir_op_fdot3
; break;
1431 case 4: op
= nir_op_fdot4
; break;
1435 case SpvOpShiftRightLogical
: op
= nir_op_ushr
; break;
1436 case SpvOpShiftRightArithmetic
: op
= nir_op_ishr
; break;
1437 case SpvOpShiftLeftLogical
: op
= nir_op_ishl
; break;
1438 case SpvOpLogicalOr
: op
= nir_op_ior
; break;
1439 case SpvOpLogicalXor
: op
= nir_op_ixor
; break;
1440 case SpvOpLogicalAnd
: op
= nir_op_iand
; break;
1441 case SpvOpBitwiseOr
: op
= nir_op_ior
; break;
1442 case SpvOpBitwiseXor
: op
= nir_op_ixor
; break;
1443 case SpvOpBitwiseAnd
: op
= nir_op_iand
; break;
1444 case SpvOpSelect
: op
= nir_op_bcsel
; break;
1445 case SpvOpIEqual
: op
= nir_op_ieq
; break;
1447 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
1448 case SpvOpFOrdEqual
: op
= nir_op_feq
; break;
1449 case SpvOpFUnordEqual
: op
= nir_op_feq
; break;
1450 case SpvOpINotEqual
: op
= nir_op_ine
; break;
1451 case SpvOpFOrdNotEqual
: op
= nir_op_fne
; break;
1452 case SpvOpFUnordNotEqual
: op
= nir_op_fne
; break;
1453 case SpvOpULessThan
: op
= nir_op_ult
; break;
1454 case SpvOpSLessThan
: op
= nir_op_ilt
; break;
1455 case SpvOpFOrdLessThan
: op
= nir_op_flt
; break;
1456 case SpvOpFUnordLessThan
: op
= nir_op_flt
; break;
1457 case SpvOpUGreaterThan
: op
= nir_op_ult
; swap
= true; break;
1458 case SpvOpSGreaterThan
: op
= nir_op_ilt
; swap
= true; break;
1459 case SpvOpFOrdGreaterThan
: op
= nir_op_flt
; swap
= true; break;
1460 case SpvOpFUnordGreaterThan
: op
= nir_op_flt
; swap
= true; break;
1461 case SpvOpULessThanEqual
: op
= nir_op_uge
; swap
= true; break;
1462 case SpvOpSLessThanEqual
: op
= nir_op_ige
; swap
= true; break;
1463 case SpvOpFOrdLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
1464 case SpvOpFUnordLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
1465 case SpvOpUGreaterThanEqual
: op
= nir_op_uge
; break;
1466 case SpvOpSGreaterThanEqual
: op
= nir_op_ige
; break;
1467 case SpvOpFOrdGreaterThanEqual
: op
= nir_op_fge
; break;
1468 case SpvOpFUnordGreaterThanEqual
:op
= nir_op_fge
; break;
1471 case SpvOpConvertFToU
: op
= nir_op_f2u
; break;
1472 case SpvOpConvertFToS
: op
= nir_op_f2i
; break;
1473 case SpvOpConvertSToF
: op
= nir_op_i2f
; break;
1474 case SpvOpConvertUToF
: op
= nir_op_u2f
; break;
1475 case SpvOpBitcast
: op
= nir_op_imov
; break;
1478 op
= nir_op_imov
; /* TODO: NIR is 32-bit only; these are no-ops. */
1485 case SpvOpDPdx
: op
= nir_op_fddx
; break;
1486 case SpvOpDPdy
: op
= nir_op_fddy
; break;
1487 case SpvOpDPdxFine
: op
= nir_op_fddx_fine
; break;
1488 case SpvOpDPdyFine
: op
= nir_op_fddy_fine
; break;
1489 case SpvOpDPdxCoarse
: op
= nir_op_fddx_coarse
; break;
1490 case SpvOpDPdyCoarse
: op
= nir_op_fddy_coarse
; break;
1492 val
->ssa
->def
= nir_fadd(&b
->nb
,
1493 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[0])),
1494 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[1])));
1496 case SpvOpFwidthFine
:
1497 val
->ssa
->def
= nir_fadd(&b
->nb
,
1498 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[0])),
1499 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[1])));
1501 case SpvOpFwidthCoarse
:
1502 val
->ssa
->def
= nir_fadd(&b
->nb
,
1503 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[0])),
1504 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[1])));
1507 case SpvOpVectorTimesScalar
:
1508 /* The builder will take care of splatting for us. */
1509 val
->ssa
->def
= nir_fmul(&b
->nb
, src
[0], src
[1]);
1514 unreachable("No NIR equivalent");
1520 case SpvOpSignBitSet
:
1521 case SpvOpLessOrGreater
:
1523 case SpvOpUnordered
:
1525 unreachable("Unhandled opcode");
1529 nir_ssa_def
*tmp
= src
[0];
1534 nir_alu_instr
*instr
= nir_alu_instr_create(b
->shader
, op
);
1535 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
.dest
,
1536 glsl_get_vector_elements(val
->type
), val
->name
);
1537 val
->ssa
->def
= &instr
->dest
.dest
.ssa
;
1539 for (unsigned i
= 0; i
< nir_op_infos
[op
].num_inputs
; i
++)
1540 instr
->src
[i
].src
= nir_src_for_ssa(src
[i
]);
1542 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
1545 static nir_ssa_def
*
1546 vtn_vector_extract(struct vtn_builder
*b
, nir_ssa_def
*src
, unsigned index
)
1548 unsigned swiz
[4] = { index
};
1549 return nir_swizzle(&b
->nb
, src
, swiz
, 1, true);
1553 static nir_ssa_def
*
1554 vtn_vector_insert(struct vtn_builder
*b
, nir_ssa_def
*src
, nir_ssa_def
*insert
,
1557 nir_alu_instr
*vec
= create_vec(b
->shader
, src
->num_components
);
1559 for (unsigned i
= 0; i
< src
->num_components
; i
++) {
1561 vec
->src
[i
].src
= nir_src_for_ssa(insert
);
1563 vec
->src
[i
].src
= nir_src_for_ssa(src
);
1564 vec
->src
[i
].swizzle
[0] = i
;
1568 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
1570 return &vec
->dest
.dest
.ssa
;
1573 static nir_ssa_def
*
1574 vtn_vector_extract_dynamic(struct vtn_builder
*b
, nir_ssa_def
*src
,
1577 nir_ssa_def
*dest
= vtn_vector_extract(b
, src
, 0);
1578 for (unsigned i
= 1; i
< src
->num_components
; i
++)
1579 dest
= nir_bcsel(&b
->nb
, nir_ieq(&b
->nb
, index
, nir_imm_int(&b
->nb
, i
)),
1580 vtn_vector_extract(b
, src
, i
), dest
);
1585 static nir_ssa_def
*
1586 vtn_vector_insert_dynamic(struct vtn_builder
*b
, nir_ssa_def
*src
,
1587 nir_ssa_def
*insert
, nir_ssa_def
*index
)
1589 nir_ssa_def
*dest
= vtn_vector_insert(b
, src
, insert
, 0);
1590 for (unsigned i
= 1; i
< src
->num_components
; i
++)
1591 dest
= nir_bcsel(&b
->nb
, nir_ieq(&b
->nb
, index
, nir_imm_int(&b
->nb
, i
)),
1592 vtn_vector_insert(b
, src
, insert
, i
), dest
);
1597 static nir_ssa_def
*
1598 vtn_vector_shuffle(struct vtn_builder
*b
, unsigned num_components
,
1599 nir_ssa_def
*src0
, nir_ssa_def
*src1
,
1600 const uint32_t *indices
)
1602 nir_alu_instr
*vec
= create_vec(b
->shader
, num_components
);
1604 nir_ssa_undef_instr
*undef
= nir_ssa_undef_instr_create(b
->shader
, 1);
1605 nir_builder_instr_insert(&b
->nb
, &undef
->instr
);
1607 for (unsigned i
= 0; i
< num_components
; i
++) {
1608 uint32_t index
= indices
[i
];
1609 if (index
== 0xffffffff) {
1610 vec
->src
[i
].src
= nir_src_for_ssa(&undef
->def
);
1611 } else if (index
< src0
->num_components
) {
1612 vec
->src
[i
].src
= nir_src_for_ssa(src0
);
1613 vec
->src
[i
].swizzle
[0] = index
;
1615 vec
->src
[i
].src
= nir_src_for_ssa(src1
);
1616 vec
->src
[i
].swizzle
[0] = index
- src0
->num_components
;
1620 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
1622 return &vec
->dest
.dest
.ssa
;
1626 * Concatentates a number of vectors/scalars together to produce a vector
1628 static nir_ssa_def
*
1629 vtn_vector_construct(struct vtn_builder
*b
, unsigned num_components
,
1630 unsigned num_srcs
, nir_ssa_def
**srcs
)
1632 nir_alu_instr
*vec
= create_vec(b
->shader
, num_components
);
1634 unsigned dest_idx
= 0;
1635 for (unsigned i
= 0; i
< num_srcs
; i
++) {
1636 nir_ssa_def
*src
= srcs
[i
];
1637 for (unsigned j
= 0; j
< src
->num_components
; j
++) {
1638 vec
->src
[dest_idx
].src
= nir_src_for_ssa(src
);
1639 vec
->src
[dest_idx
].swizzle
[0] = j
;
1644 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
1646 return &vec
->dest
.dest
.ssa
;
1649 static struct vtn_ssa_value
*
1650 vtn_composite_copy(void *mem_ctx
, struct vtn_ssa_value
*src
)
1652 struct vtn_ssa_value
*dest
= rzalloc(mem_ctx
, struct vtn_ssa_value
);
1653 dest
->type
= src
->type
;
1655 if (glsl_type_is_vector_or_scalar(src
->type
)) {
1656 dest
->def
= src
->def
;
1658 unsigned elems
= glsl_get_length(src
->type
);
1660 dest
->elems
= ralloc_array(mem_ctx
, struct vtn_ssa_value
*, elems
);
1661 for (unsigned i
= 0; i
< elems
; i
++)
1662 dest
->elems
[i
] = vtn_composite_copy(mem_ctx
, src
->elems
[i
]);
1668 static struct vtn_ssa_value
*
1669 vtn_composite_insert(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
1670 struct vtn_ssa_value
*insert
, const uint32_t *indices
,
1671 unsigned num_indices
)
1673 struct vtn_ssa_value
*dest
= vtn_composite_copy(b
, src
);
1675 struct vtn_ssa_value
*cur
= dest
;
1677 for (i
= 0; i
< num_indices
- 1; i
++) {
1678 cur
= cur
->elems
[indices
[i
]];
1681 if (glsl_type_is_vector_or_scalar(cur
->type
)) {
1682 /* According to the SPIR-V spec, OpCompositeInsert may work down to
1683 * the component granularity. In that case, the last index will be
1684 * the index to insert the scalar into the vector.
1687 cur
->def
= vtn_vector_insert(b
, cur
->def
, insert
->def
, indices
[i
]);
1689 cur
->elems
[indices
[i
]] = insert
;
1695 static struct vtn_ssa_value
*
1696 vtn_composite_extract(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
1697 const uint32_t *indices
, unsigned num_indices
)
1699 struct vtn_ssa_value
*cur
= src
;
1700 for (unsigned i
= 0; i
< num_indices
; i
++) {
1701 if (glsl_type_is_vector_or_scalar(cur
->type
)) {
1702 assert(i
== num_indices
- 1);
1703 /* According to the SPIR-V spec, OpCompositeExtract may work down to
1704 * the component granularity. The last index will be the index of the
1705 * vector to extract.
1708 struct vtn_ssa_value
*ret
= rzalloc(b
, struct vtn_ssa_value
);
1709 ret
->type
= glsl_scalar_type(glsl_get_base_type(cur
->type
));
1710 ret
->def
= vtn_vector_extract(b
, cur
->def
, indices
[i
]);
1719 vtn_handle_composite(struct vtn_builder
*b
, SpvOp opcode
,
1720 const uint32_t *w
, unsigned count
)
1722 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
1723 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1726 case SpvOpVectorExtractDynamic
:
1727 val
->ssa
->def
= vtn_vector_extract_dynamic(b
, vtn_ssa_value(b
, w
[3])->def
,
1728 vtn_ssa_value(b
, w
[4])->def
);
1731 case SpvOpVectorInsertDynamic
:
1732 val
->ssa
->def
= vtn_vector_insert_dynamic(b
, vtn_ssa_value(b
, w
[3])->def
,
1733 vtn_ssa_value(b
, w
[4])->def
,
1734 vtn_ssa_value(b
, w
[5])->def
);
1737 case SpvOpVectorShuffle
:
1738 val
->ssa
->def
= vtn_vector_shuffle(b
, glsl_get_vector_elements(val
->type
),
1739 vtn_ssa_value(b
, w
[3])->def
,
1740 vtn_ssa_value(b
, w
[4])->def
,
1744 case SpvOpCompositeConstruct
: {
1745 val
->ssa
= rzalloc(b
, struct vtn_ssa_value
);
1746 unsigned elems
= count
- 3;
1747 if (glsl_type_is_vector_or_scalar(val
->type
)) {
1748 nir_ssa_def
*srcs
[4];
1749 for (unsigned i
= 0; i
< elems
; i
++)
1750 srcs
[i
] = vtn_ssa_value(b
, w
[3 + i
])->def
;
1752 vtn_vector_construct(b
, glsl_get_vector_elements(val
->type
),
1755 val
->ssa
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1756 for (unsigned i
= 0; i
< elems
; i
++)
1757 val
->ssa
->elems
[i
] = vtn_ssa_value(b
, w
[3 + i
]);
1761 case SpvOpCompositeExtract
:
1762 val
->ssa
= vtn_composite_extract(b
, vtn_ssa_value(b
, w
[3]),
1766 case SpvOpCompositeInsert
:
1767 val
->ssa
= vtn_composite_insert(b
, vtn_ssa_value(b
, w
[4]),
1768 vtn_ssa_value(b
, w
[3]),
1772 case SpvOpCopyObject
:
1773 val
->ssa
= vtn_composite_copy(b
, vtn_ssa_value(b
, w
[3]));
1777 unreachable("unknown composite operation");
1780 val
->ssa
->type
= val
->type
;
1784 vtn_phi_node_init(struct vtn_builder
*b
, struct vtn_ssa_value
*val
)
1786 if (glsl_type_is_vector_or_scalar(val
->type
)) {
1787 nir_phi_instr
*phi
= nir_phi_instr_create(b
->shader
);
1788 nir_ssa_dest_init(&phi
->instr
, &phi
->dest
,
1789 glsl_get_vector_elements(val
->type
), NULL
);
1790 exec_list_make_empty(&phi
->srcs
);
1791 nir_builder_instr_insert(&b
->nb
, &phi
->instr
);
1792 val
->def
= &phi
->dest
.ssa
;
1794 unsigned elems
= glsl_get_length(val
->type
);
1795 for (unsigned i
= 0; i
< elems
; i
++)
1796 vtn_phi_node_init(b
, val
->elems
[i
]);
1800 static struct vtn_ssa_value
*
1801 vtn_phi_node_create(struct vtn_builder
*b
, const struct glsl_type
*type
)
1803 struct vtn_ssa_value
*val
= vtn_create_ssa_value(b
, type
);
1804 vtn_phi_node_init(b
, val
);
1809 vtn_handle_phi_first_pass(struct vtn_builder
*b
, const uint32_t *w
)
1811 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
1812 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1813 val
->ssa
= vtn_phi_node_create(b
, val
->type
);
1817 vtn_phi_node_add_src(struct vtn_ssa_value
*phi
, const nir_block
*pred
,
1818 struct vtn_ssa_value
*val
)
1820 assert(phi
->type
== val
->type
);
1821 if (glsl_type_is_vector_or_scalar(phi
->type
)) {
1822 nir_phi_instr
*phi_instr
= nir_instr_as_phi(phi
->def
->parent_instr
);
1823 nir_phi_src
*src
= ralloc(phi_instr
, nir_phi_src
);
1824 src
->pred
= (nir_block
*) pred
;
1825 src
->src
= nir_src_for_ssa(val
->def
);
1826 exec_list_push_tail(&phi_instr
->srcs
, &src
->node
);
1828 unsigned elems
= glsl_get_length(phi
->type
);
1829 for (unsigned i
= 0; i
< elems
; i
++)
1830 vtn_phi_node_add_src(phi
->elems
[i
], pred
, val
->elems
[i
]);
1834 static struct vtn_ssa_value
*
1835 vtn_get_phi_node_src(struct vtn_builder
*b
, nir_block
*block
,
1836 const struct glsl_type
*type
, const uint32_t *w
,
1839 struct hash_entry
*entry
= _mesa_hash_table_search(b
->block_table
, block
);
1841 struct vtn_block
*spv_block
= entry
->data
;
1842 for (unsigned off
= 4; off
< count
; off
+= 2) {
1843 if (spv_block
== vtn_value(b
, w
[off
], vtn_value_type_block
)->block
) {
1844 return vtn_ssa_value(b
, w
[off
- 1]);
1849 nir_builder_insert_before_block(&b
->nb
, block
);
1850 struct vtn_ssa_value
*phi
= vtn_phi_node_create(b
, type
);
1852 struct set_entry
*entry2
;
1853 set_foreach(block
->predecessors
, entry2
) {
1854 nir_block
*pred
= (nir_block
*) entry2
->key
;
1855 struct vtn_ssa_value
*val
= vtn_get_phi_node_src(b
, pred
, type
, w
,
1857 vtn_phi_node_add_src(phi
, pred
, val
);
1864 vtn_handle_phi_second_pass(struct vtn_builder
*b
, SpvOp opcode
,
1865 const uint32_t *w
, unsigned count
)
1867 if (opcode
== SpvOpLabel
) {
1868 b
->block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
1872 if (opcode
!= SpvOpPhi
)
1875 struct vtn_ssa_value
*phi
= vtn_value(b
, w
[2], vtn_value_type_ssa
)->ssa
;
1877 struct set_entry
*entry
;
1878 set_foreach(b
->block
->block
->predecessors
, entry
) {
1879 nir_block
*pred
= (nir_block
*) entry
->key
;
1881 struct vtn_ssa_value
*val
= vtn_get_phi_node_src(b
, pred
, phi
->type
, w
,
1883 vtn_phi_node_add_src(phi
, pred
, val
);
1890 vtn_handle_preamble_instruction(struct vtn_builder
*b
, SpvOp opcode
,
1891 const uint32_t *w
, unsigned count
)
1895 case SpvOpSourceExtension
:
1896 case SpvOpCompileFlag
:
1897 case SpvOpExtension
:
1898 /* Unhandled, but these are for debug so that's ok. */
1901 case SpvOpExtInstImport
:
1902 vtn_handle_extension(b
, opcode
, w
, count
);
1905 case SpvOpMemoryModel
:
1906 assert(w
[1] == SpvAddressingModelLogical
);
1907 assert(w
[2] == SpvMemoryModelGLSL450
);
1910 case SpvOpEntryPoint
:
1911 assert(b
->entry_point
== NULL
);
1912 b
->entry_point
= &b
->values
[w
[2]];
1913 b
->execution_model
= w
[1];
1916 case SpvOpExecutionMode
:
1917 unreachable("Execution modes not yet implemented");
1921 vtn_push_value(b
, w
[1], vtn_value_type_string
)->str
=
1922 vtn_string_literal(b
, &w
[2], count
- 2);
1926 b
->values
[w
[1]].name
= vtn_string_literal(b
, &w
[2], count
- 2);
1929 case SpvOpMemberName
:
1934 break; /* Ignored for now */
1936 case SpvOpDecorationGroup
:
1938 case SpvOpMemberDecorate
:
1939 case SpvOpGroupDecorate
:
1940 case SpvOpGroupMemberDecorate
:
1941 vtn_handle_decoration(b
, opcode
, w
, count
);
1947 case SpvOpTypeFloat
:
1948 case SpvOpTypeVector
:
1949 case SpvOpTypeMatrix
:
1950 case SpvOpTypeSampler
:
1951 case SpvOpTypeArray
:
1952 case SpvOpTypeRuntimeArray
:
1953 case SpvOpTypeStruct
:
1954 case SpvOpTypeOpaque
:
1955 case SpvOpTypePointer
:
1956 case SpvOpTypeFunction
:
1957 case SpvOpTypeEvent
:
1958 case SpvOpTypeDeviceEvent
:
1959 case SpvOpTypeReserveId
:
1960 case SpvOpTypeQueue
:
1962 vtn_push_value(b
, w
[1], vtn_value_type_type
)->type
=
1963 vtn_handle_type(b
, opcode
, &w
[2], count
- 2);
1966 case SpvOpConstantTrue
:
1967 case SpvOpConstantFalse
:
1969 case SpvOpConstantComposite
:
1970 case SpvOpConstantSampler
:
1971 case SpvOpConstantNullPointer
:
1972 case SpvOpConstantNullObject
:
1973 case SpvOpSpecConstantTrue
:
1974 case SpvOpSpecConstantFalse
:
1975 case SpvOpSpecConstant
:
1976 case SpvOpSpecConstantComposite
:
1977 vtn_handle_constant(b
, opcode
, w
, count
);
1981 vtn_handle_variables(b
, opcode
, w
, count
);
1985 return false; /* End of preamble */
1992 vtn_handle_first_cfg_pass_instruction(struct vtn_builder
*b
, SpvOp opcode
,
1993 const uint32_t *w
, unsigned count
)
1996 case SpvOpFunction
: {
1997 assert(b
->func
== NULL
);
1998 b
->func
= rzalloc(b
, struct vtn_function
);
2000 const struct glsl_type
*result_type
=
2001 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
2002 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_function
);
2003 const struct glsl_type
*func_type
=
2004 vtn_value(b
, w
[4], vtn_value_type_type
)->type
;
2006 assert(glsl_get_function_return_type(func_type
) == result_type
);
2008 nir_function
*func
=
2009 nir_function_create(b
->shader
, ralloc_strdup(b
->shader
, val
->name
));
2011 nir_function_overload
*overload
= nir_function_overload_create(func
);
2012 overload
->num_params
= glsl_get_length(func_type
);
2013 overload
->params
= ralloc_array(overload
, nir_parameter
,
2014 overload
->num_params
);
2015 for (unsigned i
= 0; i
< overload
->num_params
; i
++) {
2016 const struct glsl_function_param
*param
=
2017 glsl_get_function_param(func_type
, i
);
2018 overload
->params
[i
].type
= param
->type
;
2021 overload
->params
[i
].param_type
= nir_parameter_inout
;
2023 overload
->params
[i
].param_type
= nir_parameter_in
;
2027 overload
->params
[i
].param_type
= nir_parameter_out
;
2029 assert(!"Parameter is neither in nor out");
2033 b
->func
->overload
= overload
;
2037 case SpvOpFunctionEnd
:
2042 case SpvOpFunctionParameter
:
2043 break; /* Does nothing */
2046 assert(b
->block
== NULL
);
2047 b
->block
= rzalloc(b
, struct vtn_block
);
2048 b
->block
->label
= w
;
2049 vtn_push_value(b
, w
[1], vtn_value_type_block
)->block
= b
->block
;
2051 if (b
->func
->start_block
== NULL
) {
2052 /* This is the first block encountered for this function. In this
2053 * case, we set the start block and add it to the list of
2054 * implemented functions that we'll walk later.
2056 b
->func
->start_block
= b
->block
;
2057 exec_list_push_tail(&b
->functions
, &b
->func
->node
);
2063 case SpvOpBranchConditional
:
2067 case SpvOpReturnValue
:
2068 case SpvOpUnreachable
:
2070 b
->block
->branch
= w
;
2074 case SpvOpSelectionMerge
:
2075 case SpvOpLoopMerge
:
2076 assert(b
->block
&& b
->block
->merge_op
== SpvOpNop
);
2077 b
->block
->merge_op
= opcode
;
2078 b
->block
->merge_block_id
= w
[1];
2082 /* Continue on as per normal */
2090 vtn_handle_body_instruction(struct vtn_builder
*b
, SpvOp opcode
,
2091 const uint32_t *w
, unsigned count
)
2095 struct vtn_block
*block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
2096 assert(block
->block
== NULL
);
2098 struct exec_node
*list_tail
= exec_list_get_tail(b
->nb
.cf_node_list
);
2099 nir_cf_node
*tail_node
= exec_node_data(nir_cf_node
, list_tail
, node
);
2100 assert(tail_node
->type
== nir_cf_node_block
);
2101 block
->block
= nir_cf_node_as_block(tail_node
);
2105 case SpvOpLoopMerge
:
2106 case SpvOpSelectionMerge
:
2107 /* This is handled by cfg pre-pass and walk_blocks */
2111 vtn_push_value(b
, w
[2], vtn_value_type_undef
);
2115 vtn_handle_extension(b
, opcode
, w
, count
);
2119 case SpvOpVariableArray
:
2122 case SpvOpCopyMemory
:
2123 case SpvOpCopyMemorySized
:
2124 case SpvOpAccessChain
:
2125 case SpvOpInBoundsAccessChain
:
2126 case SpvOpArrayLength
:
2127 case SpvOpImagePointer
:
2128 vtn_handle_variables(b
, opcode
, w
, count
);
2131 case SpvOpFunctionCall
:
2132 vtn_handle_function_call(b
, opcode
, w
, count
);
2135 case SpvOpTextureSample
:
2136 case SpvOpTextureSampleDref
:
2137 case SpvOpTextureSampleLod
:
2138 case SpvOpTextureSampleProj
:
2139 case SpvOpTextureSampleGrad
:
2140 case SpvOpTextureSampleOffset
:
2141 case SpvOpTextureSampleProjLod
:
2142 case SpvOpTextureSampleProjGrad
:
2143 case SpvOpTextureSampleLodOffset
:
2144 case SpvOpTextureSampleProjOffset
:
2145 case SpvOpTextureSampleGradOffset
:
2146 case SpvOpTextureSampleProjLodOffset
:
2147 case SpvOpTextureSampleProjGradOffset
:
2148 case SpvOpTextureFetchTexelLod
:
2149 case SpvOpTextureFetchTexelOffset
:
2150 case SpvOpTextureFetchSample
:
2151 case SpvOpTextureFetchTexel
:
2152 case SpvOpTextureGather
:
2153 case SpvOpTextureGatherOffset
:
2154 case SpvOpTextureGatherOffsets
:
2155 case SpvOpTextureQuerySizeLod
:
2156 case SpvOpTextureQuerySize
:
2157 case SpvOpTextureQueryLod
:
2158 case SpvOpTextureQueryLevels
:
2159 case SpvOpTextureQuerySamples
:
2160 vtn_handle_texture(b
, opcode
, w
, count
);
2168 case SpvOpConvertFToU
:
2169 case SpvOpConvertFToS
:
2170 case SpvOpConvertSToF
:
2171 case SpvOpConvertUToF
:
2175 case SpvOpConvertPtrToU
:
2176 case SpvOpConvertUToPtr
:
2177 case SpvOpPtrCastToGeneric
:
2178 case SpvOpGenericCastToPtr
:
2184 case SpvOpSignBitSet
:
2185 case SpvOpLessOrGreater
:
2187 case SpvOpUnordered
:
2202 case SpvOpVectorTimesScalar
:
2204 case SpvOpShiftRightLogical
:
2205 case SpvOpShiftRightArithmetic
:
2206 case SpvOpShiftLeftLogical
:
2207 case SpvOpLogicalOr
:
2208 case SpvOpLogicalXor
:
2209 case SpvOpLogicalAnd
:
2210 case SpvOpBitwiseOr
:
2211 case SpvOpBitwiseXor
:
2212 case SpvOpBitwiseAnd
:
2215 case SpvOpFOrdEqual
:
2216 case SpvOpFUnordEqual
:
2217 case SpvOpINotEqual
:
2218 case SpvOpFOrdNotEqual
:
2219 case SpvOpFUnordNotEqual
:
2220 case SpvOpULessThan
:
2221 case SpvOpSLessThan
:
2222 case SpvOpFOrdLessThan
:
2223 case SpvOpFUnordLessThan
:
2224 case SpvOpUGreaterThan
:
2225 case SpvOpSGreaterThan
:
2226 case SpvOpFOrdGreaterThan
:
2227 case SpvOpFUnordGreaterThan
:
2228 case SpvOpULessThanEqual
:
2229 case SpvOpSLessThanEqual
:
2230 case SpvOpFOrdLessThanEqual
:
2231 case SpvOpFUnordLessThanEqual
:
2232 case SpvOpUGreaterThanEqual
:
2233 case SpvOpSGreaterThanEqual
:
2234 case SpvOpFOrdGreaterThanEqual
:
2235 case SpvOpFUnordGreaterThanEqual
:
2241 case SpvOpFwidthFine
:
2242 case SpvOpDPdxCoarse
:
2243 case SpvOpDPdyCoarse
:
2244 case SpvOpFwidthCoarse
:
2245 vtn_handle_alu(b
, opcode
, w
, count
);
2248 case SpvOpTranspose
:
2249 case SpvOpOuterProduct
:
2250 case SpvOpMatrixTimesScalar
:
2251 case SpvOpVectorTimesMatrix
:
2252 case SpvOpMatrixTimesVector
:
2253 case SpvOpMatrixTimesMatrix
:
2254 vtn_handle_matrix_alu(b
, opcode
, w
, count
);
2257 case SpvOpVectorExtractDynamic
:
2258 case SpvOpVectorInsertDynamic
:
2259 case SpvOpVectorShuffle
:
2260 case SpvOpCompositeConstruct
:
2261 case SpvOpCompositeExtract
:
2262 case SpvOpCompositeInsert
:
2263 case SpvOpCopyObject
:
2264 vtn_handle_composite(b
, opcode
, w
, count
);
2268 vtn_handle_phi_first_pass(b
, w
);
2272 unreachable("Unhandled opcode");
2279 vtn_walk_blocks(struct vtn_builder
*b
, struct vtn_block
*start
,
2280 struct vtn_block
*break_block
, struct vtn_block
*cont_block
,
2281 struct vtn_block
*end_block
)
2283 struct vtn_block
*block
= start
;
2284 while (block
!= end_block
) {
2285 if (block
->merge_op
== SpvOpLoopMerge
) {
2286 /* This is the jump into a loop. */
2287 struct vtn_block
*new_cont_block
= block
;
2288 struct vtn_block
*new_break_block
=
2289 vtn_value(b
, block
->merge_block_id
, vtn_value_type_block
)->block
;
2291 nir_loop
*loop
= nir_loop_create(b
->shader
);
2292 nir_cf_node_insert_end(b
->nb
.cf_node_list
, &loop
->cf_node
);
2294 struct exec_list
*old_list
= b
->nb
.cf_node_list
;
2296 /* Reset the merge_op to prerevent infinite recursion */
2297 block
->merge_op
= SpvOpNop
;
2299 nir_builder_insert_after_cf_list(&b
->nb
, &loop
->body
);
2300 vtn_walk_blocks(b
, block
, new_break_block
, new_cont_block
, NULL
);
2302 nir_builder_insert_after_cf_list(&b
->nb
, old_list
);
2303 block
= new_break_block
;
2307 const uint32_t *w
= block
->branch
;
2308 SpvOp branch_op
= w
[0] & SpvOpCodeMask
;
2311 vtn_foreach_instruction(b
, block
->label
, block
->branch
,
2312 vtn_handle_body_instruction
);
2314 nir_cf_node
*cur_cf_node
=
2315 exec_node_data(nir_cf_node
, exec_list_get_tail(b
->nb
.cf_node_list
),
2317 nir_block
*cur_block
= nir_cf_node_as_block(cur_cf_node
);
2318 _mesa_hash_table_insert(b
->block_table
, cur_block
, block
);
2320 switch (branch_op
) {
2322 struct vtn_block
*branch_block
=
2323 vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
2325 if (branch_block
== break_block
) {
2326 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2328 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
2331 } else if (branch_block
== cont_block
) {
2332 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2334 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
2337 } else if (branch_block
== end_block
) {
2338 /* We're branching to the merge block of an if, since for loops
2339 * and functions end_block == NULL, so we're done here.
2343 /* We're branching to another block, and according to the rules,
2344 * we can only branch to another block with one predecessor (so
2345 * we're the only one jumping to it) so we can just process it
2348 block
= branch_block
;
2353 case SpvOpBranchConditional
: {
2354 /* Gather up the branch blocks */
2355 struct vtn_block
*then_block
=
2356 vtn_value(b
, w
[2], vtn_value_type_block
)->block
;
2357 struct vtn_block
*else_block
=
2358 vtn_value(b
, w
[3], vtn_value_type_block
)->block
;
2360 nir_if
*if_stmt
= nir_if_create(b
->shader
);
2361 if_stmt
->condition
= nir_src_for_ssa(vtn_ssa_value(b
, w
[1])->def
);
2362 nir_cf_node_insert_end(b
->nb
.cf_node_list
, &if_stmt
->cf_node
);
2364 if (then_block
== break_block
) {
2365 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2367 nir_instr_insert_after_cf_list(&if_stmt
->then_list
,
2370 } else if (else_block
== break_block
) {
2371 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2373 nir_instr_insert_after_cf_list(&if_stmt
->else_list
,
2376 } else if (then_block
== cont_block
) {
2377 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2379 nir_instr_insert_after_cf_list(&if_stmt
->then_list
,
2382 } else if (else_block
== cont_block
) {
2383 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2385 nir_instr_insert_after_cf_list(&if_stmt
->else_list
,
2389 /* According to the rules we're branching to two blocks that don't
2390 * have any other predecessors, so we can handle this as a
2393 assert(block
->merge_op
== SpvOpSelectionMerge
);
2394 struct vtn_block
*merge_block
=
2395 vtn_value(b
, block
->merge_block_id
, vtn_value_type_block
)->block
;
2397 struct exec_list
*old_list
= b
->nb
.cf_node_list
;
2399 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->then_list
);
2400 vtn_walk_blocks(b
, then_block
, break_block
, cont_block
, merge_block
);
2402 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->else_list
);
2403 vtn_walk_blocks(b
, else_block
, break_block
, cont_block
, merge_block
);
2405 nir_builder_insert_after_cf_list(&b
->nb
, old_list
);
2406 block
= merge_block
;
2410 /* If we got here then we inserted a predicated break or continue
2411 * above and we need to handle the other case. We already set
2412 * `block` above to indicate what block to visit after the
2416 /* It's possible that the other branch is also a break/continue.
2417 * If it is, we handle that here.
2419 if (block
== break_block
) {
2420 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2422 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
2425 } else if (block
== cont_block
) {
2426 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2428 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
2433 /* If we got here then there was a predicated break/continue but
2434 * the other half of the if has stuff in it. `block` was already
2435 * set above so there is nothing left for us to do.
2441 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
2443 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
2448 nir_intrinsic_instr
*discard
=
2449 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_discard
);
2450 nir_builder_instr_insert(&b
->nb
, &discard
->instr
);
2455 case SpvOpReturnValue
:
2456 case SpvOpUnreachable
:
2458 unreachable("Unhandled opcode");
2464 spirv_to_nir(const uint32_t *words
, size_t word_count
,
2465 const nir_shader_compiler_options
*options
)
2467 const uint32_t *word_end
= words
+ word_count
;
2469 /* Handle the SPIR-V header (first 4 dwords) */
2470 assert(word_count
> 5);
2472 assert(words
[0] == SpvMagicNumber
);
2473 assert(words
[1] == 99);
2474 /* words[2] == generator magic */
2475 unsigned value_id_bound
= words
[3];
2476 assert(words
[4] == 0);
2480 nir_shader
*shader
= nir_shader_create(NULL
, options
);
2482 /* Initialize the stn_builder object */
2483 struct vtn_builder
*b
= rzalloc(NULL
, struct vtn_builder
);
2485 b
->value_id_bound
= value_id_bound
;
2486 b
->values
= ralloc_array(b
, struct vtn_value
, value_id_bound
);
2487 exec_list_make_empty(&b
->functions
);
2489 /* Handle all the preamble instructions */
2490 words
= vtn_foreach_instruction(b
, words
, word_end
,
2491 vtn_handle_preamble_instruction
);
2493 /* Do a very quick CFG analysis pass */
2494 vtn_foreach_instruction(b
, words
, word_end
,
2495 vtn_handle_first_cfg_pass_instruction
);
2497 foreach_list_typed(struct vtn_function
, func
, node
, &b
->functions
) {
2498 b
->impl
= nir_function_impl_create(func
->overload
);
2499 b
->const_table
= _mesa_hash_table_create(b
, _mesa_hash_pointer
,
2500 _mesa_key_pointer_equal
);
2501 b
->block_table
= _mesa_hash_table_create(b
, _mesa_hash_pointer
,
2502 _mesa_key_pointer_equal
);
2503 nir_builder_init(&b
->nb
, b
->impl
);
2504 nir_builder_insert_after_cf_list(&b
->nb
, &b
->impl
->body
);
2505 vtn_walk_blocks(b
, func
->start_block
, NULL
, NULL
, NULL
);
2506 vtn_foreach_instruction(b
, func
->start_block
->label
, func
->end
,
2507 vtn_handle_phi_second_pass
);