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