• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 Collabora Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "nir_to_spirv.h"
25 #include "spirv_builder.h"
26 
27 #include "nir.h"
28 #include "pipe/p_state.h"
29 #include "util/u_math.h"
30 #include "util/u_memory.h"
31 #include "util/hash_table.h"
32 
33 #define SLOT_UNSET ((unsigned char) -1)
34 
35 struct ntv_context {
36    void *mem_ctx;
37 
38    /* SPIR-V 1.4 and later requires entrypoints to list all global
39     * variables in the interface.
40     */
41    bool spirv_1_4_interfaces;
42 
43    bool explicit_lod; //whether to set lod=0 for texture()
44 
45    struct spirv_builder builder;
46    nir_shader *nir;
47 
48    struct hash_table *glsl_types;
49    struct hash_table *bo_struct_types;
50    struct hash_table *bo_array_types;
51 
52    SpvId GLSL_std_450;
53 
54    gl_shader_stage stage;
55    const struct zink_shader_info *sinfo;
56 
57    SpvId ubos[2][5]; //8, 16, 32, unused, 64
58    nir_variable *ubo_vars[2];
59 
60    SpvId ssbos[5]; //8, 16, 32, unused, 64
61    nir_variable *ssbo_vars;
62    SpvId image_types[PIPE_MAX_SAMPLERS];
63    SpvId images[PIPE_MAX_SAMPLERS];
64    SpvId sampler_types[PIPE_MAX_SAMPLERS];
65    SpvId samplers[PIPE_MAX_SAMPLERS];
66    unsigned char sampler_array_sizes[PIPE_MAX_SAMPLERS];
67    unsigned samplers_used : PIPE_MAX_SAMPLERS;
68    SpvId entry_ifaces[PIPE_MAX_SHADER_INPUTS * 4 + PIPE_MAX_SHADER_OUTPUTS * 4];
69    size_t num_entry_ifaces;
70 
71    SpvId *defs;
72    SpvId *resident_defs;
73    size_t num_defs;
74 
75    SpvId *regs;
76    size_t num_regs;
77 
78    struct hash_table *vars; /* nir_variable -> SpvId */
79    struct hash_table *image_vars; /* SpvId -> nir_variable */
80    struct hash_table *so_outputs; /* pipe_stream_output -> SpvId */
81    unsigned outputs[VARYING_SLOT_MAX * 4];
82    const struct glsl_type *so_output_gl_types[VARYING_SLOT_MAX * 4];
83    SpvId so_output_types[VARYING_SLOT_MAX * 4];
84 
85    const SpvId *block_ids;
86    size_t num_blocks;
87    bool block_started;
88    SpvId loop_break, loop_cont;
89 
90    SpvId front_face_var, instance_id_var, vertex_id_var,
91          primitive_id_var, invocation_id_var, // geometry
92          sample_mask_type, sample_id_var, sample_pos_var, sample_mask_in_var,
93          tess_patch_vertices_in, tess_coord_var, // tess
94          push_const_var,
95          workgroup_id_var, num_workgroups_var,
96          local_invocation_id_var, global_invocation_id_var,
97          local_invocation_index_var, helper_invocation_var,
98          local_group_size_var,
99          shared_block_var,
100          base_vertex_var, base_instance_var, draw_id_var;
101 
102    SpvId subgroup_eq_mask_var,
103          subgroup_ge_mask_var,
104          subgroup_gt_mask_var,
105          subgroup_id_var,
106          subgroup_invocation_var,
107          subgroup_le_mask_var,
108          subgroup_lt_mask_var,
109          subgroup_size_var;
110 
111    SpvId discard_func;
112 };
113 
114 static SpvId
115 get_fvec_constant(struct ntv_context *ctx, unsigned bit_size,
116                   unsigned num_components, double value);
117 
118 static SpvId
119 get_ivec_constant(struct ntv_context *ctx, unsigned bit_size,
120                   unsigned num_components, int64_t value);
121 
122 static SpvId
123 emit_unop(struct ntv_context *ctx, SpvOp op, SpvId type, SpvId src);
124 
125 static SpvId
126 emit_binop(struct ntv_context *ctx, SpvOp op, SpvId type,
127            SpvId src0, SpvId src1);
128 
129 static SpvId
130 emit_triop(struct ntv_context *ctx, SpvOp op, SpvId type,
131            SpvId src0, SpvId src1, SpvId src2);
132 
133 static SpvId
get_bvec_type(struct ntv_context * ctx,int num_components)134 get_bvec_type(struct ntv_context *ctx, int num_components)
135 {
136    SpvId bool_type = spirv_builder_type_bool(&ctx->builder);
137    if (num_components > 1)
138       return spirv_builder_type_vector(&ctx->builder, bool_type,
139                                        num_components);
140 
141    assert(num_components == 1);
142    return bool_type;
143 }
144 
145 static SpvScope
get_scope(nir_scope scope)146 get_scope(nir_scope scope)
147 {
148    SpvScope conv[] = {
149       [NIR_SCOPE_NONE] = 0,
150       [NIR_SCOPE_INVOCATION] = SpvScopeInvocation,
151       [NIR_SCOPE_SUBGROUP] = SpvScopeSubgroup,
152       [NIR_SCOPE_SHADER_CALL] = SpvScopeShaderCallKHR,
153       [NIR_SCOPE_WORKGROUP] = SpvScopeWorkgroup,
154       [NIR_SCOPE_QUEUE_FAMILY] = SpvScopeQueueFamily,
155       [NIR_SCOPE_DEVICE] = SpvScopeDevice,
156    };
157    return conv[scope];
158 }
159 
160 static SpvId
block_label(struct ntv_context * ctx,nir_block * block)161 block_label(struct ntv_context *ctx, nir_block *block)
162 {
163    assert(block->index < ctx->num_blocks);
164    return ctx->block_ids[block->index];
165 }
166 
167 static void
emit_access_decorations(struct ntv_context * ctx,nir_variable * var,SpvId var_id)168 emit_access_decorations(struct ntv_context *ctx, nir_variable *var, SpvId var_id)
169 {
170     u_foreach_bit(bit, var->data.access) {
171        switch (1 << bit) {
172        case ACCESS_COHERENT:
173           /* SpvDecorationCoherent can't be used with vulkan memory model */
174           break;
175        case ACCESS_RESTRICT:
176           spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationRestrict);
177           break;
178        case ACCESS_VOLATILE:
179           /* SpvDecorationVolatile can't be used with vulkan memory model */
180           break;
181        case ACCESS_NON_READABLE:
182           spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationNonReadable);
183           break;
184        case ACCESS_NON_WRITEABLE:
185           spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationNonWritable);
186           break;
187        case ACCESS_NON_UNIFORM:
188           spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationNonUniform);
189           break;
190        case ACCESS_CAN_REORDER:
191        case ACCESS_STREAM_CACHE_POLICY:
192           /* no equivalent */
193           break;
194        default:
195           unreachable("unknown access bit");
196        }
197     }
198     /* The Simple, GLSL, and Vulkan memory models can assume that aliasing is generally
199      * not present between the memory object declarations. Specifically, the consumer
200      * is free to assume aliasing is not present between memory object declarations,
201      * unless the memory object declarations explicitly indicate they alias.
202      * ...
203      * Applying Restrict is allowed, but has no effect.
204      * ...
205      * Only those memory object declarations decorated with Aliased or AliasedPointer may alias each other.
206      *
207      * - SPIRV 2.18.2 Aliasing
208      *
209      * thus if the variable isn't marked restrict, assume it may alias
210      */
211     if (!(var->data.access & ACCESS_RESTRICT))
212        spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationAliased);
213 }
214 
215 static SpvOp
get_atomic_op(nir_intrinsic_op op)216 get_atomic_op(nir_intrinsic_op op)
217 {
218    switch (op) {
219 #define CASE_ATOMIC_OP(type) \
220    case nir_intrinsic_deref_atomic_##type: \
221    case nir_intrinsic_image_deref_atomic_##type: \
222    case nir_intrinsic_shared_atomic_##type
223 
224    CASE_ATOMIC_OP(add):
225       return SpvOpAtomicIAdd;
226    CASE_ATOMIC_OP(umin):
227       return SpvOpAtomicUMin;
228    CASE_ATOMIC_OP(imin):
229       return SpvOpAtomicSMin;
230    CASE_ATOMIC_OP(umax):
231       return SpvOpAtomicUMax;
232    CASE_ATOMIC_OP(imax):
233       return SpvOpAtomicSMax;
234    CASE_ATOMIC_OP(and):
235       return SpvOpAtomicAnd;
236    CASE_ATOMIC_OP(or):
237       return SpvOpAtomicOr;
238    CASE_ATOMIC_OP(xor):
239       return SpvOpAtomicXor;
240    CASE_ATOMIC_OP(exchange):
241       return SpvOpAtomicExchange;
242    CASE_ATOMIC_OP(comp_swap):
243       return SpvOpAtomicCompareExchange;
244    default:
245       debug_printf("%s - ", nir_intrinsic_infos[op].name);
246       unreachable("unhandled atomic op");
247    }
248    return 0;
249 }
250 #undef CASE_ATOMIC_OP
251 static SpvId
emit_float_const(struct ntv_context * ctx,int bit_size,double value)252 emit_float_const(struct ntv_context *ctx, int bit_size, double value)
253 {
254    assert(bit_size == 16 || bit_size == 32 || bit_size == 64);
255    return spirv_builder_const_float(&ctx->builder, bit_size, value);
256 }
257 
258 static SpvId
emit_uint_const(struct ntv_context * ctx,int bit_size,uint64_t value)259 emit_uint_const(struct ntv_context *ctx, int bit_size, uint64_t value)
260 {
261    assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
262    return spirv_builder_const_uint(&ctx->builder, bit_size, value);
263 }
264 
265 static SpvId
emit_int_const(struct ntv_context * ctx,int bit_size,int64_t value)266 emit_int_const(struct ntv_context *ctx, int bit_size, int64_t value)
267 {
268    assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
269    return spirv_builder_const_int(&ctx->builder, bit_size, value);
270 }
271 
272 static SpvId
get_fvec_type(struct ntv_context * ctx,unsigned bit_size,unsigned num_components)273 get_fvec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
274 {
275    assert(bit_size == 16 || bit_size == 32 || bit_size == 64);
276 
277    SpvId float_type = spirv_builder_type_float(&ctx->builder, bit_size);
278    if (num_components > 1)
279       return spirv_builder_type_vector(&ctx->builder, float_type,
280                                        num_components);
281 
282    assert(num_components == 1);
283    return float_type;
284 }
285 
286 static SpvId
get_ivec_type(struct ntv_context * ctx,unsigned bit_size,unsigned num_components)287 get_ivec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
288 {
289    assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
290 
291    SpvId int_type = spirv_builder_type_int(&ctx->builder, bit_size);
292    if (num_components > 1)
293       return spirv_builder_type_vector(&ctx->builder, int_type,
294                                        num_components);
295 
296    assert(num_components == 1);
297    return int_type;
298 }
299 
300 static SpvId
get_uvec_type(struct ntv_context * ctx,unsigned bit_size,unsigned num_components)301 get_uvec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
302 {
303    assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
304 
305    SpvId uint_type = spirv_builder_type_uint(&ctx->builder, bit_size);
306    if (num_components > 1)
307       return spirv_builder_type_vector(&ctx->builder, uint_type,
308                                        num_components);
309 
310    assert(num_components == 1);
311    return uint_type;
312 }
313 
314 static SpvStorageClass
get_storage_class(struct nir_variable * var)315 get_storage_class(struct nir_variable *var)
316 {
317    switch (var->data.mode) {
318    case nir_var_function_temp:
319       return SpvStorageClassFunction;
320    case nir_var_mem_push_const:
321       return SpvStorageClassPushConstant;
322    case nir_var_shader_in:
323       return SpvStorageClassInput;
324    case nir_var_shader_out:
325       return SpvStorageClassOutput;
326    case nir_var_uniform:
327    case nir_var_image:
328       return SpvStorageClassUniformConstant;
329    case nir_var_mem_ubo:
330       return SpvStorageClassUniform;
331    case nir_var_mem_ssbo:
332       return SpvStorageClassStorageBuffer;
333    default:
334       unreachable("Unsupported nir_variable_mode");
335    }
336    return 0;
337 }
338 
339 static SpvId
get_dest_uvec_type(struct ntv_context * ctx,nir_dest * dest)340 get_dest_uvec_type(struct ntv_context *ctx, nir_dest *dest)
341 {
342    unsigned bit_size = nir_dest_bit_size(*dest);
343    return get_uvec_type(ctx, bit_size, nir_dest_num_components(*dest));
344 }
345 
346 static SpvId
get_glsl_basetype(struct ntv_context * ctx,enum glsl_base_type type)347 get_glsl_basetype(struct ntv_context *ctx, enum glsl_base_type type)
348 {
349    switch (type) {
350    case GLSL_TYPE_BOOL:
351       return spirv_builder_type_bool(&ctx->builder);
352 
353    case GLSL_TYPE_FLOAT16:
354       return spirv_builder_type_float(&ctx->builder, 16);
355 
356    case GLSL_TYPE_FLOAT:
357       return spirv_builder_type_float(&ctx->builder, 32);
358 
359    case GLSL_TYPE_INT:
360       return spirv_builder_type_int(&ctx->builder, 32);
361 
362    case GLSL_TYPE_UINT:
363       return spirv_builder_type_uint(&ctx->builder, 32);
364 
365    case GLSL_TYPE_DOUBLE:
366       return spirv_builder_type_float(&ctx->builder, 64);
367 
368    case GLSL_TYPE_INT64:
369       return spirv_builder_type_int(&ctx->builder, 64);
370 
371    case GLSL_TYPE_UINT64:
372       return spirv_builder_type_uint(&ctx->builder, 64);
373 
374    case GLSL_TYPE_UINT16:
375       return spirv_builder_type_uint(&ctx->builder, 16);
376    case GLSL_TYPE_INT16:
377       return spirv_builder_type_int(&ctx->builder, 16);
378    case GLSL_TYPE_INT8:
379       return spirv_builder_type_int(&ctx->builder, 8);
380    case GLSL_TYPE_UINT8:
381       return spirv_builder_type_uint(&ctx->builder, 8);
382 
383    default:
384       unreachable("unknown GLSL type");
385    }
386 }
387 
388 static SpvId
get_glsl_type(struct ntv_context * ctx,const struct glsl_type * type)389 get_glsl_type(struct ntv_context *ctx, const struct glsl_type *type)
390 {
391    assert(type);
392    if (glsl_type_is_scalar(type))
393       return get_glsl_basetype(ctx, glsl_get_base_type(type));
394 
395    if (glsl_type_is_vector(type))
396       return spirv_builder_type_vector(&ctx->builder,
397          get_glsl_basetype(ctx, glsl_get_base_type(type)),
398          glsl_get_vector_elements(type));
399 
400    if (glsl_type_is_matrix(type))
401       return spirv_builder_type_matrix(&ctx->builder,
402                                        spirv_builder_type_vector(&ctx->builder,
403                                                                  get_glsl_basetype(ctx, glsl_get_base_type(type)),
404                                                                  glsl_get_vector_elements(type)),
405                                        glsl_get_matrix_columns(type));
406 
407    /* Aggregate types aren't cached in spirv_builder, so let's cache
408     * them here instead.
409     */
410 
411    struct hash_entry *entry =
412       _mesa_hash_table_search(ctx->glsl_types, type);
413    if (entry)
414       return (SpvId)(uintptr_t)entry->data;
415 
416    SpvId ret;
417    if (glsl_type_is_array(type)) {
418       SpvId element_type = get_glsl_type(ctx, glsl_get_array_element(type));
419       if (glsl_type_is_unsized_array(type))
420          ret = spirv_builder_type_runtime_array(&ctx->builder, element_type);
421       else
422          ret = spirv_builder_type_array(&ctx->builder,
423                                         element_type,
424                                         emit_uint_const(ctx, 32, glsl_get_length(type)));
425       uint32_t stride = glsl_get_explicit_stride(type);
426       if (!stride && glsl_type_is_scalar(glsl_get_array_element(type))) {
427          stride = MAX2(glsl_get_bit_size(glsl_get_array_element(type)) / 8, 1);
428       }
429       if (stride)
430          spirv_builder_emit_array_stride(&ctx->builder, ret, stride);
431    } else if (glsl_type_is_struct_or_ifc(type)) {
432       const unsigned length = glsl_get_length(type);
433 
434       /* allocate some SpvId on the stack, falling back to the heap if the array is too long */
435       SpvId *types, types_stack[16];
436 
437       if (length <= ARRAY_SIZE(types_stack)) {
438          types = types_stack;
439       } else {
440          types = ralloc_array_size(ctx->mem_ctx, sizeof(SpvId), length);
441          assert(types != NULL);
442       }
443 
444       for (unsigned i = 0; i < glsl_get_length(type); i++)
445          types[i] = get_glsl_type(ctx, glsl_get_struct_field(type, i));
446       ret = spirv_builder_type_struct(&ctx->builder, types,
447                                       glsl_get_length(type));
448       for (unsigned i = 0; i < glsl_get_length(type); i++) {
449          int32_t offset = glsl_get_struct_field_offset(type, i);
450          if (offset >= 0)
451             spirv_builder_emit_member_offset(&ctx->builder, ret, i, offset);
452       }
453    } else
454       unreachable("Unhandled GLSL type");
455 
456    _mesa_hash_table_insert(ctx->glsl_types, type, (void *)(uintptr_t)ret);
457    return ret;
458 }
459 
460 static void
create_shared_block(struct ntv_context * ctx,unsigned shared_size)461 create_shared_block(struct ntv_context *ctx, unsigned shared_size)
462 {
463    SpvId type = spirv_builder_type_uint(&ctx->builder, 32);
464    SpvId array = spirv_builder_type_array(&ctx->builder, type, emit_uint_const(ctx, 32, shared_size / 4));
465    spirv_builder_emit_array_stride(&ctx->builder, array, 4);
466    SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
467                                                SpvStorageClassWorkgroup,
468                                                array);
469    ctx->shared_block_var = spirv_builder_emit_var(&ctx->builder, ptr_type, SpvStorageClassWorkgroup);
470    if (ctx->spirv_1_4_interfaces) {
471       assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
472       ctx->entry_ifaces[ctx->num_entry_ifaces++] = ctx->shared_block_var;
473    }
474 }
475 
476 #define HANDLE_EMIT_BUILTIN(SLOT, BUILTIN) \
477       case VARYING_SLOT_##SLOT: \
478          spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltIn##BUILTIN); \
479          break
480 
481 
482 static SpvId
input_var_init(struct ntv_context * ctx,struct nir_variable * var)483 input_var_init(struct ntv_context *ctx, struct nir_variable *var)
484 {
485    SpvId var_type = get_glsl_type(ctx, var->type);
486    SpvStorageClass sc = get_storage_class(var);
487    if (sc == SpvStorageClassPushConstant)
488       spirv_builder_emit_decoration(&ctx->builder, var_type, SpvDecorationBlock);
489    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
490                                                    sc, var_type);
491    SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type, sc);
492 
493    if (var->name)
494       spirv_builder_emit_name(&ctx->builder, var_id, var->name);
495 
496    if (var->data.mode == nir_var_mem_push_const) {
497       ctx->push_const_var = var_id;
498 
499       if (ctx->spirv_1_4_interfaces) {
500          assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
501          ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
502       }
503    }
504    return var_id;
505 }
506 
507 static void
emit_interpolation(struct ntv_context * ctx,SpvId var_id,enum glsl_interp_mode mode)508 emit_interpolation(struct ntv_context *ctx, SpvId var_id,
509                    enum glsl_interp_mode mode)
510 {
511    switch (mode) {
512    case INTERP_MODE_NONE:
513    case INTERP_MODE_SMOOTH:
514       /* XXX spirv doesn't seem to have anything for this */
515       break;
516    case INTERP_MODE_FLAT:
517       spirv_builder_emit_decoration(&ctx->builder, var_id,
518                                     SpvDecorationFlat);
519       break;
520    case INTERP_MODE_EXPLICIT:
521       spirv_builder_emit_decoration(&ctx->builder, var_id,
522                                     SpvDecorationExplicitInterpAMD);
523       break;
524    case INTERP_MODE_NOPERSPECTIVE:
525       spirv_builder_emit_decoration(&ctx->builder, var_id,
526                                     SpvDecorationNoPerspective);
527       break;
528    default:
529       unreachable("unknown interpolation value");
530    }
531 }
532 
533 static void
emit_input(struct ntv_context * ctx,struct nir_variable * var)534 emit_input(struct ntv_context *ctx, struct nir_variable *var)
535 {
536    SpvId var_id = input_var_init(ctx, var);
537    if (ctx->stage == MESA_SHADER_VERTEX)
538       spirv_builder_emit_location(&ctx->builder, var_id,
539                                   var->data.driver_location);
540    else if (ctx->stage == MESA_SHADER_FRAGMENT) {
541       switch (var->data.location) {
542       HANDLE_EMIT_BUILTIN(POS, FragCoord);
543       HANDLE_EMIT_BUILTIN(PNTC, PointCoord);
544       HANDLE_EMIT_BUILTIN(LAYER, Layer);
545       HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
546       HANDLE_EMIT_BUILTIN(CLIP_DIST0, ClipDistance);
547       HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
548       HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
549       HANDLE_EMIT_BUILTIN(FACE, FrontFacing);
550 
551       default:
552          spirv_builder_emit_location(&ctx->builder, var_id,
553                                      var->data.driver_location);
554       }
555       if (var->data.centroid)
556          spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationCentroid);
557       else if (var->data.sample)
558          spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationSample);
559       emit_interpolation(ctx, var_id, var->data.interpolation);
560    } else if (ctx->stage < MESA_SHADER_FRAGMENT) {
561       switch (var->data.location) {
562       HANDLE_EMIT_BUILTIN(POS, Position);
563       HANDLE_EMIT_BUILTIN(PSIZ, PointSize);
564       HANDLE_EMIT_BUILTIN(LAYER, Layer);
565       HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
566       HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
567       HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
568       HANDLE_EMIT_BUILTIN(TESS_LEVEL_OUTER, TessLevelOuter);
569       HANDLE_EMIT_BUILTIN(TESS_LEVEL_INNER, TessLevelInner);
570 
571       case VARYING_SLOT_CLIP_DIST0:
572          assert(glsl_type_is_array(var->type));
573          spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInClipDistance);
574          break;
575 
576       default:
577          spirv_builder_emit_location(&ctx->builder, var_id,
578                                      var->data.driver_location);
579       }
580    }
581 
582    if (var->data.location_frac)
583       spirv_builder_emit_component(&ctx->builder, var_id,
584                                    var->data.location_frac);
585 
586    if (var->data.patch)
587       spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationPatch);
588 
589    _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
590 
591    assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
592    ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
593 }
594 
595 static void
emit_output(struct ntv_context * ctx,struct nir_variable * var)596 emit_output(struct ntv_context *ctx, struct nir_variable *var)
597 {
598    SpvId var_type = get_glsl_type(ctx, var->type);
599 
600    /* SampleMask is always an array in spirv */
601    if (ctx->stage == MESA_SHADER_FRAGMENT && var->data.location == FRAG_RESULT_SAMPLE_MASK)
602       ctx->sample_mask_type = var_type = spirv_builder_type_array(&ctx->builder, var_type, emit_uint_const(ctx, 32, 1));
603    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
604                                                    SpvStorageClassOutput,
605                                                    var_type);
606    SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
607                                          SpvStorageClassOutput);
608    if (var->name)
609       spirv_builder_emit_name(&ctx->builder, var_id, var->name);
610 
611    if (ctx->stage != MESA_SHADER_FRAGMENT) {
612       switch (var->data.location) {
613       HANDLE_EMIT_BUILTIN(POS, Position);
614       HANDLE_EMIT_BUILTIN(PSIZ, PointSize);
615       HANDLE_EMIT_BUILTIN(LAYER, Layer);
616       HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
617       HANDLE_EMIT_BUILTIN(CLIP_DIST0, ClipDistance);
618       HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
619       HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
620       HANDLE_EMIT_BUILTIN(TESS_LEVEL_OUTER, TessLevelOuter);
621       HANDLE_EMIT_BUILTIN(TESS_LEVEL_INNER, TessLevelInner);
622 
623       default:
624          /* non-xfb psiz output will have location -1 */
625          if (var->data.location >= 0)
626             spirv_builder_emit_location(&ctx->builder, var_id,
627                                         var->data.driver_location);
628       }
629       /* tcs can't do xfb */
630       if (ctx->stage != MESA_SHADER_TESS_CTRL && var->data.location >= 0) {
631          unsigned idx = var->data.location << 2 | var->data.location_frac;
632          ctx->outputs[idx] = var_id;
633          ctx->so_output_gl_types[idx] = var->type;
634          ctx->so_output_types[idx] = var_type;
635       }
636       emit_interpolation(ctx, var_id, var->data.interpolation);
637    } else {
638       if (var->data.location >= FRAG_RESULT_DATA0) {
639          spirv_builder_emit_location(&ctx->builder, var_id,
640                                      var->data.location - FRAG_RESULT_DATA0);
641          spirv_builder_emit_index(&ctx->builder, var_id, var->data.index);
642       } else {
643          switch (var->data.location) {
644          case FRAG_RESULT_COLOR:
645             unreachable("gl_FragColor should be lowered by now");
646 
647          case FRAG_RESULT_DEPTH:
648             spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragDepth);
649             break;
650 
651          case FRAG_RESULT_SAMPLE_MASK:
652             spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInSampleMask);
653             break;
654 
655          case FRAG_RESULT_STENCIL:
656             spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragStencilRefEXT);
657             break;
658 
659          default:
660             spirv_builder_emit_location(&ctx->builder, var_id,
661                                         var->data.location);
662             spirv_builder_emit_index(&ctx->builder, var_id, var->data.index);
663          }
664       }
665       if (var->data.sample)
666          spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationSample);
667    }
668 
669    if (var->data.location_frac)
670       spirv_builder_emit_component(&ctx->builder, var_id,
671                                    var->data.location_frac);
672 
673    if (var->data.patch)
674       spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationPatch);
675 
676    if (var->data.explicit_xfb_buffer &&
677        (!glsl_type_is_array(var->type) || glsl_array_size(var->type) == 1  || !glsl_type_is_interface(glsl_without_array(var->type)))) {
678       spirv_builder_emit_offset(&ctx->builder, var_id, var->data.offset);
679       spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, var->data.xfb.buffer);
680       spirv_builder_emit_xfb_stride(&ctx->builder, var_id, var->data.xfb.stride);
681       if (var->data.stream)
682          spirv_builder_emit_stream(&ctx->builder, var_id, var->data.stream);
683    }
684 
685    _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
686 
687    assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
688    ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
689 }
690 
691 static void
emit_temp(struct ntv_context * ctx,struct nir_variable * var)692 emit_temp(struct ntv_context *ctx, struct nir_variable *var)
693 {
694    SpvId var_type = get_glsl_type(ctx, var->type);
695 
696    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
697                                                    SpvStorageClassFunction,
698                                                    var_type);
699    SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
700                                          SpvStorageClassFunction);
701    if (var->name)
702       spirv_builder_emit_name(&ctx->builder, var_id, var->name);
703 
704    _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
705 }
706 
707 static SpvDim
type_to_dim(enum glsl_sampler_dim gdim,bool * is_ms)708 type_to_dim(enum glsl_sampler_dim gdim, bool *is_ms)
709 {
710    *is_ms = false;
711    switch (gdim) {
712    case GLSL_SAMPLER_DIM_1D:
713       return SpvDim1D;
714    case GLSL_SAMPLER_DIM_2D:
715       return SpvDim2D;
716    case GLSL_SAMPLER_DIM_3D:
717       return SpvDim3D;
718    case GLSL_SAMPLER_DIM_CUBE:
719       return SpvDimCube;
720    case GLSL_SAMPLER_DIM_RECT:
721       return SpvDim2D;
722    case GLSL_SAMPLER_DIM_BUF:
723       return SpvDimBuffer;
724    case GLSL_SAMPLER_DIM_EXTERNAL:
725       return SpvDim2D; /* seems dodgy... */
726    case GLSL_SAMPLER_DIM_MS:
727       *is_ms = true;
728       return SpvDim2D;
729    case GLSL_SAMPLER_DIM_SUBPASS_MS:
730       *is_ms = true;
731       return SpvDimSubpassData;
732    case GLSL_SAMPLER_DIM_SUBPASS:
733       return SpvDimSubpassData;
734    default:
735       fprintf(stderr, "unknown sampler type %d\n", gdim);
736       break;
737    }
738    return SpvDim2D;
739 }
740 
741 static inline SpvImageFormat
get_shader_image_format(enum pipe_format format)742 get_shader_image_format(enum pipe_format format)
743 {
744    switch (format) {
745    case PIPE_FORMAT_R32G32B32A32_FLOAT:
746       return SpvImageFormatRgba32f;
747    case PIPE_FORMAT_R16G16B16A16_FLOAT:
748       return SpvImageFormatRgba16f;
749    case PIPE_FORMAT_R32_FLOAT:
750       return SpvImageFormatR32f;
751    case PIPE_FORMAT_R8G8B8A8_UNORM:
752       return SpvImageFormatRgba8;
753    case PIPE_FORMAT_R8G8B8A8_SNORM:
754       return SpvImageFormatRgba8Snorm;
755    case PIPE_FORMAT_R32G32B32A32_SINT:
756       return SpvImageFormatRgba32i;
757    case PIPE_FORMAT_R16G16B16A16_SINT:
758       return SpvImageFormatRgba16i;
759    case PIPE_FORMAT_R8G8B8A8_SINT:
760       return SpvImageFormatRgba8i;
761    case PIPE_FORMAT_R32_SINT:
762       return SpvImageFormatR32i;
763    case PIPE_FORMAT_R32G32B32A32_UINT:
764       return SpvImageFormatRgba32ui;
765    case PIPE_FORMAT_R16G16B16A16_UINT:
766       return SpvImageFormatRgba16ui;
767    case PIPE_FORMAT_R8G8B8A8_UINT:
768       return SpvImageFormatRgba8ui;
769    case PIPE_FORMAT_R32_UINT:
770       return SpvImageFormatR32ui;
771    default:
772       return SpvImageFormatUnknown;
773    }
774 }
775 
776 static inline SpvImageFormat
get_extended_image_format(enum pipe_format format)777 get_extended_image_format(enum pipe_format format)
778 {
779    switch (format) {
780    case PIPE_FORMAT_R32G32_FLOAT:
781       return SpvImageFormatRg32f;
782    case PIPE_FORMAT_R16G16_FLOAT:
783       return SpvImageFormatRg16f;
784    case PIPE_FORMAT_R11G11B10_FLOAT:
785       return SpvImageFormatR11fG11fB10f;
786    case PIPE_FORMAT_R16_FLOAT:
787       return SpvImageFormatR16f;
788    case PIPE_FORMAT_R16G16B16A16_UNORM:
789       return SpvImageFormatRgba16;
790    case PIPE_FORMAT_R10G10B10A2_UNORM:
791       return SpvImageFormatRgb10A2;
792    case PIPE_FORMAT_R16G16_UNORM:
793       return SpvImageFormatRg16;
794    case PIPE_FORMAT_R8G8_UNORM:
795       return SpvImageFormatRg8;
796    case PIPE_FORMAT_R16_UNORM:
797       return SpvImageFormatR16;
798    case PIPE_FORMAT_R8_UNORM:
799       return SpvImageFormatR8;
800    case PIPE_FORMAT_R16G16B16A16_SNORM:
801       return SpvImageFormatRgba16Snorm;
802    case PIPE_FORMAT_R16G16_SNORM:
803       return SpvImageFormatRg16Snorm;
804    case PIPE_FORMAT_R8G8_SNORM:
805       return SpvImageFormatRg8Snorm;
806    case PIPE_FORMAT_R16_SNORM:
807       return SpvImageFormatR16Snorm;
808    case PIPE_FORMAT_R8_SNORM:
809       return SpvImageFormatR8Snorm;
810    case PIPE_FORMAT_R32G32_SINT:
811       return SpvImageFormatRg32i;
812    case PIPE_FORMAT_R16G16_SINT:
813       return SpvImageFormatRg16i;
814    case PIPE_FORMAT_R8G8_SINT:
815       return SpvImageFormatRg8i;
816    case PIPE_FORMAT_R16_SINT:
817       return SpvImageFormatR16i;
818    case PIPE_FORMAT_R8_SINT:
819       return SpvImageFormatR8i;
820    case PIPE_FORMAT_R10G10B10A2_UINT:
821       return SpvImageFormatRgb10a2ui;
822    case PIPE_FORMAT_R32G32_UINT:
823       return SpvImageFormatRg32ui;
824    case PIPE_FORMAT_R16G16_UINT:
825       return SpvImageFormatRg16ui;
826    case PIPE_FORMAT_R8G8_UINT:
827       return SpvImageFormatRg8ui;
828    case PIPE_FORMAT_R16_UINT:
829       return SpvImageFormatR16ui;
830    case PIPE_FORMAT_R8_UINT:
831       return SpvImageFormatR8ui;
832 
833    default:
834       return SpvImageFormatUnknown;
835    }
836 }
837 
838 static inline SpvImageFormat
get_image_format(struct ntv_context * ctx,enum pipe_format format)839 get_image_format(struct ntv_context *ctx, enum pipe_format format)
840 {
841    /* always supported */
842    if (format == PIPE_FORMAT_NONE)
843       return SpvImageFormatUnknown;
844 
845    SpvImageFormat ret = get_shader_image_format(format);
846    if (ret != SpvImageFormatUnknown) {
847       /* requires the shader-cap, but we already emit that */
848       return ret;
849    }
850 
851    ret = get_extended_image_format(format);
852    assert(ret != SpvImageFormatUnknown);
853    spirv_builder_emit_cap(&ctx->builder,
854                           SpvCapabilityStorageImageExtendedFormats);
855    return ret;
856 }
857 
858 static SpvId
get_bare_image_type(struct ntv_context * ctx,struct nir_variable * var,bool is_sampler)859 get_bare_image_type(struct ntv_context *ctx, struct nir_variable *var, bool is_sampler)
860 {
861    const struct glsl_type *type = glsl_without_array(var->type);
862 
863    bool is_ms;
864 
865    if (var->data.fb_fetch_output) {
866       spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInputAttachment);
867    } else if (!is_sampler && !var->data.image.format) {
868       if (!(var->data.access & ACCESS_NON_WRITEABLE))
869          spirv_builder_emit_cap(&ctx->builder, SpvCapabilityStorageImageWriteWithoutFormat);
870       if (!(var->data.access & ACCESS_NON_READABLE))
871          spirv_builder_emit_cap(&ctx->builder, SpvCapabilityStorageImageReadWithoutFormat);
872    }
873 
874    SpvDim dimension = type_to_dim(glsl_get_sampler_dim(type), &is_ms);
875    if (dimension == SpvDim1D) {
876       if (is_sampler)
877          spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySampled1D);
878       else
879          spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImage1D);
880    }
881    if (dimension == SpvDimBuffer) {
882       if (is_sampler)
883          spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageBuffer);
884       else
885          spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySampledBuffer);
886    }
887 
888    bool arrayed = glsl_sampler_type_is_array(type);
889    if (dimension == SpvDimCube && arrayed)
890       spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageCubeArray);
891 
892    SpvId result_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
893    return spirv_builder_type_image(&ctx->builder, result_type,
894                                                dimension, false,
895                                                arrayed,
896                                                is_ms, is_sampler ? 1 : 2,
897                                                get_image_format(ctx, var->data.image.format));
898 }
899 
900 static SpvId
get_image_type(struct ntv_context * ctx,struct nir_variable * var,bool is_sampler)901 get_image_type(struct ntv_context *ctx, struct nir_variable *var, bool is_sampler)
902 {
903    SpvId image_type = get_bare_image_type(ctx, var, is_sampler);
904    return is_sampler ? spirv_builder_type_sampled_image(&ctx->builder, image_type) : image_type;
905 }
906 
907 static SpvId
emit_image(struct ntv_context * ctx,struct nir_variable * var,bool bindless)908 emit_image(struct ntv_context *ctx, struct nir_variable *var, bool bindless)
909 {
910    if (var->data.bindless)
911       return 0;
912    const struct glsl_type *type = glsl_without_array(var->type);
913 
914    bool is_sampler = glsl_type_is_sampler(type);
915    SpvId image_type = get_bare_image_type(ctx, var, is_sampler);
916    SpvId var_type = is_sampler ? spirv_builder_type_sampled_image(&ctx->builder, image_type) : image_type;
917 
918    int index = var->data.driver_location;
919    assert(!is_sampler || (!(ctx->samplers_used & (1 << index))));
920    assert(!is_sampler || !ctx->sampler_types[index]);
921    assert(is_sampler || !ctx->image_types[index]);
922 
923    if (!bindless && glsl_type_is_array(var->type)) {
924       var_type = spirv_builder_type_array(&ctx->builder, var_type,
925                                               emit_uint_const(ctx, 32, glsl_get_aoa_size(var->type)));
926       spirv_builder_emit_array_stride(&ctx->builder, var_type, sizeof(void*));
927       ctx->sampler_array_sizes[index] = glsl_get_aoa_size(var->type);
928    }
929    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
930                                                    SpvStorageClassUniformConstant,
931                                                    var_type);
932 
933    SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
934                                          SpvStorageClassUniformConstant);
935 
936    if (var->name)
937       spirv_builder_emit_name(&ctx->builder, var_id, var->name);
938 
939    if (var->data.fb_fetch_output)
940       spirv_builder_emit_input_attachment_index(&ctx->builder, var_id, var->data.index);
941 
942    if (bindless)
943       return var_id;
944 
945    _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
946    if (is_sampler) {
947       ctx->sampler_types[index] = image_type;
948       ctx->samplers[index] = var_id;
949       ctx->samplers_used |= 1 << index;
950    } else {
951       ctx->image_types[index] = image_type;
952       ctx->images[index] = var_id;
953       uint32_t *key = ralloc_size(ctx->mem_ctx, sizeof(uint32_t));
954       *key = var_id;
955       _mesa_hash_table_insert(ctx->image_vars, key, var);
956       emit_access_decorations(ctx, var, var_id);
957    }
958    if (ctx->spirv_1_4_interfaces) {
959       assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
960       ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
961    }
962 
963    spirv_builder_emit_descriptor_set(&ctx->builder, var_id, var->data.descriptor_set);
964    spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
965    return var_id;
966 }
967 
968 static SpvId
get_sized_uint_array_type(struct ntv_context * ctx,unsigned array_size,unsigned bitsize)969 get_sized_uint_array_type(struct ntv_context *ctx, unsigned array_size, unsigned bitsize)
970 {
971    SpvId array_length = emit_uint_const(ctx, 32, array_size);
972    SpvId array_type = spirv_builder_type_array(&ctx->builder, get_uvec_type(ctx, bitsize, 1),
973                                             array_length);
974    spirv_builder_emit_array_stride(&ctx->builder, array_type, bitsize / 8);
975    return array_type;
976 }
977 
978 /* get array<struct(array_type <--this one)> */
979 static SpvId
get_bo_array_type(struct ntv_context * ctx,struct nir_variable * var)980 get_bo_array_type(struct ntv_context *ctx, struct nir_variable *var)
981 {
982    struct hash_entry *he = _mesa_hash_table_search(ctx->bo_array_types, var);
983    if (he)
984       return (SpvId)(uintptr_t)he->data;
985    unsigned bitsize = glsl_get_bit_size(glsl_get_array_element(glsl_get_struct_field(glsl_without_array(var->type), 0)));
986    assert(bitsize);
987    SpvId array_type;
988    const struct glsl_type *type = glsl_without_array(var->type);
989    const struct glsl_type *first_type = glsl_get_struct_field(type, 0);
990    if (!glsl_type_is_unsized_array(first_type)) {
991       uint32_t array_size = glsl_get_length(first_type);
992       assert(array_size);
993       return get_sized_uint_array_type(ctx, array_size, bitsize);
994    }
995    SpvId uint_type = spirv_builder_type_uint(&ctx->builder, bitsize);
996    array_type = spirv_builder_type_runtime_array(&ctx->builder, uint_type);
997    spirv_builder_emit_array_stride(&ctx->builder, array_type, bitsize / 8);
998    return array_type;
999 }
1000 
1001 /* get array<struct(array_type) <--this one> */
1002 static SpvId
get_bo_struct_type(struct ntv_context * ctx,struct nir_variable * var)1003 get_bo_struct_type(struct ntv_context *ctx, struct nir_variable *var)
1004 {
1005    struct hash_entry *he = _mesa_hash_table_search(ctx->bo_struct_types, var);
1006    if (he)
1007       return (SpvId)(uintptr_t)he->data;
1008    const struct glsl_type *bare_type = glsl_without_array(var->type);
1009    unsigned bitsize = glsl_get_bit_size(glsl_get_array_element(glsl_get_struct_field(bare_type, 0)));
1010    SpvId array_type = get_bo_array_type(ctx, var);
1011    _mesa_hash_table_insert(ctx->bo_array_types, var, (void *)(uintptr_t)array_type);
1012    bool ssbo = var->data.mode == nir_var_mem_ssbo;
1013 
1014    // wrap UBO-array in a struct
1015    SpvId runtime_array = 0;
1016    if (ssbo && glsl_get_length(bare_type) > 1) {
1017        const struct glsl_type *last_member = glsl_get_struct_field(bare_type, glsl_get_length(bare_type) - 1);
1018        if (glsl_type_is_unsized_array(last_member)) {
1019           bool is_64bit = glsl_type_is_64bit(glsl_without_array(last_member));
1020           runtime_array = spirv_builder_type_runtime_array(&ctx->builder, get_uvec_type(ctx, is_64bit ? 64 : bitsize, 1));
1021           spirv_builder_emit_array_stride(&ctx->builder, runtime_array, glsl_get_explicit_stride(last_member));
1022        }
1023    }
1024    SpvId types[] = {array_type, runtime_array};
1025    SpvId struct_type = spirv_builder_type_struct(&ctx->builder, types, 1 + !!runtime_array);
1026    if (var->name) {
1027       char struct_name[100];
1028       snprintf(struct_name, sizeof(struct_name), "struct_%s", var->name);
1029       spirv_builder_emit_name(&ctx->builder, struct_type, struct_name);
1030    }
1031 
1032    spirv_builder_emit_decoration(&ctx->builder, struct_type,
1033                                  SpvDecorationBlock);
1034    spirv_builder_emit_member_offset(&ctx->builder, struct_type, 0, 0);
1035    if (runtime_array)
1036       spirv_builder_emit_member_offset(&ctx->builder, struct_type, 1, 0);
1037 
1038    return struct_type;
1039 }
1040 
1041 static void
emit_bo(struct ntv_context * ctx,struct nir_variable * var)1042 emit_bo(struct ntv_context *ctx, struct nir_variable *var)
1043 {
1044    unsigned bitsize = glsl_get_bit_size(glsl_get_array_element(glsl_get_struct_field(glsl_without_array(var->type), 0)));
1045    bool ssbo = var->data.mode == nir_var_mem_ssbo;
1046    SpvId struct_type = get_bo_struct_type(ctx, var);
1047    _mesa_hash_table_insert(ctx->bo_struct_types, var, (void *)(uintptr_t)struct_type);
1048    SpvId array_length = emit_uint_const(ctx, 32, glsl_get_length(var->type));
1049    SpvId array_type = spirv_builder_type_array(&ctx->builder, struct_type, array_length);
1050    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1051                                                    ssbo ? SpvStorageClassStorageBuffer : SpvStorageClassUniform,
1052                                                    array_type);
1053    SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
1054                                          ssbo ? SpvStorageClassStorageBuffer : SpvStorageClassUniform);
1055    if (var->name)
1056       spirv_builder_emit_name(&ctx->builder, var_id, var->name);
1057 
1058    unsigned idx = bitsize >> 4;
1059    assert(idx < ARRAY_SIZE(ctx->ssbos));
1060    if (ssbo) {
1061       assert(!ctx->ssbos[idx]);
1062       ctx->ssbos[idx] = var_id;
1063       ctx->ssbo_vars = var;
1064    } else {
1065       assert(!ctx->ubos[var->data.driver_location][idx]);
1066       ctx->ubos[var->data.driver_location][idx] = var_id;
1067       ctx->ubo_vars[var->data.driver_location] = var;
1068    }
1069    if (ctx->spirv_1_4_interfaces) {
1070       assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
1071       ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
1072    }
1073    _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
1074 
1075    spirv_builder_emit_descriptor_set(&ctx->builder, var_id, var->data.descriptor_set);
1076    spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
1077 }
1078 
1079 static void
emit_uniform(struct ntv_context * ctx,struct nir_variable * var)1080 emit_uniform(struct ntv_context *ctx, struct nir_variable *var)
1081 {
1082    if (var->data.mode == nir_var_mem_ubo || var->data.mode == nir_var_mem_ssbo)
1083       emit_bo(ctx, var);
1084    else {
1085       assert(var->data.mode == nir_var_uniform ||
1086              var->data.mode == nir_var_image);
1087       const struct glsl_type *type = glsl_without_array(var->type);
1088       if (glsl_type_is_sampler(type) || glsl_type_is_image(type))
1089          emit_image(ctx, var, false);
1090    }
1091 }
1092 
1093 static SpvId
get_vec_from_bit_size(struct ntv_context * ctx,uint32_t bit_size,uint32_t num_components)1094 get_vec_from_bit_size(struct ntv_context *ctx, uint32_t bit_size, uint32_t num_components)
1095 {
1096    if (bit_size == 1)
1097       return get_bvec_type(ctx, num_components);
1098    return get_uvec_type(ctx, bit_size, num_components);
1099 }
1100 
1101 static SpvId
get_src_ssa(struct ntv_context * ctx,const nir_ssa_def * ssa)1102 get_src_ssa(struct ntv_context *ctx, const nir_ssa_def *ssa)
1103 {
1104    assert(ssa->index < ctx->num_defs);
1105    assert(ctx->defs[ssa->index] != 0);
1106    return ctx->defs[ssa->index];
1107 }
1108 
1109 static SpvId
get_var_from_reg(struct ntv_context * ctx,nir_register * reg)1110 get_var_from_reg(struct ntv_context *ctx, nir_register *reg)
1111 {
1112    assert(reg->index < ctx->num_regs);
1113    assert(ctx->regs[reg->index] != 0);
1114    return ctx->regs[reg->index];
1115 }
1116 
1117 static SpvId
get_src_reg(struct ntv_context * ctx,const nir_reg_src * reg)1118 get_src_reg(struct ntv_context *ctx, const nir_reg_src *reg)
1119 {
1120    assert(reg->reg);
1121    assert(!reg->indirect);
1122    assert(!reg->base_offset);
1123 
1124    SpvId var = get_var_from_reg(ctx, reg->reg);
1125    SpvId type = get_vec_from_bit_size(ctx, reg->reg->bit_size, reg->reg->num_components);
1126    return spirv_builder_emit_load(&ctx->builder, type, var);
1127 }
1128 
1129 static SpvId
get_src(struct ntv_context * ctx,nir_src * src)1130 get_src(struct ntv_context *ctx, nir_src *src)
1131 {
1132    if (src->is_ssa)
1133       return get_src_ssa(ctx, src->ssa);
1134    else
1135       return get_src_reg(ctx, &src->reg);
1136 }
1137 
1138 static SpvId
get_alu_src_raw(struct ntv_context * ctx,nir_alu_instr * alu,unsigned src)1139 get_alu_src_raw(struct ntv_context *ctx, nir_alu_instr *alu, unsigned src)
1140 {
1141    assert(!alu->src[src].negate);
1142    assert(!alu->src[src].abs);
1143 
1144    SpvId def = get_src(ctx, &alu->src[src].src);
1145 
1146    unsigned used_channels = 0;
1147    bool need_swizzle = false;
1148    for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
1149       if (!nir_alu_instr_channel_used(alu, src, i))
1150          continue;
1151 
1152       used_channels++;
1153 
1154       if (alu->src[src].swizzle[i] != i)
1155          need_swizzle = true;
1156    }
1157    assert(used_channels != 0);
1158 
1159    unsigned live_channels = nir_src_num_components(alu->src[src].src);
1160    if (used_channels != live_channels)
1161       need_swizzle = true;
1162 
1163    if (!need_swizzle)
1164       return def;
1165 
1166    int bit_size = nir_src_bit_size(alu->src[src].src);
1167    SpvId raw_type = bit_size == 1 ? spirv_builder_type_bool(&ctx->builder) :
1168                                     spirv_builder_type_uint(&ctx->builder, bit_size);
1169 
1170    if (used_channels == 1) {
1171       uint32_t indices[] =  { alu->src[src].swizzle[0] };
1172       return spirv_builder_emit_composite_extract(&ctx->builder, raw_type,
1173                                                   def, indices,
1174                                                   ARRAY_SIZE(indices));
1175    } else if (live_channels == 1) {
1176       SpvId raw_vec_type = spirv_builder_type_vector(&ctx->builder,
1177                                                      raw_type,
1178                                                      used_channels);
1179 
1180       SpvId constituents[NIR_MAX_VEC_COMPONENTS] = {0};
1181       for (unsigned i = 0; i < used_channels; ++i)
1182         constituents[i] = def;
1183 
1184       return spirv_builder_emit_composite_construct(&ctx->builder,
1185                                                     raw_vec_type,
1186                                                     constituents,
1187                                                     used_channels);
1188    } else {
1189       SpvId raw_vec_type = spirv_builder_type_vector(&ctx->builder,
1190                                                      raw_type,
1191                                                      used_channels);
1192 
1193       uint32_t components[NIR_MAX_VEC_COMPONENTS] = {0};
1194       size_t num_components = 0;
1195       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
1196          if (!nir_alu_instr_channel_used(alu, src, i))
1197             continue;
1198 
1199          components[num_components++] = alu->src[src].swizzle[i];
1200       }
1201 
1202       return spirv_builder_emit_vector_shuffle(&ctx->builder, raw_vec_type,
1203                                                def, def, components,
1204                                                num_components);
1205    }
1206 }
1207 
1208 static void
store_ssa_def(struct ntv_context * ctx,nir_ssa_def * ssa,SpvId result)1209 store_ssa_def(struct ntv_context *ctx, nir_ssa_def *ssa, SpvId result)
1210 {
1211    assert(result != 0);
1212    assert(ssa->index < ctx->num_defs);
1213    ctx->defs[ssa->index] = result;
1214 }
1215 
1216 static SpvId
emit_select(struct ntv_context * ctx,SpvId type,SpvId cond,SpvId if_true,SpvId if_false)1217 emit_select(struct ntv_context *ctx, SpvId type, SpvId cond,
1218             SpvId if_true, SpvId if_false)
1219 {
1220    return emit_triop(ctx, SpvOpSelect, type, cond, if_true, if_false);
1221 }
1222 
1223 static SpvId
emit_bitcast(struct ntv_context * ctx,SpvId type,SpvId value)1224 emit_bitcast(struct ntv_context *ctx, SpvId type, SpvId value)
1225 {
1226    return emit_unop(ctx, SpvOpBitcast, type, value);
1227 }
1228 
1229 static SpvId
bitcast_to_uvec(struct ntv_context * ctx,SpvId value,unsigned bit_size,unsigned num_components)1230 bitcast_to_uvec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
1231                 unsigned num_components)
1232 {
1233    SpvId type = get_uvec_type(ctx, bit_size, num_components);
1234    return emit_bitcast(ctx, type, value);
1235 }
1236 
1237 static SpvId
bitcast_to_ivec(struct ntv_context * ctx,SpvId value,unsigned bit_size,unsigned num_components)1238 bitcast_to_ivec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
1239                 unsigned num_components)
1240 {
1241    SpvId type = get_ivec_type(ctx, bit_size, num_components);
1242    return emit_bitcast(ctx, type, value);
1243 }
1244 
1245 static SpvId
bitcast_to_fvec(struct ntv_context * ctx,SpvId value,unsigned bit_size,unsigned num_components)1246 bitcast_to_fvec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
1247                unsigned num_components)
1248 {
1249    SpvId type = get_fvec_type(ctx, bit_size, num_components);
1250    return emit_bitcast(ctx, type, value);
1251 }
1252 
1253 static void
store_reg_def(struct ntv_context * ctx,nir_reg_dest * reg,SpvId result)1254 store_reg_def(struct ntv_context *ctx, nir_reg_dest *reg, SpvId result)
1255 {
1256    SpvId var = get_var_from_reg(ctx, reg->reg);
1257    assert(var);
1258    spirv_builder_emit_store(&ctx->builder, var, result);
1259 }
1260 
1261 static void
store_dest_raw(struct ntv_context * ctx,nir_dest * dest,SpvId result)1262 store_dest_raw(struct ntv_context *ctx, nir_dest *dest, SpvId result)
1263 {
1264    if (dest->is_ssa)
1265       store_ssa_def(ctx, &dest->ssa, result);
1266    else
1267       store_reg_def(ctx, &dest->reg, result);
1268 }
1269 
1270 static SpvId
store_dest(struct ntv_context * ctx,nir_dest * dest,SpvId result,nir_alu_type type)1271 store_dest(struct ntv_context *ctx, nir_dest *dest, SpvId result, nir_alu_type type)
1272 {
1273    unsigned num_components = nir_dest_num_components(*dest);
1274    unsigned bit_size = nir_dest_bit_size(*dest);
1275 
1276    if (bit_size != 1) {
1277       switch (nir_alu_type_get_base_type(type)) {
1278       case nir_type_bool:
1279          assert("bool should have bit-size 1");
1280          break;
1281 
1282       case nir_type_uint:
1283       case nir_type_uint8:
1284       case nir_type_uint16:
1285       case nir_type_uint64:
1286          break; /* nothing to do! */
1287 
1288       case nir_type_int:
1289       case nir_type_int8:
1290       case nir_type_int16:
1291       case nir_type_int64:
1292       case nir_type_float:
1293       case nir_type_float16:
1294       case nir_type_float64:
1295          result = bitcast_to_uvec(ctx, result, bit_size, num_components);
1296          break;
1297 
1298       default:
1299          unreachable("unsupported nir_alu_type");
1300       }
1301    }
1302 
1303    store_dest_raw(ctx, dest, result);
1304    return result;
1305 }
1306 
1307 static SpvId
emit_unop(struct ntv_context * ctx,SpvOp op,SpvId type,SpvId src)1308 emit_unop(struct ntv_context *ctx, SpvOp op, SpvId type, SpvId src)
1309 {
1310    return spirv_builder_emit_unop(&ctx->builder, op, type, src);
1311 }
1312 
1313 /* return the intended xfb output vec type based on base type and vector size */
1314 static SpvId
get_output_type(struct ntv_context * ctx,unsigned register_index,unsigned num_components)1315 get_output_type(struct ntv_context *ctx, unsigned register_index, unsigned num_components)
1316 {
1317    const struct glsl_type *out_type = NULL;
1318    /* index is based on component, so we might have to go back a few slots to get to the base */
1319    while (!out_type)
1320       out_type = ctx->so_output_gl_types[register_index--];
1321    const struct glsl_type *bare_type = glsl_without_array(out_type);
1322    enum glsl_base_type base_type;
1323    if (glsl_type_is_struct_or_ifc(bare_type))
1324       base_type = GLSL_TYPE_UINT;
1325    else
1326       base_type = glsl_get_base_type(bare_type);
1327 
1328 
1329    switch (base_type) {
1330    case GLSL_TYPE_BOOL:
1331       return get_bvec_type(ctx, num_components);
1332 
1333    case GLSL_TYPE_DOUBLE: //this case is misleading, as so outputs are always 32bit floats
1334    case GLSL_TYPE_FLOAT:
1335       return get_fvec_type(ctx, 32, num_components);
1336 
1337    case GLSL_TYPE_INT:
1338       return get_ivec_type(ctx, 32, num_components);
1339 
1340    case GLSL_TYPE_UINT:
1341       return get_uvec_type(ctx, 32, num_components);
1342 
1343    default:
1344       unreachable("unknown type");
1345       break;
1346    }
1347    return 0;
1348 }
1349 
1350 static nir_variable *
find_propagate_var(nir_shader * nir,unsigned slot)1351 find_propagate_var(nir_shader *nir, unsigned slot)
1352 {
1353    nir_foreach_shader_out_variable(var, nir) {
1354       if (var->data.location == slot && glsl_type_is_array(var->type))
1355          return var;
1356    }
1357    return NULL;
1358 }
1359 
1360 /* for streamout create new outputs, as streamout can be done on individual components,
1361    from complete outputs, so we just can't use the created packed outputs */
1362 static void
emit_so_info(struct ntv_context * ctx,const struct zink_shader_info * so_info,unsigned first_so)1363 emit_so_info(struct ntv_context *ctx, const struct zink_shader_info *so_info,
1364              unsigned first_so)
1365 {
1366    unsigned output = 0;
1367    for (unsigned i = 0; i < so_info->so_info.num_outputs; i++) {
1368       struct pipe_stream_output so_output = so_info->so_info.output[i];
1369       unsigned slot = so_info->so_info_slots[i] << 2 | so_output.start_component;
1370       SpvId out_type = get_output_type(ctx, slot, so_output.num_components);
1371       SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1372                                                       SpvStorageClassOutput,
1373                                                       out_type);
1374       SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
1375                                             SpvStorageClassOutput);
1376       char name[10];
1377 
1378       snprintf(name, 10, "xfb%d", output);
1379       spirv_builder_emit_name(&ctx->builder, var_id, name);
1380       spirv_builder_emit_offset(&ctx->builder, var_id, (so_output.dst_offset * 4));
1381       spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, so_output.output_buffer);
1382       spirv_builder_emit_xfb_stride(&ctx->builder, var_id, so_info->so_info.stride[so_output.output_buffer] * 4);
1383       if (so_output.stream)
1384          spirv_builder_emit_stream(&ctx->builder, var_id, so_output.stream);
1385 
1386       /* output location is incremented by VARYING_SLOT_VAR0 for non-builtins in vtn,
1387        * so we need to ensure that the new xfb location slot doesn't conflict with any previously-emitted
1388        * outputs.
1389        */
1390       uint32_t location = first_so + i;
1391       assert(location < VARYING_SLOT_VAR0);
1392       spirv_builder_emit_location(&ctx->builder, var_id, location);
1393 
1394       /* note: gl_ClipDistance[4] can the 0-indexed member of VARYING_SLOT_CLIP_DIST1 here,
1395        * so this is still the 0 component
1396        */
1397       if (so_output.start_component)
1398          spirv_builder_emit_component(&ctx->builder, var_id, so_output.start_component);
1399 
1400       uint32_t *key = ralloc_size(ctx->mem_ctx, sizeof(uint32_t));
1401       *key = (uint32_t)so_output.register_index << 2 | so_output.start_component;
1402       _mesa_hash_table_insert(ctx->so_outputs, key, (void *)(intptr_t)var_id);
1403 
1404       assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
1405       ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
1406       output += align(so_output.num_components, 4) / 4;
1407    }
1408 
1409    /* these are interface block arrays which need to be split
1410     * across N buffers due to GL spec requirements
1411     */
1412    u_foreach_bit(bit, so_info->so_propagate) {
1413       unsigned slot = bit + VARYING_SLOT_VAR0;
1414       nir_variable *var = find_propagate_var(ctx->nir, slot);
1415       assert(var);
1416       const struct glsl_type *bare_type = glsl_without_array(var->type);
1417       SpvId base_type = get_glsl_type(ctx, bare_type);
1418       for (unsigned i = 0; i < glsl_array_size(var->type); i++) {
1419          SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1420                                                          SpvStorageClassOutput,
1421                                                          base_type);
1422          SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
1423                                                SpvStorageClassOutput);
1424          char name[1024];
1425          if (var->name)
1426             snprintf(name, sizeof(name), "xfb_%s[%d]", var->name, i);
1427          else
1428             snprintf(name, sizeof(name), "xfb_slot%u[%d]", slot, i);
1429          spirv_builder_emit_name(&ctx->builder, var_id, name);
1430          spirv_builder_emit_offset(&ctx->builder, var_id, var->data.offset);
1431          spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, var->data.xfb.buffer + i);
1432          spirv_builder_emit_xfb_stride(&ctx->builder, var_id, var->data.xfb.stride);
1433          if (var->data.stream)
1434             spirv_builder_emit_stream(&ctx->builder, var_id, var->data.stream);
1435 
1436          uint32_t location = first_so + so_info->so_info.num_outputs + i;
1437          assert(location < VARYING_SLOT_VAR0);
1438          spirv_builder_emit_location(&ctx->builder, var_id, location);
1439 
1440          uint32_t *key = ralloc_size(ctx->mem_ctx, sizeof(uint32_t));
1441          *key = (uint32_t)(slot + i) << 2;
1442          _mesa_hash_table_insert(ctx->so_outputs, key, (void *)(intptr_t)var_id);
1443 
1444          assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
1445          ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
1446       }
1447    }
1448 }
1449 
1450 static const struct glsl_type *
unroll_struct_type(struct ntv_context * ctx,const struct glsl_type * slot_type,unsigned * slot_idx,SpvId * deref,const struct glsl_type ** arraytype)1451 unroll_struct_type(struct ntv_context *ctx, const struct glsl_type *slot_type, unsigned *slot_idx, SpvId *deref, const struct glsl_type **arraytype)
1452 {
1453    const struct glsl_type *type = slot_type;
1454    unsigned slot_count = 0;
1455    unsigned cur_slot = 0;
1456    unsigned idx = 0;
1457    /* iterate over all the members in the struct, stopping once the slot idx is reached */
1458    for (unsigned i = 0; i < glsl_get_length(slot_type) && cur_slot <= *slot_idx; i++, cur_slot += slot_count) {
1459       /* use array type for slot counting but return array member type for unroll */
1460       *arraytype = glsl_get_struct_field(slot_type, i);
1461       type = glsl_without_array(*arraytype);
1462       slot_count = glsl_count_vec4_slots(*arraytype, false, false);
1463       idx = i;
1464    }
1465    *deref = spirv_builder_emit_composite_extract(&ctx->builder, get_glsl_type(ctx, glsl_get_struct_field(slot_type, idx)), *deref, &idx, 1);
1466    *slot_idx -= (cur_slot - slot_count);
1467    return type;
1468 }
1469 
1470 static void
emit_so_outputs(struct ntv_context * ctx,const struct zink_shader_info * so_info)1471 emit_so_outputs(struct ntv_context *ctx,
1472                 const struct zink_shader_info *so_info)
1473 {
1474    for (unsigned i = 0; i < so_info->so_info.num_outputs; i++) {
1475       uint32_t components[NIR_MAX_VEC_COMPONENTS];
1476       unsigned slot = so_info->so_info_slots[i];
1477       struct pipe_stream_output so_output = so_info->so_info.output[i];
1478       uint32_t so_key = (uint32_t) so_output.register_index << 2 | so_output.start_component;
1479       uint32_t output_location = (uint32_t) slot << 2 | so_output.start_component;
1480       uint32_t location = output_location;
1481       struct hash_entry *he = _mesa_hash_table_search(ctx->so_outputs, &so_key);
1482       assert(he);
1483       SpvId so_output_var_id = (SpvId)(intptr_t)he->data;
1484 
1485       SpvId type = get_output_type(ctx, location, so_output.num_components);
1486       SpvId output = 0;
1487       /* index is based on component, so we might have to go back a few slots to get to the base */
1488       UNUSED uint32_t orig_location = location;
1489       while (!output)
1490          output = ctx->outputs[location--];
1491       location++;
1492       SpvId output_type = ctx->so_output_types[location];
1493       const struct glsl_type *out_type = ctx->so_output_gl_types[location];
1494 
1495       SpvId src = spirv_builder_emit_load(&ctx->builder, output_type, output);
1496 
1497       SpvId result;
1498 
1499       /* this is the type being indexed into */
1500       const struct glsl_type *bare_type = glsl_without_array(out_type);
1501       /* this is the array index into matrix types */
1502       unsigned matrix_offset = glsl_type_is_matrix(bare_type) ? 0 : so_output.register_index;
1503       do {
1504          uint32_t base_slot = (location & ~so_output.start_component) / 4;
1505          /* this is the slot index into the "current" value */
1506          unsigned slot_idx = slot - base_slot;
1507          unsigned struct_slots = glsl_count_vec4_slots(bare_type, false, false);
1508          unsigned array_idx = slot_idx / struct_slots;
1509          if (glsl_type_is_struct_or_ifc(bare_type)) {
1510             bool first = true;
1511             slot_idx %= glsl_count_vec4_slots(bare_type, false, false);
1512             if (glsl_type_is_array(out_type))
1513                src = spirv_builder_emit_composite_extract(&ctx->builder, get_glsl_type(ctx, bare_type), src, &array_idx, 1);
1514             /* need to find the vec4 that's being exported by this slot */
1515             while (glsl_type_is_struct_or_ifc(bare_type)) {
1516                /* a struct may have nested arrays of structs: handle them inline here */
1517                if (!first && glsl_type_is_array(out_type)) {
1518                   struct_slots = glsl_count_vec4_slots(bare_type, false, false);
1519                   array_idx = slot_idx / struct_slots;
1520                   src = spirv_builder_emit_composite_extract(&ctx->builder, get_glsl_type(ctx, bare_type), src, &array_idx, 1);
1521                   slot_idx -= array_idx * struct_slots;
1522                }
1523                /* unroll this level of struct:
1524                 * - slot_idx is incremented to reflect the current value
1525                 * - unwrap src
1526                 * - out_type is the array type if src is an array
1527                 */
1528                bare_type = unroll_struct_type(ctx, bare_type, &slot_idx, &src, &out_type);
1529                first = false;
1530             }
1531          }
1532          /* update to the matrix row index */
1533          matrix_offset = slot_idx;
1534          output_type = get_glsl_type(ctx, out_type);
1535          if (glsl_type_is_vector_or_scalar(out_type)) {
1536             /* this is a simple case: handle below */
1537             if (glsl_get_vector_elements(out_type) * glsl_get_bit_size(out_type) == so_output.num_components * 32) {
1538                src = emit_bitcast(ctx, type, src);
1539                out_type = glsl_vector_type(GLSL_TYPE_UINT, so_output.num_components);
1540                output_type = get_glsl_type(ctx, out_type);
1541             }
1542          } else if (glsl_type_is_array(out_type)) {
1543              /* this should be impossible */
1544              if (glsl_type_is_struct(bare_type))
1545                 unreachable("zink: gross nested struct array struct arrays in xfb!");
1546              if (glsl_type_is_matrix(bare_type)) {
1547                 /* nested matrix type: unwrap, update matrix offset, select a vec, handle below */
1548                 unsigned mat_slots = glsl_count_attribute_slots(bare_type, false);
1549                 array_idx = matrix_offset / mat_slots;
1550                 output_type = get_glsl_type(ctx, bare_type);
1551                 out_type = bare_type;
1552                 src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &array_idx, 1);
1553                 matrix_offset %= mat_slots;
1554                 unsigned real_offset = glsl_type_is_64bit(bare_type) ? matrix_offset / 2 : matrix_offset;
1555                 /* store for later */
1556                 if (glsl_type_is_64bit(bare_type))
1557                    matrix_offset %= 2;
1558                 assert(real_offset < glsl_get_matrix_columns(bare_type));
1559                 out_type = glsl_without_array_or_matrix(out_type);
1560                 output_type = get_glsl_type(ctx, out_type);
1561                 src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &real_offset, 1);
1562                 break;
1563              } else if (glsl_type_is_vector(bare_type)) {
1564                 /* just extract the right vec and let it be handled below */
1565                 unsigned vec_slots = glsl_count_attribute_slots(bare_type, false);
1566                 unsigned idx = matrix_offset / vec_slots;
1567                 matrix_offset %= vec_slots;
1568                 output_type = get_glsl_type(ctx, bare_type);
1569                 out_type = bare_type;
1570                 src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &idx, 1);
1571                 break;
1572              } else {
1573                 assert(glsl_type_is_scalar(bare_type));
1574                 break;
1575              }
1576              if (so_output.num_components > 1)
1577                 src = spirv_builder_emit_composite_construct(&ctx->builder, type, components, so_output.num_components);
1578              else
1579                 src = components[0];
1580              out_type = glsl_vector_type(GLSL_TYPE_UINT, so_output.num_components);
1581              output_type = type;
1582          }
1583       } while (0);
1584       assert(!glsl_type_is_struct_or_ifc(out_type));
1585 
1586       if (!glsl_type_is_64bit(out_type) &&
1587           (glsl_type_is_scalar(out_type) ||
1588            (type == output_type &&
1589             (glsl_type_is_vector(out_type) && glsl_get_vector_elements(out_type) == so_output.num_components))))
1590          /* if we're emitting a scalar or the type we're emitting matches the output's original type and we're
1591           * emitting the same number of components, then we can skip any sort of conversion here
1592           */
1593          result = src;
1594       else {
1595          /* OpCompositeExtract can only extract scalars for our use here,
1596           * but not from arrays since they have different packing rules
1597           */
1598          if (so_output.num_components == 1 && !glsl_type_is_array(out_type)) {
1599             unsigned component = so_output.start_component;
1600             result = spirv_builder_emit_composite_extract(&ctx->builder, type, src, &component, so_output.num_components);
1601          } else if (glsl_type_is_vector(out_type)) {
1602             if (glsl_type_is_64bit(out_type)) {
1603                /* 64bit components count as 2 so outputs: bitcast to vec2 and extract */
1604                unsigned idx = 0;
1605                for (unsigned c = 0; idx < so_output.num_components; c++) {
1606                   uint32_t member = so_output.start_component + (matrix_offset * 2) + c;
1607                   SpvId base_type = get_glsl_basetype(ctx, glsl_get_base_type(out_type));
1608                   SpvId conv = spirv_builder_emit_composite_extract(&ctx->builder, base_type, src, &member, 1);
1609                   SpvId val = emit_bitcast(ctx, get_uvec_type(ctx, 32, 2), conv);
1610                   unsigned v = 0;
1611                   components[idx++] = spirv_builder_emit_composite_extract(&ctx->builder, get_uvec_type(ctx, 32, 1), val, &v, 1);
1612                   v = 1;
1613                   components[idx++] = spirv_builder_emit_composite_extract(&ctx->builder, get_uvec_type(ctx, 32, 1), val, &v, 1);
1614                }
1615                result = spirv_builder_emit_composite_construct(&ctx->builder, get_uvec_type(ctx, 32, so_output.num_components), components, so_output.num_components);
1616             } else {
1617                for (unsigned c = 0; c < so_output.num_components; c++) {
1618                   components[c] = so_output.start_component + c;
1619                   /* this is the second half of a 2 * vec4 array */
1620                   if (slot == VARYING_SLOT_CLIP_DIST1 || slot == VARYING_SLOT_CULL_DIST1)
1621                      components[c] += 4;
1622                }
1623                /* OpVectorShuffle can select vector members into a differently-sized vector */
1624                result = spirv_builder_emit_vector_shuffle(&ctx->builder, type,
1625                                                                 src, src,
1626                                                                 components, so_output.num_components);
1627             }
1628          } else {
1629              assert(glsl_type_is_array_or_matrix(out_type));
1630              const struct glsl_type *bare_type = glsl_without_array(out_type);
1631              assert(!glsl_type_is_struct_or_ifc(bare_type));
1632              if (glsl_type_is_matrix(out_type)) {
1633                 /* for matrices, the xfb output will never be more than one vec4 from a single row */
1634                 unsigned vec_size = glsl_get_vector_elements(out_type);
1635                 SpvId vec_type = get_fvec_type(ctx, glsl_get_bit_size(out_type), vec_size);
1636                 if (glsl_type_is_64bit(out_type) && vec_size > 2) {
1637                    /* dvec3/dvec4 uses 2 slots per row: normalize matrix offset */
1638                    matrix_offset /= 2;
1639                 }
1640                 src = spirv_builder_emit_composite_extract(&ctx->builder, vec_type, src, &matrix_offset, 1);
1641                 out_type = glsl_vector_type(glsl_get_base_type(out_type), glsl_get_vector_elements(out_type));
1642              }
1643              /* for arrays (or matrix rows), we need to manually extract each desired member
1644               * and re-pack them into the desired output type
1645               */
1646              unsigned idx = 0;
1647              for (unsigned c = 0; idx < so_output.num_components; c++) {
1648                 uint32_t member = so_output.start_component + c;
1649                 SpvId base_type = get_glsl_basetype(ctx, glsl_get_base_type(bare_type));
1650 
1651                 if (slot == VARYING_SLOT_CLIP_DIST1 || slot == VARYING_SLOT_CULL_DIST1)
1652                    member += 4;
1653                 components[idx] = spirv_builder_emit_composite_extract(&ctx->builder, base_type, src, &member, 1);
1654                 if (glsl_type_is_64bit(bare_type)) {
1655                    /* 64bit components count as 2 so outputs: bitcast to vec2 and extract */
1656                    SpvId val = emit_bitcast(ctx, get_uvec_type(ctx, 32, 2), components[idx]);
1657                    unsigned v = 0;
1658                    components[idx++] = spirv_builder_emit_composite_extract(&ctx->builder, get_uvec_type(ctx, 32, 1), val, &v, 1);
1659                    v = 1;
1660                    components[idx++] = spirv_builder_emit_composite_extract(&ctx->builder, get_uvec_type(ctx, 32, 1), val, &v, 1);
1661                 } else {
1662                    components[idx] = emit_bitcast(ctx, spirv_builder_type_uint(&ctx->builder, 32), components[idx]);
1663                    idx++;
1664                 }
1665              }
1666              if (so_output.num_components > 1)
1667                 result = spirv_builder_emit_composite_construct(&ctx->builder, get_uvec_type(ctx, 32, so_output.num_components), components, so_output.num_components);
1668              else
1669                 result = components[0];
1670          }
1671       }
1672 
1673       result = emit_bitcast(ctx, type, result);
1674       spirv_builder_emit_store(&ctx->builder, so_output_var_id, result);
1675    }
1676 
1677    u_foreach_bit(bit, so_info->so_propagate) {
1678       unsigned slot = bit + VARYING_SLOT_VAR0;
1679       nir_variable *var = find_propagate_var(ctx->nir, slot);
1680       assert(var);
1681 
1682       const struct glsl_type *bare_type = glsl_without_array(var->type);
1683       SpvId base_type = get_glsl_type(ctx, bare_type);
1684       SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1685                                                       SpvStorageClassOutput,
1686                                                       base_type);
1687       SpvId output = ctx->outputs[slot << 2];
1688       assert(output);
1689       for (unsigned i = 0; i < glsl_array_size(var->type); i++) {
1690          uint32_t so_key = (uint32_t) (slot + i) << 2;
1691          struct hash_entry *he = _mesa_hash_table_search(ctx->so_outputs, &so_key);
1692          assert(he);
1693          SpvId so_output_var_id = (SpvId)(intptr_t)he->data;
1694 
1695          SpvId idx = emit_uint_const(ctx, 32, i);
1696          SpvId deref = spirv_builder_emit_access_chain(&ctx->builder, pointer_type, output, &idx, 1);
1697          SpvId load = spirv_builder_emit_load(&ctx->builder, base_type, deref);
1698          spirv_builder_emit_store(&ctx->builder, so_output_var_id, load);
1699       }
1700    }
1701 }
1702 
1703 static SpvId
emit_atomic(struct ntv_context * ctx,SpvId op,SpvId type,SpvId src0,SpvId src1,SpvId src2)1704 emit_atomic(struct ntv_context *ctx, SpvId op, SpvId type, SpvId src0, SpvId src1, SpvId src2)
1705 {
1706    if (op == SpvOpAtomicLoad)
1707       return spirv_builder_emit_triop(&ctx->builder, op, type, src0, emit_uint_const(ctx, 32, SpvScopeDevice),
1708                                        emit_uint_const(ctx, 32, 0));
1709    if (op == SpvOpAtomicCompareExchange)
1710       return spirv_builder_emit_hexop(&ctx->builder, op, type, src0, emit_uint_const(ctx, 32, SpvScopeDevice),
1711                                        emit_uint_const(ctx, 32, 0),
1712                                        emit_uint_const(ctx, 32, 0),
1713                                        /* these params are intentionally swapped */
1714                                        src2, src1);
1715 
1716    return spirv_builder_emit_quadop(&ctx->builder, op, type, src0, emit_uint_const(ctx, 32, SpvScopeDevice),
1717                                     emit_uint_const(ctx, 32, 0), src1);
1718 }
1719 
1720 static SpvId
emit_binop(struct ntv_context * ctx,SpvOp op,SpvId type,SpvId src0,SpvId src1)1721 emit_binop(struct ntv_context *ctx, SpvOp op, SpvId type,
1722            SpvId src0, SpvId src1)
1723 {
1724    return spirv_builder_emit_binop(&ctx->builder, op, type, src0, src1);
1725 }
1726 
1727 static SpvId
emit_triop(struct ntv_context * ctx,SpvOp op,SpvId type,SpvId src0,SpvId src1,SpvId src2)1728 emit_triop(struct ntv_context *ctx, SpvOp op, SpvId type,
1729            SpvId src0, SpvId src1, SpvId src2)
1730 {
1731    return spirv_builder_emit_triop(&ctx->builder, op, type, src0, src1, src2);
1732 }
1733 
1734 static SpvId
emit_builtin_unop(struct ntv_context * ctx,enum GLSLstd450 op,SpvId type,SpvId src)1735 emit_builtin_unop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
1736                   SpvId src)
1737 {
1738    SpvId args[] = { src };
1739    return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1740                                       op, args, ARRAY_SIZE(args));
1741 }
1742 
1743 static SpvId
emit_builtin_binop(struct ntv_context * ctx,enum GLSLstd450 op,SpvId type,SpvId src0,SpvId src1)1744 emit_builtin_binop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
1745                    SpvId src0, SpvId src1)
1746 {
1747    SpvId args[] = { src0, src1 };
1748    return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1749                                       op, args, ARRAY_SIZE(args));
1750 }
1751 
1752 static SpvId
emit_builtin_triop(struct ntv_context * ctx,enum GLSLstd450 op,SpvId type,SpvId src0,SpvId src1,SpvId src2)1753 emit_builtin_triop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
1754                    SpvId src0, SpvId src1, SpvId src2)
1755 {
1756    SpvId args[] = { src0, src1, src2 };
1757    return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1758                                       op, args, ARRAY_SIZE(args));
1759 }
1760 
1761 static SpvId
get_fvec_constant(struct ntv_context * ctx,unsigned bit_size,unsigned num_components,double value)1762 get_fvec_constant(struct ntv_context *ctx, unsigned bit_size,
1763                   unsigned num_components, double value)
1764 {
1765    assert(bit_size == 16 || bit_size == 32 || bit_size == 64);
1766 
1767    SpvId result = emit_float_const(ctx, bit_size, value);
1768    if (num_components == 1)
1769       return result;
1770 
1771    assert(num_components > 1);
1772    SpvId components[NIR_MAX_VEC_COMPONENTS];
1773    for (int i = 0; i < num_components; i++)
1774       components[i] = result;
1775 
1776    SpvId type = get_fvec_type(ctx, bit_size, num_components);
1777    return spirv_builder_const_composite(&ctx->builder, type, components,
1778                                         num_components);
1779 }
1780 
1781 static SpvId
get_ivec_constant(struct ntv_context * ctx,unsigned bit_size,unsigned num_components,int64_t value)1782 get_ivec_constant(struct ntv_context *ctx, unsigned bit_size,
1783                   unsigned num_components, int64_t value)
1784 {
1785    assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
1786 
1787    SpvId result = emit_int_const(ctx, bit_size, value);
1788    if (num_components == 1)
1789       return result;
1790 
1791    assert(num_components > 1);
1792    SpvId components[NIR_MAX_VEC_COMPONENTS];
1793    for (int i = 0; i < num_components; i++)
1794       components[i] = result;
1795 
1796    SpvId type = get_ivec_type(ctx, bit_size, num_components);
1797    return spirv_builder_const_composite(&ctx->builder, type, components,
1798                                         num_components);
1799 }
1800 
1801 static inline unsigned
alu_instr_src_components(const nir_alu_instr * instr,unsigned src)1802 alu_instr_src_components(const nir_alu_instr *instr, unsigned src)
1803 {
1804    if (nir_op_infos[instr->op].input_sizes[src] > 0)
1805       return nir_op_infos[instr->op].input_sizes[src];
1806 
1807    if (instr->dest.dest.is_ssa)
1808       return instr->dest.dest.ssa.num_components;
1809    else
1810       return instr->dest.dest.reg.reg->num_components;
1811 }
1812 
1813 static SpvId
get_alu_src(struct ntv_context * ctx,nir_alu_instr * alu,unsigned src,SpvId * raw_value)1814 get_alu_src(struct ntv_context *ctx, nir_alu_instr *alu, unsigned src, SpvId *raw_value)
1815 {
1816    *raw_value = get_alu_src_raw(ctx, alu, src);
1817 
1818    unsigned num_components = alu_instr_src_components(alu, src);
1819    unsigned bit_size = nir_src_bit_size(alu->src[src].src);
1820    nir_alu_type type = nir_op_infos[alu->op].input_types[src];
1821 
1822    if (bit_size == 1)
1823       return *raw_value;
1824    else {
1825       switch (nir_alu_type_get_base_type(type)) {
1826       case nir_type_bool:
1827          unreachable("bool should have bit-size 1");
1828 
1829       case nir_type_int:
1830          return bitcast_to_ivec(ctx, *raw_value, bit_size, num_components);
1831 
1832       case nir_type_uint:
1833          return *raw_value;
1834 
1835       case nir_type_float:
1836          return bitcast_to_fvec(ctx, *raw_value, bit_size, num_components);
1837 
1838       default:
1839          unreachable("unknown nir_alu_type");
1840       }
1841    }
1842 }
1843 
1844 static SpvId
store_alu_result(struct ntv_context * ctx,nir_alu_instr * alu,SpvId result,bool force_float)1845 store_alu_result(struct ntv_context *ctx, nir_alu_instr *alu, SpvId result, bool force_float)
1846 {
1847    assert(!alu->dest.saturate);
1848    return store_dest(ctx, &alu->dest.dest, result,
1849                      force_float ? nir_type_float : nir_op_infos[alu->op].output_type);
1850 }
1851 
1852 static SpvId
get_alu_type(struct ntv_context * ctx,nir_alu_type type,unsigned num_components,unsigned bit_size)1853 get_alu_type(struct ntv_context *ctx, nir_alu_type type, unsigned num_components, unsigned bit_size)
1854 {
1855    if (bit_size == 1)
1856       return get_bvec_type(ctx, num_components);
1857 
1858    switch (nir_alu_type_get_base_type(type)) {
1859    case nir_type_bool:
1860       unreachable("bool should have bit-size 1");
1861 
1862    case nir_type_int:
1863    case nir_type_int8:
1864    case nir_type_int16:
1865    case nir_type_int64:
1866       return get_ivec_type(ctx, bit_size, num_components);
1867 
1868    case nir_type_uint:
1869    case nir_type_uint8:
1870    case nir_type_uint16:
1871    case nir_type_uint64:
1872       return get_uvec_type(ctx, bit_size, num_components);
1873 
1874    case nir_type_float:
1875    case nir_type_float16:
1876    case nir_type_float64:
1877       return get_fvec_type(ctx, bit_size, num_components);
1878 
1879    default:
1880       unreachable("unsupported nir_alu_type");
1881    }
1882 }
1883 
1884 static SpvId
get_dest_type(struct ntv_context * ctx,nir_dest * dest,nir_alu_type type)1885 get_dest_type(struct ntv_context *ctx, nir_dest *dest, nir_alu_type type)
1886 {
1887    unsigned num_components = nir_dest_num_components(*dest);
1888    unsigned bit_size = nir_dest_bit_size(*dest);
1889    return get_alu_type(ctx, type, num_components, bit_size);
1890 }
1891 
1892 static bool
needs_derivative_control(nir_alu_instr * alu)1893 needs_derivative_control(nir_alu_instr *alu)
1894 {
1895    switch (alu->op) {
1896    case nir_op_fddx_coarse:
1897    case nir_op_fddx_fine:
1898    case nir_op_fddy_coarse:
1899    case nir_op_fddy_fine:
1900       return true;
1901 
1902    default:
1903       return false;
1904    }
1905 }
1906 
1907 static void
emit_alu(struct ntv_context * ctx,nir_alu_instr * alu)1908 emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
1909 {
1910    SpvId src[NIR_MAX_VEC_COMPONENTS];
1911    SpvId raw_src[NIR_MAX_VEC_COMPONENTS];
1912    for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++)
1913       src[i] = get_alu_src(ctx, alu, i, &raw_src[i]);
1914 
1915    SpvId dest_type = get_dest_type(ctx, &alu->dest.dest,
1916                                    nir_op_infos[alu->op].output_type);
1917    bool force_float = false;
1918    unsigned bit_size = nir_dest_bit_size(alu->dest.dest);
1919    unsigned num_components = nir_dest_num_components(alu->dest.dest);
1920 
1921    if (needs_derivative_control(alu))
1922       spirv_builder_emit_cap(&ctx->builder, SpvCapabilityDerivativeControl);
1923 
1924    SpvId result = 0;
1925    switch (alu->op) {
1926    case nir_op_mov:
1927       assert(nir_op_infos[alu->op].num_inputs == 1);
1928       result = src[0];
1929       break;
1930 
1931 #define UNOP(nir_op, spirv_op) \
1932    case nir_op: \
1933       assert(nir_op_infos[alu->op].num_inputs == 1); \
1934       result = emit_unop(ctx, spirv_op, dest_type, src[0]); \
1935       break;
1936 
1937    UNOP(nir_op_ineg, SpvOpSNegate)
1938    UNOP(nir_op_fneg, SpvOpFNegate)
1939    UNOP(nir_op_fddx, SpvOpDPdx)
1940    UNOP(nir_op_fddx_coarse, SpvOpDPdxCoarse)
1941    UNOP(nir_op_fddx_fine, SpvOpDPdxFine)
1942    UNOP(nir_op_fddy, SpvOpDPdy)
1943    UNOP(nir_op_fddy_coarse, SpvOpDPdyCoarse)
1944    UNOP(nir_op_fddy_fine, SpvOpDPdyFine)
1945    UNOP(nir_op_f2i16, SpvOpConvertFToS)
1946    UNOP(nir_op_f2u16, SpvOpConvertFToU)
1947    UNOP(nir_op_f2i32, SpvOpConvertFToS)
1948    UNOP(nir_op_f2u32, SpvOpConvertFToU)
1949    UNOP(nir_op_i2f16, SpvOpConvertSToF)
1950    UNOP(nir_op_i2f32, SpvOpConvertSToF)
1951    UNOP(nir_op_u2f16, SpvOpConvertUToF)
1952    UNOP(nir_op_u2f32, SpvOpConvertUToF)
1953    UNOP(nir_op_i2i16, SpvOpSConvert)
1954    UNOP(nir_op_i2i32, SpvOpSConvert)
1955    UNOP(nir_op_u2u8, SpvOpUConvert)
1956    UNOP(nir_op_u2u16, SpvOpUConvert)
1957    UNOP(nir_op_u2u32, SpvOpUConvert)
1958    UNOP(nir_op_f2f16, SpvOpFConvert)
1959    UNOP(nir_op_f2f32, SpvOpFConvert)
1960    UNOP(nir_op_f2i64, SpvOpConvertFToS)
1961    UNOP(nir_op_f2u64, SpvOpConvertFToU)
1962    UNOP(nir_op_u2f64, SpvOpConvertUToF)
1963    UNOP(nir_op_i2f64, SpvOpConvertSToF)
1964    UNOP(nir_op_i2i64, SpvOpSConvert)
1965    UNOP(nir_op_u2u64, SpvOpUConvert)
1966    UNOP(nir_op_f2f64, SpvOpFConvert)
1967    UNOP(nir_op_bitfield_reverse, SpvOpBitReverse)
1968    UNOP(nir_op_bit_count, SpvOpBitCount)
1969 #undef UNOP
1970 
1971    case nir_op_inot:
1972       if (bit_size == 1)
1973          result = emit_unop(ctx, SpvOpLogicalNot, dest_type, src[0]);
1974       else
1975          result = emit_unop(ctx, SpvOpNot, dest_type, src[0]);
1976       break;
1977 
1978    case nir_op_b2i16:
1979    case nir_op_b2i32:
1980    case nir_op_b2i64:
1981       assert(nir_op_infos[alu->op].num_inputs == 1);
1982       result = emit_select(ctx, dest_type, src[0],
1983                            get_ivec_constant(ctx, bit_size, num_components, 1),
1984                            get_ivec_constant(ctx, bit_size, num_components, 0));
1985       break;
1986 
1987    case nir_op_b2f16:
1988    case nir_op_b2f32:
1989    case nir_op_b2f64:
1990       assert(nir_op_infos[alu->op].num_inputs == 1);
1991       result = emit_select(ctx, dest_type, src[0],
1992                            get_fvec_constant(ctx, bit_size, num_components, 1),
1993                            get_fvec_constant(ctx, bit_size, num_components, 0));
1994       break;
1995 
1996 #define BUILTIN_UNOP(nir_op, spirv_op) \
1997    case nir_op: \
1998       assert(nir_op_infos[alu->op].num_inputs == 1); \
1999       result = emit_builtin_unop(ctx, spirv_op, dest_type, src[0]); \
2000       break;
2001 
2002 #define BUILTIN_UNOPF(nir_op, spirv_op) \
2003    case nir_op: \
2004       assert(nir_op_infos[alu->op].num_inputs == 1); \
2005       result = emit_builtin_unop(ctx, spirv_op, get_dest_type(ctx, &alu->dest.dest, nir_type_float), src[0]); \
2006       force_float = true; \
2007       break;
2008 
2009    BUILTIN_UNOP(nir_op_iabs, GLSLstd450SAbs)
2010    BUILTIN_UNOP(nir_op_fabs, GLSLstd450FAbs)
2011    BUILTIN_UNOP(nir_op_fsqrt, GLSLstd450Sqrt)
2012    BUILTIN_UNOP(nir_op_frsq, GLSLstd450InverseSqrt)
2013    BUILTIN_UNOP(nir_op_flog2, GLSLstd450Log2)
2014    BUILTIN_UNOP(nir_op_fexp2, GLSLstd450Exp2)
2015    BUILTIN_UNOP(nir_op_ffract, GLSLstd450Fract)
2016    BUILTIN_UNOP(nir_op_ffloor, GLSLstd450Floor)
2017    BUILTIN_UNOP(nir_op_fceil, GLSLstd450Ceil)
2018    BUILTIN_UNOP(nir_op_ftrunc, GLSLstd450Trunc)
2019    BUILTIN_UNOP(nir_op_fround_even, GLSLstd450RoundEven)
2020    BUILTIN_UNOP(nir_op_fsign, GLSLstd450FSign)
2021    BUILTIN_UNOP(nir_op_isign, GLSLstd450SSign)
2022    BUILTIN_UNOP(nir_op_fsin, GLSLstd450Sin)
2023    BUILTIN_UNOP(nir_op_fcos, GLSLstd450Cos)
2024    BUILTIN_UNOP(nir_op_ufind_msb, GLSLstd450FindUMsb)
2025    BUILTIN_UNOP(nir_op_find_lsb, GLSLstd450FindILsb)
2026    BUILTIN_UNOP(nir_op_ifind_msb, GLSLstd450FindSMsb)
2027 
2028    case nir_op_pack_half_2x16:
2029       assert(nir_op_infos[alu->op].num_inputs == 1);
2030       result = emit_builtin_unop(ctx, GLSLstd450PackHalf2x16, get_dest_type(ctx, &alu->dest.dest, nir_type_uint), src[0]);
2031       break;
2032 
2033    case nir_op_unpack_64_2x32:
2034       assert(nir_op_infos[alu->op].num_inputs == 1);
2035       result = emit_builtin_unop(ctx, GLSLstd450UnpackDouble2x32, get_dest_type(ctx, &alu->dest.dest, nir_type_uint), src[0]);
2036       break;
2037 
2038    BUILTIN_UNOPF(nir_op_unpack_half_2x16, GLSLstd450UnpackHalf2x16)
2039    BUILTIN_UNOPF(nir_op_pack_64_2x32, GLSLstd450PackDouble2x32)
2040 #undef BUILTIN_UNOP
2041 #undef BUILTIN_UNOPF
2042 
2043    case nir_op_frcp:
2044       assert(nir_op_infos[alu->op].num_inputs == 1);
2045       result = emit_binop(ctx, SpvOpFDiv, dest_type,
2046                           get_fvec_constant(ctx, bit_size, num_components, 1),
2047                           src[0]);
2048       break;
2049 
2050    case nir_op_f2b1:
2051       assert(nir_op_infos[alu->op].num_inputs == 1);
2052       result = emit_binop(ctx, SpvOpFOrdNotEqual, dest_type, src[0],
2053                           get_fvec_constant(ctx,
2054                                             nir_src_bit_size(alu->src[0].src),
2055                                             num_components, 0));
2056       break;
2057    case nir_op_i2b1:
2058       assert(nir_op_infos[alu->op].num_inputs == 1);
2059       result = emit_binop(ctx, SpvOpINotEqual, dest_type, src[0],
2060                           get_ivec_constant(ctx,
2061                                             nir_src_bit_size(alu->src[0].src),
2062                                             num_components, 0));
2063       break;
2064 
2065 
2066 #define BINOP(nir_op, spirv_op) \
2067    case nir_op: \
2068       assert(nir_op_infos[alu->op].num_inputs == 2); \
2069       result = emit_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
2070       break;
2071 
2072    BINOP(nir_op_iadd, SpvOpIAdd)
2073    BINOP(nir_op_isub, SpvOpISub)
2074    BINOP(nir_op_imul, SpvOpIMul)
2075    BINOP(nir_op_idiv, SpvOpSDiv)
2076    BINOP(nir_op_udiv, SpvOpUDiv)
2077    BINOP(nir_op_umod, SpvOpUMod)
2078    BINOP(nir_op_imod, SpvOpSMod)
2079    BINOP(nir_op_fadd, SpvOpFAdd)
2080    BINOP(nir_op_fsub, SpvOpFSub)
2081    BINOP(nir_op_fmul, SpvOpFMul)
2082    BINOP(nir_op_fdiv, SpvOpFDiv)
2083    BINOP(nir_op_fmod, SpvOpFMod)
2084    BINOP(nir_op_ilt, SpvOpSLessThan)
2085    BINOP(nir_op_ige, SpvOpSGreaterThanEqual)
2086    BINOP(nir_op_ult, SpvOpULessThan)
2087    BINOP(nir_op_uge, SpvOpUGreaterThanEqual)
2088    BINOP(nir_op_flt, SpvOpFOrdLessThan)
2089    BINOP(nir_op_fge, SpvOpFOrdGreaterThanEqual)
2090    BINOP(nir_op_frem, SpvOpFRem)
2091 #undef BINOP
2092 
2093 #define BINOP_LOG(nir_op, spv_op, spv_log_op) \
2094    case nir_op: \
2095       assert(nir_op_infos[alu->op].num_inputs == 2); \
2096       if (nir_src_bit_size(alu->src[0].src) == 1) \
2097          result = emit_binop(ctx, spv_log_op, dest_type, src[0], src[1]); \
2098       else \
2099          result = emit_binop(ctx, spv_op, dest_type, src[0], src[1]); \
2100       break;
2101 
2102    BINOP_LOG(nir_op_iand, SpvOpBitwiseAnd, SpvOpLogicalAnd)
2103    BINOP_LOG(nir_op_ior, SpvOpBitwiseOr, SpvOpLogicalOr)
2104    BINOP_LOG(nir_op_ieq, SpvOpIEqual, SpvOpLogicalEqual)
2105    BINOP_LOG(nir_op_ine, SpvOpINotEqual, SpvOpLogicalNotEqual)
2106    BINOP_LOG(nir_op_ixor, SpvOpBitwiseXor, SpvOpLogicalNotEqual)
2107 #undef BINOP_LOG
2108 
2109 #define BINOP_SHIFT(nir_op, spirv_op) \
2110    case nir_op: { \
2111       assert(nir_op_infos[alu->op].num_inputs == 2); \
2112       int shift_bit_size = nir_src_bit_size(alu->src[1].src); \
2113       nir_alu_type shift_nir_type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[1]); \
2114       SpvId shift_type = get_alu_type(ctx, shift_nir_type, num_components, shift_bit_size); \
2115       SpvId shift_mask = get_ivec_constant(ctx, shift_bit_size, num_components, bit_size - 1); \
2116       SpvId shift_count = emit_binop(ctx, SpvOpBitwiseAnd, shift_type, src[1], shift_mask); \
2117       result = emit_binop(ctx, spirv_op, dest_type, src[0], shift_count); \
2118       break; \
2119    }
2120 
2121    BINOP_SHIFT(nir_op_ishl, SpvOpShiftLeftLogical)
2122    BINOP_SHIFT(nir_op_ishr, SpvOpShiftRightArithmetic)
2123    BINOP_SHIFT(nir_op_ushr, SpvOpShiftRightLogical)
2124 #undef BINOP_SHIFT
2125 
2126 #define BUILTIN_BINOP(nir_op, spirv_op) \
2127    case nir_op: \
2128       assert(nir_op_infos[alu->op].num_inputs == 2); \
2129       result = emit_builtin_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
2130       break;
2131 
2132    BUILTIN_BINOP(nir_op_fmin, GLSLstd450FMin)
2133    BUILTIN_BINOP(nir_op_fmax, GLSLstd450FMax)
2134    BUILTIN_BINOP(nir_op_imin, GLSLstd450SMin)
2135    BUILTIN_BINOP(nir_op_imax, GLSLstd450SMax)
2136    BUILTIN_BINOP(nir_op_umin, GLSLstd450UMin)
2137    BUILTIN_BINOP(nir_op_umax, GLSLstd450UMax)
2138 #undef BUILTIN_BINOP
2139 
2140    case nir_op_fdot2:
2141    case nir_op_fdot3:
2142    case nir_op_fdot4:
2143       assert(nir_op_infos[alu->op].num_inputs == 2);
2144       result = emit_binop(ctx, SpvOpDot, dest_type, src[0], src[1]);
2145       break;
2146 
2147    case nir_op_fdph:
2148    case nir_op_seq:
2149    case nir_op_sne:
2150    case nir_op_slt:
2151    case nir_op_sge:
2152       unreachable("should already be lowered away");
2153 
2154    case nir_op_fneu:
2155       assert(nir_op_infos[alu->op].num_inputs == 2);
2156       if (raw_src[0] == raw_src[1])
2157          result =  emit_unop(ctx, SpvOpIsNan, dest_type, src[0]);
2158       else
2159          result = emit_binop(ctx, SpvOpFUnordNotEqual, dest_type, src[0], src[1]);
2160       break;
2161 
2162    case nir_op_feq:
2163       assert(nir_op_infos[alu->op].num_inputs == 2);
2164       if (raw_src[0] == raw_src[1])
2165          result =  emit_unop(ctx, SpvOpLogicalNot, dest_type,
2166                              emit_unop(ctx, SpvOpIsNan, dest_type, src[0]));
2167       else
2168          result = emit_binop(ctx, SpvOpFOrdEqual, dest_type, src[0], src[1]);
2169       break;
2170 
2171    case nir_op_flrp:
2172       assert(nir_op_infos[alu->op].num_inputs == 3);
2173       result = emit_builtin_triop(ctx, GLSLstd450FMix, dest_type,
2174                                   src[0], src[1], src[2]);
2175       break;
2176 
2177    case nir_op_bcsel:
2178       assert(nir_op_infos[alu->op].num_inputs == 3);
2179       result = emit_select(ctx, dest_type, src[0], src[1], src[2]);
2180       break;
2181 
2182    case nir_op_pack_half_2x16_split: {
2183       SpvId fvec = spirv_builder_emit_composite_construct(&ctx->builder, get_fvec_type(ctx, 32, 2),
2184                                                           src, 2);
2185       result = emit_builtin_unop(ctx, GLSLstd450PackHalf2x16, dest_type, fvec);
2186       break;
2187    }
2188    case nir_op_vec2:
2189    case nir_op_vec3:
2190    case nir_op_vec4: {
2191       int num_inputs = nir_op_infos[alu->op].num_inputs;
2192       assert(2 <= num_inputs && num_inputs <= 4);
2193       result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type,
2194                                                       src, num_inputs);
2195    }
2196    break;
2197 
2198    case nir_op_ubitfield_extract:
2199       assert(nir_op_infos[alu->op].num_inputs == 3);
2200       result = emit_triop(ctx, SpvOpBitFieldUExtract, dest_type, src[0], src[1], src[2]);
2201       break;
2202 
2203    case nir_op_ibitfield_extract:
2204       assert(nir_op_infos[alu->op].num_inputs == 3);
2205       result = emit_triop(ctx, SpvOpBitFieldSExtract, dest_type, src[0], src[1], src[2]);
2206       break;
2207 
2208    case nir_op_bitfield_insert:
2209       assert(nir_op_infos[alu->op].num_inputs == 4);
2210       result = spirv_builder_emit_quadop(&ctx->builder, SpvOpBitFieldInsert, dest_type, src[0], src[1], src[2], src[3]);
2211       break;
2212 
2213    case nir_op_pack_32_2x16_split:
2214    case nir_op_pack_64_2x32_split: {
2215       nir_alu_type type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[0]);
2216       if (num_components <= 2) {
2217          SpvId components[] = {src[0], src[1]};
2218          SpvId vec_type = get_alu_type(ctx, type, num_components * 2, nir_src_bit_size(alu->src[0].src));
2219          result = spirv_builder_emit_composite_construct(&ctx->builder, vec_type, components, 2);
2220          result = emit_bitcast(ctx, dest_type, result);
2221       } else {
2222          SpvId components[NIR_MAX_VEC_COMPONENTS];
2223          SpvId conv_type = get_alu_type(ctx, type, 1, nir_src_bit_size(alu->src[0].src));
2224          SpvId vec_type = get_alu_type(ctx, type, 2, nir_src_bit_size(alu->src[0].src));
2225          SpvId dest_scalar_type = get_alu_type(ctx, nir_op_infos[alu->op].output_type, 1, bit_size);
2226          for (unsigned i = 0; i < nir_src_num_components(alu->src[0].src); i++) {
2227             SpvId conv[2];
2228             conv[0] = spirv_builder_emit_composite_extract(&ctx->builder, conv_type, src[0], &i, 1);
2229             conv[1] = spirv_builder_emit_composite_extract(&ctx->builder, conv_type, src[1], &i, 1);
2230             SpvId vec = spirv_builder_emit_composite_construct(&ctx->builder, vec_type, conv, 2);
2231             components[i] = emit_bitcast(ctx, dest_scalar_type, vec);
2232          }
2233          result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, components, num_components);
2234       }
2235       break;
2236    }
2237 
2238    case nir_op_unpack_32_2x16_split_x:
2239    case nir_op_unpack_64_2x32_split_x: {
2240       nir_alu_type type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[0]);
2241       SpvId vec_type = get_alu_type(ctx, type, 2, bit_size);
2242       unsigned idx = 0;
2243       if (num_components == 1) {
2244          SpvId vec = emit_bitcast(ctx, vec_type, src[0]);
2245          result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, vec, &idx, 1);
2246       } else {
2247          SpvId components[NIR_MAX_VEC_COMPONENTS];
2248          for (unsigned i = 0; i < nir_src_num_components(alu->src[0].src); i++) {
2249             SpvId conv = spirv_builder_emit_composite_extract(&ctx->builder, get_alu_type(ctx, type, 1, nir_src_bit_size(alu->src[0].src)), src[0], &i, 1);
2250             conv = emit_bitcast(ctx, vec_type, conv);
2251             SpvId conv_type = get_alu_type(ctx, type, 1, bit_size);
2252             components[i] = spirv_builder_emit_composite_extract(&ctx->builder, conv_type, conv, &idx, 1);
2253          }
2254          result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, components, num_components);
2255       }
2256       break;
2257    }
2258 
2259    case nir_op_unpack_32_2x16_split_y:
2260    case nir_op_unpack_64_2x32_split_y: {
2261       nir_alu_type type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[0]);
2262       SpvId vec_type = get_alu_type(ctx, type, 2, bit_size);
2263       unsigned idx = 1;
2264       if (num_components == 1) {
2265          SpvId vec = emit_bitcast(ctx, vec_type, src[0]);
2266          result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, vec, &idx, 1);
2267       } else {
2268          SpvId components[NIR_MAX_VEC_COMPONENTS];
2269          for (unsigned i = 0; i < nir_src_num_components(alu->src[0].src); i++) {
2270             SpvId conv = spirv_builder_emit_composite_extract(&ctx->builder, get_alu_type(ctx, type, 1, nir_src_bit_size(alu->src[0].src)), src[0], &i, 1);
2271             conv = emit_bitcast(ctx, vec_type, conv);
2272             SpvId conv_type = get_alu_type(ctx, type, 1, bit_size);
2273             components[i] = spirv_builder_emit_composite_extract(&ctx->builder, conv_type, conv, &idx, 1);
2274          }
2275          result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, components, num_components);
2276       }
2277       break;
2278    }
2279 
2280    default:
2281       fprintf(stderr, "emit_alu: not implemented (%s)\n",
2282               nir_op_infos[alu->op].name);
2283 
2284       unreachable("unsupported opcode");
2285       return;
2286    }
2287    if (alu->exact)
2288       spirv_builder_emit_decoration(&ctx->builder, result, SpvDecorationNoContraction);
2289 
2290    store_alu_result(ctx, alu, result, force_float);
2291 }
2292 
2293 static void
emit_load_const(struct ntv_context * ctx,nir_load_const_instr * load_const)2294 emit_load_const(struct ntv_context *ctx, nir_load_const_instr *load_const)
2295 {
2296    unsigned bit_size = load_const->def.bit_size;
2297    unsigned num_components = load_const->def.num_components;
2298 
2299    SpvId components[NIR_MAX_VEC_COMPONENTS];
2300    if (bit_size == 1) {
2301       for (int i = 0; i < num_components; i++)
2302          components[i] = spirv_builder_const_bool(&ctx->builder,
2303                                                   load_const->value[i].b);
2304    } else {
2305       for (int i = 0; i < num_components; i++) {
2306          uint64_t tmp = nir_const_value_as_uint(load_const->value[i],
2307                                                 bit_size);
2308          components[i] = emit_uint_const(ctx, bit_size, tmp);
2309       }
2310    }
2311 
2312    if (num_components > 1) {
2313       SpvId type = get_vec_from_bit_size(ctx, bit_size,
2314                                          num_components);
2315       SpvId value = spirv_builder_const_composite(&ctx->builder,
2316                                                   type, components,
2317                                                   num_components);
2318       store_ssa_def(ctx, &load_const->def, value);
2319    } else {
2320       assert(num_components == 1);
2321       store_ssa_def(ctx, &load_const->def, components[0]);
2322    }
2323 }
2324 
2325 static void
emit_discard(struct ntv_context * ctx,nir_intrinsic_instr * intr)2326 emit_discard(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2327 {
2328    assert(ctx->discard_func);
2329    SpvId type_void = spirv_builder_type_void(&ctx->builder);
2330    spirv_builder_function_call(&ctx->builder, type_void,
2331                                ctx->discard_func, NULL, 0);
2332 }
2333 
2334 static void
emit_load_deref(struct ntv_context * ctx,nir_intrinsic_instr * intr)2335 emit_load_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2336 {
2337    SpvId ptr = get_src(ctx, intr->src);
2338 
2339    nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2340    SpvId type;
2341    if (glsl_type_is_image(deref->type)) {
2342       nir_variable *var = nir_deref_instr_get_variable(deref);
2343       type = get_image_type(ctx, var, glsl_type_is_sampler(glsl_without_array(var->type)));
2344    } else {
2345       type = get_glsl_type(ctx, deref->type);
2346    }
2347    SpvId result;
2348 
2349    if (nir_intrinsic_access(intr) & ACCESS_COHERENT)
2350       result = emit_atomic(ctx, SpvOpAtomicLoad, type, ptr, 0, 0);
2351    else
2352       result = spirv_builder_emit_load(&ctx->builder, type, ptr);
2353    unsigned num_components = nir_dest_num_components(intr->dest);
2354    unsigned bit_size = nir_dest_bit_size(intr->dest);
2355    result = bitcast_to_uvec(ctx, result, bit_size, num_components);
2356    store_dest(ctx, &intr->dest, result, nir_type_uint);
2357 }
2358 
2359 static void
emit_store_deref(struct ntv_context * ctx,nir_intrinsic_instr * intr)2360 emit_store_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2361 {
2362    SpvId ptr = get_src(ctx, &intr->src[0]);
2363    SpvId src = get_src(ctx, &intr->src[1]);
2364 
2365    const struct glsl_type *gtype = nir_src_as_deref(intr->src[0])->type;
2366    SpvId type = get_glsl_type(ctx, gtype);
2367    nir_variable *var = nir_deref_instr_get_variable(nir_src_as_deref(intr->src[0]));
2368    unsigned wrmask = nir_intrinsic_write_mask(intr);
2369    if (!glsl_type_is_scalar(gtype) &&
2370        wrmask != BITFIELD_MASK(glsl_type_is_array(gtype) ? glsl_get_aoa_size(gtype) : glsl_get_vector_elements(gtype))) {
2371       /* no idea what we do if this fails */
2372       assert(glsl_type_is_array(gtype) || glsl_type_is_vector(gtype));
2373 
2374       /* this is a partial write, so we have to loop and do a per-component write */
2375       SpvId result_type;
2376       SpvId member_type;
2377       if (glsl_type_is_vector(gtype)) {
2378          result_type = get_glsl_basetype(ctx, glsl_get_base_type(gtype));
2379          member_type = get_uvec_type(ctx, glsl_get_bit_size(gtype), 1);
2380       } else
2381          member_type = result_type = get_glsl_type(ctx, glsl_get_array_element(gtype));
2382       SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2383                                                   SpvStorageClassOutput,
2384                                                   result_type);
2385       for (unsigned i = 0; i < 4; i++)
2386          if (wrmask & BITFIELD_BIT(i)) {
2387             SpvId idx = emit_uint_const(ctx, 32, i);
2388             SpvId val = spirv_builder_emit_composite_extract(&ctx->builder, member_type, src, &i, 1);
2389             val = emit_bitcast(ctx, result_type, val);
2390             SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2391                                                            ptr, &idx, 1);
2392             spirv_builder_emit_store(&ctx->builder, member, val);
2393          }
2394       return;
2395 
2396    }
2397    SpvId result;
2398    if (ctx->stage == MESA_SHADER_FRAGMENT &&
2399        var->data.mode == nir_var_shader_out &&
2400        var->data.location == FRAG_RESULT_SAMPLE_MASK) {
2401       src = emit_bitcast(ctx, type, src);
2402       /* SampleMask is always an array in spirv, so we need to construct it into one */
2403       result = spirv_builder_emit_composite_construct(&ctx->builder, ctx->sample_mask_type, &src, 1);
2404    } else
2405       result = emit_bitcast(ctx, type, src);
2406    if (nir_intrinsic_access(intr) & ACCESS_COHERENT)
2407       spirv_builder_emit_atomic_store(&ctx->builder, ptr, SpvScopeDevice, 0, result);
2408    else
2409       spirv_builder_emit_store(&ctx->builder, ptr, result);
2410 }
2411 
2412 static void
emit_load_shared(struct ntv_context * ctx,nir_intrinsic_instr * intr)2413 emit_load_shared(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2414 {
2415    SpvId dest_type = get_dest_type(ctx, &intr->dest, nir_type_uint);
2416    unsigned num_components = nir_dest_num_components(intr->dest);
2417    unsigned bit_size = nir_dest_bit_size(intr->dest);
2418    SpvId uint_type = get_uvec_type(ctx, 32, 1);
2419    SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2420                                                SpvStorageClassWorkgroup,
2421                                                uint_type);
2422    SpvId offset = get_src(ctx, &intr->src[0]);
2423    SpvId constituents[NIR_MAX_VEC_COMPONENTS];
2424    /* need to convert array -> vec */
2425    for (unsigned i = 0; i < num_components; i++) {
2426       SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2427                                                      ctx->shared_block_var, &offset, 1);
2428       constituents[i] = spirv_builder_emit_load(&ctx->builder, uint_type, member);
2429       offset = emit_binop(ctx, SpvOpIAdd, uint_type, offset, emit_uint_const(ctx, 32, 1));
2430    }
2431    SpvId result;
2432    if (num_components > 1)
2433       result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, constituents, num_components);
2434    else
2435       result = bitcast_to_uvec(ctx, constituents[0], bit_size, num_components);
2436    store_dest(ctx, &intr->dest, result, nir_type_uint);
2437 }
2438 
2439 static void
emit_store_shared(struct ntv_context * ctx,nir_intrinsic_instr * intr)2440 emit_store_shared(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2441 {
2442    SpvId src = get_src(ctx, &intr->src[0]);
2443    bool qword = nir_src_bit_size(intr->src[0]) == 64;
2444 
2445    unsigned num_writes = util_bitcount(nir_intrinsic_write_mask(intr));
2446    unsigned wrmask = nir_intrinsic_write_mask(intr);
2447    /* this is a partial write, so we have to loop and do a per-component write */
2448    SpvId uint_type = get_uvec_type(ctx, 32, 1);
2449    SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2450                                                SpvStorageClassWorkgroup,
2451                                                uint_type);
2452    SpvId offset = get_src(ctx, &intr->src[1]);
2453 
2454    for (unsigned i = 0; num_writes; i++) {
2455       if ((wrmask >> i) & 1) {
2456          for (unsigned j = 0; j < 1 + !!qword; j++) {
2457             unsigned comp = ((1 + !!qword) * i) + j;
2458             SpvId shared_offset = emit_binop(ctx, SpvOpIAdd, uint_type, offset, emit_uint_const(ctx, 32, comp));
2459             SpvId val = src;
2460             if (nir_src_num_components(intr->src[0]) != 1 || qword)
2461                val = spirv_builder_emit_composite_extract(&ctx->builder, uint_type, src, &comp, 1);
2462             SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2463                                                            ctx->shared_block_var, &shared_offset, 1);
2464             spirv_builder_emit_store(&ctx->builder, member, val);
2465          }
2466          num_writes--;
2467       }
2468    }
2469 }
2470 
2471 static void
emit_load_push_const(struct ntv_context * ctx,nir_intrinsic_instr * intr)2472 emit_load_push_const(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2473 {
2474    SpvId uint_type = get_uvec_type(ctx, 32, 1);
2475    SpvId load_type = get_uvec_type(ctx, 32, 1);
2476 
2477    /* number of components being loaded */
2478    unsigned num_components = nir_dest_num_components(intr->dest);
2479    SpvId constituents[NIR_MAX_VEC_COMPONENTS * 2];
2480    SpvId result;
2481 
2482    /* destination type for the load */
2483    SpvId type = get_dest_uvec_type(ctx, &intr->dest);
2484    SpvId one = emit_uint_const(ctx, 32, 1);
2485 
2486    /* we grab a single array member at a time, so it's a pointer to a uint */
2487    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2488                                                    SpvStorageClassPushConstant,
2489                                                    load_type);
2490 
2491    SpvId member = get_src(ctx, &intr->src[0]);
2492    /* reuse the offset from ZINK_PUSH_CONST_OFFSET */
2493    SpvId offset = emit_uint_const(ctx, 32, 0);
2494    /* OpAccessChain takes an array of indices that drill into a hierarchy based on the type:
2495     * index 0 is accessing 'base'
2496     * index 1 is accessing 'base[index 1]'
2497     *
2498     */
2499    for (unsigned i = 0; i < num_components; i++) {
2500       SpvId indices[2] = { member, offset };
2501       SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2502                                                   ctx->push_const_var, indices,
2503                                                   ARRAY_SIZE(indices));
2504       /* load a single value into the constituents array */
2505       constituents[i] = spirv_builder_emit_load(&ctx->builder, load_type, ptr);
2506       /* increment to the next vec4 member index for the next load */
2507       offset = emit_binop(ctx, SpvOpIAdd, uint_type, offset, one);
2508    }
2509 
2510    /* if loading more than 1 value, reassemble the results into the desired type,
2511     * otherwise just use the loaded result
2512     */
2513    if (num_components > 1) {
2514       result = spirv_builder_emit_composite_construct(&ctx->builder,
2515                                                       type,
2516                                                       constituents,
2517                                                       num_components);
2518    } else
2519       result = constituents[0];
2520 
2521    store_dest(ctx, &intr->dest, result, nir_type_uint);
2522 }
2523 
2524 static SpvId
create_builtin_var(struct ntv_context * ctx,SpvId var_type,SpvStorageClass storage_class,const char * name,SpvBuiltIn builtin)2525 create_builtin_var(struct ntv_context *ctx, SpvId var_type,
2526                    SpvStorageClass storage_class,
2527                    const char *name, SpvBuiltIn builtin)
2528 {
2529    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2530                                                    storage_class,
2531                                                    var_type);
2532    SpvId var = spirv_builder_emit_var(&ctx->builder, pointer_type,
2533                                       storage_class);
2534    spirv_builder_emit_name(&ctx->builder, var, name);
2535    spirv_builder_emit_builtin(&ctx->builder, var, builtin);
2536 
2537    assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
2538    ctx->entry_ifaces[ctx->num_entry_ifaces++] = var;
2539    return var;
2540 }
2541 
2542 static void
emit_load_front_face(struct ntv_context * ctx,nir_intrinsic_instr * intr)2543 emit_load_front_face(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2544 {
2545    SpvId var_type = spirv_builder_type_bool(&ctx->builder);
2546    if (!ctx->front_face_var)
2547       ctx->front_face_var = create_builtin_var(ctx, var_type,
2548                                                SpvStorageClassInput,
2549                                                "gl_FrontFacing",
2550                                                SpvBuiltInFrontFacing);
2551 
2552    SpvId result = spirv_builder_emit_load(&ctx->builder, var_type,
2553                                           ctx->front_face_var);
2554    assert(1 == nir_dest_num_components(intr->dest));
2555    store_dest(ctx, &intr->dest, result, nir_type_bool);
2556 }
2557 
2558 static void
emit_load_uint_input(struct ntv_context * ctx,nir_intrinsic_instr * intr,SpvId * var_id,const char * var_name,SpvBuiltIn builtin)2559 emit_load_uint_input(struct ntv_context *ctx, nir_intrinsic_instr *intr, SpvId *var_id, const char *var_name, SpvBuiltIn builtin)
2560 {
2561    SpvId var_type = spirv_builder_type_uint(&ctx->builder, 32);
2562    if (!*var_id) {
2563       if (builtin == SpvBuiltInSampleMask) {
2564          /* gl_SampleMaskIn is an array[1] in spirv... */
2565          var_type = spirv_builder_type_array(&ctx->builder, var_type, emit_uint_const(ctx, 32, 1));
2566          spirv_builder_emit_array_stride(&ctx->builder, var_type, sizeof(uint32_t));
2567       }
2568       *var_id = create_builtin_var(ctx, var_type,
2569                                    SpvStorageClassInput,
2570                                    var_name,
2571                                    builtin);
2572       if (builtin == SpvBuiltInSampleMask) {
2573          SpvId zero = emit_uint_const(ctx, 32, 0);
2574          var_type = spirv_builder_type_uint(&ctx->builder, 32);
2575          SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2576                                                          SpvStorageClassInput,
2577                                                          var_type);
2578          *var_id = spirv_builder_emit_access_chain(&ctx->builder, pointer_type, *var_id, &zero, 1);
2579       }
2580    }
2581 
2582    SpvId result = spirv_builder_emit_load(&ctx->builder, var_type, *var_id);
2583    assert(1 == nir_dest_num_components(intr->dest));
2584    store_dest(ctx, &intr->dest, result, nir_type_uint);
2585 }
2586 
2587 static void
emit_load_vec_input(struct ntv_context * ctx,nir_intrinsic_instr * intr,SpvId * var_id,const char * var_name,SpvBuiltIn builtin,nir_alu_type type)2588 emit_load_vec_input(struct ntv_context *ctx, nir_intrinsic_instr *intr, SpvId *var_id, const char *var_name, SpvBuiltIn builtin, nir_alu_type type)
2589 {
2590    SpvId var_type;
2591 
2592    switch (type) {
2593    case nir_type_bool:
2594       var_type = get_bvec_type(ctx, nir_dest_num_components(intr->dest));
2595       break;
2596    case nir_type_int:
2597       var_type = get_ivec_type(ctx, nir_dest_bit_size(intr->dest), nir_dest_num_components(intr->dest));
2598       break;
2599    case nir_type_uint:
2600       var_type = get_uvec_type(ctx, nir_dest_bit_size(intr->dest), nir_dest_num_components(intr->dest));
2601       break;
2602    case nir_type_float:
2603       var_type = get_fvec_type(ctx, nir_dest_bit_size(intr->dest), nir_dest_num_components(intr->dest));
2604       break;
2605    default:
2606       unreachable("unknown type passed");
2607    }
2608    if (!*var_id)
2609       *var_id = create_builtin_var(ctx, var_type,
2610                                    SpvStorageClassInput,
2611                                    var_name,
2612                                    builtin);
2613 
2614    SpvId result = spirv_builder_emit_load(&ctx->builder, var_type, *var_id);
2615    store_dest(ctx, &intr->dest, result, type);
2616 }
2617 
2618 static void
emit_interpolate(struct ntv_context * ctx,nir_intrinsic_instr * intr)2619 emit_interpolate(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2620 {
2621    SpvId op;
2622    spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInterpolationFunction);
2623    SpvId src1 = 0;
2624    switch (intr->intrinsic) {
2625    case nir_intrinsic_interp_deref_at_centroid:
2626       op = GLSLstd450InterpolateAtCentroid;
2627       break;
2628    case nir_intrinsic_interp_deref_at_sample:
2629       op = GLSLstd450InterpolateAtSample;
2630       src1 = get_src(ctx, &intr->src[1]);
2631       break;
2632    case nir_intrinsic_interp_deref_at_offset:
2633       op = GLSLstd450InterpolateAtOffset;
2634       src1 = get_src(ctx, &intr->src[1]);
2635       /*
2636          The offset operand must be a vector of 2 components of 32-bit floating-point type.
2637          - InterpolateAtOffset spec
2638        */
2639       src1 = emit_bitcast(ctx, get_fvec_type(ctx, 32, 2), src1);
2640       break;
2641    default:
2642       unreachable("unknown interp op");
2643    }
2644    SpvId ptr = get_src(ctx, &intr->src[0]);
2645    SpvId result;
2646    if (intr->intrinsic == nir_intrinsic_interp_deref_at_centroid)
2647       result = emit_builtin_unop(ctx, op, get_glsl_type(ctx, nir_src_as_deref(intr->src[0])->type), ptr);
2648    else
2649       result = emit_builtin_binop(ctx, op, get_glsl_type(ctx, nir_src_as_deref(intr->src[0])->type),
2650                                   ptr, src1);
2651    unsigned num_components = nir_dest_num_components(intr->dest);
2652    unsigned bit_size = nir_dest_bit_size(intr->dest);
2653    result = bitcast_to_uvec(ctx, result, bit_size, num_components);
2654    store_dest(ctx, &intr->dest, result, nir_type_uint);
2655 }
2656 
2657 static void
handle_atomic_op(struct ntv_context * ctx,nir_intrinsic_instr * intr,SpvId ptr,SpvId param,SpvId param2,nir_alu_type type)2658 handle_atomic_op(struct ntv_context *ctx, nir_intrinsic_instr *intr, SpvId ptr, SpvId param, SpvId param2, nir_alu_type type)
2659 {
2660    SpvId dest_type = get_dest_type(ctx, &intr->dest, type);
2661    SpvId result = emit_atomic(ctx, get_atomic_op(intr->intrinsic), dest_type, ptr, param, param2);
2662    assert(result);
2663    store_dest(ctx, &intr->dest, result, type);
2664 }
2665 
2666 static void
emit_deref_atomic_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2667 emit_deref_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2668 {
2669    SpvId ptr = get_src(ctx, &intr->src[0]);
2670    SpvId param = get_src(ctx, &intr->src[1]);
2671 
2672    SpvId param2 = 0;
2673 
2674    if (intr->intrinsic == nir_intrinsic_deref_atomic_comp_swap)
2675       param2 = get_src(ctx, &intr->src[2]);
2676 
2677    handle_atomic_op(ctx, intr, ptr, param, param2, nir_type_uint32);
2678 }
2679 
2680 static void
emit_shared_atomic_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2681 emit_shared_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2682 {
2683    SpvId dest_type = get_dest_type(ctx, &intr->dest, nir_type_uint32);
2684    SpvId param = get_src(ctx, &intr->src[1]);
2685 
2686    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2687                                                    SpvStorageClassWorkgroup,
2688                                                    dest_type);
2689    SpvId offset = emit_binop(ctx, SpvOpUDiv, get_uvec_type(ctx, 32, 1), get_src(ctx, &intr->src[0]), emit_uint_const(ctx, 32, 4));
2690    SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2691                                                ctx->shared_block_var, &offset, 1);
2692 
2693    SpvId param2 = 0;
2694 
2695    if (intr->intrinsic == nir_intrinsic_shared_atomic_comp_swap)
2696       param2 = get_src(ctx, &intr->src[2]);
2697 
2698    handle_atomic_op(ctx, intr, ptr, param, param2, nir_type_uint32);
2699 }
2700 
2701 static void
emit_get_ssbo_size(struct ntv_context * ctx,nir_intrinsic_instr * intr)2702 emit_get_ssbo_size(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2703 {
2704    SpvId uint_type = get_uvec_type(ctx, 32, 1);
2705    nir_variable *var = ctx->ssbo_vars;
2706    const struct glsl_type *bare_type = glsl_without_array(var->type);
2707    unsigned last_member_idx = glsl_get_length(bare_type) - 1;
2708    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2709                                                    SpvStorageClassStorageBuffer,
2710                                                    get_bo_struct_type(ctx, var));
2711    SpvId bo = get_src(ctx, &intr->src[0]);
2712    SpvId indices[] = { bo };
2713    SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2714                                                ctx->ssbos[2], indices,
2715                                                ARRAY_SIZE(indices));
2716    SpvId result = spirv_builder_emit_binop(&ctx->builder, SpvOpArrayLength, uint_type,
2717                                            ptr, last_member_idx);
2718    /* this is going to be converted by nir to:
2719 
2720       length = (buffer_size - offset) / stride
2721 
2722       * so we need to un-convert it to avoid having the calculation performed twice
2723       */
2724    const struct glsl_type *last_member = glsl_get_struct_field(bare_type, last_member_idx);
2725    /* multiply by stride */
2726    result = emit_binop(ctx, SpvOpIMul, uint_type, result, emit_uint_const(ctx, 32, glsl_get_explicit_stride(last_member)));
2727    /* get total ssbo size by adding offset */
2728    result = emit_binop(ctx, SpvOpIAdd, uint_type, result,
2729                         emit_uint_const(ctx, 32,
2730                                        glsl_get_struct_field_offset(bare_type, last_member_idx)));
2731    store_dest(ctx, &intr->dest, result, nir_type_uint);
2732 }
2733 
2734 static inline nir_variable *
get_var_from_image(struct ntv_context * ctx,SpvId var_id)2735 get_var_from_image(struct ntv_context *ctx, SpvId var_id)
2736 {
2737    struct hash_entry *he = _mesa_hash_table_search(ctx->image_vars, &var_id);
2738    assert(he);
2739    return he->data;
2740 }
2741 
2742 static SpvId
get_image_coords(struct ntv_context * ctx,const struct glsl_type * type,nir_src * src)2743 get_image_coords(struct ntv_context *ctx, const struct glsl_type *type, nir_src *src)
2744 {
2745    uint32_t num_coords = glsl_get_sampler_coordinate_components(type);
2746    uint32_t src_components = nir_src_num_components(*src);
2747 
2748    SpvId spv = get_src(ctx, src);
2749    if (num_coords == src_components)
2750       return spv;
2751 
2752    /* need to extract the coord dimensions that the image can use */
2753    SpvId vec_type = get_uvec_type(ctx, 32, num_coords);
2754    if (num_coords == 1)
2755       return spirv_builder_emit_vector_extract(&ctx->builder, vec_type, spv, 0);
2756    uint32_t constituents[4];
2757    SpvId zero = emit_uint_const(ctx, nir_src_bit_size(*src), 0);
2758    assert(num_coords < ARRAY_SIZE(constituents));
2759    for (unsigned i = 0; i < num_coords; i++)
2760       constituents[i] = i < src_components ? i : zero;
2761    return spirv_builder_emit_vector_shuffle(&ctx->builder, vec_type, spv, spv, constituents, num_coords);
2762 }
2763 
2764 static void
emit_image_deref_store(struct ntv_context * ctx,nir_intrinsic_instr * intr)2765 emit_image_deref_store(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2766 {
2767    SpvId img_var = get_src(ctx, &intr->src[0]);
2768    nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2769    nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
2770    SpvId img_type = var->data.bindless ? get_bare_image_type(ctx, var, false) : ctx->image_types[var->data.driver_location];
2771    const struct glsl_type *type = glsl_without_array(var->type);
2772    SpvId base_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
2773    SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
2774    SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
2775    SpvId texel = get_src(ctx, &intr->src[3]);
2776    bool use_sample = glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_MS ||
2777                      glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_SUBPASS_MS;
2778    SpvId sample = use_sample ? get_src(ctx, &intr->src[2]) : 0;
2779    assert(nir_src_bit_size(intr->src[3]) == glsl_base_type_bit_size(glsl_get_sampler_result_type(type)));
2780    /* texel type must match image type */
2781    texel = emit_bitcast(ctx,
2782                         spirv_builder_type_vector(&ctx->builder, base_type, 4),
2783                         texel);
2784    spirv_builder_emit_image_write(&ctx->builder, img, coord, texel, 0, sample, 0);
2785 }
2786 
2787 static SpvId
extract_sparse_load(struct ntv_context * ctx,SpvId result,SpvId dest_type,nir_ssa_def * dest_ssa)2788 extract_sparse_load(struct ntv_context *ctx, SpvId result, SpvId dest_type, nir_ssa_def *dest_ssa)
2789 {
2790    /* Result Type must be an OpTypeStruct with two members.
2791     * The first member’s type must be an integer type scalar.
2792     * It holds a Residency Code that can be passed to OpImageSparseTexelsResident
2793     * - OpImageSparseRead spec
2794     */
2795    uint32_t idx = 0;
2796    SpvId resident = spirv_builder_emit_composite_extract(&ctx->builder, spirv_builder_type_uint(&ctx->builder, 32), result, &idx, 1);
2797    idx = 1;
2798    /* normal vec4 return */
2799    if (dest_ssa->num_components == 4)
2800       result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, result, &idx, 1);
2801    else {
2802       /* shadow */
2803       assert(dest_ssa->num_components == 1);
2804       SpvId type = spirv_builder_type_float(&ctx->builder, dest_ssa->bit_size);
2805       SpvId val[2];
2806       /* pad to 2 components: the upcoming is_sparse_texels_resident instr will always use the
2807        * separate residency value, but the shader still expects this return to be a vec2,
2808        * so give it a vec2
2809        */
2810       val[0] = spirv_builder_emit_composite_extract(&ctx->builder, type, result, &idx, 1);
2811       val[1] = emit_float_const(ctx, dest_ssa->bit_size, 0);
2812       result = spirv_builder_emit_composite_construct(&ctx->builder, get_fvec_type(ctx, dest_ssa->bit_size, 2), val, 2);
2813    }
2814    assert(resident != 0);
2815    assert(dest_ssa->index < ctx->num_defs);
2816    ctx->resident_defs[dest_ssa->index] = resident;
2817    return result;
2818 }
2819 
2820 static void
emit_image_deref_load(struct ntv_context * ctx,nir_intrinsic_instr * intr)2821 emit_image_deref_load(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2822 {
2823    bool sparse = intr->intrinsic == nir_intrinsic_image_deref_sparse_load;
2824    SpvId img_var = get_src(ctx, &intr->src[0]);
2825    nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2826    nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
2827    SpvId img_type = var->data.bindless ? get_bare_image_type(ctx, var, false) : ctx->image_types[var->data.driver_location];
2828    const struct glsl_type *type = glsl_without_array(var->type);
2829    SpvId base_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
2830    SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
2831    SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
2832    bool use_sample = glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_MS ||
2833                      glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_SUBPASS_MS;
2834    SpvId sample = use_sample ? get_src(ctx, &intr->src[2]) : 0;
2835    SpvId dest_type = spirv_builder_type_vector(&ctx->builder, base_type, nir_dest_num_components(intr->dest));
2836    SpvId result = spirv_builder_emit_image_read(&ctx->builder,
2837                                  dest_type,
2838                                  img, coord, 0, sample, 0, sparse);
2839    if (sparse)
2840       result = extract_sparse_load(ctx, result, dest_type, &intr->dest.ssa);
2841    store_dest(ctx, &intr->dest, result, nir_type_float);
2842 }
2843 
2844 static void
emit_image_deref_size(struct ntv_context * ctx,nir_intrinsic_instr * intr)2845 emit_image_deref_size(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2846 {
2847    SpvId img_var = get_src(ctx, &intr->src[0]);
2848    nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2849    nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
2850    SpvId img_type = var->data.bindless ? get_bare_image_type(ctx, var, false) : ctx->image_types[var->data.driver_location];
2851    const struct glsl_type *type = glsl_without_array(var->type);
2852    SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
2853    unsigned num_components = glsl_get_sampler_coordinate_components(type);
2854    /* SPIRV requires 2 components for non-array cube size */
2855    if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE && !glsl_sampler_type_is_array(type))
2856       num_components = 2;
2857 
2858    spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
2859    SpvId result = spirv_builder_emit_image_query_size(&ctx->builder, get_uvec_type(ctx, 32, num_components), img, 0);
2860    store_dest(ctx, &intr->dest, result, nir_type_uint);
2861 }
2862 
2863 static void
emit_image_deref_samples(struct ntv_context * ctx,nir_intrinsic_instr * intr)2864 emit_image_deref_samples(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2865 {
2866    SpvId img_var = get_src(ctx, &intr->src[0]);
2867    nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2868    nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
2869    SpvId img_type = var->data.bindless ? get_bare_image_type(ctx, var, false) : ctx->image_types[var->data.driver_location];
2870    SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
2871 
2872    spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
2873    SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageQuerySamples, get_dest_type(ctx, &intr->dest, nir_type_uint), img);
2874    store_dest(ctx, &intr->dest, result, nir_type_uint);
2875 }
2876 
2877 static void
emit_image_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2878 emit_image_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2879 {
2880    SpvId param = get_src(ctx, &intr->src[3]);
2881    SpvId img_var = get_src(ctx, &intr->src[0]);
2882    nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2883    nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
2884    const struct glsl_type *type = glsl_without_array(var->type);
2885    bool is_ms;
2886    type_to_dim(glsl_get_sampler_dim(type), &is_ms);
2887    SpvId sample = is_ms ? get_src(ctx, &intr->src[2]) : emit_uint_const(ctx, 32, 0);
2888    SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
2889    enum glsl_base_type glsl_type = glsl_get_sampler_result_type(type);
2890    SpvId base_type = get_glsl_basetype(ctx, glsl_type);
2891    SpvId texel = spirv_builder_emit_image_texel_pointer(&ctx->builder, base_type, img_var, coord, sample);
2892    SpvId param2 = 0;
2893 
2894    /* The type of Value must be the same as Result Type.
2895     * The type of the value pointed to by Pointer must be the same as Result Type.
2896     */
2897    nir_alu_type ntype = nir_get_nir_type_for_glsl_base_type(glsl_type);
2898    SpvId cast_type = get_dest_type(ctx, &intr->dest, ntype);
2899    param = emit_bitcast(ctx, cast_type, param);
2900 
2901    if (intr->intrinsic == nir_intrinsic_image_deref_atomic_comp_swap) {
2902       param2 = get_src(ctx, &intr->src[4]);
2903       param2 = emit_bitcast(ctx, cast_type, param2);
2904    }
2905 
2906    handle_atomic_op(ctx, intr, texel, param, param2, ntype);
2907 }
2908 
2909 static void
emit_ballot(struct ntv_context * ctx,nir_intrinsic_instr * intr)2910 emit_ballot(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2911 {
2912    spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
2913    spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
2914    SpvId type = get_dest_uvec_type(ctx, &intr->dest);
2915    SpvId result = emit_unop(ctx, SpvOpSubgroupBallotKHR, type, get_src(ctx, &intr->src[0]));
2916    store_dest(ctx, &intr->dest, result, nir_type_uint);
2917 }
2918 
2919 static void
emit_read_first_invocation(struct ntv_context * ctx,nir_intrinsic_instr * intr)2920 emit_read_first_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2921 {
2922    spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
2923    spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
2924    SpvId type = get_dest_type(ctx, &intr->dest, nir_type_uint);
2925    SpvId result = emit_unop(ctx, SpvOpSubgroupFirstInvocationKHR, type, get_src(ctx, &intr->src[0]));
2926    store_dest(ctx, &intr->dest, result, nir_type_uint);
2927 }
2928 
2929 static void
emit_read_invocation(struct ntv_context * ctx,nir_intrinsic_instr * intr)2930 emit_read_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2931 {
2932    spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
2933    spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
2934    SpvId type = get_dest_type(ctx, &intr->dest, nir_type_uint);
2935    SpvId result = emit_binop(ctx, SpvOpSubgroupReadInvocationKHR, type,
2936                               get_src(ctx, &intr->src[0]),
2937                               get_src(ctx, &intr->src[1]));
2938    store_dest(ctx, &intr->dest, result, nir_type_uint);
2939 }
2940 
2941 static void
emit_shader_clock(struct ntv_context * ctx,nir_intrinsic_instr * intr)2942 emit_shader_clock(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2943 {
2944    spirv_builder_emit_cap(&ctx->builder, SpvCapabilityShaderClockKHR);
2945    spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_clock");
2946 
2947    SpvScope scope = get_scope(nir_intrinsic_memory_scope(intr));
2948    SpvId type = get_dest_type(ctx, &intr->dest, nir_type_uint);
2949    SpvId result = spirv_builder_emit_unop_const(&ctx->builder, SpvOpReadClockKHR, type, scope);
2950    store_dest(ctx, &intr->dest, result, nir_type_uint);
2951 }
2952 
2953 static void
emit_is_sparse_texels_resident(struct ntv_context * ctx,nir_intrinsic_instr * intr)2954 emit_is_sparse_texels_resident(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2955 {
2956    spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySparseResidency);
2957 
2958    SpvId type = get_dest_type(ctx, &intr->dest, nir_type_uint);
2959 
2960    /* this will always be stored with the ssa index of the parent instr */
2961    assert(intr->src[0].is_ssa);
2962    nir_ssa_def *ssa = intr->src[0].ssa;
2963    assert(ssa->parent_instr->type == nir_instr_type_alu);
2964    nir_alu_instr *alu = nir_instr_as_alu(ssa->parent_instr);
2965    assert(alu->src[0].src.is_ssa);
2966    unsigned index = alu->src[0].src.ssa->index;
2967    assert(index < ctx->num_defs);
2968    assert(ctx->resident_defs[index] != 0);
2969    SpvId resident = ctx->resident_defs[index];
2970 
2971    SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageSparseTexelsResident, type, resident);
2972    store_dest(ctx, &intr->dest, result, nir_type_uint);
2973 }
2974 
2975 static void
emit_vote(struct ntv_context * ctx,nir_intrinsic_instr * intr)2976 emit_vote(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2977 {
2978    SpvOp op;
2979 
2980    switch (intr->intrinsic) {
2981    case nir_intrinsic_vote_all:
2982       op = SpvOpGroupNonUniformAll;
2983       break;
2984    case nir_intrinsic_vote_any:
2985       op = SpvOpGroupNonUniformAny;
2986       break;
2987    case nir_intrinsic_vote_ieq:
2988    case nir_intrinsic_vote_feq:
2989       op = SpvOpGroupNonUniformAllEqual;
2990       break;
2991    default:
2992       unreachable("unknown vote intrinsic");
2993    }
2994    spirv_builder_emit_cap(&ctx->builder, SpvCapabilityGroupNonUniformVote);
2995    SpvId result = spirv_builder_emit_vote(&ctx->builder, op, get_src(ctx, &intr->src[0]));
2996    store_dest_raw(ctx, &intr->dest, result);
2997 }
2998 
2999 static void
emit_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)3000 emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3001 {
3002    switch (intr->intrinsic) {
3003    case nir_intrinsic_discard:
3004       emit_discard(ctx, intr);
3005       break;
3006 
3007    case nir_intrinsic_load_deref:
3008       emit_load_deref(ctx, intr);
3009       break;
3010 
3011    case nir_intrinsic_store_deref:
3012       emit_store_deref(ctx, intr);
3013       break;
3014 
3015    case nir_intrinsic_load_push_constant:
3016       emit_load_push_const(ctx, intr);
3017       break;
3018 
3019    case nir_intrinsic_load_front_face:
3020       emit_load_front_face(ctx, intr);
3021       break;
3022 
3023    case nir_intrinsic_load_base_instance:
3024       emit_load_uint_input(ctx, intr, &ctx->base_instance_var, "gl_BaseInstance", SpvBuiltInBaseInstance);
3025       break;
3026 
3027    case nir_intrinsic_load_instance_id:
3028       emit_load_uint_input(ctx, intr, &ctx->instance_id_var, "gl_InstanceId", SpvBuiltInInstanceIndex);
3029       break;
3030 
3031    case nir_intrinsic_load_base_vertex:
3032       emit_load_uint_input(ctx, intr, &ctx->base_vertex_var, "gl_BaseVertex", SpvBuiltInBaseVertex);
3033       break;
3034 
3035    case nir_intrinsic_load_draw_id:
3036       emit_load_uint_input(ctx, intr, &ctx->draw_id_var, "gl_DrawID", SpvBuiltInDrawIndex);
3037       break;
3038 
3039    case nir_intrinsic_load_vertex_id:
3040       emit_load_uint_input(ctx, intr, &ctx->vertex_id_var, "gl_VertexId", SpvBuiltInVertexIndex);
3041       break;
3042 
3043    case nir_intrinsic_load_primitive_id:
3044       emit_load_uint_input(ctx, intr, &ctx->primitive_id_var, "gl_PrimitiveIdIn", SpvBuiltInPrimitiveId);
3045       break;
3046 
3047    case nir_intrinsic_load_invocation_id:
3048       emit_load_uint_input(ctx, intr, &ctx->invocation_id_var, "gl_InvocationId", SpvBuiltInInvocationId);
3049       break;
3050 
3051    case nir_intrinsic_load_sample_id:
3052       emit_load_uint_input(ctx, intr, &ctx->sample_id_var, "gl_SampleId", SpvBuiltInSampleId);
3053       break;
3054 
3055    case nir_intrinsic_load_sample_pos:
3056       emit_load_vec_input(ctx, intr, &ctx->sample_pos_var, "gl_SamplePosition", SpvBuiltInSamplePosition, nir_type_float);
3057       break;
3058 
3059    case nir_intrinsic_load_sample_mask_in:
3060       emit_load_uint_input(ctx, intr, &ctx->sample_mask_in_var, "gl_SampleMaskIn", SpvBuiltInSampleMask);
3061       break;
3062 
3063    case nir_intrinsic_emit_vertex_with_counter:
3064       /* geometry shader emits copied xfb outputs just prior to EmitVertex(),
3065        * since that's the end of the shader
3066        */
3067       if (ctx->sinfo)
3068          emit_so_outputs(ctx, ctx->sinfo);
3069       if (ctx->nir->info.gs.vertices_out) //skip vertex emission if !vertices_out
3070          spirv_builder_emit_vertex(&ctx->builder, nir_intrinsic_stream_id(intr),
3071                                    ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
3072       break;
3073 
3074    case nir_intrinsic_set_vertex_and_primitive_count:
3075       /* do nothing */
3076       break;
3077 
3078    case nir_intrinsic_end_primitive_with_counter:
3079       spirv_builder_end_primitive(&ctx->builder, nir_intrinsic_stream_id(intr),
3080                                   ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
3081       break;
3082 
3083    case nir_intrinsic_load_helper_invocation:
3084       emit_load_vec_input(ctx, intr, &ctx->helper_invocation_var, "gl_HelperInvocation", SpvBuiltInHelperInvocation, nir_type_bool);
3085       break;
3086 
3087    case nir_intrinsic_load_patch_vertices_in:
3088       emit_load_vec_input(ctx, intr, &ctx->tess_patch_vertices_in, "gl_PatchVerticesIn",
3089                           SpvBuiltInPatchVertices, nir_type_int);
3090       break;
3091 
3092    case nir_intrinsic_load_tess_coord:
3093       emit_load_vec_input(ctx, intr, &ctx->tess_coord_var, "gl_TessCoord",
3094                           SpvBuiltInTessCoord, nir_type_float);
3095       break;
3096 
3097    case nir_intrinsic_memory_barrier_tcs_patch:
3098       /* handled by subsequent nir_intrinsic_control_barrier */
3099       break;
3100 
3101    case nir_intrinsic_memory_barrier:
3102       spirv_builder_emit_memory_barrier(&ctx->builder,
3103                                         ctx->sinfo->have_vulkan_memory_model ? SpvScopeQueueFamily : SpvScopeDevice,
3104                                         SpvMemorySemanticsImageMemoryMask |
3105                                         SpvMemorySemanticsUniformMemoryMask |
3106                                         SpvMemorySemanticsWorkgroupMemoryMask |
3107                                         SpvMemorySemanticsAtomicCounterMemoryMask |
3108                                         SpvMemorySemanticsAcquireReleaseMask);
3109       break;
3110 
3111    case nir_intrinsic_memory_barrier_image:
3112       spirv_builder_emit_memory_barrier(&ctx->builder, SpvScopeDevice,
3113                                         SpvMemorySemanticsImageMemoryMask |
3114                                         SpvMemorySemanticsAcquireReleaseMask);
3115       break;
3116 
3117    case nir_intrinsic_group_memory_barrier:
3118       spirv_builder_emit_memory_barrier(&ctx->builder, SpvScopeWorkgroup,
3119                                         SpvMemorySemanticsImageMemoryMask |
3120                                         SpvMemorySemanticsUniformMemoryMask |
3121                                         SpvMemorySemanticsWorkgroupMemoryMask |
3122                                         SpvMemorySemanticsAtomicCounterMemoryMask |
3123                                         SpvMemorySemanticsAcquireReleaseMask);
3124       break;
3125 
3126    case nir_intrinsic_memory_barrier_shared:
3127       spirv_builder_emit_memory_barrier(&ctx->builder, SpvScopeWorkgroup,
3128                                         SpvMemorySemanticsWorkgroupMemoryMask |
3129                                         SpvMemorySemanticsAcquireReleaseMask);
3130       break;
3131 
3132    case nir_intrinsic_control_barrier:
3133       if (ctx->stage == MESA_SHADER_COMPUTE)
3134          spirv_builder_emit_control_barrier(&ctx->builder, SpvScopeWorkgroup,
3135                                             SpvScopeWorkgroup,
3136                                             SpvMemorySemanticsWorkgroupMemoryMask | SpvMemorySemanticsAcquireReleaseMask);
3137       else if (ctx->sinfo->have_vulkan_memory_model)
3138          spirv_builder_emit_control_barrier(&ctx->builder, SpvScopeWorkgroup,
3139                                             SpvScopeWorkgroup,
3140                                             SpvMemorySemanticsOutputMemoryMask | SpvMemorySemanticsAcquireReleaseMask);
3141       else
3142          spirv_builder_emit_control_barrier(&ctx->builder, SpvScopeWorkgroup, SpvScopeInvocation, 0);
3143       break;
3144 
3145    case nir_intrinsic_interp_deref_at_centroid:
3146    case nir_intrinsic_interp_deref_at_sample:
3147    case nir_intrinsic_interp_deref_at_offset:
3148       emit_interpolate(ctx, intr);
3149       break;
3150 
3151    case nir_intrinsic_memory_barrier_buffer:
3152       spirv_builder_emit_memory_barrier(&ctx->builder, SpvScopeDevice,
3153                                         SpvMemorySemanticsUniformMemoryMask |
3154                                         SpvMemorySemanticsAcquireReleaseMask);
3155       break;
3156 
3157    case nir_intrinsic_deref_atomic_add:
3158    case nir_intrinsic_deref_atomic_umin:
3159    case nir_intrinsic_deref_atomic_imin:
3160    case nir_intrinsic_deref_atomic_umax:
3161    case nir_intrinsic_deref_atomic_imax:
3162    case nir_intrinsic_deref_atomic_and:
3163    case nir_intrinsic_deref_atomic_or:
3164    case nir_intrinsic_deref_atomic_xor:
3165    case nir_intrinsic_deref_atomic_exchange:
3166    case nir_intrinsic_deref_atomic_comp_swap:
3167       emit_deref_atomic_intrinsic(ctx, intr);
3168       break;
3169 
3170    case nir_intrinsic_shared_atomic_add:
3171    case nir_intrinsic_shared_atomic_umin:
3172    case nir_intrinsic_shared_atomic_imin:
3173    case nir_intrinsic_shared_atomic_umax:
3174    case nir_intrinsic_shared_atomic_imax:
3175    case nir_intrinsic_shared_atomic_and:
3176    case nir_intrinsic_shared_atomic_or:
3177    case nir_intrinsic_shared_atomic_xor:
3178    case nir_intrinsic_shared_atomic_exchange:
3179    case nir_intrinsic_shared_atomic_comp_swap:
3180       emit_shared_atomic_intrinsic(ctx, intr);
3181       break;
3182 
3183    case nir_intrinsic_begin_invocation_interlock:
3184    case nir_intrinsic_end_invocation_interlock:
3185       spirv_builder_emit_interlock(&ctx->builder, intr->intrinsic == nir_intrinsic_end_invocation_interlock);
3186       break;
3187 
3188    case nir_intrinsic_get_ssbo_size:
3189       emit_get_ssbo_size(ctx, intr);
3190       break;
3191 
3192    case nir_intrinsic_image_deref_store:
3193       emit_image_deref_store(ctx, intr);
3194       break;
3195 
3196    case nir_intrinsic_image_deref_sparse_load:
3197    case nir_intrinsic_image_deref_load:
3198       emit_image_deref_load(ctx, intr);
3199       break;
3200 
3201    case nir_intrinsic_image_deref_size:
3202       emit_image_deref_size(ctx, intr);
3203       break;
3204 
3205    case nir_intrinsic_image_deref_samples:
3206       emit_image_deref_samples(ctx, intr);
3207       break;
3208 
3209    case nir_intrinsic_image_deref_atomic_add:
3210    case nir_intrinsic_image_deref_atomic_umin:
3211    case nir_intrinsic_image_deref_atomic_imin:
3212    case nir_intrinsic_image_deref_atomic_umax:
3213    case nir_intrinsic_image_deref_atomic_imax:
3214    case nir_intrinsic_image_deref_atomic_and:
3215    case nir_intrinsic_image_deref_atomic_or:
3216    case nir_intrinsic_image_deref_atomic_xor:
3217    case nir_intrinsic_image_deref_atomic_exchange:
3218    case nir_intrinsic_image_deref_atomic_comp_swap:
3219       emit_image_intrinsic(ctx, intr);
3220       break;
3221 
3222    case nir_intrinsic_load_workgroup_id:
3223       emit_load_vec_input(ctx, intr, &ctx->workgroup_id_var, "gl_WorkGroupID", SpvBuiltInWorkgroupId, nir_type_uint);
3224       break;
3225 
3226    case nir_intrinsic_load_num_workgroups:
3227       emit_load_vec_input(ctx, intr, &ctx->num_workgroups_var, "gl_NumWorkGroups", SpvBuiltInNumWorkgroups, nir_type_uint);
3228       break;
3229 
3230    case nir_intrinsic_load_local_invocation_id:
3231       emit_load_vec_input(ctx, intr, &ctx->local_invocation_id_var, "gl_LocalInvocationID", SpvBuiltInLocalInvocationId, nir_type_uint);
3232       break;
3233 
3234    case nir_intrinsic_load_global_invocation_id:
3235       emit_load_vec_input(ctx, intr, &ctx->global_invocation_id_var, "gl_GlobalInvocationID", SpvBuiltInGlobalInvocationId, nir_type_uint);
3236       break;
3237 
3238    case nir_intrinsic_load_local_invocation_index:
3239       emit_load_uint_input(ctx, intr, &ctx->local_invocation_index_var, "gl_LocalInvocationIndex", SpvBuiltInLocalInvocationIndex);
3240       break;
3241 
3242 #define LOAD_SHADER_BALLOT(lowercase, camelcase) \
3243    case nir_intrinsic_load_##lowercase: \
3244       emit_load_uint_input(ctx, intr, &ctx->lowercase##_var, "gl_"#camelcase, SpvBuiltIn##camelcase); \
3245       break
3246 
3247    LOAD_SHADER_BALLOT(subgroup_id, SubgroupId);
3248    LOAD_SHADER_BALLOT(subgroup_eq_mask, SubgroupEqMask);
3249    LOAD_SHADER_BALLOT(subgroup_ge_mask, SubgroupGeMask);
3250    LOAD_SHADER_BALLOT(subgroup_invocation, SubgroupLocalInvocationId);
3251    LOAD_SHADER_BALLOT(subgroup_le_mask, SubgroupLeMask);
3252    LOAD_SHADER_BALLOT(subgroup_lt_mask, SubgroupLtMask);
3253    LOAD_SHADER_BALLOT(subgroup_size, SubgroupSize);
3254 
3255    case nir_intrinsic_ballot:
3256       emit_ballot(ctx, intr);
3257       break;
3258 
3259    case nir_intrinsic_read_first_invocation:
3260       emit_read_first_invocation(ctx, intr);
3261       break;
3262 
3263    case nir_intrinsic_read_invocation:
3264       emit_read_invocation(ctx, intr);
3265       break;
3266 
3267    case nir_intrinsic_load_workgroup_size:
3268       assert(ctx->local_group_size_var);
3269       store_dest(ctx, &intr->dest, ctx->local_group_size_var, nir_type_uint);
3270       break;
3271 
3272    case nir_intrinsic_load_shared:
3273       emit_load_shared(ctx, intr);
3274       break;
3275 
3276    case nir_intrinsic_store_shared:
3277       emit_store_shared(ctx, intr);
3278       break;
3279 
3280    case nir_intrinsic_shader_clock:
3281       emit_shader_clock(ctx, intr);
3282       break;
3283 
3284    case nir_intrinsic_vote_all:
3285    case nir_intrinsic_vote_any:
3286    case nir_intrinsic_vote_ieq:
3287    case nir_intrinsic_vote_feq:
3288       emit_vote(ctx, intr);
3289       break;
3290 
3291    case nir_intrinsic_is_sparse_texels_resident:
3292       emit_is_sparse_texels_resident(ctx, intr);
3293       break;
3294 
3295    default:
3296       fprintf(stderr, "emit_intrinsic: not implemented (%s)\n",
3297               nir_intrinsic_infos[intr->intrinsic].name);
3298       unreachable("unsupported intrinsic");
3299    }
3300 }
3301 
3302 static void
emit_undef(struct ntv_context * ctx,nir_ssa_undef_instr * undef)3303 emit_undef(struct ntv_context *ctx, nir_ssa_undef_instr *undef)
3304 {
3305    SpvId type = undef->def.bit_size == 1 ? get_bvec_type(ctx, undef->def.num_components) :
3306                                            get_uvec_type(ctx, undef->def.bit_size,
3307                                                          undef->def.num_components);
3308 
3309    store_ssa_def(ctx, &undef->def,
3310                  spirv_builder_emit_undef(&ctx->builder, type));
3311 }
3312 
3313 static SpvId
get_src_float(struct ntv_context * ctx,nir_src * src)3314 get_src_float(struct ntv_context *ctx, nir_src *src)
3315 {
3316    SpvId def = get_src(ctx, src);
3317    unsigned num_components = nir_src_num_components(*src);
3318    unsigned bit_size = nir_src_bit_size(*src);
3319    return bitcast_to_fvec(ctx, def, bit_size, num_components);
3320 }
3321 
3322 static SpvId
get_src_int(struct ntv_context * ctx,nir_src * src)3323 get_src_int(struct ntv_context *ctx, nir_src *src)
3324 {
3325    SpvId def = get_src(ctx, src);
3326    unsigned num_components = nir_src_num_components(*src);
3327    unsigned bit_size = nir_src_bit_size(*src);
3328    return bitcast_to_ivec(ctx, def, bit_size, num_components);
3329 }
3330 
3331 static inline bool
tex_instr_is_lod_allowed(nir_tex_instr * tex)3332 tex_instr_is_lod_allowed(nir_tex_instr *tex)
3333 {
3334    /* This can only be used with an OpTypeImage that has a Dim operand of 1D, 2D, 3D, or Cube
3335     * - SPIR-V: 3.14. Image Operands
3336     */
3337 
3338    return (tex->sampler_dim == GLSL_SAMPLER_DIM_1D ||
3339            tex->sampler_dim == GLSL_SAMPLER_DIM_2D ||
3340            tex->sampler_dim == GLSL_SAMPLER_DIM_3D ||
3341            tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE ||
3342            /* RECT will always become 2D, so this is fine */
3343            tex->sampler_dim == GLSL_SAMPLER_DIM_RECT);
3344 }
3345 
3346 static void
emit_tex(struct ntv_context * ctx,nir_tex_instr * tex)3347 emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
3348 {
3349    assert(tex->op == nir_texop_tex ||
3350           tex->op == nir_texop_txb ||
3351           tex->op == nir_texop_txl ||
3352           tex->op == nir_texop_txd ||
3353           tex->op == nir_texop_txf ||
3354           tex->op == nir_texop_txf_ms ||
3355           tex->op == nir_texop_txs ||
3356           tex->op == nir_texop_lod ||
3357           tex->op == nir_texop_tg4 ||
3358           tex->op == nir_texop_texture_samples ||
3359           tex->op == nir_texop_query_levels);
3360    assert(tex->texture_index == tex->sampler_index);
3361 
3362    SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0,
3363          const_offset = 0, offset = 0, sample = 0, tex_offset = 0, bindless = 0, min_lod = 0;
3364    unsigned coord_components = 0;
3365    nir_variable *bindless_var = NULL;
3366    for (unsigned i = 0; i < tex->num_srcs; i++) {
3367       nir_const_value *cv;
3368       switch (tex->src[i].src_type) {
3369       case nir_tex_src_coord:
3370          if (tex->op == nir_texop_txf ||
3371              tex->op == nir_texop_txf_ms)
3372             coord = get_src_int(ctx, &tex->src[i].src);
3373          else
3374             coord = get_src_float(ctx, &tex->src[i].src);
3375          coord_components = nir_src_num_components(tex->src[i].src);
3376          break;
3377 
3378       case nir_tex_src_projector:
3379          assert(nir_src_num_components(tex->src[i].src) == 1);
3380          proj = get_src_float(ctx, &tex->src[i].src);
3381          assert(proj != 0);
3382          break;
3383 
3384       case nir_tex_src_offset:
3385          cv = nir_src_as_const_value(tex->src[i].src);
3386          if (cv) {
3387             unsigned bit_size = nir_src_bit_size(tex->src[i].src);
3388             unsigned num_components = nir_src_num_components(tex->src[i].src);
3389 
3390             SpvId components[NIR_MAX_VEC_COMPONENTS];
3391             for (int i = 0; i < num_components; ++i) {
3392                int64_t tmp = nir_const_value_as_int(cv[i], bit_size);
3393                components[i] = emit_int_const(ctx, bit_size, tmp);
3394             }
3395 
3396             if (num_components > 1) {
3397                SpvId type = get_ivec_type(ctx, bit_size, num_components);
3398                const_offset = spirv_builder_const_composite(&ctx->builder,
3399                                                             type,
3400                                                             components,
3401                                                             num_components);
3402             } else
3403                const_offset = components[0];
3404          } else
3405             offset = get_src_int(ctx, &tex->src[i].src);
3406          break;
3407 
3408       case nir_tex_src_bias:
3409          assert(tex->op == nir_texop_txb);
3410          bias = get_src_float(ctx, &tex->src[i].src);
3411          assert(bias != 0);
3412          break;
3413 
3414       case nir_tex_src_min_lod:
3415          assert(nir_src_num_components(tex->src[i].src) == 1);
3416          min_lod = get_src_float(ctx, &tex->src[i].src);
3417          assert(min_lod != 0);
3418          break;
3419 
3420       case nir_tex_src_lod:
3421          assert(nir_src_num_components(tex->src[i].src) == 1);
3422          if (tex->op == nir_texop_txf ||
3423              tex->op == nir_texop_txf_ms ||
3424              tex->op == nir_texop_txs)
3425             lod = get_src_int(ctx, &tex->src[i].src);
3426          else
3427             lod = get_src_float(ctx, &tex->src[i].src);
3428          assert(lod != 0);
3429          break;
3430 
3431       case nir_tex_src_ms_index:
3432          assert(nir_src_num_components(tex->src[i].src) == 1);
3433          sample = get_src_int(ctx, &tex->src[i].src);
3434          break;
3435 
3436       case nir_tex_src_comparator:
3437          assert(nir_src_num_components(tex->src[i].src) == 1);
3438          dref = get_src_float(ctx, &tex->src[i].src);
3439          assert(dref != 0);
3440          break;
3441 
3442       case nir_tex_src_ddx:
3443          dx = get_src_float(ctx, &tex->src[i].src);
3444          assert(dx != 0);
3445          break;
3446 
3447       case nir_tex_src_ddy:
3448          dy = get_src_float(ctx, &tex->src[i].src);
3449          assert(dy != 0);
3450          break;
3451 
3452       case nir_tex_src_texture_offset:
3453          tex_offset = get_src_int(ctx, &tex->src[i].src);
3454          break;
3455 
3456       case nir_tex_src_sampler_offset:
3457       case nir_tex_src_sampler_handle:
3458          /* don't care */
3459          break;
3460 
3461       case nir_tex_src_texture_handle:
3462          bindless = get_src(ctx, &tex->src[i].src);
3463          bindless_var = nir_deref_instr_get_variable(nir_src_as_deref(tex->src[i].src));
3464          break;
3465 
3466       default:
3467          fprintf(stderr, "texture source: %d\n", tex->src[i].src_type);
3468          unreachable("unknown texture source");
3469       }
3470    }
3471 
3472    unsigned texture_index = tex->texture_index;
3473    if (!tex_offset) {
3474       /* convert constant index back to base + offset */
3475       unsigned last_sampler = util_last_bit(ctx->samplers_used);
3476       for (unsigned i = 0; i < last_sampler; i++) {
3477          if (!ctx->sampler_array_sizes[i]) {
3478             if (i == texture_index)
3479                /* this is a non-array sampler, so we don't need an access chain */
3480                break;
3481          } else if (texture_index <= i + ctx->sampler_array_sizes[i] - 1) {
3482             /* this is the first member of a sampler array */
3483             tex_offset = emit_uint_const(ctx, 32, texture_index - i);
3484             texture_index = i;
3485             break;
3486          }
3487       }
3488    }
3489    SpvId image_type = bindless ? get_bare_image_type(ctx, bindless_var, true) : ctx->sampler_types[texture_index];
3490    assert(image_type);
3491    SpvId sampled_type = spirv_builder_type_sampled_image(&ctx->builder,
3492                                                          image_type);
3493    assert(sampled_type);
3494    assert(bindless || ctx->samplers_used & (1u << texture_index));
3495    SpvId sampler_id = bindless ? bindless : ctx->samplers[texture_index];
3496    if (tex_offset) {
3497        SpvId ptr = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassUniformConstant, sampled_type);
3498        sampler_id = spirv_builder_emit_access_chain(&ctx->builder, ptr, sampler_id, &tex_offset, 1);
3499    }
3500    SpvId load = spirv_builder_emit_load(&ctx->builder, sampled_type, sampler_id);
3501 
3502    if (tex->is_sparse)
3503       tex->dest.ssa.num_components--;
3504    SpvId dest_type = get_dest_type(ctx, &tex->dest, tex->dest_type);
3505 
3506    if (nir_tex_instr_is_query(tex))
3507       spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
3508 
3509    if (!tex_instr_is_lod_allowed(tex))
3510       lod = 0;
3511    else if (ctx->stage != MESA_SHADER_FRAGMENT &&
3512             tex->op == nir_texop_tex && ctx->explicit_lod && !lod)
3513       lod = emit_float_const(ctx, 32, 0.0);
3514    if (tex->op == nir_texop_txs) {
3515       SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
3516       /* Its Dim operand must be one of 1D, 2D, 3D, or Cube
3517        * - OpImageQuerySizeLod specification
3518        *
3519        * Additionally, if its Dim is 1D, 2D, 3D, or Cube,
3520        * it must also have either an MS of 1 or a Sampled of 0 or 2.
3521        * - OpImageQuerySize specification
3522        *
3523        * all spirv samplers use these types
3524        */
3525       if (!lod && tex_instr_is_lod_allowed(tex))
3526          lod = emit_uint_const(ctx, 32, 0);
3527       SpvId result = spirv_builder_emit_image_query_size(&ctx->builder,
3528                                                          dest_type, image,
3529                                                          lod);
3530       store_dest(ctx, &tex->dest, result, tex->dest_type);
3531       return;
3532    }
3533    if (tex->op == nir_texop_query_levels) {
3534       SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
3535       SpvId result = spirv_builder_emit_image_query_levels(&ctx->builder,
3536                                                          dest_type, image);
3537       store_dest(ctx, &tex->dest, result, tex->dest_type);
3538       return;
3539    }
3540    if (tex->op == nir_texop_texture_samples) {
3541       SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
3542       SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageQuerySamples,
3543                                              dest_type, image);
3544       store_dest(ctx, &tex->dest, result, tex->dest_type);
3545       return;
3546    }
3547 
3548    if (proj && coord_components > 0) {
3549       SpvId constituents[NIR_MAX_VEC_COMPONENTS + 1];
3550       if (coord_components == 1)
3551          constituents[0] = coord;
3552       else {
3553          assert(coord_components > 1);
3554          SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
3555          for (uint32_t i = 0; i < coord_components; ++i)
3556             constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
3557                                                  float_type,
3558                                                  coord,
3559                                                  &i, 1);
3560       }
3561 
3562       constituents[coord_components++] = proj;
3563 
3564       SpvId vec_type = get_fvec_type(ctx, 32, coord_components);
3565       coord = spirv_builder_emit_composite_construct(&ctx->builder,
3566                                                             vec_type,
3567                                                             constituents,
3568                                                             coord_components);
3569    }
3570    if (tex->op == nir_texop_lod) {
3571       SpvId result = spirv_builder_emit_image_query_lod(&ctx->builder,
3572                                                          dest_type, load,
3573                                                          coord);
3574       store_dest(ctx, &tex->dest, result, tex->dest_type);
3575       return;
3576    }
3577    SpvId actual_dest_type;
3578    if (dref && tex->op != nir_texop_tg4)
3579       actual_dest_type = spirv_builder_type_float(&ctx->builder, 32);
3580    else {
3581       unsigned num_components = nir_dest_num_components(tex->dest);
3582       switch (nir_alu_type_get_base_type(tex->dest_type)) {
3583       case nir_type_int:
3584          actual_dest_type = get_ivec_type(ctx, 32, num_components);
3585          break;
3586 
3587       case nir_type_uint:
3588          actual_dest_type = get_uvec_type(ctx, 32, num_components);
3589          break;
3590 
3591       case nir_type_float:
3592          actual_dest_type = get_fvec_type(ctx, 32, num_components);
3593          break;
3594 
3595       default:
3596          unreachable("unexpected nir_alu_type");
3597       }
3598    }
3599 
3600    SpvId result;
3601    if (offset)
3602       spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended);
3603    if (min_lod)
3604       spirv_builder_emit_cap(&ctx->builder, SpvCapabilityMinLod);
3605    if (tex->op == nir_texop_txf ||
3606        tex->op == nir_texop_txf_ms ||
3607        tex->op == nir_texop_tg4) {
3608       SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
3609 
3610       if (tex->op == nir_texop_tg4) {
3611          if (const_offset)
3612             spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended);
3613          result = spirv_builder_emit_image_gather(&ctx->builder, actual_dest_type,
3614                                                  load, coord, emit_uint_const(ctx, 32, tex->component),
3615                                                  lod, sample, const_offset, offset, dref, tex->is_sparse);
3616          actual_dest_type = dest_type;
3617       } else
3618          result = spirv_builder_emit_image_fetch(&ctx->builder, actual_dest_type,
3619                                                  image, coord, lod, sample, const_offset, offset, tex->is_sparse);
3620    } else {
3621       if (tex->op == nir_texop_txl)
3622          min_lod = 0;
3623       result = spirv_builder_emit_image_sample(&ctx->builder,
3624                                                actual_dest_type, load,
3625                                                coord,
3626                                                proj != 0,
3627                                                lod, bias, dref, dx, dy,
3628                                                const_offset, offset, min_lod, tex->is_sparse);
3629    }
3630 
3631    spirv_builder_emit_decoration(&ctx->builder, result,
3632                                  SpvDecorationRelaxedPrecision);
3633 
3634    if (tex->is_sparse)
3635       result = extract_sparse_load(ctx, result, actual_dest_type, &tex->dest.ssa);
3636    if (dref && nir_dest_num_components(tex->dest) > 1 && tex->op != nir_texop_tg4) {
3637       SpvId components[4] = { result, result, result, result };
3638       result = spirv_builder_emit_composite_construct(&ctx->builder,
3639                                                       dest_type,
3640                                                       components,
3641                                                       4);
3642    }
3643 
3644    if (nir_dest_bit_size(tex->dest) != 32) {
3645       /* convert FP32 to FP16 */
3646       result = emit_unop(ctx, SpvOpFConvert, dest_type, result);
3647    }
3648 
3649    if (tex->is_sparse && tex->is_shadow)
3650       tex->dest.ssa.num_components++;
3651    store_dest(ctx, &tex->dest, result, tex->dest_type);
3652    if (tex->is_sparse && !tex->is_shadow)
3653       tex->dest.ssa.num_components++;
3654 }
3655 
3656 static void
start_block(struct ntv_context * ctx,SpvId label)3657 start_block(struct ntv_context *ctx, SpvId label)
3658 {
3659    /* terminate previous block if needed */
3660    if (ctx->block_started)
3661       spirv_builder_emit_branch(&ctx->builder, label);
3662 
3663    /* start new block */
3664    spirv_builder_label(&ctx->builder, label);
3665    ctx->block_started = true;
3666 }
3667 
3668 static void
branch(struct ntv_context * ctx,SpvId label)3669 branch(struct ntv_context *ctx, SpvId label)
3670 {
3671    assert(ctx->block_started);
3672    spirv_builder_emit_branch(&ctx->builder, label);
3673    ctx->block_started = false;
3674 }
3675 
3676 static void
branch_conditional(struct ntv_context * ctx,SpvId condition,SpvId then_id,SpvId else_id)3677 branch_conditional(struct ntv_context *ctx, SpvId condition, SpvId then_id,
3678                    SpvId else_id)
3679 {
3680    assert(ctx->block_started);
3681    spirv_builder_emit_branch_conditional(&ctx->builder, condition,
3682                                          then_id, else_id);
3683    ctx->block_started = false;
3684 }
3685 
3686 static void
emit_jump(struct ntv_context * ctx,nir_jump_instr * jump)3687 emit_jump(struct ntv_context *ctx, nir_jump_instr *jump)
3688 {
3689    switch (jump->type) {
3690    case nir_jump_break:
3691       assert(ctx->loop_break);
3692       branch(ctx, ctx->loop_break);
3693       break;
3694 
3695    case nir_jump_continue:
3696       assert(ctx->loop_cont);
3697       branch(ctx, ctx->loop_cont);
3698       break;
3699 
3700    default:
3701       unreachable("Unsupported jump type\n");
3702    }
3703 }
3704 
3705 static void
emit_deref_var(struct ntv_context * ctx,nir_deref_instr * deref)3706 emit_deref_var(struct ntv_context *ctx, nir_deref_instr *deref)
3707 {
3708    assert(deref->deref_type == nir_deref_type_var);
3709 
3710    struct hash_entry *he = _mesa_hash_table_search(ctx->vars, deref->var);
3711    assert(he);
3712    SpvId result = (SpvId)(intptr_t)he->data;
3713    store_dest_raw(ctx, &deref->dest, result);
3714 }
3715 
3716 static void
emit_deref_array(struct ntv_context * ctx,nir_deref_instr * deref)3717 emit_deref_array(struct ntv_context *ctx, nir_deref_instr *deref)
3718 {
3719    assert(deref->deref_type == nir_deref_type_array);
3720    nir_variable *var = nir_deref_instr_get_variable(deref);
3721 
3722    if (!nir_src_is_always_uniform(deref->arr.index)) {
3723       if (deref->modes & nir_var_mem_ubo)
3724          spirv_builder_emit_cap(&ctx->builder,
3725                                 SpvCapabilityUniformBufferArrayDynamicIndexing);
3726 
3727       if (deref->modes & nir_var_mem_ssbo)
3728          spirv_builder_emit_cap(&ctx->builder,
3729                                 SpvCapabilityStorageBufferArrayDynamicIndexing);
3730 
3731       if (deref->modes & (nir_var_uniform | nir_var_image)) {
3732          const struct glsl_type *type = glsl_without_array(var->type);
3733          assert(glsl_type_is_sampler(type) || glsl_type_is_image(type));
3734 
3735          if (glsl_type_is_sampler(type))
3736             spirv_builder_emit_cap(&ctx->builder,
3737                                    SpvCapabilitySampledImageArrayDynamicIndexing);
3738          else
3739             spirv_builder_emit_cap(&ctx->builder,
3740                                    SpvCapabilityStorageImageArrayDynamicIndexing);
3741       }
3742    }
3743 
3744    SpvStorageClass storage_class = get_storage_class(var);
3745    SpvId base, type;
3746    switch (var->data.mode) {
3747 
3748    case nir_var_mem_ubo:
3749    case nir_var_mem_ssbo:
3750       base = get_src(ctx, &deref->parent);
3751       /* this is either the array<buffers> deref or the array<uint> deref */
3752       if (glsl_type_is_struct_or_ifc(deref->type)) {
3753          /* array<buffers> */
3754          type = get_bo_struct_type(ctx, var);
3755          break;
3756       }
3757       /* array<uint> */
3758       FALLTHROUGH;
3759    case nir_var_function_temp:
3760    case nir_var_shader_in:
3761    case nir_var_shader_out:
3762       base = get_src(ctx, &deref->parent);
3763       type = get_glsl_type(ctx, deref->type);
3764       break;
3765 
3766    case nir_var_uniform:
3767    case nir_var_image: {
3768       struct hash_entry *he = _mesa_hash_table_search(ctx->vars, var);
3769       assert(he);
3770       base = (SpvId)(intptr_t)he->data;
3771       type = get_image_type(ctx, var, glsl_type_is_sampler(glsl_without_array(var->type)));
3772       break;
3773    }
3774 
3775    default:
3776       unreachable("Unsupported nir_variable_mode\n");
3777    }
3778 
3779    SpvId index = get_src(ctx, &deref->arr.index);
3780 
3781    SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
3782                                                storage_class,
3783                                                type);
3784 
3785    SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
3786                                                   ptr_type,
3787                                                   base,
3788                                                   &index, 1);
3789    /* uint is a bit of a lie here, it's really just an opaque type */
3790    store_dest(ctx, &deref->dest, result, nir_type_uint);
3791 
3792    /* image ops always need to be able to get the variable to check out sampler types and such */
3793    if (glsl_type_is_image(glsl_without_array(var->type))) {
3794       uint32_t *key = ralloc_size(ctx->mem_ctx, sizeof(uint32_t));
3795       *key = result;
3796       _mesa_hash_table_insert(ctx->image_vars, key, var);
3797    }
3798 }
3799 
3800 static void
emit_deref_struct(struct ntv_context * ctx,nir_deref_instr * deref)3801 emit_deref_struct(struct ntv_context *ctx, nir_deref_instr *deref)
3802 {
3803    assert(deref->deref_type == nir_deref_type_struct);
3804    nir_variable *var = nir_deref_instr_get_variable(deref);
3805 
3806    SpvStorageClass storage_class = get_storage_class(var);
3807 
3808    SpvId index = emit_uint_const(ctx, 32, deref->strct.index);
3809    SpvId type = (var->data.mode & (nir_var_mem_ubo | nir_var_mem_ssbo)) ?
3810                 get_bo_array_type(ctx, var) :
3811                 get_glsl_type(ctx, deref->type);
3812 
3813    SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
3814                                                storage_class,
3815                                                type);
3816 
3817    SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
3818                                                   ptr_type,
3819                                                   get_src(ctx, &deref->parent),
3820                                                   &index, 1);
3821    /* uint is a bit of a lie here, it's really just an opaque type */
3822    store_dest(ctx, &deref->dest, result, nir_type_uint);
3823 }
3824 
3825 static void
emit_deref(struct ntv_context * ctx,nir_deref_instr * deref)3826 emit_deref(struct ntv_context *ctx, nir_deref_instr *deref)
3827 {
3828    switch (deref->deref_type) {
3829    case nir_deref_type_var:
3830       emit_deref_var(ctx, deref);
3831       break;
3832 
3833    case nir_deref_type_array:
3834       emit_deref_array(ctx, deref);
3835       break;
3836 
3837    case nir_deref_type_struct:
3838       emit_deref_struct(ctx, deref);
3839       break;
3840 
3841    default:
3842       unreachable("unexpected deref_type");
3843    }
3844 }
3845 
3846 static void
emit_block(struct ntv_context * ctx,struct nir_block * block)3847 emit_block(struct ntv_context *ctx, struct nir_block *block)
3848 {
3849    start_block(ctx, block_label(ctx, block));
3850    nir_foreach_instr(instr, block) {
3851       switch (instr->type) {
3852       case nir_instr_type_alu:
3853          emit_alu(ctx, nir_instr_as_alu(instr));
3854          break;
3855       case nir_instr_type_intrinsic:
3856          emit_intrinsic(ctx, nir_instr_as_intrinsic(instr));
3857          break;
3858       case nir_instr_type_load_const:
3859          emit_load_const(ctx, nir_instr_as_load_const(instr));
3860          break;
3861       case nir_instr_type_ssa_undef:
3862          emit_undef(ctx, nir_instr_as_ssa_undef(instr));
3863          break;
3864       case nir_instr_type_tex:
3865          emit_tex(ctx, nir_instr_as_tex(instr));
3866          break;
3867       case nir_instr_type_phi:
3868          unreachable("nir_instr_type_phi not supported");
3869          break;
3870       case nir_instr_type_jump:
3871          emit_jump(ctx, nir_instr_as_jump(instr));
3872          break;
3873       case nir_instr_type_call:
3874          unreachable("nir_instr_type_call not supported");
3875          break;
3876       case nir_instr_type_parallel_copy:
3877          unreachable("nir_instr_type_parallel_copy not supported");
3878          break;
3879       case nir_instr_type_deref:
3880          emit_deref(ctx, nir_instr_as_deref(instr));
3881          break;
3882       }
3883    }
3884 }
3885 
3886 static void
3887 emit_cf_list(struct ntv_context *ctx, struct exec_list *list);
3888 
3889 static SpvId
get_src_bool(struct ntv_context * ctx,nir_src * src)3890 get_src_bool(struct ntv_context *ctx, nir_src *src)
3891 {
3892    assert(nir_src_bit_size(*src) == 1);
3893    return get_src(ctx, src);
3894 }
3895 
3896 static void
emit_if(struct ntv_context * ctx,nir_if * if_stmt)3897 emit_if(struct ntv_context *ctx, nir_if *if_stmt)
3898 {
3899    SpvId condition = get_src_bool(ctx, &if_stmt->condition);
3900 
3901    SpvId header_id = spirv_builder_new_id(&ctx->builder);
3902    SpvId then_id = block_label(ctx, nir_if_first_then_block(if_stmt));
3903    SpvId endif_id = spirv_builder_new_id(&ctx->builder);
3904    SpvId else_id = endif_id;
3905 
3906    bool has_else = !exec_list_is_empty(&if_stmt->else_list);
3907    if (has_else) {
3908       assert(nir_if_first_else_block(if_stmt)->index < ctx->num_blocks);
3909       else_id = block_label(ctx, nir_if_first_else_block(if_stmt));
3910    }
3911 
3912    /* create a header-block */
3913    start_block(ctx, header_id);
3914    spirv_builder_emit_selection_merge(&ctx->builder, endif_id,
3915                                       SpvSelectionControlMaskNone);
3916    branch_conditional(ctx, condition, then_id, else_id);
3917 
3918    emit_cf_list(ctx, &if_stmt->then_list);
3919 
3920    if (has_else) {
3921       if (ctx->block_started)
3922          branch(ctx, endif_id);
3923 
3924       emit_cf_list(ctx, &if_stmt->else_list);
3925    }
3926 
3927    start_block(ctx, endif_id);
3928 }
3929 
3930 static void
emit_loop(struct ntv_context * ctx,nir_loop * loop)3931 emit_loop(struct ntv_context *ctx, nir_loop *loop)
3932 {
3933    SpvId header_id = spirv_builder_new_id(&ctx->builder);
3934    SpvId begin_id = block_label(ctx, nir_loop_first_block(loop));
3935    SpvId break_id = spirv_builder_new_id(&ctx->builder);
3936    SpvId cont_id = spirv_builder_new_id(&ctx->builder);
3937 
3938    /* create a header-block */
3939    start_block(ctx, header_id);
3940    spirv_builder_loop_merge(&ctx->builder, break_id, cont_id, SpvLoopControlMaskNone);
3941    branch(ctx, begin_id);
3942 
3943    SpvId save_break = ctx->loop_break;
3944    SpvId save_cont = ctx->loop_cont;
3945    ctx->loop_break = break_id;
3946    ctx->loop_cont = cont_id;
3947 
3948    emit_cf_list(ctx, &loop->body);
3949 
3950    ctx->loop_break = save_break;
3951    ctx->loop_cont = save_cont;
3952 
3953    /* loop->body may have already ended our block */
3954    if (ctx->block_started)
3955       branch(ctx, cont_id);
3956    start_block(ctx, cont_id);
3957    branch(ctx, header_id);
3958 
3959    start_block(ctx, break_id);
3960 }
3961 
3962 static void
emit_cf_list(struct ntv_context * ctx,struct exec_list * list)3963 emit_cf_list(struct ntv_context *ctx, struct exec_list *list)
3964 {
3965    foreach_list_typed(nir_cf_node, node, node, list) {
3966       switch (node->type) {
3967       case nir_cf_node_block:
3968          emit_block(ctx, nir_cf_node_as_block(node));
3969          break;
3970 
3971       case nir_cf_node_if:
3972          emit_if(ctx, nir_cf_node_as_if(node));
3973          break;
3974 
3975       case nir_cf_node_loop:
3976          emit_loop(ctx, nir_cf_node_as_loop(node));
3977          break;
3978 
3979       case nir_cf_node_function:
3980          unreachable("nir_cf_node_function not supported");
3981          break;
3982       }
3983    }
3984 }
3985 
3986 static SpvExecutionMode
get_input_prim_type_mode(enum shader_prim type)3987 get_input_prim_type_mode(enum shader_prim type)
3988 {
3989    switch (type) {
3990    case SHADER_PRIM_POINTS:
3991       return SpvExecutionModeInputPoints;
3992    case SHADER_PRIM_LINES:
3993    case SHADER_PRIM_LINE_LOOP:
3994    case SHADER_PRIM_LINE_STRIP:
3995       return SpvExecutionModeInputLines;
3996    case SHADER_PRIM_TRIANGLE_STRIP:
3997    case SHADER_PRIM_TRIANGLES:
3998    case SHADER_PRIM_TRIANGLE_FAN:
3999       return SpvExecutionModeTriangles;
4000    case SHADER_PRIM_QUADS:
4001    case SHADER_PRIM_QUAD_STRIP:
4002       return SpvExecutionModeQuads;
4003       break;
4004    case SHADER_PRIM_POLYGON:
4005       unreachable("handle polygons in gs");
4006       break;
4007    case SHADER_PRIM_LINES_ADJACENCY:
4008    case SHADER_PRIM_LINE_STRIP_ADJACENCY:
4009       return SpvExecutionModeInputLinesAdjacency;
4010    case SHADER_PRIM_TRIANGLES_ADJACENCY:
4011    case SHADER_PRIM_TRIANGLE_STRIP_ADJACENCY:
4012       return SpvExecutionModeInputTrianglesAdjacency;
4013       break;
4014    default:
4015       debug_printf("unknown geometry shader input mode %u\n", type);
4016       unreachable("error!");
4017       break;
4018    }
4019 
4020    return 0;
4021 }
4022 static SpvExecutionMode
get_output_prim_type_mode(enum shader_prim type)4023 get_output_prim_type_mode(enum shader_prim type)
4024 {
4025    switch (type) {
4026    case SHADER_PRIM_POINTS:
4027       return SpvExecutionModeOutputPoints;
4028    case SHADER_PRIM_LINES:
4029    case SHADER_PRIM_LINE_LOOP:
4030       unreachable("SHADER_PRIM_LINES/LINE_LOOP passed as gs output");
4031       break;
4032    case SHADER_PRIM_LINE_STRIP:
4033       return SpvExecutionModeOutputLineStrip;
4034    case SHADER_PRIM_TRIANGLE_STRIP:
4035       return SpvExecutionModeOutputTriangleStrip;
4036    case SHADER_PRIM_TRIANGLES:
4037    case SHADER_PRIM_TRIANGLE_FAN: //FIXME: not sure if right for output
4038       return SpvExecutionModeTriangles;
4039    case SHADER_PRIM_QUADS:
4040    case SHADER_PRIM_QUAD_STRIP:
4041       return SpvExecutionModeQuads;
4042    case SHADER_PRIM_POLYGON:
4043       unreachable("handle polygons in gs");
4044       break;
4045    case SHADER_PRIM_LINES_ADJACENCY:
4046    case SHADER_PRIM_LINE_STRIP_ADJACENCY:
4047       unreachable("handle line adjacency in gs");
4048       break;
4049    case SHADER_PRIM_TRIANGLES_ADJACENCY:
4050    case SHADER_PRIM_TRIANGLE_STRIP_ADJACENCY:
4051       unreachable("handle triangle adjacency in gs");
4052       break;
4053    default:
4054       debug_printf("unknown geometry shader output mode %u\n", type);
4055       unreachable("error!");
4056       break;
4057    }
4058 
4059    return 0;
4060 }
4061 
4062 static SpvExecutionMode
get_depth_layout_mode(enum gl_frag_depth_layout depth_layout)4063 get_depth_layout_mode(enum gl_frag_depth_layout depth_layout)
4064 {
4065    switch (depth_layout) {
4066    case FRAG_DEPTH_LAYOUT_NONE:
4067    case FRAG_DEPTH_LAYOUT_ANY:
4068       return SpvExecutionModeDepthReplacing;
4069    case FRAG_DEPTH_LAYOUT_GREATER:
4070       return SpvExecutionModeDepthGreater;
4071    case FRAG_DEPTH_LAYOUT_LESS:
4072       return SpvExecutionModeDepthLess;
4073    case FRAG_DEPTH_LAYOUT_UNCHANGED:
4074       return SpvExecutionModeDepthUnchanged;
4075    default:
4076       unreachable("unexpected depth layout");
4077    }
4078 }
4079 
4080 static SpvExecutionMode
get_primitive_mode(enum tess_primitive_mode primitive_mode)4081 get_primitive_mode(enum tess_primitive_mode primitive_mode)
4082 {
4083    switch (primitive_mode) {
4084    case TESS_PRIMITIVE_TRIANGLES: return SpvExecutionModeTriangles;
4085    case TESS_PRIMITIVE_QUADS: return SpvExecutionModeQuads;
4086    case TESS_PRIMITIVE_ISOLINES: return SpvExecutionModeIsolines;
4087    default:
4088       unreachable("unknown tess prim type!");
4089    }
4090 }
4091 
4092 static SpvExecutionMode
get_spacing(enum gl_tess_spacing spacing)4093 get_spacing(enum gl_tess_spacing spacing)
4094 {
4095    switch (spacing) {
4096    case TESS_SPACING_EQUAL:
4097       return SpvExecutionModeSpacingEqual;
4098    case TESS_SPACING_FRACTIONAL_ODD:
4099       return SpvExecutionModeSpacingFractionalOdd;
4100    case TESS_SPACING_FRACTIONAL_EVEN:
4101       return SpvExecutionModeSpacingFractionalEven;
4102    default:
4103       unreachable("unknown tess spacing!");
4104    }
4105 }
4106 
4107 struct spirv_shader *
nir_to_spirv(struct nir_shader * s,const struct zink_shader_info * sinfo,uint32_t spirv_version)4108 nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_t spirv_version)
4109 {
4110    struct spirv_shader *ret = NULL;
4111 
4112    struct ntv_context ctx = {0};
4113    ctx.mem_ctx = ralloc_context(NULL);
4114    ctx.nir = s;
4115    ctx.builder.mem_ctx = ctx.mem_ctx;
4116    assert(spirv_version >= SPIRV_VERSION(1, 0));
4117    ctx.spirv_1_4_interfaces = spirv_version >= SPIRV_VERSION(1, 4);
4118 
4119    ctx.glsl_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4120    ctx.bo_array_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4121    ctx.bo_struct_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4122    if (!ctx.glsl_types || !ctx.bo_array_types || !ctx.bo_struct_types)
4123       goto fail;
4124 
4125    spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShader);
4126 
4127    switch (s->info.stage) {
4128    case MESA_SHADER_FRAGMENT:
4129       if (s->info.fs.post_depth_coverage &&
4130           BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_SAMPLE_MASK_IN))
4131          spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampleMaskPostDepthCoverage);
4132       if (s->info.fs.uses_sample_shading)
4133          spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampleRateShading);
4134       break;
4135 
4136    case MESA_SHADER_VERTEX:
4137       if (BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_INSTANCE_ID) ||
4138           BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_DRAW_ID) ||
4139           BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_BASE_INSTANCE) ||
4140           BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_BASE_VERTEX)) {
4141          spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_shader_draw_parameters");
4142          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDrawParameters);
4143       }
4144       break;
4145 
4146    case MESA_SHADER_TESS_CTRL:
4147    case MESA_SHADER_TESS_EVAL:
4148       spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellation);
4149       /* TODO: check features for this */
4150       if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_PSIZ))
4151          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellationPointSize);
4152       break;
4153 
4154    case MESA_SHADER_GEOMETRY:
4155       spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometry);
4156       if (s->info.gs.active_stream_mask)
4157          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometryStreams);
4158       if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_PSIZ))
4159          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometryPointSize);
4160       break;
4161 
4162    default: ;
4163    }
4164 
4165    if (s->info.stage < MESA_SHADER_GEOMETRY) {
4166       if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_LAYER) ||
4167           s->info.inputs_read & BITFIELD64_BIT(VARYING_SLOT_LAYER)) {
4168          if (spirv_version >= SPIRV_VERSION(1, 5))
4169             spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderLayer);
4170          else {
4171             spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_shader_viewport_index_layer");
4172             spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderViewportIndexLayerEXT);
4173          }
4174       }
4175    } else if (s->info.stage == MESA_SHADER_FRAGMENT) {
4176       /* incredibly, this is legal and intended.
4177        * https://github.com/KhronosGroup/SPIRV-Registry/issues/95
4178        */
4179       if (s->info.inputs_read & (BITFIELD64_BIT(VARYING_SLOT_LAYER) |
4180                                  BITFIELD64_BIT(VARYING_SLOT_PRIMITIVE_ID)))
4181          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometry);
4182    }
4183 
4184    if (s->info.num_ssbos && spirv_version < SPIRV_VERSION(1, 1))
4185       spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_storage_buffer_storage_class");
4186 
4187    if (s->info.stage < MESA_SHADER_FRAGMENT &&
4188        s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_VIEWPORT)) {
4189       if (s->info.stage < MESA_SHADER_GEOMETRY)
4190          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderViewportIndex);
4191       else
4192          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityMultiViewport);
4193    }
4194 
4195    ctx.stage = s->info.stage;
4196    ctx.sinfo = sinfo;
4197    ctx.GLSL_std_450 = spirv_builder_import(&ctx.builder, "GLSL.std.450");
4198    ctx.explicit_lod = true;
4199    spirv_builder_emit_source(&ctx.builder, SpvSourceLanguageUnknown, 0);
4200 
4201    if (s->info.stage == MESA_SHADER_COMPUTE) {
4202       SpvAddressingModel model;
4203       if (s->info.cs.ptr_size == 32)
4204          model = SpvAddressingModelPhysical32;
4205       else if (s->info.cs.ptr_size == 64)
4206          model = SpvAddressingModelPhysical64;
4207       else
4208          model = SpvAddressingModelLogical;
4209       spirv_builder_emit_mem_model(&ctx.builder, model,
4210                                    SpvMemoryModelGLSL450);
4211    } else {
4212       if (ctx.sinfo->have_vulkan_memory_model) {
4213          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityVulkanMemoryModel);
4214          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityVulkanMemoryModelDeviceScope);
4215          spirv_builder_emit_mem_model(&ctx.builder, SpvAddressingModelLogical,
4216                                       SpvMemoryModelVulkan);
4217       } else {
4218          spirv_builder_emit_mem_model(&ctx.builder, SpvAddressingModelLogical,
4219                                       SpvMemoryModelGLSL450);
4220       }
4221    }
4222 
4223    if (s->info.stage == MESA_SHADER_FRAGMENT &&
4224        s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) {
4225       spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_shader_stencil_export");
4226       spirv_builder_emit_cap(&ctx.builder, SpvCapabilityStencilExportEXT);
4227    }
4228 
4229    SpvExecutionModel exec_model;
4230    switch (s->info.stage) {
4231    case MESA_SHADER_VERTEX:
4232       exec_model = SpvExecutionModelVertex;
4233       break;
4234    case MESA_SHADER_TESS_CTRL:
4235       exec_model = SpvExecutionModelTessellationControl;
4236       break;
4237    case MESA_SHADER_TESS_EVAL:
4238       exec_model = SpvExecutionModelTessellationEvaluation;
4239       break;
4240    case MESA_SHADER_GEOMETRY:
4241       exec_model = SpvExecutionModelGeometry;
4242       break;
4243    case MESA_SHADER_FRAGMENT:
4244       exec_model = SpvExecutionModelFragment;
4245       break;
4246    case MESA_SHADER_COMPUTE:
4247       exec_model = SpvExecutionModelGLCompute;
4248       break;
4249    default:
4250       unreachable("invalid stage");
4251    }
4252 
4253    SpvId type_void = spirv_builder_type_void(&ctx.builder);
4254    SpvId type_void_func = spirv_builder_type_function(&ctx.builder, type_void,
4255                                                       NULL, 0);
4256    SpvId entry_point = spirv_builder_new_id(&ctx.builder);
4257    spirv_builder_emit_name(&ctx.builder, entry_point, "main");
4258 
4259    ctx.vars = _mesa_hash_table_create(ctx.mem_ctx, _mesa_hash_pointer,
4260                                       _mesa_key_pointer_equal);
4261 
4262    ctx.image_vars = _mesa_hash_table_create(ctx.mem_ctx, _mesa_hash_u32,
4263                                       _mesa_key_u32_equal);
4264 
4265    ctx.so_outputs = _mesa_hash_table_create(ctx.mem_ctx, _mesa_hash_u32,
4266                                             _mesa_key_u32_equal);
4267 
4268    nir_foreach_variable_with_modes(var, s, nir_var_mem_push_const)
4269       input_var_init(&ctx, var);
4270 
4271    nir_foreach_shader_in_variable(var, s)
4272       emit_input(&ctx, var);
4273 
4274    int max_output = 0;
4275    nir_foreach_shader_out_variable(var, s) {
4276       /* ignore SPIR-V built-ins, tagged with a sentinel value */
4277       if (var->data.driver_location != UINT_MAX) {
4278          assert(var->data.driver_location < INT_MAX);
4279          unsigned extent = glsl_count_attribute_slots(var->type, false);
4280          max_output = MAX2(max_output, (int)var->data.driver_location + extent);
4281       }
4282       emit_output(&ctx, var);
4283    }
4284 
4285    if (sinfo->last_vertex)
4286       emit_so_info(&ctx, sinfo, max_output);
4287    uint32_t tcs_vertices_out_word = 0;
4288 
4289    /* we have to reverse iterate to match what's done in zink_compiler.c */
4290    foreach_list_typed_reverse(nir_variable, var, node, &s->variables)
4291       if (_nir_shader_variable_has_mode(var, nir_var_uniform |
4292                                         nir_var_image |
4293                                         nir_var_mem_ubo |
4294                                         nir_var_mem_ssbo))
4295          emit_uniform(&ctx, var);
4296 
4297    switch (s->info.stage) {
4298    case MESA_SHADER_FRAGMENT:
4299       spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4300                                    SpvExecutionModeOriginUpperLeft);
4301       if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
4302          spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4303                                       get_depth_layout_mode(s->info.fs.depth_layout));
4304       if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL))
4305          spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4306                                       SpvExecutionModeStencilRefReplacingEXT);
4307       if (s->info.fs.early_fragment_tests)
4308          spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4309                                       SpvExecutionModeEarlyFragmentTests);
4310       if (s->info.fs.post_depth_coverage) {
4311          spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_post_depth_coverage");
4312          spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4313                                       SpvExecutionModePostDepthCoverage);
4314       }
4315 
4316       if (s->info.fs.pixel_interlock_ordered || s->info.fs.pixel_interlock_unordered ||
4317           s->info.fs.sample_interlock_ordered || s->info.fs.sample_interlock_unordered)
4318          spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_fragment_shader_interlock");
4319       if (s->info.fs.pixel_interlock_ordered || s->info.fs.pixel_interlock_unordered)
4320          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityFragmentShaderPixelInterlockEXT);
4321       if (s->info.fs.sample_interlock_ordered || s->info.fs.sample_interlock_unordered)
4322          spirv_builder_emit_cap(&ctx.builder, SpvCapabilityFragmentShaderSampleInterlockEXT);
4323       if (s->info.fs.pixel_interlock_ordered)
4324          spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePixelInterlockOrderedEXT);
4325       if (s->info.fs.pixel_interlock_unordered)
4326          spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePixelInterlockUnorderedEXT);
4327       if (s->info.fs.sample_interlock_ordered)
4328          spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSampleInterlockOrderedEXT);
4329       if (s->info.fs.sample_interlock_unordered)
4330          spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSampleInterlockUnorderedEXT);
4331       break;
4332    case MESA_SHADER_TESS_CTRL:
4333       tcs_vertices_out_word = spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4334                                                                    SpvExecutionModeOutputVertices,
4335                                                                    s->info.tess.tcs_vertices_out);
4336       break;
4337    case MESA_SHADER_TESS_EVAL:
4338       spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4339                                    get_primitive_mode(s->info.tess._primitive_mode));
4340       spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4341                                    s->info.tess.ccw ? SpvExecutionModeVertexOrderCcw
4342                                                     : SpvExecutionModeVertexOrderCw);
4343       spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4344                                    get_spacing(s->info.tess.spacing));
4345       if (s->info.tess.point_mode)
4346          spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePointMode);
4347       break;
4348    case MESA_SHADER_GEOMETRY:
4349       spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4350                                    get_input_prim_type_mode(s->info.gs.input_primitive));
4351       spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4352                                    get_output_prim_type_mode(s->info.gs.output_primitive));
4353       spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4354                                            SpvExecutionModeInvocations,
4355                                            s->info.gs.invocations);
4356       spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4357                                            SpvExecutionModeOutputVertices,
4358                                            MAX2(s->info.gs.vertices_out, 1));
4359       break;
4360    case MESA_SHADER_COMPUTE:
4361       if (s->info.shared_size)
4362          create_shared_block(&ctx, s->info.shared_size);
4363 
4364       if (s->info.workgroup_size[0] || s->info.workgroup_size[1] || s->info.workgroup_size[2])
4365          spirv_builder_emit_exec_mode_literal3(&ctx.builder, entry_point, SpvExecutionModeLocalSize,
4366                                                (uint32_t[3]){(uint32_t)s->info.workgroup_size[0], (uint32_t)s->info.workgroup_size[1],
4367                                                (uint32_t)s->info.workgroup_size[2]});
4368       else {
4369          SpvId sizes[3];
4370          uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
4371          const char *names[] = {"x", "y", "z"};
4372          for (int i = 0; i < 3; i ++) {
4373             sizes[i] = spirv_builder_spec_const_uint(&ctx.builder, 32);
4374             spirv_builder_emit_specid(&ctx.builder, sizes[i], ids[i]);
4375             spirv_builder_emit_name(&ctx.builder, sizes[i], names[i]);
4376          }
4377          SpvId var_type = get_uvec_type(&ctx, 32, 3);
4378          ctx.local_group_size_var = spirv_builder_spec_const_composite(&ctx.builder, var_type, sizes, 3);
4379          spirv_builder_emit_name(&ctx.builder, ctx.local_group_size_var, "gl_LocalGroupSize");
4380          spirv_builder_emit_builtin(&ctx.builder, ctx.local_group_size_var, SpvBuiltInWorkgroupSize);
4381       }
4382       break;
4383    default:
4384       break;
4385    }
4386    if (BITSET_TEST_RANGE(s->info.system_values_read, SYSTEM_VALUE_SUBGROUP_SIZE, SYSTEM_VALUE_SUBGROUP_LT_MASK)) {
4387       spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySubgroupBallotKHR);
4388       spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_shader_ballot");
4389    }
4390    if (s->info.has_transform_feedback_varyings) {
4391       spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTransformFeedback);
4392       spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4393                                    SpvExecutionModeXfb);
4394    }
4395 
4396    if (s->info.stage == MESA_SHADER_FRAGMENT && s->info.fs.uses_discard) {
4397       ctx.discard_func = spirv_builder_new_id(&ctx.builder);
4398       spirv_builder_emit_name(&ctx.builder, ctx.discard_func, "discard");
4399       spirv_builder_function(&ctx.builder, ctx.discard_func, type_void,
4400                              SpvFunctionControlMaskNone,
4401                              type_void_func);
4402       SpvId label = spirv_builder_new_id(&ctx.builder);
4403       spirv_builder_label(&ctx.builder, label);
4404       spirv_builder_emit_kill(&ctx.builder);
4405       spirv_builder_function_end(&ctx.builder);
4406    }
4407 
4408    spirv_builder_function(&ctx.builder, entry_point, type_void,
4409                           SpvFunctionControlMaskNone,
4410                           type_void_func);
4411 
4412    nir_function_impl *entry = nir_shader_get_entrypoint(s);
4413    nir_metadata_require(entry, nir_metadata_block_index);
4414 
4415    ctx.defs = ralloc_array_size(ctx.mem_ctx,
4416                                 sizeof(SpvId), entry->ssa_alloc);
4417    if (!ctx.defs)
4418       goto fail;
4419    if (sinfo->have_sparse) {
4420       spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySparseResidency);
4421       /* this could be huge, so only alloc if needed since it's extremely unlikely to
4422        * ever be used by anything except cts
4423        */
4424       ctx.resident_defs = ralloc_array_size(ctx.mem_ctx,
4425                                             sizeof(SpvId), entry->ssa_alloc);
4426       if (!ctx.resident_defs)
4427          goto fail;
4428    }
4429    ctx.num_defs = entry->ssa_alloc;
4430 
4431    nir_index_local_regs(entry);
4432    ctx.regs = ralloc_array_size(ctx.mem_ctx,
4433                                 sizeof(SpvId), entry->reg_alloc);
4434    if (!ctx.regs)
4435       goto fail;
4436    ctx.num_regs = entry->reg_alloc;
4437 
4438    SpvId *block_ids = ralloc_array_size(ctx.mem_ctx,
4439                                         sizeof(SpvId), entry->num_blocks);
4440    if (!block_ids)
4441       goto fail;
4442 
4443    for (int i = 0; i < entry->num_blocks; ++i)
4444       block_ids[i] = spirv_builder_new_id(&ctx.builder);
4445 
4446    ctx.block_ids = block_ids;
4447    ctx.num_blocks = entry->num_blocks;
4448 
4449    /* emit a block only for the variable declarations */
4450    start_block(&ctx, spirv_builder_new_id(&ctx.builder));
4451    foreach_list_typed(nir_register, reg, node, &entry->registers) {
4452       SpvId type = get_vec_from_bit_size(&ctx, reg->bit_size, reg->num_components);
4453       SpvId pointer_type = spirv_builder_type_pointer(&ctx.builder,
4454                                                       SpvStorageClassFunction,
4455                                                       type);
4456       SpvId var = spirv_builder_emit_var(&ctx.builder, pointer_type,
4457                                          SpvStorageClassFunction);
4458 
4459       ctx.regs[reg->index] = var;
4460    }
4461 
4462    nir_foreach_function_temp_variable(var, entry)
4463       emit_temp(&ctx, var);
4464 
4465 
4466    emit_cf_list(&ctx, &entry->body);
4467 
4468    /* vertex/tess shader emits copied xfb outputs at the end of the shader */
4469    if (sinfo->last_vertex && (ctx.stage == MESA_SHADER_VERTEX || ctx.stage == MESA_SHADER_TESS_EVAL))
4470       emit_so_outputs(&ctx, sinfo);
4471 
4472    spirv_builder_return(&ctx.builder); // doesn't belong here, but whatevz
4473    spirv_builder_function_end(&ctx.builder);
4474 
4475    spirv_builder_emit_entry_point(&ctx.builder, exec_model, entry_point,
4476                                   "main", ctx.entry_ifaces,
4477                                   ctx.num_entry_ifaces);
4478 
4479    size_t num_words = spirv_builder_get_num_words(&ctx.builder);
4480 
4481    ret = ralloc(NULL, struct spirv_shader);
4482    if (!ret)
4483       goto fail;
4484 
4485    ret->words = ralloc_size(ret, sizeof(uint32_t) * num_words);
4486    if (!ret->words)
4487       goto fail;
4488 
4489    ret->num_words = spirv_builder_get_words(&ctx.builder, ret->words, num_words, spirv_version, &tcs_vertices_out_word);
4490    ret->tcs_vertices_out_word = tcs_vertices_out_word;
4491    assert(ret->num_words == num_words);
4492 
4493    ralloc_free(ctx.mem_ctx);
4494 
4495    return ret;
4496 
4497 fail:
4498    ralloc_free(ctx.mem_ctx);
4499 
4500    if (ret)
4501       spirv_shader_delete(ret);
4502 
4503    return NULL;
4504 }
4505 
4506 void
spirv_shader_delete(struct spirv_shader * s)4507 spirv_shader_delete(struct spirv_shader *s)
4508 {
4509    ralloc_free(s);
4510 }
4511