• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/set.h"
28 #include "util/ralloc.h"
29 #include "util/u_bitcast.h"
30 #include "util/u_memory.h"
31 #include "util/half_float.h"
32 #include "util/hash_table.h"
33 #define XXH_INLINE_ALL
34 #include "util/xxhash.h"
35 #include "vk_util.h"
36 
37 #include <stdbool.h>
38 #include <inttypes.h>
39 #include <string.h>
40 
41 static bool
spirv_buffer_grow(struct spirv_buffer * b,void * mem_ctx,size_t needed)42 spirv_buffer_grow(struct spirv_buffer *b, void *mem_ctx, size_t needed)
43 {
44    size_t new_room = MAX3(64, (b->room * 3) / 2, needed);
45 
46    uint32_t *new_words = reralloc_size(mem_ctx, b->words,
47                                        new_room * sizeof(uint32_t));
48    if (!new_words)
49       return false;
50 
51    b->words = new_words;
52    b->room = new_room;
53    return true;
54 }
55 
56 static inline bool
spirv_buffer_prepare(struct spirv_buffer * b,void * mem_ctx,size_t needed)57 spirv_buffer_prepare(struct spirv_buffer *b, void *mem_ctx, size_t needed)
58 {
59    needed += b->num_words;
60    if (b->room >= b->num_words + needed)
61       return true;
62 
63    return spirv_buffer_grow(b, mem_ctx, needed);
64 }
65 
66 static inline uint32_t
spirv_buffer_emit_word(struct spirv_buffer * b,uint32_t word)67 spirv_buffer_emit_word(struct spirv_buffer *b, uint32_t word)
68 {
69    assert(b->num_words < b->room);
70    b->words[b->num_words] = word;
71    return b->num_words++;
72 }
73 
74 static int
spirv_buffer_emit_string(struct spirv_buffer * b,void * mem_ctx,const char * str)75 spirv_buffer_emit_string(struct spirv_buffer *b, void *mem_ctx,
76                          const char *str)
77 {
78    int pos = 0;
79    uint32_t word = 0;
80    while (str[pos] != '\0') {
81       word |= str[pos] << (8 * (pos % 4));
82       if (++pos % 4 == 0) {
83          spirv_buffer_prepare(b, mem_ctx, 1);
84          spirv_buffer_emit_word(b, word);
85          word = 0;
86       }
87    }
88 
89    spirv_buffer_prepare(b, mem_ctx, 1);
90    spirv_buffer_emit_word(b, word);
91 
92    return 1 + pos / 4;
93 }
94 
95 void
spirv_builder_emit_cap(struct spirv_builder * b,SpvCapability cap)96 spirv_builder_emit_cap(struct spirv_builder *b, SpvCapability cap)
97 {
98    if (!b->caps)
99       b->caps = _mesa_set_create_u32_keys(b->mem_ctx);
100 
101    assert(b->caps);
102    _mesa_set_add(b->caps, (void*)(uintptr_t)cap);
103 }
104 
105 void
spirv_builder_emit_extension(struct spirv_builder * b,const char * name)106 spirv_builder_emit_extension(struct spirv_builder *b, const char *name)
107 {
108    size_t pos = b->extensions.num_words;
109    spirv_buffer_prepare(&b->extensions, b->mem_ctx, 1);
110    spirv_buffer_emit_word(&b->extensions, SpvOpExtension);
111    int len = spirv_buffer_emit_string(&b->extensions, b->mem_ctx, name);
112    b->extensions.words[pos] |= (1 + len) << 16;
113 }
114 
115 void
spirv_builder_emit_source(struct spirv_builder * b,SpvSourceLanguage lang,uint32_t version)116 spirv_builder_emit_source(struct spirv_builder *b, SpvSourceLanguage lang,
117                           uint32_t version)
118 {
119    spirv_buffer_prepare(&b->debug_names, b->mem_ctx, 3);
120    spirv_buffer_emit_word(&b->debug_names, SpvOpSource | (3 << 16));
121    spirv_buffer_emit_word(&b->debug_names, lang);
122    spirv_buffer_emit_word(&b->debug_names, version);
123 }
124 
125 void
spirv_builder_emit_mem_model(struct spirv_builder * b,SpvAddressingModel addr_model,SpvMemoryModel mem_model)126 spirv_builder_emit_mem_model(struct spirv_builder *b,
127                              SpvAddressingModel addr_model,
128                              SpvMemoryModel mem_model)
129 {
130    spirv_buffer_prepare(&b->memory_model, b->mem_ctx, 3);
131    spirv_buffer_emit_word(&b->memory_model, SpvOpMemoryModel | (3 << 16));
132    spirv_buffer_emit_word(&b->memory_model, addr_model);
133    spirv_buffer_emit_word(&b->memory_model, mem_model);
134 }
135 
136 void
spirv_builder_emit_entry_point(struct spirv_builder * b,SpvExecutionModel exec_model,SpvId entry_point,const char * name,const SpvId interfaces[],size_t num_interfaces)137 spirv_builder_emit_entry_point(struct spirv_builder *b,
138                                SpvExecutionModel exec_model, SpvId entry_point,
139                                const char *name, const SpvId interfaces[],
140                                size_t num_interfaces)
141 {
142    size_t pos = b->entry_points.num_words;
143    spirv_buffer_prepare(&b->entry_points, b->mem_ctx, 3);
144    spirv_buffer_emit_word(&b->entry_points, SpvOpEntryPoint);
145    spirv_buffer_emit_word(&b->entry_points, exec_model);
146    spirv_buffer_emit_word(&b->entry_points, entry_point);
147    int len = spirv_buffer_emit_string(&b->entry_points, b->mem_ctx, name);
148    b->entry_points.words[pos] |= (3 + len + num_interfaces) << 16;
149    spirv_buffer_prepare(&b->entry_points, b->mem_ctx, num_interfaces);
150    for (int i = 0; i < num_interfaces; ++i)
151       spirv_buffer_emit_word(&b->entry_points, interfaces[i]);
152 }
153 
154 uint32_t
spirv_builder_emit_exec_mode_literal(struct spirv_builder * b,SpvId entry_point,SpvExecutionMode exec_mode,uint32_t param)155 spirv_builder_emit_exec_mode_literal(struct spirv_builder *b, SpvId entry_point,
156                                      SpvExecutionMode exec_mode, uint32_t param)
157 {
158    spirv_buffer_prepare(&b->exec_modes, b->mem_ctx, 4);
159    spirv_buffer_emit_word(&b->exec_modes, SpvOpExecutionMode | (4 << 16));
160    spirv_buffer_emit_word(&b->exec_modes, entry_point);
161    spirv_buffer_emit_word(&b->exec_modes, exec_mode);
162    return spirv_buffer_emit_word(&b->exec_modes, param);
163 }
164 
165 void
spirv_builder_emit_exec_mode_literal3(struct spirv_builder * b,SpvId entry_point,SpvExecutionMode exec_mode,uint32_t param[3])166 spirv_builder_emit_exec_mode_literal3(struct spirv_builder *b, SpvId entry_point,
167                                      SpvExecutionMode exec_mode, uint32_t param[3])
168 {
169    spirv_buffer_prepare(&b->exec_modes, b->mem_ctx, 6);
170    spirv_buffer_emit_word(&b->exec_modes, SpvOpExecutionMode | (6 << 16));
171    spirv_buffer_emit_word(&b->exec_modes, entry_point);
172    spirv_buffer_emit_word(&b->exec_modes, exec_mode);
173    for (unsigned i = 0; i < 3; i++)
174       spirv_buffer_emit_word(&b->exec_modes, param[i]);
175 }
176 
177 void
spirv_builder_emit_exec_mode_id3(struct spirv_builder * b,SpvId entry_point,SpvExecutionMode exec_mode,SpvId param[3])178 spirv_builder_emit_exec_mode_id3(struct spirv_builder *b, SpvId entry_point,
179                                 SpvExecutionMode exec_mode, SpvId param[3])
180 {
181    spirv_buffer_prepare(&b->exec_modes, b->mem_ctx, 6);
182    spirv_buffer_emit_word(&b->exec_modes, SpvOpExecutionModeId | (6 << 16));
183    spirv_buffer_emit_word(&b->exec_modes, entry_point);
184    spirv_buffer_emit_word(&b->exec_modes, exec_mode);
185    for (unsigned i = 0; i < 3; i++)
186       spirv_buffer_emit_word(&b->exec_modes, param[i]);
187 }
188 
189 void
spirv_builder_emit_exec_mode(struct spirv_builder * b,SpvId entry_point,SpvExecutionMode exec_mode)190 spirv_builder_emit_exec_mode(struct spirv_builder *b, SpvId entry_point,
191                              SpvExecutionMode exec_mode)
192 {
193    spirv_buffer_prepare(&b->exec_modes, b->mem_ctx, 3);
194    spirv_buffer_emit_word(&b->exec_modes, SpvOpExecutionMode | (3 << 16));
195    spirv_buffer_emit_word(&b->exec_modes, entry_point);
196    spirv_buffer_emit_word(&b->exec_modes, exec_mode);
197 }
198 
199 void
spirv_builder_emit_name(struct spirv_builder * b,SpvId target,const char * name)200 spirv_builder_emit_name(struct spirv_builder *b, SpvId target,
201                         const char *name)
202 {
203    char *ptr = (char *)name;
204 
205    // Validate first character:
206    char c = ptr[0];
207    if (!(c == '_' || c == '$' || c == '.' ||
208       (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
209          ptr[0] = '_';
210    }
211 
212    // Validate remaining characters:
213    for (int i = 1; ptr[i] != '\0'; i++) {
214       c = ptr[i];
215       if (!(c == '_' || c == '$' || c == '.' ||
216             (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
217             (c >= '0' && c <= '9'))) {
218             ptr[i] = '_';
219       }
220    }
221    char *new_name = NULL;
222    struct set_entry *entry = _mesa_set_search(b->name_syms, ptr);
223    if (entry != NULL) {
224       /* we have a collision with another name, append an _ + a unique index */
225       asprintf(&new_name, "%s_%u", ptr, b->name_syms_index++);
226    } else {
227       /* Mark this one as seen */
228       _mesa_set_add(b->name_syms, ptr);
229    }
230 
231    size_t pos = b->debug_names.num_words;
232    spirv_buffer_prepare(&b->debug_names, b->mem_ctx, 2);
233    spirv_buffer_emit_word(&b->debug_names, SpvOpName);
234    spirv_buffer_emit_word(&b->debug_names, target);
235    int len = 0;
236    if (new_name != NULL) {
237       len = spirv_buffer_emit_string(&b->debug_names, b->mem_ctx, new_name);
238       free(new_name);
239       new_name = NULL;
240    } else {
241       len = spirv_buffer_emit_string(&b->debug_names, b->mem_ctx, name);
242    }
243    b->debug_names.words[pos] |= (2 + len) << 16;
244 }
245 
246 static void
emit_decoration(struct spirv_builder * b,SpvId target,SpvDecoration decoration,const uint32_t extra_operands[],size_t num_extra_operands)247 emit_decoration(struct spirv_builder *b, SpvId target,
248                 SpvDecoration decoration, const uint32_t extra_operands[],
249                 size_t num_extra_operands)
250 {
251    int words = 3 + num_extra_operands;
252    spirv_buffer_prepare(&b->decorations, b->mem_ctx, words);
253    spirv_buffer_emit_word(&b->decorations, SpvOpDecorate | (words << 16));
254    spirv_buffer_emit_word(&b->decorations, target);
255    spirv_buffer_emit_word(&b->decorations, decoration);
256    for (int i = 0; i < num_extra_operands; ++i)
257       spirv_buffer_emit_word(&b->decorations, extra_operands[i]);
258 }
259 
260 void
spirv_builder_emit_decoration(struct spirv_builder * b,SpvId target,SpvDecoration decoration)261 spirv_builder_emit_decoration(struct spirv_builder *b, SpvId target,
262                               SpvDecoration decoration)
263 {
264    emit_decoration(b, target, decoration, NULL, 0);
265 }
266 
267 void
spirv_builder_emit_rounding_mode(struct spirv_builder * b,SpvId target,SpvFPRoundingMode rounding)268 spirv_builder_emit_rounding_mode(struct spirv_builder *b, SpvId target,
269                                  SpvFPRoundingMode rounding)
270 {
271    uint32_t args[] = { rounding };
272    emit_decoration(b, target, SpvDecorationFPRoundingMode, args, ARRAY_SIZE(args));
273 }
274 
275 void
spirv_builder_emit_input_attachment_index(struct spirv_builder * b,SpvId target,uint32_t id)276 spirv_builder_emit_input_attachment_index(struct spirv_builder *b, SpvId target, uint32_t id)
277 {
278    uint32_t args[] = { id };
279    emit_decoration(b, target, SpvDecorationInputAttachmentIndex, args, ARRAY_SIZE(args));
280 }
281 
282 void
spirv_builder_emit_specid(struct spirv_builder * b,SpvId target,uint32_t id)283 spirv_builder_emit_specid(struct spirv_builder *b, SpvId target, uint32_t id)
284 {
285    uint32_t args[] = { id };
286    emit_decoration(b, target, SpvDecorationSpecId, args, ARRAY_SIZE(args));
287 }
288 
289 void
spirv_builder_emit_location(struct spirv_builder * b,SpvId target,uint32_t location)290 spirv_builder_emit_location(struct spirv_builder *b, SpvId target,
291                             uint32_t location)
292 {
293    uint32_t args[] = { location };
294    emit_decoration(b, target, SpvDecorationLocation, args, ARRAY_SIZE(args));
295 }
296 
297 void
spirv_builder_emit_component(struct spirv_builder * b,SpvId target,uint32_t component)298 spirv_builder_emit_component(struct spirv_builder *b, SpvId target,
299                              uint32_t component)
300 {
301    uint32_t args[] = { component };
302    emit_decoration(b, target, SpvDecorationComponent, args, ARRAY_SIZE(args));
303 }
304 
305 void
spirv_builder_emit_builtin(struct spirv_builder * b,SpvId target,SpvBuiltIn builtin)306 spirv_builder_emit_builtin(struct spirv_builder *b, SpvId target,
307                            SpvBuiltIn builtin)
308 {
309    uint32_t args[] = { builtin };
310    emit_decoration(b, target, SpvDecorationBuiltIn, args, ARRAY_SIZE(args));
311 }
312 
313 void
spirv_builder_emit_vertex(struct spirv_builder * b,uint32_t stream,bool multistream)314 spirv_builder_emit_vertex(struct spirv_builder *b, uint32_t stream, bool multistream)
315 {
316    unsigned words = 1;
317    SpvOp op = SpvOpEmitVertex;
318    if (multistream) {
319       spirv_builder_emit_cap(b, SpvCapabilityGeometryStreams);
320       op = SpvOpEmitStreamVertex;
321       words++;
322    }
323    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
324    spirv_buffer_emit_word(&b->instructions, op | (words << 16));
325    if (multistream)
326       spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, stream));
327 }
328 
329 void
spirv_builder_end_primitive(struct spirv_builder * b,uint32_t stream,bool multistream)330 spirv_builder_end_primitive(struct spirv_builder *b, uint32_t stream, bool multistream)
331 {
332    unsigned words = 1;
333    SpvOp op = SpvOpEndPrimitive;
334 
335    if (multistream)
336       spirv_builder_emit_cap(b, SpvCapabilityGeometryStreams);
337    if (multistream || stream > 0) {
338       op = SpvOpEndStreamPrimitive;
339       words++;
340    }
341    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
342    spirv_buffer_emit_word(&b->instructions, op | (words << 16));
343    if (multistream || stream > 0)
344       spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, stream));
345 }
346 
347 void
spirv_builder_emit_descriptor_set(struct spirv_builder * b,SpvId target,uint32_t descriptor_set)348 spirv_builder_emit_descriptor_set(struct spirv_builder *b, SpvId target,
349                                   uint32_t descriptor_set)
350 {
351    uint32_t args[] = { descriptor_set };
352    emit_decoration(b, target, SpvDecorationDescriptorSet, args,
353                    ARRAY_SIZE(args));
354 }
355 
356 void
spirv_builder_emit_binding(struct spirv_builder * b,SpvId target,uint32_t binding)357 spirv_builder_emit_binding(struct spirv_builder *b, SpvId target,
358                            uint32_t binding)
359 {
360    uint32_t args[] = { binding };
361    emit_decoration(b, target, SpvDecorationBinding, args, ARRAY_SIZE(args));
362 }
363 
364 void
spirv_builder_emit_array_stride(struct spirv_builder * b,SpvId target,uint32_t stride)365 spirv_builder_emit_array_stride(struct spirv_builder *b, SpvId target,
366                                 uint32_t stride)
367 {
368    uint32_t args[] = { stride };
369    emit_decoration(b, target, SpvDecorationArrayStride, args, ARRAY_SIZE(args));
370 }
371 
372 void
spirv_builder_emit_offset(struct spirv_builder * b,SpvId target,uint32_t offset)373 spirv_builder_emit_offset(struct spirv_builder *b, SpvId target,
374                           uint32_t offset)
375 {
376    uint32_t args[] = { offset };
377    emit_decoration(b, target, SpvDecorationOffset, args, ARRAY_SIZE(args));
378 }
379 
380 void
spirv_builder_emit_xfb_buffer(struct spirv_builder * b,SpvId target,uint32_t buffer)381 spirv_builder_emit_xfb_buffer(struct spirv_builder *b, SpvId target,
382                               uint32_t buffer)
383 {
384    uint32_t args[] = { buffer };
385    emit_decoration(b, target, SpvDecorationXfbBuffer, args, ARRAY_SIZE(args));
386 }
387 
388 void
spirv_builder_emit_xfb_stride(struct spirv_builder * b,SpvId target,uint32_t stride)389 spirv_builder_emit_xfb_stride(struct spirv_builder *b, SpvId target,
390                               uint32_t stride)
391 {
392    uint32_t args[] = { stride };
393    emit_decoration(b, target, SpvDecorationXfbStride, args, ARRAY_SIZE(args));
394 }
395 
396 void
spirv_builder_emit_index(struct spirv_builder * b,SpvId target,int index)397 spirv_builder_emit_index(struct spirv_builder *b, SpvId target, int index)
398 {
399    uint32_t args[] = { index };
400    emit_decoration(b, target, SpvDecorationIndex, args, ARRAY_SIZE(args));
401 }
402 
403 void
spirv_builder_emit_stream(struct spirv_builder * b,SpvId target,int stream)404 spirv_builder_emit_stream(struct spirv_builder *b, SpvId target, int stream)
405 {
406    uint32_t args[] = { stream };
407    emit_decoration(b, target, SpvDecorationStream, args, ARRAY_SIZE(args));
408 }
409 
410 static void
emit_member_decoration(struct spirv_builder * b,SpvId target,uint32_t member,SpvDecoration decoration,const uint32_t extra_operands[],size_t num_extra_operands)411 emit_member_decoration(struct spirv_builder *b, SpvId target, uint32_t member,
412                        SpvDecoration decoration, const uint32_t extra_operands[],
413                        size_t num_extra_operands)
414 {
415    int words = 4 + num_extra_operands;
416    spirv_buffer_prepare(&b->decorations, b->mem_ctx, words);
417    spirv_buffer_emit_word(&b->decorations,
418                           SpvOpMemberDecorate | (words << 16));
419    spirv_buffer_emit_word(&b->decorations, target);
420    spirv_buffer_emit_word(&b->decorations, member);
421    spirv_buffer_emit_word(&b->decorations, decoration);
422    for (int i = 0; i < num_extra_operands; ++i)
423       spirv_buffer_emit_word(&b->decorations, extra_operands[i]);
424 }
425 
426 void
spirv_builder_emit_member_offset(struct spirv_builder * b,SpvId target,uint32_t member,uint32_t offset)427 spirv_builder_emit_member_offset(struct spirv_builder *b, SpvId target,
428                           uint32_t member, uint32_t offset)
429 {
430    uint32_t args[] = { offset };
431    emit_member_decoration(b, target, member, SpvDecorationOffset,
432                           args, ARRAY_SIZE(args));
433 }
434 
435 void
spirv_builder_emit_member_builtin(struct spirv_builder * b,SpvId target,uint32_t member,SpvBuiltIn builtin)436 spirv_builder_emit_member_builtin(struct spirv_builder *b, SpvId target,
437                                   uint32_t member, SpvBuiltIn builtin)
438 {
439     uint32_t args[] = { builtin };
440     emit_member_decoration(b, target, member, SpvDecorationBuiltIn,
441                            args, ARRAY_SIZE(args));
442 }
443 
444 void
spirv_builder_emit_member_name(struct spirv_builder * b,SpvId struct_name,unsigned member,const char * name)445 spirv_builder_emit_member_name(struct spirv_builder *b, SpvId struct_name,
446                                unsigned member, const char *name)
447 {
448     size_t pos = b->debug_names.num_words;
449     spirv_buffer_prepare(&b->debug_names, b->mem_ctx, 3);
450     spirv_buffer_emit_word(&b->debug_names, SpvOpMemberName);
451     spirv_buffer_emit_word(&b->debug_names, struct_name);
452     spirv_buffer_emit_word(&b->debug_names, member);
453     int len = spirv_buffer_emit_string(&b->debug_names, b->mem_ctx, name);
454     b->debug_names.words[pos] |= (3 + len) << 16;
455 }
456 
457 SpvId
spirv_builder_emit_undef(struct spirv_builder * b,SpvId result_type)458 spirv_builder_emit_undef(struct spirv_builder *b, SpvId result_type)
459 {
460    SpvId result = spirv_builder_new_id(b);
461    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 3);
462    spirv_buffer_emit_word(&b->instructions, SpvOpUndef | (3 << 16));
463    spirv_buffer_emit_word(&b->instructions, result_type);
464    spirv_buffer_emit_word(&b->instructions, result);
465    return result;
466 }
467 
468 void
spirv_builder_function(struct spirv_builder * b,SpvId result,SpvId return_type,SpvFunctionControlMask function_control,SpvId function_type)469 spirv_builder_function(struct spirv_builder *b, SpvId result,
470                        SpvId return_type,
471                        SpvFunctionControlMask function_control,
472                        SpvId function_type)
473 {
474    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 5);
475    spirv_buffer_emit_word(&b->instructions, SpvOpFunction | (5 << 16));
476    spirv_buffer_emit_word(&b->instructions, return_type);
477    spirv_buffer_emit_word(&b->instructions, result);
478    spirv_buffer_emit_word(&b->instructions, function_control);
479    spirv_buffer_emit_word(&b->instructions, function_type);
480 }
481 
482 void
spirv_builder_function_end(struct spirv_builder * b)483 spirv_builder_function_end(struct spirv_builder *b)
484 {
485    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
486    spirv_buffer_emit_word(&b->instructions, SpvOpFunctionEnd | (1 << 16));
487 }
488 
489 SpvId
spirv_builder_function_call(struct spirv_builder * b,SpvId result_type,SpvId function,const SpvId arguments[],size_t num_arguments)490 spirv_builder_function_call(struct spirv_builder *b, SpvId result_type,
491                             SpvId function, const SpvId arguments[],
492                             size_t num_arguments)
493 {
494    SpvId result = spirv_builder_new_id(b);
495 
496    int words = 4 + num_arguments;
497    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
498    spirv_buffer_emit_word(&b->instructions,
499                           SpvOpFunctionCall | (words << 16));
500    spirv_buffer_emit_word(&b->instructions, result_type);
501    spirv_buffer_emit_word(&b->instructions, result);
502    spirv_buffer_emit_word(&b->instructions, function);
503 
504    for (int i = 0; i < num_arguments; ++i)
505       spirv_buffer_emit_word(&b->instructions, arguments[i]);
506 
507    return result;
508 }
509 
510 
511 void
spirv_builder_label(struct spirv_builder * b,SpvId label)512 spirv_builder_label(struct spirv_builder *b, SpvId label)
513 {
514    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 2);
515    spirv_buffer_emit_word(&b->instructions, SpvOpLabel | (2 << 16));
516    spirv_buffer_emit_word(&b->instructions, label);
517 }
518 
519 void
spirv_builder_return(struct spirv_builder * b)520 spirv_builder_return(struct spirv_builder *b)
521 {
522    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
523    spirv_buffer_emit_word(&b->instructions, SpvOpReturn | (1 << 16));
524 }
525 
526 SpvId
spirv_builder_emit_load(struct spirv_builder * b,SpvId result_type,SpvId pointer)527 spirv_builder_emit_load(struct spirv_builder *b, SpvId result_type,
528                         SpvId pointer)
529 {
530    return spirv_builder_emit_unop(b, SpvOpLoad, result_type, pointer);
531 }
532 
533 SpvId
spirv_builder_emit_load_aligned(struct spirv_builder * b,SpvId result_type,SpvId pointer,unsigned alignment,bool coherent)534 spirv_builder_emit_load_aligned(struct spirv_builder *b, SpvId result_type, SpvId pointer, unsigned alignment, bool coherent)
535 {
536    if (coherent) {
537       SpvId scope = spirv_builder_const_int(b, 32, SpvScopeDevice);
538       return spirv_builder_emit_quadop(b, SpvOpLoad, result_type, pointer, SpvMemoryAccessAlignedMask | SpvMemoryAccessNonPrivatePointerMask | SpvMemoryAccessMakePointerVisibleMask, alignment, scope);
539    } else {
540       return spirv_builder_emit_triop(b, SpvOpLoad, result_type, pointer, SpvMemoryAccessAlignedMask, alignment);
541    }
542 }
543 
544 void
spirv_builder_emit_store(struct spirv_builder * b,SpvId pointer,SpvId object)545 spirv_builder_emit_store(struct spirv_builder *b, SpvId pointer, SpvId object)
546 {
547    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 3);
548    spirv_buffer_emit_word(&b->instructions, SpvOpStore | (3 << 16));
549    spirv_buffer_emit_word(&b->instructions, pointer);
550    spirv_buffer_emit_word(&b->instructions, object);
551 }
552 
553 void
spirv_builder_emit_store_aligned(struct spirv_builder * b,SpvId pointer,SpvId object,unsigned alignment,bool coherent)554 spirv_builder_emit_store_aligned(struct spirv_builder *b, SpvId pointer, SpvId object, unsigned alignment, bool coherent)
555 {
556    unsigned size = 5;
557    SpvMemoryAccessMask mask = SpvMemoryAccessAlignedMask;
558 
559    if (coherent) {
560       mask |= SpvMemoryAccessNonPrivatePointerMask | SpvMemoryAccessMakePointerAvailableMask;
561       size++;
562    }
563 
564    spirv_buffer_prepare(&b->instructions, b->mem_ctx, size);
565    spirv_buffer_emit_word(&b->instructions, SpvOpStore | (size << 16));
566    spirv_buffer_emit_word(&b->instructions, pointer);
567    spirv_buffer_emit_word(&b->instructions, object);
568    spirv_buffer_emit_word(&b->instructions, mask);
569    spirv_buffer_emit_word(&b->instructions, alignment);
570 
571    if (coherent) {
572       SpvId scope = spirv_builder_const_int(b, 32, SpvScopeDevice);
573       spirv_buffer_emit_word(&b->instructions, scope);
574    }
575 }
576 
577 void
spirv_builder_emit_atomic_store(struct spirv_builder * b,SpvId pointer,SpvScope scope,SpvMemorySemanticsMask semantics,SpvId object)578 spirv_builder_emit_atomic_store(struct spirv_builder *b, SpvId pointer, SpvScope scope,
579                                 SpvMemorySemanticsMask semantics, SpvId object)
580 {
581    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 5);
582    spirv_buffer_emit_word(&b->instructions, SpvOpAtomicStore | (5 << 16));
583    spirv_buffer_emit_word(&b->instructions, pointer);
584    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, scope));
585    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, semantics));
586    spirv_buffer_emit_word(&b->instructions, object);
587 }
588 
589 SpvId
spirv_builder_emit_access_chain(struct spirv_builder * b,SpvId result_type,SpvId base,const SpvId indexes[],size_t num_indexes)590 spirv_builder_emit_access_chain(struct spirv_builder *b, SpvId result_type,
591                                 SpvId base, const SpvId indexes[],
592                                 size_t num_indexes)
593 {
594    assert(base);
595    assert(result_type);
596    SpvId result = spirv_builder_new_id(b);
597 
598    int words = 4 + num_indexes;
599    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
600    spirv_buffer_emit_word(&b->instructions, SpvOpAccessChain | (words << 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, base);
604    for (int i = 0; i < num_indexes; ++i) {
605       assert(indexes[i]);
606       spirv_buffer_emit_word(&b->instructions, indexes[i]);
607    }
608    return result;
609 }
610 
611 void
spirv_builder_emit_interlock(struct spirv_builder * b,bool end)612 spirv_builder_emit_interlock(struct spirv_builder *b, bool end)
613 {
614    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
615    spirv_buffer_emit_word(&b->instructions, (end ? SpvOpEndInvocationInterlockEXT : SpvOpBeginInvocationInterlockEXT) | (1 << 16));
616 }
617 
618 
619 SpvId
spirv_builder_emit_unop_const(struct spirv_builder * b,SpvOp op,SpvId result_type,uint64_t operand)620 spirv_builder_emit_unop_const(struct spirv_builder *b, SpvOp op, SpvId result_type, uint64_t operand)
621 {
622    SpvId result = spirv_builder_new_id(b);
623    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
624    spirv_buffer_emit_word(&b->instructions, op | (4 << 16));
625    spirv_buffer_emit_word(&b->instructions, result_type);
626    spirv_buffer_emit_word(&b->instructions, result);
627    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, operand));
628    return result;
629 }
630 
631 SpvId
spirv_builder_emit_unop(struct spirv_builder * b,SpvOp op,SpvId result_type,SpvId operand)632 spirv_builder_emit_unop(struct spirv_builder *b, SpvOp op, SpvId result_type,
633                         SpvId operand)
634 {
635    struct spirv_buffer *buf = op == SpvOpSpecConstant ? &b->types_const_defs : &b->instructions;
636    SpvId result = spirv_builder_new_id(b);
637    spirv_buffer_prepare(buf, b->mem_ctx, 4);
638    spirv_buffer_emit_word(buf, op | (4 << 16));
639    spirv_buffer_emit_word(buf, result_type);
640    spirv_buffer_emit_word(buf, result);
641    spirv_buffer_emit_word(buf, operand);
642    return result;
643 }
644 
645 SpvId
spirv_builder_emit_binop(struct spirv_builder * b,SpvOp op,SpvId result_type,SpvId operand0,SpvId operand1)646 spirv_builder_emit_binop(struct spirv_builder *b, SpvOp op, SpvId result_type,
647                          SpvId operand0, SpvId operand1)
648 {
649    SpvId result = spirv_builder_new_id(b);
650    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 5);
651    spirv_buffer_emit_word(&b->instructions, op | (5 << 16));
652    spirv_buffer_emit_word(&b->instructions, result_type);
653    spirv_buffer_emit_word(&b->instructions, result);
654    spirv_buffer_emit_word(&b->instructions, operand0);
655    spirv_buffer_emit_word(&b->instructions, operand1);
656    return result;
657 }
658 
659 SpvId
spirv_builder_emit_triop(struct spirv_builder * b,SpvOp op,SpvId result_type,SpvId operand0,SpvId operand1,SpvId operand2)660 spirv_builder_emit_triop(struct spirv_builder *b, SpvOp op, SpvId result_type,
661                          SpvId operand0, SpvId operand1, SpvId operand2)
662 {
663    struct spirv_buffer *buf = op == SpvOpSpecConstantOp ? &b->types_const_defs : &b->instructions;
664 
665    SpvId result = spirv_builder_new_id(b);
666    spirv_buffer_prepare(buf, b->mem_ctx, 6);
667    spirv_buffer_emit_word(buf, op | (6 << 16));
668    spirv_buffer_emit_word(buf, result_type);
669    spirv_buffer_emit_word(buf, result);
670    spirv_buffer_emit_word(buf, operand0);
671    spirv_buffer_emit_word(buf, operand1);
672    spirv_buffer_emit_word(buf, operand2);
673    return result;
674 }
675 
676 SpvId
spirv_builder_emit_quadop(struct spirv_builder * b,SpvOp op,SpvId result_type,SpvId operand0,SpvId operand1,SpvId operand2,SpvId operand3)677 spirv_builder_emit_quadop(struct spirv_builder *b, SpvOp op, SpvId result_type,
678                          SpvId operand0, SpvId operand1, SpvId operand2, SpvId operand3)
679 {
680    struct spirv_buffer *buf = op == SpvOpSpecConstantOp ? &b->types_const_defs : &b->instructions;
681 
682    SpvId result = spirv_builder_new_id(b);
683    spirv_buffer_prepare(buf, b->mem_ctx, 7);
684    spirv_buffer_emit_word(buf, op | (7 << 16));
685    spirv_buffer_emit_word(buf, result_type);
686    spirv_buffer_emit_word(buf, result);
687    spirv_buffer_emit_word(buf, operand0);
688    spirv_buffer_emit_word(buf, operand1);
689    spirv_buffer_emit_word(buf, operand2);
690    spirv_buffer_emit_word(buf, operand3);
691    return result;
692 }
693 
694 SpvId
spirv_builder_emit_hexop(struct spirv_builder * b,SpvOp op,SpvId result_type,SpvId operand0,SpvId operand1,SpvId operand2,SpvId operand3,SpvId operand4,SpvId operand5)695 spirv_builder_emit_hexop(struct spirv_builder *b, SpvOp op, SpvId result_type,
696                          SpvId operand0, SpvId operand1, SpvId operand2, SpvId operand3,
697                          SpvId operand4, SpvId operand5)
698 {
699    struct spirv_buffer *buf = op == SpvOpSpecConstantOp ? &b->types_const_defs : &b->instructions;
700 
701    SpvId result = spirv_builder_new_id(b);
702    spirv_buffer_prepare(buf, b->mem_ctx, 9);
703    spirv_buffer_emit_word(buf, op | (9 << 16));
704    spirv_buffer_emit_word(buf, result_type);
705    spirv_buffer_emit_word(buf, result);
706    spirv_buffer_emit_word(buf, operand0);
707    spirv_buffer_emit_word(buf, operand1);
708    spirv_buffer_emit_word(buf, operand2);
709    spirv_buffer_emit_word(buf, operand3);
710    spirv_buffer_emit_word(buf, operand4);
711    spirv_buffer_emit_word(buf, operand5);
712    return result;
713 }
714 
715 SpvId
spirv_builder_emit_composite_extract(struct spirv_builder * b,SpvId result_type,SpvId composite,const uint32_t indexes[],size_t num_indexes)716 spirv_builder_emit_composite_extract(struct spirv_builder *b, SpvId result_type,
717                                      SpvId composite, const uint32_t indexes[],
718                                      size_t num_indexes)
719 {
720    SpvId result = spirv_builder_new_id(b);
721 
722    assert(num_indexes > 0);
723    int words = 4 + num_indexes;
724    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
725    spirv_buffer_emit_word(&b->instructions,
726                           SpvOpCompositeExtract | (words << 16));
727    spirv_buffer_emit_word(&b->instructions, result_type);
728    spirv_buffer_emit_word(&b->instructions, result);
729    spirv_buffer_emit_word(&b->instructions, composite);
730    for (int i = 0; i < num_indexes; ++i)
731       spirv_buffer_emit_word(&b->instructions, indexes[i]);
732    return result;
733 }
734 
735 SpvId
spirv_builder_emit_composite_construct(struct spirv_builder * b,SpvId result_type,const SpvId constituents[],size_t num_constituents)736 spirv_builder_emit_composite_construct(struct spirv_builder *b,
737                                        SpvId result_type,
738                                        const SpvId constituents[],
739                                        size_t num_constituents)
740 {
741    SpvId result = spirv_builder_new_id(b);
742 
743    assert(num_constituents > 0);
744    int words = 3 + num_constituents;
745    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
746    spirv_buffer_emit_word(&b->instructions,
747                           SpvOpCompositeConstruct | (words << 16));
748    spirv_buffer_emit_word(&b->instructions, result_type);
749    spirv_buffer_emit_word(&b->instructions, result);
750    for (int i = 0; i < num_constituents; ++i)
751       spirv_buffer_emit_word(&b->instructions, constituents[i]);
752    return result;
753 }
754 
755 SpvId
spirv_builder_emit_vector_shuffle(struct spirv_builder * b,SpvId result_type,SpvId vector_1,SpvId vector_2,const uint32_t components[],size_t num_components)756 spirv_builder_emit_vector_shuffle(struct spirv_builder *b, SpvId result_type,
757                                   SpvId vector_1, SpvId vector_2,
758                                   const uint32_t components[],
759                                   size_t num_components)
760 {
761    SpvId result = spirv_builder_new_id(b);
762 
763    assert(num_components > 0);
764    int words = 5 + num_components;
765    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
766    spirv_buffer_emit_word(&b->instructions, SpvOpVectorShuffle | (words << 16));
767    spirv_buffer_emit_word(&b->instructions, result_type);
768    spirv_buffer_emit_word(&b->instructions, result);
769    spirv_buffer_emit_word(&b->instructions, vector_1);
770    spirv_buffer_emit_word(&b->instructions, vector_2);
771    for (int i = 0; i < num_components; ++i)
772       spirv_buffer_emit_word(&b->instructions, components[i]);
773    return result;
774 }
775 
776 SpvId
spirv_builder_emit_vector_extract(struct spirv_builder * b,SpvId result_type,SpvId vector_1,uint32_t component)777 spirv_builder_emit_vector_extract(struct spirv_builder *b, SpvId result_type,
778                                   SpvId vector_1,
779                                   uint32_t component)
780 {
781    SpvId result = spirv_builder_new_id(b);
782 
783    int words = 5;
784    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
785    spirv_buffer_emit_word(&b->instructions, SpvOpVectorExtractDynamic | (words << 16));
786    spirv_buffer_emit_word(&b->instructions, result_type);
787    spirv_buffer_emit_word(&b->instructions, result);
788    spirv_buffer_emit_word(&b->instructions, vector_1);
789    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, component));
790    return result;
791 }
792 
793 SpvId
spirv_builder_emit_vector_insert(struct spirv_builder * b,SpvId result_type,SpvId vector_1,SpvId component,uint32_t index)794 spirv_builder_emit_vector_insert(struct spirv_builder *b, SpvId result_type,
795                                   SpvId vector_1,
796                                   SpvId component,
797                                   uint32_t index)
798 {
799    SpvId result = spirv_builder_new_id(b);
800 
801    int words = 6;
802    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
803    spirv_buffer_emit_word(&b->instructions, SpvOpVectorInsertDynamic | (words << 16));
804    spirv_buffer_emit_word(&b->instructions, result_type);
805    spirv_buffer_emit_word(&b->instructions, result);
806    spirv_buffer_emit_word(&b->instructions, vector_1);
807    spirv_buffer_emit_word(&b->instructions, component);
808    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, index));
809    return result;
810 }
811 
812 void
spirv_builder_emit_branch(struct spirv_builder * b,SpvId label)813 spirv_builder_emit_branch(struct spirv_builder *b, SpvId label)
814 {
815    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 2);
816    spirv_buffer_emit_word(&b->instructions, SpvOpBranch | (2 << 16));
817    spirv_buffer_emit_word(&b->instructions, label);
818 }
819 
820 void
spirv_builder_emit_selection_merge(struct spirv_builder * b,SpvId merge_block,SpvSelectionControlMask selection_control)821 spirv_builder_emit_selection_merge(struct spirv_builder *b, SpvId merge_block,
822                                    SpvSelectionControlMask selection_control)
823 {
824    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 3);
825    spirv_buffer_emit_word(&b->instructions, SpvOpSelectionMerge | (3 << 16));
826    spirv_buffer_emit_word(&b->instructions, merge_block);
827    spirv_buffer_emit_word(&b->instructions, selection_control);
828 }
829 
830 void
spirv_builder_loop_merge(struct spirv_builder * b,SpvId merge_block,SpvId cont_target,SpvLoopControlMask loop_control)831 spirv_builder_loop_merge(struct spirv_builder *b, SpvId merge_block,
832                          SpvId cont_target, SpvLoopControlMask loop_control)
833 {
834    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
835    spirv_buffer_emit_word(&b->instructions, SpvOpLoopMerge | (4 << 16));
836    spirv_buffer_emit_word(&b->instructions, merge_block);
837    spirv_buffer_emit_word(&b->instructions, cont_target);
838    spirv_buffer_emit_word(&b->instructions, loop_control);
839 }
840 
841 void
spirv_builder_emit_branch_conditional(struct spirv_builder * b,SpvId condition,SpvId true_label,SpvId false_label)842 spirv_builder_emit_branch_conditional(struct spirv_builder *b, SpvId condition,
843                                       SpvId true_label, SpvId false_label)
844 {
845    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
846    spirv_buffer_emit_word(&b->instructions, SpvOpBranchConditional | (4 << 16));
847    spirv_buffer_emit_word(&b->instructions, condition);
848    spirv_buffer_emit_word(&b->instructions, true_label);
849    spirv_buffer_emit_word(&b->instructions, false_label);
850 }
851 
852 SpvId
spirv_builder_emit_phi(struct spirv_builder * b,SpvId result_type,size_t num_vars,size_t * position)853 spirv_builder_emit_phi(struct spirv_builder *b, SpvId result_type,
854                        size_t num_vars, size_t *position)
855 {
856    SpvId result = spirv_builder_new_id(b);
857 
858    assert(num_vars > 0);
859    int words = 3 + 2 * num_vars;
860    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
861    spirv_buffer_emit_word(&b->instructions, SpvOpPhi | (words << 16));
862    spirv_buffer_emit_word(&b->instructions, result_type);
863    spirv_buffer_emit_word(&b->instructions, result);
864    *position = b->instructions.num_words;
865    for (int i = 0; i < 2 * num_vars; ++i)
866       spirv_buffer_emit_word(&b->instructions, 0);
867    return result;
868 }
869 
870 void
spirv_builder_set_phi_operand(struct spirv_builder * b,size_t position,size_t index,SpvId variable,SpvId parent)871 spirv_builder_set_phi_operand(struct spirv_builder *b, size_t position,
872                               size_t index, SpvId variable, SpvId parent)
873 {
874    b->instructions.words[position + index * 2 + 0] = variable;
875    b->instructions.words[position + index * 2 + 1] = parent;
876 }
877 
878 void
spirv_builder_emit_kill(struct spirv_builder * b)879 spirv_builder_emit_kill(struct spirv_builder *b)
880 {
881    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
882    spirv_buffer_emit_word(&b->instructions, SpvOpKill | (1 << 16));
883 }
884 
885 void
spirv_builder_emit_terminate(struct spirv_builder * b)886 spirv_builder_emit_terminate(struct spirv_builder *b)
887 {
888    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
889    spirv_buffer_emit_word(&b->instructions, SpvOpTerminateInvocation | (1 << 16));
890 }
891 
892 void
spirv_builder_emit_demote(struct spirv_builder * b)893 spirv_builder_emit_demote(struct spirv_builder *b)
894 {
895    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 1);
896    spirv_buffer_emit_word(&b->instructions, SpvOpDemoteToHelperInvocation | (1 << 16));
897 }
898 
899 SpvId
spirv_is_helper_invocation(struct spirv_builder * b)900 spirv_is_helper_invocation(struct spirv_builder *b)
901 {
902    SpvId result = spirv_builder_new_id(b);
903    SpvId result_type = spirv_builder_type_bool(b);
904 
905    int words = 3;
906    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
907    spirv_buffer_emit_word(&b->instructions, SpvOpIsHelperInvocationEXT | (words << 16));
908    spirv_buffer_emit_word(&b->instructions, result_type);
909    spirv_buffer_emit_word(&b->instructions, result);
910    return result;
911 }
912 
913 SpvId
spirv_builder_emit_vote(struct spirv_builder * b,SpvOp op,SpvId src)914 spirv_builder_emit_vote(struct spirv_builder *b, SpvOp op, SpvId src)
915 {
916    return spirv_builder_emit_binop(b, op, spirv_builder_type_bool(b),
917                                    spirv_builder_const_uint(b, 32, SpvScopeSubgroup), src);
918 }
919 
920 static SpvId
sparse_wrap_result_type(struct spirv_builder * b,SpvId result_type)921 sparse_wrap_result_type(struct spirv_builder *b, SpvId result_type)
922 {
923    SpvId types[2];
924    types[0] = spirv_builder_type_uint(b, 32);
925    types[1] = result_type;
926    return spirv_builder_type_struct(b, types, 2);
927 }
928 
929 SpvId
spirv_builder_emit_image_sample(struct spirv_builder * b,SpvId result_type,SpvId sampled_image,const struct spriv_tex_src * src)930 spirv_builder_emit_image_sample(struct spirv_builder *b,
931                                 SpvId result_type,
932                                 SpvId sampled_image,
933                                 const struct spriv_tex_src *src)
934 {
935    SpvId result = spirv_builder_new_id(b);
936 
937    bool proj = src->proj != 0;
938 
939    int operands = 5;
940    int opcode;
941    if (src->sparse) {
942       opcode = SpvOpImageSparseSampleImplicitLod;
943       if (proj)
944          opcode += SpvOpImageSparseSampleProjImplicitLod - SpvOpImageSparseSampleImplicitLod;
945       if (src->lod || (src->dx && src->dy))
946          opcode += SpvOpImageSparseSampleExplicitLod - SpvOpImageSparseSampleImplicitLod;
947       if (src->dref) {
948          opcode += SpvOpImageSparseSampleDrefImplicitLod - SpvOpImageSparseSampleImplicitLod;
949          operands++;
950       }
951       result_type = sparse_wrap_result_type(b, result_type);
952    } else {
953       opcode = SpvOpImageSampleImplicitLod;
954       if (proj)
955          opcode += SpvOpImageSampleProjImplicitLod - SpvOpImageSampleImplicitLod;
956       if (src->lod || (src->dx && src->dy))
957          opcode += SpvOpImageSampleExplicitLod - SpvOpImageSampleImplicitLod;
958       if (src->dref) {
959          opcode += SpvOpImageSampleDrefImplicitLod - SpvOpImageSampleImplicitLod;
960          operands++;
961       }
962    }
963 
964    SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
965    SpvId extra_operands[6];
966    int num_extra_operands = 1;
967    if (src->bias) {
968       extra_operands[num_extra_operands++] = src->bias;
969       operand_mask |= SpvImageOperandsBiasMask;
970    }
971    if (src->lod) {
972       extra_operands[num_extra_operands++] = src->lod;
973       operand_mask |= SpvImageOperandsLodMask;
974    } else if (src->dx && src->dy) {
975       extra_operands[num_extra_operands++] = src->dx;
976       extra_operands[num_extra_operands++] = src->dy;
977       operand_mask |= SpvImageOperandsGradMask;
978    }
979    assert(!(src->const_offset && src->offset));
980    if (src->const_offset) {
981       extra_operands[num_extra_operands++] = src->const_offset;
982       operand_mask |= SpvImageOperandsConstOffsetMask;
983    } else if (src->offset) {
984       extra_operands[num_extra_operands++] = src->offset;
985       operand_mask |= SpvImageOperandsOffsetMask;
986    }
987    if (src->min_lod) {
988       extra_operands[num_extra_operands++] = src->min_lod;
989       operand_mask |= SpvImageOperandsMinLodMask;
990    }
991 
992    /* finalize num_extra_operands / extra_operands */
993    extra_operands[0] = operand_mask;
994 
995    spirv_buffer_prepare(&b->instructions, b->mem_ctx, operands + num_extra_operands);
996    spirv_buffer_emit_word(&b->instructions, opcode | ((operands + num_extra_operands) << 16));
997    spirv_buffer_emit_word(&b->instructions, result_type);
998    spirv_buffer_emit_word(&b->instructions, result);
999    spirv_buffer_emit_word(&b->instructions, sampled_image);
1000    spirv_buffer_emit_word(&b->instructions, src->coord);
1001    if (src->dref)
1002       spirv_buffer_emit_word(&b->instructions, src->dref);
1003    for (int i = 0; i < num_extra_operands; ++i)
1004       spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
1005    return result;
1006 }
1007 
1008 SpvId
spirv_builder_emit_image(struct spirv_builder * b,SpvId result_type,SpvId sampled_image)1009 spirv_builder_emit_image(struct spirv_builder *b, SpvId result_type,
1010                          SpvId sampled_image)
1011 {
1012    SpvId result = spirv_builder_new_id(b);
1013    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
1014    spirv_buffer_emit_word(&b->instructions, SpvOpImage | (4 << 16));
1015    spirv_buffer_emit_word(&b->instructions, result_type);
1016    spirv_buffer_emit_word(&b->instructions, result);
1017    spirv_buffer_emit_word(&b->instructions, sampled_image);
1018    return result;
1019 }
1020 
1021 SpvId
spirv_builder_emit_image_texel_pointer(struct spirv_builder * b,SpvId result_type,SpvId image,SpvId coordinate,SpvId sample)1022 spirv_builder_emit_image_texel_pointer(struct spirv_builder *b,
1023                                        SpvId result_type,
1024                                        SpvId image,
1025                                        SpvId coordinate,
1026                                        SpvId sample)
1027 {
1028    SpvId pointer_type = spirv_builder_type_pointer(b,
1029                                                    SpvStorageClassImage,
1030                                                    result_type);
1031    return spirv_builder_emit_triop(b, SpvOpImageTexelPointer, pointer_type, image, coordinate, sample);
1032 }
1033 
1034 SpvId
spirv_builder_emit_image_read(struct spirv_builder * b,SpvId result_type,SpvId image,SpvId coordinate,SpvId lod,SpvId sample,SpvId offset,bool sparse)1035 spirv_builder_emit_image_read(struct spirv_builder *b,
1036                               SpvId result_type,
1037                               SpvId image,
1038                               SpvId coordinate,
1039                               SpvId lod,
1040                               SpvId sample,
1041                               SpvId offset,
1042                               bool sparse)
1043 {
1044    SpvId result = spirv_builder_new_id(b);
1045 
1046    SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
1047    SpvId extra_operands[5];
1048    int num_extra_operands = 1;
1049    if (sparse)
1050       result_type = sparse_wrap_result_type(b, result_type);
1051    if (lod) {
1052       extra_operands[num_extra_operands++] = lod;
1053       operand_mask |= SpvImageOperandsLodMask;
1054    }
1055    if (sample) {
1056       extra_operands[num_extra_operands++] = sample;
1057       operand_mask |= SpvImageOperandsSampleMask;
1058    }
1059    if (offset) {
1060       extra_operands[num_extra_operands++] = offset;
1061       operand_mask |= SpvImageOperandsOffsetMask;
1062    }
1063    /* finalize num_extra_operands / extra_operands */
1064    extra_operands[0] = operand_mask;
1065 
1066    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 5 + num_extra_operands);
1067    spirv_buffer_emit_word(&b->instructions, (sparse ? SpvOpImageSparseRead : SpvOpImageRead) |
1068                           ((5 + num_extra_operands) << 16));
1069    spirv_buffer_emit_word(&b->instructions, result_type);
1070    spirv_buffer_emit_word(&b->instructions, result);
1071    spirv_buffer_emit_word(&b->instructions, image);
1072    spirv_buffer_emit_word(&b->instructions, coordinate);
1073    for (int i = 0; i < num_extra_operands; ++i)
1074       spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
1075    return result;
1076 }
1077 
1078 void
spirv_builder_emit_image_write(struct spirv_builder * b,SpvId image,SpvId coordinate,SpvId texel,SpvId lod,SpvId sample,SpvId offset)1079 spirv_builder_emit_image_write(struct spirv_builder *b,
1080                                SpvId image,
1081                                SpvId coordinate,
1082                                SpvId texel,
1083                                SpvId lod,
1084                                SpvId sample,
1085                                SpvId offset)
1086 {
1087    SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
1088    SpvId extra_operands[5];
1089    int num_extra_operands = 1;
1090    if (lod) {
1091       extra_operands[num_extra_operands++] = lod;
1092       operand_mask |= SpvImageOperandsLodMask;
1093    }
1094    if (sample) {
1095       extra_operands[num_extra_operands++] = sample;
1096       operand_mask |= SpvImageOperandsSampleMask;
1097    }
1098    if (offset) {
1099       extra_operands[num_extra_operands++] = offset;
1100       operand_mask |= SpvImageOperandsOffsetMask;
1101    }
1102    /* finalize num_extra_operands / extra_operands */
1103    extra_operands[0] = operand_mask;
1104 
1105    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4 + num_extra_operands);
1106    spirv_buffer_emit_word(&b->instructions, SpvOpImageWrite |
1107                           ((4 + num_extra_operands) << 16));
1108    spirv_buffer_emit_word(&b->instructions, image);
1109    spirv_buffer_emit_word(&b->instructions, coordinate);
1110    spirv_buffer_emit_word(&b->instructions, texel);
1111    for (int i = 0; i < num_extra_operands; ++i)
1112       spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
1113 }
1114 
1115 SpvId
spirv_builder_emit_image_gather(struct spirv_builder * b,SpvId result_type,SpvId image,const struct spriv_tex_src * src,SpvId component)1116 spirv_builder_emit_image_gather(struct spirv_builder *b,
1117                                 SpvId result_type,
1118                                 SpvId image,
1119                                 const struct spriv_tex_src *src,
1120                                 SpvId component)
1121 {
1122    SpvId result = spirv_builder_new_id(b);
1123    SpvId op = src->sparse ? SpvOpImageSparseGather : SpvOpImageGather;
1124 
1125    SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
1126    SpvId extra_operands[4];
1127    int num_extra_operands = 1;
1128    if (src->lod) {
1129       extra_operands[num_extra_operands++] = src->lod;
1130       operand_mask |= SpvImageOperandsLodMask;
1131    }
1132    if (src->sample) {
1133       extra_operands[num_extra_operands++] = src->sample;
1134       operand_mask |= SpvImageOperandsSampleMask;
1135    }
1136    assert(!(src->const_offset && src->offset));
1137    if (src->const_offset) {
1138       extra_operands[num_extra_operands++] = src->const_offset;
1139       operand_mask |= SpvImageOperandsConstOffsetMask;
1140    } else if (src->offset) {
1141       extra_operands[num_extra_operands++] = src->offset;
1142       operand_mask |= SpvImageOperandsOffsetMask;
1143    }
1144    if (src->dref)
1145       op = src->sparse ? SpvOpImageSparseDrefGather : SpvOpImageDrefGather;
1146    if (src->sparse)
1147       result_type = sparse_wrap_result_type(b, result_type);
1148    /* finalize num_extra_operands / extra_operands */
1149    extra_operands[0] = operand_mask;
1150 
1151    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 6 + num_extra_operands);
1152    spirv_buffer_emit_word(&b->instructions, op |
1153                           ((6 + num_extra_operands) << 16));
1154    spirv_buffer_emit_word(&b->instructions, result_type);
1155    spirv_buffer_emit_word(&b->instructions, result);
1156    spirv_buffer_emit_word(&b->instructions, image);
1157    spirv_buffer_emit_word(&b->instructions, src->coord);
1158    if (src->dref)
1159       spirv_buffer_emit_word(&b->instructions, src->dref);
1160    else
1161       spirv_buffer_emit_word(&b->instructions, component);
1162    for (int i = 0; i < num_extra_operands; ++i)
1163       spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
1164    return result;
1165 }
1166 
1167 SpvId
spirv_builder_emit_image_fetch(struct spirv_builder * b,SpvId result_type,SpvId image,const struct spriv_tex_src * src)1168 spirv_builder_emit_image_fetch(struct spirv_builder *b,
1169                                SpvId result_type,
1170                                SpvId image,
1171                                const struct spriv_tex_src *src)
1172 {
1173    SpvId result = spirv_builder_new_id(b);
1174 
1175    SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
1176    SpvId extra_operands[4];
1177    int num_extra_operands = 1;
1178    if (src->lod) {
1179       extra_operands[num_extra_operands++] = src->lod;
1180       operand_mask |= SpvImageOperandsLodMask;
1181    }
1182    if (src->sample) {
1183       extra_operands[num_extra_operands++] = src->sample;
1184       operand_mask |= SpvImageOperandsSampleMask;
1185    }
1186    assert(!(src->const_offset && src->offset));
1187    if (src->const_offset) {
1188       extra_operands[num_extra_operands++] = src->const_offset;
1189       operand_mask |= SpvImageOperandsConstOffsetMask;
1190    } else if (src->offset) {
1191       extra_operands[num_extra_operands++] = src->offset;
1192       operand_mask |= SpvImageOperandsOffsetMask;
1193    }
1194    if (src->sparse)
1195       result_type = sparse_wrap_result_type(b, result_type);
1196 
1197    /* finalize num_extra_operands / extra_operands */
1198    extra_operands[0] = operand_mask;
1199 
1200    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 5 + num_extra_operands);
1201    spirv_buffer_emit_word(&b->instructions, (src->sparse ? SpvOpImageSparseFetch : SpvOpImageFetch) |
1202                           ((5 + num_extra_operands) << 16));
1203    spirv_buffer_emit_word(&b->instructions, result_type);
1204    spirv_buffer_emit_word(&b->instructions, result);
1205    spirv_buffer_emit_word(&b->instructions, image);
1206    spirv_buffer_emit_word(&b->instructions, src->coord);
1207    for (int i = 0; i < num_extra_operands; ++i)
1208       spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
1209    return result;
1210 }
1211 
1212 SpvId
spirv_builder_emit_image_query_size(struct spirv_builder * b,SpvId result_type,SpvId image,SpvId lod)1213 spirv_builder_emit_image_query_size(struct spirv_builder *b,
1214                                     SpvId result_type,
1215                                     SpvId image,
1216                                     SpvId lod)
1217 {
1218    int opcode = SpvOpImageQuerySize;
1219    int words = 4;
1220    if (lod) {
1221       words++;
1222       opcode = SpvOpImageQuerySizeLod;
1223    }
1224 
1225    SpvId result = spirv_builder_new_id(b);
1226    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
1227    spirv_buffer_emit_word(&b->instructions, opcode | (words << 16));
1228    spirv_buffer_emit_word(&b->instructions, result_type);
1229    spirv_buffer_emit_word(&b->instructions, result);
1230    spirv_buffer_emit_word(&b->instructions, image);
1231 
1232    if (lod)
1233       spirv_buffer_emit_word(&b->instructions, lod);
1234 
1235    return result;
1236 }
1237 
1238 SpvId
spirv_builder_emit_image_query_levels(struct spirv_builder * b,SpvId result_type,SpvId image)1239 spirv_builder_emit_image_query_levels(struct spirv_builder *b,
1240                                     SpvId result_type,
1241                                     SpvId image)
1242 {
1243    return spirv_builder_emit_unop(b, SpvOpImageQueryLevels, result_type, image);
1244 }
1245 
1246 SpvId
spirv_builder_emit_image_query_lod(struct spirv_builder * b,SpvId result_type,SpvId image,SpvId coords)1247 spirv_builder_emit_image_query_lod(struct spirv_builder *b,
1248                                     SpvId result_type,
1249                                     SpvId image,
1250                                     SpvId coords)
1251 {
1252    int opcode = SpvOpImageQueryLod;
1253    int words = 5;
1254 
1255    SpvId result = spirv_builder_new_id(b);
1256    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
1257    spirv_buffer_emit_word(&b->instructions, opcode | (words << 16));
1258    spirv_buffer_emit_word(&b->instructions, result_type);
1259    spirv_buffer_emit_word(&b->instructions, result);
1260    spirv_buffer_emit_word(&b->instructions, image);
1261    spirv_buffer_emit_word(&b->instructions, coords);
1262 
1263    return result;
1264 }
1265 
1266 SpvId
spirv_builder_emit_ext_inst(struct spirv_builder * b,SpvId result_type,SpvId set,uint32_t instruction,const SpvId * args,size_t num_args)1267 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
1268                             SpvId set, uint32_t instruction,
1269                             const SpvId *args, size_t num_args)
1270 {
1271    SpvId result = spirv_builder_new_id(b);
1272 
1273    int words = 5 + num_args;
1274    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
1275    spirv_buffer_emit_word(&b->instructions, SpvOpExtInst | (words << 16));
1276    spirv_buffer_emit_word(&b->instructions, result_type);
1277    spirv_buffer_emit_word(&b->instructions, result);
1278    spirv_buffer_emit_word(&b->instructions, set);
1279    spirv_buffer_emit_word(&b->instructions, instruction);
1280    for (int i = 0; i < num_args; ++i)
1281       spirv_buffer_emit_word(&b->instructions, args[i]);
1282    return result;
1283 }
1284 
1285 struct spirv_type {
1286    SpvOp op;
1287    uint32_t args[8];
1288    size_t num_args;
1289 
1290    SpvId type;
1291 };
1292 
1293 static uint32_t
non_aggregate_type_hash(const void * arg)1294 non_aggregate_type_hash(const void *arg)
1295 {
1296    const struct spirv_type *type = arg;
1297 
1298    uint32_t hash = 0;
1299    hash = XXH32(&type->op, sizeof(type->op), hash);
1300    hash = XXH32(type->args, sizeof(uint32_t) * type->num_args, hash);
1301    return hash;
1302 }
1303 
1304 static bool
non_aggregate_type_equals(const void * a,const void * b)1305 non_aggregate_type_equals(const void *a, const void *b)
1306 {
1307    const struct spirv_type *ta = a, *tb = b;
1308 
1309    if (ta->op != tb->op)
1310       return false;
1311 
1312    assert(ta->num_args == tb->num_args);
1313    return memcmp(ta->args, tb->args, sizeof(uint32_t) * ta->num_args) == 0;
1314 }
1315 
1316 static SpvId
get_type_def(struct spirv_builder * b,SpvOp op,const uint32_t args[],size_t num_args)1317 get_type_def(struct spirv_builder *b, SpvOp op, const uint32_t args[],
1318              size_t num_args)
1319 {
1320    /* According to the SPIR-V specification:
1321     *
1322     *   "Two different type <id>s form, by definition, two different types. It
1323     *    is valid to declare multiple aggregate type <id>s having the same
1324     *    opcode and operands. This is to allow multiple instances of aggregate
1325     *    types with the same structure to be decorated differently. (Different
1326     *    decorations are not required; two different aggregate type <id>s are
1327     *    allowed to have identical declarations and decorations, and will still
1328     *    be two different types.) Non-aggregate types are different: It is
1329     *    invalid to declare multiple type <id>s for the same scalar, vector, or
1330     *    matrix type. That is, non-aggregate type declarations must all have
1331     *    different opcodes or operands. (Note that non-aggregate types cannot
1332     *    be decorated in ways that affect their type.)"
1333     *
1334     *  ..so, we need to prevent the same non-aggregate type to be re-defined
1335     *  with a new <id>. We do this by putting the definitions in a hash-map, so
1336     *  we can easily look up and reuse them.
1337     */
1338 
1339    struct spirv_type key;
1340    assert(num_args <= ARRAY_SIZE(key.args));
1341    key.op = op;
1342    memcpy(&key.args, args, sizeof(uint32_t) * num_args);
1343    key.num_args = num_args;
1344 
1345    struct hash_entry *entry;
1346    if (b->types) {
1347       entry = _mesa_hash_table_search(b->types, &key);
1348       if (entry)
1349          return ((struct spirv_type *)entry->data)->type;
1350    } else {
1351       b->types = _mesa_hash_table_create(b->mem_ctx,
1352                                          non_aggregate_type_hash,
1353                                          non_aggregate_type_equals);
1354       assert(b->types);
1355    }
1356 
1357    struct spirv_type *type = rzalloc(b->mem_ctx, struct spirv_type);
1358    if (!type)
1359       return 0;
1360 
1361    type->op = op;
1362    memcpy(&type->args, args, sizeof(uint32_t) * num_args);
1363    type->num_args = num_args;
1364 
1365    type->type = spirv_builder_new_id(b);
1366    spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, 2 + num_args);
1367    spirv_buffer_emit_word(&b->types_const_defs, op | ((2 + num_args) << 16));
1368    spirv_buffer_emit_word(&b->types_const_defs, type->type);
1369    for (int i = 0; i < num_args; ++i)
1370       spirv_buffer_emit_word(&b->types_const_defs, args[i]);
1371 
1372    entry = _mesa_hash_table_insert(b->types, type, type);
1373    assert(entry);
1374 
1375    return ((struct spirv_type *)entry->data)->type;
1376 }
1377 
1378 SpvId
spirv_builder_type_void(struct spirv_builder * b)1379 spirv_builder_type_void(struct spirv_builder *b)
1380 {
1381    return get_type_def(b, SpvOpTypeVoid, NULL, 0);
1382 }
1383 
1384 SpvId
spirv_builder_type_bool(struct spirv_builder * b)1385 spirv_builder_type_bool(struct spirv_builder *b)
1386 {
1387    return get_type_def(b, SpvOpTypeBool, NULL, 0);
1388 }
1389 
1390 SpvId
spirv_builder_type_int(struct spirv_builder * b,unsigned width)1391 spirv_builder_type_int(struct spirv_builder *b, unsigned width)
1392 {
1393    uint32_t args[] = { width, 1 };
1394    if (width == 8)
1395       spirv_builder_emit_cap(b, SpvCapabilityInt8);
1396    else if (width == 16)
1397       spirv_builder_emit_cap(b, SpvCapabilityInt16);
1398    else if (width == 64)
1399       spirv_builder_emit_cap(b, SpvCapabilityInt64);
1400    return get_type_def(b, SpvOpTypeInt, args, ARRAY_SIZE(args));
1401 }
1402 
1403 SpvId
spirv_builder_type_uint(struct spirv_builder * b,unsigned width)1404 spirv_builder_type_uint(struct spirv_builder *b, unsigned width)
1405 {
1406    uint32_t args[] = { width, 0 };
1407    if (width == 8)
1408       spirv_builder_emit_cap(b, SpvCapabilityInt8);
1409    else if (width == 16)
1410       spirv_builder_emit_cap(b, SpvCapabilityInt16);
1411    else if (width == 64)
1412       spirv_builder_emit_cap(b, SpvCapabilityInt64);
1413    return get_type_def(b, SpvOpTypeInt, args, ARRAY_SIZE(args));
1414 }
1415 
1416 SpvId
spirv_builder_type_float(struct spirv_builder * b,unsigned width)1417 spirv_builder_type_float(struct spirv_builder *b, unsigned width)
1418 {
1419    uint32_t args[] = { width };
1420    if (width == 16)
1421       spirv_builder_emit_cap(b, SpvCapabilityFloat16);
1422    else if (width == 64)
1423       spirv_builder_emit_cap(b, SpvCapabilityFloat64);
1424    return get_type_def(b, SpvOpTypeFloat, args, ARRAY_SIZE(args));
1425 }
1426 
1427 SpvId
spirv_builder_type_image(struct spirv_builder * b,SpvId sampled_type,SpvDim dim,bool depth,bool arrayed,bool ms,unsigned sampled,SpvImageFormat image_format)1428 spirv_builder_type_image(struct spirv_builder *b, SpvId sampled_type,
1429                          SpvDim dim, bool depth, bool arrayed, bool ms,
1430                          unsigned sampled, SpvImageFormat image_format)
1431 {
1432    assert(sampled < 3);
1433    uint32_t args[] = {
1434       sampled_type, dim, depth ? 1 : 0, arrayed ? 1 : 0, ms ? 1 : 0, sampled,
1435       image_format
1436    };
1437    if (sampled == 2 && ms && dim != SpvDimSubpassData)
1438       spirv_builder_emit_cap(b, SpvCapabilityStorageImageMultisample);
1439    return get_type_def(b, SpvOpTypeImage, args, ARRAY_SIZE(args));
1440 }
1441 
1442 SpvId
spirv_builder_emit_sampled_image(struct spirv_builder * b,SpvId result_type,SpvId image,SpvId sampler)1443 spirv_builder_emit_sampled_image(struct spirv_builder *b, SpvId result_type, SpvId image, SpvId sampler)
1444 {
1445    return spirv_builder_emit_binop(b, SpvOpSampledImage, result_type, image, sampler);
1446 }
1447 
1448 SpvId
spirv_builder_type_sampled_image(struct spirv_builder * b,SpvId image_type)1449 spirv_builder_type_sampled_image(struct spirv_builder *b, SpvId image_type)
1450 {
1451    uint32_t args[] = { image_type };
1452    return get_type_def(b, SpvOpTypeSampledImage, args, ARRAY_SIZE(args));
1453 }
1454 
1455 SpvId
spirv_builder_type_sampler(struct spirv_builder * b)1456 spirv_builder_type_sampler(struct spirv_builder *b)
1457 {
1458    uint32_t args[1] = {0};
1459    return get_type_def(b, SpvOpTypeSampler, args, 0);
1460 }
1461 
1462 SpvId
spirv_builder_type_pointer(struct spirv_builder * b,SpvStorageClass storage_class,SpvId type)1463 spirv_builder_type_pointer(struct spirv_builder *b,
1464                            SpvStorageClass storage_class, SpvId type)
1465 {
1466    uint32_t args[] = { storage_class, type };
1467    return get_type_def(b, SpvOpTypePointer, args, ARRAY_SIZE(args));
1468 }
1469 
1470 SpvId
spirv_builder_type_vector(struct spirv_builder * b,SpvId component_type,unsigned component_count)1471 spirv_builder_type_vector(struct spirv_builder *b, SpvId component_type,
1472                           unsigned component_count)
1473 {
1474    assert(component_count > 1);
1475    uint32_t args[] = { component_type, component_count };
1476    return get_type_def(b, SpvOpTypeVector, args, ARRAY_SIZE(args));
1477 }
1478 
1479 SpvId
spirv_builder_type_matrix(struct spirv_builder * b,SpvId component_type,unsigned component_count)1480 spirv_builder_type_matrix(struct spirv_builder *b, SpvId component_type,
1481                           unsigned component_count)
1482 {
1483    assert(component_count > 1);
1484    uint32_t args[] = { component_type, component_count };
1485    return get_type_def(b, SpvOpTypeMatrix, args, ARRAY_SIZE(args));
1486 }
1487 
1488 SpvId
spirv_builder_type_runtime_array(struct spirv_builder * b,SpvId component_type)1489 spirv_builder_type_runtime_array(struct spirv_builder *b, SpvId component_type)
1490 {
1491    SpvId type = spirv_builder_new_id(b);
1492    spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, 3);
1493    spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeRuntimeArray | (3 << 16));
1494    spirv_buffer_emit_word(&b->types_const_defs, type);
1495    spirv_buffer_emit_word(&b->types_const_defs, component_type);
1496    return type;
1497 }
1498 
1499 SpvId
spirv_builder_type_array(struct spirv_builder * b,SpvId component_type,SpvId length)1500 spirv_builder_type_array(struct spirv_builder *b, SpvId component_type,
1501                          SpvId length)
1502 {
1503    SpvId type = spirv_builder_new_id(b);
1504    spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, 4);
1505    spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeArray | (4 << 16));
1506    spirv_buffer_emit_word(&b->types_const_defs, type);
1507    spirv_buffer_emit_word(&b->types_const_defs, component_type);
1508    spirv_buffer_emit_word(&b->types_const_defs, length);
1509    return type;
1510 }
1511 
1512 SpvId
spirv_builder_type_struct(struct spirv_builder * b,const SpvId member_types[],size_t num_member_types)1513 spirv_builder_type_struct(struct spirv_builder *b, const SpvId member_types[],
1514                           size_t num_member_types)
1515 {
1516    int words = 2 + num_member_types;
1517    SpvId type = spirv_builder_new_id(b);
1518    spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, words);
1519    spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeStruct | (words << 16));
1520    spirv_buffer_emit_word(&b->types_const_defs, type);
1521    for (int i = 0; i < num_member_types; ++i)
1522       spirv_buffer_emit_word(&b->types_const_defs, member_types[i]);
1523    return type;
1524 }
1525 
1526 SpvId
spirv_builder_type_function(struct spirv_builder * b,SpvId return_type,const SpvId parameter_types[],size_t num_parameter_types)1527 spirv_builder_type_function(struct spirv_builder *b, SpvId return_type,
1528                             const SpvId parameter_types[],
1529                             size_t num_parameter_types)
1530 {
1531    int words = 3 + num_parameter_types;
1532    SpvId type = spirv_builder_new_id(b);
1533    spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, words);
1534    spirv_buffer_emit_word(&b->types_const_defs, SpvOpTypeFunction | (words << 16));
1535    spirv_buffer_emit_word(&b->types_const_defs, type);
1536    spirv_buffer_emit_word(&b->types_const_defs, return_type);
1537    for (int i = 0; i < num_parameter_types; ++i)
1538       spirv_buffer_emit_word(&b->types_const_defs, parameter_types[i]);
1539    return type;
1540 }
1541 
1542 struct spirv_const {
1543    SpvOp op, type;
1544    uint32_t args[8];
1545    size_t num_args;
1546 
1547    SpvId result;
1548 };
1549 
1550 static uint32_t
const_hash(const void * arg)1551 const_hash(const void *arg)
1552 {
1553    const struct spirv_const *key = arg;
1554 
1555    uint32_t hash = 0;
1556    hash = XXH32(&key->op, sizeof(key->op), hash);
1557    hash = XXH32(&key->type, sizeof(key->type), hash);
1558    hash = XXH32(key->args, sizeof(uint32_t) * key->num_args, hash);
1559    return hash;
1560 }
1561 
1562 static bool
const_equals(const void * a,const void * b)1563 const_equals(const void *a, const void *b)
1564 {
1565    const struct spirv_const *ca = a, *cb = b;
1566 
1567    if (ca->op != cb->op ||
1568        ca->type != cb->type)
1569       return false;
1570 
1571    assert(ca->num_args == cb->num_args);
1572    return memcmp(ca->args, cb->args, sizeof(uint32_t) * ca->num_args) == 0;
1573 }
1574 
1575 static SpvId
get_const_def(struct spirv_builder * b,SpvOp op,SpvId type,const uint32_t args[],size_t num_args)1576 get_const_def(struct spirv_builder *b, SpvOp op, SpvId type,
1577               const uint32_t args[], size_t num_args)
1578 {
1579    struct spirv_const key;
1580    assert(num_args <= ARRAY_SIZE(key.args));
1581    key.op = op;
1582    key.type = type;
1583    memcpy(&key.args, args, sizeof(uint32_t) * num_args);
1584    key.num_args = num_args;
1585 
1586    struct hash_entry *entry;
1587    if (b->consts) {
1588       entry = _mesa_hash_table_search(b->consts, &key);
1589       if (entry)
1590          return ((struct spirv_const *)entry->data)->result;
1591    } else {
1592       b->consts = _mesa_hash_table_create(b->mem_ctx, const_hash,
1593                                           const_equals);
1594       assert(b->consts);
1595    }
1596 
1597    struct spirv_const *cnst = rzalloc(b->mem_ctx, struct spirv_const);
1598    if (!cnst)
1599       return 0;
1600 
1601    cnst->op = op;
1602    cnst->type = type;
1603    memcpy(&cnst->args, args, sizeof(uint32_t) * num_args);
1604    cnst->num_args = num_args;
1605 
1606    cnst->result = spirv_builder_new_id(b);
1607    spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, 3 + num_args);
1608    spirv_buffer_emit_word(&b->types_const_defs, op | ((3 + num_args) << 16));
1609    spirv_buffer_emit_word(&b->types_const_defs, type);
1610    spirv_buffer_emit_word(&b->types_const_defs, cnst->result);
1611    for (int i = 0; i < num_args; ++i)
1612       spirv_buffer_emit_word(&b->types_const_defs, args[i]);
1613 
1614    entry = _mesa_hash_table_insert(b->consts, cnst, cnst);
1615    assert(entry);
1616 
1617    return ((struct spirv_const *)entry->data)->result;
1618 }
1619 
1620 static SpvId
emit_constant_32(struct spirv_builder * b,SpvId type,uint32_t val)1621 emit_constant_32(struct spirv_builder *b, SpvId type, uint32_t val)
1622 {
1623    uint32_t args[] = { val };
1624    return get_const_def(b, SpvOpConstant, type, args, ARRAY_SIZE(args));
1625 }
1626 
1627 static SpvId
emit_constant_64(struct spirv_builder * b,SpvId type,uint64_t val)1628 emit_constant_64(struct spirv_builder *b, SpvId type, uint64_t val)
1629 {
1630    uint32_t args[] = { val & UINT32_MAX, val >> 32 };
1631    return get_const_def(b, SpvOpConstant, type, args, ARRAY_SIZE(args));
1632 }
1633 
1634 SpvId
spirv_builder_const_bool(struct spirv_builder * b,bool val)1635 spirv_builder_const_bool(struct spirv_builder *b, bool val)
1636 {
1637    return get_const_def(b, val ? SpvOpConstantTrue : SpvOpConstantFalse,
1638                         spirv_builder_type_bool(b), NULL, 0);
1639 }
1640 
1641 SpvId
spirv_builder_const_int(struct spirv_builder * b,int width,int64_t val)1642 spirv_builder_const_int(struct spirv_builder *b, int width, int64_t val)
1643 {
1644    assert(width >= 8);
1645    SpvId type = spirv_builder_type_int(b, width);
1646    if (width <= 32)
1647       return emit_constant_32(b, type, val);
1648    else
1649       return emit_constant_64(b, type, val);
1650 }
1651 
1652 SpvId
spirv_builder_const_uint(struct spirv_builder * b,int width,uint64_t val)1653 spirv_builder_const_uint(struct spirv_builder *b, int width, uint64_t val)
1654 {
1655    assert(width >= 8);
1656    if (width == 8)
1657       spirv_builder_emit_cap(b, SpvCapabilityInt8);
1658    else if (width == 16)
1659       spirv_builder_emit_cap(b, SpvCapabilityInt16);
1660    else if (width == 64)
1661       spirv_builder_emit_cap(b, SpvCapabilityInt64);
1662    SpvId type = spirv_builder_type_uint(b, width);
1663    if (width <= 32)
1664       return emit_constant_32(b, type, val);
1665    else
1666       return emit_constant_64(b, type, val);
1667 }
1668 
1669 SpvId
spirv_builder_spec_const_uint(struct spirv_builder * b,int width)1670 spirv_builder_spec_const_uint(struct spirv_builder *b, int width)
1671 {
1672    assert(width <= 32);
1673    SpvId const_type = spirv_builder_type_uint(b, width);
1674    SpvId result = spirv_builder_new_id(b);
1675    spirv_buffer_prepare(&b->types_const_defs, b->mem_ctx, 4);
1676    spirv_buffer_emit_word(&b->types_const_defs, SpvOpSpecConstant | (4 << 16));
1677    spirv_buffer_emit_word(&b->types_const_defs, const_type);
1678    spirv_buffer_emit_word(&b->types_const_defs, result);
1679    /* this is the default value for spec constants;
1680     * if any users need a different default, add a param to pass for it
1681     */
1682    spirv_buffer_emit_word(&b->types_const_defs, 1);
1683    return result;
1684 }
1685 
1686 SpvId
spirv_builder_const_float(struct spirv_builder * b,int width,double val)1687 spirv_builder_const_float(struct spirv_builder *b, int width, double val)
1688 {
1689    assert(width >= 16);
1690    SpvId type = spirv_builder_type_float(b, width);
1691    if (width == 16) {
1692       spirv_builder_emit_cap(b, SpvCapabilityFloat16);
1693       return emit_constant_32(b, type, _mesa_float_to_half(val));
1694    } else if (width == 32)
1695       return emit_constant_32(b, type, u_bitcast_f2u(val));
1696    else if (width == 64) {
1697       spirv_builder_emit_cap(b, SpvCapabilityFloat64);
1698       return emit_constant_64(b, type, u_bitcast_d2u(val));
1699    }
1700 
1701    unreachable("unhandled float-width");
1702 }
1703 
1704 SpvId
spirv_builder_const_composite(struct spirv_builder * b,SpvId result_type,const SpvId constituents[],size_t num_constituents)1705 spirv_builder_const_composite(struct spirv_builder *b, SpvId result_type,
1706                               const SpvId constituents[],
1707                               size_t num_constituents)
1708 {
1709    return get_const_def(b, SpvOpConstantComposite, result_type,
1710                         (const uint32_t *)constituents,
1711                         num_constituents);
1712 }
1713 
1714 SpvId
spirv_builder_spec_const_composite(struct spirv_builder * b,SpvId result_type,const SpvId constituents[],size_t num_constituents)1715 spirv_builder_spec_const_composite(struct spirv_builder *b, SpvId result_type,
1716                                    const SpvId constituents[],
1717                                    size_t num_constituents)
1718 {
1719    SpvId result = spirv_builder_new_id(b);
1720 
1721    assert(num_constituents > 0);
1722    int words = 3 + num_constituents;
1723    spirv_buffer_prepare(&b->instructions, b->mem_ctx, words);
1724    spirv_buffer_emit_word(&b->instructions,
1725                           SpvOpSpecConstantComposite | (words << 16));
1726    spirv_buffer_emit_word(&b->instructions, result_type);
1727    spirv_buffer_emit_word(&b->instructions, result);
1728    for (int i = 0; i < num_constituents; ++i)
1729       spirv_buffer_emit_word(&b->instructions, constituents[i]);
1730    return result;
1731 }
1732 
1733 SpvId
spirv_builder_emit_var(struct spirv_builder * b,SpvId type,SpvStorageClass storage_class)1734 spirv_builder_emit_var(struct spirv_builder *b, SpvId type,
1735                        SpvStorageClass storage_class)
1736 {
1737    assert(storage_class != SpvStorageClassGeneric);
1738    struct spirv_buffer *buf = storage_class != SpvStorageClassFunction ?
1739                               &b->types_const_defs : &b->local_vars;
1740 
1741    SpvId ret = spirv_builder_new_id(b);
1742    spirv_buffer_prepare(buf, b->mem_ctx, 4);
1743    spirv_buffer_emit_word(buf, SpvOpVariable | (4 << 16));
1744    spirv_buffer_emit_word(buf, type);
1745    spirv_buffer_emit_word(buf, ret);
1746    spirv_buffer_emit_word(buf, storage_class);
1747    return ret;
1748 }
1749 
1750 void
spirv_builder_emit_memory_barrier(struct spirv_builder * b,SpvScope scope,SpvMemorySemanticsMask semantics)1751 spirv_builder_emit_memory_barrier(struct spirv_builder *b, SpvScope scope, SpvMemorySemanticsMask semantics)
1752 {
1753    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 3);
1754    spirv_buffer_emit_word(&b->instructions, SpvOpMemoryBarrier | (3 << 16));
1755    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, scope));
1756    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, semantics));
1757 }
1758 
1759 void
spirv_builder_emit_control_barrier(struct spirv_builder * b,SpvScope scope,SpvScope mem_scope,SpvMemorySemanticsMask semantics)1760 spirv_builder_emit_control_barrier(struct spirv_builder *b, SpvScope scope, SpvScope mem_scope, SpvMemorySemanticsMask semantics)
1761 {
1762    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 4);
1763    spirv_buffer_emit_word(&b->instructions, SpvOpControlBarrier | (4 << 16));
1764    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, scope));
1765    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, mem_scope));
1766    spirv_buffer_emit_word(&b->instructions, spirv_builder_const_uint(b, 32, semantics));
1767 }
1768 
1769 SpvId
spirv_builder_import(struct spirv_builder * b,const char * name)1770 spirv_builder_import(struct spirv_builder *b, const char *name)
1771 {
1772    SpvId result = spirv_builder_new_id(b);
1773    size_t pos = b->imports.num_words;
1774    spirv_buffer_prepare(&b->imports, b->mem_ctx, 2);
1775    spirv_buffer_emit_word(&b->imports, SpvOpExtInstImport);
1776    spirv_buffer_emit_word(&b->imports, result);
1777    int len = spirv_buffer_emit_string(&b->imports, b->mem_ctx, name);
1778    b->imports.words[pos] |= (2 + len) << 16;
1779    return result;
1780 }
1781 
1782 size_t
spirv_builder_get_num_words(struct spirv_builder * b)1783 spirv_builder_get_num_words(struct spirv_builder *b)
1784 {
1785    const size_t header_size = 5;
1786    const size_t caps_size = b->caps ? b->caps->entries * 2 : 0;
1787    return header_size + caps_size +
1788           b->extensions.num_words +
1789           b->imports.num_words +
1790           b->memory_model.num_words +
1791           b->entry_points.num_words +
1792           b->exec_modes.num_words +
1793           b->debug_names.num_words +
1794           b->decorations.num_words +
1795           b->types_const_defs.num_words +
1796           b->local_vars.num_words +
1797           b->instructions.num_words;
1798 }
1799 
1800 size_t
spirv_builder_get_words(struct spirv_builder * b,uint32_t * words,size_t num_words,uint32_t spirv_version,uint32_t * tcs_vertices_out_word)1801 spirv_builder_get_words(struct spirv_builder *b, uint32_t *words,
1802                         size_t num_words, uint32_t spirv_version,
1803                         uint32_t *tcs_vertices_out_word)
1804 {
1805    assert(num_words >= spirv_builder_get_num_words(b));
1806 
1807    size_t written  = 0;
1808    words[written++] = SpvMagicNumber;
1809    words[written++] = spirv_version;
1810    words[written++] = 0;
1811    words[written++] = b->prev_id + 1;
1812    words[written++] = 0;
1813 
1814    if (b->caps) {
1815       set_foreach(b->caps, entry) {
1816          words[written++] = SpvOpCapability | (2 << 16);
1817          words[written++] = (uintptr_t)entry->key;
1818       }
1819    }
1820 
1821    const struct spirv_buffer *buffers[] = {
1822       &b->extensions,
1823       &b->imports,
1824       &b->memory_model,
1825       &b->entry_points,
1826       &b->exec_modes,
1827       &b->debug_names,
1828       &b->decorations,
1829       &b->types_const_defs,
1830    };
1831 
1832    for (int i = 0; i < ARRAY_SIZE(buffers); ++i) {
1833       const struct spirv_buffer *buffer = buffers[i];
1834 
1835       if (buffer == &b->exec_modes && *tcs_vertices_out_word > 0)
1836          *tcs_vertices_out_word += written;
1837 
1838       memcpy(words + written, buffer->words,
1839              buffer->num_words * sizeof(uint32_t));
1840       written += buffer->num_words;
1841    }
1842    typed_memcpy(&words[written], b->instructions.words, b->local_vars_begin);
1843    written += b->local_vars_begin;
1844    typed_memcpy(&words[written], b->local_vars.words, b->local_vars.num_words);
1845    written += b->local_vars.num_words;
1846    typed_memcpy(&words[written], &b->instructions.words[b->local_vars_begin], (b->instructions.num_words - b->local_vars_begin));
1847    written += b->instructions.num_words - b->local_vars_begin;
1848 
1849    assert(written == spirv_builder_get_num_words(b));
1850    return written;
1851 }
1852 
1853 void
spirv_builder_begin_local_vars(struct spirv_builder * b)1854 spirv_builder_begin_local_vars(struct spirv_builder *b)
1855 {
1856    b->local_vars_begin = b->instructions.num_words;
1857 }
1858