radeonsi: reduce type sizes in si_shader_selector
[mesa.git] / src / gallium / drivers / zink / nir_to_spirv / spirv_builder.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 "spirv_builder.h"
25
26 #include "util/macros.h"
27 #include "util/ralloc.h"
28 #include "util/u_bitcast.h"
29 #include "util/u_memory.h"
30 #include "util/hash_table.h"
31 #define XXH_INLINE_ALL
32 #include "util/xxhash.h"
33
34 #include <stdbool.h>
35 #include <inttypes.h>
36 #include <string.h>
37
38 static bool
39 spirv_buffer_grow(struct spirv_buffer *b, void *mem_ctx, size_t needed)
40 {
41 size_t new_room = MAX3(64, (b->room * 3) / 2, needed);
42
43 uint32_t *new_words = reralloc_size(mem_ctx, b->words,
44 new_room * sizeof(uint32_t));
45 if (!new_words)
46 return false;
47
48 b->words = new_words;
49 b->room = new_room;
50 return true;
51 }
52
53 static inline bool
54 spirv_buffer_prepare(struct spirv_buffer *b, void *mem_ctx, size_t needed)
55 {
56 needed += b->num_words;
57 if (b->room >= b->num_words + needed)
58 return true;
59
60 return spirv_buffer_grow(b, mem_ctx, needed);
61 }
62
63 static inline void
64 spirv_buffer_emit_word(struct spirv_buffer *b, uint32_t word)
65 {
66 assert(b->num_words < b->room);
67 b->words[b->num_words++] = word;
68 }
69
70 static int
71 spirv_buffer_emit_string(struct spirv_buffer *b, void *mem_ctx,
72 const char *str)
73 {
74 int pos = 0;
75 uint32_t word = 0;
76 while (str[pos] != '\0') {
77 word |= str[pos] << (8 * (pos % 4));
78 if (++pos % 4 == 0) {
79 spirv_buffer_prepare(b, mem_ctx, 1);
80 spirv_buffer_emit_word(b, word);
81 word = 0;
82 }
83 }
84
85 spirv_buffer_prepare(b, mem_ctx, 1);
86 spirv_buffer_emit_word(b, word);
87
88 return 1 + pos / 4;
89 }
90
91 void
92 spirv_builder_emit_cap(struct spirv_builder *b, SpvCapability cap)
93 {
94 spirv_buffer_prepare(&b->capabilities, b->mem_ctx, 2);
95 spirv_buffer_emit_word(&b->capabilities, SpvOpCapability | (2 << 16));
96 spirv_buffer_emit_word(&b->capabilities, cap);
97 }
98
99 void
100 spirv_builder_emit_extension(struct spirv_builder *b, const char *name)
101 {
102 size_t pos = b->extensions.num_words;
103 spirv_buffer_prepare(&b->extensions, b->mem_ctx, 1);
104 spirv_buffer_emit_word(&b->extensions, SpvOpExtension);
105 int len = spirv_buffer_emit_string(&b->extensions, b->mem_ctx, name);
106 b->extensions.words[pos] |= (1 + len) << 16;
107 }
108
109 void
110 spirv_builder_emit_source(struct spirv_builder *b, SpvSourceLanguage lang,
111 uint32_t version)
112 {
113 spirv_buffer_prepare(&b->debug_names, b->mem_ctx, 3);
114 spirv_buffer_emit_word(&b->debug_names, SpvOpSource | (3 << 16));
115 spirv_buffer_emit_word(&b->debug_names, lang);
116 spirv_buffer_emit_word(&b->debug_names, version);
117 }
118
119 void
120 spirv_builder_emit_mem_model(struct spirv_builder *b,
121 SpvAddressingModel addr_model,
122 SpvMemoryModel mem_model)
123 {
124 spirv_buffer_prepare(&b->memory_model, b->mem_ctx, 3);
125 spirv_buffer_emit_word(&b->memory_model, SpvOpMemoryModel | (3 << 16));
126 spirv_buffer_emit_word(&b->memory_model, addr_model);
127 spirv_buffer_emit_word(&b->memory_model, mem_model);
128 }
129
130 void
131 spirv_builder_emit_entry_point(struct spirv_builder *b,
132 SpvExecutionModel exec_model, SpvId entry_point,
133 const char *name, const SpvId interfaces[],
134 size_t num_interfaces)
135 {
136 size_t pos = b->entry_points.num_words;
137 spirv_buffer_prepare(&b->entry_points, b->mem_ctx, 3);
138 spirv_buffer_emit_word(&b->entry_points, SpvOpEntryPoint);
139 spirv_buffer_emit_word(&b->entry_points, exec_model);
140 spirv_buffer_emit_word(&b->entry_points, entry_point);
141 int len = spirv_buffer_emit_string(&b->entry_points, b->mem_ctx, name);
142 b->entry_points.words[pos] |= (3 + len + num_interfaces) << 16;
143 spirv_buffer_prepare(&b->entry_points, b->mem_ctx, num_interfaces);
144 for (int i = 0; i < num_interfaces; ++i)
145 spirv_buffer_emit_word(&b->entry_points, interfaces[i]);
146 }
147
148 void
149 spirv_builder_emit_exec_mode(struct spirv_builder *b, SpvId entry_point,
150 SpvExecutionMode exec_mode)
151 {
152 spirv_buffer_prepare(&b->exec_modes, b->mem_ctx, 3);
153 spirv_buffer_emit_word(&b->exec_modes, SpvOpExecutionMode | (3 << 16));
154 spirv_buffer_emit_word(&b->exec_modes, entry_point);
155 spirv_buffer_emit_word(&b->exec_modes, exec_mode);
156 }
157
158 void
159 spirv_builder_emit_name(struct spirv_builder *b, SpvId target,
160 const char *name)
161 {
162 size_t pos = b->debug_names.num_words;
163 spirv_buffer_prepare(&b->debug_names, b->mem_ctx, 2);
164 spirv_buffer_emit_word(&b->debug_names, SpvOpName);
165 spirv_buffer_emit_word(&b->debug_names, target);
166 int len = spirv_buffer_emit_string(&b->debug_names, b->mem_ctx, name);
167 b->debug_names.words[pos] |= (2 + len) << 16;
168 }
169
170 static void
171 emit_decoration(struct spirv_builder *b, SpvId target,
172 SpvDecoration decoration, const uint32_t extra_operands[],
173 size_t num_extra_operands)
174 {
175 int words = 3 + num_extra_operands;
176 spirv_buffer_prepare(&b->decorations, b->mem_ctx, words);
177 spirv_buffer_emit_word(&b->decorations, SpvOpDecorate | (words << 16));
178 spirv_buffer_emit_word(&b->decorations, target);
179 spirv_buffer_emit_word(&b->decorations, decoration);
180 for (int i = 0; i < num_extra_operands; ++i)
181 spirv_buffer_emit_word(&b->decorations, extra_operands[i]);
182 }
183
184 void
185 spirv_builder_emit_decoration(struct spirv_builder *b, SpvId target,
186 SpvDecoration decoration)
187 {
188 emit_decoration(b, target, decoration, NULL, 0);
189 }
190
191 void
192 spirv_builder_emit_location(struct spirv_builder *b, SpvId target,
193 uint32_t location)
194 {
195 uint32_t args[] = { location };
196 emit_decoration(b, target, SpvDecorationLocation, args, ARRAY_SIZE(args));
197 }
198
199 void
200 spirv_builder_emit_component(struct spirv_builder *b, SpvId target,
201 uint32_t component)
202 {
203 uint32_t args[] = { component };
204 emit_decoration(b, target, SpvDecorationComponent, args, ARRAY_SIZE(args));
205 }
206
207 void
208 spirv_builder_emit_builtin(struct spirv_builder *b, SpvId target,
209 SpvBuiltIn builtin)
210 {
211 uint32_t args[] = { builtin };
212 emit_decoration(b, target, SpvDecorationBuiltIn, args, ARRAY_SIZE(args));
213 }
214
215 void
216 spirv_builder_emit_descriptor_set(struct spirv_builder *b, SpvId target,
217 uint32_t descriptor_set)
218 {
219 uint32_t args[] = { descriptor_set };
220 emit_decoration(b, target, SpvDecorationDescriptorSet, args,
221 ARRAY_SIZE(args));
222 }
223
224 void
225 spirv_builder_emit_binding(struct spirv_builder *b, SpvId target,
226 uint32_t binding)
227 {
228 uint32_t args[] = { binding };
229 emit_decoration(b, target, SpvDecorationBinding, args, ARRAY_SIZE(args));
230 }
231
232 void
233 spirv_builder_emit_array_stride(struct spirv_builder *b, SpvId target,
234 uint32_t stride)
235 {
236 uint32_t args[] = { stride };
237 emit_decoration(b, target, SpvDecorationArrayStride, args, ARRAY_SIZE(args));
238 }
239
240 void
241 spirv_builder_emit_offset(struct spirv_builder *b, SpvId target,
242 uint32_t offset)
243 {
244 uint32_t args[] = { offset };
245 emit_decoration(b, target, SpvDecorationOffset, args, ARRAY_SIZE(args));
246 }
247
248 void
249 spirv_builder_emit_xfb_buffer(struct spirv_builder *b, SpvId target,
250 uint32_t buffer)
251 {
252 uint32_t args[] = { buffer };
253 emit_decoration(b, target, SpvDecorationXfbBuffer, args, ARRAY_SIZE(args));
254 }
255
256 void
257 spirv_builder_emit_xfb_stride(struct spirv_builder *b, SpvId target,
258 uint32_t stride)
259 {
260 uint32_t args[] = { stride };
261 emit_decoration(b, target, SpvDecorationXfbStride, args, ARRAY_SIZE(args));
262 }
263
264 void
265 spirv_builder_emit_index(struct spirv_builder *b, SpvId target, int index)
266 {
267 uint32_t args[] = { index };
268 emit_decoration(b, target, SpvDecorationIndex, args, ARRAY_SIZE(args));
269 }
270
271 static void
272 emit_member_decoration(struct spirv_builder *b, SpvId target, uint32_t member,
273 SpvDecoration decoration, const uint32_t extra_operands[],
274 size_t num_extra_operands)
275 {
276 int words = 4 + num_extra_operands;
277 spirv_buffer_prepare(&b->decorations, b->mem_ctx, words);
278 spirv_buffer_emit_word(&b->decorations,
279 SpvOpMemberDecorate | (words << 16));
280 spirv_buffer_emit_word(&b->decorations, target);
281 spirv_buffer_emit_word(&b->decorations, member);
282 spirv_buffer_emit_word(&b->decorations, decoration);
283 for (int i = 0; i < num_extra_operands; ++i)
284 spirv_buffer_emit_word(&b->decorations, extra_operands[i]);
285 }
286
287 void
288 spirv_builder_emit_member_offset(struct spirv_builder *b, SpvId target,
289 uint32_t member, uint32_t offset)
290 {
291 uint32_t args[] = { offset };
292 emit_member_decoration(b, target, member, SpvDecorationOffset,
293 args, ARRAY_SIZE(args));
294 }
295
296 SpvId
297 spirv_builder_emit_undef(struct spirv_builder *b, SpvId result_type)
298 {
299 SpvId result = spirv_builder_new_id(b);
300 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 3);
301 spirv_buffer_emit_word(&b->instructions, SpvOpUndef | (3 << 16));
302 spirv_buffer_emit_word(&b->instructions, result_type);
303 spirv_buffer_emit_word(&b->instructions, result);
304 return result;
305 }
306
307 void
308 spirv_builder_function(struct spirv_builder *b, SpvId result,
309 SpvId return_type,
310 SpvFunctionControlMask function_control,
311 SpvId function_type)
312 {
313 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 5);
314 spirv_buffer_emit_word(&b->instructions, SpvOpFunction | (5 << 16));
315 spirv_buffer_emit_word(&b->instructions, return_type);
316 spirv_buffer_emit_word(&b->instructions, result);
317 spirv_buffer_emit_word(&b->instructions, function_control);
318 spirv_buffer_emit_word(&b->instructions, function_type);
319 }
320
321 void
322 spirv_builder_function_end(struct spirv_builder *b)
323 {
324 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
325 spirv_buffer_emit_word(&b->instructions, SpvOpFunctionEnd | (1 << 16));
326 }
327
328 void
329 spirv_builder_label(struct spirv_builder *b, SpvId label)
330 {
331 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 2);
332 spirv_buffer_emit_word(&b->instructions, SpvOpLabel | (2 << 16));
333 spirv_buffer_emit_word(&b->instructions, label);
334 }
335
336 void
337 spirv_builder_return(struct spirv_builder *b)
338 {
339 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
340 spirv_buffer_emit_word(&b->instructions, SpvOpReturn | (1 << 16));
341 }
342
343 SpvId
344 spirv_builder_emit_load(struct spirv_builder *b, SpvId result_type,
345 SpvId pointer)
346 {
347 return spirv_builder_emit_unop(b, SpvOpLoad, result_type, pointer);
348 }
349
350 void
351 spirv_builder_emit_store(struct spirv_builder *b, SpvId pointer, SpvId object)
352 {
353 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 3);
354 spirv_buffer_emit_word(&b->instructions, SpvOpStore | (3 << 16));
355 spirv_buffer_emit_word(&b->instructions, pointer);
356 spirv_buffer_emit_word(&b->instructions, object);
357 }
358
359 SpvId
360 spirv_builder_emit_access_chain(struct spirv_builder *b, SpvId result_type,
361 SpvId base, const SpvId indexes[],
362 size_t num_indexes)
363 {
364 assert(base);
365 assert(result_type);
366 SpvId result = spirv_builder_new_id(b);
367
368 int words = 4 + num_indexes;
369 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
370 spirv_buffer_emit_word(&b->instructions, SpvOpAccessChain | (words << 16));
371 spirv_buffer_emit_word(&b->instructions, result_type);
372 spirv_buffer_emit_word(&b->instructions, result);
373 spirv_buffer_emit_word(&b->instructions, base);
374 for (int i = 0; i < num_indexes; ++i)
375 spirv_buffer_emit_word(&b->instructions, indexes[i]);
376 return result;
377 }
378
379
380 SpvId
381 spirv_builder_emit_unop(struct spirv_builder *b, SpvOp op, SpvId result_type,
382 SpvId operand)
383 {
384 SpvId result = spirv_builder_new_id(b);
385 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
386 spirv_buffer_emit_word(&b->instructions, op | (4 << 16));
387 spirv_buffer_emit_word(&b->instructions, result_type);
388 spirv_buffer_emit_word(&b->instructions, result);
389 spirv_buffer_emit_word(&b->instructions, operand);
390 return result;
391 }
392
393 SpvId
394 spirv_builder_emit_binop(struct spirv_builder *b, SpvOp op, SpvId result_type,
395 SpvId operand0, SpvId operand1)
396 {
397 SpvId result = spirv_builder_new_id(b);
398 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 5);
399 spirv_buffer_emit_word(&b->instructions, op | (5 << 16));
400 spirv_buffer_emit_word(&b->instructions, result_type);
401 spirv_buffer_emit_word(&b->instructions, result);
402 spirv_buffer_emit_word(&b->instructions, operand0);
403 spirv_buffer_emit_word(&b->instructions, operand1);
404 return result;
405 }
406
407 SpvId
408 spirv_builder_emit_triop(struct spirv_builder *b, SpvOp op, SpvId result_type,
409 SpvId operand0, SpvId operand1, SpvId operand2)
410 {
411 SpvId result = spirv_builder_new_id(b);
412 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 6);
413 spirv_buffer_emit_word(&b->instructions, op | (6 << 16));
414 spirv_buffer_emit_word(&b->instructions, result_type);
415 spirv_buffer_emit_word(&b->instructions, result);
416 spirv_buffer_emit_word(&b->instructions, operand0);
417 spirv_buffer_emit_word(&b->instructions, operand1);
418 spirv_buffer_emit_word(&b->instructions, operand2);
419 return result;
420 }
421
422 SpvId
423 spirv_builder_emit_composite_extract(struct spirv_builder *b, SpvId result_type,
424 SpvId composite, const uint32_t indexes[],
425 size_t num_indexes)
426 {
427 SpvId result = spirv_builder_new_id(b);
428
429 assert(num_indexes > 0);
430 int words = 4 + num_indexes;
431 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
432 spirv_buffer_emit_word(&b->instructions,
433 SpvOpCompositeExtract | (words << 16));
434 spirv_buffer_emit_word(&b->instructions, result_type);
435 spirv_buffer_emit_word(&b->instructions, result);
436 spirv_buffer_emit_word(&b->instructions, composite);
437 for (int i = 0; i < num_indexes; ++i)
438 spirv_buffer_emit_word(&b->instructions, indexes[i]);
439 return result;
440 }
441
442 SpvId
443 spirv_builder_emit_composite_construct(struct spirv_builder *b,
444 SpvId result_type,
445 const SpvId constituents[],
446 size_t num_constituents)
447 {
448 SpvId result = spirv_builder_new_id(b);
449
450 assert(num_constituents > 0);
451 int words = 3 + num_constituents;
452 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
453 spirv_buffer_emit_word(&b->instructions,
454 SpvOpCompositeConstruct | (words << 16));
455 spirv_buffer_emit_word(&b->instructions, result_type);
456 spirv_buffer_emit_word(&b->instructions, result);
457 for (int i = 0; i < num_constituents; ++i)
458 spirv_buffer_emit_word(&b->instructions, constituents[i]);
459 return result;
460 }
461
462 SpvId
463 spirv_builder_emit_vector_shuffle(struct spirv_builder *b, SpvId result_type,
464 SpvId vector_1, SpvId vector_2,
465 const uint32_t components[],
466 size_t num_components)
467 {
468 SpvId result = spirv_builder_new_id(b);
469
470 assert(num_components > 0);
471 int words = 5 + num_components;
472 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
473 spirv_buffer_emit_word(&b->instructions, SpvOpVectorShuffle | (words << 16));
474 spirv_buffer_emit_word(&b->instructions, result_type);
475 spirv_buffer_emit_word(&b->instructions, result);
476 spirv_buffer_emit_word(&b->instructions, vector_1);
477 spirv_buffer_emit_word(&b->instructions, vector_2);
478 for (int i = 0; i < num_components; ++i)
479 spirv_buffer_emit_word(&b->instructions, components[i]);
480 return result;
481 }
482
483 SpvId
484 spirv_builder_emit_vector_extract(struct spirv_builder *b, SpvId result_type,
485 SpvId vector_1,
486 uint32_t component)
487 {
488 SpvId result = spirv_builder_new_id(b);
489
490 int words = 5;
491 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
492 spirv_buffer_emit_word(&b->instructions, SpvOpVectorExtractDynamic | (words << 16));
493 spirv_buffer_emit_word(&b->instructions, result_type);
494 spirv_buffer_emit_word(&b->instructions, result);
495 spirv_buffer_emit_word(&b->instructions, vector_1);
496 spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, component));
497 return result;
498 }
499
500 SpvId
501 spirv_builder_emit_vector_insert(struct spirv_builder *b, SpvId result_type,
502 SpvId vector_1,
503 SpvId component,
504 uint32_t index)
505 {
506 SpvId result = spirv_builder_new_id(b);
507
508 int words = 6;
509 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
510 spirv_buffer_emit_word(&b->instructions, SpvOpVectorInsertDynamic | (words << 16));
511 spirv_buffer_emit_word(&b->instructions, result_type);
512 spirv_buffer_emit_word(&b->instructions, result);
513 spirv_buffer_emit_word(&b->instructions, vector_1);
514 spirv_buffer_emit_word(&b->instructions, component);
515 spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, index));
516 return result;
517 }
518
519 void
520 spirv_builder_emit_branch(struct spirv_builder *b, SpvId label)
521 {
522 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 2);
523 spirv_buffer_emit_word(&b->instructions, SpvOpBranch | (2 << 16));
524 spirv_buffer_emit_word(&b->instructions, label);
525 }
526
527 void
528 spirv_builder_emit_selection_merge(struct spirv_builder *b, SpvId merge_block,
529 SpvSelectionControlMask selection_control)
530 {
531 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 3);
532 spirv_buffer_emit_word(&b->instructions, SpvOpSelectionMerge | (3 << 16));
533 spirv_buffer_emit_word(&b->instructions, merge_block);
534 spirv_buffer_emit_word(&b->instructions, selection_control);
535 }
536
537 void
538 spirv_builder_loop_merge(struct spirv_builder *b, SpvId merge_block,
539 SpvId cont_target, SpvLoopControlMask loop_control)
540 {
541 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
542 spirv_buffer_emit_word(&b->instructions, SpvOpLoopMerge | (4 << 16));
543 spirv_buffer_emit_word(&b->instructions, merge_block);
544 spirv_buffer_emit_word(&b->instructions, cont_target);
545 spirv_buffer_emit_word(&b->instructions, loop_control);
546 }
547
548 void
549 spirv_builder_emit_branch_conditional(struct spirv_builder *b, SpvId condition,
550 SpvId true_label, SpvId false_label)
551 {
552 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
553 spirv_buffer_emit_word(&b->instructions, SpvOpBranchConditional | (4 << 16));
554 spirv_buffer_emit_word(&b->instructions, condition);
555 spirv_buffer_emit_word(&b->instructions, true_label);
556 spirv_buffer_emit_word(&b->instructions, false_label);
557 }
558
559 SpvId
560 spirv_builder_emit_phi(struct spirv_builder *b, SpvId result_type,
561 size_t num_vars, size_t *position)
562 {
563 SpvId result = spirv_builder_new_id(b);
564
565 assert(num_vars > 0);
566 int words = 3 + 2 * num_vars;
567 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
568 spirv_buffer_emit_word(&b->instructions, SpvOpPhi | (words << 16));
569 spirv_buffer_emit_word(&b->instructions, result_type);
570 spirv_buffer_emit_word(&b->instructions, result);
571 *position = b->instructions.num_words;
572 for (int i = 0; i < 2 * num_vars; ++i)
573 spirv_buffer_emit_word(&b->instructions, 0);
574 return result;
575 }
576
577 void
578 spirv_builder_set_phi_operand(struct spirv_builder *b, size_t position,
579 size_t index, SpvId variable, SpvId parent)
580 {
581 b->instructions.words[position + index * 2 + 0] = variable;
582 b->instructions.words[position + index * 2 + 1] = parent;
583 }
584
585 void
586 spirv_builder_emit_kill(struct spirv_builder *b)
587 {
588 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
589 spirv_buffer_emit_word(&b->instructions, SpvOpKill | (1 << 16));
590 }
591
592 SpvId
593 spirv_builder_emit_image_sample(struct spirv_builder *b,
594 SpvId result_type,
595 SpvId sampled_image,
596 SpvId coordinate,
597 bool proj,
598 SpvId lod,
599 SpvId bias,
600 SpvId dref,
601 SpvId dx,
602 SpvId dy,
603 SpvId offset)
604 {
605 SpvId result = spirv_builder_new_id(b);
606
607 int opcode = SpvOpImageSampleImplicitLod;
608 int operands = 5;
609 if (proj)
610 opcode += SpvOpImageSampleProjImplicitLod - SpvOpImageSampleImplicitLod;
611 if (lod || (dx && dy))
612 opcode += SpvOpImageSampleExplicitLod - SpvOpImageSampleImplicitLod;
613 if (dref) {
614 opcode += SpvOpImageSampleDrefImplicitLod - SpvOpImageSampleImplicitLod;
615 operands++;
616 }
617
618 SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
619 SpvId extra_operands[5];
620 int num_extra_operands = 0;
621 if (bias) {
622 extra_operands[++num_extra_operands] = bias;
623 operand_mask |= SpvImageOperandsBiasMask;
624 }
625 if (lod) {
626 extra_operands[++num_extra_operands] = lod;
627 operand_mask |= SpvImageOperandsLodMask;
628 } else if (dx && dy) {
629 extra_operands[++num_extra_operands] = dx;
630 extra_operands[++num_extra_operands] = dy;
631 operand_mask |= SpvImageOperandsGradMask;
632 }
633 if (offset) {
634 extra_operands[++num_extra_operands] = offset;
635 operand_mask |= SpvImageOperandsOffsetMask;
636 }
637
638 /* finalize num_extra_operands / extra_operands */
639 if (num_extra_operands > 0) {
640 extra_operands[0] = operand_mask;
641 num_extra_operands++;
642 }
643
644 spirv_buffer_prepare(&b->instructions, b->mem_ctx, operands + num_extra_operands);
645 spirv_buffer_emit_word(&b->instructions, opcode | ((operands + num_extra_operands) << 16));
646 spirv_buffer_emit_word(&b->instructions, result_type);
647 spirv_buffer_emit_word(&b->instructions, result);
648 spirv_buffer_emit_word(&b->instructions, sampled_image);
649 spirv_buffer_emit_word(&b->instructions, coordinate);
650 if (dref)
651 spirv_buffer_emit_word(&b->instructions, dref);
652 for (int i = 0; i < num_extra_operands; ++i)
653 spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
654 return result;
655 }
656
657 SpvId
658 spirv_builder_emit_image(struct spirv_builder *b, SpvId result_type,
659 SpvId sampled_image)
660 {
661 SpvId result = spirv_builder_new_id(b);
662 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
663 spirv_buffer_emit_word(&b->instructions, SpvOpImage | (4 << 16));
664 spirv_buffer_emit_word(&b->instructions, result_type);
665 spirv_buffer_emit_word(&b->instructions, result);
666 spirv_buffer_emit_word(&b->instructions, sampled_image);
667 return result;
668 }
669
670 SpvId
671 spirv_builder_emit_image_fetch(struct spirv_builder *b,
672 SpvId result_type,
673 SpvId image,
674 SpvId coordinate,
675 SpvId lod,
676 SpvId sample)
677 {
678 SpvId result = spirv_builder_new_id(b);
679
680 SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
681 SpvId extra_operands[3];
682 int num_extra_operands = 0;
683 if (lod) {
684 extra_operands[++num_extra_operands] = lod;
685 operand_mask |= SpvImageOperandsLodMask;
686 }
687 if (sample) {
688 extra_operands[++num_extra_operands] = sample;
689 operand_mask |= SpvImageOperandsSampleMask;
690 }
691
692 /* finalize num_extra_operands / extra_operands */
693 if (num_extra_operands > 0) {
694 extra_operands[0] = operand_mask;
695 num_extra_operands++;
696 }
697
698 spirv_buffer_prepare(&b->instructions, b->mem_ctx, 5 + num_extra_operands);
699 spirv_buffer_emit_word(&b->instructions, SpvOpImageFetch |
700 ((5 + num_extra_operands) << 16));
701 spirv_buffer_emit_word(&b->instructions, result_type);
702 spirv_buffer_emit_word(&b->instructions, result);
703 spirv_buffer_emit_word(&b->instructions, image);
704 spirv_buffer_emit_word(&b->instructions, coordinate);
705 for (int i = 0; i < num_extra_operands; ++i)
706 spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
707 return result;
708 }
709
710 SpvId
711 spirv_builder_emit_image_query_size(struct spirv_builder *b,
712 SpvId result_type,
713 SpvId image,
714 SpvId lod)
715 {
716 int opcode = SpvOpImageQuerySize;
717 int words = 4;
718 if (lod) {
719 words++;
720 opcode = SpvOpImageQuerySizeLod;
721 }
722
723 SpvId result = spirv_builder_new_id(b);
724 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
725 spirv_buffer_emit_word(&b->instructions, opcode | (words << 16));
726 spirv_buffer_emit_word(&b->instructions, result_type);
727 spirv_buffer_emit_word(&b->instructions, result);
728 spirv_buffer_emit_word(&b->instructions, image);
729
730 if (lod)
731 spirv_buffer_emit_word(&b->instructions, lod);
732
733 return result;
734 }
735
736 SpvId
737 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
738 SpvId set, uint32_t instruction,
739 const SpvId *args, size_t num_args)
740 {
741 SpvId result = spirv_builder_new_id(b);
742
743 int words = 5 + num_args;
744 spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
745 spirv_buffer_emit_word(&b->instructions, SpvOpExtInst | (words << 16));
746 spirv_buffer_emit_word(&b->instructions, result_type);
747 spirv_buffer_emit_word(&b->instructions, result);
748 spirv_buffer_emit_word(&b->instructions, set);
749 spirv_buffer_emit_word(&b->instructions, instruction);
750 for (int i = 0; i < num_args; ++i)
751 spirv_buffer_emit_word(&b->instructions, args[i]);
752 return result;
753 }
754
755 struct spirv_type {
756 SpvOp op;
757 uint32_t args[8];
758 size_t num_args;
759
760 SpvId type;
761 };
762
763 static uint32_t
764 non_aggregate_type_hash(const void *arg)
765 {
766 const struct spirv_type *type = arg;
767
768 uint32_t hash = 0;
769 hash = XXH32(&type->op, sizeof(type->op), hash);
770 hash = XXH32(type->args, sizeof(uint32_t) * type->num_args, hash);
771 return hash;
772 }
773
774 static bool
775 non_aggregate_type_equals(const void *a, const void *b)
776 {
777 const struct spirv_type *ta = a, *tb = b;
778
779 if (ta->op != tb->op)
780 return false;
781
782 assert(ta->num_args == tb->num_args);
783 return memcmp(ta->args, tb->args, sizeof(uint32_t) * ta->num_args) == 0;
784 }
785
786 static SpvId
787 get_type_def(struct spirv_builder *b, SpvOp op, const uint32_t args[],
788 size_t num_args)
789 {
790 /* According to the SPIR-V specification:
791 *
792 * "Two different type <id>s form, by definition, two different types. It
793 * is valid to declare multiple aggregate type <id>s having the same
794 * opcode and operands. This is to allow multiple instances of aggregate
795 * types with the same structure to be decorated differently. (Different
796 * decorations are not required; two different aggregate type <id>s are
797 * allowed to have identical declarations and decorations, and will still
798 * be two different types.) Non-aggregate types are different: It is
799 * invalid to declare multiple type <id>s for the same scalar, vector, or
800 * matrix type. That is, non-aggregate type declarations must all have
801 * different opcodes or operands. (Note that non-aggregate types cannot
802 * be decorated in ways that affect their type.)"
803 *
804 * ..so, we need to prevent the same non-aggregate type to be re-defined
805 * with a new <id>. We do this by putting the definitions in a hash-map, so
806 * we can easily look up and reuse them.
807 */
808
809 struct spirv_type key;
810 assert(num_args <= ARRAY_SIZE(key.args));
811 key.op = op;
812 memcpy(&key.args, args, sizeof(uint32_t) * num_args);
813 key.num_args = num_args;
814
815 struct hash_entry *entry;
816 if (b->types) {
817 entry = _mesa_hash_table_search(b->types, &key);
818 if (entry)
819 return ((struct spirv_type *)entry->data)->type;
820 } else {
821 b->types = _mesa_hash_table_create(b->mem_ctx,
822 non_aggregate_type_hash,
823 non_aggregate_type_equals);
824 assert(b->types);
825 }
826
827 struct spirv_type *type = rzalloc(b->mem_ctx, struct spirv_type);
828 if (!type)
829 return 0;
830
831 type->op = op;
832 memcpy(&type->args, args, sizeof(uint32_t) * num_args);
833 type->num_args = num_args;
834
835 type->type = spirv_builder_new_id(b);
836 spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, 2 + num_args);
837 spirv_buffer_emit_word(&b->types_const_defs, op | ((2 + num_args) << 16));
838 spirv_buffer_emit_word(&b->types_const_defs, type->type);
839 for (int i = 0; i < num_args; ++i)
840 spirv_buffer_emit_word(&b->types_const_defs, args[i]);
841
842 entry = _mesa_hash_table_insert(b->types, type, type);
843 assert(entry);
844
845 return ((struct spirv_type *)entry->data)->type;
846 }
847
848 SpvId
849 spirv_builder_type_void(struct spirv_builder *b)
850 {
851 return get_type_def(b, SpvOpTypeVoid, NULL, 0);
852 }
853
854 SpvId
855 spirv_builder_type_bool(struct spirv_builder *b)
856 {
857 return get_type_def(b, SpvOpTypeBool, NULL, 0);
858 }
859
860 SpvId
861 spirv_builder_type_int(struct spirv_builder *b, unsigned width)
862 {
863 uint32_t args[] = { width, 1 };
864 return get_type_def(b, SpvOpTypeInt, args, ARRAY_SIZE(args));
865 }
866
867 SpvId
868 spirv_builder_type_uint(struct spirv_builder *b, unsigned width)
869 {
870 uint32_t args[] = { width, 0 };
871 return get_type_def(b, SpvOpTypeInt, args, ARRAY_SIZE(args));
872 }
873
874 SpvId
875 spirv_builder_type_float(struct spirv_builder *b, unsigned width)
876 {
877 uint32_t args[] = { width };
878 return get_type_def(b, SpvOpTypeFloat, args, ARRAY_SIZE(args));
879 }
880
881 SpvId
882 spirv_builder_type_image(struct spirv_builder *b, SpvId sampled_type,
883 SpvDim dim, bool depth, bool arrayed, bool ms,
884 unsigned sampled, SpvImageFormat image_format)
885 {
886 assert(sampled < 3);
887 uint32_t args[] = {
888 sampled_type, dim, depth ? 1 : 0, arrayed ? 1 : 0, ms ? 1 : 0, sampled,
889 image_format
890 };
891 return get_type_def(b, SpvOpTypeImage, args, ARRAY_SIZE(args));
892 }
893
894 SpvId
895 spirv_builder_type_sampled_image(struct spirv_builder *b, SpvId image_type)
896 {
897 uint32_t args[] = { image_type };
898 return get_type_def(b, SpvOpTypeSampledImage, args, ARRAY_SIZE(args));
899 }
900
901 SpvId
902 spirv_builder_type_pointer(struct spirv_builder *b,
903 SpvStorageClass storage_class, SpvId type)
904 {
905 uint32_t args[] = { storage_class, type };
906 return get_type_def(b, SpvOpTypePointer, args, ARRAY_SIZE(args));
907 }
908
909 SpvId
910 spirv_builder_type_vector(struct spirv_builder *b, SpvId component_type,
911 unsigned component_count)
912 {
913 assert(component_count > 1);
914 uint32_t args[] = { component_type, component_count };
915 return get_type_def(b, SpvOpTypeVector, args, ARRAY_SIZE(args));
916 }
917
918 SpvId
919 spirv_builder_type_matrix(struct spirv_builder *b, SpvId component_type,
920 unsigned component_count)
921 {
922 assert(component_count > 1);
923 uint32_t args[] = { component_type, component_count };
924 return get_type_def(b, SpvOpTypeMatrix, args, ARRAY_SIZE(args));
925 }
926
927 SpvId
928 spirv_builder_type_array(struct spirv_builder *b, SpvId component_type,
929 SpvId length)
930 {
931 SpvId type = spirv_builder_new_id(b);
932 spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, 4);
933 spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeArray | (4 << 16));
934 spirv_buffer_emit_word(&b->types_const_defs, type);
935 spirv_buffer_emit_word(&b->types_const_defs, component_type);
936 spirv_buffer_emit_word(&b->types_const_defs, length);
937 return type;
938 }
939
940 SpvId
941 spirv_builder_type_struct(struct spirv_builder *b, const SpvId member_types[],
942 size_t num_member_types)
943 {
944 int words = 2 + num_member_types;
945 SpvId type = spirv_builder_new_id(b);
946 spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, words);
947 spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeStruct | (words << 16));
948 spirv_buffer_emit_word(&b->types_const_defs, type);
949 for (int i = 0; i < num_member_types; ++i)
950 spirv_buffer_emit_word(&b->types_const_defs, member_types[i]);
951 return type;
952 }
953
954 SpvId
955 spirv_builder_type_function(struct spirv_builder *b, SpvId return_type,
956 const SpvId parameter_types[],
957 size_t num_parameter_types)
958 {
959 int words = 3 + num_parameter_types;
960 SpvId type = spirv_builder_new_id(b);
961 spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, words);
962 spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeFunction | (words << 16));
963 spirv_buffer_emit_word(&b->types_const_defs, type);
964 spirv_buffer_emit_word(&b->types_const_defs, return_type);
965 for (int i = 0; i < num_parameter_types; ++i)
966 spirv_buffer_emit_word(&b->types_const_defs, parameter_types[i]);
967 return type;
968 }
969
970 struct spirv_const {
971 SpvOp op, type;
972 uint32_t args[8];
973 size_t num_args;
974
975 SpvId result;
976 };
977
978 static uint32_t
979 const_hash(const void *arg)
980 {
981 const struct spirv_const *key = arg;
982
983 uint32_t hash = 0;
984 hash = XXH32(&key->op, sizeof(key->op), hash);
985 hash = XXH32(&key->type, sizeof(key->type), hash);
986 hash = XXH32(key->args, sizeof(uint32_t) * key->num_args, hash);
987 return hash;
988 }
989
990 static bool
991 const_equals(const void *a, const void *b)
992 {
993 const struct spirv_const *ca = a, *cb = b;
994
995 if (ca->op != cb->op ||
996 ca->type != cb->type)
997 return false;
998
999 assert(ca->num_args == cb->num_args);
1000 return memcmp(ca->args, cb->args, sizeof(uint32_t) * ca->num_args) == 0;
1001 }
1002
1003 static SpvId
1004 get_const_def(struct spirv_builder *b, SpvOp op, SpvId type,
1005 const uint32_t args[], size_t num_args)
1006 {
1007 struct spirv_const key;
1008 assert(num_args <= ARRAY_SIZE(key.args));
1009 key.op = op;
1010 key.type = type;
1011 memcpy(&key.args, args, sizeof(uint32_t) * num_args);
1012 key.num_args = num_args;
1013
1014 struct hash_entry *entry;
1015 if (b->consts) {
1016 entry = _mesa_hash_table_search(b->consts, &key);
1017 if (entry)
1018 return ((struct spirv_const *)entry->data)->result;
1019 } else {
1020 b->consts = _mesa_hash_table_create(b->mem_ctx, const_hash,
1021 const_equals);
1022 assert(b->consts);
1023 }
1024
1025 struct spirv_const *cnst = rzalloc(b->mem_ctx, struct spirv_const);
1026 if (!cnst)
1027 return 0;
1028
1029 cnst->op = op;
1030 cnst->type = type;
1031 memcpy(&cnst->args, args, sizeof(uint32_t) * num_args);
1032 cnst->num_args = num_args;
1033
1034 cnst->result = spirv_builder_new_id(b);
1035 spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, 3 + num_args);
1036 spirv_buffer_emit_word(&b->types_const_defs, op | ((3 + num_args) << 16));
1037 spirv_buffer_emit_word(&b->types_const_defs, type);
1038 spirv_buffer_emit_word(&b->types_const_defs, cnst->result);
1039 for (int i = 0; i < num_args; ++i)
1040 spirv_buffer_emit_word(&b->types_const_defs, args[i]);
1041
1042 entry = _mesa_hash_table_insert(b->consts, cnst, cnst);
1043 assert(entry);
1044
1045 return ((struct spirv_const *)entry->data)->result;
1046 }
1047
1048 SpvId
1049 spirv_builder_const_bool(struct spirv_builder *b, bool val)
1050 {
1051 return get_const_def(b, val ? SpvOpConstantTrue : SpvOpConstantFalse,
1052 spirv_builder_type_bool(b), NULL, 0);
1053 }
1054
1055 SpvId
1056 spirv_builder_const_int(struct spirv_builder *b, int width, int32_t val)
1057 {
1058 assert(width <= 32);
1059 uint32_t args[] = { val };
1060 return get_const_def(b, SpvOpConstant, spirv_builder_type_int(b, width),
1061 args, ARRAY_SIZE(args));
1062 }
1063
1064 SpvId
1065 spirv_builder_const_uint(struct spirv_builder *b, int width, uint32_t val)
1066 {
1067 assert(width <= 32);
1068 uint32_t args[] = { val };
1069 return get_const_def(b, SpvOpConstant, spirv_builder_type_uint(b, width),
1070 args, ARRAY_SIZE(args));
1071 }
1072
1073 SpvId
1074 spirv_builder_const_float(struct spirv_builder *b, int width, float val)
1075 {
1076 assert(width <= 32);
1077 uint32_t args[] = { u_bitcast_f2u(val) };
1078 return get_const_def(b, SpvOpConstant, spirv_builder_type_float(b, width),
1079 args, ARRAY_SIZE(args));
1080 }
1081
1082 SpvId
1083 spirv_builder_const_composite(struct spirv_builder *b, SpvId result_type,
1084 const SpvId constituents[],
1085 size_t num_constituents)
1086 {
1087 return get_const_def(b, SpvOpConstantComposite, result_type,
1088 (const uint32_t *)constituents,
1089 num_constituents);
1090 }
1091
1092 SpvId
1093 spirv_builder_emit_var(struct spirv_builder *b, SpvId type,
1094 SpvStorageClass storage_class)
1095 {
1096 assert(storage_class != SpvStorageClassGeneric);
1097 struct spirv_buffer *buf = storage_class != SpvStorageClassFunction ?
1098 &b->types_const_defs : &b->instructions;
1099
1100 SpvId ret = spirv_builder_new_id(b);
1101 spirv_buffer_prepare(buf, b->mem_ctx, 4);
1102 spirv_buffer_emit_word(buf, SpvOpVariable | (4 << 16));
1103 spirv_buffer_emit_word(buf, type);
1104 spirv_buffer_emit_word(buf, ret);
1105 spirv_buffer_emit_word(buf, storage_class);
1106 return ret;
1107 }
1108
1109 SpvId
1110 spirv_builder_import(struct spirv_builder *b, const char *name)
1111 {
1112 SpvId result = spirv_builder_new_id(b);
1113 size_t pos = b->imports.num_words;
1114 spirv_buffer_prepare(&b->imports, b->mem_ctx, 2);
1115 spirv_buffer_emit_word(&b->imports, SpvOpExtInstImport);
1116 spirv_buffer_emit_word(&b->imports, result);
1117 int len = spirv_buffer_emit_string(&b->imports, b->mem_ctx, name);
1118 b->imports.words[pos] |= (2 + len) << 16;
1119 return result;
1120 }
1121
1122 size_t
1123 spirv_builder_get_num_words(struct spirv_builder *b)
1124 {
1125 const size_t header_size = 5;
1126 return header_size +
1127 b->capabilities.num_words +
1128 b->extensions.num_words +
1129 b->imports.num_words +
1130 b->memory_model.num_words +
1131 b->entry_points.num_words +
1132 b->exec_modes.num_words +
1133 b->debug_names.num_words +
1134 b->decorations.num_words +
1135 b->types_const_defs.num_words +
1136 b->instructions.num_words;
1137 }
1138
1139 size_t
1140 spirv_builder_get_words(struct spirv_builder *b, uint32_t *words,
1141 size_t num_words)
1142 {
1143 assert(num_words >= spirv_builder_get_num_words(b));
1144
1145 size_t written = 0;
1146 words[written++] = SpvMagicNumber;
1147 words[written++] = 0x00010000;
1148 words[written++] = 0;
1149 words[written++] = b->prev_id + 1;
1150 words[written++] = 0;
1151
1152 const struct spirv_buffer *buffers[] = {
1153 &b->capabilities,
1154 &b->extensions,
1155 &b->imports,
1156 &b->memory_model,
1157 &b->entry_points,
1158 &b->exec_modes,
1159 &b->debug_names,
1160 &b->decorations,
1161 &b->types_const_defs,
1162 &b->instructions
1163 };
1164
1165 for (int i = 0; i < ARRAY_SIZE(buffers); ++i) {
1166 const struct spirv_buffer *buffer = buffers[i];
1167 for (int j = 0; j < buffer->num_words; ++j)
1168 words[written++] = buffer->words[j];
1169 }
1170
1171 assert(written == spirv_builder_get_num_words(b));
1172 return written;
1173 }