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