compiler/nir: Add support for variable initialization from a pointer
[mesa.git] / src / compiler / nir / nir_serialize.c
index e16c107428508e52d0fa8184805c4981c2f17470..0be80faf9a1763866a0b9ceb60b115ab39174bce 100644 (file)
@@ -141,6 +141,8 @@ decode_bit_size_3bits(uint8_t bit_size)
    return 0;
 }
 
+#define NUM_COMPONENTS_IS_SEPARATE_7   7
+
 static uint8_t
 encode_num_components_in_3bits(uint8_t num_components)
 {
@@ -151,8 +153,8 @@ encode_num_components_in_3bits(uint8_t num_components)
    if (num_components == 16)
       return 6;
 
-   unreachable("invalid number in num_components");
-   return 0;
+   /* special value indicating that num_components is in the next uint32 */
+   return NUM_COMPONENTS_IS_SEPARATE_7;
 }
 
 static uint8_t
@@ -204,12 +206,13 @@ union packed_var {
    struct {
       unsigned has_name:1;
       unsigned has_constant_initializer:1;
+      unsigned has_pointer_initializer:1;
       unsigned has_interface_type:1;
       unsigned num_state_slots:7;
       unsigned data_encoding:2;
       unsigned type_same_as_last:1;
       unsigned interface_type_same_as_last:1;
-      unsigned _pad:2;
+      unsigned _pad:1;
       unsigned num_members:16;
    } u;
 };
@@ -229,7 +232,6 @@ write_variable(write_ctx *ctx, const nir_variable *var)
    write_add_object(ctx, var);
 
    assert(var->num_state_slots < (1 << 7));
-   assert(var->num_members < (1 << 16));
 
    STATIC_ASSERT(sizeof(union packed_var) == 4);
    union packed_var flags;
@@ -237,6 +239,7 @@ write_variable(write_ctx *ctx, const nir_variable *var)
 
    flags.u.has_name = !ctx->strip && var->name;
    flags.u.has_constant_initializer = !!(var->constant_initializer);
+   flags.u.has_pointer_initializer = !!(var->pointer_initializer);
    flags.u.has_interface_type = !!(var->interface_type);
    flags.u.type_same_as_last = var->type == ctx->last_type;
    flags.u.interface_type_same_as_last =
@@ -321,6 +324,8 @@ write_variable(write_ctx *ctx, const nir_variable *var)
    }
    if (var->constant_initializer)
       write_constant(ctx, var->constant_initializer);
+   if (var->pointer_initializer)
+      write_lookup_object(ctx, var->pointer_initializer);
    if (var->num_members > 0) {
       blob_write_bytes(ctx->blob, (uint8_t *) var->members,
                        var->num_members * sizeof(*var->members));
@@ -391,6 +396,12 @@ read_variable(read_ctx *ctx)
       var->constant_initializer = read_constant(ctx, var);
    else
       var->constant_initializer = NULL;
+
+   if (flags.u.has_pointer_initializer)
+      var->pointer_initializer = read_object(ctx);
+   else
+      var->pointer_initializer = NULL;
+
    var->num_members = flags.u.num_members;
    if (var->num_members > 0) {
       var->members = ralloc_array(var, struct nir_variable_data,
@@ -732,6 +743,10 @@ write_dest(write_ctx *ctx, const nir_dest *dst, union packed_instr header,
       blob_write_uint32(ctx->blob, header.u32);
    }
 
+   if (dest.ssa.is_ssa &&
+       dest.ssa.num_components == NUM_COMPONENTS_IS_SEPARATE_7)
+      blob_write_uint32(ctx->blob, dst->ssa.num_components);
+
    if (dst->is_ssa) {
       write_add_object(ctx, &dst->ssa);
       if (dest.ssa.has_name)
@@ -753,8 +768,11 @@ read_dest(read_ctx *ctx, nir_dest *dst, nir_instr *instr,
 
    if (dest.ssa.is_ssa) {
       unsigned bit_size = decode_bit_size_3bits(dest.ssa.bit_size);
-      unsigned num_components =
-         decode_num_components_in_3bits(dest.ssa.num_components);
+      unsigned num_components;
+      if (dest.ssa.num_components == NUM_COMPONENTS_IS_SEPARATE_7)
+         num_components = blob_read_uint32(ctx->blob);
+      else
+         num_components = decode_num_components_in_3bits(dest.ssa.num_components);
       char *name = dest.ssa.has_name ? blob_read_string(ctx->blob) : NULL;
       nir_ssa_dest_init(instr, dst, num_components, bit_size, name);
       read_add_object(ctx, &dst->ssa);
@@ -790,7 +808,8 @@ is_alu_src_ssa_16bit(write_ctx *ctx, const nir_alu_instr *alu)
          /* The swizzles for src0.x and src1.x are stored
           * in writemask_or_two_swizzles for SSA ALUs.
           */
-         if (alu->dest.dest.is_ssa && i < 2 && chan == 0)
+         if (alu->dest.dest.is_ssa && i < 2 && chan == 0 &&
+             alu->src[i].swizzle[chan] < 4)
             continue;
 
          if (alu->src[i].swizzle[chan] != chan)
@@ -845,14 +864,16 @@ write_alu(write_ctx *ctx, const nir_alu_instr *alu)
       }
    } else {
       for (unsigned i = 0; i < num_srcs; i++) {
-         unsigned src_components = nir_ssa_alu_instr_src_components(alu, i);
+         unsigned src_channels = nir_ssa_alu_instr_src_components(alu, i);
+         unsigned src_components = nir_src_num_components(alu->src[i].src);
          union packed_src src;
+         bool packed = src_components <= 4 && src_channels <= 4;
          src.u32 = 0;
 
          src.alu.negate = alu->src[i].negate;
          src.alu.abs = alu->src[i].abs;
 
-         if (src_components <= 4) {
+         if (packed) {
             src.alu.swizzle_x = alu->src[i].swizzle[0];
             src.alu.swizzle_y = alu->src[i].swizzle[1];
             src.alu.swizzle_z = alu->src[i].swizzle[2];
@@ -862,12 +883,12 @@ write_alu(write_ctx *ctx, const nir_alu_instr *alu)
          write_src_full(ctx, &alu->src[i].src, src);
 
          /* Store swizzles for vec8 and vec16. */
-         if (src_components > 4) {
-            for (unsigned i = 0; i < src_components; i += 8) {
+         if (!packed) {
+            for (unsigned o = 0; o < src_channels; o += 8) {
                unsigned value = 0;
 
-               for (unsigned j = 0; j < 8 && i + j < src_components; j++) {
-                  value |= alu->src[i].swizzle[i + j] <<
+               for (unsigned j = 0; j < 8 && o + j < src_channels; j++) {
+                  value |= (uint32_t)alu->src[i].swizzle[o + j] <<
                            (4 * j); /* 4 bits per swizzle */
                }
 
@@ -917,25 +938,27 @@ read_alu(read_ctx *ctx, union packed_instr header)
    } else {
       for (unsigned i = 0; i < num_srcs; i++) {
          union packed_src src = read_src(ctx, &alu->src[i].src, &alu->instr);
-         unsigned src_components = nir_ssa_alu_instr_src_components(alu, i);
+         unsigned src_channels = nir_ssa_alu_instr_src_components(alu, i);
+         unsigned src_components = nir_src_num_components(alu->src[i].src);
+         bool packed = src_components <= 4 && src_channels <= 4;
 
          alu->src[i].negate = src.alu.negate;
          alu->src[i].abs = src.alu.abs;
 
          memset(&alu->src[i].swizzle, 0, sizeof(alu->src[i].swizzle));
 
-         if (src_components <= 4) {
+         if (packed) {
             alu->src[i].swizzle[0] = src.alu.swizzle_x;
             alu->src[i].swizzle[1] = src.alu.swizzle_y;
             alu->src[i].swizzle[2] = src.alu.swizzle_z;
             alu->src[i].swizzle[3] = src.alu.swizzle_w;
          } else {
             /* Load swizzles for vec8 and vec16. */
-            for (unsigned i = 0; i < src_components; i += 8) {
+            for (unsigned o = 0; o < src_channels; o += 8) {
                unsigned value = blob_read_uint32(ctx->blob);
 
-               for (unsigned j = 0; j < 8 && i + j < src_components; j++) {
-                  alu->src[i].swizzle[i + j] =
+               for (unsigned j = 0; j < 8 && o + j < src_channels; j++) {
+                  alu->src[i].swizzle[o + j] =
                      (value >> (4 * j)) & 0xf; /* 4 bits per swizzle */
                }
             }
@@ -1426,7 +1449,9 @@ union packed_tex_data {
       unsigned is_shadow:1;
       unsigned is_new_style_shadow:1;
       unsigned component:2;
-      unsigned unused:10; /* Mark unused for valgrind. */
+      unsigned texture_non_uniform:1;
+      unsigned sampler_non_uniform:1;
+      unsigned unused:8; /* Mark unused for valgrind. */
    } u;
 };
 
@@ -1461,6 +1486,8 @@ write_tex(write_ctx *ctx, const nir_tex_instr *tex)
       .u.is_shadow = tex->is_shadow,
       .u.is_new_style_shadow = tex->is_new_style_shadow,
       .u.component = tex->component,
+      .u.texture_non_uniform = tex->texture_non_uniform,
+      .u.sampler_non_uniform = tex->sampler_non_uniform,
    };
    blob_write_uint32(ctx->blob, packed.u32);
 
@@ -1495,6 +1522,8 @@ read_tex(read_ctx *ctx, union packed_instr header)
    tex->is_shadow = packed.u.is_shadow;
    tex->is_new_style_shadow = packed.u.is_new_style_shadow;
    tex->component = packed.u.component;
+   tex->texture_non_uniform = packed.u.texture_non_uniform;
+   tex->sampler_non_uniform = packed.u.sampler_non_uniform;
 
    for (unsigned i = 0; i < tex->num_srcs; i++) {
       union packed_src src = read_src(ctx, &tex->src[i].src, &tex->instr);