zink: fixup initialization of operand_mask / num_extra_operands
[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 static void
226 emit_member_decoration(struct spirv_builder *b, SpvId target, uint32_t member,
227 SpvDecoration decoration, const uint32_t extra_operands[],
228 size_t num_extra_operands)
229 {
230 int words = 4 + num_extra_operands;
231 spirv_buffer_prepare(&b->decorations, words);
232 spirv_buffer_emit_word(&b->decorations,
233 SpvOpMemberDecorate | (words << 16));
234 spirv_buffer_emit_word(&b->decorations, target);
235 spirv_buffer_emit_word(&b->decorations, member);
236 spirv_buffer_emit_word(&b->decorations, decoration);
237 for (int i = 0; i < num_extra_operands; ++i)
238 spirv_buffer_emit_word(&b->decorations, extra_operands[i]);
239 }
240
241 void
242 spirv_builder_emit_member_offset(struct spirv_builder *b, SpvId target,
243 uint32_t member, uint32_t offset)
244 {
245 uint32_t args[] = { offset };
246 emit_member_decoration(b, target, member, SpvDecorationOffset,
247 args, ARRAY_SIZE(args));
248 }
249
250 SpvId
251 spirv_builder_emit_undef(struct spirv_builder *b, SpvId result_type)
252 {
253 SpvId result = spirv_builder_new_id(b);
254 spirv_buffer_prepare(&b->instructions, 3);
255 spirv_buffer_emit_word(&b->instructions, SpvOpUndef | (3 << 16));
256 spirv_buffer_emit_word(&b->instructions, result_type);
257 spirv_buffer_emit_word(&b->instructions, result);
258 return result;
259 }
260
261 void
262 spirv_builder_function(struct spirv_builder *b, SpvId result,
263 SpvId return_type,
264 SpvFunctionControlMask function_control,
265 SpvId function_type)
266 {
267 spirv_buffer_prepare(&b->instructions, 5);
268 spirv_buffer_emit_word(&b->instructions, SpvOpFunction | (5 << 16));
269 spirv_buffer_emit_word(&b->instructions, return_type);
270 spirv_buffer_emit_word(&b->instructions, result);
271 spirv_buffer_emit_word(&b->instructions, function_control);
272 spirv_buffer_emit_word(&b->instructions, function_type);
273 }
274
275 void
276 spirv_builder_function_end(struct spirv_builder *b)
277 {
278 spirv_buffer_prepare(&b->instructions, 1);
279 spirv_buffer_emit_word(&b->instructions, SpvOpFunctionEnd | (1 << 16));
280 }
281
282 void
283 spirv_builder_label(struct spirv_builder *b, SpvId label)
284 {
285 spirv_buffer_prepare(&b->instructions, 2);
286 spirv_buffer_emit_word(&b->instructions, SpvOpLabel | (2 << 16));
287 spirv_buffer_emit_word(&b->instructions, label);
288 }
289
290 void
291 spirv_builder_return(struct spirv_builder *b)
292 {
293 spirv_buffer_prepare(&b->instructions, 1);
294 spirv_buffer_emit_word(&b->instructions, SpvOpReturn | (1 << 16));
295 }
296
297 SpvId
298 spirv_builder_emit_load(struct spirv_builder *b, SpvId result_type,
299 SpvId pointer)
300 {
301 return spirv_builder_emit_unop(b, SpvOpLoad, result_type, pointer);
302 }
303
304 void
305 spirv_builder_emit_store(struct spirv_builder *b, SpvId pointer, SpvId object)
306 {
307 spirv_buffer_prepare(&b->instructions, 3);
308 spirv_buffer_emit_word(&b->instructions, SpvOpStore | (3 << 16));
309 spirv_buffer_emit_word(&b->instructions, pointer);
310 spirv_buffer_emit_word(&b->instructions, object);
311 }
312
313 SpvId
314 spirv_builder_emit_access_chain(struct spirv_builder *b, SpvId result_type,
315 SpvId base, const SpvId indexes[],
316 size_t num_indexes)
317 {
318 SpvId result = spirv_builder_new_id(b);
319
320 int words = 4 + num_indexes;
321 spirv_buffer_prepare(&b->instructions, words);
322 spirv_buffer_emit_word(&b->instructions, SpvOpAccessChain | (words << 16));
323 spirv_buffer_emit_word(&b->instructions, result_type);
324 spirv_buffer_emit_word(&b->instructions, result);
325 spirv_buffer_emit_word(&b->instructions, base);
326 for (int i = 0; i < num_indexes; ++i)
327 spirv_buffer_emit_word(&b->instructions, indexes[i]);
328 return result;
329 }
330
331
332 SpvId
333 spirv_builder_emit_unop(struct spirv_builder *b, SpvOp op, SpvId result_type,
334 SpvId operand)
335 {
336 SpvId result = spirv_builder_new_id(b);
337 spirv_buffer_prepare(&b->instructions, 4);
338 spirv_buffer_emit_word(&b->instructions, op | (4 << 16));
339 spirv_buffer_emit_word(&b->instructions, result_type);
340 spirv_buffer_emit_word(&b->instructions, result);
341 spirv_buffer_emit_word(&b->instructions, operand);
342 return result;
343 }
344
345 SpvId
346 spirv_builder_emit_binop(struct spirv_builder *b, SpvOp op, SpvId result_type,
347 SpvId operand0, SpvId operand1)
348 {
349 SpvId result = spirv_builder_new_id(b);
350 spirv_buffer_prepare(&b->instructions, 5);
351 spirv_buffer_emit_word(&b->instructions, op | (5 << 16));
352 spirv_buffer_emit_word(&b->instructions, result_type);
353 spirv_buffer_emit_word(&b->instructions, result);
354 spirv_buffer_emit_word(&b->instructions, operand0);
355 spirv_buffer_emit_word(&b->instructions, operand1);
356 return result;
357 }
358
359 SpvId
360 spirv_builder_emit_triop(struct spirv_builder *b, SpvOp op, SpvId result_type,
361 SpvId operand0, SpvId operand1, SpvId operand2)
362 {
363 SpvId result = spirv_builder_new_id(b);
364 spirv_buffer_prepare(&b->instructions, 6);
365 spirv_buffer_emit_word(&b->instructions, op | (6 << 16));
366 spirv_buffer_emit_word(&b->instructions, result_type);
367 spirv_buffer_emit_word(&b->instructions, result);
368 spirv_buffer_emit_word(&b->instructions, operand0);
369 spirv_buffer_emit_word(&b->instructions, operand1);
370 spirv_buffer_emit_word(&b->instructions, operand2);
371 return result;
372 }
373
374 SpvId
375 spirv_builder_emit_composite_extract(struct spirv_builder *b, SpvId result_type,
376 SpvId composite, const uint32_t indexes[],
377 size_t num_indexes)
378 {
379 SpvId result = spirv_builder_new_id(b);
380
381 assert(num_indexes > 0);
382 int words = 4 + num_indexes;
383 spirv_buffer_prepare(&b->instructions, words);
384 spirv_buffer_emit_word(&b->instructions,
385 SpvOpCompositeExtract | (words << 16));
386 spirv_buffer_emit_word(&b->instructions, result_type);
387 spirv_buffer_emit_word(&b->instructions, result);
388 spirv_buffer_emit_word(&b->instructions, composite);
389 for (int i = 0; i < num_indexes; ++i)
390 spirv_buffer_emit_word(&b->instructions, indexes[i]);
391 return result;
392 }
393
394 SpvId
395 spirv_builder_emit_composite_construct(struct spirv_builder *b,
396 SpvId result_type,
397 const SpvId constituents[],
398 size_t num_constituents)
399 {
400 SpvId result = spirv_builder_new_id(b);
401
402 assert(num_constituents > 0);
403 int words = 3 + num_constituents;
404 spirv_buffer_prepare(&b->instructions, words);
405 spirv_buffer_emit_word(&b->instructions,
406 SpvOpCompositeConstruct | (words << 16));
407 spirv_buffer_emit_word(&b->instructions, result_type);
408 spirv_buffer_emit_word(&b->instructions, result);
409 for (int i = 0; i < num_constituents; ++i)
410 spirv_buffer_emit_word(&b->instructions, constituents[i]);
411 return result;
412 }
413
414 SpvId
415 spirv_builder_emit_vector_shuffle(struct spirv_builder *b, SpvId result_type,
416 SpvId vector_1, SpvId vector_2,
417 const uint32_t components[],
418 size_t num_components)
419 {
420 SpvId result = spirv_builder_new_id(b);
421
422 assert(num_components > 0);
423 int words = 5 + num_components;
424 spirv_buffer_prepare(&b->instructions, words);
425 spirv_buffer_emit_word(&b->instructions, SpvOpVectorShuffle | (words << 16));
426 spirv_buffer_emit_word(&b->instructions, result_type);
427 spirv_buffer_emit_word(&b->instructions, result);
428 spirv_buffer_emit_word(&b->instructions, vector_1);
429 spirv_buffer_emit_word(&b->instructions, vector_2);
430 for (int i = 0; i < num_components; ++i)
431 spirv_buffer_emit_word(&b->instructions, components[i]);
432 return result;
433 }
434
435 void
436 spirv_builder_emit_branch(struct spirv_builder *b, SpvId label)
437 {
438 spirv_buffer_prepare(&b->instructions, 2);
439 spirv_buffer_emit_word(&b->instructions, SpvOpBranch | (2 << 16));
440 spirv_buffer_emit_word(&b->instructions, label);
441 }
442
443 void
444 spirv_builder_emit_selection_merge(struct spirv_builder *b, SpvId merge_block,
445 SpvSelectionControlMask selection_control)
446 {
447 spirv_buffer_prepare(&b->instructions, 3);
448 spirv_buffer_emit_word(&b->instructions, SpvOpSelectionMerge | (3 << 16));
449 spirv_buffer_emit_word(&b->instructions, merge_block);
450 spirv_buffer_emit_word(&b->instructions, selection_control);
451 }
452
453 void
454 spirv_builder_loop_merge(struct spirv_builder *b, SpvId merge_block,
455 SpvId cont_target, SpvLoopControlMask loop_control)
456 {
457 spirv_buffer_prepare(&b->instructions, 4);
458 spirv_buffer_emit_word(&b->instructions, SpvOpLoopMerge | (4 << 16));
459 spirv_buffer_emit_word(&b->instructions, merge_block);
460 spirv_buffer_emit_word(&b->instructions, cont_target);
461 spirv_buffer_emit_word(&b->instructions, loop_control);
462 }
463
464 void
465 spirv_builder_emit_branch_conditional(struct spirv_builder *b, SpvId condition,
466 SpvId true_label, SpvId false_label)
467 {
468 spirv_buffer_prepare(&b->instructions, 4);
469 spirv_buffer_emit_word(&b->instructions, SpvOpBranchConditional | (4 << 16));
470 spirv_buffer_emit_word(&b->instructions, condition);
471 spirv_buffer_emit_word(&b->instructions, true_label);
472 spirv_buffer_emit_word(&b->instructions, false_label);
473 }
474
475 SpvId
476 spirv_builder_emit_phi(struct spirv_builder *b, SpvId result_type,
477 size_t num_vars, size_t *position)
478 {
479 SpvId result = spirv_builder_new_id(b);
480
481 assert(num_vars > 0);
482 int words = 3 + 2 * num_vars;
483 spirv_buffer_prepare(&b->instructions, words);
484 spirv_buffer_emit_word(&b->instructions, SpvOpPhi | (words << 16));
485 spirv_buffer_emit_word(&b->instructions, result_type);
486 spirv_buffer_emit_word(&b->instructions, result);
487 *position = b->instructions.num_words;
488 for (int i = 0; i < 2 * num_vars; ++i)
489 spirv_buffer_emit_word(&b->instructions, 0);
490 return result;
491 }
492
493 void
494 spirv_builder_set_phi_operand(struct spirv_builder *b, size_t position,
495 size_t index, SpvId variable, SpvId parent)
496 {
497 b->instructions.words[position + index * 2 + 0] = variable;
498 b->instructions.words[position + index * 2 + 1] = parent;
499 }
500
501 void
502 spirv_builder_emit_kill(struct spirv_builder *b)
503 {
504 spirv_buffer_prepare(&b->instructions, 1);
505 spirv_buffer_emit_word(&b->instructions, SpvOpKill | (1 << 16));
506 }
507
508 SpvId
509 spirv_builder_emit_image_sample(struct spirv_builder *b,
510 SpvId result_type,
511 SpvId sampled_image,
512 SpvId coordinate,
513 bool proj,
514 SpvId lod,
515 SpvId bias,
516 SpvId dref,
517 SpvId dx,
518 SpvId dy)
519 {
520 SpvId result = spirv_builder_new_id(b);
521
522 int opcode = SpvOpImageSampleImplicitLod;
523 int operands = 5;
524 if (proj)
525 opcode += SpvOpImageSampleProjImplicitLod - SpvOpImageSampleImplicitLod;
526 if (lod || (dx && dy))
527 opcode += SpvOpImageSampleExplicitLod - SpvOpImageSampleImplicitLod;
528 if (dref) {
529 opcode += SpvOpImageSampleDrefImplicitLod - SpvOpImageSampleImplicitLod;
530 operands++;
531 }
532
533 SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
534 SpvId extra_operands[4];
535 int num_extra_operands = 0;
536 if (bias) {
537 extra_operands[++num_extra_operands] = bias;
538 operand_mask |= SpvImageOperandsBiasMask;
539 }
540 if (lod) {
541 extra_operands[++num_extra_operands] = lod;
542 operand_mask |= SpvImageOperandsLodMask;
543 } else if (dx && dy) {
544 extra_operands[++num_extra_operands] = dx;
545 extra_operands[++num_extra_operands] = dy;
546 operand_mask |= SpvImageOperandsGradMask;
547 }
548
549 /* finalize num_extra_operands / extra_operands */
550 if (num_extra_operands > 0) {
551 extra_operands[0] = operand_mask;
552 num_extra_operands++;
553 }
554
555 spirv_buffer_prepare(&b->instructions, operands + num_extra_operands);
556 spirv_buffer_emit_word(&b->instructions, opcode | ((operands + num_extra_operands) << 16));
557 spirv_buffer_emit_word(&b->instructions, result_type);
558 spirv_buffer_emit_word(&b->instructions, result);
559 spirv_buffer_emit_word(&b->instructions, sampled_image);
560 spirv_buffer_emit_word(&b->instructions, coordinate);
561 if (dref)
562 spirv_buffer_emit_word(&b->instructions, dref);
563 for (int i = 0; i < num_extra_operands; ++i)
564 spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
565 return result;
566 }
567
568 SpvId
569 spirv_builder_emit_image(struct spirv_builder *b, SpvId result_type,
570 SpvId sampled_image)
571 {
572 SpvId result = spirv_builder_new_id(b);
573 spirv_buffer_prepare(&b->instructions, 4);
574 spirv_buffer_emit_word(&b->instructions, SpvOpImage | (4 << 16));
575 spirv_buffer_emit_word(&b->instructions, result_type);
576 spirv_buffer_emit_word(&b->instructions, result);
577 spirv_buffer_emit_word(&b->instructions, sampled_image);
578 return result;
579 }
580
581 SpvId
582 spirv_builder_emit_image_fetch(struct spirv_builder *b,
583 SpvId result_type,
584 SpvId image,
585 SpvId coordinate,
586 SpvId lod)
587 {
588 SpvId result = spirv_builder_new_id(b);
589
590 SpvId extra_operands[2];
591 int num_extra_operands = 0;
592 if (lod) {
593 extra_operands[0] = SpvImageOperandsLodMask;
594 extra_operands[1] = lod;
595 num_extra_operands = 2;
596 }
597
598 spirv_buffer_prepare(&b->instructions, 5 + num_extra_operands);
599 spirv_buffer_emit_word(&b->instructions, SpvOpImageFetch |
600 ((5 + num_extra_operands) << 16));
601 spirv_buffer_emit_word(&b->instructions, result_type);
602 spirv_buffer_emit_word(&b->instructions, result);
603 spirv_buffer_emit_word(&b->instructions, image);
604 spirv_buffer_emit_word(&b->instructions, coordinate);
605 for (int i = 0; i < num_extra_operands; ++i)
606 spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
607 return result;
608 }
609
610 SpvId
611 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
612 SpvId set, uint32_t instruction,
613 const SpvId *args, size_t num_args)
614 {
615 SpvId result = spirv_builder_new_id(b);
616
617 int words = 5 + num_args;
618 spirv_buffer_prepare(&b->instructions, words);
619 spirv_buffer_emit_word(&b->instructions, SpvOpExtInst | (words << 16));
620 spirv_buffer_emit_word(&b->instructions, result_type);
621 spirv_buffer_emit_word(&b->instructions, result);
622 spirv_buffer_emit_word(&b->instructions, set);
623 spirv_buffer_emit_word(&b->instructions, instruction);
624 for (int i = 0; i < num_args; ++i)
625 spirv_buffer_emit_word(&b->instructions, args[i]);
626 return result;
627 }
628
629 struct spirv_type {
630 SpvOp op;
631 uint32_t args[8];
632 size_t num_args;
633
634 SpvId type;
635 };
636
637 static uint32_t
638 non_aggregate_type_hash(const void *arg)
639 {
640 const struct spirv_type *type = arg;
641
642 uint32_t hash = _mesa_fnv32_1a_offset_bias;
643 hash = _mesa_fnv32_1a_accumulate(hash, type->op);
644 hash = _mesa_fnv32_1a_accumulate_block(hash, type->args, sizeof(uint32_t) *
645 type->num_args);
646 return hash;
647 }
648
649 static bool
650 non_aggregate_type_equals(const void *a, const void *b)
651 {
652 const struct spirv_type *ta = a, *tb = b;
653
654 if (ta->op != tb->op)
655 return false;
656
657 assert(ta->num_args == tb->num_args);
658 return memcmp(ta->args, tb->args, sizeof(uint32_t) * ta->num_args) == 0;
659 }
660
661 static SpvId
662 get_type_def(struct spirv_builder *b, SpvOp op, const uint32_t args[],
663 size_t num_args)
664 {
665 /* According to the SPIR-V specification:
666 *
667 * "Two different type <id>s form, by definition, two different types. It
668 * is valid to declare multiple aggregate type <id>s having the same
669 * opcode and operands. This is to allow multiple instances of aggregate
670 * types with the same structure to be decorated differently. (Different
671 * decorations are not required; two different aggregate type <id>s are
672 * allowed to have identical declarations and decorations, and will still
673 * be two different types.) Non-aggregate types are different: It is
674 * invalid to declare multiple type <id>s for the same scalar, vector, or
675 * matrix type. That is, non-aggregate type declarations must all have
676 * different opcodes or operands. (Note that non-aggregate types cannot
677 * be decorated in ways that affect their type.)"
678 *
679 * ..so, we need to prevent the same non-aggregate type to be re-defined
680 * with a new <id>. We do this by putting the definitions in a hash-map, so
681 * we can easily look up and reuse them.
682 */
683
684 struct spirv_type key;
685 assert(num_args <= ARRAY_SIZE(key.args));
686 key.op = op;
687 memcpy(&key.args, args, sizeof(uint32_t) * num_args);
688 key.num_args = num_args;
689
690 struct hash_entry *entry;
691 if (b->types) {
692 entry = _mesa_hash_table_search(b->types, &key);
693 if (entry)
694 return ((struct spirv_type *)entry->data)->type;
695 } else {
696 b->types = _mesa_hash_table_create(NULL, non_aggregate_type_hash,
697 non_aggregate_type_equals);
698 assert(b->types);
699 }
700
701 struct spirv_type *type = CALLOC_STRUCT(spirv_type);
702 if (!type)
703 return 0;
704
705 type->op = op;
706 memcpy(&type->args, args, sizeof(uint32_t) * num_args);
707 type->num_args = num_args;
708
709 type->type = spirv_builder_new_id(b);
710 spirv_buffer_prepare(&b->types_const_defs, 2 + num_args);
711 spirv_buffer_emit_word(&b->types_const_defs, op | ((2 + num_args) << 16));
712 spirv_buffer_emit_word(&b->types_const_defs, type->type);
713 for (int i = 0; i < num_args; ++i)
714 spirv_buffer_emit_word(&b->types_const_defs, args[i]);
715
716 entry = _mesa_hash_table_insert(b->types, type, type);
717 assert(entry);
718
719 return ((struct spirv_type *)entry->data)->type;
720 }
721
722 SpvId
723 spirv_builder_type_void(struct spirv_builder *b)
724 {
725 return get_type_def(b, SpvOpTypeVoid, NULL, 0);
726 }
727
728 SpvId
729 spirv_builder_type_bool(struct spirv_builder *b)
730 {
731 return get_type_def(b, SpvOpTypeBool, NULL, 0);
732 }
733
734 SpvId
735 spirv_builder_type_int(struct spirv_builder *b, unsigned width)
736 {
737 uint32_t args[] = { width, 1 };
738 return get_type_def(b, SpvOpTypeInt, args, ARRAY_SIZE(args));
739 }
740
741 SpvId
742 spirv_builder_type_uint(struct spirv_builder *b, unsigned width)
743 {
744 uint32_t args[] = { width, 0 };
745 return get_type_def(b, SpvOpTypeInt, args, ARRAY_SIZE(args));
746 }
747
748 SpvId
749 spirv_builder_type_float(struct spirv_builder *b, unsigned width)
750 {
751 uint32_t args[] = { width };
752 return get_type_def(b, SpvOpTypeFloat, args, ARRAY_SIZE(args));
753 }
754
755 SpvId
756 spirv_builder_type_image(struct spirv_builder *b, SpvId sampled_type,
757 SpvDim dim, bool depth, bool arrayed, bool ms,
758 unsigned sampled, SpvImageFormat image_format)
759 {
760 assert(sampled < 3);
761 uint32_t args[] = {
762 sampled_type, dim, depth ? 1 : 0, arrayed ? 1 : 0, ms ? 1 : 0, sampled,
763 image_format
764 };
765 return get_type_def(b, SpvOpTypeImage, args, ARRAY_SIZE(args));
766 }
767
768 SpvId
769 spirv_builder_type_sampled_image(struct spirv_builder *b, SpvId image_type)
770 {
771 uint32_t args[] = { image_type };
772 return get_type_def(b, SpvOpTypeSampledImage, args, ARRAY_SIZE(args));
773 }
774
775 SpvId
776 spirv_builder_type_pointer(struct spirv_builder *b,
777 SpvStorageClass storage_class, SpvId type)
778 {
779 uint32_t args[] = { storage_class, type };
780 return get_type_def(b, SpvOpTypePointer, args, ARRAY_SIZE(args));
781 }
782
783 SpvId
784 spirv_builder_type_vector(struct spirv_builder *b, SpvId component_type,
785 unsigned component_count)
786 {
787 assert(component_count > 1);
788 uint32_t args[] = { component_type, component_count };
789 return get_type_def(b, SpvOpTypeVector, args, ARRAY_SIZE(args));
790 }
791
792 SpvId
793 spirv_builder_type_array(struct spirv_builder *b, SpvId component_type,
794 SpvId length)
795 {
796 SpvId type = spirv_builder_new_id(b);
797 spirv_buffer_prepare(&b->types_const_defs, 4);
798 spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeArray | (4 << 16));
799 spirv_buffer_emit_word(&b->types_const_defs, type);
800 spirv_buffer_emit_word(&b->types_const_defs, component_type);
801 spirv_buffer_emit_word(&b->types_const_defs, length);
802 return type;
803 }
804
805 SpvId
806 spirv_builder_type_struct(struct spirv_builder *b, const SpvId member_types[],
807 size_t num_member_types)
808 {
809 int words = 2 + num_member_types;
810 SpvId type = spirv_builder_new_id(b);
811 spirv_buffer_prepare(&b->types_const_defs, words);
812 spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeStruct | (words << 16));
813 spirv_buffer_emit_word(&b->types_const_defs, type);
814 for (int i = 0; i < num_member_types; ++i)
815 spirv_buffer_emit_word(&b->types_const_defs, member_types[i]);
816 return type;
817 }
818
819 SpvId
820 spirv_builder_type_function(struct spirv_builder *b, SpvId return_type,
821 const SpvId parameter_types[],
822 size_t num_parameter_types)
823 {
824 int words = 3 + num_parameter_types;
825 SpvId type = spirv_builder_new_id(b);
826 spirv_buffer_prepare(&b->types_const_defs, words);
827 spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeFunction | (words << 16));
828 spirv_buffer_emit_word(&b->types_const_defs, type);
829 spirv_buffer_emit_word(&b->types_const_defs, return_type);
830 for (int i = 0; i < num_parameter_types; ++i)
831 spirv_buffer_emit_word(&b->types_const_defs, parameter_types[i]);
832 return type;
833 }
834
835 struct spirv_const {
836 SpvOp op, type;
837 uint32_t args[8];
838 size_t num_args;
839
840 SpvId result;
841 };
842
843 static uint32_t
844 const_hash(const void *arg)
845 {
846 const struct spirv_const *key = arg;
847
848 uint32_t hash = _mesa_fnv32_1a_offset_bias;
849 hash = _mesa_fnv32_1a_accumulate(hash, key->op);
850 hash = _mesa_fnv32_1a_accumulate(hash, key->type);
851 hash = _mesa_fnv32_1a_accumulate_block(hash, key->args, sizeof(uint32_t) *
852 key->num_args);
853 return hash;
854 }
855
856 static bool
857 const_equals(const void *a, const void *b)
858 {
859 const struct spirv_const *ca = a, *cb = b;
860
861 if (ca->op != cb->op ||
862 ca->type != cb->type)
863 return false;
864
865 assert(ca->num_args == cb->num_args);
866 return memcmp(ca->args, cb->args, sizeof(uint32_t) * ca->num_args) == 0;
867 }
868
869 static SpvId
870 get_const_def(struct spirv_builder *b, SpvOp op, SpvId type,
871 const uint32_t args[], size_t num_args)
872 {
873 struct spirv_const key;
874 assert(num_args <= ARRAY_SIZE(key.args));
875 key.op = op;
876 key.type = type;
877 memcpy(&key.args, args, sizeof(uint32_t) * num_args);
878 key.num_args = num_args;
879
880 struct hash_entry *entry;
881 if (b->consts) {
882 entry = _mesa_hash_table_search(b->consts, &key);
883 if (entry)
884 return ((struct spirv_const *)entry->data)->result;
885 } else {
886 b->consts = _mesa_hash_table_create(NULL, const_hash, const_equals);
887 assert(b->consts);
888 }
889
890 struct spirv_const *cnst = CALLOC_STRUCT(spirv_const);
891 if (!cnst)
892 return 0;
893
894 cnst->op = op;
895 cnst->type = type;
896 memcpy(&cnst->args, args, sizeof(uint32_t) * num_args);
897 cnst->num_args = num_args;
898
899 cnst->result = spirv_builder_new_id(b);
900 spirv_buffer_prepare(&b->types_const_defs, 3 + num_args);
901 spirv_buffer_emit_word(&b->types_const_defs, op | ((3 + num_args) << 16));
902 spirv_buffer_emit_word(&b->types_const_defs, type);
903 spirv_buffer_emit_word(&b->types_const_defs, cnst->result);
904 for (int i = 0; i < num_args; ++i)
905 spirv_buffer_emit_word(&b->types_const_defs, args[i]);
906
907 entry = _mesa_hash_table_insert(b->consts, cnst, cnst);
908 assert(entry);
909
910 return ((struct spirv_const *)entry->data)->result;
911 }
912
913 SpvId
914 spirv_builder_const_bool(struct spirv_builder *b, bool val)
915 {
916 return get_const_def(b, val ? SpvOpConstantTrue : SpvOpConstantFalse,
917 spirv_builder_type_bool(b), NULL, 0);
918 }
919
920 SpvId
921 spirv_builder_const_int(struct spirv_builder *b, int width, int32_t val)
922 {
923 assert(width <= 32);
924 uint32_t args[] = { val };
925 return get_const_def(b, SpvOpConstant, spirv_builder_type_int(b, width),
926 args, ARRAY_SIZE(args));
927 }
928
929 SpvId
930 spirv_builder_const_uint(struct spirv_builder *b, int width, uint32_t val)
931 {
932 assert(width <= 32);
933 uint32_t args[] = { val };
934 return get_const_def(b, SpvOpConstant, spirv_builder_type_uint(b, width),
935 args, ARRAY_SIZE(args));
936 }
937
938 SpvId
939 spirv_builder_const_float(struct spirv_builder *b, int width, float val)
940 {
941 assert(width <= 32);
942 uint32_t args[] = { u_bitcast_f2u(val) };
943 return get_const_def(b, SpvOpConstant, spirv_builder_type_float(b, width),
944 args, ARRAY_SIZE(args));
945 }
946
947 SpvId
948 spirv_builder_const_composite(struct spirv_builder *b, SpvId result_type,
949 const SpvId constituents[],
950 size_t num_constituents)
951 {
952 return get_const_def(b, SpvOpConstantComposite, result_type,
953 (const uint32_t *)constituents,
954 num_constituents);
955 }
956
957 SpvId
958 spirv_builder_emit_var(struct spirv_builder *b, SpvId type,
959 SpvStorageClass storage_class)
960 {
961 assert(storage_class != SpvStorageClassGeneric);
962 struct spirv_buffer *buf = storage_class != SpvStorageClassFunction ?
963 &b->types_const_defs : &b->instructions;
964
965 SpvId ret = spirv_builder_new_id(b);
966 spirv_buffer_prepare(buf, 4);
967 spirv_buffer_emit_word(buf, SpvOpVariable | (4 << 16));
968 spirv_buffer_emit_word(buf, type);
969 spirv_buffer_emit_word(buf, ret);
970 spirv_buffer_emit_word(buf, storage_class);
971 return ret;
972 }
973
974 SpvId
975 spirv_builder_import(struct spirv_builder *b, const char *name)
976 {
977 SpvId result = spirv_builder_new_id(b);
978 size_t pos = b->imports.num_words;
979 spirv_buffer_prepare(&b->imports, 2);
980 spirv_buffer_emit_word(&b->imports, SpvOpExtInstImport);
981 spirv_buffer_emit_word(&b->imports, result);
982 int len = spirv_buffer_emit_string(&b->imports, name);
983 b->imports.words[pos] |= (2 + len) << 16;
984 return result;
985 }
986
987 size_t
988 spirv_builder_get_num_words(struct spirv_builder *b)
989 {
990 const size_t header_size = 5;
991 return header_size +
992 b->capabilities.num_words +
993 b->imports.num_words +
994 b->memory_model.num_words +
995 b->entry_points.num_words +
996 b->exec_modes.num_words +
997 b->debug_names.num_words +
998 b->decorations.num_words +
999 b->types_const_defs.num_words +
1000 b->instructions.num_words;
1001 }
1002
1003 size_t
1004 spirv_builder_get_words(struct spirv_builder *b, uint32_t *words,
1005 size_t num_words)
1006 {
1007 assert(num_words >= spirv_builder_get_num_words(b));
1008
1009 size_t written = 0;
1010 words[written++] = SpvMagicNumber;
1011 words[written++] = 0x00010000;
1012 words[written++] = 0;
1013 words[written++] = b->prev_id + 1;
1014 words[written++] = 0;
1015
1016 const struct spirv_buffer *buffers[] = {
1017 &b->capabilities,
1018 &b->imports,
1019 &b->memory_model,
1020 &b->entry_points,
1021 &b->exec_modes,
1022 &b->debug_names,
1023 &b->decorations,
1024 &b->types_const_defs,
1025 &b->instructions
1026 };
1027
1028 for (int i = 0; i < ARRAY_SIZE(buffers); ++i) {
1029 const struct spirv_buffer *buffer = buffers[i];
1030 for (int j = 0; j < buffer->num_words; ++j)
1031 words[written++] = buffer->words[j];
1032 }
1033
1034 assert(written == spirv_builder_get_num_words(b));
1035 return written;
1036 }