zink: add ult handling for ntv
[mesa.git] / src / gallium / drivers / zink / nir_to_spirv / nir_to_spirv.c
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_memory.h"
30 #include "util/hash_table.h"
31
32 /* this consistently maps slots to a zero-indexed value to avoid wasting slots */
33 static unsigned slot_pack_map[] = {
34 /* Position is builtin */
35 [VARYING_SLOT_POS] = UINT_MAX,
36 [VARYING_SLOT_COL0] = 0, /* input/output */
37 [VARYING_SLOT_COL1] = 1, /* input/output */
38 [VARYING_SLOT_FOGC] = 2, /* input/output */
39 /* TEX0-7 are translated to VAR0-7 by nir, so we don't need to reserve */
40 [VARYING_SLOT_TEX0] = UINT_MAX, /* input/output */
41 [VARYING_SLOT_TEX1] = UINT_MAX,
42 [VARYING_SLOT_TEX2] = UINT_MAX,
43 [VARYING_SLOT_TEX3] = UINT_MAX,
44 [VARYING_SLOT_TEX4] = UINT_MAX,
45 [VARYING_SLOT_TEX5] = UINT_MAX,
46 [VARYING_SLOT_TEX6] = UINT_MAX,
47 [VARYING_SLOT_TEX7] = UINT_MAX,
48
49 /* PointSize is builtin */
50 [VARYING_SLOT_PSIZ] = UINT_MAX,
51
52 [VARYING_SLOT_BFC0] = 3, /* output only */
53 [VARYING_SLOT_BFC1] = 4, /* output only */
54 [VARYING_SLOT_EDGE] = 5, /* output only */
55 [VARYING_SLOT_CLIP_VERTEX] = 6, /* output only */
56
57 /* ClipDistance is builtin */
58 [VARYING_SLOT_CLIP_DIST0] = UINT_MAX,
59 [VARYING_SLOT_CLIP_DIST1] = UINT_MAX,
60
61 /* CullDistance is builtin */
62 [VARYING_SLOT_CULL_DIST0] = UINT_MAX, /* input/output */
63 [VARYING_SLOT_CULL_DIST1] = UINT_MAX, /* never actually used */
64
65 /* PrimitiveId is builtin */
66 [VARYING_SLOT_PRIMITIVE_ID] = UINT_MAX,
67
68 /* Layer is builtin */
69 [VARYING_SLOT_LAYER] = UINT_MAX, /* input/output */
70
71 /* ViewportIndex is builtin */
72 [VARYING_SLOT_VIEWPORT] = UINT_MAX, /* input/output */
73
74 /* FrontFacing is builtin */
75 [VARYING_SLOT_FACE] = UINT_MAX,
76
77 /* PointCoord is builtin */
78 [VARYING_SLOT_PNTC] = UINT_MAX, /* input only */
79
80 /* TessLevelOuter is builtin */
81 [VARYING_SLOT_TESS_LEVEL_OUTER] = UINT_MAX,
82 /* TessLevelInner is builtin */
83 [VARYING_SLOT_TESS_LEVEL_INNER] = UINT_MAX,
84
85 [VARYING_SLOT_BOUNDING_BOX0] = 7, /* Only appears as TCS output. */
86 [VARYING_SLOT_BOUNDING_BOX1] = 8, /* Only appears as TCS output. */
87 [VARYING_SLOT_VIEW_INDEX] = 9, /* input/output */
88 [VARYING_SLOT_VIEWPORT_MASK] = 10, /* output only */
89 };
90 #define NTV_MIN_RESERVED_SLOTS 11
91
92 struct ntv_context {
93 struct spirv_builder builder;
94
95 SpvId GLSL_std_450;
96
97 gl_shader_stage stage;
98
99 SpvId ubos[128];
100 size_t num_ubos;
101 SpvId image_types[PIPE_MAX_SAMPLERS];
102 SpvId samplers[PIPE_MAX_SAMPLERS];
103 unsigned samplers_used : PIPE_MAX_SAMPLERS;
104 SpvId entry_ifaces[PIPE_MAX_SHADER_INPUTS * 4 + PIPE_MAX_SHADER_OUTPUTS * 4];
105 size_t num_entry_ifaces;
106
107 SpvId *defs;
108 size_t num_defs;
109
110 SpvId *regs;
111 size_t num_regs;
112
113 struct hash_table *vars; /* nir_variable -> SpvId */
114 struct hash_table *so_outputs; /* pipe_stream_output -> SpvId */
115 unsigned outputs[VARYING_SLOT_MAX];
116 const struct glsl_type *so_output_gl_types[VARYING_SLOT_MAX];
117 SpvId so_output_types[VARYING_SLOT_MAX];
118
119 const SpvId *block_ids;
120 size_t num_blocks;
121 bool block_started;
122 SpvId loop_break, loop_cont;
123
124 SpvId front_face_var, instance_id_var, vertex_id_var;
125 };
126
127 static SpvId
128 get_fvec_constant(struct ntv_context *ctx, unsigned bit_size,
129 unsigned num_components, float value);
130
131 static SpvId
132 get_uvec_constant(struct ntv_context *ctx, unsigned bit_size,
133 unsigned num_components, uint32_t value);
134
135 static SpvId
136 get_ivec_constant(struct ntv_context *ctx, unsigned bit_size,
137 unsigned num_components, int32_t value);
138
139 static SpvId
140 emit_unop(struct ntv_context *ctx, SpvOp op, SpvId type, SpvId src);
141
142 static SpvId
143 emit_binop(struct ntv_context *ctx, SpvOp op, SpvId type,
144 SpvId src0, SpvId src1);
145
146 static SpvId
147 emit_triop(struct ntv_context *ctx, SpvOp op, SpvId type,
148 SpvId src0, SpvId src1, SpvId src2);
149
150 static SpvId
151 get_bvec_type(struct ntv_context *ctx, int num_components)
152 {
153 SpvId bool_type = spirv_builder_type_bool(&ctx->builder);
154 if (num_components > 1)
155 return spirv_builder_type_vector(&ctx->builder, bool_type,
156 num_components);
157
158 assert(num_components == 1);
159 return bool_type;
160 }
161
162 static SpvId
163 block_label(struct ntv_context *ctx, nir_block *block)
164 {
165 assert(block->index < ctx->num_blocks);
166 return ctx->block_ids[block->index];
167 }
168
169 static SpvId
170 emit_float_const(struct ntv_context *ctx, int bit_size, float value)
171 {
172 assert(bit_size == 32);
173 return spirv_builder_const_float(&ctx->builder, bit_size, value);
174 }
175
176 static SpvId
177 emit_uint_const(struct ntv_context *ctx, int bit_size, uint32_t value)
178 {
179 assert(bit_size == 32);
180 return spirv_builder_const_uint(&ctx->builder, bit_size, value);
181 }
182
183 static SpvId
184 emit_int_const(struct ntv_context *ctx, int bit_size, int32_t value)
185 {
186 assert(bit_size == 32);
187 return spirv_builder_const_int(&ctx->builder, bit_size, value);
188 }
189
190 static SpvId
191 get_fvec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
192 {
193 assert(bit_size == 32); // only 32-bit floats supported so far
194
195 SpvId float_type = spirv_builder_type_float(&ctx->builder, bit_size);
196 if (num_components > 1)
197 return spirv_builder_type_vector(&ctx->builder, float_type,
198 num_components);
199
200 assert(num_components == 1);
201 return float_type;
202 }
203
204 static SpvId
205 get_ivec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
206 {
207 assert(bit_size == 32); // only 32-bit ints supported so far
208
209 SpvId int_type = spirv_builder_type_int(&ctx->builder, bit_size);
210 if (num_components > 1)
211 return spirv_builder_type_vector(&ctx->builder, int_type,
212 num_components);
213
214 assert(num_components == 1);
215 return int_type;
216 }
217
218 static SpvId
219 get_uvec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
220 {
221 assert(bit_size == 32); // only 32-bit uints supported so far
222
223 SpvId uint_type = spirv_builder_type_uint(&ctx->builder, bit_size);
224 if (num_components > 1)
225 return spirv_builder_type_vector(&ctx->builder, uint_type,
226 num_components);
227
228 assert(num_components == 1);
229 return uint_type;
230 }
231
232 static SpvId
233 get_dest_uvec_type(struct ntv_context *ctx, nir_dest *dest)
234 {
235 unsigned bit_size = MAX2(nir_dest_bit_size(*dest), 32);
236 return get_uvec_type(ctx, bit_size, nir_dest_num_components(*dest));
237 }
238
239 static SpvId
240 get_glsl_basetype(struct ntv_context *ctx, enum glsl_base_type type)
241 {
242 switch (type) {
243 case GLSL_TYPE_BOOL:
244 return spirv_builder_type_bool(&ctx->builder);
245
246 case GLSL_TYPE_FLOAT:
247 return spirv_builder_type_float(&ctx->builder, 32);
248
249 case GLSL_TYPE_INT:
250 return spirv_builder_type_int(&ctx->builder, 32);
251
252 case GLSL_TYPE_UINT:
253 return spirv_builder_type_uint(&ctx->builder, 32);
254 /* TODO: handle more types */
255
256 default:
257 unreachable("unknown GLSL type");
258 }
259 }
260
261 static SpvId
262 get_glsl_type(struct ntv_context *ctx, const struct glsl_type *type)
263 {
264 assert(type);
265 if (glsl_type_is_scalar(type))
266 return get_glsl_basetype(ctx, glsl_get_base_type(type));
267
268 if (glsl_type_is_vector(type))
269 return spirv_builder_type_vector(&ctx->builder,
270 get_glsl_basetype(ctx, glsl_get_base_type(type)),
271 glsl_get_vector_elements(type));
272
273 if (glsl_type_is_array(type)) {
274 SpvId ret = spirv_builder_type_array(&ctx->builder,
275 get_glsl_type(ctx, glsl_get_array_element(type)),
276 emit_uint_const(ctx, 32, glsl_get_length(type)));
277 uint32_t stride = glsl_get_explicit_stride(type);
278 if (stride)
279 spirv_builder_emit_array_stride(&ctx->builder, ret, stride);
280 return ret;
281 }
282
283
284 unreachable("we shouldn't get here, I think...");
285 }
286
287 #define HANDLE_EMIT_BUILTIN(SLOT, BUILTIN) \
288 case VARYING_SLOT_##SLOT: \
289 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltIn##BUILTIN); \
290 break
291
292
293 static void
294 emit_input(struct ntv_context *ctx, struct nir_variable *var)
295 {
296 SpvId var_type = get_glsl_type(ctx, var->type);
297 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
298 SpvStorageClassInput,
299 var_type);
300 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
301 SpvStorageClassInput);
302
303 if (var->name)
304 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
305
306 if (ctx->stage == MESA_SHADER_FRAGMENT) {
307 unsigned slot = var->data.location;
308 switch (slot) {
309 HANDLE_EMIT_BUILTIN(POS, FragCoord);
310 HANDLE_EMIT_BUILTIN(PNTC, PointCoord);
311 HANDLE_EMIT_BUILTIN(LAYER, Layer);
312 HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
313 HANDLE_EMIT_BUILTIN(CLIP_DIST0, ClipDistance);
314 HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
315 HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
316 HANDLE_EMIT_BUILTIN(FACE, FrontFacing);
317
318 default:
319 if (slot < VARYING_SLOT_VAR0) {
320 slot = slot_pack_map[slot];
321 if (slot == UINT_MAX)
322 debug_printf("unhandled varying slot: %s\n", gl_varying_slot_name(var->data.location));
323 } else
324 slot -= VARYING_SLOT_VAR0 - NTV_MIN_RESERVED_SLOTS;
325 assert(slot < VARYING_SLOT_VAR0);
326 spirv_builder_emit_location(&ctx->builder, var_id, slot);
327 }
328 } else {
329 spirv_builder_emit_location(&ctx->builder, var_id,
330 var->data.driver_location);
331 }
332
333 if (var->data.location_frac)
334 spirv_builder_emit_component(&ctx->builder, var_id,
335 var->data.location_frac);
336
337 if (var->data.interpolation == INTERP_MODE_FLAT)
338 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationFlat);
339
340 _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
341
342 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
343 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
344 }
345
346 static void
347 emit_output(struct ntv_context *ctx, struct nir_variable *var)
348 {
349 SpvId var_type = get_glsl_type(ctx, var->type);
350 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
351 SpvStorageClassOutput,
352 var_type);
353 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
354 SpvStorageClassOutput);
355 if (var->name)
356 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
357
358
359 if (ctx->stage == MESA_SHADER_VERTEX) {
360 unsigned slot = var->data.location;
361 switch (slot) {
362 HANDLE_EMIT_BUILTIN(POS, Position);
363 HANDLE_EMIT_BUILTIN(PSIZ, PointSize);
364 HANDLE_EMIT_BUILTIN(LAYER, Layer);
365 HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
366 HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
367 HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
368 HANDLE_EMIT_BUILTIN(TESS_LEVEL_OUTER, TessLevelOuter);
369 HANDLE_EMIT_BUILTIN(TESS_LEVEL_INNER, TessLevelInner);
370
371 case VARYING_SLOT_CLIP_DIST0:
372 assert(glsl_type_is_array(var->type));
373 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInClipDistance);
374 /* this can be as large as 2x vec4, which requires 2 slots */
375 ctx->outputs[VARYING_SLOT_CLIP_DIST1] = var_id;
376 ctx->so_output_gl_types[VARYING_SLOT_CLIP_DIST1] = var->type;
377 ctx->so_output_types[VARYING_SLOT_CLIP_DIST1] = var_type;
378 break;
379
380 default:
381 if (slot < VARYING_SLOT_VAR0) {
382 slot = slot_pack_map[slot];
383 if (slot == UINT_MAX)
384 debug_printf("unhandled varying slot: %s\n", gl_varying_slot_name(var->data.location));
385 } else
386 slot -= VARYING_SLOT_VAR0 - NTV_MIN_RESERVED_SLOTS;
387 assert(slot < VARYING_SLOT_VAR0);
388 spirv_builder_emit_location(&ctx->builder, var_id, slot);
389 /* non-builtins get location incremented by VARYING_SLOT_VAR0 in vtn, so
390 * use driver_location for non-builtins with defined slots to avoid overlap
391 */
392 }
393 ctx->outputs[var->data.location] = var_id;
394 ctx->so_output_gl_types[var->data.location] = var->type;
395 ctx->so_output_types[var->data.location] = var_type;
396 } else if (ctx->stage == MESA_SHADER_FRAGMENT) {
397 if (var->data.location >= FRAG_RESULT_DATA0)
398 spirv_builder_emit_location(&ctx->builder, var_id,
399 var->data.location - FRAG_RESULT_DATA0);
400 else {
401 switch (var->data.location) {
402 case FRAG_RESULT_COLOR:
403 spirv_builder_emit_location(&ctx->builder, var_id, 0);
404 spirv_builder_emit_index(&ctx->builder, var_id, var->data.index);
405 break;
406
407 case FRAG_RESULT_DEPTH:
408 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragDepth);
409 break;
410
411 default:
412 spirv_builder_emit_location(&ctx->builder, var_id,
413 var->data.driver_location);
414 }
415 }
416 }
417
418 if (var->data.location_frac)
419 spirv_builder_emit_component(&ctx->builder, var_id,
420 var->data.location_frac);
421
422 switch (var->data.interpolation) {
423 case INTERP_MODE_NONE:
424 case INTERP_MODE_SMOOTH: /* XXX spirv doesn't seem to have anything for this */
425 break;
426 case INTERP_MODE_FLAT:
427 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationFlat);
428 break;
429 case INTERP_MODE_EXPLICIT:
430 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationExplicitInterpAMD);
431 break;
432 case INTERP_MODE_NOPERSPECTIVE:
433 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationNoPerspective);
434 break;
435 default:
436 unreachable("unknown interpolation value");
437 }
438
439 _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
440
441 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
442 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
443 }
444
445 static SpvDim
446 type_to_dim(enum glsl_sampler_dim gdim, bool *is_ms)
447 {
448 *is_ms = false;
449 switch (gdim) {
450 case GLSL_SAMPLER_DIM_1D:
451 return SpvDim1D;
452 case GLSL_SAMPLER_DIM_2D:
453 return SpvDim2D;
454 case GLSL_SAMPLER_DIM_3D:
455 return SpvDim3D;
456 case GLSL_SAMPLER_DIM_CUBE:
457 return SpvDimCube;
458 case GLSL_SAMPLER_DIM_RECT:
459 return SpvDim2D;
460 case GLSL_SAMPLER_DIM_BUF:
461 return SpvDimBuffer;
462 case GLSL_SAMPLER_DIM_EXTERNAL:
463 return SpvDim2D; /* seems dodgy... */
464 case GLSL_SAMPLER_DIM_MS:
465 *is_ms = true;
466 return SpvDim2D;
467 default:
468 fprintf(stderr, "unknown sampler type %d\n", gdim);
469 break;
470 }
471 return SpvDim2D;
472 }
473
474 uint32_t
475 zink_binding(gl_shader_stage stage, VkDescriptorType type, int index)
476 {
477 if (stage == MESA_SHADER_NONE ||
478 stage >= MESA_SHADER_COMPUTE) {
479 unreachable("not supported");
480 } else {
481 uint32_t stage_offset = (uint32_t)stage * (PIPE_MAX_CONSTANT_BUFFERS +
482 PIPE_MAX_SHADER_SAMPLER_VIEWS);
483
484 switch (type) {
485 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
486 assert(index < PIPE_MAX_CONSTANT_BUFFERS);
487 return stage_offset + index;
488
489 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
490 assert(index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
491 return stage_offset + PIPE_MAX_CONSTANT_BUFFERS + index;
492
493 default:
494 unreachable("unexpected type");
495 }
496 }
497 }
498
499 static void
500 emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
501 {
502 const struct glsl_type *type = glsl_without_array(var->type);
503
504 bool is_ms;
505 SpvDim dimension = type_to_dim(glsl_get_sampler_dim(type), &is_ms);
506
507 SpvId result_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
508 SpvId image_type = spirv_builder_type_image(&ctx->builder, result_type,
509 dimension, false,
510 glsl_sampler_type_is_array(type),
511 is_ms, 1,
512 SpvImageFormatUnknown);
513
514 SpvId sampled_type = spirv_builder_type_sampled_image(&ctx->builder,
515 image_type);
516 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
517 SpvStorageClassUniformConstant,
518 sampled_type);
519
520 if (glsl_type_is_array(var->type)) {
521 for (int i = 0; i < glsl_get_length(var->type); ++i) {
522 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
523 SpvStorageClassUniformConstant);
524
525 if (var->name) {
526 char element_name[100];
527 snprintf(element_name, sizeof(element_name), "%s_%d", var->name, i);
528 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
529 }
530
531 int index = var->data.binding + i;
532 assert(!(ctx->samplers_used & (1 << index)));
533 assert(!ctx->image_types[index]);
534 ctx->image_types[index] = image_type;
535 ctx->samplers[index] = var_id;
536 ctx->samplers_used |= 1 << index;
537
538 spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
539 var->data.descriptor_set);
540 int binding = zink_binding(ctx->stage,
541 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
542 var->data.binding + i);
543 spirv_builder_emit_binding(&ctx->builder, var_id, binding);
544 }
545 } else {
546 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
547 SpvStorageClassUniformConstant);
548
549 if (var->name)
550 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
551
552 int index = var->data.binding;
553 assert(!(ctx->samplers_used & (1 << index)));
554 assert(!ctx->image_types[index]);
555 ctx->image_types[index] = image_type;
556 ctx->samplers[index] = var_id;
557 ctx->samplers_used |= 1 << index;
558
559 spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
560 var->data.descriptor_set);
561 int binding = zink_binding(ctx->stage,
562 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
563 var->data.binding);
564 spirv_builder_emit_binding(&ctx->builder, var_id, binding);
565 }
566 }
567
568 static void
569 emit_ubo(struct ntv_context *ctx, struct nir_variable *var)
570 {
571 uint32_t size = glsl_count_attribute_slots(var->type, false);
572 SpvId vec4_type = get_uvec_type(ctx, 32, 4);
573 SpvId array_length = emit_uint_const(ctx, 32, size);
574 SpvId array_type = spirv_builder_type_array(&ctx->builder, vec4_type,
575 array_length);
576 spirv_builder_emit_array_stride(&ctx->builder, array_type, 16);
577
578 // wrap UBO-array in a struct
579 SpvId struct_type = spirv_builder_type_struct(&ctx->builder, &array_type, 1);
580 if (var->name) {
581 char struct_name[100];
582 snprintf(struct_name, sizeof(struct_name), "struct_%s", var->name);
583 spirv_builder_emit_name(&ctx->builder, struct_type, struct_name);
584 }
585
586 spirv_builder_emit_decoration(&ctx->builder, struct_type,
587 SpvDecorationBlock);
588 spirv_builder_emit_member_offset(&ctx->builder, struct_type, 0, 0);
589
590
591 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
592 SpvStorageClassUniform,
593 struct_type);
594
595 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
596 SpvStorageClassUniform);
597 if (var->name)
598 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
599
600 assert(ctx->num_ubos < ARRAY_SIZE(ctx->ubos));
601 ctx->ubos[ctx->num_ubos++] = var_id;
602
603 spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
604 var->data.descriptor_set);
605 int binding = zink_binding(ctx->stage,
606 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
607 var->data.binding);
608 spirv_builder_emit_binding(&ctx->builder, var_id, binding);
609 }
610
611 static void
612 emit_uniform(struct ntv_context *ctx, struct nir_variable *var)
613 {
614 if (var->data.mode == nir_var_mem_ubo)
615 emit_ubo(ctx, var);
616 else {
617 assert(var->data.mode == nir_var_uniform);
618 if (glsl_type_is_sampler(glsl_without_array(var->type)))
619 emit_sampler(ctx, var);
620 }
621 }
622
623 static SpvId
624 get_src_ssa(struct ntv_context *ctx, const nir_ssa_def *ssa)
625 {
626 assert(ssa->index < ctx->num_defs);
627 assert(ctx->defs[ssa->index] != 0);
628 return ctx->defs[ssa->index];
629 }
630
631 static SpvId
632 get_var_from_reg(struct ntv_context *ctx, nir_register *reg)
633 {
634 assert(reg->index < ctx->num_regs);
635 assert(ctx->regs[reg->index] != 0);
636 return ctx->regs[reg->index];
637 }
638
639 static SpvId
640 get_src_reg(struct ntv_context *ctx, const nir_reg_src *reg)
641 {
642 assert(reg->reg);
643 assert(!reg->indirect);
644 assert(!reg->base_offset);
645
646 SpvId var = get_var_from_reg(ctx, reg->reg);
647 SpvId type = get_uvec_type(ctx, reg->reg->bit_size, reg->reg->num_components);
648 return spirv_builder_emit_load(&ctx->builder, type, var);
649 }
650
651 static SpvId
652 get_src(struct ntv_context *ctx, nir_src *src)
653 {
654 if (src->is_ssa)
655 return get_src_ssa(ctx, src->ssa);
656 else
657 return get_src_reg(ctx, &src->reg);
658 }
659
660 static SpvId
661 get_alu_src_raw(struct ntv_context *ctx, nir_alu_instr *alu, unsigned src)
662 {
663 assert(!alu->src[src].negate);
664 assert(!alu->src[src].abs);
665
666 SpvId def = get_src(ctx, &alu->src[src].src);
667
668 unsigned used_channels = 0;
669 bool need_swizzle = false;
670 for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
671 if (!nir_alu_instr_channel_used(alu, src, i))
672 continue;
673
674 used_channels++;
675
676 if (alu->src[src].swizzle[i] != i)
677 need_swizzle = true;
678 }
679 assert(used_channels != 0);
680
681 unsigned live_channels = nir_src_num_components(alu->src[src].src);
682 if (used_channels != live_channels)
683 need_swizzle = true;
684
685 if (!need_swizzle)
686 return def;
687
688 int bit_size = nir_src_bit_size(alu->src[src].src);
689 assert(bit_size == 1 || bit_size == 32);
690
691 SpvId raw_type = bit_size == 1 ? spirv_builder_type_bool(&ctx->builder) :
692 spirv_builder_type_uint(&ctx->builder, bit_size);
693
694 if (used_channels == 1) {
695 uint32_t indices[] = { alu->src[src].swizzle[0] };
696 return spirv_builder_emit_composite_extract(&ctx->builder, raw_type,
697 def, indices,
698 ARRAY_SIZE(indices));
699 } else if (live_channels == 1) {
700 SpvId raw_vec_type = spirv_builder_type_vector(&ctx->builder,
701 raw_type,
702 used_channels);
703
704 SpvId constituents[NIR_MAX_VEC_COMPONENTS] = {0};
705 for (unsigned i = 0; i < used_channels; ++i)
706 constituents[i] = def;
707
708 return spirv_builder_emit_composite_construct(&ctx->builder,
709 raw_vec_type,
710 constituents,
711 used_channels);
712 } else {
713 SpvId raw_vec_type = spirv_builder_type_vector(&ctx->builder,
714 raw_type,
715 used_channels);
716
717 uint32_t components[NIR_MAX_VEC_COMPONENTS] = {0};
718 size_t num_components = 0;
719 for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
720 if (!nir_alu_instr_channel_used(alu, src, i))
721 continue;
722
723 components[num_components++] = alu->src[src].swizzle[i];
724 }
725
726 return spirv_builder_emit_vector_shuffle(&ctx->builder, raw_vec_type,
727 def, def, components,
728 num_components);
729 }
730 }
731
732 static void
733 store_ssa_def(struct ntv_context *ctx, nir_ssa_def *ssa, SpvId result)
734 {
735 assert(result != 0);
736 assert(ssa->index < ctx->num_defs);
737 ctx->defs[ssa->index] = result;
738 }
739
740 static SpvId
741 emit_select(struct ntv_context *ctx, SpvId type, SpvId cond,
742 SpvId if_true, SpvId if_false)
743 {
744 return emit_triop(ctx, SpvOpSelect, type, cond, if_true, if_false);
745 }
746
747 static SpvId
748 uvec_to_bvec(struct ntv_context *ctx, SpvId value, unsigned num_components)
749 {
750 SpvId type = get_bvec_type(ctx, num_components);
751 SpvId zero = get_uvec_constant(ctx, 32, num_components, 0);
752 return emit_binop(ctx, SpvOpINotEqual, type, value, zero);
753 }
754
755 static SpvId
756 emit_bitcast(struct ntv_context *ctx, SpvId type, SpvId value)
757 {
758 return emit_unop(ctx, SpvOpBitcast, type, value);
759 }
760
761 static SpvId
762 bitcast_to_uvec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
763 unsigned num_components)
764 {
765 SpvId type = get_uvec_type(ctx, bit_size, num_components);
766 return emit_bitcast(ctx, type, value);
767 }
768
769 static SpvId
770 bitcast_to_ivec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
771 unsigned num_components)
772 {
773 SpvId type = get_ivec_type(ctx, bit_size, num_components);
774 return emit_bitcast(ctx, type, value);
775 }
776
777 static SpvId
778 bitcast_to_fvec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
779 unsigned num_components)
780 {
781 SpvId type = get_fvec_type(ctx, bit_size, num_components);
782 return emit_bitcast(ctx, type, value);
783 }
784
785 static void
786 store_reg_def(struct ntv_context *ctx, nir_reg_dest *reg, SpvId result)
787 {
788 SpvId var = get_var_from_reg(ctx, reg->reg);
789 assert(var);
790 spirv_builder_emit_store(&ctx->builder, var, result);
791 }
792
793 static void
794 store_dest_raw(struct ntv_context *ctx, nir_dest *dest, SpvId result)
795 {
796 if (dest->is_ssa)
797 store_ssa_def(ctx, &dest->ssa, result);
798 else
799 store_reg_def(ctx, &dest->reg, result);
800 }
801
802 static SpvId
803 store_dest(struct ntv_context *ctx, nir_dest *dest, SpvId result, nir_alu_type type)
804 {
805 unsigned num_components = nir_dest_num_components(*dest);
806 unsigned bit_size = nir_dest_bit_size(*dest);
807
808 if (bit_size != 1) {
809 switch (nir_alu_type_get_base_type(type)) {
810 case nir_type_bool:
811 assert("bool should have bit-size 1");
812
813 case nir_type_uint:
814 break; /* nothing to do! */
815
816 case nir_type_int:
817 case nir_type_float:
818 result = bitcast_to_uvec(ctx, result, bit_size, num_components);
819 break;
820
821 default:
822 unreachable("unsupported nir_alu_type");
823 }
824 }
825
826 store_dest_raw(ctx, dest, result);
827 return result;
828 }
829
830 static SpvId
831 emit_unop(struct ntv_context *ctx, SpvOp op, SpvId type, SpvId src)
832 {
833 return spirv_builder_emit_unop(&ctx->builder, op, type, src);
834 }
835
836 /* return the intended xfb output vec type based on base type and vector size */
837 static SpvId
838 get_output_type(struct ntv_context *ctx, unsigned register_index, unsigned num_components)
839 {
840 const struct glsl_type *out_type = ctx->so_output_gl_types[register_index];
841 enum glsl_base_type base_type = glsl_get_base_type(out_type);
842 if (base_type == GLSL_TYPE_ARRAY)
843 base_type = glsl_get_base_type(glsl_without_array(out_type));
844
845 switch (base_type) {
846 case GLSL_TYPE_BOOL:
847 return get_bvec_type(ctx, num_components);
848
849 case GLSL_TYPE_FLOAT:
850 return get_fvec_type(ctx, 32, num_components);
851
852 case GLSL_TYPE_INT:
853 return get_ivec_type(ctx, 32, num_components);
854
855 case GLSL_TYPE_UINT:
856 return get_uvec_type(ctx, 32, num_components);
857
858 default:
859 break;
860 }
861 unreachable("unknown type");
862 return 0;
863 }
864
865 /* for streamout create new outputs, as streamout can be done on individual components,
866 from complete outputs, so we just can't use the created packed outputs */
867 static void
868 emit_so_info(struct ntv_context *ctx, unsigned max_output_location,
869 const struct pipe_stream_output_info *so_info, struct pipe_stream_output_info *local_so_info)
870 {
871 for (unsigned i = 0; i < local_so_info->num_outputs; i++) {
872 struct pipe_stream_output so_output = local_so_info->output[i];
873 SpvId out_type = get_output_type(ctx, so_output.register_index, so_output.num_components);
874 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
875 SpvStorageClassOutput,
876 out_type);
877 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
878 SpvStorageClassOutput);
879 char name[10];
880
881 snprintf(name, 10, "xfb%d", i);
882 spirv_builder_emit_name(&ctx->builder, var_id, name);
883 spirv_builder_emit_offset(&ctx->builder, var_id, (so_output.dst_offset * 4));
884 spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, so_output.output_buffer);
885 spirv_builder_emit_xfb_stride(&ctx->builder, var_id, so_info->stride[so_output.output_buffer] * 4);
886
887 /* output location is incremented by VARYING_SLOT_VAR0 for non-builtins in vtn,
888 * so we need to ensure that the new xfb location slot doesn't conflict with any previously-emitted
889 * outputs.
890 *
891 * if there's no previous outputs that take up user slots (VAR0+) then we can start right after the
892 * glsl builtin reserved slots, otherwise we start just after the adjusted user output slot
893 */
894 uint32_t location = NTV_MIN_RESERVED_SLOTS + i;
895 if (max_output_location >= VARYING_SLOT_VAR0)
896 location = max_output_location - VARYING_SLOT_VAR0 + 1 + i;
897 assert(location < VARYING_SLOT_VAR0);
898 spirv_builder_emit_location(&ctx->builder, var_id, location);
899
900 /* note: gl_ClipDistance[4] can the 0-indexed member of VARYING_SLOT_CLIP_DIST1 here,
901 * so this is still the 0 component
902 */
903 if (so_output.start_component)
904 spirv_builder_emit_component(&ctx->builder, var_id, so_output.start_component);
905
906 uint32_t *key = ralloc_size(NULL, sizeof(uint32_t));
907 *key = (uint32_t)so_output.register_index << 2 | so_output.start_component;
908 _mesa_hash_table_insert(ctx->so_outputs, key, (void *)(intptr_t)var_id);
909
910 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
911 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
912 }
913 }
914
915 static void
916 emit_so_outputs(struct ntv_context *ctx,
917 const struct pipe_stream_output_info *so_info, struct pipe_stream_output_info *local_so_info)
918 {
919 SpvId loaded_outputs[VARYING_SLOT_MAX] = {};
920 for (unsigned i = 0; i < local_so_info->num_outputs; i++) {
921 uint32_t components[NIR_MAX_VEC_COMPONENTS];
922 struct pipe_stream_output so_output = local_so_info->output[i];
923 uint32_t so_key = (uint32_t) so_output.register_index << 2 | so_output.start_component;
924 struct hash_entry *he = _mesa_hash_table_search(ctx->so_outputs, &so_key);
925 assert(he);
926 SpvId so_output_var_id = (SpvId)(intptr_t)he->data;
927
928 SpvId type = get_output_type(ctx, so_output.register_index, so_output.num_components);
929 SpvId output = ctx->outputs[so_output.register_index];
930 SpvId output_type = ctx->so_output_types[so_output.register_index];
931 const struct glsl_type *out_type = ctx->so_output_gl_types[so_output.register_index];
932
933 if (!loaded_outputs[so_output.register_index])
934 loaded_outputs[so_output.register_index] = spirv_builder_emit_load(&ctx->builder, output_type, output);
935 SpvId src = loaded_outputs[so_output.register_index];
936
937 SpvId result;
938
939 for (unsigned c = 0; c < so_output.num_components; c++) {
940 components[c] = so_output.start_component + c;
941 /* this is the second half of a 2 * vec4 array */
942 if (ctx->stage == MESA_SHADER_VERTEX && so_output.register_index == VARYING_SLOT_CLIP_DIST1)
943 components[c] += 4;
944 }
945
946 /* if we're emitting a scalar or the type we're emitting matches the output's original type and we're
947 * emitting the same number of components, then we can skip any sort of conversion here
948 */
949 if (glsl_type_is_scalar(out_type) || (type == output_type && glsl_get_length(out_type) == so_output.num_components))
950 result = src;
951 else {
952 /* OpCompositeExtract can only extract scalars for our use here */
953 if (so_output.num_components == 1) {
954 result = spirv_builder_emit_composite_extract(&ctx->builder, type, src, components, so_output.num_components);
955 } else if (glsl_type_is_vector(out_type)) {
956 /* OpVectorShuffle can select vector members into a differently-sized vector */
957 result = spirv_builder_emit_vector_shuffle(&ctx->builder, type,
958 src, src,
959 components, so_output.num_components);
960 result = emit_unop(ctx, SpvOpBitcast, type, result);
961 } else {
962 /* for arrays, we need to manually extract each desired member
963 * and re-pack them into the desired output type
964 */
965 for (unsigned c = 0; c < so_output.num_components; c++) {
966 uint32_t member[] = { so_output.start_component + c };
967 SpvId base_type = get_glsl_type(ctx, glsl_without_array(out_type));
968
969 if (ctx->stage == MESA_SHADER_VERTEX && so_output.register_index == VARYING_SLOT_CLIP_DIST1)
970 member[0] += 4;
971 components[c] = spirv_builder_emit_composite_extract(&ctx->builder, base_type, src, member, 1);
972 }
973 result = spirv_builder_emit_composite_construct(&ctx->builder, type, components, so_output.num_components);
974 }
975 }
976
977 spirv_builder_emit_store(&ctx->builder, so_output_var_id, result);
978 }
979 }
980
981 static SpvId
982 emit_binop(struct ntv_context *ctx, SpvOp op, SpvId type,
983 SpvId src0, SpvId src1)
984 {
985 return spirv_builder_emit_binop(&ctx->builder, op, type, src0, src1);
986 }
987
988 static SpvId
989 emit_triop(struct ntv_context *ctx, SpvOp op, SpvId type,
990 SpvId src0, SpvId src1, SpvId src2)
991 {
992 return spirv_builder_emit_triop(&ctx->builder, op, type, src0, src1, src2);
993 }
994
995 static SpvId
996 emit_builtin_unop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
997 SpvId src)
998 {
999 SpvId args[] = { src };
1000 return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1001 op, args, ARRAY_SIZE(args));
1002 }
1003
1004 static SpvId
1005 emit_builtin_binop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
1006 SpvId src0, SpvId src1)
1007 {
1008 SpvId args[] = { src0, src1 };
1009 return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1010 op, args, ARRAY_SIZE(args));
1011 }
1012
1013 static SpvId
1014 emit_builtin_triop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
1015 SpvId src0, SpvId src1, SpvId src2)
1016 {
1017 SpvId args[] = { src0, src1, src2 };
1018 return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1019 op, args, ARRAY_SIZE(args));
1020 }
1021
1022 static SpvId
1023 get_fvec_constant(struct ntv_context *ctx, unsigned bit_size,
1024 unsigned num_components, float value)
1025 {
1026 assert(bit_size == 32);
1027
1028 SpvId result = emit_float_const(ctx, bit_size, value);
1029 if (num_components == 1)
1030 return result;
1031
1032 assert(num_components > 1);
1033 SpvId components[num_components];
1034 for (int i = 0; i < num_components; i++)
1035 components[i] = result;
1036
1037 SpvId type = get_fvec_type(ctx, bit_size, num_components);
1038 return spirv_builder_const_composite(&ctx->builder, type, components,
1039 num_components);
1040 }
1041
1042 static SpvId
1043 get_uvec_constant(struct ntv_context *ctx, unsigned bit_size,
1044 unsigned num_components, uint32_t value)
1045 {
1046 assert(bit_size == 32);
1047
1048 SpvId result = emit_uint_const(ctx, bit_size, value);
1049 if (num_components == 1)
1050 return result;
1051
1052 assert(num_components > 1);
1053 SpvId components[num_components];
1054 for (int i = 0; i < num_components; i++)
1055 components[i] = result;
1056
1057 SpvId type = get_uvec_type(ctx, bit_size, num_components);
1058 return spirv_builder_const_composite(&ctx->builder, type, components,
1059 num_components);
1060 }
1061
1062 static SpvId
1063 get_ivec_constant(struct ntv_context *ctx, unsigned bit_size,
1064 unsigned num_components, int32_t value)
1065 {
1066 assert(bit_size == 32);
1067
1068 SpvId result = emit_int_const(ctx, bit_size, value);
1069 if (num_components == 1)
1070 return result;
1071
1072 assert(num_components > 1);
1073 SpvId components[num_components];
1074 for (int i = 0; i < num_components; i++)
1075 components[i] = result;
1076
1077 SpvId type = get_ivec_type(ctx, bit_size, num_components);
1078 return spirv_builder_const_composite(&ctx->builder, type, components,
1079 num_components);
1080 }
1081
1082 static inline unsigned
1083 alu_instr_src_components(const nir_alu_instr *instr, unsigned src)
1084 {
1085 if (nir_op_infos[instr->op].input_sizes[src] > 0)
1086 return nir_op_infos[instr->op].input_sizes[src];
1087
1088 if (instr->dest.dest.is_ssa)
1089 return instr->dest.dest.ssa.num_components;
1090 else
1091 return instr->dest.dest.reg.reg->num_components;
1092 }
1093
1094 static SpvId
1095 get_alu_src(struct ntv_context *ctx, nir_alu_instr *alu, unsigned src)
1096 {
1097 SpvId raw_value = get_alu_src_raw(ctx, alu, src);
1098
1099 unsigned num_components = alu_instr_src_components(alu, src);
1100 unsigned bit_size = nir_src_bit_size(alu->src[src].src);
1101 nir_alu_type type = nir_op_infos[alu->op].input_types[src];
1102
1103 if (bit_size == 1)
1104 return raw_value;
1105 else {
1106 switch (nir_alu_type_get_base_type(type)) {
1107 case nir_type_bool:
1108 unreachable("bool should have bit-size 1");
1109
1110 case nir_type_int:
1111 return bitcast_to_ivec(ctx, raw_value, bit_size, num_components);
1112
1113 case nir_type_uint:
1114 return raw_value;
1115
1116 case nir_type_float:
1117 return bitcast_to_fvec(ctx, raw_value, bit_size, num_components);
1118
1119 default:
1120 unreachable("unknown nir_alu_type");
1121 }
1122 }
1123 }
1124
1125 static SpvId
1126 store_alu_result(struct ntv_context *ctx, nir_alu_instr *alu, SpvId result)
1127 {
1128 assert(!alu->dest.saturate);
1129 return store_dest(ctx, &alu->dest.dest, result,
1130 nir_op_infos[alu->op].output_type);
1131 }
1132
1133 static SpvId
1134 get_dest_type(struct ntv_context *ctx, nir_dest *dest, nir_alu_type type)
1135 {
1136 unsigned num_components = nir_dest_num_components(*dest);
1137 unsigned bit_size = nir_dest_bit_size(*dest);
1138
1139 if (bit_size == 1)
1140 return get_bvec_type(ctx, num_components);
1141
1142 switch (nir_alu_type_get_base_type(type)) {
1143 case nir_type_bool:
1144 unreachable("bool should have bit-size 1");
1145
1146 case nir_type_int:
1147 return get_ivec_type(ctx, bit_size, num_components);
1148
1149 case nir_type_uint:
1150 return get_uvec_type(ctx, bit_size, num_components);
1151
1152 case nir_type_float:
1153 return get_fvec_type(ctx, bit_size, num_components);
1154
1155 default:
1156 unreachable("unsupported nir_alu_type");
1157 }
1158 }
1159
1160 static void
1161 emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
1162 {
1163 SpvId src[nir_op_infos[alu->op].num_inputs];
1164 unsigned in_bit_sizes[nir_op_infos[alu->op].num_inputs];
1165 for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++) {
1166 src[i] = get_alu_src(ctx, alu, i);
1167 in_bit_sizes[i] = nir_src_bit_size(alu->src[i].src);
1168 }
1169
1170 SpvId dest_type = get_dest_type(ctx, &alu->dest.dest,
1171 nir_op_infos[alu->op].output_type);
1172 unsigned bit_size = nir_dest_bit_size(alu->dest.dest);
1173 unsigned num_components = nir_dest_num_components(alu->dest.dest);
1174
1175 SpvId result = 0;
1176 switch (alu->op) {
1177 case nir_op_mov:
1178 assert(nir_op_infos[alu->op].num_inputs == 1);
1179 result = src[0];
1180 break;
1181
1182 #define UNOP(nir_op, spirv_op) \
1183 case nir_op: \
1184 assert(nir_op_infos[alu->op].num_inputs == 1); \
1185 result = emit_unop(ctx, spirv_op, dest_type, src[0]); \
1186 break;
1187
1188 UNOP(nir_op_ineg, SpvOpSNegate)
1189 UNOP(nir_op_fneg, SpvOpFNegate)
1190 UNOP(nir_op_fddx, SpvOpDPdx)
1191 UNOP(nir_op_fddx_coarse, SpvOpDPdxCoarse)
1192 UNOP(nir_op_fddx_fine, SpvOpDPdxFine)
1193 UNOP(nir_op_fddy, SpvOpDPdy)
1194 UNOP(nir_op_fddy_coarse, SpvOpDPdyCoarse)
1195 UNOP(nir_op_fddy_fine, SpvOpDPdyFine)
1196 UNOP(nir_op_f2i32, SpvOpConvertFToS)
1197 UNOP(nir_op_f2u32, SpvOpConvertFToU)
1198 UNOP(nir_op_i2f32, SpvOpConvertSToF)
1199 UNOP(nir_op_u2f32, SpvOpConvertUToF)
1200 #undef UNOP
1201
1202 case nir_op_inot:
1203 if (bit_size == 1)
1204 result = emit_unop(ctx, SpvOpLogicalNot, dest_type, src[0]);
1205 else
1206 result = emit_unop(ctx, SpvOpNot, dest_type, src[0]);
1207 break;
1208
1209 case nir_op_b2i32:
1210 assert(nir_op_infos[alu->op].num_inputs == 1);
1211 result = emit_select(ctx, dest_type, src[0],
1212 get_ivec_constant(ctx, 32, num_components, 1),
1213 get_ivec_constant(ctx, 32, num_components, 0));
1214 break;
1215
1216 case nir_op_b2f32:
1217 assert(nir_op_infos[alu->op].num_inputs == 1);
1218 result = emit_select(ctx, dest_type, src[0],
1219 get_fvec_constant(ctx, 32, num_components, 1),
1220 get_fvec_constant(ctx, 32, num_components, 0));
1221 break;
1222
1223 #define BUILTIN_UNOP(nir_op, spirv_op) \
1224 case nir_op: \
1225 assert(nir_op_infos[alu->op].num_inputs == 1); \
1226 result = emit_builtin_unop(ctx, spirv_op, dest_type, src[0]); \
1227 break;
1228
1229 BUILTIN_UNOP(nir_op_iabs, GLSLstd450SAbs)
1230 BUILTIN_UNOP(nir_op_fabs, GLSLstd450FAbs)
1231 BUILTIN_UNOP(nir_op_fsqrt, GLSLstd450Sqrt)
1232 BUILTIN_UNOP(nir_op_frsq, GLSLstd450InverseSqrt)
1233 BUILTIN_UNOP(nir_op_flog2, GLSLstd450Log2)
1234 BUILTIN_UNOP(nir_op_fexp2, GLSLstd450Exp2)
1235 BUILTIN_UNOP(nir_op_ffract, GLSLstd450Fract)
1236 BUILTIN_UNOP(nir_op_ffloor, GLSLstd450Floor)
1237 BUILTIN_UNOP(nir_op_fceil, GLSLstd450Ceil)
1238 BUILTIN_UNOP(nir_op_ftrunc, GLSLstd450Trunc)
1239 BUILTIN_UNOP(nir_op_fround_even, GLSLstd450RoundEven)
1240 BUILTIN_UNOP(nir_op_fsign, GLSLstd450FSign)
1241 BUILTIN_UNOP(nir_op_fsin, GLSLstd450Sin)
1242 BUILTIN_UNOP(nir_op_fcos, GLSLstd450Cos)
1243 #undef BUILTIN_UNOP
1244
1245 case nir_op_frcp:
1246 assert(nir_op_infos[alu->op].num_inputs == 1);
1247 result = emit_binop(ctx, SpvOpFDiv, dest_type,
1248 get_fvec_constant(ctx, bit_size, num_components, 1),
1249 src[0]);
1250 break;
1251
1252 case nir_op_f2b1:
1253 assert(nir_op_infos[alu->op].num_inputs == 1);
1254 result = emit_binop(ctx, SpvOpFOrdNotEqual, dest_type, src[0],
1255 get_fvec_constant(ctx,
1256 nir_src_bit_size(alu->src[0].src),
1257 num_components, 0));
1258 break;
1259 case nir_op_i2b1:
1260 assert(nir_op_infos[alu->op].num_inputs == 1);
1261 result = emit_binop(ctx, SpvOpINotEqual, dest_type, src[0],
1262 get_ivec_constant(ctx,
1263 nir_src_bit_size(alu->src[0].src),
1264 num_components, 0));
1265 break;
1266
1267
1268 #define BINOP(nir_op, spirv_op) \
1269 case nir_op: \
1270 assert(nir_op_infos[alu->op].num_inputs == 2); \
1271 result = emit_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
1272 break;
1273
1274 BINOP(nir_op_iadd, SpvOpIAdd)
1275 BINOP(nir_op_isub, SpvOpISub)
1276 BINOP(nir_op_imul, SpvOpIMul)
1277 BINOP(nir_op_idiv, SpvOpSDiv)
1278 BINOP(nir_op_udiv, SpvOpUDiv)
1279 BINOP(nir_op_umod, SpvOpUMod)
1280 BINOP(nir_op_fadd, SpvOpFAdd)
1281 BINOP(nir_op_fsub, SpvOpFSub)
1282 BINOP(nir_op_fmul, SpvOpFMul)
1283 BINOP(nir_op_fdiv, SpvOpFDiv)
1284 BINOP(nir_op_fmod, SpvOpFMod)
1285 BINOP(nir_op_ilt, SpvOpSLessThan)
1286 BINOP(nir_op_ige, SpvOpSGreaterThanEqual)
1287 BINOP(nir_op_ult, SpvOpULessThan)
1288 BINOP(nir_op_uge, SpvOpUGreaterThanEqual)
1289 BINOP(nir_op_flt, SpvOpFOrdLessThan)
1290 BINOP(nir_op_fge, SpvOpFOrdGreaterThanEqual)
1291 BINOP(nir_op_feq, SpvOpFOrdEqual)
1292 BINOP(nir_op_fne, SpvOpFOrdNotEqual)
1293 BINOP(nir_op_ishl, SpvOpShiftLeftLogical)
1294 BINOP(nir_op_ishr, SpvOpShiftRightArithmetic)
1295 BINOP(nir_op_ushr, SpvOpShiftRightLogical)
1296 #undef BINOP
1297
1298 #define BINOP_LOG(nir_op, spv_op, spv_log_op) \
1299 case nir_op: \
1300 assert(nir_op_infos[alu->op].num_inputs == 2); \
1301 if (nir_src_bit_size(alu->src[0].src) == 1) \
1302 result = emit_binop(ctx, spv_log_op, dest_type, src[0], src[1]); \
1303 else \
1304 result = emit_binop(ctx, spv_op, dest_type, src[0], src[1]); \
1305 break;
1306
1307 BINOP_LOG(nir_op_iand, SpvOpBitwiseAnd, SpvOpLogicalAnd)
1308 BINOP_LOG(nir_op_ior, SpvOpBitwiseOr, SpvOpLogicalOr)
1309 BINOP_LOG(nir_op_ieq, SpvOpIEqual, SpvOpLogicalEqual)
1310 BINOP_LOG(nir_op_ine, SpvOpINotEqual, SpvOpLogicalNotEqual)
1311 #undef BINOP_LOG
1312
1313 #define BUILTIN_BINOP(nir_op, spirv_op) \
1314 case nir_op: \
1315 assert(nir_op_infos[alu->op].num_inputs == 2); \
1316 result = emit_builtin_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
1317 break;
1318
1319 BUILTIN_BINOP(nir_op_fmin, GLSLstd450FMin)
1320 BUILTIN_BINOP(nir_op_fmax, GLSLstd450FMax)
1321 BUILTIN_BINOP(nir_op_imin, GLSLstd450SMin)
1322 BUILTIN_BINOP(nir_op_imax, GLSLstd450SMax)
1323 BUILTIN_BINOP(nir_op_umin, GLSLstd450UMin)
1324 BUILTIN_BINOP(nir_op_umax, GLSLstd450UMax)
1325 #undef BUILTIN_BINOP
1326
1327 case nir_op_fdot2:
1328 case nir_op_fdot3:
1329 case nir_op_fdot4:
1330 assert(nir_op_infos[alu->op].num_inputs == 2);
1331 result = emit_binop(ctx, SpvOpDot, dest_type, src[0], src[1]);
1332 break;
1333
1334 case nir_op_fdph:
1335 unreachable("should already be lowered away");
1336
1337 case nir_op_seq:
1338 case nir_op_sne:
1339 case nir_op_slt:
1340 case nir_op_sge: {
1341 assert(nir_op_infos[alu->op].num_inputs == 2);
1342 int num_components = nir_dest_num_components(alu->dest.dest);
1343 SpvId bool_type = get_bvec_type(ctx, num_components);
1344
1345 SpvId zero = emit_float_const(ctx, bit_size, 0.0f);
1346 SpvId one = emit_float_const(ctx, bit_size, 1.0f);
1347 if (num_components > 1) {
1348 SpvId zero_comps[num_components], one_comps[num_components];
1349 for (int i = 0; i < num_components; i++) {
1350 zero_comps[i] = zero;
1351 one_comps[i] = one;
1352 }
1353
1354 zero = spirv_builder_const_composite(&ctx->builder, dest_type,
1355 zero_comps, num_components);
1356 one = spirv_builder_const_composite(&ctx->builder, dest_type,
1357 one_comps, num_components);
1358 }
1359
1360 SpvOp op;
1361 switch (alu->op) {
1362 case nir_op_seq: op = SpvOpFOrdEqual; break;
1363 case nir_op_sne: op = SpvOpFOrdNotEqual; break;
1364 case nir_op_slt: op = SpvOpFOrdLessThan; break;
1365 case nir_op_sge: op = SpvOpFOrdGreaterThanEqual; break;
1366 default: unreachable("unexpected op");
1367 }
1368
1369 result = emit_binop(ctx, op, bool_type, src[0], src[1]);
1370 result = emit_select(ctx, dest_type, result, one, zero);
1371 }
1372 break;
1373
1374 case nir_op_flrp:
1375 assert(nir_op_infos[alu->op].num_inputs == 3);
1376 result = emit_builtin_triop(ctx, GLSLstd450FMix, dest_type,
1377 src[0], src[1], src[2]);
1378 break;
1379
1380 case nir_op_fcsel:
1381 result = emit_binop(ctx, SpvOpFOrdGreaterThan,
1382 get_bvec_type(ctx, num_components),
1383 src[0],
1384 get_fvec_constant(ctx,
1385 nir_src_bit_size(alu->src[0].src),
1386 num_components, 0));
1387 result = emit_select(ctx, dest_type, result, src[1], src[2]);
1388 break;
1389
1390 case nir_op_bcsel:
1391 assert(nir_op_infos[alu->op].num_inputs == 3);
1392 result = emit_select(ctx, dest_type, src[0], src[1], src[2]);
1393 break;
1394
1395 case nir_op_bany_fnequal2:
1396 case nir_op_bany_fnequal3:
1397 case nir_op_bany_fnequal4: {
1398 assert(nir_op_infos[alu->op].num_inputs == 2);
1399 assert(alu_instr_src_components(alu, 0) ==
1400 alu_instr_src_components(alu, 1));
1401 assert(in_bit_sizes[0] == in_bit_sizes[1]);
1402 /* The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. */
1403 SpvOp op = in_bit_sizes[0] == 1 ? SpvOpLogicalNotEqual : SpvOpFOrdNotEqual;
1404 result = emit_binop(ctx, op,
1405 get_bvec_type(ctx, alu_instr_src_components(alu, 0)),
1406 src[0], src[1]);
1407 result = emit_unop(ctx, SpvOpAny, dest_type, result);
1408 break;
1409 }
1410
1411 case nir_op_ball_fequal2:
1412 case nir_op_ball_fequal3:
1413 case nir_op_ball_fequal4: {
1414 assert(nir_op_infos[alu->op].num_inputs == 2);
1415 assert(alu_instr_src_components(alu, 0) ==
1416 alu_instr_src_components(alu, 1));
1417 assert(in_bit_sizes[0] == in_bit_sizes[1]);
1418 /* The type of Operand 1 and Operand 2 must be a scalar or vector of floating-point type. */
1419 SpvOp op = in_bit_sizes[0] == 1 ? SpvOpLogicalEqual : SpvOpFOrdEqual;
1420 result = emit_binop(ctx, op,
1421 get_bvec_type(ctx, alu_instr_src_components(alu, 0)),
1422 src[0], src[1]);
1423 result = emit_unop(ctx, SpvOpAll, dest_type, result);
1424 break;
1425 }
1426
1427 case nir_op_bany_inequal2:
1428 case nir_op_bany_inequal3:
1429 case nir_op_bany_inequal4: {
1430 assert(nir_op_infos[alu->op].num_inputs == 2);
1431 assert(alu_instr_src_components(alu, 0) ==
1432 alu_instr_src_components(alu, 1));
1433 assert(in_bit_sizes[0] == in_bit_sizes[1]);
1434 /* The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. */
1435 SpvOp op = in_bit_sizes[0] == 1 ? SpvOpLogicalNotEqual : SpvOpINotEqual;
1436 result = emit_binop(ctx, op,
1437 get_bvec_type(ctx, alu_instr_src_components(alu, 0)),
1438 src[0], src[1]);
1439 result = emit_unop(ctx, SpvOpAny, dest_type, result);
1440 break;
1441 }
1442
1443 case nir_op_ball_iequal2:
1444 case nir_op_ball_iequal3:
1445 case nir_op_ball_iequal4: {
1446 assert(nir_op_infos[alu->op].num_inputs == 2);
1447 assert(alu_instr_src_components(alu, 0) ==
1448 alu_instr_src_components(alu, 1));
1449 assert(in_bit_sizes[0] == in_bit_sizes[1]);
1450 /* The type of Operand 1 and Operand 2 must be a scalar or vector of integer type. */
1451 SpvOp op = in_bit_sizes[0] == 1 ? SpvOpLogicalEqual : SpvOpIEqual;
1452 result = emit_binop(ctx, op,
1453 get_bvec_type(ctx, alu_instr_src_components(alu, 0)),
1454 src[0], src[1]);
1455 result = emit_unop(ctx, SpvOpAll, dest_type, result);
1456 break;
1457 }
1458
1459 case nir_op_vec2:
1460 case nir_op_vec3:
1461 case nir_op_vec4: {
1462 int num_inputs = nir_op_infos[alu->op].num_inputs;
1463 assert(2 <= num_inputs && num_inputs <= 4);
1464 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type,
1465 src, num_inputs);
1466 }
1467 break;
1468
1469 default:
1470 fprintf(stderr, "emit_alu: not implemented (%s)\n",
1471 nir_op_infos[alu->op].name);
1472
1473 unreachable("unsupported opcode");
1474 return;
1475 }
1476
1477 store_alu_result(ctx, alu, result);
1478 }
1479
1480 static void
1481 emit_load_const(struct ntv_context *ctx, nir_load_const_instr *load_const)
1482 {
1483 unsigned bit_size = load_const->def.bit_size;
1484 unsigned num_components = load_const->def.num_components;
1485
1486 SpvId constant;
1487 if (num_components > 1) {
1488 SpvId components[num_components];
1489 SpvId type;
1490 if (bit_size == 1) {
1491 for (int i = 0; i < num_components; i++)
1492 components[i] = spirv_builder_const_bool(&ctx->builder,
1493 load_const->value[i].b);
1494
1495 type = get_bvec_type(ctx, num_components);
1496 } else {
1497 for (int i = 0; i < num_components; i++)
1498 components[i] = emit_uint_const(ctx, bit_size,
1499 load_const->value[i].u32);
1500
1501 type = get_uvec_type(ctx, bit_size, num_components);
1502 }
1503 constant = spirv_builder_const_composite(&ctx->builder, type,
1504 components, num_components);
1505 } else {
1506 assert(num_components == 1);
1507 if (bit_size == 1)
1508 constant = spirv_builder_const_bool(&ctx->builder,
1509 load_const->value[0].b);
1510 else
1511 constant = emit_uint_const(ctx, bit_size, load_const->value[0].u32);
1512 }
1513
1514 store_ssa_def(ctx, &load_const->def, constant);
1515 }
1516
1517 static void
1518 emit_load_ubo(struct ntv_context *ctx, nir_intrinsic_instr *intr)
1519 {
1520 nir_const_value *const_block_index = nir_src_as_const_value(intr->src[0]);
1521 assert(const_block_index); // no dynamic indexing for now
1522 assert(const_block_index->u32 == 0); // we only support the default UBO for now
1523
1524 nir_const_value *const_offset = nir_src_as_const_value(intr->src[1]);
1525 if (const_offset) {
1526 SpvId uvec4_type = get_uvec_type(ctx, 32, 4);
1527 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1528 SpvStorageClassUniform,
1529 uvec4_type);
1530
1531 unsigned idx = const_offset->u32;
1532 SpvId member = emit_uint_const(ctx, 32, 0);
1533 SpvId offset = emit_uint_const(ctx, 32, idx);
1534 SpvId offsets[] = { member, offset };
1535 SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
1536 ctx->ubos[0], offsets,
1537 ARRAY_SIZE(offsets));
1538 SpvId result = spirv_builder_emit_load(&ctx->builder, uvec4_type, ptr);
1539
1540 SpvId type = get_dest_uvec_type(ctx, &intr->dest);
1541 unsigned num_components = nir_dest_num_components(intr->dest);
1542 if (num_components == 1) {
1543 uint32_t components[] = { 0 };
1544 result = spirv_builder_emit_composite_extract(&ctx->builder,
1545 type,
1546 result, components,
1547 1);
1548 } else if (num_components < 4) {
1549 SpvId constituents[num_components];
1550 SpvId uint_type = spirv_builder_type_uint(&ctx->builder, 32);
1551 for (uint32_t i = 0; i < num_components; ++i)
1552 constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
1553 uint_type,
1554 result, &i,
1555 1);
1556
1557 result = spirv_builder_emit_composite_construct(&ctx->builder,
1558 type,
1559 constituents,
1560 num_components);
1561 }
1562
1563 if (nir_dest_bit_size(intr->dest) == 1)
1564 result = uvec_to_bvec(ctx, result, num_components);
1565
1566 store_dest(ctx, &intr->dest, result, nir_type_uint);
1567 } else
1568 unreachable("uniform-addressing not yet supported");
1569 }
1570
1571 static void
1572 emit_discard(struct ntv_context *ctx, nir_intrinsic_instr *intr)
1573 {
1574 assert(ctx->block_started);
1575 spirv_builder_emit_kill(&ctx->builder);
1576 /* discard is weird in NIR, so let's just create an unreachable block after
1577 it and hope that the vulkan driver will DCE any instructinos in it. */
1578 spirv_builder_label(&ctx->builder, spirv_builder_new_id(&ctx->builder));
1579 }
1580
1581 static void
1582 emit_load_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
1583 {
1584 SpvId ptr = get_src(ctx, intr->src);
1585
1586 nir_variable *var = nir_intrinsic_get_var(intr, 0);
1587 SpvId result = spirv_builder_emit_load(&ctx->builder,
1588 get_glsl_type(ctx, var->type),
1589 ptr);
1590 unsigned num_components = nir_dest_num_components(intr->dest);
1591 unsigned bit_size = nir_dest_bit_size(intr->dest);
1592 result = bitcast_to_uvec(ctx, result, bit_size, num_components);
1593 store_dest(ctx, &intr->dest, result, nir_type_uint);
1594 }
1595
1596 static void
1597 emit_store_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
1598 {
1599 SpvId ptr = get_src(ctx, &intr->src[0]);
1600 SpvId src = get_src(ctx, &intr->src[1]);
1601
1602 nir_variable *var = nir_intrinsic_get_var(intr, 0);
1603 SpvId type = get_glsl_type(ctx, glsl_without_array(var->type));
1604 SpvId result = emit_bitcast(ctx, type, src);
1605 spirv_builder_emit_store(&ctx->builder, ptr, result);
1606 }
1607
1608 static SpvId
1609 create_builtin_var(struct ntv_context *ctx, SpvId var_type,
1610 SpvStorageClass storage_class,
1611 const char *name, SpvBuiltIn builtin)
1612 {
1613 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1614 storage_class,
1615 var_type);
1616 SpvId var = spirv_builder_emit_var(&ctx->builder, pointer_type,
1617 storage_class);
1618 spirv_builder_emit_name(&ctx->builder, var, name);
1619 spirv_builder_emit_builtin(&ctx->builder, var, builtin);
1620
1621 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
1622 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var;
1623 return var;
1624 }
1625
1626 static void
1627 emit_load_front_face(struct ntv_context *ctx, nir_intrinsic_instr *intr)
1628 {
1629 SpvId var_type = spirv_builder_type_bool(&ctx->builder);
1630 if (!ctx->front_face_var)
1631 ctx->front_face_var = create_builtin_var(ctx, var_type,
1632 SpvStorageClassInput,
1633 "gl_FrontFacing",
1634 SpvBuiltInFrontFacing);
1635
1636 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type,
1637 ctx->front_face_var);
1638 assert(1 == nir_dest_num_components(intr->dest));
1639 store_dest(ctx, &intr->dest, result, nir_type_bool);
1640 }
1641
1642 static void
1643 emit_load_instance_id(struct ntv_context *ctx, nir_intrinsic_instr *intr)
1644 {
1645 SpvId var_type = spirv_builder_type_uint(&ctx->builder, 32);
1646 if (!ctx->instance_id_var)
1647 ctx->instance_id_var = create_builtin_var(ctx, var_type,
1648 SpvStorageClassInput,
1649 "gl_InstanceId",
1650 SpvBuiltInInstanceIndex);
1651
1652 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type,
1653 ctx->instance_id_var);
1654 assert(1 == nir_dest_num_components(intr->dest));
1655 store_dest(ctx, &intr->dest, result, nir_type_uint);
1656 }
1657
1658 static void
1659 emit_load_vertex_id(struct ntv_context *ctx, nir_intrinsic_instr *intr)
1660 {
1661 SpvId var_type = spirv_builder_type_uint(&ctx->builder, 32);
1662 if (!ctx->vertex_id_var)
1663 ctx->vertex_id_var = create_builtin_var(ctx, var_type,
1664 SpvStorageClassInput,
1665 "gl_VertexID",
1666 SpvBuiltInVertexIndex);
1667
1668 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type,
1669 ctx->vertex_id_var);
1670 assert(1 == nir_dest_num_components(intr->dest));
1671 store_dest(ctx, &intr->dest, result, nir_type_uint);
1672 }
1673
1674 static void
1675 emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
1676 {
1677 switch (intr->intrinsic) {
1678 case nir_intrinsic_load_ubo:
1679 emit_load_ubo(ctx, intr);
1680 break;
1681
1682 case nir_intrinsic_discard:
1683 emit_discard(ctx, intr);
1684 break;
1685
1686 case nir_intrinsic_load_deref:
1687 emit_load_deref(ctx, intr);
1688 break;
1689
1690 case nir_intrinsic_store_deref:
1691 emit_store_deref(ctx, intr);
1692 break;
1693
1694 case nir_intrinsic_load_front_face:
1695 emit_load_front_face(ctx, intr);
1696 break;
1697
1698 case nir_intrinsic_load_instance_id:
1699 emit_load_instance_id(ctx, intr);
1700 break;
1701
1702 case nir_intrinsic_load_vertex_id:
1703 emit_load_vertex_id(ctx, intr);
1704 break;
1705
1706 default:
1707 fprintf(stderr, "emit_intrinsic: not implemented (%s)\n",
1708 nir_intrinsic_infos[intr->intrinsic].name);
1709 unreachable("unsupported intrinsic");
1710 }
1711 }
1712
1713 static void
1714 emit_undef(struct ntv_context *ctx, nir_ssa_undef_instr *undef)
1715 {
1716 SpvId type = get_uvec_type(ctx, undef->def.bit_size,
1717 undef->def.num_components);
1718
1719 store_ssa_def(ctx, &undef->def,
1720 spirv_builder_emit_undef(&ctx->builder, type));
1721 }
1722
1723 static SpvId
1724 get_src_float(struct ntv_context *ctx, nir_src *src)
1725 {
1726 SpvId def = get_src(ctx, src);
1727 unsigned num_components = nir_src_num_components(*src);
1728 unsigned bit_size = nir_src_bit_size(*src);
1729 return bitcast_to_fvec(ctx, def, bit_size, num_components);
1730 }
1731
1732 static SpvId
1733 get_src_int(struct ntv_context *ctx, nir_src *src)
1734 {
1735 SpvId def = get_src(ctx, src);
1736 unsigned num_components = nir_src_num_components(*src);
1737 unsigned bit_size = nir_src_bit_size(*src);
1738 return bitcast_to_ivec(ctx, def, bit_size, num_components);
1739 }
1740
1741 static void
1742 emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
1743 {
1744 assert(tex->op == nir_texop_tex ||
1745 tex->op == nir_texop_txb ||
1746 tex->op == nir_texop_txl ||
1747 tex->op == nir_texop_txd ||
1748 tex->op == nir_texop_txf ||
1749 tex->op == nir_texop_txf_ms ||
1750 tex->op == nir_texop_txs);
1751 assert(tex->texture_index == tex->sampler_index);
1752
1753 SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0,
1754 offset = 0, sample = 0;
1755 unsigned coord_components = 0;
1756 for (unsigned i = 0; i < tex->num_srcs; i++) {
1757 switch (tex->src[i].src_type) {
1758 case nir_tex_src_coord:
1759 if (tex->op == nir_texop_txf ||
1760 tex->op == nir_texop_txf_ms)
1761 coord = get_src_int(ctx, &tex->src[i].src);
1762 else
1763 coord = get_src_float(ctx, &tex->src[i].src);
1764 coord_components = nir_src_num_components(tex->src[i].src);
1765 break;
1766
1767 case nir_tex_src_projector:
1768 assert(nir_src_num_components(tex->src[i].src) == 1);
1769 proj = get_src_float(ctx, &tex->src[i].src);
1770 assert(proj != 0);
1771 break;
1772
1773 case nir_tex_src_offset:
1774 offset = get_src_int(ctx, &tex->src[i].src);
1775 break;
1776
1777 case nir_tex_src_bias:
1778 assert(tex->op == nir_texop_txb);
1779 bias = get_src_float(ctx, &tex->src[i].src);
1780 assert(bias != 0);
1781 break;
1782
1783 case nir_tex_src_lod:
1784 assert(nir_src_num_components(tex->src[i].src) == 1);
1785 if (tex->op == nir_texop_txf ||
1786 tex->op == nir_texop_txf_ms ||
1787 tex->op == nir_texop_txs)
1788 lod = get_src_int(ctx, &tex->src[i].src);
1789 else
1790 lod = get_src_float(ctx, &tex->src[i].src);
1791 assert(lod != 0);
1792 break;
1793
1794 case nir_tex_src_ms_index:
1795 assert(nir_src_num_components(tex->src[i].src) == 1);
1796 sample = get_src_int(ctx, &tex->src[i].src);
1797 break;
1798
1799 case nir_tex_src_comparator:
1800 assert(nir_src_num_components(tex->src[i].src) == 1);
1801 dref = get_src_float(ctx, &tex->src[i].src);
1802 assert(dref != 0);
1803 break;
1804
1805 case nir_tex_src_ddx:
1806 dx = get_src_float(ctx, &tex->src[i].src);
1807 assert(dx != 0);
1808 break;
1809
1810 case nir_tex_src_ddy:
1811 dy = get_src_float(ctx, &tex->src[i].src);
1812 assert(dy != 0);
1813 break;
1814
1815 default:
1816 fprintf(stderr, "texture source: %d\n", tex->src[i].src_type);
1817 unreachable("unknown texture source");
1818 }
1819 }
1820
1821 if (lod == 0 && ctx->stage != MESA_SHADER_FRAGMENT) {
1822 lod = emit_float_const(ctx, 32, 0.0f);
1823 assert(lod != 0);
1824 }
1825
1826 SpvId image_type = ctx->image_types[tex->texture_index];
1827 SpvId sampled_type = spirv_builder_type_sampled_image(&ctx->builder,
1828 image_type);
1829
1830 assert(ctx->samplers_used & (1u << tex->texture_index));
1831 SpvId load = spirv_builder_emit_load(&ctx->builder, sampled_type,
1832 ctx->samplers[tex->texture_index]);
1833
1834 SpvId dest_type = get_dest_type(ctx, &tex->dest, tex->dest_type);
1835
1836 if (tex->op == nir_texop_txs) {
1837 SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
1838 SpvId result = spirv_builder_emit_image_query_size(&ctx->builder,
1839 dest_type, image,
1840 lod);
1841 store_dest(ctx, &tex->dest, result, tex->dest_type);
1842 return;
1843 }
1844
1845 if (proj && coord_components > 0) {
1846 SpvId constituents[coord_components + 1];
1847 if (coord_components == 1)
1848 constituents[0] = coord;
1849 else {
1850 assert(coord_components > 1);
1851 SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
1852 for (uint32_t i = 0; i < coord_components; ++i)
1853 constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
1854 float_type,
1855 coord,
1856 &i, 1);
1857 }
1858
1859 constituents[coord_components++] = proj;
1860
1861 SpvId vec_type = get_fvec_type(ctx, 32, coord_components);
1862 coord = spirv_builder_emit_composite_construct(&ctx->builder,
1863 vec_type,
1864 constituents,
1865 coord_components);
1866 }
1867
1868 SpvId actual_dest_type = dest_type;
1869 if (dref)
1870 actual_dest_type = spirv_builder_type_float(&ctx->builder, 32);
1871
1872 SpvId result;
1873 if (tex->op == nir_texop_txf ||
1874 tex->op == nir_texop_txf_ms) {
1875 SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
1876 result = spirv_builder_emit_image_fetch(&ctx->builder, dest_type,
1877 image, coord, lod, sample);
1878 } else {
1879 result = spirv_builder_emit_image_sample(&ctx->builder,
1880 actual_dest_type, load,
1881 coord,
1882 proj != 0,
1883 lod, bias, dref, dx, dy,
1884 offset);
1885 }
1886
1887 spirv_builder_emit_decoration(&ctx->builder, result,
1888 SpvDecorationRelaxedPrecision);
1889
1890 if (dref && nir_dest_num_components(tex->dest) > 1) {
1891 SpvId components[4] = { result, result, result, result };
1892 result = spirv_builder_emit_composite_construct(&ctx->builder,
1893 dest_type,
1894 components,
1895 4);
1896 }
1897
1898 store_dest(ctx, &tex->dest, result, tex->dest_type);
1899 }
1900
1901 static void
1902 start_block(struct ntv_context *ctx, SpvId label)
1903 {
1904 /* terminate previous block if needed */
1905 if (ctx->block_started)
1906 spirv_builder_emit_branch(&ctx->builder, label);
1907
1908 /* start new block */
1909 spirv_builder_label(&ctx->builder, label);
1910 ctx->block_started = true;
1911 }
1912
1913 static void
1914 branch(struct ntv_context *ctx, SpvId label)
1915 {
1916 assert(ctx->block_started);
1917 spirv_builder_emit_branch(&ctx->builder, label);
1918 ctx->block_started = false;
1919 }
1920
1921 static void
1922 branch_conditional(struct ntv_context *ctx, SpvId condition, SpvId then_id,
1923 SpvId else_id)
1924 {
1925 assert(ctx->block_started);
1926 spirv_builder_emit_branch_conditional(&ctx->builder, condition,
1927 then_id, else_id);
1928 ctx->block_started = false;
1929 }
1930
1931 static void
1932 emit_jump(struct ntv_context *ctx, nir_jump_instr *jump)
1933 {
1934 switch (jump->type) {
1935 case nir_jump_break:
1936 assert(ctx->loop_break);
1937 branch(ctx, ctx->loop_break);
1938 break;
1939
1940 case nir_jump_continue:
1941 assert(ctx->loop_cont);
1942 branch(ctx, ctx->loop_cont);
1943 break;
1944
1945 default:
1946 unreachable("Unsupported jump type\n");
1947 }
1948 }
1949
1950 static void
1951 emit_deref_var(struct ntv_context *ctx, nir_deref_instr *deref)
1952 {
1953 assert(deref->deref_type == nir_deref_type_var);
1954
1955 struct hash_entry *he = _mesa_hash_table_search(ctx->vars, deref->var);
1956 assert(he);
1957 SpvId result = (SpvId)(intptr_t)he->data;
1958 store_dest_raw(ctx, &deref->dest, result);
1959 }
1960
1961 static void
1962 emit_deref_array(struct ntv_context *ctx, nir_deref_instr *deref)
1963 {
1964 assert(deref->deref_type == nir_deref_type_array);
1965 nir_variable *var = nir_deref_instr_get_variable(deref);
1966
1967 SpvStorageClass storage_class;
1968 switch (var->data.mode) {
1969 case nir_var_shader_in:
1970 storage_class = SpvStorageClassInput;
1971 break;
1972
1973 case nir_var_shader_out:
1974 storage_class = SpvStorageClassOutput;
1975 break;
1976
1977 default:
1978 unreachable("Unsupported nir_variable_mode\n");
1979 }
1980
1981 SpvId index = get_src(ctx, &deref->arr.index);
1982
1983 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
1984 storage_class,
1985 get_glsl_type(ctx, deref->type));
1986
1987 SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
1988 ptr_type,
1989 get_src(ctx, &deref->parent),
1990 &index, 1);
1991 /* uint is a bit of a lie here, it's really just an opaque type */
1992 store_dest(ctx, &deref->dest, result, nir_type_uint);
1993 }
1994
1995 static void
1996 emit_deref(struct ntv_context *ctx, nir_deref_instr *deref)
1997 {
1998 switch (deref->deref_type) {
1999 case nir_deref_type_var:
2000 emit_deref_var(ctx, deref);
2001 break;
2002
2003 case nir_deref_type_array:
2004 emit_deref_array(ctx, deref);
2005 break;
2006
2007 default:
2008 unreachable("unexpected deref_type");
2009 }
2010 }
2011
2012 static void
2013 emit_block(struct ntv_context *ctx, struct nir_block *block)
2014 {
2015 start_block(ctx, block_label(ctx, block));
2016 nir_foreach_instr(instr, block) {
2017 switch (instr->type) {
2018 case nir_instr_type_alu:
2019 emit_alu(ctx, nir_instr_as_alu(instr));
2020 break;
2021 case nir_instr_type_intrinsic:
2022 emit_intrinsic(ctx, nir_instr_as_intrinsic(instr));
2023 break;
2024 case nir_instr_type_load_const:
2025 emit_load_const(ctx, nir_instr_as_load_const(instr));
2026 break;
2027 case nir_instr_type_ssa_undef:
2028 emit_undef(ctx, nir_instr_as_ssa_undef(instr));
2029 break;
2030 case nir_instr_type_tex:
2031 emit_tex(ctx, nir_instr_as_tex(instr));
2032 break;
2033 case nir_instr_type_phi:
2034 unreachable("nir_instr_type_phi not supported");
2035 break;
2036 case nir_instr_type_jump:
2037 emit_jump(ctx, nir_instr_as_jump(instr));
2038 break;
2039 case nir_instr_type_call:
2040 unreachable("nir_instr_type_call not supported");
2041 break;
2042 case nir_instr_type_parallel_copy:
2043 unreachable("nir_instr_type_parallel_copy not supported");
2044 break;
2045 case nir_instr_type_deref:
2046 emit_deref(ctx, nir_instr_as_deref(instr));
2047 break;
2048 }
2049 }
2050 }
2051
2052 static void
2053 emit_cf_list(struct ntv_context *ctx, struct exec_list *list);
2054
2055 static SpvId
2056 get_src_bool(struct ntv_context *ctx, nir_src *src)
2057 {
2058 assert(nir_src_bit_size(*src) == 1);
2059 return get_src(ctx, src);
2060 }
2061
2062 static void
2063 emit_if(struct ntv_context *ctx, nir_if *if_stmt)
2064 {
2065 SpvId condition = get_src_bool(ctx, &if_stmt->condition);
2066
2067 SpvId header_id = spirv_builder_new_id(&ctx->builder);
2068 SpvId then_id = block_label(ctx, nir_if_first_then_block(if_stmt));
2069 SpvId endif_id = spirv_builder_new_id(&ctx->builder);
2070 SpvId else_id = endif_id;
2071
2072 bool has_else = !exec_list_is_empty(&if_stmt->else_list);
2073 if (has_else) {
2074 assert(nir_if_first_else_block(if_stmt)->index < ctx->num_blocks);
2075 else_id = block_label(ctx, nir_if_first_else_block(if_stmt));
2076 }
2077
2078 /* create a header-block */
2079 start_block(ctx, header_id);
2080 spirv_builder_emit_selection_merge(&ctx->builder, endif_id,
2081 SpvSelectionControlMaskNone);
2082 branch_conditional(ctx, condition, then_id, else_id);
2083
2084 emit_cf_list(ctx, &if_stmt->then_list);
2085
2086 if (has_else) {
2087 if (ctx->block_started)
2088 branch(ctx, endif_id);
2089
2090 emit_cf_list(ctx, &if_stmt->else_list);
2091 }
2092
2093 start_block(ctx, endif_id);
2094 }
2095
2096 static void
2097 emit_loop(struct ntv_context *ctx, nir_loop *loop)
2098 {
2099 SpvId header_id = spirv_builder_new_id(&ctx->builder);
2100 SpvId begin_id = block_label(ctx, nir_loop_first_block(loop));
2101 SpvId break_id = spirv_builder_new_id(&ctx->builder);
2102 SpvId cont_id = spirv_builder_new_id(&ctx->builder);
2103
2104 /* create a header-block */
2105 start_block(ctx, header_id);
2106 spirv_builder_loop_merge(&ctx->builder, break_id, cont_id, SpvLoopControlMaskNone);
2107 branch(ctx, begin_id);
2108
2109 SpvId save_break = ctx->loop_break;
2110 SpvId save_cont = ctx->loop_cont;
2111 ctx->loop_break = break_id;
2112 ctx->loop_cont = cont_id;
2113
2114 emit_cf_list(ctx, &loop->body);
2115
2116 ctx->loop_break = save_break;
2117 ctx->loop_cont = save_cont;
2118
2119 branch(ctx, cont_id);
2120 start_block(ctx, cont_id);
2121 branch(ctx, header_id);
2122
2123 start_block(ctx, break_id);
2124 }
2125
2126 static void
2127 emit_cf_list(struct ntv_context *ctx, struct exec_list *list)
2128 {
2129 foreach_list_typed(nir_cf_node, node, node, list) {
2130 switch (node->type) {
2131 case nir_cf_node_block:
2132 emit_block(ctx, nir_cf_node_as_block(node));
2133 break;
2134
2135 case nir_cf_node_if:
2136 emit_if(ctx, nir_cf_node_as_if(node));
2137 break;
2138
2139 case nir_cf_node_loop:
2140 emit_loop(ctx, nir_cf_node_as_loop(node));
2141 break;
2142
2143 case nir_cf_node_function:
2144 unreachable("nir_cf_node_function not supported");
2145 break;
2146 }
2147 }
2148 }
2149
2150 struct spirv_shader *
2151 nir_to_spirv(struct nir_shader *s, const struct pipe_stream_output_info *so_info, struct pipe_stream_output_info *local_so_info)
2152 {
2153 struct spirv_shader *ret = NULL;
2154
2155 struct ntv_context ctx = {};
2156
2157 switch (s->info.stage) {
2158 case MESA_SHADER_VERTEX:
2159 case MESA_SHADER_FRAGMENT:
2160 case MESA_SHADER_COMPUTE:
2161 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShader);
2162 break;
2163
2164 case MESA_SHADER_TESS_CTRL:
2165 case MESA_SHADER_TESS_EVAL:
2166 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellation);
2167 break;
2168
2169 case MESA_SHADER_GEOMETRY:
2170 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometry);
2171 break;
2172
2173 default:
2174 unreachable("invalid stage");
2175 }
2176
2177 // TODO: only enable when needed
2178 if (s->info.stage == MESA_SHADER_FRAGMENT) {
2179 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampled1D);
2180 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityImageQuery);
2181 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDerivativeControl);
2182 }
2183
2184 ctx.stage = s->info.stage;
2185 ctx.GLSL_std_450 = spirv_builder_import(&ctx.builder, "GLSL.std.450");
2186 spirv_builder_emit_source(&ctx.builder, SpvSourceLanguageGLSL, 450);
2187
2188 spirv_builder_emit_mem_model(&ctx.builder, SpvAddressingModelLogical,
2189 SpvMemoryModelGLSL450);
2190
2191 SpvExecutionModel exec_model;
2192 switch (s->info.stage) {
2193 case MESA_SHADER_VERTEX:
2194 exec_model = SpvExecutionModelVertex;
2195 break;
2196 case MESA_SHADER_TESS_CTRL:
2197 exec_model = SpvExecutionModelTessellationControl;
2198 break;
2199 case MESA_SHADER_TESS_EVAL:
2200 exec_model = SpvExecutionModelTessellationEvaluation;
2201 break;
2202 case MESA_SHADER_GEOMETRY:
2203 exec_model = SpvExecutionModelGeometry;
2204 break;
2205 case MESA_SHADER_FRAGMENT:
2206 exec_model = SpvExecutionModelFragment;
2207 break;
2208 case MESA_SHADER_COMPUTE:
2209 exec_model = SpvExecutionModelGLCompute;
2210 break;
2211 default:
2212 unreachable("invalid stage");
2213 }
2214
2215 SpvId type_void = spirv_builder_type_void(&ctx.builder);
2216 SpvId type_main = spirv_builder_type_function(&ctx.builder, type_void,
2217 NULL, 0);
2218 SpvId entry_point = spirv_builder_new_id(&ctx.builder);
2219 spirv_builder_emit_name(&ctx.builder, entry_point, "main");
2220
2221 ctx.vars = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
2222 _mesa_key_pointer_equal);
2223
2224 ctx.so_outputs = _mesa_hash_table_create(NULL, _mesa_hash_u32,
2225 _mesa_key_u32_equal);
2226
2227 nir_foreach_variable(var, &s->inputs)
2228 emit_input(&ctx, var);
2229
2230 nir_foreach_variable(var, &s->outputs)
2231 emit_output(&ctx, var);
2232
2233 if (so_info)
2234 emit_so_info(&ctx, util_last_bit64(s->info.outputs_written), so_info, local_so_info);
2235 nir_foreach_variable(var, &s->uniforms)
2236 emit_uniform(&ctx, var);
2237
2238 if (s->info.stage == MESA_SHADER_FRAGMENT) {
2239 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
2240 SpvExecutionModeOriginUpperLeft);
2241 if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
2242 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
2243 SpvExecutionModeDepthReplacing);
2244 }
2245
2246 if (so_info && so_info->num_outputs) {
2247 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTransformFeedback);
2248 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
2249 SpvExecutionModeXfb);
2250 }
2251
2252 spirv_builder_function(&ctx.builder, entry_point, type_void,
2253 SpvFunctionControlMaskNone,
2254 type_main);
2255
2256 nir_function_impl *entry = nir_shader_get_entrypoint(s);
2257 nir_metadata_require(entry, nir_metadata_block_index);
2258
2259 ctx.defs = (SpvId *)malloc(sizeof(SpvId) * entry->ssa_alloc);
2260 if (!ctx.defs)
2261 goto fail;
2262 ctx.num_defs = entry->ssa_alloc;
2263
2264 nir_index_local_regs(entry);
2265 ctx.regs = malloc(sizeof(SpvId) * entry->reg_alloc);
2266 if (!ctx.regs)
2267 goto fail;
2268 ctx.num_regs = entry->reg_alloc;
2269
2270 SpvId *block_ids = (SpvId *)malloc(sizeof(SpvId) * entry->num_blocks);
2271 if (!block_ids)
2272 goto fail;
2273
2274 for (int i = 0; i < entry->num_blocks; ++i)
2275 block_ids[i] = spirv_builder_new_id(&ctx.builder);
2276
2277 ctx.block_ids = block_ids;
2278 ctx.num_blocks = entry->num_blocks;
2279
2280 /* emit a block only for the variable declarations */
2281 start_block(&ctx, spirv_builder_new_id(&ctx.builder));
2282 foreach_list_typed(nir_register, reg, node, &entry->registers) {
2283 SpvId type = get_uvec_type(&ctx, reg->bit_size, reg->num_components);
2284 SpvId pointer_type = spirv_builder_type_pointer(&ctx.builder,
2285 SpvStorageClassFunction,
2286 type);
2287 SpvId var = spirv_builder_emit_var(&ctx.builder, pointer_type,
2288 SpvStorageClassFunction);
2289
2290 ctx.regs[reg->index] = var;
2291 }
2292
2293 emit_cf_list(&ctx, &entry->body);
2294
2295 free(ctx.defs);
2296
2297 if (so_info)
2298 emit_so_outputs(&ctx, so_info, local_so_info);
2299
2300 spirv_builder_return(&ctx.builder); // doesn't belong here, but whatevz
2301 spirv_builder_function_end(&ctx.builder);
2302
2303 spirv_builder_emit_entry_point(&ctx.builder, exec_model, entry_point,
2304 "main", ctx.entry_ifaces,
2305 ctx.num_entry_ifaces);
2306
2307 size_t num_words = spirv_builder_get_num_words(&ctx.builder);
2308
2309 ret = CALLOC_STRUCT(spirv_shader);
2310 if (!ret)
2311 goto fail;
2312
2313 ret->words = MALLOC(sizeof(uint32_t) * num_words);
2314 if (!ret->words)
2315 goto fail;
2316
2317 ret->num_words = spirv_builder_get_words(&ctx.builder, ret->words, num_words);
2318 assert(ret->num_words == num_words);
2319
2320 return ret;
2321
2322 fail:
2323
2324 if (ret)
2325 spirv_shader_delete(ret);
2326
2327 if (ctx.vars)
2328 _mesa_hash_table_destroy(ctx.vars, NULL);
2329
2330 if (ctx.so_outputs)
2331 _mesa_hash_table_destroy(ctx.so_outputs, NULL);
2332
2333 return NULL;
2334 }
2335
2336 void
2337 spirv_shader_delete(struct spirv_shader *s)
2338 {
2339 FREE(s->words);
2340 FREE(s);
2341 }