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 "vtn_private.h"
29 #include "nir/nir_vla.h"
30 #include "nir/nir_control_flow.h"
32 static struct vtn_ssa_value
*
33 vtn_undef_ssa_value(struct vtn_builder
*b
, const struct glsl_type
*type
)
35 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
38 if (glsl_type_is_vector_or_scalar(type
)) {
39 unsigned num_components
= glsl_get_vector_elements(val
->type
);
40 nir_ssa_undef_instr
*undef
=
41 nir_ssa_undef_instr_create(b
->shader
, num_components
);
43 nir_instr_insert_before_cf_list(&b
->impl
->body
, &undef
->instr
);
44 val
->def
= &undef
->def
;
46 unsigned elems
= glsl_get_length(val
->type
);
47 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
48 if (glsl_type_is_matrix(type
)) {
49 const struct glsl_type
*elem_type
=
50 glsl_vector_type(glsl_get_base_type(type
),
51 glsl_get_vector_elements(type
));
53 for (unsigned i
= 0; i
< elems
; i
++)
54 val
->elems
[i
] = vtn_undef_ssa_value(b
, elem_type
);
55 } else if (glsl_type_is_array(type
)) {
56 const struct glsl_type
*elem_type
= glsl_get_array_element(type
);
57 for (unsigned i
= 0; i
< elems
; i
++)
58 val
->elems
[i
] = vtn_undef_ssa_value(b
, elem_type
);
60 for (unsigned i
= 0; i
< elems
; i
++) {
61 const struct glsl_type
*elem_type
= glsl_get_struct_field(type
, i
);
62 val
->elems
[i
] = vtn_undef_ssa_value(b
, elem_type
);
70 static struct vtn_ssa_value
*
71 vtn_const_ssa_value(struct vtn_builder
*b
, nir_constant
*constant
,
72 const struct glsl_type
*type
)
74 struct hash_entry
*entry
= _mesa_hash_table_search(b
->const_table
, constant
);
79 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
82 switch (glsl_get_base_type(type
)) {
87 case GLSL_TYPE_DOUBLE
:
88 if (glsl_type_is_vector_or_scalar(type
)) {
89 unsigned num_components
= glsl_get_vector_elements(val
->type
);
90 nir_load_const_instr
*load
=
91 nir_load_const_instr_create(b
->shader
, num_components
);
93 for (unsigned i
= 0; i
< num_components
; i
++)
94 load
->value
.u
[i
] = constant
->value
.u
[i
];
96 nir_instr_insert_before_cf_list(&b
->impl
->body
, &load
->instr
);
97 val
->def
= &load
->def
;
99 assert(glsl_type_is_matrix(type
));
100 unsigned rows
= glsl_get_vector_elements(val
->type
);
101 unsigned columns
= glsl_get_matrix_columns(val
->type
);
102 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, columns
);
104 for (unsigned i
= 0; i
< columns
; i
++) {
105 struct vtn_ssa_value
*col_val
= rzalloc(b
, struct vtn_ssa_value
);
106 col_val
->type
= glsl_get_column_type(val
->type
);
107 nir_load_const_instr
*load
=
108 nir_load_const_instr_create(b
->shader
, rows
);
110 for (unsigned j
= 0; j
< rows
; j
++)
111 load
->value
.u
[j
] = constant
->value
.u
[rows
* i
+ j
];
113 nir_instr_insert_before_cf_list(&b
->impl
->body
, &load
->instr
);
114 col_val
->def
= &load
->def
;
116 val
->elems
[i
] = col_val
;
121 case GLSL_TYPE_ARRAY
: {
122 unsigned elems
= glsl_get_length(val
->type
);
123 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
124 const struct glsl_type
*elem_type
= glsl_get_array_element(val
->type
);
125 for (unsigned i
= 0; i
< elems
; i
++)
126 val
->elems
[i
] = vtn_const_ssa_value(b
, constant
->elements
[i
],
131 case GLSL_TYPE_STRUCT
: {
132 unsigned elems
= glsl_get_length(val
->type
);
133 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
134 for (unsigned i
= 0; i
< elems
; i
++) {
135 const struct glsl_type
*elem_type
=
136 glsl_get_struct_field(val
->type
, i
);
137 val
->elems
[i
] = vtn_const_ssa_value(b
, constant
->elements
[i
],
144 unreachable("bad constant type");
150 static struct vtn_ssa_value
*
151 vtn_variable_load(struct vtn_builder
*b
, nir_deref_var
*src
,
152 struct vtn_type
*src_type
);
154 struct vtn_ssa_value
*
155 vtn_ssa_value(struct vtn_builder
*b
, uint32_t value_id
)
157 struct vtn_value
*val
= vtn_untyped_value(b
, value_id
);
158 switch (val
->value_type
) {
159 case vtn_value_type_undef
:
160 return vtn_undef_ssa_value(b
, val
->type
->type
);
162 case vtn_value_type_constant
:
163 return vtn_const_ssa_value(b
, val
->constant
, val
->const_type
);
165 case vtn_value_type_ssa
:
168 case vtn_value_type_deref
:
169 /* This is needed for function parameters */
170 return vtn_variable_load(b
, val
->deref
, val
->deref_type
);
173 unreachable("Invalid type for an SSA value");
178 vtn_string_literal(struct vtn_builder
*b
, const uint32_t *words
,
181 return ralloc_strndup(b
, (char *)words
, word_count
* sizeof(*words
));
185 vtn_foreach_instruction(struct vtn_builder
*b
, const uint32_t *start
,
186 const uint32_t *end
, vtn_instruction_handler handler
)
188 const uint32_t *w
= start
;
190 SpvOp opcode
= w
[0] & SpvOpCodeMask
;
191 unsigned count
= w
[0] >> SpvWordCountShift
;
192 assert(count
>= 1 && w
+ count
<= end
);
194 if (opcode
== SpvOpNop
) {
199 if (!handler(b
, opcode
, w
, count
))
209 vtn_handle_extension(struct vtn_builder
*b
, SpvOp opcode
,
210 const uint32_t *w
, unsigned count
)
213 case SpvOpExtInstImport
: {
214 struct vtn_value
*val
= vtn_push_value(b
, w
[1], vtn_value_type_extension
);
215 if (strcmp((const char *)&w
[2], "GLSL.std.450") == 0) {
216 val
->ext_handler
= vtn_handle_glsl450_instruction
;
218 assert(!"Unsupported extension");
224 struct vtn_value
*val
= vtn_value(b
, w
[3], vtn_value_type_extension
);
225 bool handled
= val
->ext_handler(b
, w
[4], w
, count
);
232 unreachable("Unhandled opcode");
237 _foreach_decoration_helper(struct vtn_builder
*b
,
238 struct vtn_value
*base_value
,
240 struct vtn_value
*value
,
241 vtn_decoration_foreach_cb cb
, void *data
)
243 for (struct vtn_decoration
*dec
= value
->decoration
; dec
; dec
= dec
->next
) {
245 if (dec
->scope
== VTN_DEC_DECORATION
) {
246 member
= parent_member
;
247 } else if (dec
->scope
>= VTN_DEC_STRUCT_MEMBER0
) {
248 assert(parent_member
== -1);
249 member
= dec
->scope
- VTN_DEC_STRUCT_MEMBER0
;
251 /* Not a decoration */
256 assert(dec
->group
->value_type
== vtn_value_type_decoration_group
);
257 _foreach_decoration_helper(b
, base_value
, member
, dec
->group
,
260 cb(b
, base_value
, member
, dec
, data
);
265 /** Iterates (recursively if needed) over all of the decorations on a value
267 * This function iterates over all of the decorations applied to a given
268 * value. If it encounters a decoration group, it recurses into the group
269 * and iterates over all of those decorations as well.
272 vtn_foreach_decoration(struct vtn_builder
*b
, struct vtn_value
*value
,
273 vtn_decoration_foreach_cb cb
, void *data
)
275 _foreach_decoration_helper(b
, value
, -1, value
, cb
, data
);
279 vtn_foreach_execution_mode(struct vtn_builder
*b
, struct vtn_value
*value
,
280 vtn_execution_mode_foreach_cb cb
, void *data
)
282 for (struct vtn_decoration
*dec
= value
->decoration
; dec
; dec
= dec
->next
) {
283 if (dec
->scope
!= VTN_DEC_EXECUTION_MODE
)
286 assert(dec
->group
== NULL
);
287 cb(b
, value
, dec
, data
);
292 vtn_handle_decoration(struct vtn_builder
*b
, SpvOp opcode
,
293 const uint32_t *w
, unsigned count
)
295 const uint32_t *w_end
= w
+ count
;
296 const uint32_t target
= w
[1];
300 case SpvOpDecorationGroup
:
301 vtn_push_value(b
, target
, vtn_value_type_undef
);
305 case SpvOpMemberDecorate
:
306 case SpvOpExecutionMode
: {
307 struct vtn_value
*val
= &b
->values
[target
];
309 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
312 dec
->scope
= VTN_DEC_DECORATION
;
314 case SpvOpMemberDecorate
:
315 dec
->scope
= VTN_DEC_STRUCT_MEMBER0
+ *(w
++);
317 case SpvOpExecutionMode
:
318 dec
->scope
= VTN_DEC_EXECUTION_MODE
;
321 unreachable("Invalid decoration opcode");
323 dec
->decoration
= *(w
++);
326 /* Link into the list */
327 dec
->next
= val
->decoration
;
328 val
->decoration
= dec
;
332 case SpvOpGroupMemberDecorate
:
333 case SpvOpGroupDecorate
: {
334 struct vtn_value
*group
= &b
->values
[target
];
335 assert(group
->value_type
== vtn_value_type_decoration_group
);
338 if (opcode
== SpvOpGroupDecorate
) {
339 scope
= VTN_DEC_DECORATION
;
341 scope
= VTN_DEC_STRUCT_MEMBER0
+ *(w
++);
344 for (; w
< w_end
; w
++) {
345 struct vtn_value
*val
= &b
->values
[*w
];
346 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
350 /* Link into the list */
351 dec
->next
= val
->decoration
;
352 val
->decoration
= dec
;
358 unreachable("Unhandled opcode");
362 struct member_decoration_ctx
{
363 struct glsl_struct_field
*fields
;
364 struct vtn_type
*type
;
367 /* does a shallow copy of a vtn_type */
369 static struct vtn_type
*
370 vtn_type_copy(struct vtn_builder
*b
, struct vtn_type
*src
)
372 struct vtn_type
*dest
= ralloc(b
, struct vtn_type
);
373 dest
->type
= src
->type
;
374 dest
->is_builtin
= src
->is_builtin
;
376 dest
->builtin
= src
->builtin
;
378 if (!glsl_type_is_vector_or_scalar(src
->type
)) {
379 switch (glsl_get_base_type(src
->type
)) {
380 case GLSL_TYPE_ARRAY
:
381 dest
->array_element
= src
->array_element
;
382 dest
->stride
= src
->stride
;
388 case GLSL_TYPE_FLOAT
:
389 case GLSL_TYPE_DOUBLE
:
391 dest
->row_major
= src
->row_major
;
392 dest
->stride
= src
->stride
;
395 case GLSL_TYPE_STRUCT
: {
396 unsigned elems
= glsl_get_length(src
->type
);
398 dest
->members
= ralloc_array(b
, struct vtn_type
*, elems
);
399 memcpy(dest
->members
, src
->members
, elems
* sizeof(struct vtn_type
*));
401 dest
->offsets
= ralloc_array(b
, unsigned, elems
);
402 memcpy(dest
->offsets
, src
->offsets
, elems
* sizeof(unsigned));
407 unreachable("unhandled type");
415 struct_member_decoration_cb(struct vtn_builder
*b
,
416 struct vtn_value
*val
, int member
,
417 const struct vtn_decoration
*dec
, void *void_ctx
)
419 struct member_decoration_ctx
*ctx
= void_ctx
;
424 switch (dec
->decoration
) {
425 case SpvDecorationRelaxedPrecision
:
426 break; /* FIXME: Do nothing with this for now. */
427 case SpvDecorationNoPerspective
:
428 ctx
->fields
[member
].interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
430 case SpvDecorationFlat
:
431 ctx
->fields
[member
].interpolation
= INTERP_QUALIFIER_FLAT
;
433 case SpvDecorationCentroid
:
434 ctx
->fields
[member
].centroid
= true;
436 case SpvDecorationSample
:
437 ctx
->fields
[member
].sample
= true;
439 case SpvDecorationLocation
:
440 ctx
->fields
[member
].location
= dec
->literals
[0];
442 case SpvDecorationBuiltIn
:
443 ctx
->type
->members
[member
] = vtn_type_copy(b
,
444 ctx
->type
->members
[member
]);
445 ctx
->type
->members
[member
]->is_builtin
= true;
446 ctx
->type
->members
[member
]->builtin
= dec
->literals
[0];
447 ctx
->type
->builtin_block
= true;
449 case SpvDecorationOffset
:
450 ctx
->type
->offsets
[member
] = dec
->literals
[0];
452 case SpvDecorationMatrixStride
:
453 ctx
->type
->members
[member
]->stride
= dec
->literals
[0];
455 case SpvDecorationColMajor
:
456 break; /* Nothing to do here. Column-major is the default. */
458 unreachable("Unhandled member decoration");
463 type_decoration_cb(struct vtn_builder
*b
,
464 struct vtn_value
*val
, int member
,
465 const struct vtn_decoration
*dec
, void *ctx
)
467 struct vtn_type
*type
= val
->type
;
472 switch (dec
->decoration
) {
473 case SpvDecorationArrayStride
:
474 type
->stride
= dec
->literals
[0];
476 case SpvDecorationBlock
:
479 case SpvDecorationBufferBlock
:
480 type
->buffer_block
= true;
482 case SpvDecorationGLSLShared
:
483 case SpvDecorationGLSLPacked
:
484 /* Ignore these, since we get explicit offsets anyways */
487 case SpvDecorationStream
:
488 assert(dec
->literals
[0] == 0);
492 unreachable("Unhandled type decoration");
497 translate_image_format(SpvImageFormat format
)
500 case SpvImageFormatUnknown
: return 0; /* GL_NONE */
501 case SpvImageFormatRgba32f
: return 0x8814; /* GL_RGBA32F */
502 case SpvImageFormatRgba16f
: return 0x881A; /* GL_RGBA16F */
503 case SpvImageFormatR32f
: return 0x822E; /* GL_R32F */
504 case SpvImageFormatRgba8
: return 0x8058; /* GL_RGBA8 */
505 case SpvImageFormatRgba8Snorm
: return 0x8F97; /* GL_RGBA8_SNORM */
506 case SpvImageFormatRg32f
: return 0x8230; /* GL_RG32F */
507 case SpvImageFormatRg16f
: return 0x822F; /* GL_RG16F */
508 case SpvImageFormatR11fG11fB10f
: return 0x8C3A; /* GL_R11F_G11F_B10F */
509 case SpvImageFormatR16f
: return 0x822D; /* GL_R16F */
510 case SpvImageFormatRgba16
: return 0x805B; /* GL_RGBA16 */
511 case SpvImageFormatRgb10A2
: return 0x8059; /* GL_RGB10_A2 */
512 case SpvImageFormatRg16
: return 0x822C; /* GL_RG16 */
513 case SpvImageFormatRg8
: return 0x822B; /* GL_RG8 */
514 case SpvImageFormatR16
: return 0x822A; /* GL_R16 */
515 case SpvImageFormatR8
: return 0x8229; /* GL_R8 */
516 case SpvImageFormatRgba16Snorm
: return 0x8F9B; /* GL_RGBA16_SNORM */
517 case SpvImageFormatRg16Snorm
: return 0x8F99; /* GL_RG16_SNORM */
518 case SpvImageFormatRg8Snorm
: return 0x8F95; /* GL_RG8_SNORM */
519 case SpvImageFormatR16Snorm
: return 0x8F98; /* GL_R16_SNORM */
520 case SpvImageFormatR8Snorm
: return 0x8F94; /* GL_R8_SNORM */
521 case SpvImageFormatRgba32i
: return 0x8D82; /* GL_RGBA32I */
522 case SpvImageFormatRgba16i
: return 0x8D88; /* GL_RGBA16I */
523 case SpvImageFormatRgba8i
: return 0x8D8E; /* GL_RGBA8I */
524 case SpvImageFormatR32i
: return 0x8235; /* GL_R32I */
525 case SpvImageFormatRg32i
: return 0x823B; /* GL_RG32I */
526 case SpvImageFormatRg16i
: return 0x8239; /* GL_RG16I */
527 case SpvImageFormatRg8i
: return 0x8237; /* GL_RG8I */
528 case SpvImageFormatR16i
: return 0x8233; /* GL_R16I */
529 case SpvImageFormatR8i
: return 0x8231; /* GL_R8I */
530 case SpvImageFormatRgba32ui
: return 0x8D70; /* GL_RGBA32UI */
531 case SpvImageFormatRgba16ui
: return 0x8D76; /* GL_RGBA16UI */
532 case SpvImageFormatRgba8ui
: return 0x8D7C; /* GL_RGBA8UI */
533 case SpvImageFormatR32ui
: return 0x8236; /* GL_R32UI */
534 case SpvImageFormatRgb10a2ui
: return 0x906F; /* GL_RGB10_A2UI */
535 case SpvImageFormatRg32ui
: return 0x823C; /* GL_RG32UI */
536 case SpvImageFormatRg16ui
: return 0x823A; /* GL_RG16UI */
537 case SpvImageFormatRg8ui
: return 0x8238; /* GL_RG8UI */
538 case SpvImageFormatR16ui
: return 0x823A; /* GL_RG16UI */
539 case SpvImageFormatR8ui
: return 0x8232; /* GL_R8UI */
541 assert(!"Invalid image format");
547 vtn_handle_type(struct vtn_builder
*b
, SpvOp opcode
,
548 const uint32_t *w
, unsigned count
)
550 struct vtn_value
*val
= vtn_push_value(b
, w
[1], vtn_value_type_type
);
552 val
->type
= rzalloc(b
, struct vtn_type
);
553 val
->type
->is_builtin
= false;
557 val
->type
->type
= glsl_void_type();
560 val
->type
->type
= glsl_bool_type();
563 val
->type
->type
= glsl_int_type();
566 val
->type
->type
= glsl_float_type();
569 case SpvOpTypeVector
: {
570 const struct glsl_type
*base
=
571 vtn_value(b
, w
[2], vtn_value_type_type
)->type
->type
;
572 unsigned elems
= w
[3];
574 assert(glsl_type_is_scalar(base
));
575 val
->type
->type
= glsl_vector_type(glsl_get_base_type(base
), elems
);
579 case SpvOpTypeMatrix
: {
580 struct vtn_type
*base
=
581 vtn_value(b
, w
[2], vtn_value_type_type
)->type
;
582 unsigned columns
= w
[3];
584 assert(glsl_type_is_vector(base
->type
));
585 val
->type
->type
= glsl_matrix_type(glsl_get_base_type(base
->type
),
586 glsl_get_vector_elements(base
->type
),
588 val
->type
->array_element
= base
;
589 val
->type
->row_major
= false;
590 val
->type
->stride
= 0;
594 case SpvOpTypeRuntimeArray
:
595 case SpvOpTypeArray
: {
596 struct vtn_type
*array_element
=
597 vtn_value(b
, w
[2], vtn_value_type_type
)->type
;
600 if (opcode
== SpvOpTypeRuntimeArray
) {
601 /* A length of 0 is used to denote unsized arrays */
605 vtn_value(b
, w
[3], vtn_value_type_constant
)->constant
->value
.u
[0];
608 val
->type
->type
= glsl_array_type(array_element
->type
, length
);
609 val
->type
->array_element
= array_element
;
610 val
->type
->stride
= 0;
614 case SpvOpTypeStruct
: {
615 unsigned num_fields
= count
- 2;
616 val
->type
->members
= ralloc_array(b
, struct vtn_type
*, num_fields
);
617 val
->type
->offsets
= ralloc_array(b
, unsigned, num_fields
);
619 NIR_VLA(struct glsl_struct_field
, fields
, count
);
620 for (unsigned i
= 0; i
< num_fields
; i
++) {
621 val
->type
->members
[i
] =
622 vtn_value(b
, w
[i
+ 2], vtn_value_type_type
)->type
;
623 fields
[i
] = (struct glsl_struct_field
) {
624 .type
= val
->type
->members
[i
]->type
,
625 .name
= ralloc_asprintf(b
, "field%d", i
),
630 struct member_decoration_ctx ctx
= {
635 vtn_foreach_decoration(b
, val
, struct_member_decoration_cb
, &ctx
);
637 const char *name
= val
->name
? val
->name
: "struct";
639 val
->type
->type
= glsl_struct_type(fields
, num_fields
, name
);
643 case SpvOpTypeFunction
: {
644 const struct glsl_type
*return_type
=
645 vtn_value(b
, w
[2], vtn_value_type_type
)->type
->type
;
646 NIR_VLA(struct glsl_function_param
, params
, count
- 3);
647 for (unsigned i
= 0; i
< count
- 3; i
++) {
648 params
[i
].type
= vtn_value(b
, w
[i
+ 3], vtn_value_type_type
)->type
->type
;
652 params
[i
].out
= true;
654 val
->type
->type
= glsl_function_type(return_type
, params
, count
- 3);
658 case SpvOpTypePointer
:
659 /* FIXME: For now, we'll just do the really lame thing and return
660 * the same type. The validator should ensure that the proper number
661 * of dereferences happen
663 val
->type
= vtn_value(b
, w
[3], vtn_value_type_type
)->type
;
666 case SpvOpTypeImage
: {
667 const struct glsl_type
*sampled_type
=
668 vtn_value(b
, w
[2], vtn_value_type_type
)->type
->type
;
670 assert(glsl_type_is_vector_or_scalar(sampled_type
));
672 enum glsl_sampler_dim dim
;
673 switch ((SpvDim
)w
[3]) {
674 case SpvDim1D
: dim
= GLSL_SAMPLER_DIM_1D
; break;
675 case SpvDim2D
: dim
= GLSL_SAMPLER_DIM_2D
; break;
676 case SpvDim3D
: dim
= GLSL_SAMPLER_DIM_3D
; break;
677 case SpvDimCube
: dim
= GLSL_SAMPLER_DIM_CUBE
; break;
678 case SpvDimRect
: dim
= GLSL_SAMPLER_DIM_RECT
; break;
679 case SpvDimBuffer
: dim
= GLSL_SAMPLER_DIM_BUF
; break;
681 unreachable("Invalid SPIR-V Sampler dimension");
684 bool is_shadow
= w
[4];
685 bool is_array
= w
[5];
686 bool multisampled
= w
[6];
687 unsigned sampled
= w
[7];
688 SpvImageFormat format
= w
[8];
690 assert(!multisampled
&& "FIXME: Handl multi-sampled textures");
692 val
->type
->image_format
= translate_image_format(format
);
695 val
->type
->type
= glsl_sampler_type(dim
, is_shadow
, is_array
,
696 glsl_get_base_type(sampled_type
));
697 } else if (sampled
== 2) {
700 val
->type
->type
= glsl_image_type(dim
, is_array
,
701 glsl_get_base_type(sampled_type
));
703 assert(!"We need to know if the image will be sampled");
708 case SpvOpTypeSampledImage
:
709 val
->type
= vtn_value(b
, w
[2], vtn_value_type_type
)->type
;
712 case SpvOpTypeSampler
:
713 /* The actual sampler type here doesn't really matter. It gets
714 * thrown away the moment you combine it with an image. What really
715 * matters is that it's a sampler type as opposed to an integer type
716 * so the backend knows what to do.
718 * TODO: Eventually we should consider adding a "bare sampler" type
721 val
->type
->type
= glsl_sampler_type(GLSL_SAMPLER_DIM_2D
, false, false,
725 case SpvOpTypeOpaque
:
727 case SpvOpTypeDeviceEvent
:
728 case SpvOpTypeReserveId
:
732 unreachable("Unhandled opcode");
735 vtn_foreach_decoration(b
, val
, type_decoration_cb
, NULL
);
739 vtn_handle_constant(struct vtn_builder
*b
, SpvOp opcode
,
740 const uint32_t *w
, unsigned count
)
742 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_constant
);
743 val
->const_type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
744 val
->constant
= ralloc(b
, nir_constant
);
746 case SpvOpConstantTrue
:
747 assert(val
->const_type
== glsl_bool_type());
748 val
->constant
->value
.u
[0] = NIR_TRUE
;
750 case SpvOpConstantFalse
:
751 assert(val
->const_type
== glsl_bool_type());
752 val
->constant
->value
.u
[0] = NIR_FALSE
;
755 assert(glsl_type_is_scalar(val
->const_type
));
756 val
->constant
->value
.u
[0] = w
[3];
758 case SpvOpConstantComposite
: {
759 unsigned elem_count
= count
- 3;
760 nir_constant
**elems
= ralloc_array(b
, nir_constant
*, elem_count
);
761 for (unsigned i
= 0; i
< elem_count
; i
++)
762 elems
[i
] = vtn_value(b
, w
[i
+ 3], vtn_value_type_constant
)->constant
;
764 switch (glsl_get_base_type(val
->const_type
)) {
767 case GLSL_TYPE_FLOAT
:
769 if (glsl_type_is_matrix(val
->const_type
)) {
770 unsigned rows
= glsl_get_vector_elements(val
->const_type
);
771 assert(glsl_get_matrix_columns(val
->const_type
) == elem_count
);
772 for (unsigned i
= 0; i
< elem_count
; i
++)
773 for (unsigned j
= 0; j
< rows
; j
++)
774 val
->constant
->value
.u
[rows
* i
+ j
] = elems
[i
]->value
.u
[j
];
776 assert(glsl_type_is_vector(val
->const_type
));
777 assert(glsl_get_vector_elements(val
->const_type
) == elem_count
);
778 for (unsigned i
= 0; i
< elem_count
; i
++)
779 val
->constant
->value
.u
[i
] = elems
[i
]->value
.u
[0];
784 case GLSL_TYPE_STRUCT
:
785 case GLSL_TYPE_ARRAY
:
786 ralloc_steal(val
->constant
, elems
);
787 val
->constant
->elements
= elems
;
791 unreachable("Unsupported type for constants");
797 unreachable("Unhandled opcode");
802 set_mode_system_value(nir_variable_mode
*mode
)
804 assert(*mode
== nir_var_system_value
|| *mode
== nir_var_shader_in
);
805 *mode
= nir_var_system_value
;
809 validate_per_vertex_mode(struct vtn_builder
*b
, nir_variable_mode mode
)
811 switch (b
->shader
->stage
) {
812 case MESA_SHADER_VERTEX
:
813 assert(mode
== nir_var_shader_out
);
815 case MESA_SHADER_GEOMETRY
:
816 assert(mode
== nir_var_shader_out
|| mode
== nir_var_shader_in
);
819 assert(!"Invalid shader stage");
824 vtn_get_builtin_location(struct vtn_builder
*b
,
825 SpvBuiltIn builtin
, int *location
,
826 nir_variable_mode
*mode
)
829 case SpvBuiltInPosition
:
830 *location
= VARYING_SLOT_POS
;
831 validate_per_vertex_mode(b
, *mode
);
833 case SpvBuiltInPointSize
:
834 *location
= VARYING_SLOT_PSIZ
;
835 validate_per_vertex_mode(b
, *mode
);
837 case SpvBuiltInClipDistance
:
838 *location
= VARYING_SLOT_CLIP_DIST0
; /* XXX CLIP_DIST1? */
839 validate_per_vertex_mode(b
, *mode
);
841 case SpvBuiltInCullDistance
:
842 /* XXX figure this out */
843 unreachable("unhandled builtin");
844 case SpvBuiltInVertexId
:
845 /* Vulkan defines VertexID to be zero-based and reserves the new
846 * builtin keyword VertexIndex to indicate the non-zero-based value.
848 *location
= SYSTEM_VALUE_VERTEX_ID_ZERO_BASE
;
849 set_mode_system_value(mode
);
851 case SpvBuiltInInstanceId
:
852 *location
= SYSTEM_VALUE_INSTANCE_ID
;
853 set_mode_system_value(mode
);
855 case SpvBuiltInPrimitiveId
:
856 *location
= VARYING_SLOT_PRIMITIVE_ID
;
857 *mode
= nir_var_shader_out
;
859 case SpvBuiltInInvocationId
:
860 *location
= SYSTEM_VALUE_INVOCATION_ID
;
861 set_mode_system_value(mode
);
863 case SpvBuiltInLayer
:
864 *location
= VARYING_SLOT_LAYER
;
865 *mode
= nir_var_shader_out
;
867 case SpvBuiltInTessLevelOuter
:
868 case SpvBuiltInTessLevelInner
:
869 case SpvBuiltInTessCoord
:
870 case SpvBuiltInPatchVertices
:
871 unreachable("no tessellation support");
872 case SpvBuiltInFragCoord
:
873 *location
= VARYING_SLOT_POS
;
874 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
875 assert(*mode
== nir_var_shader_in
);
877 case SpvBuiltInPointCoord
:
878 *location
= VARYING_SLOT_PNTC
;
879 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
880 assert(*mode
== nir_var_shader_in
);
882 case SpvBuiltInFrontFacing
:
883 *location
= VARYING_SLOT_FACE
;
884 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
885 assert(*mode
== nir_var_shader_in
);
887 case SpvBuiltInSampleId
:
888 *location
= SYSTEM_VALUE_SAMPLE_ID
;
889 set_mode_system_value(mode
);
891 case SpvBuiltInSamplePosition
:
892 *location
= SYSTEM_VALUE_SAMPLE_POS
;
893 set_mode_system_value(mode
);
895 case SpvBuiltInSampleMask
:
896 *location
= SYSTEM_VALUE_SAMPLE_MASK_IN
; /* XXX out? */
897 set_mode_system_value(mode
);
899 case SpvBuiltInFragDepth
:
900 *location
= FRAG_RESULT_DEPTH
;
901 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
902 assert(*mode
== nir_var_shader_out
);
904 case SpvBuiltInNumWorkgroups
:
905 *location
= SYSTEM_VALUE_NUM_WORK_GROUPS
;
906 set_mode_system_value(mode
);
908 case SpvBuiltInWorkgroupSize
:
909 /* This should already be handled */
910 unreachable("unsupported builtin");
912 case SpvBuiltInWorkgroupId
:
913 *location
= SYSTEM_VALUE_WORK_GROUP_ID
;
914 set_mode_system_value(mode
);
916 case SpvBuiltInLocalInvocationId
:
917 *location
= SYSTEM_VALUE_LOCAL_INVOCATION_ID
;
918 set_mode_system_value(mode
);
920 case SpvBuiltInLocalInvocationIndex
:
921 *location
= SYSTEM_VALUE_LOCAL_INVOCATION_INDEX
;
922 set_mode_system_value(mode
);
924 case SpvBuiltInGlobalInvocationId
:
925 *location
= SYSTEM_VALUE_GLOBAL_INVOCATION_ID
;
926 set_mode_system_value(mode
);
928 case SpvBuiltInHelperInvocation
:
930 unreachable("unsupported builtin");
935 var_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
, int member
,
936 const struct vtn_decoration
*dec
, void *void_var
)
938 assert(val
->value_type
== vtn_value_type_deref
);
939 assert(val
->deref
->deref
.child
== NULL
);
940 assert(val
->deref
->var
== void_var
);
942 nir_variable
*var
= void_var
;
943 switch (dec
->decoration
) {
944 case SpvDecorationRelaxedPrecision
:
945 break; /* FIXME: Do nothing with this for now. */
946 case SpvDecorationNoPerspective
:
947 var
->data
.interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
949 case SpvDecorationFlat
:
950 var
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
952 case SpvDecorationCentroid
:
953 var
->data
.centroid
= true;
955 case SpvDecorationSample
:
956 var
->data
.sample
= true;
958 case SpvDecorationInvariant
:
959 var
->data
.invariant
= true;
961 case SpvDecorationConstant
:
962 assert(var
->constant_initializer
!= NULL
);
963 var
->data
.read_only
= true;
965 case SpvDecorationNonWritable
:
966 var
->data
.read_only
= true;
968 case SpvDecorationLocation
:
969 var
->data
.location
= dec
->literals
[0];
971 case SpvDecorationComponent
:
972 var
->data
.location_frac
= dec
->literals
[0];
974 case SpvDecorationIndex
:
975 var
->data
.explicit_index
= true;
976 var
->data
.index
= dec
->literals
[0];
978 case SpvDecorationBinding
:
979 var
->data
.explicit_binding
= true;
980 var
->data
.binding
= dec
->literals
[0];
982 case SpvDecorationDescriptorSet
:
983 var
->data
.descriptor_set
= dec
->literals
[0];
985 case SpvDecorationBuiltIn
: {
986 SpvBuiltIn builtin
= dec
->literals
[0];
988 if (builtin
== SpvBuiltInWorkgroupSize
) {
989 /* This shouldn't be a builtin. It's actually a constant. */
990 var
->data
.mode
= nir_var_global
;
991 var
->data
.read_only
= true;
993 nir_constant
*val
= ralloc(var
, nir_constant
);
994 val
->value
.u
[0] = b
->shader
->info
.cs
.local_size
[0];
995 val
->value
.u
[1] = b
->shader
->info
.cs
.local_size
[1];
996 val
->value
.u
[2] = b
->shader
->info
.cs
.local_size
[2];
997 var
->constant_initializer
= val
;
1001 nir_variable_mode mode
= var
->data
.mode
;
1002 vtn_get_builtin_location(b
, builtin
, &var
->data
.location
, &mode
);
1003 var
->data
.explicit_location
= true;
1004 var
->data
.mode
= mode
;
1005 if (mode
== nir_var_shader_in
|| mode
== nir_var_system_value
)
1006 var
->data
.read_only
= true;
1008 if (builtin
== SpvBuiltInFragCoord
|| builtin
== SpvBuiltInSamplePosition
)
1009 var
->data
.origin_upper_left
= b
->origin_upper_left
;
1011 if (mode
== nir_var_shader_out
)
1012 b
->builtins
[dec
->literals
[0]].out
= var
;
1014 b
->builtins
[dec
->literals
[0]].in
= var
;
1017 case SpvDecorationRowMajor
:
1018 case SpvDecorationColMajor
:
1019 case SpvDecorationGLSLShared
:
1020 case SpvDecorationPatch
:
1021 case SpvDecorationRestrict
:
1022 case SpvDecorationAliased
:
1023 case SpvDecorationVolatile
:
1024 case SpvDecorationCoherent
:
1025 case SpvDecorationNonReadable
:
1026 case SpvDecorationUniform
:
1027 /* This is really nice but we have no use for it right now. */
1028 case SpvDecorationCPacked
:
1029 case SpvDecorationSaturatedConversion
:
1030 case SpvDecorationStream
:
1031 case SpvDecorationOffset
:
1032 case SpvDecorationXfbBuffer
:
1033 case SpvDecorationFuncParamAttr
:
1034 case SpvDecorationFPRoundingMode
:
1035 case SpvDecorationFPFastMathMode
:
1036 case SpvDecorationLinkageAttributes
:
1037 case SpvDecorationSpecId
:
1040 unreachable("Unhandled variable decoration");
1044 static nir_variable
*
1045 get_builtin_variable(struct vtn_builder
*b
,
1046 nir_variable_mode mode
,
1047 const struct glsl_type
*type
,
1051 if (mode
== nir_var_shader_out
)
1052 var
= b
->builtins
[builtin
].out
;
1054 var
= b
->builtins
[builtin
].in
;
1058 vtn_get_builtin_location(b
, builtin
, &location
, &mode
);
1060 var
= nir_variable_create(b
->shader
, mode
, type
, "builtin");
1062 var
->data
.location
= location
;
1063 var
->data
.explicit_location
= true;
1065 if (builtin
== SpvBuiltInFragCoord
|| builtin
== SpvBuiltInSamplePosition
)
1066 var
->data
.origin_upper_left
= b
->origin_upper_left
;
1068 if (mode
== nir_var_shader_out
)
1069 b
->builtins
[builtin
].out
= var
;
1071 b
->builtins
[builtin
].in
= var
;
1077 static struct vtn_ssa_value
*
1078 _vtn_variable_load(struct vtn_builder
*b
,
1079 nir_deref_var
*src_deref
, nir_deref
*src_deref_tail
)
1081 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
1082 val
->type
= src_deref_tail
->type
;
1084 /* The deref tail may contain a deref to select a component of a vector (in
1085 * other words, it might not be an actual tail) so we have to save it away
1086 * here since we overwrite it later.
1088 nir_deref
*old_child
= src_deref_tail
->child
;
1090 if (glsl_type_is_vector_or_scalar(val
->type
)) {
1091 /* Terminate the deref chain in case there is one more link to pick
1092 * off a component of the vector.
1094 src_deref_tail
->child
= NULL
;
1096 nir_intrinsic_instr
*load
=
1097 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_load_var
);
1098 load
->variables
[0] =
1099 nir_deref_as_var(nir_copy_deref(load
, &src_deref
->deref
));
1100 load
->num_components
= glsl_get_vector_elements(val
->type
);
1101 nir_ssa_dest_init(&load
->instr
, &load
->dest
, load
->num_components
, NULL
);
1103 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
1105 if (src_deref
->var
->data
.mode
== nir_var_uniform
&&
1106 glsl_get_base_type(val
->type
) == GLSL_TYPE_BOOL
) {
1107 /* Uniform boolean loads need to be fixed up since they're defined
1108 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
1110 val
->def
= nir_ine(&b
->nb
, &load
->dest
.ssa
, nir_imm_int(&b
->nb
, 0));
1112 val
->def
= &load
->dest
.ssa
;
1114 } else if (glsl_get_base_type(val
->type
) == GLSL_TYPE_ARRAY
||
1115 glsl_type_is_matrix(val
->type
)) {
1116 unsigned elems
= glsl_get_length(val
->type
);
1117 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1119 nir_deref_array
*deref
= nir_deref_array_create(b
);
1120 deref
->deref_array_type
= nir_deref_array_type_direct
;
1121 deref
->deref
.type
= glsl_get_array_element(val
->type
);
1122 src_deref_tail
->child
= &deref
->deref
;
1123 for (unsigned i
= 0; i
< elems
; i
++) {
1124 deref
->base_offset
= i
;
1125 val
->elems
[i
] = _vtn_variable_load(b
, src_deref
, &deref
->deref
);
1128 assert(glsl_get_base_type(val
->type
) == GLSL_TYPE_STRUCT
);
1129 unsigned elems
= glsl_get_length(val
->type
);
1130 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1132 nir_deref_struct
*deref
= nir_deref_struct_create(b
, 0);
1133 src_deref_tail
->child
= &deref
->deref
;
1134 for (unsigned i
= 0; i
< elems
; i
++) {
1136 deref
->deref
.type
= glsl_get_struct_field(val
->type
, i
);
1137 val
->elems
[i
] = _vtn_variable_load(b
, src_deref
, &deref
->deref
);
1141 src_deref_tail
->child
= old_child
;
1147 _vtn_variable_store(struct vtn_builder
*b
,
1148 nir_deref_var
*dest_deref
, nir_deref
*dest_deref_tail
,
1149 struct vtn_ssa_value
*src
)
1151 nir_deref
*old_child
= dest_deref_tail
->child
;
1153 if (glsl_type_is_vector_or_scalar(src
->type
)) {
1154 /* Terminate the deref chain in case there is one more link to pick
1155 * off a component of the vector.
1157 dest_deref_tail
->child
= NULL
;
1159 nir_intrinsic_instr
*store
=
1160 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_store_var
);
1161 store
->variables
[0] =
1162 nir_deref_as_var(nir_copy_deref(store
, &dest_deref
->deref
));
1163 store
->num_components
= glsl_get_vector_elements(src
->type
);
1164 store
->const_index
[0] = (1 << store
->num_components
) - 1;
1165 store
->src
[0] = nir_src_for_ssa(src
->def
);
1167 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
1168 } else if (glsl_get_base_type(src
->type
) == GLSL_TYPE_ARRAY
||
1169 glsl_type_is_matrix(src
->type
)) {
1170 unsigned elems
= glsl_get_length(src
->type
);
1172 nir_deref_array
*deref
= nir_deref_array_create(b
);
1173 deref
->deref_array_type
= nir_deref_array_type_direct
;
1174 deref
->deref
.type
= glsl_get_array_element(src
->type
);
1175 dest_deref_tail
->child
= &deref
->deref
;
1176 for (unsigned i
= 0; i
< elems
; i
++) {
1177 deref
->base_offset
= i
;
1178 _vtn_variable_store(b
, dest_deref
, &deref
->deref
, src
->elems
[i
]);
1181 assert(glsl_get_base_type(src
->type
) == GLSL_TYPE_STRUCT
);
1182 unsigned elems
= glsl_get_length(src
->type
);
1184 nir_deref_struct
*deref
= nir_deref_struct_create(b
, 0);
1185 dest_deref_tail
->child
= &deref
->deref
;
1186 for (unsigned i
= 0; i
< elems
; i
++) {
1188 deref
->deref
.type
= glsl_get_struct_field(src
->type
, i
);
1189 _vtn_variable_store(b
, dest_deref
, &deref
->deref
, src
->elems
[i
]);
1193 dest_deref_tail
->child
= old_child
;
1196 static nir_ssa_def
*
1197 nir_vulkan_resource_index(nir_builder
*b
, unsigned set
, unsigned binding
,
1198 nir_variable_mode mode
, nir_ssa_def
*array_index
)
1200 if (array_index
== NULL
)
1201 array_index
= nir_imm_int(b
, 0);
1203 nir_intrinsic_instr
*instr
=
1204 nir_intrinsic_instr_create(b
->shader
,
1205 nir_intrinsic_vulkan_resource_index
);
1206 instr
->src
[0] = nir_src_for_ssa(array_index
);
1207 instr
->const_index
[0] = set
;
1208 instr
->const_index
[1] = binding
;
1209 instr
->const_index
[2] = mode
;
1211 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
, 1, NULL
);
1212 nir_builder_instr_insert(b
, &instr
->instr
);
1214 return &instr
->dest
.ssa
;
1217 static struct vtn_ssa_value
*
1218 _vtn_block_load(struct vtn_builder
*b
, nir_intrinsic_op op
,
1219 unsigned set
, unsigned binding
, nir_variable_mode mode
,
1220 nir_ssa_def
*index
, nir_ssa_def
*offset
, struct vtn_type
*type
)
1222 struct vtn_ssa_value
*val
= ralloc(b
, struct vtn_ssa_value
);
1223 val
->type
= type
->type
;
1224 val
->transposed
= NULL
;
1225 if (glsl_type_is_vector_or_scalar(type
->type
)) {
1226 nir_intrinsic_instr
*load
= nir_intrinsic_instr_create(b
->shader
, op
);
1227 load
->num_components
= glsl_get_vector_elements(type
->type
);
1230 case nir_intrinsic_load_ubo
:
1231 case nir_intrinsic_load_ssbo
: {
1232 nir_ssa_def
*res_index
= nir_vulkan_resource_index(&b
->nb
,
1235 load
->src
[0] = nir_src_for_ssa(res_index
);
1236 load
->src
[1] = nir_src_for_ssa(offset
);
1240 case nir_intrinsic_load_push_constant
:
1241 load
->src
[0] = nir_src_for_ssa(offset
);
1245 unreachable("Invalid block load intrinsic");
1248 nir_ssa_dest_init(&load
->instr
, &load
->dest
, load
->num_components
, NULL
);
1249 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
1251 if (glsl_get_base_type(type
->type
) == GLSL_TYPE_BOOL
) {
1252 /* Loads of booleans from externally visible memory need to be
1253 * fixed up since they're defined to be zero/nonzero rather than
1254 * NIR_FALSE/NIR_TRUE.
1256 val
->def
= nir_ine(&b
->nb
, &load
->dest
.ssa
, nir_imm_int(&b
->nb
, 0));
1258 val
->def
= &load
->dest
.ssa
;
1261 unsigned elems
= glsl_get_length(type
->type
);
1262 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1263 if (glsl_type_is_struct(type
->type
)) {
1264 for (unsigned i
= 0; i
< elems
; i
++) {
1265 nir_ssa_def
*child_offset
=
1266 nir_iadd(&b
->nb
, offset
, nir_imm_int(&b
->nb
, type
->offsets
[i
]));
1267 val
->elems
[i
] = _vtn_block_load(b
, op
, set
, binding
, mode
, index
,
1268 child_offset
, type
->members
[i
]);
1271 for (unsigned i
= 0; i
< elems
; i
++) {
1272 nir_ssa_def
*child_offset
=
1273 nir_iadd(&b
->nb
, offset
, nir_imm_int(&b
->nb
, i
* type
->stride
));
1274 val
->elems
[i
] = _vtn_block_load(b
, op
, set
, binding
, mode
, index
,
1275 child_offset
,type
->array_element
);
1284 vtn_block_get_offset(struct vtn_builder
*b
, nir_deref_var
*src
,
1285 struct vtn_type
**type
, nir_deref
*src_tail
,
1286 nir_ssa_def
**index
, nir_ssa_def
**offset
)
1288 nir_deref
*deref
= &src
->deref
;
1290 if (deref
->child
->deref_type
== nir_deref_type_array
) {
1291 deref
= deref
->child
;
1292 *type
= (*type
)->array_element
;
1293 nir_deref_array
*deref_array
= nir_deref_as_array(deref
);
1294 *index
= nir_imm_int(&b
->nb
, deref_array
->base_offset
);
1296 if (deref_array
->deref_array_type
== nir_deref_array_type_indirect
)
1297 *index
= nir_iadd(&b
->nb
, *index
, deref_array
->indirect
.ssa
);
1299 *index
= nir_imm_int(&b
->nb
, 0);
1302 *offset
= nir_imm_int(&b
->nb
, 0);
1303 while (deref
!= src_tail
) {
1304 deref
= deref
->child
;
1305 switch (deref
->deref_type
) {
1306 case nir_deref_type_array
: {
1307 nir_deref_array
*deref_array
= nir_deref_as_array(deref
);
1308 nir_ssa_def
*off
= nir_imm_int(&b
->nb
, deref_array
->base_offset
);
1310 if (deref_array
->deref_array_type
== nir_deref_array_type_indirect
)
1311 off
= nir_iadd(&b
->nb
, off
, deref_array
->indirect
.ssa
);
1313 off
= nir_imul(&b
->nb
, off
, nir_imm_int(&b
->nb
, (*type
)->stride
));
1314 *offset
= nir_iadd(&b
->nb
, *offset
, off
);
1316 *type
= (*type
)->array_element
;
1320 case nir_deref_type_struct
: {
1321 nir_deref_struct
*deref_struct
= nir_deref_as_struct(deref
);
1323 unsigned elem_off
= (*type
)->offsets
[deref_struct
->index
];
1324 *offset
= nir_iadd(&b
->nb
, *offset
, nir_imm_int(&b
->nb
, elem_off
));
1326 *type
= (*type
)->members
[deref_struct
->index
];
1331 unreachable("unknown deref type");
1336 static struct vtn_ssa_value
*
1337 vtn_block_load(struct vtn_builder
*b
, nir_deref_var
*src
,
1338 struct vtn_type
*type
, nir_deref
*src_tail
)
1341 nir_ssa_def
*offset
;
1342 vtn_block_get_offset(b
, src
, &type
, src_tail
, &index
, &offset
);
1344 nir_intrinsic_op op
;
1345 if (src
->var
->data
.mode
== nir_var_uniform
) {
1346 if (src
->var
->data
.descriptor_set
>= 0) {
1348 assert(src
->var
->data
.binding
>= 0);
1350 op
= nir_intrinsic_load_ubo
;
1352 /* Push constant load */
1353 assert(src
->var
->data
.descriptor_set
== -1 &&
1354 src
->var
->data
.binding
== -1);
1356 op
= nir_intrinsic_load_push_constant
;
1359 assert(src
->var
->data
.mode
== nir_var_shader_storage
);
1360 op
= nir_intrinsic_load_ssbo
;
1363 return _vtn_block_load(b
, op
, src
->var
->data
.descriptor_set
,
1364 src
->var
->data
.binding
, src
->var
->data
.mode
,
1365 index
, offset
, type
);
1369 * Gets the NIR-level deref tail, which may have as a child an array deref
1370 * selecting which component due to OpAccessChain supporting per-component
1371 * indexing in SPIR-V.
1375 get_deref_tail(nir_deref_var
*deref
)
1377 nir_deref
*cur
= &deref
->deref
;
1378 while (!glsl_type_is_vector_or_scalar(cur
->type
) && cur
->child
)
1384 static nir_ssa_def
*vtn_vector_extract(struct vtn_builder
*b
,
1385 nir_ssa_def
*src
, unsigned index
);
1387 static nir_ssa_def
*vtn_vector_extract_dynamic(struct vtn_builder
*b
,
1389 nir_ssa_def
*index
);
1392 variable_is_external_block(nir_variable
*var
)
1394 return var
->interface_type
&&
1395 glsl_type_is_struct(var
->interface_type
) &&
1396 (var
->data
.mode
== nir_var_uniform
||
1397 var
->data
.mode
== nir_var_shader_storage
);
1400 static struct vtn_ssa_value
*
1401 vtn_variable_load(struct vtn_builder
*b
, nir_deref_var
*src
,
1402 struct vtn_type
*src_type
)
1404 nir_deref
*src_tail
= get_deref_tail(src
);
1406 struct vtn_ssa_value
*val
;
1407 if (variable_is_external_block(src
->var
))
1408 val
= vtn_block_load(b
, src
, src_type
, src_tail
);
1410 val
= _vtn_variable_load(b
, src
, src_tail
);
1412 if (src_tail
->child
) {
1413 nir_deref_array
*vec_deref
= nir_deref_as_array(src_tail
->child
);
1414 assert(vec_deref
->deref
.child
== NULL
);
1415 val
->type
= vec_deref
->deref
.type
;
1416 if (vec_deref
->deref_array_type
== nir_deref_array_type_direct
)
1417 val
->def
= vtn_vector_extract(b
, val
->def
, vec_deref
->base_offset
);
1419 val
->def
= vtn_vector_extract_dynamic(b
, val
->def
,
1420 vec_deref
->indirect
.ssa
);
1427 _vtn_block_store(struct vtn_builder
*b
, nir_intrinsic_op op
,
1428 struct vtn_ssa_value
*src
, unsigned set
, unsigned binding
,
1429 nir_variable_mode mode
, nir_ssa_def
*index
,
1430 nir_ssa_def
*offset
, struct vtn_type
*type
)
1432 assert(src
->type
== type
->type
);
1433 if (glsl_type_is_vector_or_scalar(type
->type
)) {
1434 nir_intrinsic_instr
*store
= nir_intrinsic_instr_create(b
->shader
, op
);
1435 store
->num_components
= glsl_get_vector_elements(type
->type
);
1436 store
->const_index
[0] = (1 << store
->num_components
) - 1;
1437 store
->src
[0] = nir_src_for_ssa(src
->def
);
1439 nir_ssa_def
*res_index
= nir_vulkan_resource_index(&b
->nb
,
1442 store
->src
[1] = nir_src_for_ssa(res_index
);
1443 store
->src
[2] = nir_src_for_ssa(offset
);
1445 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
1447 unsigned elems
= glsl_get_length(type
->type
);
1448 if (glsl_type_is_struct(type
->type
)) {
1449 for (unsigned i
= 0; i
< elems
; i
++) {
1450 nir_ssa_def
*child_offset
=
1451 nir_iadd(&b
->nb
, offset
, nir_imm_int(&b
->nb
, type
->offsets
[i
]));
1452 _vtn_block_store(b
, op
, src
->elems
[i
], set
, binding
, mode
,
1453 index
, child_offset
, type
->members
[i
]);
1456 for (unsigned i
= 0; i
< elems
; i
++) {
1457 nir_ssa_def
*child_offset
=
1458 nir_iadd(&b
->nb
, offset
, nir_imm_int(&b
->nb
, i
* type
->stride
));
1459 _vtn_block_store(b
, op
, src
->elems
[i
], set
, binding
, mode
,
1460 index
, child_offset
, type
->array_element
);
1467 vtn_block_store(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
1468 nir_deref_var
*dest
, struct vtn_type
*type
,
1469 nir_deref
*dest_tail
)
1472 nir_ssa_def
*offset
;
1473 vtn_block_get_offset(b
, dest
, &type
, dest_tail
, &index
, &offset
);
1475 nir_intrinsic_op op
= nir_intrinsic_store_ssbo
;
1477 return _vtn_block_store(b
, op
, src
, dest
->var
->data
.descriptor_set
,
1478 dest
->var
->data
.binding
, dest
->var
->data
.mode
,
1479 index
, offset
, type
);
1482 static nir_ssa_def
* vtn_vector_insert(struct vtn_builder
*b
,
1483 nir_ssa_def
*src
, nir_ssa_def
*insert
,
1486 static nir_ssa_def
* vtn_vector_insert_dynamic(struct vtn_builder
*b
,
1488 nir_ssa_def
*insert
,
1489 nir_ssa_def
*index
);
1491 vtn_variable_store(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
1492 nir_deref_var
*dest
, struct vtn_type
*dest_type
)
1494 nir_deref
*dest_tail
= get_deref_tail(dest
);
1495 if (variable_is_external_block(dest
->var
)) {
1496 assert(dest
->var
->data
.mode
== nir_var_shader_storage
);
1497 vtn_block_store(b
, src
, dest
, dest_type
, dest_tail
);
1499 if (dest_tail
->child
) {
1500 struct vtn_ssa_value
*val
= _vtn_variable_load(b
, dest
, dest_tail
);
1501 nir_deref_array
*deref
= nir_deref_as_array(dest_tail
->child
);
1502 assert(deref
->deref
.child
== NULL
);
1503 if (deref
->deref_array_type
== nir_deref_array_type_direct
)
1504 val
->def
= vtn_vector_insert(b
, val
->def
, src
->def
,
1505 deref
->base_offset
);
1507 val
->def
= vtn_vector_insert_dynamic(b
, val
->def
, src
->def
,
1508 deref
->indirect
.ssa
);
1509 _vtn_variable_store(b
, dest
, dest_tail
, val
);
1511 _vtn_variable_store(b
, dest
, dest_tail
, src
);
1517 vtn_variable_copy(struct vtn_builder
*b
, nir_deref_var
*src
,
1518 nir_deref_var
*dest
, struct vtn_type
*type
)
1520 nir_deref
*src_tail
= get_deref_tail(src
);
1522 if (src_tail
->child
|| src
->var
->interface_type
) {
1523 assert(get_deref_tail(dest
)->child
);
1524 struct vtn_ssa_value
*val
= vtn_variable_load(b
, src
, type
);
1525 vtn_variable_store(b
, val
, dest
, type
);
1527 nir_intrinsic_instr
*copy
=
1528 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
1529 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
1530 copy
->variables
[1] = nir_deref_as_var(nir_copy_deref(copy
, &src
->deref
));
1532 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
1536 /* Tries to compute the size of an interface block based on the strides and
1537 * offsets that are provided to us in the SPIR-V source.
1540 vtn_type_block_size(struct vtn_type
*type
)
1542 enum glsl_base_type base_type
= glsl_get_base_type(type
->type
);
1543 switch (base_type
) {
1544 case GLSL_TYPE_UINT
:
1546 case GLSL_TYPE_FLOAT
:
1547 case GLSL_TYPE_BOOL
:
1548 case GLSL_TYPE_DOUBLE
: {
1549 unsigned cols
= type
->row_major
? glsl_get_vector_elements(type
->type
) :
1550 glsl_get_matrix_columns(type
->type
);
1552 assert(type
->stride
> 0);
1553 return type
->stride
* cols
;
1554 } else if (base_type
== GLSL_TYPE_DOUBLE
) {
1555 return glsl_get_vector_elements(type
->type
) * 8;
1557 return glsl_get_vector_elements(type
->type
) * 4;
1561 case GLSL_TYPE_STRUCT
:
1562 case GLSL_TYPE_INTERFACE
: {
1564 unsigned num_fields
= glsl_get_length(type
->type
);
1565 for (unsigned f
= 0; f
< num_fields
; f
++) {
1566 unsigned field_end
= type
->offsets
[f
] +
1567 vtn_type_block_size(type
->members
[f
]);
1568 size
= MAX2(size
, field_end
);
1573 case GLSL_TYPE_ARRAY
:
1574 assert(type
->stride
> 0);
1575 assert(glsl_get_length(type
->type
) > 0);
1576 return type
->stride
* glsl_get_length(type
->type
);
1579 assert(!"Invalid block type");
1585 is_interface_type(struct vtn_type
*type
)
1587 return type
->block
|| type
->buffer_block
||
1588 glsl_type_is_sampler(type
->type
) ||
1589 glsl_type_is_image(type
->type
);
1593 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
1594 const uint32_t *w
, unsigned count
)
1597 case SpvOpVariable
: {
1598 struct vtn_type
*type
=
1599 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1600 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
1602 nir_variable
*var
= rzalloc(b
->shader
, nir_variable
);
1604 var
->type
= type
->type
;
1605 var
->name
= ralloc_strdup(var
, val
->name
);
1607 struct vtn_type
*interface_type
;
1608 if (is_interface_type(type
)) {
1609 interface_type
= type
;
1610 } else if (glsl_type_is_array(type
->type
) &&
1611 is_interface_type(type
->array_element
)) {
1612 interface_type
= type
->array_element
;
1614 interface_type
= NULL
;
1618 var
->interface_type
= interface_type
->type
;
1620 switch ((SpvStorageClass
)w
[3]) {
1621 case SpvStorageClassUniform
:
1622 case SpvStorageClassUniformConstant
:
1623 if (interface_type
&& interface_type
->buffer_block
) {
1624 var
->data
.mode
= nir_var_shader_storage
;
1625 b
->shader
->info
.num_ssbos
++;
1627 /* UBO's and samplers */
1628 var
->data
.mode
= nir_var_uniform
;
1629 var
->data
.read_only
= true;
1630 if (interface_type
) {
1631 if (glsl_type_is_image(interface_type
->type
)) {
1632 b
->shader
->info
.num_images
++;
1633 var
->data
.image
.format
= interface_type
->image_format
;
1634 } else if (glsl_type_is_sampler(interface_type
->type
)) {
1635 b
->shader
->info
.num_textures
++;
1637 assert(glsl_type_is_struct(interface_type
->type
));
1638 b
->shader
->info
.num_ubos
++;
1643 case SpvStorageClassPushConstant
:
1644 assert(interface_type
&& interface_type
->block
);
1645 var
->data
.mode
= nir_var_uniform
;
1646 var
->data
.read_only
= true;
1647 var
->data
.descriptor_set
= -1;
1648 var
->data
.binding
= -1;
1650 /* We have exactly one push constant block */
1651 assert(b
->shader
->num_uniforms
== 0);
1652 b
->shader
->num_uniforms
= vtn_type_block_size(type
) * 4;
1654 case SpvStorageClassInput
:
1655 var
->data
.mode
= nir_var_shader_in
;
1656 var
->data
.read_only
= true;
1658 case SpvStorageClassOutput
:
1659 var
->data
.mode
= nir_var_shader_out
;
1661 case SpvStorageClassPrivate
:
1662 var
->data
.mode
= nir_var_global
;
1664 case SpvStorageClassFunction
:
1665 var
->data
.mode
= nir_var_local
;
1667 case SpvStorageClassWorkgroup
:
1668 case SpvStorageClassCrossWorkgroup
:
1669 case SpvStorageClassGeneric
:
1670 case SpvStorageClassAtomicCounter
:
1672 unreachable("Unhandled variable storage class");
1677 var
->constant_initializer
=
1678 vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
1681 val
->deref
= nir_deref_var_create(b
, var
);
1682 val
->deref_type
= type
;
1684 /* We handle decorations first because decorations might give us
1685 * location information. We use the data.explicit_location field to
1686 * note that the location provided is the "final" location. If
1687 * data.explicit_location == false, this means that it's relative to
1688 * whatever the base location is.
1690 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
1692 if (!var
->data
.explicit_location
) {
1693 if (b
->shader
->stage
== MESA_SHADER_FRAGMENT
&&
1694 var
->data
.mode
== nir_var_shader_out
) {
1695 var
->data
.location
+= FRAG_RESULT_DATA0
;
1696 } else if (b
->shader
->stage
== MESA_SHADER_VERTEX
&&
1697 var
->data
.mode
== nir_var_shader_in
) {
1698 var
->data
.location
+= VERT_ATTRIB_GENERIC0
;
1699 } else if (var
->data
.mode
== nir_var_shader_in
||
1700 var
->data
.mode
== nir_var_shader_out
) {
1701 var
->data
.location
+= VARYING_SLOT_VAR0
;
1705 /* Interface block variables aren't actually going to be referenced
1706 * by the generated NIR, so we don't put them in the list
1708 if (interface_type
&& glsl_type_is_struct(interface_type
->type
))
1711 if (var
->data
.mode
== nir_var_local
) {
1712 nir_function_impl_add_variable(b
->impl
, var
);
1714 nir_shader_add_variable(b
->shader
, var
);
1720 case SpvOpAccessChain
:
1721 case SpvOpInBoundsAccessChain
: {
1722 nir_deref_var
*base
;
1723 struct vtn_value
*base_val
= vtn_untyped_value(b
, w
[3]);
1724 if (base_val
->value_type
== vtn_value_type_sampled_image
) {
1725 /* This is rather insane. SPIR-V allows you to use OpSampledImage
1726 * to combine an array of images with a single sampler to get an
1727 * array of sampled images that all share the same sampler.
1728 * Fortunately, this means that we can more-or-less ignore the
1729 * sampler when crawling the access chain, but it does leave us
1730 * with this rather awkward little special-case.
1732 base
= base_val
->sampled_image
->image
;
1734 assert(base_val
->value_type
== vtn_value_type_deref
);
1735 base
= base_val
->deref
;
1738 nir_deref_var
*deref
= nir_deref_as_var(nir_copy_deref(b
, &base
->deref
));
1739 struct vtn_type
*deref_type
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref_type
;
1741 nir_deref
*tail
= &deref
->deref
;
1745 for (unsigned i
= 0; i
< count
- 4; i
++) {
1746 assert(w
[i
+ 4] < b
->value_id_bound
);
1747 struct vtn_value
*idx_val
= &b
->values
[w
[i
+ 4]];
1749 enum glsl_base_type base_type
= glsl_get_base_type(tail
->type
);
1750 switch (base_type
) {
1751 case GLSL_TYPE_UINT
:
1753 case GLSL_TYPE_FLOAT
:
1754 case GLSL_TYPE_DOUBLE
:
1755 case GLSL_TYPE_BOOL
:
1756 case GLSL_TYPE_ARRAY
: {
1757 nir_deref_array
*deref_arr
= nir_deref_array_create(b
);
1758 if (base_type
== GLSL_TYPE_ARRAY
||
1759 glsl_type_is_matrix(tail
->type
)) {
1760 deref_type
= deref_type
->array_element
;
1762 assert(glsl_type_is_vector(tail
->type
));
1763 deref_type
= ralloc(b
, struct vtn_type
);
1764 deref_type
->type
= glsl_scalar_type(base_type
);
1767 deref_arr
->deref
.type
= deref_type
->type
;
1769 if (idx_val
->value_type
== vtn_value_type_constant
) {
1770 unsigned idx
= idx_val
->constant
->value
.u
[0];
1771 deref_arr
->deref_array_type
= nir_deref_array_type_direct
;
1772 deref_arr
->base_offset
= idx
;
1774 assert(idx_val
->value_type
== vtn_value_type_ssa
);
1775 assert(glsl_type_is_scalar(idx_val
->ssa
->type
));
1776 deref_arr
->deref_array_type
= nir_deref_array_type_indirect
;
1777 deref_arr
->base_offset
= 0;
1778 deref_arr
->indirect
= nir_src_for_ssa(idx_val
->ssa
->def
);
1780 tail
->child
= &deref_arr
->deref
;
1784 case GLSL_TYPE_STRUCT
: {
1785 assert(idx_val
->value_type
== vtn_value_type_constant
);
1786 unsigned idx
= idx_val
->constant
->value
.u
[0];
1787 deref_type
= deref_type
->members
[idx
];
1788 nir_deref_struct
*deref_struct
= nir_deref_struct_create(b
, idx
);
1789 deref_struct
->deref
.type
= deref_type
->type
;
1790 tail
->child
= &deref_struct
->deref
;
1794 unreachable("Invalid type for deref");
1797 if (deref_type
->is_builtin
) {
1798 /* If we encounter a builtin, we throw away the ress of the
1799 * access chain, jump to the builtin, and keep building.
1801 const struct glsl_type
*builtin_type
= deref_type
->type
;
1803 nir_deref_array
*per_vertex_deref
= NULL
;
1804 if (glsl_type_is_array(base
->var
->type
)) {
1805 /* This builtin is a per-vertex builtin */
1806 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
1807 assert(base
->var
->data
.mode
== nir_var_shader_in
);
1808 builtin_type
= glsl_array_type(builtin_type
,
1809 b
->shader
->info
.gs
.vertices_in
);
1811 /* The first non-var deref should be an array deref. */
1812 assert(deref
->deref
.child
->deref_type
==
1813 nir_deref_type_array
);
1814 per_vertex_deref
= nir_deref_as_array(deref
->deref
.child
);
1817 nir_variable
*builtin
= get_builtin_variable(b
,
1818 base
->var
->data
.mode
,
1820 deref_type
->builtin
);
1821 deref
= nir_deref_var_create(b
, builtin
);
1823 if (per_vertex_deref
) {
1824 /* Since deref chains start at the variable, we can just
1825 * steal that link and use it.
1827 deref
->deref
.child
= &per_vertex_deref
->deref
;
1828 per_vertex_deref
->deref
.child
= NULL
;
1829 per_vertex_deref
->deref
.type
=
1830 glsl_get_array_element(builtin_type
);
1832 tail
= &per_vertex_deref
->deref
;
1834 tail
= &deref
->deref
;
1841 /* For uniform blocks, we don't resolve the access chain until we
1842 * actually access the variable, so we need to keep around the original
1843 * type of the variable.
1845 if (variable_is_external_block(base
->var
))
1846 deref_type
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref_type
;
1848 if (base_val
->value_type
== vtn_value_type_sampled_image
) {
1849 struct vtn_value
*val
=
1850 vtn_push_value(b
, w
[2], vtn_value_type_sampled_image
);
1851 val
->sampled_image
= ralloc(b
, struct vtn_sampled_image
);
1852 val
->sampled_image
->image
= deref
;
1853 val
->sampled_image
->sampler
= base_val
->sampled_image
->sampler
;
1855 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
1857 val
->deref_type
= deref_type
;
1863 case SpvOpCopyMemory
: {
1864 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
1865 nir_deref_var
*src
= vtn_value(b
, w
[2], vtn_value_type_deref
)->deref
;
1866 struct vtn_type
*type
=
1867 vtn_value(b
, w
[1], vtn_value_type_deref
)->deref_type
;
1869 vtn_variable_copy(b
, src
, dest
, type
);
1874 nir_deref_var
*src
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
1875 struct vtn_type
*src_type
=
1876 vtn_value(b
, w
[3], vtn_value_type_deref
)->deref_type
;
1878 if (src
->var
->interface_type
&&
1879 (glsl_type_is_sampler(src
->var
->interface_type
) ||
1880 glsl_type_is_image(src
->var
->interface_type
))) {
1881 vtn_push_value(b
, w
[2], vtn_value_type_deref
)->deref
= src
;
1885 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
1886 val
->ssa
= vtn_variable_load(b
, src
, src_type
);
1891 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
1892 struct vtn_type
*dest_type
=
1893 vtn_value(b
, w
[1], vtn_value_type_deref
)->deref_type
;
1894 struct vtn_ssa_value
*src
= vtn_ssa_value(b
, w
[2]);
1895 vtn_variable_store(b
, src
, dest
, dest_type
);
1899 case SpvOpCopyMemorySized
:
1900 case SpvOpArrayLength
:
1902 unreachable("Unhandled opcode");
1907 vtn_handle_function_call(struct vtn_builder
*b
, SpvOp opcode
,
1908 const uint32_t *w
, unsigned count
)
1910 struct nir_function
*callee
=
1911 vtn_value(b
, w
[3], vtn_value_type_function
)->func
->impl
->function
;
1913 nir_call_instr
*call
= nir_call_instr_create(b
->nb
.shader
, callee
);
1914 for (unsigned i
= 0; i
< call
->num_params
; i
++) {
1915 unsigned arg_id
= w
[4 + i
];
1916 struct vtn_value
*arg
= vtn_untyped_value(b
, arg_id
);
1917 if (arg
->value_type
== vtn_value_type_deref
) {
1919 nir_deref_as_var(nir_copy_deref(call
, &arg
->deref
->deref
));
1921 struct vtn_ssa_value
*arg_ssa
= vtn_ssa_value(b
, arg_id
);
1923 /* Make a temporary to store the argument in */
1925 nir_local_variable_create(b
->impl
, arg_ssa
->type
, "arg_tmp");
1926 call
->params
[i
] = nir_deref_var_create(call
, tmp
);
1928 vtn_variable_store(b
, arg_ssa
, call
->params
[i
], arg
->type
);
1932 nir_variable
*out_tmp
= NULL
;
1933 if (!glsl_type_is_void(callee
->return_type
)) {
1934 out_tmp
= nir_local_variable_create(b
->impl
, callee
->return_type
,
1936 call
->return_deref
= nir_deref_var_create(call
, out_tmp
);
1939 nir_builder_instr_insert(&b
->nb
, &call
->instr
);
1941 if (glsl_type_is_void(callee
->return_type
)) {
1942 vtn_push_value(b
, w
[2], vtn_value_type_undef
);
1944 struct vtn_type
*rettype
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1945 struct vtn_value
*retval
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
1946 retval
->ssa
= vtn_variable_load(b
, call
->return_deref
, rettype
);
1950 static struct vtn_ssa_value
*
1951 vtn_create_ssa_value(struct vtn_builder
*b
, const struct glsl_type
*type
)
1953 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
1956 if (!glsl_type_is_vector_or_scalar(type
)) {
1957 unsigned elems
= glsl_get_length(type
);
1958 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1959 for (unsigned i
= 0; i
< elems
; i
++) {
1960 const struct glsl_type
*child_type
;
1962 switch (glsl_get_base_type(type
)) {
1964 case GLSL_TYPE_UINT
:
1965 case GLSL_TYPE_BOOL
:
1966 case GLSL_TYPE_FLOAT
:
1967 case GLSL_TYPE_DOUBLE
:
1968 child_type
= glsl_get_column_type(type
);
1970 case GLSL_TYPE_ARRAY
:
1971 child_type
= glsl_get_array_element(type
);
1973 case GLSL_TYPE_STRUCT
:
1974 child_type
= glsl_get_struct_field(type
, i
);
1977 unreachable("unkown base type");
1980 val
->elems
[i
] = vtn_create_ssa_value(b
, child_type
);
1988 vtn_tex_src(struct vtn_builder
*b
, unsigned index
, nir_tex_src_type type
)
1991 src
.src
= nir_src_for_ssa(vtn_ssa_value(b
, index
)->def
);
1992 src
.src_type
= type
;
1997 vtn_handle_texture(struct vtn_builder
*b
, SpvOp opcode
,
1998 const uint32_t *w
, unsigned count
)
2000 if (opcode
== SpvOpSampledImage
) {
2001 struct vtn_value
*val
=
2002 vtn_push_value(b
, w
[2], vtn_value_type_sampled_image
);
2003 val
->sampled_image
= ralloc(b
, struct vtn_sampled_image
);
2004 val
->sampled_image
->image
=
2005 vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
2006 val
->sampled_image
->sampler
=
2007 vtn_value(b
, w
[4], vtn_value_type_deref
)->deref
;
2011 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2013 struct vtn_sampled_image sampled
;
2014 struct vtn_value
*sampled_val
= vtn_untyped_value(b
, w
[3]);
2015 if (sampled_val
->value_type
== vtn_value_type_sampled_image
) {
2016 sampled
= *sampled_val
->sampled_image
;
2018 assert(sampled_val
->value_type
== vtn_value_type_deref
);
2019 sampled
.image
= NULL
;
2020 sampled
.sampler
= sampled_val
->deref
;
2023 nir_tex_src srcs
[8]; /* 8 should be enough */
2024 nir_tex_src
*p
= srcs
;
2028 unsigned coord_components
= 0;
2030 case SpvOpImageSampleImplicitLod
:
2031 case SpvOpImageSampleExplicitLod
:
2032 case SpvOpImageSampleDrefImplicitLod
:
2033 case SpvOpImageSampleDrefExplicitLod
:
2034 case SpvOpImageSampleProjImplicitLod
:
2035 case SpvOpImageSampleProjExplicitLod
:
2036 case SpvOpImageSampleProjDrefImplicitLod
:
2037 case SpvOpImageSampleProjDrefExplicitLod
:
2038 case SpvOpImageFetch
:
2039 case SpvOpImageGather
:
2040 case SpvOpImageDrefGather
:
2041 case SpvOpImageQueryLod
: {
2042 /* All these types have the coordinate as their first real argument */
2043 struct vtn_ssa_value
*coord
= vtn_ssa_value(b
, w
[idx
++]);
2044 coord_components
= glsl_get_vector_elements(coord
->type
);
2045 p
->src
= nir_src_for_ssa(coord
->def
);
2046 p
->src_type
= nir_tex_src_coord
;
2055 /* These all have an explicit depth value as their next source */
2057 case SpvOpImageSampleDrefImplicitLod
:
2058 case SpvOpImageSampleDrefExplicitLod
:
2059 case SpvOpImageSampleProjDrefImplicitLod
:
2060 case SpvOpImageSampleProjDrefExplicitLod
:
2061 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_comparitor
);
2067 /* Figure out the base texture operation */
2070 case SpvOpImageSampleImplicitLod
:
2071 case SpvOpImageSampleDrefImplicitLod
:
2072 case SpvOpImageSampleProjImplicitLod
:
2073 case SpvOpImageSampleProjDrefImplicitLod
:
2074 texop
= nir_texop_tex
;
2077 case SpvOpImageSampleExplicitLod
:
2078 case SpvOpImageSampleDrefExplicitLod
:
2079 case SpvOpImageSampleProjExplicitLod
:
2080 case SpvOpImageSampleProjDrefExplicitLod
:
2081 texop
= nir_texop_txl
;
2084 case SpvOpImageFetch
:
2085 texop
= nir_texop_txf
;
2088 case SpvOpImageGather
:
2089 case SpvOpImageDrefGather
:
2090 texop
= nir_texop_tg4
;
2093 case SpvOpImageQuerySizeLod
:
2094 case SpvOpImageQuerySize
:
2095 texop
= nir_texop_txs
;
2098 case SpvOpImageQueryLod
:
2099 texop
= nir_texop_lod
;
2102 case SpvOpImageQueryLevels
:
2103 texop
= nir_texop_query_levels
;
2106 case SpvOpImageQuerySamples
:
2108 unreachable("Unhandled opcode");
2111 /* Now we need to handle some number of optional arguments */
2113 uint32_t operands
= w
[idx
++];
2115 if (operands
& SpvImageOperandsBiasMask
) {
2116 assert(texop
== nir_texop_tex
);
2117 texop
= nir_texop_txb
;
2118 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_bias
);
2121 if (operands
& SpvImageOperandsLodMask
) {
2122 assert(texop
== nir_texop_txl
|| texop
== nir_texop_txf
||
2123 texop
== nir_texop_txs
);
2124 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_lod
);
2127 if (operands
& SpvImageOperandsGradMask
) {
2128 assert(texop
== nir_texop_tex
);
2129 texop
= nir_texop_txd
;
2130 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_ddx
);
2131 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_ddy
);
2134 if (operands
& SpvImageOperandsOffsetMask
||
2135 operands
& SpvImageOperandsConstOffsetMask
)
2136 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_offset
);
2138 if (operands
& SpvImageOperandsConstOffsetsMask
)
2139 assert(!"Constant offsets to texture gather not yet implemented");
2141 if (operands
& SpvImageOperandsSampleMask
) {
2142 assert(texop
== nir_texop_txf
);
2143 texop
= nir_texop_txf_ms
;
2144 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_ms_index
);
2147 /* We should have now consumed exactly all of the arguments */
2148 assert(idx
== count
);
2150 nir_tex_instr
*instr
= nir_tex_instr_create(b
->shader
, p
- srcs
);
2152 const struct glsl_type
*sampler_type
=
2153 nir_deref_tail(&sampled
.sampler
->deref
)->type
;
2154 instr
->sampler_dim
= glsl_get_sampler_dim(sampler_type
);
2156 switch (glsl_get_sampler_result_type(sampler_type
)) {
2157 case GLSL_TYPE_FLOAT
: instr
->dest_type
= nir_type_float
; break;
2158 case GLSL_TYPE_INT
: instr
->dest_type
= nir_type_int
; break;
2159 case GLSL_TYPE_UINT
: instr
->dest_type
= nir_type_uint
; break;
2160 case GLSL_TYPE_BOOL
: instr
->dest_type
= nir_type_bool
; break;
2162 unreachable("Invalid base type for sampler result");
2166 memcpy(instr
->src
, srcs
, instr
->num_srcs
* sizeof(*instr
->src
));
2167 instr
->coord_components
= coord_components
;
2168 instr
->is_array
= glsl_sampler_type_is_array(sampler_type
);
2169 instr
->is_shadow
= glsl_sampler_type_is_shadow(sampler_type
);
2172 nir_deref_as_var(nir_copy_deref(instr
, &sampled
.sampler
->deref
));
2173 if (sampled
.image
) {
2175 nir_deref_as_var(nir_copy_deref(instr
, &sampled
.image
->deref
));
2177 instr
->texture
= NULL
;
2180 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
, 4, NULL
);
2181 val
->ssa
= vtn_create_ssa_value(b
, glsl_vector_type(GLSL_TYPE_FLOAT
, 4));
2182 val
->ssa
->def
= &instr
->dest
.ssa
;
2184 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
2187 static nir_ssa_def
*
2188 get_image_coord(struct vtn_builder
*b
, uint32_t value
)
2190 struct vtn_ssa_value
*coord
= vtn_ssa_value(b
, value
);
2192 /* The image_load_store intrinsics assume a 4-dim coordinate */
2193 unsigned dim
= glsl_get_vector_elements(coord
->type
);
2194 unsigned swizzle
[4];
2195 for (unsigned i
= 0; i
< 4; i
++)
2196 swizzle
[i
] = MIN2(i
, dim
- 1);
2198 return nir_swizzle(&b
->nb
, coord
->def
, swizzle
, 4, false);
2202 vtn_handle_image(struct vtn_builder
*b
, SpvOp opcode
,
2203 const uint32_t *w
, unsigned count
)
2205 /* Just get this one out of the way */
2206 if (opcode
== SpvOpImageTexelPointer
) {
2207 struct vtn_value
*val
=
2208 vtn_push_value(b
, w
[2], vtn_value_type_image_pointer
);
2209 val
->image
= ralloc(b
, struct vtn_image_pointer
);
2211 val
->image
->deref
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
2212 val
->image
->coord
= get_image_coord(b
, w
[4]);
2213 val
->image
->sample
= vtn_ssa_value(b
, w
[5])->def
;
2217 struct vtn_image_pointer image
;
2220 case SpvOpAtomicExchange
:
2221 case SpvOpAtomicCompareExchange
:
2222 case SpvOpAtomicCompareExchangeWeak
:
2223 case SpvOpAtomicIIncrement
:
2224 case SpvOpAtomicIDecrement
:
2225 case SpvOpAtomicIAdd
:
2226 case SpvOpAtomicISub
:
2227 case SpvOpAtomicSMin
:
2228 case SpvOpAtomicUMin
:
2229 case SpvOpAtomicSMax
:
2230 case SpvOpAtomicUMax
:
2231 case SpvOpAtomicAnd
:
2233 case SpvOpAtomicXor
:
2234 image
= *vtn_value(b
, w
[3], vtn_value_type_image_pointer
)->image
;
2237 case SpvOpImageRead
:
2238 image
.deref
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
2239 image
.coord
= get_image_coord(b
, w
[4]);
2241 if (count
> 5 && (w
[5] & SpvImageOperandsSampleMask
)) {
2242 assert(w
[5] == SpvImageOperandsSampleMask
);
2243 image
.sample
= vtn_ssa_value(b
, w
[6])->def
;
2245 image
.sample
= nir_ssa_undef(&b
->nb
, 1);
2249 case SpvOpImageWrite
:
2250 image
.deref
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
2251 image
.coord
= get_image_coord(b
, w
[2]);
2255 if (count
> 4 && (w
[4] & SpvImageOperandsSampleMask
)) {
2256 assert(w
[4] == SpvImageOperandsSampleMask
);
2257 image
.sample
= vtn_ssa_value(b
, w
[5])->def
;
2259 image
.sample
= nir_ssa_undef(&b
->nb
, 1);
2263 unreachable("Invalid image opcode");
2266 nir_intrinsic_op op
;
2268 #define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_##N; break;
2270 OP(ImageWrite
, store
)
2271 OP(AtomicExchange
, atomic_exchange
)
2272 OP(AtomicCompareExchange
, atomic_comp_swap
)
2273 OP(AtomicIIncrement
, atomic_add
)
2274 OP(AtomicIDecrement
, atomic_add
)
2275 OP(AtomicIAdd
, atomic_add
)
2276 OP(AtomicISub
, atomic_add
)
2277 OP(AtomicSMin
, atomic_min
)
2278 OP(AtomicUMin
, atomic_min
)
2279 OP(AtomicSMax
, atomic_max
)
2280 OP(AtomicUMax
, atomic_max
)
2281 OP(AtomicAnd
, atomic_and
)
2282 OP(AtomicOr
, atomic_or
)
2283 OP(AtomicXor
, atomic_xor
)
2286 unreachable("Invalid image opcode");
2289 nir_intrinsic_instr
*intrin
= nir_intrinsic_instr_create(b
->shader
, op
);
2290 intrin
->variables
[0] =
2291 nir_deref_as_var(nir_copy_deref(&intrin
->instr
, &image
.deref
->deref
));
2292 intrin
->src
[0] = nir_src_for_ssa(image
.coord
);
2293 intrin
->src
[1] = nir_src_for_ssa(image
.sample
);
2296 case SpvOpImageRead
:
2298 case SpvOpImageWrite
:
2299 intrin
->src
[2] = nir_src_for_ssa(vtn_ssa_value(b
, w
[3])->def
);
2301 case SpvOpAtomicIIncrement
:
2302 intrin
->src
[2] = nir_src_for_ssa(nir_imm_int(&b
->nb
, 1));
2304 case SpvOpAtomicIDecrement
:
2305 intrin
->src
[2] = nir_src_for_ssa(nir_imm_int(&b
->nb
, -1));
2308 case SpvOpAtomicExchange
:
2309 case SpvOpAtomicIAdd
:
2310 case SpvOpAtomicSMin
:
2311 case SpvOpAtomicUMin
:
2312 case SpvOpAtomicSMax
:
2313 case SpvOpAtomicUMax
:
2314 case SpvOpAtomicAnd
:
2316 case SpvOpAtomicXor
:
2317 intrin
->src
[2] = nir_src_for_ssa(vtn_ssa_value(b
, w
[6])->def
);
2320 case SpvOpAtomicCompareExchange
:
2321 intrin
->src
[2] = nir_src_for_ssa(vtn_ssa_value(b
, w
[7])->def
);
2322 intrin
->src
[3] = nir_src_for_ssa(vtn_ssa_value(b
, w
[6])->def
);
2325 case SpvOpAtomicISub
:
2326 intrin
->src
[2] = nir_src_for_ssa(nir_ineg(&b
->nb
, vtn_ssa_value(b
, w
[6])->def
));
2330 unreachable("Invalid image opcode");
2333 if (opcode
!= SpvOpImageWrite
) {
2334 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2335 struct vtn_type
*type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
2336 nir_ssa_dest_init(&intrin
->instr
, &intrin
->dest
,
2337 glsl_get_vector_elements(type
->type
), NULL
);
2338 val
->ssa
= vtn_create_ssa_value(b
, type
->type
);
2339 val
->ssa
->def
= &intrin
->dest
.ssa
;
2342 nir_builder_instr_insert(&b
->nb
, &intrin
->instr
);
2345 static nir_alu_instr
*
2346 create_vec(nir_shader
*shader
, unsigned num_components
)
2349 switch (num_components
) {
2350 case 1: op
= nir_op_fmov
; break;
2351 case 2: op
= nir_op_vec2
; break;
2352 case 3: op
= nir_op_vec3
; break;
2353 case 4: op
= nir_op_vec4
; break;
2354 default: unreachable("bad vector size");
2357 nir_alu_instr
*vec
= nir_alu_instr_create(shader
, op
);
2358 nir_ssa_dest_init(&vec
->instr
, &vec
->dest
.dest
, num_components
, NULL
);
2359 vec
->dest
.write_mask
= (1 << num_components
) - 1;
2364 static struct vtn_ssa_value
*
2365 vtn_transpose(struct vtn_builder
*b
, struct vtn_ssa_value
*src
)
2367 if (src
->transposed
)
2368 return src
->transposed
;
2370 struct vtn_ssa_value
*dest
=
2371 vtn_create_ssa_value(b
, glsl_transposed_type(src
->type
));
2373 for (unsigned i
= 0; i
< glsl_get_matrix_columns(dest
->type
); i
++) {
2374 nir_alu_instr
*vec
= create_vec(b
->shader
,
2375 glsl_get_matrix_columns(src
->type
));
2376 if (glsl_type_is_vector_or_scalar(src
->type
)) {
2377 vec
->src
[0].src
= nir_src_for_ssa(src
->def
);
2378 vec
->src
[0].swizzle
[0] = i
;
2380 for (unsigned j
= 0; j
< glsl_get_matrix_columns(src
->type
); j
++) {
2381 vec
->src
[j
].src
= nir_src_for_ssa(src
->elems
[j
]->def
);
2382 vec
->src
[j
].swizzle
[0] = i
;
2385 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2386 dest
->elems
[i
]->def
= &vec
->dest
.dest
.ssa
;
2389 dest
->transposed
= src
;
2395 * Normally, column vectors in SPIR-V correspond to a single NIR SSA
2396 * definition. But for matrix multiplies, we want to do one routine for
2397 * multiplying a matrix by a matrix and then pretend that vectors are matrices
2398 * with one column. So we "wrap" these things, and unwrap the result before we
2402 static struct vtn_ssa_value
*
2403 vtn_wrap_matrix(struct vtn_builder
*b
, struct vtn_ssa_value
*val
)
2408 if (glsl_type_is_matrix(val
->type
))
2411 struct vtn_ssa_value
*dest
= rzalloc(b
, struct vtn_ssa_value
);
2412 dest
->type
= val
->type
;
2413 dest
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, 1);
2414 dest
->elems
[0] = val
;
2419 static struct vtn_ssa_value
*
2420 vtn_unwrap_matrix(struct vtn_ssa_value
*val
)
2422 if (glsl_type_is_matrix(val
->type
))
2425 return val
->elems
[0];
2428 static struct vtn_ssa_value
*
2429 vtn_matrix_multiply(struct vtn_builder
*b
,
2430 struct vtn_ssa_value
*_src0
, struct vtn_ssa_value
*_src1
)
2433 struct vtn_ssa_value
*src0
= vtn_wrap_matrix(b
, _src0
);
2434 struct vtn_ssa_value
*src1
= vtn_wrap_matrix(b
, _src1
);
2435 struct vtn_ssa_value
*src0_transpose
= vtn_wrap_matrix(b
, _src0
->transposed
);
2436 struct vtn_ssa_value
*src1_transpose
= vtn_wrap_matrix(b
, _src1
->transposed
);
2438 unsigned src0_rows
= glsl_get_vector_elements(src0
->type
);
2439 unsigned src0_columns
= glsl_get_matrix_columns(src0
->type
);
2440 unsigned src1_columns
= glsl_get_matrix_columns(src1
->type
);
2442 const struct glsl_type
*dest_type
;
2443 if (src1_columns
> 1) {
2444 dest_type
= glsl_matrix_type(glsl_get_base_type(src0
->type
),
2445 src0_rows
, src1_columns
);
2447 dest_type
= glsl_vector_type(glsl_get_base_type(src0
->type
), src0_rows
);
2449 struct vtn_ssa_value
*dest
= vtn_create_ssa_value(b
, dest_type
);
2451 dest
= vtn_wrap_matrix(b
, dest
);
2453 bool transpose_result
= false;
2454 if (src0_transpose
&& src1_transpose
) {
2455 /* transpose(A) * transpose(B) = transpose(B * A) */
2456 src1
= src0_transpose
;
2457 src0
= src1_transpose
;
2458 src0_transpose
= NULL
;
2459 src1_transpose
= NULL
;
2460 transpose_result
= true;
2463 if (src0_transpose
&& !src1_transpose
&&
2464 glsl_get_base_type(src0
->type
) == GLSL_TYPE_FLOAT
) {
2465 /* We already have the rows of src0 and the columns of src1 available,
2466 * so we can just take the dot product of each row with each column to
2470 for (unsigned i
= 0; i
< src1_columns
; i
++) {
2471 nir_alu_instr
*vec
= create_vec(b
->shader
, src0_rows
);
2472 for (unsigned j
= 0; j
< src0_rows
; j
++) {
2474 nir_src_for_ssa(nir_fdot(&b
->nb
, src0_transpose
->elems
[j
]->def
,
2475 src1
->elems
[i
]->def
));
2478 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2479 dest
->elems
[i
]->def
= &vec
->dest
.dest
.ssa
;
2482 /* We don't handle the case where src1 is transposed but not src0, since
2483 * the general case only uses individual components of src1 so the
2484 * optimizer should chew through the transpose we emitted for src1.
2487 for (unsigned i
= 0; i
< src1_columns
; i
++) {
2488 /* dest[i] = sum(src0[j] * src1[i][j] for all j) */
2489 dest
->elems
[i
]->def
=
2490 nir_fmul(&b
->nb
, src0
->elems
[0]->def
,
2491 vtn_vector_extract(b
, src1
->elems
[i
]->def
, 0));
2492 for (unsigned j
= 1; j
< src0_columns
; j
++) {
2493 dest
->elems
[i
]->def
=
2494 nir_fadd(&b
->nb
, dest
->elems
[i
]->def
,
2495 nir_fmul(&b
->nb
, src0
->elems
[j
]->def
,
2496 vtn_vector_extract(b
,
2497 src1
->elems
[i
]->def
, j
)));
2502 dest
= vtn_unwrap_matrix(dest
);
2504 if (transpose_result
)
2505 dest
= vtn_transpose(b
, dest
);
2510 static struct vtn_ssa_value
*
2511 vtn_mat_times_scalar(struct vtn_builder
*b
,
2512 struct vtn_ssa_value
*mat
,
2513 nir_ssa_def
*scalar
)
2515 struct vtn_ssa_value
*dest
= vtn_create_ssa_value(b
, mat
->type
);
2516 for (unsigned i
= 0; i
< glsl_get_matrix_columns(mat
->type
); i
++) {
2517 if (glsl_get_base_type(mat
->type
) == GLSL_TYPE_FLOAT
)
2518 dest
->elems
[i
]->def
= nir_fmul(&b
->nb
, mat
->elems
[i
]->def
, scalar
);
2520 dest
->elems
[i
]->def
= nir_imul(&b
->nb
, mat
->elems
[i
]->def
, scalar
);
2527 vtn_handle_matrix_alu(struct vtn_builder
*b
, SpvOp opcode
,
2528 const uint32_t *w
, unsigned count
)
2530 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2533 case SpvOpTranspose
: {
2534 struct vtn_ssa_value
*src
= vtn_ssa_value(b
, w
[3]);
2535 val
->ssa
= vtn_transpose(b
, src
);
2539 case SpvOpOuterProduct
: {
2540 struct vtn_ssa_value
*src0
= vtn_ssa_value(b
, w
[3]);
2541 struct vtn_ssa_value
*src1
= vtn_ssa_value(b
, w
[4]);
2543 val
->ssa
= vtn_matrix_multiply(b
, src0
, vtn_transpose(b
, src1
));
2547 case SpvOpMatrixTimesScalar
: {
2548 struct vtn_ssa_value
*mat
= vtn_ssa_value(b
, w
[3]);
2549 struct vtn_ssa_value
*scalar
= vtn_ssa_value(b
, w
[4]);
2551 if (mat
->transposed
) {
2552 val
->ssa
= vtn_transpose(b
, vtn_mat_times_scalar(b
, mat
->transposed
,
2555 val
->ssa
= vtn_mat_times_scalar(b
, mat
, scalar
->def
);
2560 case SpvOpVectorTimesMatrix
:
2561 case SpvOpMatrixTimesVector
:
2562 case SpvOpMatrixTimesMatrix
: {
2563 struct vtn_ssa_value
*src0
= vtn_ssa_value(b
, w
[3]);
2564 struct vtn_ssa_value
*src1
= vtn_ssa_value(b
, w
[4]);
2566 if (opcode
== SpvOpVectorTimesMatrix
) {
2567 val
->ssa
= vtn_matrix_multiply(b
, vtn_transpose(b
, src1
), src0
);
2569 val
->ssa
= vtn_matrix_multiply(b
, src0
, src1
);
2574 default: unreachable("unknown matrix opcode");
2579 vtn_handle_alu(struct vtn_builder
*b
, SpvOp opcode
,
2580 const uint32_t *w
, unsigned count
)
2582 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2583 const struct glsl_type
*type
=
2584 vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
2585 val
->ssa
= vtn_create_ssa_value(b
, type
);
2587 /* Collect the various SSA sources */
2588 const unsigned num_inputs
= count
- 3;
2589 nir_ssa_def
*src
[4];
2590 for (unsigned i
= 0; i
< num_inputs
; i
++)
2591 src
[i
] = vtn_ssa_value(b
, w
[i
+ 3])->def
;
2592 for (unsigned i
= num_inputs
; i
< 4; i
++)
2595 /* Indicates that the first two arguments should be swapped. This is
2596 * used for implementing greater-than and less-than-or-equal.
2602 /* Basic ALU operations */
2603 case SpvOpSNegate
: op
= nir_op_ineg
; break;
2604 case SpvOpFNegate
: op
= nir_op_fneg
; break;
2605 case SpvOpNot
: op
= nir_op_inot
; break;
2608 if (src
[0]->num_components
== 1) {
2611 switch (src
[0]->num_components
) {
2612 case 2: op
= nir_op_bany_inequal2
; break;
2613 case 3: op
= nir_op_bany_inequal3
; break;
2614 case 4: op
= nir_op_bany_inequal4
; break;
2616 src
[1] = nir_imm_int(&b
->nb
, NIR_FALSE
);
2621 if (src
[0]->num_components
== 1) {
2624 switch (src
[0]->num_components
) {
2625 case 2: op
= nir_op_ball_iequal2
; break;
2626 case 3: op
= nir_op_ball_iequal3
; break;
2627 case 4: op
= nir_op_ball_iequal4
; break;
2629 src
[1] = nir_imm_int(&b
->nb
, NIR_TRUE
);
2633 case SpvOpIAdd
: op
= nir_op_iadd
; break;
2634 case SpvOpFAdd
: op
= nir_op_fadd
; break;
2635 case SpvOpISub
: op
= nir_op_isub
; break;
2636 case SpvOpFSub
: op
= nir_op_fsub
; break;
2637 case SpvOpIMul
: op
= nir_op_imul
; break;
2638 case SpvOpFMul
: op
= nir_op_fmul
; break;
2639 case SpvOpUDiv
: op
= nir_op_udiv
; break;
2640 case SpvOpSDiv
: op
= nir_op_idiv
; break;
2641 case SpvOpFDiv
: op
= nir_op_fdiv
; break;
2642 case SpvOpUMod
: op
= nir_op_umod
; break;
2643 case SpvOpSMod
: op
= nir_op_umod
; break; /* FIXME? */
2644 case SpvOpFMod
: op
= nir_op_fmod
; break;
2647 assert(src
[0]->num_components
== src
[1]->num_components
);
2648 switch (src
[0]->num_components
) {
2649 case 1: op
= nir_op_fmul
; break;
2650 case 2: op
= nir_op_fdot2
; break;
2651 case 3: op
= nir_op_fdot3
; break;
2652 case 4: op
= nir_op_fdot4
; break;
2656 case SpvOpShiftRightLogical
: op
= nir_op_ushr
; break;
2657 case SpvOpShiftRightArithmetic
: op
= nir_op_ishr
; break;
2658 case SpvOpShiftLeftLogical
: op
= nir_op_ishl
; break;
2659 case SpvOpLogicalOr
: op
= nir_op_ior
; break;
2660 case SpvOpLogicalEqual
: op
= nir_op_ieq
; break;
2661 case SpvOpLogicalNotEqual
: op
= nir_op_ine
; break;
2662 case SpvOpLogicalAnd
: op
= nir_op_iand
; break;
2663 case SpvOpLogicalNot
: op
= nir_op_inot
; break;
2664 case SpvOpBitwiseOr
: op
= nir_op_ior
; break;
2665 case SpvOpBitwiseXor
: op
= nir_op_ixor
; break;
2666 case SpvOpBitwiseAnd
: op
= nir_op_iand
; break;
2667 case SpvOpSelect
: op
= nir_op_bcsel
; break;
2668 case SpvOpIEqual
: op
= nir_op_ieq
; break;
2670 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
2671 case SpvOpFOrdEqual
: op
= nir_op_feq
; break;
2672 case SpvOpFUnordEqual
: op
= nir_op_feq
; break;
2673 case SpvOpINotEqual
: op
= nir_op_ine
; break;
2674 case SpvOpFOrdNotEqual
: op
= nir_op_fne
; break;
2675 case SpvOpFUnordNotEqual
: op
= nir_op_fne
; break;
2676 case SpvOpULessThan
: op
= nir_op_ult
; break;
2677 case SpvOpSLessThan
: op
= nir_op_ilt
; break;
2678 case SpvOpFOrdLessThan
: op
= nir_op_flt
; break;
2679 case SpvOpFUnordLessThan
: op
= nir_op_flt
; break;
2680 case SpvOpUGreaterThan
: op
= nir_op_ult
; swap
= true; break;
2681 case SpvOpSGreaterThan
: op
= nir_op_ilt
; swap
= true; break;
2682 case SpvOpFOrdGreaterThan
: op
= nir_op_flt
; swap
= true; break;
2683 case SpvOpFUnordGreaterThan
: op
= nir_op_flt
; swap
= true; break;
2684 case SpvOpULessThanEqual
: op
= nir_op_uge
; swap
= true; break;
2685 case SpvOpSLessThanEqual
: op
= nir_op_ige
; swap
= true; break;
2686 case SpvOpFOrdLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
2687 case SpvOpFUnordLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
2688 case SpvOpUGreaterThanEqual
: op
= nir_op_uge
; break;
2689 case SpvOpSGreaterThanEqual
: op
= nir_op_ige
; break;
2690 case SpvOpFOrdGreaterThanEqual
: op
= nir_op_fge
; break;
2691 case SpvOpFUnordGreaterThanEqual
:op
= nir_op_fge
; break;
2694 case SpvOpConvertFToU
: op
= nir_op_f2u
; break;
2695 case SpvOpConvertFToS
: op
= nir_op_f2i
; break;
2696 case SpvOpConvertSToF
: op
= nir_op_i2f
; break;
2697 case SpvOpConvertUToF
: op
= nir_op_u2f
; break;
2698 case SpvOpBitcast
: op
= nir_op_imov
; break;
2701 op
= nir_op_imov
; /* TODO: NIR is 32-bit only; these are no-ops. */
2708 case SpvOpDPdx
: op
= nir_op_fddx
; break;
2709 case SpvOpDPdy
: op
= nir_op_fddy
; break;
2710 case SpvOpDPdxFine
: op
= nir_op_fddx_fine
; break;
2711 case SpvOpDPdyFine
: op
= nir_op_fddy_fine
; break;
2712 case SpvOpDPdxCoarse
: op
= nir_op_fddx_coarse
; break;
2713 case SpvOpDPdyCoarse
: op
= nir_op_fddy_coarse
; break;
2715 val
->ssa
->def
= nir_fadd(&b
->nb
,
2716 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[0])),
2717 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[1])));
2719 case SpvOpFwidthFine
:
2720 val
->ssa
->def
= nir_fadd(&b
->nb
,
2721 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[0])),
2722 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[1])));
2724 case SpvOpFwidthCoarse
:
2725 val
->ssa
->def
= nir_fadd(&b
->nb
,
2726 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[0])),
2727 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[1])));
2730 case SpvOpVectorTimesScalar
:
2731 /* The builder will take care of splatting for us. */
2732 val
->ssa
->def
= nir_fmul(&b
->nb
, src
[0], src
[1]);
2737 unreachable("No NIR equivalent");
2740 val
->ssa
->def
= nir_fne(&b
->nb
, src
[0], src
[0]);
2744 val
->ssa
->def
= nir_feq(&b
->nb
, nir_fabs(&b
->nb
, src
[0]),
2745 nir_imm_float(&b
->nb
, INFINITY
));
2750 case SpvOpSignBitSet
:
2751 case SpvOpLessOrGreater
:
2753 case SpvOpUnordered
:
2755 unreachable("Unhandled opcode");
2759 nir_ssa_def
*tmp
= src
[0];
2764 val
->ssa
->def
= nir_build_alu(&b
->nb
, op
, src
[0], src
[1], src
[2], src
[3]);
2767 static nir_ssa_def
*
2768 vtn_vector_extract(struct vtn_builder
*b
, nir_ssa_def
*src
, unsigned index
)
2770 unsigned swiz
[4] = { index
};
2771 return nir_swizzle(&b
->nb
, src
, swiz
, 1, true);
2775 static nir_ssa_def
*
2776 vtn_vector_insert(struct vtn_builder
*b
, nir_ssa_def
*src
, nir_ssa_def
*insert
,
2779 nir_alu_instr
*vec
= create_vec(b
->shader
, src
->num_components
);
2781 for (unsigned i
= 0; i
< src
->num_components
; i
++) {
2783 vec
->src
[i
].src
= nir_src_for_ssa(insert
);
2785 vec
->src
[i
].src
= nir_src_for_ssa(src
);
2786 vec
->src
[i
].swizzle
[0] = i
;
2790 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2792 return &vec
->dest
.dest
.ssa
;
2795 static nir_ssa_def
*
2796 vtn_vector_extract_dynamic(struct vtn_builder
*b
, nir_ssa_def
*src
,
2799 nir_ssa_def
*dest
= vtn_vector_extract(b
, src
, 0);
2800 for (unsigned i
= 1; i
< src
->num_components
; i
++)
2801 dest
= nir_bcsel(&b
->nb
, nir_ieq(&b
->nb
, index
, nir_imm_int(&b
->nb
, i
)),
2802 vtn_vector_extract(b
, src
, i
), dest
);
2807 static nir_ssa_def
*
2808 vtn_vector_insert_dynamic(struct vtn_builder
*b
, nir_ssa_def
*src
,
2809 nir_ssa_def
*insert
, nir_ssa_def
*index
)
2811 nir_ssa_def
*dest
= vtn_vector_insert(b
, src
, insert
, 0);
2812 for (unsigned i
= 1; i
< src
->num_components
; i
++)
2813 dest
= nir_bcsel(&b
->nb
, nir_ieq(&b
->nb
, index
, nir_imm_int(&b
->nb
, i
)),
2814 vtn_vector_insert(b
, src
, insert
, i
), dest
);
2819 static nir_ssa_def
*
2820 vtn_vector_shuffle(struct vtn_builder
*b
, unsigned num_components
,
2821 nir_ssa_def
*src0
, nir_ssa_def
*src1
,
2822 const uint32_t *indices
)
2824 nir_alu_instr
*vec
= create_vec(b
->shader
, num_components
);
2826 nir_ssa_undef_instr
*undef
= nir_ssa_undef_instr_create(b
->shader
, 1);
2827 nir_builder_instr_insert(&b
->nb
, &undef
->instr
);
2829 for (unsigned i
= 0; i
< num_components
; i
++) {
2830 uint32_t index
= indices
[i
];
2831 if (index
== 0xffffffff) {
2832 vec
->src
[i
].src
= nir_src_for_ssa(&undef
->def
);
2833 } else if (index
< src0
->num_components
) {
2834 vec
->src
[i
].src
= nir_src_for_ssa(src0
);
2835 vec
->src
[i
].swizzle
[0] = index
;
2837 vec
->src
[i
].src
= nir_src_for_ssa(src1
);
2838 vec
->src
[i
].swizzle
[0] = index
- src0
->num_components
;
2842 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2844 return &vec
->dest
.dest
.ssa
;
2848 * Concatentates a number of vectors/scalars together to produce a vector
2850 static nir_ssa_def
*
2851 vtn_vector_construct(struct vtn_builder
*b
, unsigned num_components
,
2852 unsigned num_srcs
, nir_ssa_def
**srcs
)
2854 nir_alu_instr
*vec
= create_vec(b
->shader
, num_components
);
2856 unsigned dest_idx
= 0;
2857 for (unsigned i
= 0; i
< num_srcs
; i
++) {
2858 nir_ssa_def
*src
= srcs
[i
];
2859 for (unsigned j
= 0; j
< src
->num_components
; j
++) {
2860 vec
->src
[dest_idx
].src
= nir_src_for_ssa(src
);
2861 vec
->src
[dest_idx
].swizzle
[0] = j
;
2866 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2868 return &vec
->dest
.dest
.ssa
;
2871 static struct vtn_ssa_value
*
2872 vtn_composite_copy(void *mem_ctx
, struct vtn_ssa_value
*src
)
2874 struct vtn_ssa_value
*dest
= rzalloc(mem_ctx
, struct vtn_ssa_value
);
2875 dest
->type
= src
->type
;
2877 if (glsl_type_is_vector_or_scalar(src
->type
)) {
2878 dest
->def
= src
->def
;
2880 unsigned elems
= glsl_get_length(src
->type
);
2882 dest
->elems
= ralloc_array(mem_ctx
, struct vtn_ssa_value
*, elems
);
2883 for (unsigned i
= 0; i
< elems
; i
++)
2884 dest
->elems
[i
] = vtn_composite_copy(mem_ctx
, src
->elems
[i
]);
2890 static struct vtn_ssa_value
*
2891 vtn_composite_insert(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
2892 struct vtn_ssa_value
*insert
, const uint32_t *indices
,
2893 unsigned num_indices
)
2895 struct vtn_ssa_value
*dest
= vtn_composite_copy(b
, src
);
2897 struct vtn_ssa_value
*cur
= dest
;
2899 for (i
= 0; i
< num_indices
- 1; i
++) {
2900 cur
= cur
->elems
[indices
[i
]];
2903 if (glsl_type_is_vector_or_scalar(cur
->type
)) {
2904 /* According to the SPIR-V spec, OpCompositeInsert may work down to
2905 * the component granularity. In that case, the last index will be
2906 * the index to insert the scalar into the vector.
2909 cur
->def
= vtn_vector_insert(b
, cur
->def
, insert
->def
, indices
[i
]);
2911 cur
->elems
[indices
[i
]] = insert
;
2917 static struct vtn_ssa_value
*
2918 vtn_composite_extract(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
2919 const uint32_t *indices
, unsigned num_indices
)
2921 struct vtn_ssa_value
*cur
= src
;
2922 for (unsigned i
= 0; i
< num_indices
; i
++) {
2923 if (glsl_type_is_vector_or_scalar(cur
->type
)) {
2924 assert(i
== num_indices
- 1);
2925 /* According to the SPIR-V spec, OpCompositeExtract may work down to
2926 * the component granularity. The last index will be the index of the
2927 * vector to extract.
2930 struct vtn_ssa_value
*ret
= rzalloc(b
, struct vtn_ssa_value
);
2931 ret
->type
= glsl_scalar_type(glsl_get_base_type(cur
->type
));
2932 ret
->def
= vtn_vector_extract(b
, cur
->def
, indices
[i
]);
2935 cur
= cur
->elems
[indices
[i
]];
2943 vtn_handle_composite(struct vtn_builder
*b
, SpvOp opcode
,
2944 const uint32_t *w
, unsigned count
)
2946 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2947 const struct glsl_type
*type
=
2948 vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
2949 val
->ssa
= vtn_create_ssa_value(b
, type
);
2952 case SpvOpVectorExtractDynamic
:
2953 val
->ssa
->def
= vtn_vector_extract_dynamic(b
, vtn_ssa_value(b
, w
[3])->def
,
2954 vtn_ssa_value(b
, w
[4])->def
);
2957 case SpvOpVectorInsertDynamic
:
2958 val
->ssa
->def
= vtn_vector_insert_dynamic(b
, vtn_ssa_value(b
, w
[3])->def
,
2959 vtn_ssa_value(b
, w
[4])->def
,
2960 vtn_ssa_value(b
, w
[5])->def
);
2963 case SpvOpVectorShuffle
:
2964 val
->ssa
->def
= vtn_vector_shuffle(b
, glsl_get_vector_elements(type
),
2965 vtn_ssa_value(b
, w
[3])->def
,
2966 vtn_ssa_value(b
, w
[4])->def
,
2970 case SpvOpCompositeConstruct
: {
2971 unsigned elems
= count
- 3;
2972 if (glsl_type_is_vector_or_scalar(type
)) {
2973 nir_ssa_def
*srcs
[4];
2974 for (unsigned i
= 0; i
< elems
; i
++)
2975 srcs
[i
] = vtn_ssa_value(b
, w
[3 + i
])->def
;
2977 vtn_vector_construct(b
, glsl_get_vector_elements(type
),
2980 val
->ssa
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
2981 for (unsigned i
= 0; i
< elems
; i
++)
2982 val
->ssa
->elems
[i
] = vtn_ssa_value(b
, w
[3 + i
]);
2986 case SpvOpCompositeExtract
:
2987 val
->ssa
= vtn_composite_extract(b
, vtn_ssa_value(b
, w
[3]),
2991 case SpvOpCompositeInsert
:
2992 val
->ssa
= vtn_composite_insert(b
, vtn_ssa_value(b
, w
[4]),
2993 vtn_ssa_value(b
, w
[3]),
2997 case SpvOpCopyObject
:
2998 val
->ssa
= vtn_composite_copy(b
, vtn_ssa_value(b
, w
[3]));
3002 unreachable("unknown composite operation");
3007 vtn_handle_barrier(struct vtn_builder
*b
, SpvOp opcode
,
3008 const uint32_t *w
, unsigned count
)
3010 nir_intrinsic_op intrinsic_op
;
3012 case SpvOpEmitVertex
:
3013 case SpvOpEmitStreamVertex
:
3014 intrinsic_op
= nir_intrinsic_emit_vertex
;
3016 case SpvOpEndPrimitive
:
3017 case SpvOpEndStreamPrimitive
:
3018 intrinsic_op
= nir_intrinsic_end_primitive
;
3020 case SpvOpMemoryBarrier
:
3021 intrinsic_op
= nir_intrinsic_memory_barrier
;
3023 case SpvOpControlBarrier
:
3025 unreachable("unknown barrier instruction");
3028 nir_intrinsic_instr
*intrin
=
3029 nir_intrinsic_instr_create(b
->shader
, intrinsic_op
);
3031 if (opcode
== SpvOpEmitStreamVertex
|| opcode
== SpvOpEndStreamPrimitive
)
3032 intrin
->const_index
[0] = w
[1];
3034 nir_builder_instr_insert(&b
->nb
, &intrin
->instr
);
3038 vtn_phi_node_init(struct vtn_builder
*b
, struct vtn_ssa_value
*val
)
3040 if (glsl_type_is_vector_or_scalar(val
->type
)) {
3041 nir_phi_instr
*phi
= nir_phi_instr_create(b
->shader
);
3042 nir_ssa_dest_init(&phi
->instr
, &phi
->dest
,
3043 glsl_get_vector_elements(val
->type
), NULL
);
3044 exec_list_make_empty(&phi
->srcs
);
3045 nir_builder_instr_insert(&b
->nb
, &phi
->instr
);
3046 val
->def
= &phi
->dest
.ssa
;
3048 unsigned elems
= glsl_get_length(val
->type
);
3049 for (unsigned i
= 0; i
< elems
; i
++)
3050 vtn_phi_node_init(b
, val
->elems
[i
]);
3054 static struct vtn_ssa_value
*
3055 vtn_phi_node_create(struct vtn_builder
*b
, const struct glsl_type
*type
)
3057 struct vtn_ssa_value
*val
= vtn_create_ssa_value(b
, type
);
3058 vtn_phi_node_init(b
, val
);
3063 vtn_handle_phi_first_pass(struct vtn_builder
*b
, const uint32_t *w
)
3065 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
3066 const struct glsl_type
*type
=
3067 vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
3068 val
->ssa
= vtn_phi_node_create(b
, type
);
3072 vtn_phi_node_add_src(struct vtn_ssa_value
*phi
, const nir_block
*pred
,
3073 struct vtn_ssa_value
*val
)
3075 assert(phi
->type
== val
->type
);
3076 if (glsl_type_is_vector_or_scalar(phi
->type
)) {
3077 nir_phi_instr
*phi_instr
= nir_instr_as_phi(phi
->def
->parent_instr
);
3078 nir_phi_src
*src
= ralloc(phi_instr
, nir_phi_src
);
3079 src
->pred
= (nir_block
*) pred
;
3080 src
->src
= NIR_SRC_INIT
;
3081 exec_list_push_tail(&phi_instr
->srcs
, &src
->node
);
3082 nir_instr_rewrite_src(&phi_instr
->instr
, &src
->src
,
3083 nir_src_for_ssa(val
->def
));
3085 unsigned elems
= glsl_get_length(phi
->type
);
3086 for (unsigned i
= 0; i
< elems
; i
++)
3087 vtn_phi_node_add_src(phi
->elems
[i
], pred
, val
->elems
[i
]);
3091 static struct vtn_ssa_value
*
3092 vtn_get_phi_node_src(struct vtn_builder
*b
, nir_block
*block
,
3093 const struct glsl_type
*type
, const uint32_t *w
,
3096 struct hash_entry
*entry
= _mesa_hash_table_search(b
->block_table
, block
);
3098 struct vtn_block
*spv_block
= entry
->data
;
3099 for (unsigned off
= 4; off
< count
; off
+= 2) {
3100 if (spv_block
== vtn_value(b
, w
[off
], vtn_value_type_block
)->block
) {
3101 return vtn_ssa_value(b
, w
[off
- 1]);
3106 b
->nb
.cursor
= nir_before_block(block
);
3107 struct vtn_ssa_value
*phi
= vtn_phi_node_create(b
, type
);
3109 struct set_entry
*entry2
;
3110 set_foreach(block
->predecessors
, entry2
) {
3111 nir_block
*pred
= (nir_block
*) entry2
->key
;
3112 struct vtn_ssa_value
*val
= vtn_get_phi_node_src(b
, pred
, type
, w
,
3114 vtn_phi_node_add_src(phi
, pred
, val
);
3121 vtn_handle_phi_second_pass(struct vtn_builder
*b
, SpvOp opcode
,
3122 const uint32_t *w
, unsigned count
)
3124 if (opcode
== SpvOpLabel
) {
3125 b
->block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
3129 if (opcode
!= SpvOpPhi
)
3132 struct vtn_ssa_value
*phi
= vtn_value(b
, w
[2], vtn_value_type_ssa
)->ssa
;
3134 struct set_entry
*entry
;
3135 set_foreach(b
->block
->block
->predecessors
, entry
) {
3136 nir_block
*pred
= (nir_block
*) entry
->key
;
3138 struct vtn_ssa_value
*val
= vtn_get_phi_node_src(b
, pred
, phi
->type
, w
,
3140 vtn_phi_node_add_src(phi
, pred
, val
);
3147 gl_primitive_from_spv_execution_mode(SpvExecutionMode mode
)
3150 case SpvExecutionModeInputPoints
:
3151 case SpvExecutionModeOutputPoints
:
3152 return 0; /* GL_POINTS */
3153 case SpvExecutionModeInputLines
:
3154 return 1; /* GL_LINES */
3155 case SpvExecutionModeInputLinesAdjacency
:
3156 return 0x000A; /* GL_LINE_STRIP_ADJACENCY_ARB */
3157 case SpvExecutionModeTriangles
:
3158 return 4; /* GL_TRIANGLES */
3159 case SpvExecutionModeInputTrianglesAdjacency
:
3160 return 0x000C; /* GL_TRIANGLES_ADJACENCY_ARB */
3161 case SpvExecutionModeQuads
:
3162 return 7; /* GL_QUADS */
3163 case SpvExecutionModeIsolines
:
3164 return 0x8E7A; /* GL_ISOLINES */
3165 case SpvExecutionModeOutputLineStrip
:
3166 return 3; /* GL_LINE_STRIP */
3167 case SpvExecutionModeOutputTriangleStrip
:
3168 return 5; /* GL_TRIANGLE_STRIP */
3170 assert(!"Invalid primitive type");
3176 vertices_in_from_spv_execution_mode(SpvExecutionMode mode
)
3179 case SpvExecutionModeInputPoints
:
3181 case SpvExecutionModeInputLines
:
3183 case SpvExecutionModeInputLinesAdjacency
:
3185 case SpvExecutionModeTriangles
:
3187 case SpvExecutionModeInputTrianglesAdjacency
:
3190 assert(!"Invalid GS input mode");
3196 vtn_handle_preamble_instruction(struct vtn_builder
*b
, SpvOp opcode
,
3197 const uint32_t *w
, unsigned count
)
3201 case SpvOpSourceExtension
:
3202 case SpvOpExtension
:
3203 /* Unhandled, but these are for debug so that's ok. */
3206 case SpvOpCapability
:
3207 switch ((SpvCapability
)w
[1]) {
3208 case SpvCapabilityMatrix
:
3209 case SpvCapabilityShader
:
3210 case SpvCapabilityGeometry
:
3213 assert(!"Unsupported capability");
3217 case SpvOpExtInstImport
:
3218 vtn_handle_extension(b
, opcode
, w
, count
);
3221 case SpvOpMemoryModel
:
3222 assert(w
[1] == SpvAddressingModelLogical
);
3223 assert(w
[2] == SpvMemoryModelGLSL450
);
3226 case SpvOpEntryPoint
:
3227 /* Let this be a name label regardless */
3228 b
->values
[w
[2]].name
= vtn_string_literal(b
, &w
[3], count
- 3);
3230 if (strcmp(b
->values
[w
[2]].name
, b
->entry_point_name
) != 0)
3233 assert(b
->entry_point
== NULL
);
3234 b
->entry_point
= &b
->values
[w
[2]];
3235 b
->execution_model
= w
[1];
3239 vtn_push_value(b
, w
[1], vtn_value_type_string
)->str
=
3240 vtn_string_literal(b
, &w
[2], count
- 2);
3244 b
->values
[w
[1]].name
= vtn_string_literal(b
, &w
[2], count
- 2);
3247 case SpvOpMemberName
:
3252 break; /* Ignored for now */
3254 case SpvOpExecutionMode
:
3255 case SpvOpDecorationGroup
:
3257 case SpvOpMemberDecorate
:
3258 case SpvOpGroupDecorate
:
3259 case SpvOpGroupMemberDecorate
:
3260 vtn_handle_decoration(b
, opcode
, w
, count
);
3264 return false; /* End of preamble */
3271 vtn_handle_execution_mode(struct vtn_builder
*b
, struct vtn_value
*entry_point
,
3272 const struct vtn_decoration
*mode
, void *data
)
3274 assert(b
->entry_point
== entry_point
);
3276 switch(mode
->exec_mode
) {
3277 case SpvExecutionModeOriginUpperLeft
:
3278 case SpvExecutionModeOriginLowerLeft
:
3279 b
->origin_upper_left
=
3280 (mode
->exec_mode
== SpvExecutionModeOriginUpperLeft
);
3283 case SpvExecutionModeEarlyFragmentTests
:
3284 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3285 b
->shader
->info
.fs
.early_fragment_tests
= true;
3288 case SpvExecutionModeInvocations
:
3289 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
3290 b
->shader
->info
.gs
.invocations
= MAX2(1, mode
->literals
[0]);
3293 case SpvExecutionModeDepthReplacing
:
3294 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3295 b
->shader
->info
.fs
.depth_layout
= FRAG_DEPTH_LAYOUT_ANY
;
3297 case SpvExecutionModeDepthGreater
:
3298 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3299 b
->shader
->info
.fs
.depth_layout
= FRAG_DEPTH_LAYOUT_GREATER
;
3301 case SpvExecutionModeDepthLess
:
3302 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3303 b
->shader
->info
.fs
.depth_layout
= FRAG_DEPTH_LAYOUT_LESS
;
3305 case SpvExecutionModeDepthUnchanged
:
3306 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3307 b
->shader
->info
.fs
.depth_layout
= FRAG_DEPTH_LAYOUT_UNCHANGED
;
3310 case SpvExecutionModeLocalSize
:
3311 assert(b
->shader
->stage
== MESA_SHADER_COMPUTE
);
3312 b
->shader
->info
.cs
.local_size
[0] = mode
->literals
[0];
3313 b
->shader
->info
.cs
.local_size
[1] = mode
->literals
[1];
3314 b
->shader
->info
.cs
.local_size
[2] = mode
->literals
[2];
3316 case SpvExecutionModeLocalSizeHint
:
3317 break; /* Nothing do do with this */
3319 case SpvExecutionModeOutputVertices
:
3320 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
3321 b
->shader
->info
.gs
.vertices_out
= mode
->literals
[0];
3324 case SpvExecutionModeInputPoints
:
3325 case SpvExecutionModeInputLines
:
3326 case SpvExecutionModeInputLinesAdjacency
:
3327 case SpvExecutionModeTriangles
:
3328 case SpvExecutionModeInputTrianglesAdjacency
:
3329 case SpvExecutionModeQuads
:
3330 case SpvExecutionModeIsolines
:
3331 if (b
->shader
->stage
== MESA_SHADER_GEOMETRY
) {
3332 b
->shader
->info
.gs
.vertices_in
=
3333 vertices_in_from_spv_execution_mode(mode
->exec_mode
);
3335 assert(!"Tesselation shaders not yet supported");
3339 case SpvExecutionModeOutputPoints
:
3340 case SpvExecutionModeOutputLineStrip
:
3341 case SpvExecutionModeOutputTriangleStrip
:
3342 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
3343 b
->shader
->info
.gs
.output_primitive
=
3344 gl_primitive_from_spv_execution_mode(mode
->exec_mode
);
3347 case SpvExecutionModeSpacingEqual
:
3348 case SpvExecutionModeSpacingFractionalEven
:
3349 case SpvExecutionModeSpacingFractionalOdd
:
3350 case SpvExecutionModeVertexOrderCw
:
3351 case SpvExecutionModeVertexOrderCcw
:
3352 case SpvExecutionModePointMode
:
3353 assert(!"TODO: Add tessellation metadata");
3356 case SpvExecutionModePixelCenterInteger
:
3357 case SpvExecutionModeXfb
:
3358 assert(!"Unhandled execution mode");
3361 case SpvExecutionModeVecTypeHint
:
3362 case SpvExecutionModeContractionOff
:
3368 vtn_handle_variable_or_type_instruction(struct vtn_builder
*b
, SpvOp opcode
,
3369 const uint32_t *w
, unsigned count
)
3373 case SpvOpSourceExtension
:
3374 case SpvOpExtension
:
3375 case SpvOpCapability
:
3376 case SpvOpExtInstImport
:
3377 case SpvOpMemoryModel
:
3378 case SpvOpEntryPoint
:
3379 case SpvOpExecutionMode
:
3382 case SpvOpMemberName
:
3384 case SpvOpDecorationGroup
:
3386 case SpvOpMemberDecorate
:
3387 case SpvOpGroupDecorate
:
3388 case SpvOpGroupMemberDecorate
:
3389 assert(!"Invalid opcode types and variables section");
3395 case SpvOpTypeFloat
:
3396 case SpvOpTypeVector
:
3397 case SpvOpTypeMatrix
:
3398 case SpvOpTypeImage
:
3399 case SpvOpTypeSampler
:
3400 case SpvOpTypeSampledImage
:
3401 case SpvOpTypeArray
:
3402 case SpvOpTypeRuntimeArray
:
3403 case SpvOpTypeStruct
:
3404 case SpvOpTypeOpaque
:
3405 case SpvOpTypePointer
:
3406 case SpvOpTypeFunction
:
3407 case SpvOpTypeEvent
:
3408 case SpvOpTypeDeviceEvent
:
3409 case SpvOpTypeReserveId
:
3410 case SpvOpTypeQueue
:
3412 vtn_handle_type(b
, opcode
, w
, count
);
3415 case SpvOpConstantTrue
:
3416 case SpvOpConstantFalse
:
3418 case SpvOpConstantComposite
:
3419 case SpvOpConstantSampler
:
3420 case SpvOpSpecConstantTrue
:
3421 case SpvOpSpecConstantFalse
:
3422 case SpvOpSpecConstant
:
3423 case SpvOpSpecConstantComposite
:
3424 vtn_handle_constant(b
, opcode
, w
, count
);
3428 vtn_handle_variables(b
, opcode
, w
, count
);
3432 return false; /* End of preamble */
3439 vtn_handle_body_instruction(struct vtn_builder
*b
, SpvOp opcode
,
3440 const uint32_t *w
, unsigned count
)
3444 struct vtn_block
*block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
3445 assert(block
->block
== nir_cursor_current_block(b
->nb
.cursor
));
3449 case SpvOpLoopMerge
:
3450 case SpvOpSelectionMerge
:
3451 /* This is handled by cfg pre-pass and walk_blocks */
3455 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_undef
);
3456 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
3461 vtn_handle_extension(b
, opcode
, w
, count
);
3467 case SpvOpCopyMemory
:
3468 case SpvOpCopyMemorySized
:
3469 case SpvOpAccessChain
:
3470 case SpvOpInBoundsAccessChain
:
3471 case SpvOpArrayLength
:
3472 vtn_handle_variables(b
, opcode
, w
, count
);
3475 case SpvOpFunctionCall
:
3476 vtn_handle_function_call(b
, opcode
, w
, count
);
3479 case SpvOpSampledImage
:
3480 case SpvOpImageSampleImplicitLod
:
3481 case SpvOpImageSampleExplicitLod
:
3482 case SpvOpImageSampleDrefImplicitLod
:
3483 case SpvOpImageSampleDrefExplicitLod
:
3484 case SpvOpImageSampleProjImplicitLod
:
3485 case SpvOpImageSampleProjExplicitLod
:
3486 case SpvOpImageSampleProjDrefImplicitLod
:
3487 case SpvOpImageSampleProjDrefExplicitLod
:
3488 case SpvOpImageFetch
:
3489 case SpvOpImageGather
:
3490 case SpvOpImageDrefGather
:
3491 case SpvOpImageQuerySizeLod
:
3492 case SpvOpImageQuerySize
:
3493 case SpvOpImageQueryLod
:
3494 case SpvOpImageQueryLevels
:
3495 case SpvOpImageQuerySamples
:
3496 vtn_handle_texture(b
, opcode
, w
, count
);
3499 case SpvOpImageRead
:
3500 case SpvOpImageWrite
:
3501 case SpvOpImageTexelPointer
:
3502 vtn_handle_image(b
, opcode
, w
, count
);
3505 case SpvOpAtomicExchange
:
3506 case SpvOpAtomicCompareExchange
:
3507 case SpvOpAtomicCompareExchangeWeak
:
3508 case SpvOpAtomicIIncrement
:
3509 case SpvOpAtomicIDecrement
:
3510 case SpvOpAtomicIAdd
:
3511 case SpvOpAtomicISub
:
3512 case SpvOpAtomicSMin
:
3513 case SpvOpAtomicUMin
:
3514 case SpvOpAtomicSMax
:
3515 case SpvOpAtomicUMax
:
3516 case SpvOpAtomicAnd
:
3518 case SpvOpAtomicXor
: {
3519 struct vtn_value
*pointer
= vtn_untyped_value(b
, w
[3]);
3520 if (pointer
->value_type
== vtn_value_type_image_pointer
) {
3521 vtn_handle_image(b
, opcode
, w
, count
);
3523 assert(!"Atomic buffers not yet implemented");
3532 case SpvOpConvertFToU
:
3533 case SpvOpConvertFToS
:
3534 case SpvOpConvertSToF
:
3535 case SpvOpConvertUToF
:
3539 case SpvOpConvertPtrToU
:
3540 case SpvOpConvertUToPtr
:
3541 case SpvOpPtrCastToGeneric
:
3542 case SpvOpGenericCastToPtr
:
3548 case SpvOpSignBitSet
:
3549 case SpvOpLessOrGreater
:
3551 case SpvOpUnordered
:
3566 case SpvOpVectorTimesScalar
:
3568 case SpvOpShiftRightLogical
:
3569 case SpvOpShiftRightArithmetic
:
3570 case SpvOpShiftLeftLogical
:
3571 case SpvOpLogicalEqual
:
3572 case SpvOpLogicalNotEqual
:
3573 case SpvOpLogicalOr
:
3574 case SpvOpLogicalAnd
:
3575 case SpvOpLogicalNot
:
3576 case SpvOpBitwiseOr
:
3577 case SpvOpBitwiseXor
:
3578 case SpvOpBitwiseAnd
:
3581 case SpvOpFOrdEqual
:
3582 case SpvOpFUnordEqual
:
3583 case SpvOpINotEqual
:
3584 case SpvOpFOrdNotEqual
:
3585 case SpvOpFUnordNotEqual
:
3586 case SpvOpULessThan
:
3587 case SpvOpSLessThan
:
3588 case SpvOpFOrdLessThan
:
3589 case SpvOpFUnordLessThan
:
3590 case SpvOpUGreaterThan
:
3591 case SpvOpSGreaterThan
:
3592 case SpvOpFOrdGreaterThan
:
3593 case SpvOpFUnordGreaterThan
:
3594 case SpvOpULessThanEqual
:
3595 case SpvOpSLessThanEqual
:
3596 case SpvOpFOrdLessThanEqual
:
3597 case SpvOpFUnordLessThanEqual
:
3598 case SpvOpUGreaterThanEqual
:
3599 case SpvOpSGreaterThanEqual
:
3600 case SpvOpFOrdGreaterThanEqual
:
3601 case SpvOpFUnordGreaterThanEqual
:
3607 case SpvOpFwidthFine
:
3608 case SpvOpDPdxCoarse
:
3609 case SpvOpDPdyCoarse
:
3610 case SpvOpFwidthCoarse
:
3611 vtn_handle_alu(b
, opcode
, w
, count
);
3614 case SpvOpTranspose
:
3615 case SpvOpOuterProduct
:
3616 case SpvOpMatrixTimesScalar
:
3617 case SpvOpVectorTimesMatrix
:
3618 case SpvOpMatrixTimesVector
:
3619 case SpvOpMatrixTimesMatrix
:
3620 vtn_handle_matrix_alu(b
, opcode
, w
, count
);
3623 case SpvOpVectorExtractDynamic
:
3624 case SpvOpVectorInsertDynamic
:
3625 case SpvOpVectorShuffle
:
3626 case SpvOpCompositeConstruct
:
3627 case SpvOpCompositeExtract
:
3628 case SpvOpCompositeInsert
:
3629 case SpvOpCopyObject
:
3630 vtn_handle_composite(b
, opcode
, w
, count
);
3634 vtn_handle_phi_first_pass(b
, w
);
3637 case SpvOpEmitVertex
:
3638 case SpvOpEndPrimitive
:
3639 case SpvOpEmitStreamVertex
:
3640 case SpvOpEndStreamPrimitive
:
3641 case SpvOpControlBarrier
:
3642 case SpvOpMemoryBarrier
:
3643 vtn_handle_barrier(b
, opcode
, w
, count
);
3647 unreachable("Unhandled opcode");
3653 static gl_shader_stage
3654 stage_for_execution_model(SpvExecutionModel model
)
3657 case SpvExecutionModelVertex
:
3658 return MESA_SHADER_VERTEX
;
3659 case SpvExecutionModelTessellationControl
:
3660 return MESA_SHADER_TESS_CTRL
;
3661 case SpvExecutionModelTessellationEvaluation
:
3662 return MESA_SHADER_TESS_EVAL
;
3663 case SpvExecutionModelGeometry
:
3664 return MESA_SHADER_GEOMETRY
;
3665 case SpvExecutionModelFragment
:
3666 return MESA_SHADER_FRAGMENT
;
3667 case SpvExecutionModelGLCompute
:
3668 return MESA_SHADER_COMPUTE
;
3670 unreachable("Unsupported execution model");
3675 spirv_to_nir(const uint32_t *words
, size_t word_count
,
3676 const char *entry_point_name
,
3677 const nir_shader_compiler_options
*options
)
3679 const uint32_t *word_end
= words
+ word_count
;
3681 /* Handle the SPIR-V header (first 4 dwords) */
3682 assert(word_count
> 5);
3684 assert(words
[0] == SpvMagicNumber
);
3685 assert(words
[1] >= 0x10000);
3686 /* words[2] == generator magic */
3687 unsigned value_id_bound
= words
[3];
3688 assert(words
[4] == 0);
3692 /* Initialize the stn_builder object */
3693 struct vtn_builder
*b
= rzalloc(NULL
, struct vtn_builder
);
3694 b
->value_id_bound
= value_id_bound
;
3695 b
->values
= rzalloc_array(b
, struct vtn_value
, value_id_bound
);
3696 exec_list_make_empty(&b
->functions
);
3697 b
->entry_point_name
= entry_point_name
;
3699 /* Handle all the preamble instructions */
3700 words
= vtn_foreach_instruction(b
, words
, word_end
,
3701 vtn_handle_preamble_instruction
);
3703 if (b
->entry_point
== NULL
) {
3704 assert(!"Entry point not found");
3709 gl_shader_stage stage
= stage_for_execution_model(b
->execution_model
);
3710 b
->shader
= nir_shader_create(NULL
, stage
, options
);
3712 /* Parse execution modes */
3713 vtn_foreach_execution_mode(b
, b
->entry_point
,
3714 vtn_handle_execution_mode
, NULL
);
3716 /* Handle all variable, type, and constant instructions */
3717 words
= vtn_foreach_instruction(b
, words
, word_end
,
3718 vtn_handle_variable_or_type_instruction
);
3720 vtn_build_cfg(b
, words
, word_end
);
3722 foreach_list_typed(struct vtn_function
, func
, node
, &b
->functions
) {
3723 b
->impl
= func
->impl
;
3724 b
->const_table
= _mesa_hash_table_create(b
, _mesa_hash_pointer
,
3725 _mesa_key_pointer_equal
);
3726 b
->block_table
= _mesa_hash_table_create(b
, _mesa_hash_pointer
,
3727 _mesa_key_pointer_equal
);
3728 vtn_function_emit(b
, func
, vtn_handle_body_instruction
);
3729 vtn_foreach_instruction(b
, func
->start_block
->label
, func
->end
,
3730 vtn_handle_phi_second_pass
);
3733 assert(b
->entry_point
->value_type
== vtn_value_type_function
);
3734 nir_function
*entry_point
= b
->entry_point
->func
->impl
->function
;
3735 assert(entry_point
);
3739 /* Because we can still have output reads in NIR, we need to lower
3740 * outputs to temporaries before we are truely finished.
3742 nir_lower_outputs_to_temporaries(entry_point
->shader
, entry_point
);