"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c" (16 Sep 2020, 35985 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "spirv_builder.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

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