nir_serialize.c revision 01e04c3f
1/* 2 * Copyright © 2017 Connor Abbott 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "nir_serialize.h" 25#include "nir_control_flow.h" 26#include "util/u_dynarray.h" 27 28typedef struct { 29 size_t blob_offset; 30 nir_ssa_def *src; 31 nir_block *block; 32} write_phi_fixup; 33 34typedef struct { 35 const nir_shader *nir; 36 37 struct blob *blob; 38 39 /* maps pointer to index */ 40 struct hash_table *remap_table; 41 42 /* the next index to assign to a NIR in-memory object */ 43 uintptr_t next_idx; 44 45 /* Array of write_phi_fixup structs representing phi sources that need to 46 * be resolved in the second pass. 47 */ 48 struct util_dynarray phi_fixups; 49} write_ctx; 50 51typedef struct { 52 nir_shader *nir; 53 54 struct blob_reader *blob; 55 56 /* the next index to assign to a NIR in-memory object */ 57 uintptr_t next_idx; 58 59 /* The length of the index -> object table */ 60 uintptr_t idx_table_len; 61 62 /* map from index to deserialized pointer */ 63 void **idx_table; 64 65 /* List of phi sources. */ 66 struct list_head phi_srcs; 67 68} read_ctx; 69 70static void 71write_add_object(write_ctx *ctx, const void *obj) 72{ 73 uintptr_t index = ctx->next_idx++; 74 _mesa_hash_table_insert(ctx->remap_table, obj, (void *) index); 75} 76 77static uintptr_t 78write_lookup_object(write_ctx *ctx, const void *obj) 79{ 80 struct hash_entry *entry = _mesa_hash_table_search(ctx->remap_table, obj); 81 assert(entry); 82 return (uintptr_t) entry->data; 83} 84 85static void 86write_object(write_ctx *ctx, const void *obj) 87{ 88 blob_write_intptr(ctx->blob, write_lookup_object(ctx, obj)); 89} 90 91static void 92read_add_object(read_ctx *ctx, void *obj) 93{ 94 assert(ctx->next_idx < ctx->idx_table_len); 95 ctx->idx_table[ctx->next_idx++] = obj; 96} 97 98static void * 99read_lookup_object(read_ctx *ctx, uintptr_t idx) 100{ 101 assert(idx < ctx->idx_table_len); 102 return ctx->idx_table[idx]; 103} 104 105static void * 106read_object(read_ctx *ctx) 107{ 108 return read_lookup_object(ctx, blob_read_intptr(ctx->blob)); 109} 110 111static void 112write_constant(write_ctx *ctx, const nir_constant *c) 113{ 114 blob_write_bytes(ctx->blob, c->values, sizeof(c->values)); 115 blob_write_uint32(ctx->blob, c->num_elements); 116 for (unsigned i = 0; i < c->num_elements; i++) 117 write_constant(ctx, c->elements[i]); 118} 119 120static nir_constant * 121read_constant(read_ctx *ctx, nir_variable *nvar) 122{ 123 nir_constant *c = ralloc(nvar, nir_constant); 124 125 blob_copy_bytes(ctx->blob, (uint8_t *)c->values, sizeof(c->values)); 126 c->num_elements = blob_read_uint32(ctx->blob); 127 c->elements = ralloc_array(nvar, nir_constant *, c->num_elements); 128 for (unsigned i = 0; i < c->num_elements; i++) 129 c->elements[i] = read_constant(ctx, nvar); 130 131 return c; 132} 133 134static void 135write_variable(write_ctx *ctx, const nir_variable *var) 136{ 137 write_add_object(ctx, var); 138 encode_type_to_blob(ctx->blob, var->type); 139 blob_write_uint32(ctx->blob, !!(var->name)); 140 if (var->name) 141 blob_write_string(ctx->blob, var->name); 142 blob_write_bytes(ctx->blob, (uint8_t *) &var->data, sizeof(var->data)); 143 blob_write_uint32(ctx->blob, var->num_state_slots); 144 blob_write_bytes(ctx->blob, (uint8_t *) var->state_slots, 145 var->num_state_slots * sizeof(nir_state_slot)); 146 blob_write_uint32(ctx->blob, !!(var->constant_initializer)); 147 if (var->constant_initializer) 148 write_constant(ctx, var->constant_initializer); 149 blob_write_uint32(ctx->blob, !!(var->interface_type)); 150 if (var->interface_type) 151 encode_type_to_blob(ctx->blob, var->interface_type); 152 blob_write_uint32(ctx->blob, var->num_members); 153 if (var->num_members > 0) { 154 blob_write_bytes(ctx->blob, (uint8_t *) var->members, 155 var->num_members * sizeof(*var->members)); 156 } 157} 158 159static nir_variable * 160read_variable(read_ctx *ctx) 161{ 162 nir_variable *var = rzalloc(ctx->nir, nir_variable); 163 read_add_object(ctx, var); 164 165 var->type = decode_type_from_blob(ctx->blob); 166 bool has_name = blob_read_uint32(ctx->blob); 167 if (has_name) { 168 const char *name = blob_read_string(ctx->blob); 169 var->name = ralloc_strdup(var, name); 170 } else { 171 var->name = NULL; 172 } 173 blob_copy_bytes(ctx->blob, (uint8_t *) &var->data, sizeof(var->data)); 174 var->num_state_slots = blob_read_uint32(ctx->blob); 175 var->state_slots = ralloc_array(var, nir_state_slot, var->num_state_slots); 176 blob_copy_bytes(ctx->blob, (uint8_t *) var->state_slots, 177 var->num_state_slots * sizeof(nir_state_slot)); 178 bool has_const_initializer = blob_read_uint32(ctx->blob); 179 if (has_const_initializer) 180 var->constant_initializer = read_constant(ctx, var); 181 else 182 var->constant_initializer = NULL; 183 bool has_interface_type = blob_read_uint32(ctx->blob); 184 if (has_interface_type) 185 var->interface_type = decode_type_from_blob(ctx->blob); 186 else 187 var->interface_type = NULL; 188 var->num_members = blob_read_uint32(ctx->blob); 189 if (var->num_members > 0) { 190 var->members = ralloc_array(var, struct nir_variable_data, 191 var->num_members); 192 blob_copy_bytes(ctx->blob, (uint8_t *) var->members, 193 var->num_members * sizeof(*var->members)); 194 } 195 196 return var; 197} 198 199static void 200write_var_list(write_ctx *ctx, const struct exec_list *src) 201{ 202 blob_write_uint32(ctx->blob, exec_list_length(src)); 203 foreach_list_typed(nir_variable, var, node, src) { 204 write_variable(ctx, var); 205 } 206} 207 208static void 209read_var_list(read_ctx *ctx, struct exec_list *dst) 210{ 211 exec_list_make_empty(dst); 212 unsigned num_vars = blob_read_uint32(ctx->blob); 213 for (unsigned i = 0; i < num_vars; i++) { 214 nir_variable *var = read_variable(ctx); 215 exec_list_push_tail(dst, &var->node); 216 } 217} 218 219static void 220write_register(write_ctx *ctx, const nir_register *reg) 221{ 222 write_add_object(ctx, reg); 223 blob_write_uint32(ctx->blob, reg->num_components); 224 blob_write_uint32(ctx->blob, reg->bit_size); 225 blob_write_uint32(ctx->blob, reg->num_array_elems); 226 blob_write_uint32(ctx->blob, reg->index); 227 blob_write_uint32(ctx->blob, !!(reg->name)); 228 if (reg->name) 229 blob_write_string(ctx->blob, reg->name); 230 blob_write_uint32(ctx->blob, reg->is_global << 1 | reg->is_packed); 231} 232 233static nir_register * 234read_register(read_ctx *ctx) 235{ 236 nir_register *reg = ralloc(ctx->nir, nir_register); 237 read_add_object(ctx, reg); 238 reg->num_components = blob_read_uint32(ctx->blob); 239 reg->bit_size = blob_read_uint32(ctx->blob); 240 reg->num_array_elems = blob_read_uint32(ctx->blob); 241 reg->index = blob_read_uint32(ctx->blob); 242 bool has_name = blob_read_uint32(ctx->blob); 243 if (has_name) { 244 const char *name = blob_read_string(ctx->blob); 245 reg->name = ralloc_strdup(reg, name); 246 } else { 247 reg->name = NULL; 248 } 249 unsigned flags = blob_read_uint32(ctx->blob); 250 reg->is_global = flags & 0x2; 251 reg->is_packed = flags & 0x1; 252 253 list_inithead(®->uses); 254 list_inithead(®->defs); 255 list_inithead(®->if_uses); 256 257 return reg; 258} 259 260static void 261write_reg_list(write_ctx *ctx, const struct exec_list *src) 262{ 263 blob_write_uint32(ctx->blob, exec_list_length(src)); 264 foreach_list_typed(nir_register, reg, node, src) 265 write_register(ctx, reg); 266} 267 268static void 269read_reg_list(read_ctx *ctx, struct exec_list *dst) 270{ 271 exec_list_make_empty(dst); 272 unsigned num_regs = blob_read_uint32(ctx->blob); 273 for (unsigned i = 0; i < num_regs; i++) { 274 nir_register *reg = read_register(ctx); 275 exec_list_push_tail(dst, ®->node); 276 } 277} 278 279static void 280write_src(write_ctx *ctx, const nir_src *src) 281{ 282 /* Since sources are very frequent, we try to save some space when storing 283 * them. In particular, we store whether the source is a register and 284 * whether the register has an indirect index in the low two bits. We can 285 * assume that the high two bits of the index are zero, since otherwise our 286 * address space would've been exhausted allocating the remap table! 287 */ 288 if (src->is_ssa) { 289 uintptr_t idx = write_lookup_object(ctx, src->ssa) << 2; 290 idx |= 1; 291 blob_write_intptr(ctx->blob, idx); 292 } else { 293 uintptr_t idx = write_lookup_object(ctx, src->reg.reg) << 2; 294 if (src->reg.indirect) 295 idx |= 2; 296 blob_write_intptr(ctx->blob, idx); 297 blob_write_uint32(ctx->blob, src->reg.base_offset); 298 if (src->reg.indirect) { 299 write_src(ctx, src->reg.indirect); 300 } 301 } 302} 303 304static void 305read_src(read_ctx *ctx, nir_src *src, void *mem_ctx) 306{ 307 uintptr_t val = blob_read_intptr(ctx->blob); 308 uintptr_t idx = val >> 2; 309 src->is_ssa = val & 0x1; 310 if (src->is_ssa) { 311 src->ssa = read_lookup_object(ctx, idx); 312 } else { 313 bool is_indirect = val & 0x2; 314 src->reg.reg = read_lookup_object(ctx, idx); 315 src->reg.base_offset = blob_read_uint32(ctx->blob); 316 if (is_indirect) { 317 src->reg.indirect = ralloc(mem_ctx, nir_src); 318 read_src(ctx, src->reg.indirect, mem_ctx); 319 } else { 320 src->reg.indirect = NULL; 321 } 322 } 323} 324 325static void 326write_dest(write_ctx *ctx, const nir_dest *dst) 327{ 328 uint32_t val = dst->is_ssa; 329 if (dst->is_ssa) { 330 val |= !!(dst->ssa.name) << 1; 331 val |= dst->ssa.num_components << 2; 332 val |= dst->ssa.bit_size << 5; 333 } else { 334 val |= !!(dst->reg.indirect) << 1; 335 } 336 blob_write_uint32(ctx->blob, val); 337 if (dst->is_ssa) { 338 write_add_object(ctx, &dst->ssa); 339 if (dst->ssa.name) 340 blob_write_string(ctx->blob, dst->ssa.name); 341 } else { 342 blob_write_intptr(ctx->blob, write_lookup_object(ctx, dst->reg.reg)); 343 blob_write_uint32(ctx->blob, dst->reg.base_offset); 344 if (dst->reg.indirect) 345 write_src(ctx, dst->reg.indirect); 346 } 347} 348 349static void 350read_dest(read_ctx *ctx, nir_dest *dst, nir_instr *instr) 351{ 352 uint32_t val = blob_read_uint32(ctx->blob); 353 bool is_ssa = val & 0x1; 354 if (is_ssa) { 355 bool has_name = val & 0x2; 356 unsigned num_components = (val >> 2) & 0x7; 357 unsigned bit_size = val >> 5; 358 char *name = has_name ? blob_read_string(ctx->blob) : NULL; 359 nir_ssa_dest_init(instr, dst, num_components, bit_size, name); 360 read_add_object(ctx, &dst->ssa); 361 } else { 362 bool is_indirect = val & 0x2; 363 dst->reg.reg = read_object(ctx); 364 dst->reg.base_offset = blob_read_uint32(ctx->blob); 365 if (is_indirect) { 366 dst->reg.indirect = ralloc(instr, nir_src); 367 read_src(ctx, dst->reg.indirect, instr); 368 } 369 } 370} 371 372static void 373write_alu(write_ctx *ctx, const nir_alu_instr *alu) 374{ 375 blob_write_uint32(ctx->blob, alu->op); 376 uint32_t flags = alu->exact; 377 flags |= alu->dest.saturate << 1; 378 flags |= alu->dest.write_mask << 2; 379 blob_write_uint32(ctx->blob, flags); 380 381 write_dest(ctx, &alu->dest.dest); 382 383 for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++) { 384 write_src(ctx, &alu->src[i].src); 385 flags = alu->src[i].negate; 386 flags |= alu->src[i].abs << 1; 387 for (unsigned j = 0; j < 4; j++) 388 flags |= alu->src[i].swizzle[j] << (2 + 2 * j); 389 blob_write_uint32(ctx->blob, flags); 390 } 391} 392 393static nir_alu_instr * 394read_alu(read_ctx *ctx) 395{ 396 nir_op op = blob_read_uint32(ctx->blob); 397 nir_alu_instr *alu = nir_alu_instr_create(ctx->nir, op); 398 399 uint32_t flags = blob_read_uint32(ctx->blob); 400 alu->exact = flags & 1; 401 alu->dest.saturate = flags & 2; 402 alu->dest.write_mask = flags >> 2; 403 404 read_dest(ctx, &alu->dest.dest, &alu->instr); 405 406 for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++) { 407 read_src(ctx, &alu->src[i].src, &alu->instr); 408 flags = blob_read_uint32(ctx->blob); 409 alu->src[i].negate = flags & 1; 410 alu->src[i].abs = flags & 2; 411 for (unsigned j = 0; j < 4; j++) 412 alu->src[i].swizzle[j] = (flags >> (2 * j + 2)) & 3; 413 } 414 415 return alu; 416} 417 418static void 419write_deref(write_ctx *ctx, const nir_deref_instr *deref) 420{ 421 blob_write_uint32(ctx->blob, deref->deref_type); 422 423 blob_write_uint32(ctx->blob, deref->mode); 424 encode_type_to_blob(ctx->blob, deref->type); 425 426 write_dest(ctx, &deref->dest); 427 428 if (deref->deref_type == nir_deref_type_var) { 429 write_object(ctx, deref->var); 430 return; 431 } 432 433 write_src(ctx, &deref->parent); 434 435 switch (deref->deref_type) { 436 case nir_deref_type_struct: 437 blob_write_uint32(ctx->blob, deref->strct.index); 438 break; 439 440 case nir_deref_type_array: 441 write_src(ctx, &deref->arr.index); 442 break; 443 444 case nir_deref_type_array_wildcard: 445 case nir_deref_type_cast: 446 /* Nothing to do */ 447 break; 448 449 default: 450 unreachable("Invalid deref type"); 451 } 452} 453 454static nir_deref_instr * 455read_deref(read_ctx *ctx) 456{ 457 nir_deref_type deref_type = blob_read_uint32(ctx->blob); 458 nir_deref_instr *deref = nir_deref_instr_create(ctx->nir, deref_type); 459 460 deref->mode = blob_read_uint32(ctx->blob); 461 deref->type = decode_type_from_blob(ctx->blob); 462 463 read_dest(ctx, &deref->dest, &deref->instr); 464 465 if (deref_type == nir_deref_type_var) { 466 deref->var = read_object(ctx); 467 return deref; 468 } 469 470 read_src(ctx, &deref->parent, &deref->instr); 471 472 switch (deref->deref_type) { 473 case nir_deref_type_struct: 474 deref->strct.index = blob_read_uint32(ctx->blob); 475 break; 476 477 case nir_deref_type_array: 478 read_src(ctx, &deref->arr.index, &deref->instr); 479 break; 480 481 case nir_deref_type_array_wildcard: 482 case nir_deref_type_cast: 483 /* Nothing to do */ 484 break; 485 486 default: 487 unreachable("Invalid deref type"); 488 } 489 490 return deref; 491} 492 493static void 494write_intrinsic(write_ctx *ctx, const nir_intrinsic_instr *intrin) 495{ 496 blob_write_uint32(ctx->blob, intrin->intrinsic); 497 498 unsigned num_srcs = nir_intrinsic_infos[intrin->intrinsic].num_srcs; 499 unsigned num_indices = nir_intrinsic_infos[intrin->intrinsic].num_indices; 500 501 blob_write_uint32(ctx->blob, intrin->num_components); 502 503 if (nir_intrinsic_infos[intrin->intrinsic].has_dest) 504 write_dest(ctx, &intrin->dest); 505 506 for (unsigned i = 0; i < num_srcs; i++) 507 write_src(ctx, &intrin->src[i]); 508 509 for (unsigned i = 0; i < num_indices; i++) 510 blob_write_uint32(ctx->blob, intrin->const_index[i]); 511} 512 513static nir_intrinsic_instr * 514read_intrinsic(read_ctx *ctx) 515{ 516 nir_intrinsic_op op = blob_read_uint32(ctx->blob); 517 518 nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(ctx->nir, op); 519 520 unsigned num_srcs = nir_intrinsic_infos[op].num_srcs; 521 unsigned num_indices = nir_intrinsic_infos[op].num_indices; 522 523 intrin->num_components = blob_read_uint32(ctx->blob); 524 525 if (nir_intrinsic_infos[op].has_dest) 526 read_dest(ctx, &intrin->dest, &intrin->instr); 527 528 for (unsigned i = 0; i < num_srcs; i++) 529 read_src(ctx, &intrin->src[i], &intrin->instr); 530 531 for (unsigned i = 0; i < num_indices; i++) 532 intrin->const_index[i] = blob_read_uint32(ctx->blob); 533 534 return intrin; 535} 536 537static void 538write_load_const(write_ctx *ctx, const nir_load_const_instr *lc) 539{ 540 uint32_t val = lc->def.num_components; 541 val |= lc->def.bit_size << 3; 542 blob_write_uint32(ctx->blob, val); 543 blob_write_bytes(ctx->blob, (uint8_t *) &lc->value, sizeof(lc->value)); 544 write_add_object(ctx, &lc->def); 545} 546 547static nir_load_const_instr * 548read_load_const(read_ctx *ctx) 549{ 550 uint32_t val = blob_read_uint32(ctx->blob); 551 552 nir_load_const_instr *lc = 553 nir_load_const_instr_create(ctx->nir, val & 0x7, val >> 3); 554 555 blob_copy_bytes(ctx->blob, (uint8_t *) &lc->value, sizeof(lc->value)); 556 read_add_object(ctx, &lc->def); 557 return lc; 558} 559 560static void 561write_ssa_undef(write_ctx *ctx, const nir_ssa_undef_instr *undef) 562{ 563 uint32_t val = undef->def.num_components; 564 val |= undef->def.bit_size << 3; 565 blob_write_uint32(ctx->blob, val); 566 write_add_object(ctx, &undef->def); 567} 568 569static nir_ssa_undef_instr * 570read_ssa_undef(read_ctx *ctx) 571{ 572 uint32_t val = blob_read_uint32(ctx->blob); 573 574 nir_ssa_undef_instr *undef = 575 nir_ssa_undef_instr_create(ctx->nir, val & 0x7, val >> 3); 576 577 read_add_object(ctx, &undef->def); 578 return undef; 579} 580 581union packed_tex_data { 582 uint32_t u32; 583 struct { 584 enum glsl_sampler_dim sampler_dim:4; 585 nir_alu_type dest_type:8; 586 unsigned coord_components:3; 587 unsigned is_array:1; 588 unsigned is_shadow:1; 589 unsigned is_new_style_shadow:1; 590 unsigned component:2; 591 unsigned unused:10; /* Mark unused for valgrind. */ 592 } u; 593}; 594 595static void 596write_tex(write_ctx *ctx, const nir_tex_instr *tex) 597{ 598 blob_write_uint32(ctx->blob, tex->num_srcs); 599 blob_write_uint32(ctx->blob, tex->op); 600 blob_write_uint32(ctx->blob, tex->texture_index); 601 blob_write_uint32(ctx->blob, tex->texture_array_size); 602 blob_write_uint32(ctx->blob, tex->sampler_index); 603 604 STATIC_ASSERT(sizeof(union packed_tex_data) == sizeof(uint32_t)); 605 union packed_tex_data packed = { 606 .u.sampler_dim = tex->sampler_dim, 607 .u.dest_type = tex->dest_type, 608 .u.coord_components = tex->coord_components, 609 .u.is_array = tex->is_array, 610 .u.is_shadow = tex->is_shadow, 611 .u.is_new_style_shadow = tex->is_new_style_shadow, 612 .u.component = tex->component, 613 }; 614 blob_write_uint32(ctx->blob, packed.u32); 615 616 write_dest(ctx, &tex->dest); 617 for (unsigned i = 0; i < tex->num_srcs; i++) { 618 blob_write_uint32(ctx->blob, tex->src[i].src_type); 619 write_src(ctx, &tex->src[i].src); 620 } 621} 622 623static nir_tex_instr * 624read_tex(read_ctx *ctx) 625{ 626 unsigned num_srcs = blob_read_uint32(ctx->blob); 627 nir_tex_instr *tex = nir_tex_instr_create(ctx->nir, num_srcs); 628 629 tex->op = blob_read_uint32(ctx->blob); 630 tex->texture_index = blob_read_uint32(ctx->blob); 631 tex->texture_array_size = blob_read_uint32(ctx->blob); 632 tex->sampler_index = blob_read_uint32(ctx->blob); 633 634 union packed_tex_data packed; 635 packed.u32 = blob_read_uint32(ctx->blob); 636 tex->sampler_dim = packed.u.sampler_dim; 637 tex->dest_type = packed.u.dest_type; 638 tex->coord_components = packed.u.coord_components; 639 tex->is_array = packed.u.is_array; 640 tex->is_shadow = packed.u.is_shadow; 641 tex->is_new_style_shadow = packed.u.is_new_style_shadow; 642 tex->component = packed.u.component; 643 644 read_dest(ctx, &tex->dest, &tex->instr); 645 for (unsigned i = 0; i < tex->num_srcs; i++) { 646 tex->src[i].src_type = blob_read_uint32(ctx->blob); 647 read_src(ctx, &tex->src[i].src, &tex->instr); 648 } 649 650 return tex; 651} 652 653static void 654write_phi(write_ctx *ctx, const nir_phi_instr *phi) 655{ 656 /* Phi nodes are special, since they may reference SSA definitions and 657 * basic blocks that don't exist yet. We leave two empty uintptr_t's here, 658 * and then store enough information so that a later fixup pass can fill 659 * them in correctly. 660 */ 661 write_dest(ctx, &phi->dest); 662 663 blob_write_uint32(ctx->blob, exec_list_length(&phi->srcs)); 664 665 nir_foreach_phi_src(src, phi) { 666 assert(src->src.is_ssa); 667 size_t blob_offset = blob_reserve_intptr(ctx->blob); 668 MAYBE_UNUSED size_t blob_offset2 = blob_reserve_intptr(ctx->blob); 669 assert(blob_offset + sizeof(uintptr_t) == blob_offset2); 670 write_phi_fixup fixup = { 671 .blob_offset = blob_offset, 672 .src = src->src.ssa, 673 .block = src->pred, 674 }; 675 util_dynarray_append(&ctx->phi_fixups, write_phi_fixup, fixup); 676 } 677} 678 679static void 680write_fixup_phis(write_ctx *ctx) 681{ 682 util_dynarray_foreach(&ctx->phi_fixups, write_phi_fixup, fixup) { 683 uintptr_t *blob_ptr = (uintptr_t *)(ctx->blob->data + fixup->blob_offset); 684 blob_ptr[0] = write_lookup_object(ctx, fixup->src); 685 blob_ptr[1] = write_lookup_object(ctx, fixup->block); 686 } 687 688 util_dynarray_clear(&ctx->phi_fixups); 689} 690 691static nir_phi_instr * 692read_phi(read_ctx *ctx, nir_block *blk) 693{ 694 nir_phi_instr *phi = nir_phi_instr_create(ctx->nir); 695 696 read_dest(ctx, &phi->dest, &phi->instr); 697 698 unsigned num_srcs = blob_read_uint32(ctx->blob); 699 700 /* For similar reasons as before, we just store the index directly into the 701 * pointer, and let a later pass resolve the phi sources. 702 * 703 * In order to ensure that the copied sources (which are just the indices 704 * from the blob for now) don't get inserted into the old shader's use-def 705 * lists, we have to add the phi instruction *before* we set up its 706 * sources. 707 */ 708 nir_instr_insert_after_block(blk, &phi->instr); 709 710 for (unsigned i = 0; i < num_srcs; i++) { 711 nir_phi_src *src = ralloc(phi, nir_phi_src); 712 713 src->src.is_ssa = true; 714 src->src.ssa = (nir_ssa_def *) blob_read_intptr(ctx->blob); 715 src->pred = (nir_block *) blob_read_intptr(ctx->blob); 716 717 /* Since we're not letting nir_insert_instr handle use/def stuff for us, 718 * we have to set the parent_instr manually. It doesn't really matter 719 * when we do it, so we might as well do it here. 720 */ 721 src->src.parent_instr = &phi->instr; 722 723 /* Stash it in the list of phi sources. We'll walk this list and fix up 724 * sources at the very end of read_function_impl. 725 */ 726 list_add(&src->src.use_link, &ctx->phi_srcs); 727 728 exec_list_push_tail(&phi->srcs, &src->node); 729 } 730 731 return phi; 732} 733 734static void 735read_fixup_phis(read_ctx *ctx) 736{ 737 list_for_each_entry_safe(nir_phi_src, src, &ctx->phi_srcs, src.use_link) { 738 src->pred = read_lookup_object(ctx, (uintptr_t)src->pred); 739 src->src.ssa = read_lookup_object(ctx, (uintptr_t)src->src.ssa); 740 741 /* Remove from this list */ 742 list_del(&src->src.use_link); 743 744 list_addtail(&src->src.use_link, &src->src.ssa->uses); 745 } 746 assert(list_empty(&ctx->phi_srcs)); 747} 748 749static void 750write_jump(write_ctx *ctx, const nir_jump_instr *jmp) 751{ 752 blob_write_uint32(ctx->blob, jmp->type); 753} 754 755static nir_jump_instr * 756read_jump(read_ctx *ctx) 757{ 758 nir_jump_type type = blob_read_uint32(ctx->blob); 759 nir_jump_instr *jmp = nir_jump_instr_create(ctx->nir, type); 760 return jmp; 761} 762 763static void 764write_call(write_ctx *ctx, const nir_call_instr *call) 765{ 766 blob_write_intptr(ctx->blob, write_lookup_object(ctx, call->callee)); 767 768 for (unsigned i = 0; i < call->num_params; i++) 769 write_src(ctx, &call->params[i]); 770} 771 772static nir_call_instr * 773read_call(read_ctx *ctx) 774{ 775 nir_function *callee = read_object(ctx); 776 nir_call_instr *call = nir_call_instr_create(ctx->nir, callee); 777 778 for (unsigned i = 0; i < call->num_params; i++) 779 read_src(ctx, &call->params[i], call); 780 781 return call; 782} 783 784static void 785write_instr(write_ctx *ctx, const nir_instr *instr) 786{ 787 blob_write_uint32(ctx->blob, instr->type); 788 switch (instr->type) { 789 case nir_instr_type_alu: 790 write_alu(ctx, nir_instr_as_alu(instr)); 791 break; 792 case nir_instr_type_deref: 793 write_deref(ctx, nir_instr_as_deref(instr)); 794 break; 795 case nir_instr_type_intrinsic: 796 write_intrinsic(ctx, nir_instr_as_intrinsic(instr)); 797 break; 798 case nir_instr_type_load_const: 799 write_load_const(ctx, nir_instr_as_load_const(instr)); 800 break; 801 case nir_instr_type_ssa_undef: 802 write_ssa_undef(ctx, nir_instr_as_ssa_undef(instr)); 803 break; 804 case nir_instr_type_tex: 805 write_tex(ctx, nir_instr_as_tex(instr)); 806 break; 807 case nir_instr_type_phi: 808 write_phi(ctx, nir_instr_as_phi(instr)); 809 break; 810 case nir_instr_type_jump: 811 write_jump(ctx, nir_instr_as_jump(instr)); 812 break; 813 case nir_instr_type_call: 814 write_call(ctx, nir_instr_as_call(instr)); 815 break; 816 case nir_instr_type_parallel_copy: 817 unreachable("Cannot write parallel copies"); 818 default: 819 unreachable("bad instr type"); 820 } 821} 822 823static void 824read_instr(read_ctx *ctx, nir_block *block) 825{ 826 nir_instr_type type = blob_read_uint32(ctx->blob); 827 nir_instr *instr; 828 switch (type) { 829 case nir_instr_type_alu: 830 instr = &read_alu(ctx)->instr; 831 break; 832 case nir_instr_type_deref: 833 instr = &read_deref(ctx)->instr; 834 break; 835 case nir_instr_type_intrinsic: 836 instr = &read_intrinsic(ctx)->instr; 837 break; 838 case nir_instr_type_load_const: 839 instr = &read_load_const(ctx)->instr; 840 break; 841 case nir_instr_type_ssa_undef: 842 instr = &read_ssa_undef(ctx)->instr; 843 break; 844 case nir_instr_type_tex: 845 instr = &read_tex(ctx)->instr; 846 break; 847 case nir_instr_type_phi: 848 /* Phi instructions are a bit of a special case when reading because we 849 * don't want inserting the instruction to automatically handle use/defs 850 * for us. Instead, we need to wait until all the blocks/instructions 851 * are read so that we can set their sources up. 852 */ 853 read_phi(ctx, block); 854 return; 855 case nir_instr_type_jump: 856 instr = &read_jump(ctx)->instr; 857 break; 858 case nir_instr_type_call: 859 instr = &read_call(ctx)->instr; 860 break; 861 case nir_instr_type_parallel_copy: 862 unreachable("Cannot read parallel copies"); 863 default: 864 unreachable("bad instr type"); 865 } 866 867 nir_instr_insert_after_block(block, instr); 868} 869 870static void 871write_block(write_ctx *ctx, const nir_block *block) 872{ 873 write_add_object(ctx, block); 874 blob_write_uint32(ctx->blob, exec_list_length(&block->instr_list)); 875 nir_foreach_instr(instr, block) 876 write_instr(ctx, instr); 877} 878 879static void 880read_block(read_ctx *ctx, struct exec_list *cf_list) 881{ 882 /* Don't actually create a new block. Just use the one from the tail of 883 * the list. NIR guarantees that the tail of the list is a block and that 884 * no two blocks are side-by-side in the IR; It should be empty. 885 */ 886 nir_block *block = 887 exec_node_data(nir_block, exec_list_get_tail(cf_list), cf_node.node); 888 889 read_add_object(ctx, block); 890 unsigned num_instrs = blob_read_uint32(ctx->blob); 891 for (unsigned i = 0; i < num_instrs; i++) { 892 read_instr(ctx, block); 893 } 894} 895 896static void 897write_cf_list(write_ctx *ctx, const struct exec_list *cf_list); 898 899static void 900read_cf_list(read_ctx *ctx, struct exec_list *cf_list); 901 902static void 903write_if(write_ctx *ctx, nir_if *nif) 904{ 905 write_src(ctx, &nif->condition); 906 907 write_cf_list(ctx, &nif->then_list); 908 write_cf_list(ctx, &nif->else_list); 909} 910 911static void 912read_if(read_ctx *ctx, struct exec_list *cf_list) 913{ 914 nir_if *nif = nir_if_create(ctx->nir); 915 916 read_src(ctx, &nif->condition, nif); 917 918 nir_cf_node_insert_end(cf_list, &nif->cf_node); 919 920 read_cf_list(ctx, &nif->then_list); 921 read_cf_list(ctx, &nif->else_list); 922} 923 924static void 925write_loop(write_ctx *ctx, nir_loop *loop) 926{ 927 write_cf_list(ctx, &loop->body); 928} 929 930static void 931read_loop(read_ctx *ctx, struct exec_list *cf_list) 932{ 933 nir_loop *loop = nir_loop_create(ctx->nir); 934 935 nir_cf_node_insert_end(cf_list, &loop->cf_node); 936 937 read_cf_list(ctx, &loop->body); 938} 939 940static void 941write_cf_node(write_ctx *ctx, nir_cf_node *cf) 942{ 943 blob_write_uint32(ctx->blob, cf->type); 944 945 switch (cf->type) { 946 case nir_cf_node_block: 947 write_block(ctx, nir_cf_node_as_block(cf)); 948 break; 949 case nir_cf_node_if: 950 write_if(ctx, nir_cf_node_as_if(cf)); 951 break; 952 case nir_cf_node_loop: 953 write_loop(ctx, nir_cf_node_as_loop(cf)); 954 break; 955 default: 956 unreachable("bad cf type"); 957 } 958} 959 960static void 961read_cf_node(read_ctx *ctx, struct exec_list *list) 962{ 963 nir_cf_node_type type = blob_read_uint32(ctx->blob); 964 965 switch (type) { 966 case nir_cf_node_block: 967 read_block(ctx, list); 968 break; 969 case nir_cf_node_if: 970 read_if(ctx, list); 971 break; 972 case nir_cf_node_loop: 973 read_loop(ctx, list); 974 break; 975 default: 976 unreachable("bad cf type"); 977 } 978} 979 980static void 981write_cf_list(write_ctx *ctx, const struct exec_list *cf_list) 982{ 983 blob_write_uint32(ctx->blob, exec_list_length(cf_list)); 984 foreach_list_typed(nir_cf_node, cf, node, cf_list) { 985 write_cf_node(ctx, cf); 986 } 987} 988 989static void 990read_cf_list(read_ctx *ctx, struct exec_list *cf_list) 991{ 992 uint32_t num_cf_nodes = blob_read_uint32(ctx->blob); 993 for (unsigned i = 0; i < num_cf_nodes; i++) 994 read_cf_node(ctx, cf_list); 995} 996 997static void 998write_function_impl(write_ctx *ctx, const nir_function_impl *fi) 999{ 1000 write_var_list(ctx, &fi->locals); 1001 write_reg_list(ctx, &fi->registers); 1002 blob_write_uint32(ctx->blob, fi->reg_alloc); 1003 1004 write_cf_list(ctx, &fi->body); 1005 write_fixup_phis(ctx); 1006} 1007 1008static nir_function_impl * 1009read_function_impl(read_ctx *ctx, nir_function *fxn) 1010{ 1011 nir_function_impl *fi = nir_function_impl_create_bare(ctx->nir); 1012 fi->function = fxn; 1013 1014 read_var_list(ctx, &fi->locals); 1015 read_reg_list(ctx, &fi->registers); 1016 fi->reg_alloc = blob_read_uint32(ctx->blob); 1017 1018 read_cf_list(ctx, &fi->body); 1019 read_fixup_phis(ctx); 1020 1021 fi->valid_metadata = 0; 1022 1023 return fi; 1024} 1025 1026static void 1027write_function(write_ctx *ctx, const nir_function *fxn) 1028{ 1029 blob_write_uint32(ctx->blob, !!(fxn->name)); 1030 if (fxn->name) 1031 blob_write_string(ctx->blob, fxn->name); 1032 1033 write_add_object(ctx, fxn); 1034 1035 blob_write_uint32(ctx->blob, fxn->num_params); 1036 for (unsigned i = 0; i < fxn->num_params; i++) { 1037 uint32_t val = 1038 ((uint32_t)fxn->params[i].num_components) | 1039 ((uint32_t)fxn->params[i].bit_size) << 8; 1040 blob_write_uint32(ctx->blob, val); 1041 } 1042 1043 /* At first glance, it looks like we should write the function_impl here. 1044 * However, call instructions need to be able to reference at least the 1045 * function and those will get processed as we write the function_impls. 1046 * We stop here and write function_impls as a second pass. 1047 */ 1048} 1049 1050static void 1051read_function(read_ctx *ctx) 1052{ 1053 bool has_name = blob_read_uint32(ctx->blob); 1054 char *name = has_name ? blob_read_string(ctx->blob) : NULL; 1055 1056 nir_function *fxn = nir_function_create(ctx->nir, name); 1057 1058 read_add_object(ctx, fxn); 1059 1060 fxn->num_params = blob_read_uint32(ctx->blob); 1061 fxn->params = ralloc_array(fxn, nir_parameter, fxn->num_params); 1062 for (unsigned i = 0; i < fxn->num_params; i++) { 1063 uint32_t val = blob_read_uint32(ctx->blob); 1064 fxn->params[i].num_components = val & 0xff; 1065 fxn->params[i].bit_size = (val >> 8) & 0xff; 1066 } 1067} 1068 1069void 1070nir_serialize(struct blob *blob, const nir_shader *nir) 1071{ 1072 write_ctx ctx; 1073 ctx.remap_table = _mesa_hash_table_create(NULL, _mesa_hash_pointer, 1074 _mesa_key_pointer_equal); 1075 ctx.next_idx = 0; 1076 ctx.blob = blob; 1077 ctx.nir = nir; 1078 util_dynarray_init(&ctx.phi_fixups, NULL); 1079 1080 size_t idx_size_offset = blob_reserve_intptr(blob); 1081 1082 struct shader_info info = nir->info; 1083 uint32_t strings = 0; 1084 if (info.name) 1085 strings |= 0x1; 1086 if (info.label) 1087 strings |= 0x2; 1088 blob_write_uint32(blob, strings); 1089 if (info.name) 1090 blob_write_string(blob, info.name); 1091 if (info.label) 1092 blob_write_string(blob, info.label); 1093 info.name = info.label = NULL; 1094 blob_write_bytes(blob, (uint8_t *) &info, sizeof(info)); 1095 1096 write_var_list(&ctx, &nir->uniforms); 1097 write_var_list(&ctx, &nir->inputs); 1098 write_var_list(&ctx, &nir->outputs); 1099 write_var_list(&ctx, &nir->shared); 1100 write_var_list(&ctx, &nir->globals); 1101 write_var_list(&ctx, &nir->system_values); 1102 1103 write_reg_list(&ctx, &nir->registers); 1104 blob_write_uint32(blob, nir->reg_alloc); 1105 blob_write_uint32(blob, nir->num_inputs); 1106 blob_write_uint32(blob, nir->num_uniforms); 1107 blob_write_uint32(blob, nir->num_outputs); 1108 blob_write_uint32(blob, nir->num_shared); 1109 1110 blob_write_uint32(blob, exec_list_length(&nir->functions)); 1111 nir_foreach_function(fxn, nir) { 1112 write_function(&ctx, fxn); 1113 } 1114 1115 nir_foreach_function(fxn, nir) { 1116 write_function_impl(&ctx, fxn->impl); 1117 } 1118 1119 blob_write_uint32(blob, nir->constant_data_size); 1120 if (nir->constant_data_size > 0) 1121 blob_write_bytes(blob, nir->constant_data, nir->constant_data_size); 1122 1123 *(uintptr_t *)(blob->data + idx_size_offset) = ctx.next_idx; 1124 1125 _mesa_hash_table_destroy(ctx.remap_table, NULL); 1126 util_dynarray_fini(&ctx.phi_fixups); 1127} 1128 1129nir_shader * 1130nir_deserialize(void *mem_ctx, 1131 const struct nir_shader_compiler_options *options, 1132 struct blob_reader *blob) 1133{ 1134 read_ctx ctx; 1135 ctx.blob = blob; 1136 list_inithead(&ctx.phi_srcs); 1137 ctx.idx_table_len = blob_read_intptr(blob); 1138 ctx.idx_table = calloc(ctx.idx_table_len, sizeof(uintptr_t)); 1139 ctx.next_idx = 0; 1140 1141 uint32_t strings = blob_read_uint32(blob); 1142 char *name = (strings & 0x1) ? blob_read_string(blob) : NULL; 1143 char *label = (strings & 0x2) ? blob_read_string(blob) : NULL; 1144 1145 struct shader_info info; 1146 blob_copy_bytes(blob, (uint8_t *) &info, sizeof(info)); 1147 1148 ctx.nir = nir_shader_create(mem_ctx, info.stage, options, NULL); 1149 1150 info.name = name ? ralloc_strdup(ctx.nir, name) : NULL; 1151 info.label = label ? ralloc_strdup(ctx.nir, label) : NULL; 1152 1153 ctx.nir->info = info; 1154 1155 read_var_list(&ctx, &ctx.nir->uniforms); 1156 read_var_list(&ctx, &ctx.nir->inputs); 1157 read_var_list(&ctx, &ctx.nir->outputs); 1158 read_var_list(&ctx, &ctx.nir->shared); 1159 read_var_list(&ctx, &ctx.nir->globals); 1160 read_var_list(&ctx, &ctx.nir->system_values); 1161 1162 read_reg_list(&ctx, &ctx.nir->registers); 1163 ctx.nir->reg_alloc = blob_read_uint32(blob); 1164 ctx.nir->num_inputs = blob_read_uint32(blob); 1165 ctx.nir->num_uniforms = blob_read_uint32(blob); 1166 ctx.nir->num_outputs = blob_read_uint32(blob); 1167 ctx.nir->num_shared = blob_read_uint32(blob); 1168 1169 unsigned num_functions = blob_read_uint32(blob); 1170 for (unsigned i = 0; i < num_functions; i++) 1171 read_function(&ctx); 1172 1173 nir_foreach_function(fxn, ctx.nir) 1174 fxn->impl = read_function_impl(&ctx, fxn); 1175 1176 ctx.nir->constant_data_size = blob_read_uint32(blob); 1177 if (ctx.nir->constant_data_size > 0) { 1178 ctx.nir->constant_data = 1179 ralloc_size(ctx.nir, ctx.nir->constant_data_size); 1180 blob_copy_bytes(blob, ctx.nir->constant_data, 1181 ctx.nir->constant_data_size); 1182 } 1183 1184 free(ctx.idx_table); 1185 1186 return ctx.nir; 1187} 1188 1189nir_shader * 1190nir_shader_serialize_deserialize(void *mem_ctx, nir_shader *s) 1191{ 1192 const struct nir_shader_compiler_options *options = s->options; 1193 1194 struct blob writer; 1195 blob_init(&writer); 1196 nir_serialize(&writer, s); 1197 ralloc_free(s); 1198 1199 struct blob_reader reader; 1200 blob_reader_init(&reader, writer.data, writer.size); 1201 nir_shader *ns = nir_deserialize(mem_ctx, options, &reader); 1202 1203 blob_finish(&writer); 1204 1205 return ns; 1206} 1207