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