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