nir: Make nir_search's dumping go to stderr.
[mesa.git] / src / compiler / nir / nir_serialize.c
index 37699109ab5d9eb30e2bb0527175730665f8cb79..0a953c8daf419a8b8e8e4ed1f4bbe49d3a48c8a4 100644 (file)
@@ -124,7 +124,7 @@ read_constant(read_ctx *ctx, nir_variable *nvar)
 
    blob_copy_bytes(ctx->blob, (uint8_t *)c->values, sizeof(c->values));
    c->num_elements = blob_read_uint32(ctx->blob);
-   c->elements = ralloc_array(ctx->nir, nir_constant *, c->num_elements);
+   c->elements = ralloc_array(nvar, nir_constant *, c->num_elements);
    for (unsigned i = 0; i < c->num_elements; i++)
       c->elements[i] = read_constant(ctx, nvar);
 
@@ -141,8 +141,11 @@ write_variable(write_ctx *ctx, const nir_variable *var)
       blob_write_string(ctx->blob, var->name);
    blob_write_bytes(ctx->blob, (uint8_t *) &var->data, sizeof(var->data));
    blob_write_uint32(ctx->blob, var->num_state_slots);
-   blob_write_bytes(ctx->blob, (uint8_t *) var->state_slots,
-                    var->num_state_slots * sizeof(nir_state_slot));
+   for (unsigned i = 0; i < var->num_state_slots; i++) {
+      for (unsigned j = 0; j < STATE_LENGTH; j++)
+         blob_write_uint32(ctx->blob, var->state_slots[i].tokens[j]);
+      blob_write_uint32(ctx->blob, var->state_slots[i].swizzle);
+   }
    blob_write_uint32(ctx->blob, !!(var->constant_initializer));
    if (var->constant_initializer)
       write_constant(ctx, var->constant_initializer);
@@ -172,9 +175,15 @@ read_variable(read_ctx *ctx)
    }
    blob_copy_bytes(ctx->blob, (uint8_t *) &var->data, sizeof(var->data));
    var->num_state_slots = blob_read_uint32(ctx->blob);
-   var->state_slots = ralloc_array(var, nir_state_slot, var->num_state_slots);
-   blob_copy_bytes(ctx->blob, (uint8_t *) var->state_slots,
-                   var->num_state_slots * sizeof(nir_state_slot));
+   if (var->num_state_slots != 0) {
+      var->state_slots = ralloc_array(var, nir_state_slot,
+                                      var->num_state_slots);
+      for (unsigned i = 0; i < var->num_state_slots; i++) {
+         for (unsigned j = 0; j < STATE_LENGTH; j++)
+            var->state_slots[i].tokens[j] = blob_read_uint32(ctx->blob);
+         var->state_slots[i].swizzle = blob_read_uint32(ctx->blob);
+      }
+   }
    bool has_const_initializer = blob_read_uint32(ctx->blob);
    if (has_const_initializer)
       var->constant_initializer = read_constant(ctx, var);
@@ -227,7 +236,6 @@ write_register(write_ctx *ctx, const nir_register *reg)
    blob_write_uint32(ctx->blob, !!(reg->name));
    if (reg->name)
       blob_write_string(ctx->blob, reg->name);
-   blob_write_uint32(ctx->blob, reg->is_global << 1 | reg->is_packed);
 }
 
 static nir_register *
@@ -246,9 +254,6 @@ read_register(read_ctx *ctx)
    } else {
       reg->name = NULL;
    }
-   unsigned flags = blob_read_uint32(ctx->blob);
-   reg->is_global = flags & 0x2;
-   reg->is_packed = flags & 0x1;
 
    list_inithead(&reg->uses);
    list_inithead(&reg->defs);
@@ -369,88 +374,15 @@ read_dest(read_ctx *ctx, nir_dest *dst, nir_instr *instr)
    }
 }
 
-static void
-write_deref_chain(write_ctx *ctx, const nir_deref_var *deref_var)
-{
-   write_object(ctx, deref_var->var);
-
-   uint32_t len = 0;
-   for (const nir_deref *d = deref_var->deref.child; d; d = d->child)
-      len++;
-   blob_write_uint32(ctx->blob, len);
-
-   for (const nir_deref *d = deref_var->deref.child; d; d = d->child) {
-      blob_write_uint32(ctx->blob, d->deref_type);
-      switch (d->deref_type) {
-      case nir_deref_type_array: {
-         const nir_deref_array *deref_array = nir_deref_as_array(d);
-         blob_write_uint32(ctx->blob, deref_array->deref_array_type);
-         blob_write_uint32(ctx->blob, deref_array->base_offset);
-         if (deref_array->deref_array_type == nir_deref_array_type_indirect)
-            write_src(ctx, &deref_array->indirect);
-         break;
-      }
-      case nir_deref_type_struct: {
-         const nir_deref_struct *deref_struct = nir_deref_as_struct(d);
-         blob_write_uint32(ctx->blob, deref_struct->index);
-         break;
-      }
-      case nir_deref_type_var:
-         unreachable("Invalid deref type");
-      }
-
-      encode_type_to_blob(ctx->blob, d->type);
-   }
-}
-
-static nir_deref_var *
-read_deref_chain(read_ctx *ctx, void *mem_ctx)
-{
-   nir_variable *var = read_object(ctx);
-   nir_deref_var *deref_var = nir_deref_var_create(mem_ctx, var);
-
-   uint32_t len = blob_read_uint32(ctx->blob);
-
-   nir_deref *tail = &deref_var->deref;
-   for (uint32_t i = 0; i < len; i++) {
-      nir_deref_type deref_type = blob_read_uint32(ctx->blob);
-      nir_deref *deref = NULL;
-      switch (deref_type) {
-      case nir_deref_type_array: {
-         nir_deref_array *deref_array = nir_deref_array_create(tail);
-         deref_array->deref_array_type = blob_read_uint32(ctx->blob);
-         deref_array->base_offset = blob_read_uint32(ctx->blob);
-         if (deref_array->deref_array_type == nir_deref_array_type_indirect)
-            read_src(ctx, &deref_array->indirect, mem_ctx);
-         deref = &deref_array->deref;
-         break;
-      }
-      case nir_deref_type_struct: {
-         uint32_t index = blob_read_uint32(ctx->blob);
-         nir_deref_struct *deref_struct = nir_deref_struct_create(tail, index);
-         deref = &deref_struct->deref;
-         break;
-      }
-      case nir_deref_type_var:
-         unreachable("Invalid deref type");
-      }
-
-      deref->type = decode_type_from_blob(ctx->blob);
-
-      tail->child = deref;
-      tail = deref;
-   }
-
-   return deref_var;
-}
-
 static void
 write_alu(write_ctx *ctx, const nir_alu_instr *alu)
 {
    blob_write_uint32(ctx->blob, alu->op);
    uint32_t flags = alu->exact;
-   flags |= alu->dest.saturate << 1;
-   flags |= alu->dest.write_mask << 2;
+   flags |= alu->no_signed_wrap << 1;
+   flags |= alu->no_unsigned_wrap << 2;
+   flags |= alu->dest.saturate << 3;
+   flags |= alu->dest.write_mask << 4;
    blob_write_uint32(ctx->blob, flags);
 
    write_dest(ctx, &alu->dest.dest);
@@ -473,8 +405,10 @@ read_alu(read_ctx *ctx)
 
    uint32_t flags = blob_read_uint32(ctx->blob);
    alu->exact = flags & 1;
-   alu->dest.saturate = flags & 2;
-   alu->dest.write_mask = flags >> 2;
+   alu->no_signed_wrap = flags & 2;
+   alu->no_unsigned_wrap = flags & 4;
+   alu->dest.saturate = flags & 8;
+   alu->dest.write_mask = flags >> 4;
 
    read_dest(ctx, &alu->dest.dest, &alu->instr);
 
@@ -513,11 +447,15 @@ write_deref(write_ctx *ctx, const nir_deref_instr *deref)
       break;
 
    case nir_deref_type_array:
+   case nir_deref_type_ptr_as_array:
       write_src(ctx, &deref->arr.index);
       break;
 
-   case nir_deref_type_array_wildcard:
    case nir_deref_type_cast:
+      blob_write_uint32(ctx->blob, deref->cast.ptr_stride);
+      break;
+
+   case nir_deref_type_array_wildcard:
       /* Nothing to do */
       break;
 
@@ -550,11 +488,15 @@ read_deref(read_ctx *ctx)
       break;
 
    case nir_deref_type_array:
+   case nir_deref_type_ptr_as_array:
       read_src(ctx, &deref->arr.index, &deref->instr);
       break;
 
-   case nir_deref_type_array_wildcard:
    case nir_deref_type_cast:
+      deref->cast.ptr_stride = blob_read_uint32(ctx->blob);
+      break;
+
+   case nir_deref_type_array_wildcard:
       /* Nothing to do */
       break;
 
@@ -570,7 +512,6 @@ write_intrinsic(write_ctx *ctx, const nir_intrinsic_instr *intrin)
 {
    blob_write_uint32(ctx->blob, intrin->intrinsic);
 
-   unsigned num_variables = nir_intrinsic_infos[intrin->intrinsic].num_variables;
    unsigned num_srcs = nir_intrinsic_infos[intrin->intrinsic].num_srcs;
    unsigned num_indices = nir_intrinsic_infos[intrin->intrinsic].num_indices;
 
@@ -579,9 +520,6 @@ write_intrinsic(write_ctx *ctx, const nir_intrinsic_instr *intrin)
    if (nir_intrinsic_infos[intrin->intrinsic].has_dest)
       write_dest(ctx, &intrin->dest);
 
-   for (unsigned i = 0; i < num_variables; i++)
-      write_deref_chain(ctx, intrin->variables[i]);
-
    for (unsigned i = 0; i < num_srcs; i++)
       write_src(ctx, &intrin->src[i]);
 
@@ -596,7 +534,6 @@ read_intrinsic(read_ctx *ctx)
 
    nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(ctx->nir, op);
 
-   unsigned num_variables = nir_intrinsic_infos[op].num_variables;
    unsigned num_srcs = nir_intrinsic_infos[op].num_srcs;
    unsigned num_indices = nir_intrinsic_infos[op].num_indices;
 
@@ -605,9 +542,6 @@ read_intrinsic(read_ctx *ctx)
    if (nir_intrinsic_infos[op].has_dest)
       read_dest(ctx, &intrin->dest, &intrin->instr);
 
-   for (unsigned i = 0; i < num_variables; i++)
-      intrin->variables[i] = read_deref_chain(ctx, &intrin->instr);
-
    for (unsigned i = 0; i < num_srcs; i++)
       read_src(ctx, &intrin->src[i], &intrin->instr);
 
@@ -623,7 +557,7 @@ write_load_const(write_ctx *ctx, const nir_load_const_instr *lc)
    uint32_t val = lc->def.num_components;
    val |= lc->def.bit_size << 3;
    blob_write_uint32(ctx->blob, val);
-   blob_write_bytes(ctx->blob, (uint8_t *) &lc->value, sizeof(lc->value));
+   blob_write_bytes(ctx->blob, lc->value, sizeof(*lc->value) * lc->def.num_components);
    write_add_object(ctx, &lc->def);
 }
 
@@ -635,7 +569,7 @@ read_load_const(read_ctx *ctx)
    nir_load_const_instr *lc =
       nir_load_const_instr_create(ctx->nir, val & 0x7, val >> 3);
 
-   blob_copy_bytes(ctx->blob, (uint8_t *) &lc->value, sizeof(lc->value));
+   blob_copy_bytes(ctx->blob, lc->value, sizeof(*lc->value) * lc->def.num_components);
    read_add_object(ctx, &lc->def);
    return lc;
 }
@@ -671,8 +605,6 @@ union packed_tex_data {
       unsigned is_shadow:1;
       unsigned is_new_style_shadow:1;
       unsigned component:2;
-      unsigned has_texture_deref:1;
-      unsigned has_sampler_deref:1;
       unsigned unused:10; /* Mark unused for valgrind. */
    } u;
 };
@@ -685,6 +617,7 @@ write_tex(write_ctx *ctx, const nir_tex_instr *tex)
    blob_write_uint32(ctx->blob, tex->texture_index);
    blob_write_uint32(ctx->blob, tex->texture_array_size);
    blob_write_uint32(ctx->blob, tex->sampler_index);
+   blob_write_bytes(ctx->blob, tex->tg4_offsets, sizeof(tex->tg4_offsets));
 
    STATIC_ASSERT(sizeof(union packed_tex_data) == sizeof(uint32_t));
    union packed_tex_data packed = {
@@ -695,8 +628,6 @@ 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.has_texture_deref = tex->texture != NULL,
-      .u.has_sampler_deref = tex->sampler != NULL,
    };
    blob_write_uint32(ctx->blob, packed.u32);
 
@@ -705,11 +636,6 @@ write_tex(write_ctx *ctx, const nir_tex_instr *tex)
       blob_write_uint32(ctx->blob, tex->src[i].src_type);
       write_src(ctx, &tex->src[i].src);
    }
-
-   if (tex->texture)
-      write_deref_chain(ctx, tex->texture);
-   if (tex->sampler)
-      write_deref_chain(ctx, tex->sampler);
 }
 
 static nir_tex_instr *
@@ -722,6 +648,7 @@ read_tex(read_ctx *ctx)
    tex->texture_index = blob_read_uint32(ctx->blob);
    tex->texture_array_size = blob_read_uint32(ctx->blob);
    tex->sampler_index = blob_read_uint32(ctx->blob);
+   blob_copy_bytes(ctx->blob, tex->tg4_offsets, sizeof(tex->tg4_offsets));
 
    union packed_tex_data packed;
    packed.u32 = blob_read_uint32(ctx->blob);
@@ -739,11 +666,6 @@ read_tex(read_ctx *ctx)
       read_src(ctx, &tex->src[i].src, &tex->instr);
    }
 
-   tex->texture = packed.u.has_texture_deref ?
-                  read_deref_chain(ctx, &tex->instr) : NULL;
-   tex->sampler = packed.u.has_sampler_deref ?
-                  read_deref_chain(ctx, &tex->instr) : NULL;
-
    return tex;
 }
 
@@ -762,7 +684,7 @@ write_phi(write_ctx *ctx, const nir_phi_instr *phi)
    nir_foreach_phi_src(src, phi) {
       assert(src->src.is_ssa);
       size_t blob_offset = blob_reserve_intptr(ctx->blob);
-      MAYBE_UNUSED size_t blob_offset2 = blob_reserve_intptr(ctx->blob);
+      ASSERTED size_t blob_offset2 = blob_reserve_intptr(ctx->blob);
       assert(blob_offset + sizeof(uintptr_t) == blob_offset2);
       write_phi_fixup fixup = {
          .blob_offset = blob_offset,
@@ -1137,6 +1059,8 @@ write_function(write_ctx *ctx, const nir_function *fxn)
       blob_write_uint32(ctx->blob, val);
    }
 
+   blob_write_uint32(ctx->blob, fxn->is_entrypoint);
+
    /* At first glance, it looks like we should write the function_impl here.
     * However, call instructions need to be able to reference at least the
     * function and those will get processed as we write the function_impls.
@@ -1161,14 +1085,15 @@ read_function(read_ctx *ctx)
       fxn->params[i].num_components = val & 0xff;
       fxn->params[i].bit_size = (val >> 8) & 0xff;
    }
+
+   fxn->is_entrypoint = blob_read_uint32(ctx->blob);
 }
 
 void
 nir_serialize(struct blob *blob, const nir_shader *nir)
 {
    write_ctx ctx;
-   ctx.remap_table = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
-                                             _mesa_key_pointer_equal);
+   ctx.remap_table = _mesa_pointer_hash_table_create(NULL);
    ctx.next_idx = 0;
    ctx.blob = blob;
    ctx.nir = nir;
@@ -1197,13 +1122,11 @@ nir_serialize(struct blob *blob, const nir_shader *nir)
    write_var_list(&ctx, &nir->globals);
    write_var_list(&ctx, &nir->system_values);
 
-   write_reg_list(&ctx, &nir->registers);
-   blob_write_uint32(blob, nir->reg_alloc);
    blob_write_uint32(blob, nir->num_inputs);
    blob_write_uint32(blob, nir->num_uniforms);
    blob_write_uint32(blob, nir->num_outputs);
    blob_write_uint32(blob, nir->num_shared);
-   blob_write_uint32(blob, nir->lowered_derefs);
+   blob_write_uint32(blob, nir->scratch_size);
 
    blob_write_uint32(blob, exec_list_length(&nir->functions));
    nir_foreach_function(fxn, nir) {
@@ -1214,6 +1137,10 @@ nir_serialize(struct blob *blob, const nir_shader *nir)
       write_function_impl(&ctx, fxn->impl);
    }
 
+   blob_write_uint32(blob, nir->constant_data_size);
+   if (nir->constant_data_size > 0)
+      blob_write_bytes(blob, nir->constant_data, nir->constant_data_size);
+
    *(uintptr_t *)(blob->data + idx_size_offset) = ctx.next_idx;
 
    _mesa_hash_table_destroy(ctx.remap_table, NULL);
@@ -1253,13 +1180,11 @@ nir_deserialize(void *mem_ctx,
    read_var_list(&ctx, &ctx.nir->globals);
    read_var_list(&ctx, &ctx.nir->system_values);
 
-   read_reg_list(&ctx, &ctx.nir->registers);
-   ctx.nir->reg_alloc = blob_read_uint32(blob);
    ctx.nir->num_inputs = blob_read_uint32(blob);
    ctx.nir->num_uniforms = blob_read_uint32(blob);
    ctx.nir->num_outputs = blob_read_uint32(blob);
    ctx.nir->num_shared = blob_read_uint32(blob);
-   ctx.nir->lowered_derefs = blob_read_uint32(blob);
+   ctx.nir->scratch_size = blob_read_uint32(blob);
 
    unsigned num_functions = blob_read_uint32(blob);
    for (unsigned i = 0; i < num_functions; i++)
@@ -1268,26 +1193,41 @@ nir_deserialize(void *mem_ctx,
    nir_foreach_function(fxn, ctx.nir)
       fxn->impl = read_function_impl(&ctx, fxn);
 
+   ctx.nir->constant_data_size = blob_read_uint32(blob);
+   if (ctx.nir->constant_data_size > 0) {
+      ctx.nir->constant_data =
+         ralloc_size(ctx.nir, ctx.nir->constant_data_size);
+      blob_copy_bytes(blob, ctx.nir->constant_data,
+                      ctx.nir->constant_data_size);
+   }
+
    free(ctx.idx_table);
 
    return ctx.nir;
 }
 
-nir_shader *
-nir_shader_serialize_deserialize(void *mem_ctx, nir_shader *s)
+void
+nir_shader_serialize_deserialize(nir_shader *shader)
 {
-   const struct nir_shader_compiler_options *options = s->options;
+   const struct nir_shader_compiler_options *options = shader->options;
 
    struct blob writer;
    blob_init(&writer);
-   nir_serialize(&writer, s);
-   ralloc_free(s);
+   nir_serialize(&writer, shader);
+
+   /* Delete all of dest's ralloc children but leave dest alone */
+   void *dead_ctx = ralloc_context(NULL);
+   ralloc_adopt(dead_ctx, shader);
+   ralloc_free(dead_ctx);
+
+   dead_ctx = ralloc_context(NULL);
 
    struct blob_reader reader;
    blob_reader_init(&reader, writer.data, writer.size);
-   nir_shader *ns = nir_deserialize(mem_ctx, options, &reader);
+   nir_shader *copy = nir_deserialize(dead_ctx, options, &reader);
 
    blob_finish(&writer);
 
-   return ns;
+   nir_shader_replace(shader, copy);
+   ralloc_free(dead_ctx);
 }