zink: add spirv builder util functions for emitting xfb decorations
[mesa.git] / src / gallium / drivers / zink / nir_to_spirv / spirv_builder.c
index 43a4a5566535e1601805f0377c28df8834fd73cb..4f4b790cddc0f90ee5147730aa30619c7af87703 100644 (file)
@@ -27,6 +27,8 @@
 #include "util/u_bitcast.h"
 #include "util/u_memory.h"
 #include "util/hash_table.h"
+#define XXH_INLINE_ALL
+#include "util/xxhash.h"
 
 #include <stdbool.h>
 #include <inttypes.h>
@@ -222,6 +224,37 @@ spirv_builder_emit_array_stride(struct spirv_builder *b, SpvId target,
    emit_decoration(b, target, SpvDecorationArrayStride, args, ARRAY_SIZE(args));
 }
 
+void
+spirv_builder_emit_offset(struct spirv_builder *b, SpvId target,
+                          uint32_t offset)
+{
+   uint32_t args[] = { offset };
+   emit_decoration(b, target, SpvDecorationOffset, args, ARRAY_SIZE(args));
+}
+
+void
+spirv_builder_emit_xfb_buffer(struct spirv_builder *b, SpvId target,
+                              uint32_t buffer)
+{
+   uint32_t args[] = { buffer };
+   emit_decoration(b, target, SpvDecorationXfbBuffer, args, ARRAY_SIZE(args));
+}
+
+void
+spirv_builder_emit_xfb_stride(struct spirv_builder *b, SpvId target,
+                              uint32_t stride)
+{
+   uint32_t args[] = { stride };
+   emit_decoration(b, target, SpvDecorationXfbStride, args, ARRAY_SIZE(args));
+}
+
+void
+spirv_builder_emit_index(struct spirv_builder *b, SpvId target, int index)
+{
+   uint32_t args[] = { index };
+   emit_decoration(b, target, SpvDecorationIndex, args, ARRAY_SIZE(args));
+}
+
 static void
 emit_member_decoration(struct spirv_builder *b, SpvId target, uint32_t member,
                        SpvDecoration decoration, const uint32_t extra_operands[],
@@ -515,7 +548,8 @@ spirv_builder_emit_image_sample(struct spirv_builder *b,
                                 SpvId bias,
                                 SpvId dref,
                                 SpvId dx,
-                                SpvId dy)
+                                SpvId dy,
+                                SpvId offset)
 {
    SpvId result = spirv_builder_new_id(b);
 
@@ -530,9 +564,9 @@ spirv_builder_emit_image_sample(struct spirv_builder *b,
       operands++;
    }
 
-   SpvImageOperandsMask operand_mask = 0;
-   SpvId extra_operands[4];
-   int num_extra_operands = SpvImageOperandsMaskNone;
+   SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
+   SpvId extra_operands[5];
+   int num_extra_operands = 0;
    if (bias) {
       extra_operands[++num_extra_operands] = bias;
       operand_mask |= SpvImageOperandsBiasMask;
@@ -545,6 +579,10 @@ spirv_builder_emit_image_sample(struct spirv_builder *b,
       extra_operands[++num_extra_operands] = dy;
       operand_mask |= SpvImageOperandsGradMask;
    }
+   if (offset) {
+      extra_operands[++num_extra_operands] = offset;
+      operand_mask |= SpvImageOperandsOffsetMask;
+   }
 
    /* finalize num_extra_operands / extra_operands */
    if (num_extra_operands > 0) {
@@ -583,16 +621,27 @@ spirv_builder_emit_image_fetch(struct spirv_builder *b,
                                SpvId result_type,
                                SpvId image,
                                SpvId coordinate,
-                               SpvId lod)
+                               SpvId lod,
+                               SpvId sample)
 {
    SpvId result = spirv_builder_new_id(b);
 
-   SpvId extra_operands[2];
+   SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
+   SpvId extra_operands[3];
    int num_extra_operands = 0;
    if (lod) {
-      extra_operands[0] = SpvImageOperandsLodMask;
-      extra_operands[1] = lod;
-      num_extra_operands = 2;
+      extra_operands[++num_extra_operands] = lod;
+      operand_mask |= SpvImageOperandsLodMask;
+   }
+   if (sample) {
+      extra_operands[++num_extra_operands] = sample;
+      operand_mask |= SpvImageOperandsSampleMask;
+   }
+
+   /* finalize num_extra_operands / extra_operands */
+   if (num_extra_operands > 0) {
+      extra_operands[0] = operand_mask;
+      num_extra_operands++;
    }
 
    spirv_buffer_prepare(&b->instructions, 5 + num_extra_operands);
@@ -607,6 +656,32 @@ spirv_builder_emit_image_fetch(struct spirv_builder *b,
    return result;
 }
 
+SpvId
+spirv_builder_emit_image_query_size(struct spirv_builder *b,
+                                    SpvId result_type,
+                                    SpvId image,
+                                    SpvId lod)
+{
+   int opcode = SpvOpImageQuerySize;
+   int words = 4;
+   if (lod) {
+      words++;
+      opcode = SpvOpImageQuerySizeLod;
+   }
+
+   SpvId result = spirv_builder_new_id(b);
+   spirv_buffer_prepare(&b->instructions, words);
+   spirv_buffer_emit_word(&b->instructions, opcode | (words << 16));
+   spirv_buffer_emit_word(&b->instructions, result_type);
+   spirv_buffer_emit_word(&b->instructions, result);
+   spirv_buffer_emit_word(&b->instructions, image);
+
+   if (lod)
+      spirv_buffer_emit_word(&b->instructions, lod);
+
+   return result;
+}
+
 SpvId
 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
                             SpvId set, uint32_t instruction,
@@ -639,10 +714,9 @@ non_aggregate_type_hash(const void *arg)
 {
    const struct spirv_type *type = arg;
 
-   uint32_t hash = _mesa_fnv32_1a_offset_bias;
-   hash = _mesa_fnv32_1a_accumulate(hash, type->op);
-   hash = _mesa_fnv32_1a_accumulate_block(hash, type->args, sizeof(uint32_t) *
-                                          type->num_args);
+   uint32_t hash = 0;
+   hash = XXH32(&type->op, sizeof(type->op), hash);
+   hash = XXH32(type->args, sizeof(uint32_t) * type->num_args, hash);
    return hash;
 }
 
@@ -845,11 +919,10 @@ const_hash(const void *arg)
 {
    const struct spirv_const *key = arg;
 
-   uint32_t hash = _mesa_fnv32_1a_offset_bias;
-   hash = _mesa_fnv32_1a_accumulate(hash, key->op);
-   hash = _mesa_fnv32_1a_accumulate(hash, key->type);
-   hash = _mesa_fnv32_1a_accumulate_block(hash, key->args, sizeof(uint32_t) *
-                                          key->num_args);
+   uint32_t hash = 0;
+   hash = XXH32(&key->op, sizeof(key->op), hash);
+   hash = XXH32(&key->type, sizeof(key->type), hash);
+   hash = XXH32(key->args, sizeof(uint32_t) * key->num_args, hash);
    return hash;
 }