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