1/* 2 * Copyright © 2014 Intel Corporation 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 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24/** 25 * \file serialize.cpp 26 * 27 * GLSL serialization 28 * 29 * Supports serializing and deserializing glsl programs using a blob. 30 */ 31 32#include "compiler/glsl_types.h" 33#include "compiler/shader_info.h" 34#include "ir_uniform.h" 35#include "main/mtypes.h" 36#include "main/shaderobj.h" 37#include "program/program.h" 38#include "string_to_uint_map.h" 39#include "util/bitscan.h" 40 41 42static void 43write_subroutines(struct blob *metadata, struct gl_shader_program *prog) 44{ 45 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 46 struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 47 if (!sh) 48 continue; 49 50 struct gl_program *glprog = sh->Program; 51 52 blob_write_uint32(metadata, glprog->sh.NumSubroutineUniforms); 53 blob_write_uint32(metadata, glprog->sh.MaxSubroutineFunctionIndex); 54 blob_write_uint32(metadata, glprog->sh.NumSubroutineFunctions); 55 for (unsigned j = 0; j < glprog->sh.NumSubroutineFunctions; j++) { 56 int num_types = glprog->sh.SubroutineFunctions[j].num_compat_types; 57 58 blob_write_string(metadata, glprog->sh.SubroutineFunctions[j].name.string); 59 blob_write_uint32(metadata, glprog->sh.SubroutineFunctions[j].index); 60 blob_write_uint32(metadata, num_types); 61 62 for (int k = 0; k < num_types; k++) { 63 encode_type_to_blob(metadata, 64 glprog->sh.SubroutineFunctions[j].types[k]); 65 } 66 } 67 } 68} 69 70static void 71read_subroutines(struct blob_reader *metadata, struct gl_shader_program *prog) 72{ 73 struct gl_subroutine_function *subs; 74 75 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 76 struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 77 if (!sh) 78 continue; 79 80 struct gl_program *glprog = sh->Program; 81 82 glprog->sh.NumSubroutineUniforms = blob_read_uint32(metadata); 83 glprog->sh.MaxSubroutineFunctionIndex = blob_read_uint32(metadata); 84 glprog->sh.NumSubroutineFunctions = blob_read_uint32(metadata); 85 86 subs = rzalloc_array(prog, struct gl_subroutine_function, 87 glprog->sh.NumSubroutineFunctions); 88 glprog->sh.SubroutineFunctions = subs; 89 90 for (unsigned j = 0; j < glprog->sh.NumSubroutineFunctions; j++) { 91 subs[j].name.string = ralloc_strdup(prog, blob_read_string (metadata)); 92 resource_name_updated(&subs[j].name); 93 subs[j].index = (int) blob_read_uint32(metadata); 94 subs[j].num_compat_types = (int) blob_read_uint32(metadata); 95 96 subs[j].types = rzalloc_array(prog, const struct glsl_type *, 97 subs[j].num_compat_types); 98 for (int k = 0; k < subs[j].num_compat_types; k++) { 99 subs[j].types[k] = decode_type_from_blob(metadata); 100 } 101 } 102 } 103} 104 105static void 106write_buffer_block(struct blob *metadata, struct gl_uniform_block *b) 107{ 108 blob_write_string(metadata, b->name.string); 109 blob_write_uint32(metadata, b->NumUniforms); 110 blob_write_uint32(metadata, b->Binding); 111 blob_write_uint32(metadata, b->UniformBufferSize); 112 blob_write_uint32(metadata, b->stageref); 113 114 for (unsigned j = 0; j < b->NumUniforms; j++) { 115 blob_write_string(metadata, b->Uniforms[j].Name); 116 blob_write_string(metadata, b->Uniforms[j].IndexName); 117 encode_type_to_blob(metadata, b->Uniforms[j].Type); 118 blob_write_uint32(metadata, b->Uniforms[j].Offset); 119 } 120} 121 122static void 123write_buffer_blocks(struct blob *metadata, struct gl_shader_program *prog) 124{ 125 blob_write_uint32(metadata, prog->data->NumUniformBlocks); 126 blob_write_uint32(metadata, prog->data->NumShaderStorageBlocks); 127 128 for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) { 129 write_buffer_block(metadata, &prog->data->UniformBlocks[i]); 130 } 131 132 for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) { 133 write_buffer_block(metadata, &prog->data->ShaderStorageBlocks[i]); 134 } 135 136 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 137 struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 138 if (!sh) 139 continue; 140 141 struct gl_program *glprog = sh->Program; 142 143 blob_write_uint32(metadata, glprog->sh.NumUniformBlocks); 144 blob_write_uint32(metadata, glprog->info.num_ssbos); 145 146 for (unsigned j = 0; j < glprog->sh.NumUniformBlocks; j++) { 147 uint32_t offset = 148 glprog->sh.UniformBlocks[j] - prog->data->UniformBlocks; 149 blob_write_uint32(metadata, offset); 150 } 151 152 for (unsigned j = 0; j < glprog->info.num_ssbos; j++) { 153 uint32_t offset = glprog->sh.ShaderStorageBlocks[j] - 154 prog->data->ShaderStorageBlocks; 155 blob_write_uint32(metadata, offset); 156 } 157 } 158} 159 160static void 161read_buffer_block(struct blob_reader *metadata, struct gl_uniform_block *b, 162 struct gl_shader_program *prog) 163{ 164 b->name.string = ralloc_strdup(prog->data, blob_read_string (metadata)); 165 resource_name_updated(&b->name); 166 b->NumUniforms = blob_read_uint32(metadata); 167 b->Binding = blob_read_uint32(metadata); 168 b->UniformBufferSize = blob_read_uint32(metadata); 169 b->stageref = blob_read_uint32(metadata); 170 171 b->Uniforms = 172 rzalloc_array(prog->data, struct gl_uniform_buffer_variable, 173 b->NumUniforms); 174 for (unsigned j = 0; j < b->NumUniforms; j++) { 175 b->Uniforms[j].Name = ralloc_strdup(prog->data, 176 blob_read_string (metadata)); 177 178 char *index_name = blob_read_string(metadata); 179 if (strcmp(b->Uniforms[j].Name, index_name) == 0) { 180 b->Uniforms[j].IndexName = b->Uniforms[j].Name; 181 } else { 182 b->Uniforms[j].IndexName = ralloc_strdup(prog->data, index_name); 183 } 184 185 b->Uniforms[j].Type = decode_type_from_blob(metadata); 186 b->Uniforms[j].Offset = blob_read_uint32(metadata); 187 } 188} 189 190static void 191read_buffer_blocks(struct blob_reader *metadata, 192 struct gl_shader_program *prog) 193{ 194 prog->data->NumUniformBlocks = blob_read_uint32(metadata); 195 prog->data->NumShaderStorageBlocks = blob_read_uint32(metadata); 196 197 prog->data->UniformBlocks = 198 rzalloc_array(prog->data, struct gl_uniform_block, 199 prog->data->NumUniformBlocks); 200 201 prog->data->ShaderStorageBlocks = 202 rzalloc_array(prog->data, struct gl_uniform_block, 203 prog->data->NumShaderStorageBlocks); 204 205 for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) { 206 read_buffer_block(metadata, &prog->data->UniformBlocks[i], prog); 207 } 208 209 for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) { 210 read_buffer_block(metadata, &prog->data->ShaderStorageBlocks[i], prog); 211 } 212 213 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 214 struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 215 if (!sh) 216 continue; 217 218 struct gl_program *glprog = sh->Program; 219 220 glprog->sh.NumUniformBlocks = blob_read_uint32(metadata); 221 glprog->info.num_ssbos = blob_read_uint32(metadata); 222 223 glprog->sh.UniformBlocks = 224 rzalloc_array(glprog, gl_uniform_block *, glprog->sh.NumUniformBlocks); 225 glprog->sh.ShaderStorageBlocks = 226 rzalloc_array(glprog, gl_uniform_block *, glprog->info.num_ssbos); 227 228 for (unsigned j = 0; j < glprog->sh.NumUniformBlocks; j++) { 229 uint32_t offset = blob_read_uint32(metadata); 230 glprog->sh.UniformBlocks[j] = prog->data->UniformBlocks + offset; 231 } 232 233 for (unsigned j = 0; j < glprog->info.num_ssbos; j++) { 234 uint32_t offset = blob_read_uint32(metadata); 235 glprog->sh.ShaderStorageBlocks[j] = 236 prog->data->ShaderStorageBlocks + offset; 237 } 238 } 239} 240 241static void 242write_atomic_buffers(struct blob *metadata, struct gl_shader_program *prog) 243{ 244 blob_write_uint32(metadata, prog->data->NumAtomicBuffers); 245 246 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 247 if (prog->_LinkedShaders[i]) { 248 struct gl_program *glprog = prog->_LinkedShaders[i]->Program; 249 blob_write_uint32(metadata, glprog->info.num_abos); 250 } 251 } 252 253 for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) { 254 blob_write_uint32(metadata, prog->data->AtomicBuffers[i].Binding); 255 blob_write_uint32(metadata, prog->data->AtomicBuffers[i].MinimumSize); 256 blob_write_uint32(metadata, prog->data->AtomicBuffers[i].NumUniforms); 257 258 blob_write_bytes(metadata, prog->data->AtomicBuffers[i].StageReferences, 259 sizeof(prog->data->AtomicBuffers[i].StageReferences)); 260 261 for (unsigned j = 0; j < prog->data->AtomicBuffers[i].NumUniforms; j++) { 262 blob_write_uint32(metadata, prog->data->AtomicBuffers[i].Uniforms[j]); 263 } 264 } 265} 266 267static void 268read_atomic_buffers(struct blob_reader *metadata, 269 struct gl_shader_program *prog) 270{ 271 prog->data->NumAtomicBuffers = blob_read_uint32(metadata); 272 prog->data->AtomicBuffers = 273 rzalloc_array(prog, gl_active_atomic_buffer, 274 prog->data->NumAtomicBuffers); 275 276 struct gl_active_atomic_buffer **stage_buff_list[MESA_SHADER_STAGES]; 277 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 278 if (prog->_LinkedShaders[i]) { 279 struct gl_program *glprog = prog->_LinkedShaders[i]->Program; 280 281 glprog->info.num_abos = blob_read_uint32(metadata); 282 glprog->sh.AtomicBuffers = 283 rzalloc_array(glprog, gl_active_atomic_buffer *, 284 glprog->info.num_abos); 285 stage_buff_list[i] = glprog->sh.AtomicBuffers; 286 } 287 } 288 289 for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) { 290 prog->data->AtomicBuffers[i].Binding = blob_read_uint32(metadata); 291 prog->data->AtomicBuffers[i].MinimumSize = blob_read_uint32(metadata); 292 prog->data->AtomicBuffers[i].NumUniforms = blob_read_uint32(metadata); 293 294 blob_copy_bytes(metadata, 295 (uint8_t *) &prog->data->AtomicBuffers[i].StageReferences, 296 sizeof(prog->data->AtomicBuffers[i].StageReferences)); 297 298 prog->data->AtomicBuffers[i].Uniforms = rzalloc_array(prog, unsigned, 299 prog->data->AtomicBuffers[i].NumUniforms); 300 301 for (unsigned j = 0; j < prog->data->AtomicBuffers[i].NumUniforms; j++) { 302 prog->data->AtomicBuffers[i].Uniforms[j] = blob_read_uint32(metadata); 303 } 304 305 for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) { 306 if (prog->data->AtomicBuffers[i].StageReferences[j]) { 307 *stage_buff_list[j] = &prog->data->AtomicBuffers[i]; 308 stage_buff_list[j]++; 309 } 310 } 311 } 312} 313 314static void 315write_xfb(struct blob *metadata, struct gl_shader_program *shProg) 316{ 317 struct gl_program *prog = shProg->last_vert_prog; 318 319 if (!prog) { 320 blob_write_uint32(metadata, ~0u); 321 return; 322 } 323 324 struct gl_transform_feedback_info *ltf = prog->sh.LinkedTransformFeedback; 325 326 blob_write_uint32(metadata, prog->info.stage); 327 328 /* Data set by glTransformFeedbackVaryings. */ 329 blob_write_uint32(metadata, shProg->TransformFeedback.BufferMode); 330 blob_write_bytes(metadata, shProg->TransformFeedback.BufferStride, 331 sizeof(shProg->TransformFeedback.BufferStride)); 332 blob_write_uint32(metadata, shProg->TransformFeedback.NumVarying); 333 for (unsigned i = 0; i < shProg->TransformFeedback.NumVarying; i++) 334 blob_write_string(metadata, shProg->TransformFeedback.VaryingNames[i]); 335 336 blob_write_uint32(metadata, ltf->NumOutputs); 337 blob_write_uint32(metadata, ltf->ActiveBuffers); 338 blob_write_uint32(metadata, ltf->NumVarying); 339 340 blob_write_bytes(metadata, ltf->Outputs, 341 sizeof(struct gl_transform_feedback_output) * 342 ltf->NumOutputs); 343 344 for (int i = 0; i < ltf->NumVarying; i++) { 345 blob_write_string(metadata, ltf->Varyings[i].name.string); 346 blob_write_uint32(metadata, ltf->Varyings[i].Type); 347 blob_write_uint32(metadata, ltf->Varyings[i].BufferIndex); 348 blob_write_uint32(metadata, ltf->Varyings[i].Size); 349 blob_write_uint32(metadata, ltf->Varyings[i].Offset); 350 } 351 352 blob_write_bytes(metadata, ltf->Buffers, 353 sizeof(struct gl_transform_feedback_buffer) * 354 MAX_FEEDBACK_BUFFERS); 355} 356 357static void 358read_xfb(struct blob_reader *metadata, struct gl_shader_program *shProg) 359{ 360 unsigned xfb_stage = blob_read_uint32(metadata); 361 362 if (xfb_stage == ~0u) 363 return; 364 365 if (shProg->TransformFeedback.VaryingNames) { 366 for (unsigned i = 0; i < shProg->TransformFeedback.NumVarying; ++i) 367 free(shProg->TransformFeedback.VaryingNames[i]); 368 } 369 370 /* Data set by glTransformFeedbackVaryings. */ 371 shProg->TransformFeedback.BufferMode = blob_read_uint32(metadata); 372 blob_copy_bytes(metadata, &shProg->TransformFeedback.BufferStride, 373 sizeof(shProg->TransformFeedback.BufferStride)); 374 shProg->TransformFeedback.NumVarying = blob_read_uint32(metadata); 375 376 shProg->TransformFeedback.VaryingNames = (char **) 377 realloc(shProg->TransformFeedback.VaryingNames, 378 shProg->TransformFeedback.NumVarying * sizeof(GLchar *)); 379 /* Note, malloc used with VaryingNames. */ 380 for (unsigned i = 0; i < shProg->TransformFeedback.NumVarying; i++) 381 shProg->TransformFeedback.VaryingNames[i] = 382 strdup(blob_read_string(metadata)); 383 384 struct gl_program *prog = shProg->_LinkedShaders[xfb_stage]->Program; 385 struct gl_transform_feedback_info *ltf = 386 rzalloc(prog, struct gl_transform_feedback_info); 387 388 prog->sh.LinkedTransformFeedback = ltf; 389 shProg->last_vert_prog = prog; 390 391 ltf->NumOutputs = blob_read_uint32(metadata); 392 ltf->ActiveBuffers = blob_read_uint32(metadata); 393 ltf->NumVarying = blob_read_uint32(metadata); 394 395 ltf->Outputs = rzalloc_array(prog, struct gl_transform_feedback_output, 396 ltf->NumOutputs); 397 398 blob_copy_bytes(metadata, (uint8_t *) ltf->Outputs, 399 sizeof(struct gl_transform_feedback_output) * 400 ltf->NumOutputs); 401 402 ltf->Varyings = rzalloc_array(prog, 403 struct gl_transform_feedback_varying_info, 404 ltf->NumVarying); 405 406 for (int i = 0; i < ltf->NumVarying; i++) { 407 ltf->Varyings[i].name.string = ralloc_strdup(prog, blob_read_string(metadata)); 408 resource_name_updated(<f->Varyings[i].name); 409 ltf->Varyings[i].Type = blob_read_uint32(metadata); 410 ltf->Varyings[i].BufferIndex = blob_read_uint32(metadata); 411 ltf->Varyings[i].Size = blob_read_uint32(metadata); 412 ltf->Varyings[i].Offset = blob_read_uint32(metadata); 413 } 414 415 blob_copy_bytes(metadata, (uint8_t *) ltf->Buffers, 416 sizeof(struct gl_transform_feedback_buffer) * 417 MAX_FEEDBACK_BUFFERS); 418} 419 420static bool 421has_uniform_storage(struct gl_shader_program *prog, unsigned idx) 422{ 423 if (!prog->data->UniformStorage[idx].builtin && 424 !prog->data->UniformStorage[idx].is_shader_storage && 425 prog->data->UniformStorage[idx].block_index == -1) 426 return true; 427 428 return false; 429} 430 431static void 432write_uniforms(struct blob *metadata, struct gl_shader_program *prog) 433{ 434 blob_write_uint32(metadata, prog->SamplersValidated); 435 blob_write_uint32(metadata, prog->data->NumUniformStorage); 436 blob_write_uint32(metadata, prog->data->NumUniformDataSlots); 437 438 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 439 encode_type_to_blob(metadata, prog->data->UniformStorage[i].type); 440 blob_write_uint32(metadata, prog->data->UniformStorage[i].array_elements); 441 if (prog->data->UniformStorage[i].name.string) { 442 blob_write_string(metadata, prog->data->UniformStorage[i].name.string); 443 } else { 444 blob_write_string(metadata, ""); 445 } 446 blob_write_uint32(metadata, prog->data->UniformStorage[i].builtin); 447 blob_write_uint32(metadata, prog->data->UniformStorage[i].remap_location); 448 blob_write_uint32(metadata, prog->data->UniformStorage[i].block_index); 449 blob_write_uint32(metadata, prog->data->UniformStorage[i].atomic_buffer_index); 450 blob_write_uint32(metadata, prog->data->UniformStorage[i].offset); 451 blob_write_uint32(metadata, prog->data->UniformStorage[i].array_stride); 452 blob_write_uint32(metadata, prog->data->UniformStorage[i].hidden); 453 blob_write_uint32(metadata, prog->data->UniformStorage[i].is_shader_storage); 454 blob_write_uint32(metadata, prog->data->UniformStorage[i].active_shader_mask); 455 blob_write_uint32(metadata, prog->data->UniformStorage[i].matrix_stride); 456 blob_write_uint32(metadata, prog->data->UniformStorage[i].row_major); 457 blob_write_uint32(metadata, prog->data->UniformStorage[i].is_bindless); 458 blob_write_uint32(metadata, 459 prog->data->UniformStorage[i].num_compatible_subroutines); 460 blob_write_uint32(metadata, 461 prog->data->UniformStorage[i].top_level_array_size); 462 blob_write_uint32(metadata, 463 prog->data->UniformStorage[i].top_level_array_stride); 464 465 if (has_uniform_storage(prog, i)) { 466 blob_write_uint32(metadata, prog->data->UniformStorage[i].storage - 467 prog->data->UniformDataSlots); 468 } 469 470 blob_write_bytes(metadata, prog->data->UniformStorage[i].opaque, 471 sizeof(prog->data->UniformStorage[i].opaque)); 472 } 473 474 /* Here we cache all uniform values. We do this to retain values for 475 * uniforms with initialisers and also hidden uniforms that may be lowered 476 * constant arrays. We could possibly just store the values we need but for 477 * now we just store everything. 478 */ 479 blob_write_uint32(metadata, prog->data->NumHiddenUniforms); 480 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 481 if (has_uniform_storage(prog, i)) { 482 unsigned vec_size = 483 prog->data->UniformStorage[i].type->component_slots() * 484 MAX2(prog->data->UniformStorage[i].array_elements, 1); 485 unsigned slot = 486 prog->data->UniformStorage[i].storage - 487 prog->data->UniformDataSlots; 488 blob_write_bytes(metadata, &prog->data->UniformDataDefaults[slot], 489 sizeof(union gl_constant_value) * vec_size); 490 } 491 } 492} 493 494static void 495read_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog) 496{ 497 struct gl_uniform_storage *uniforms; 498 union gl_constant_value *data; 499 500 prog->SamplersValidated = blob_read_uint32(metadata); 501 prog->data->NumUniformStorage = blob_read_uint32(metadata); 502 prog->data->NumUniformDataSlots = blob_read_uint32(metadata); 503 504 uniforms = rzalloc_array(prog->data, struct gl_uniform_storage, 505 prog->data->NumUniformStorage); 506 prog->data->UniformStorage = uniforms; 507 508 data = rzalloc_array(uniforms, union gl_constant_value, 509 prog->data->NumUniformDataSlots); 510 prog->data->UniformDataSlots = data; 511 prog->data->UniformDataDefaults = 512 rzalloc_array(uniforms, union gl_constant_value, 513 prog->data->NumUniformDataSlots); 514 515 prog->UniformHash = new string_to_uint_map; 516 517 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 518 uniforms[i].type = decode_type_from_blob(metadata); 519 uniforms[i].array_elements = blob_read_uint32(metadata); 520 uniforms[i].name.string = ralloc_strdup(prog, blob_read_string (metadata)); 521 resource_name_updated(&uniforms[i].name); 522 uniforms[i].builtin = blob_read_uint32(metadata); 523 uniforms[i].remap_location = blob_read_uint32(metadata); 524 uniforms[i].block_index = blob_read_uint32(metadata); 525 uniforms[i].atomic_buffer_index = blob_read_uint32(metadata); 526 uniforms[i].offset = blob_read_uint32(metadata); 527 uniforms[i].array_stride = blob_read_uint32(metadata); 528 uniforms[i].hidden = blob_read_uint32(metadata); 529 uniforms[i].is_shader_storage = blob_read_uint32(metadata); 530 uniforms[i].active_shader_mask = blob_read_uint32(metadata); 531 uniforms[i].matrix_stride = blob_read_uint32(metadata); 532 uniforms[i].row_major = blob_read_uint32(metadata); 533 uniforms[i].is_bindless = blob_read_uint32(metadata); 534 uniforms[i].num_compatible_subroutines = blob_read_uint32(metadata); 535 uniforms[i].top_level_array_size = blob_read_uint32(metadata); 536 uniforms[i].top_level_array_stride = blob_read_uint32(metadata); 537 prog->UniformHash->put(i, uniforms[i].name.string); 538 539 if (has_uniform_storage(prog, i)) { 540 uniforms[i].storage = data + blob_read_uint32(metadata); 541 } 542 543 memcpy(uniforms[i].opaque, 544 blob_read_bytes(metadata, sizeof(uniforms[i].opaque)), 545 sizeof(uniforms[i].opaque)); 546 } 547 548 /* Restore uniform values. */ 549 prog->data->NumHiddenUniforms = blob_read_uint32(metadata); 550 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 551 if (has_uniform_storage(prog, i)) { 552 unsigned vec_size = 553 prog->data->UniformStorage[i].type->component_slots() * 554 MAX2(prog->data->UniformStorage[i].array_elements, 1); 555 unsigned slot = 556 prog->data->UniformStorage[i].storage - 557 prog->data->UniformDataSlots; 558 blob_copy_bytes(metadata, 559 (uint8_t *) &prog->data->UniformDataSlots[slot], 560 sizeof(union gl_constant_value) * vec_size); 561 562 assert(vec_size + prog->data->UniformStorage[i].storage <= 563 data + prog->data->NumUniformDataSlots); 564 } 565 } 566 567 memcpy(prog->data->UniformDataDefaults, prog->data->UniformDataSlots, 568 sizeof(union gl_constant_value) * prog->data->NumUniformDataSlots); 569} 570 571enum uniform_remap_type 572{ 573 remap_type_inactive_explicit_location, 574 remap_type_null_ptr, 575 remap_type_uniform_offset, 576 remap_type_uniform_offsets_equal, 577}; 578 579static void 580write_uniform_remap_table(struct blob *metadata, 581 unsigned num_entries, 582 gl_uniform_storage *uniform_storage, 583 gl_uniform_storage **remap_table) 584{ 585 blob_write_uint32(metadata, num_entries); 586 587 for (unsigned i = 0; i < num_entries; i++) { 588 gl_uniform_storage *entry = remap_table[i]; 589 uint32_t offset = entry - uniform_storage; 590 591 if (entry == INACTIVE_UNIFORM_EXPLICIT_LOCATION) { 592 blob_write_uint32(metadata, remap_type_inactive_explicit_location); 593 } else if (entry == NULL) { 594 blob_write_uint32(metadata, remap_type_null_ptr); 595 } else if (i+1 < num_entries && entry == remap_table[i+1]) { 596 blob_write_uint32(metadata, remap_type_uniform_offsets_equal); 597 598 /* If many offsets are equal, write only one offset and the number 599 * of consecutive entries being equal. 600 */ 601 unsigned count = 1; 602 for (unsigned j = i + 1; j < num_entries; j++) { 603 if (entry != remap_table[j]) 604 break; 605 606 count++; 607 } 608 609 blob_write_uint32(metadata, offset); 610 blob_write_uint32(metadata, count); 611 i += count - 1; 612 } else { 613 blob_write_uint32(metadata, remap_type_uniform_offset); 614 615 blob_write_uint32(metadata, offset); 616 } 617 } 618} 619 620static void 621write_uniform_remap_tables(struct blob *metadata, 622 struct gl_shader_program *prog) 623{ 624 write_uniform_remap_table(metadata, prog->NumUniformRemapTable, 625 prog->data->UniformStorage, 626 prog->UniformRemapTable); 627 628 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 629 struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 630 if (sh) { 631 write_uniform_remap_table(metadata, 632 sh->Program->sh.NumSubroutineUniformRemapTable, 633 prog->data->UniformStorage, 634 sh->Program->sh.SubroutineUniformRemapTable); 635 } 636 } 637} 638 639static struct gl_uniform_storage ** 640read_uniform_remap_table(struct blob_reader *metadata, 641 struct gl_shader_program *prog, 642 unsigned *num_entries, 643 gl_uniform_storage *uniform_storage) 644{ 645 unsigned num = blob_read_uint32(metadata); 646 *num_entries = num; 647 648 struct gl_uniform_storage **remap_table = 649 rzalloc_array(prog, struct gl_uniform_storage *, num); 650 651 for (unsigned i = 0; i < num; i++) { 652 enum uniform_remap_type type = 653 (enum uniform_remap_type) blob_read_uint32(metadata); 654 655 if (type == remap_type_inactive_explicit_location) { 656 remap_table[i] = INACTIVE_UNIFORM_EXPLICIT_LOCATION; 657 } else if (type == remap_type_null_ptr) { 658 remap_table[i] = NULL; 659 } else if (type == remap_type_uniform_offsets_equal) { 660 uint32_t uni_offset = blob_read_uint32(metadata); 661 uint32_t count = blob_read_uint32(metadata); 662 struct gl_uniform_storage *entry = uniform_storage + uni_offset; 663 664 for (unsigned j = 0; j < count; j++) 665 remap_table[i+j] = entry; 666 i += count - 1; 667 } else { 668 uint32_t uni_offset = blob_read_uint32(metadata); 669 remap_table[i] = uniform_storage + uni_offset; 670 } 671 } 672 return remap_table; 673} 674 675static void 676read_uniform_remap_tables(struct blob_reader *metadata, 677 struct gl_shader_program *prog) 678{ 679 prog->UniformRemapTable = 680 read_uniform_remap_table(metadata, prog, &prog->NumUniformRemapTable, 681 prog->data->UniformStorage); 682 683 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 684 struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 685 if (sh) { 686 struct gl_program *glprog = sh->Program; 687 688 glprog->sh.SubroutineUniformRemapTable = 689 read_uniform_remap_table(metadata, prog, 690 &glprog->sh.NumSubroutineUniformRemapTable, 691 prog->data->UniformStorage); 692 } 693 } 694} 695 696struct whte_closure 697{ 698 struct blob *blob; 699 size_t num_entries; 700}; 701 702static void 703write_hash_table_entry(const char *key, unsigned value, void *closure) 704{ 705 struct whte_closure *whte = (struct whte_closure *) closure; 706 707 blob_write_string(whte->blob, key); 708 blob_write_uint32(whte->blob, value); 709 710 whte->num_entries++; 711} 712 713static void 714write_hash_table(struct blob *metadata, struct string_to_uint_map *hash) 715{ 716 size_t offset; 717 struct whte_closure whte; 718 719 whte.blob = metadata; 720 whte.num_entries = 0; 721 722 offset = metadata->size; 723 724 /* Write a placeholder for the hashtable size. */ 725 blob_write_uint32 (metadata, 0); 726 727 hash->iterate(write_hash_table_entry, &whte); 728 729 /* Overwrite with the computed number of entries written. */ 730 blob_overwrite_uint32 (metadata, offset, whte.num_entries); 731} 732 733static void 734read_hash_table(struct blob_reader *metadata, struct string_to_uint_map *hash) 735{ 736 size_t i, num_entries; 737 const char *key; 738 uint32_t value; 739 740 num_entries = blob_read_uint32 (metadata); 741 742 for (i = 0; i < num_entries; i++) { 743 key = blob_read_string(metadata); 744 value = blob_read_uint32(metadata); 745 746 hash->put(value, key); 747 } 748} 749 750static void 751write_hash_tables(struct blob *metadata, struct gl_shader_program *prog) 752{ 753 write_hash_table(metadata, prog->AttributeBindings); 754 write_hash_table(metadata, prog->FragDataBindings); 755 write_hash_table(metadata, prog->FragDataIndexBindings); 756} 757 758static void 759read_hash_tables(struct blob_reader *metadata, struct gl_shader_program *prog) 760{ 761 read_hash_table(metadata, prog->AttributeBindings); 762 read_hash_table(metadata, prog->FragDataBindings); 763 read_hash_table(metadata, prog->FragDataIndexBindings); 764} 765 766static void 767write_shader_subroutine_index(struct blob *metadata, 768 struct gl_linked_shader *sh, 769 struct gl_program_resource *res) 770{ 771 assert(sh); 772 773 for (unsigned j = 0; j < sh->Program->sh.NumSubroutineFunctions; j++) { 774 if (strcmp(((gl_subroutine_function *)res->Data)->name.string, 775 sh->Program->sh.SubroutineFunctions[j].name.string) == 0) { 776 blob_write_uint32(metadata, j); 777 break; 778 } 779 } 780} 781 782static void 783get_shader_var_and_pointer_sizes(size_t *s_var_size, size_t *s_var_ptrs, 784 const gl_shader_variable *var) 785{ 786 *s_var_size = sizeof(gl_shader_variable); 787 *s_var_ptrs = 788 sizeof(var->type) + 789 sizeof(var->interface_type) + 790 sizeof(var->outermost_struct_type) + 791 sizeof(var->name); 792} 793 794enum uniform_type 795{ 796 uniform_remapped, 797 uniform_not_remapped 798}; 799 800static void 801write_program_resource_data(struct blob *metadata, 802 struct gl_shader_program *prog, 803 struct gl_program_resource *res) 804{ 805 struct gl_linked_shader *sh; 806 807 switch(res->Type) { 808 case GL_PROGRAM_INPUT: 809 case GL_PROGRAM_OUTPUT: { 810 const gl_shader_variable *var = (gl_shader_variable *)res->Data; 811 812 encode_type_to_blob(metadata, var->type); 813 encode_type_to_blob(metadata, var->interface_type); 814 encode_type_to_blob(metadata, var->outermost_struct_type); 815 816 if (var->name.string) { 817 blob_write_string(metadata, var->name.string); 818 } else { 819 blob_write_string(metadata, ""); 820 } 821 822 size_t s_var_size, s_var_ptrs; 823 get_shader_var_and_pointer_sizes(&s_var_size, &s_var_ptrs, var); 824 825 /* Write gl_shader_variable skipping over the pointers */ 826 blob_write_bytes(metadata, ((char *)var) + s_var_ptrs, 827 s_var_size - s_var_ptrs); 828 break; 829 } 830 case GL_UNIFORM_BLOCK: 831 for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) { 832 if (strcmp(((gl_uniform_block *)res->Data)->name.string, 833 prog->data->UniformBlocks[i].name.string) == 0) { 834 blob_write_uint32(metadata, i); 835 break; 836 } 837 } 838 break; 839 case GL_SHADER_STORAGE_BLOCK: 840 for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) { 841 if (strcmp(((gl_uniform_block *)res->Data)->name.string, 842 prog->data->ShaderStorageBlocks[i].name.string) == 0) { 843 blob_write_uint32(metadata, i); 844 break; 845 } 846 } 847 break; 848 case GL_BUFFER_VARIABLE: 849 case GL_VERTEX_SUBROUTINE_UNIFORM: 850 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 851 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 852 case GL_COMPUTE_SUBROUTINE_UNIFORM: 853 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 854 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 855 case GL_UNIFORM: 856 if (((gl_uniform_storage *)res->Data)->builtin || 857 res->Type != GL_UNIFORM) { 858 blob_write_uint32(metadata, uniform_not_remapped); 859 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 860 if (strcmp(((gl_uniform_storage *)res->Data)->name.string, 861 prog->data->UniformStorage[i].name.string) == 0) { 862 blob_write_uint32(metadata, i); 863 break; 864 } 865 } 866 } else { 867 blob_write_uint32(metadata, uniform_remapped); 868 blob_write_uint32(metadata, ((gl_uniform_storage *)res->Data)->remap_location); 869 } 870 break; 871 case GL_ATOMIC_COUNTER_BUFFER: 872 for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) { 873 if (((gl_active_atomic_buffer *)res->Data)->Binding == 874 prog->data->AtomicBuffers[i].Binding) { 875 blob_write_uint32(metadata, i); 876 break; 877 } 878 } 879 break; 880 case GL_TRANSFORM_FEEDBACK_BUFFER: 881 for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) { 882 if (((gl_transform_feedback_buffer *)res->Data)->Binding == 883 prog->last_vert_prog->sh.LinkedTransformFeedback->Buffers[i].Binding) { 884 blob_write_uint32(metadata, i); 885 break; 886 } 887 } 888 break; 889 case GL_TRANSFORM_FEEDBACK_VARYING: 890 for (int i = 0; i < prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying; i++) { 891 if (strcmp(((gl_transform_feedback_varying_info *)res->Data)->name.string, 892 prog->last_vert_prog->sh.LinkedTransformFeedback->Varyings[i].name.string) == 0) { 893 blob_write_uint32(metadata, i); 894 break; 895 } 896 } 897 break; 898 case GL_VERTEX_SUBROUTINE: 899 case GL_TESS_CONTROL_SUBROUTINE: 900 case GL_TESS_EVALUATION_SUBROUTINE: 901 case GL_GEOMETRY_SUBROUTINE: 902 case GL_FRAGMENT_SUBROUTINE: 903 case GL_COMPUTE_SUBROUTINE: 904 sh = 905 prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)]; 906 write_shader_subroutine_index(metadata, sh, res); 907 break; 908 default: 909 assert(!"Support for writing resource not yet implemented."); 910 } 911} 912 913static void 914read_program_resource_data(struct blob_reader *metadata, 915 struct gl_shader_program *prog, 916 struct gl_program_resource *res) 917{ 918 struct gl_linked_shader *sh; 919 920 switch(res->Type) { 921 case GL_PROGRAM_INPUT: 922 case GL_PROGRAM_OUTPUT: { 923 gl_shader_variable *var = ralloc(prog, struct gl_shader_variable); 924 925 var->type = decode_type_from_blob(metadata); 926 var->interface_type = decode_type_from_blob(metadata); 927 var->outermost_struct_type = decode_type_from_blob(metadata); 928 929 var->name.string = ralloc_strdup(prog, blob_read_string(metadata)); 930 resource_name_updated(&var->name); 931 932 size_t s_var_size, s_var_ptrs; 933 get_shader_var_and_pointer_sizes(&s_var_size, &s_var_ptrs, var); 934 935 blob_copy_bytes(metadata, ((uint8_t *) var) + s_var_ptrs, 936 s_var_size - s_var_ptrs); 937 938 res->Data = var; 939 break; 940 } 941 case GL_UNIFORM_BLOCK: 942 res->Data = &prog->data->UniformBlocks[blob_read_uint32(metadata)]; 943 break; 944 case GL_SHADER_STORAGE_BLOCK: 945 res->Data = &prog->data->ShaderStorageBlocks[blob_read_uint32(metadata)]; 946 break; 947 case GL_BUFFER_VARIABLE: 948 case GL_VERTEX_SUBROUTINE_UNIFORM: 949 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 950 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 951 case GL_COMPUTE_SUBROUTINE_UNIFORM: 952 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 953 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 954 case GL_UNIFORM: { 955 enum uniform_type type = (enum uniform_type) blob_read_uint32(metadata); 956 if (type == uniform_not_remapped) { 957 res->Data = &prog->data->UniformStorage[blob_read_uint32(metadata)]; 958 } else { 959 res->Data = prog->UniformRemapTable[blob_read_uint32(metadata)]; 960 } 961 break; 962 } 963 case GL_ATOMIC_COUNTER_BUFFER: 964 res->Data = &prog->data->AtomicBuffers[blob_read_uint32(metadata)]; 965 break; 966 case GL_TRANSFORM_FEEDBACK_BUFFER: 967 res->Data = &prog->last_vert_prog-> 968 sh.LinkedTransformFeedback->Buffers[blob_read_uint32(metadata)]; 969 break; 970 case GL_TRANSFORM_FEEDBACK_VARYING: 971 res->Data = &prog->last_vert_prog-> 972 sh.LinkedTransformFeedback->Varyings[blob_read_uint32(metadata)]; 973 break; 974 case GL_VERTEX_SUBROUTINE: 975 case GL_TESS_CONTROL_SUBROUTINE: 976 case GL_TESS_EVALUATION_SUBROUTINE: 977 case GL_GEOMETRY_SUBROUTINE: 978 case GL_FRAGMENT_SUBROUTINE: 979 case GL_COMPUTE_SUBROUTINE: 980 sh = 981 prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)]; 982 res->Data = 983 &sh->Program->sh.SubroutineFunctions[blob_read_uint32(metadata)]; 984 break; 985 default: 986 assert(!"Support for reading resource not yet implemented."); 987 } 988} 989 990static void 991write_program_resource_list(struct blob *metadata, 992 struct gl_shader_program *prog) 993{ 994 blob_write_uint32(metadata, prog->data->NumProgramResourceList); 995 996 for (unsigned i = 0; i < prog->data->NumProgramResourceList; i++) { 997 blob_write_uint32(metadata, prog->data->ProgramResourceList[i].Type); 998 write_program_resource_data(metadata, prog, 999 &prog->data->ProgramResourceList[i]); 1000 blob_write_bytes(metadata, 1001 &prog->data->ProgramResourceList[i].StageReferences, 1002 sizeof(prog->data->ProgramResourceList[i].StageReferences)); 1003 } 1004} 1005 1006static void 1007read_program_resource_list(struct blob_reader *metadata, 1008 struct gl_shader_program *prog) 1009{ 1010 prog->data->NumProgramResourceList = blob_read_uint32(metadata); 1011 1012 prog->data->ProgramResourceList = 1013 ralloc_array(prog->data, gl_program_resource, 1014 prog->data->NumProgramResourceList); 1015 1016 for (unsigned i = 0; i < prog->data->NumProgramResourceList; i++) { 1017 prog->data->ProgramResourceList[i].Type = blob_read_uint32(metadata); 1018 read_program_resource_data(metadata, prog, 1019 &prog->data->ProgramResourceList[i]); 1020 blob_copy_bytes(metadata, 1021 (uint8_t *) &prog->data->ProgramResourceList[i].StageReferences, 1022 sizeof(prog->data->ProgramResourceList[i].StageReferences)); 1023 } 1024} 1025 1026static void 1027write_shader_parameters(struct blob *metadata, 1028 struct gl_program_parameter_list *params) 1029{ 1030 blob_write_uint32(metadata, params->NumParameters); 1031 uint32_t i = 0; 1032 1033 while (i < params->NumParameters) { 1034 struct gl_program_parameter *param = ¶ms->Parameters[i]; 1035 blob_write_uint32(metadata, param->Type); 1036 blob_write_string(metadata, param->Name); 1037 blob_write_uint32(metadata, param->Size); 1038 blob_write_uint32(metadata, param->Padded); 1039 blob_write_uint32(metadata, param->DataType); 1040 blob_write_bytes(metadata, param->StateIndexes, 1041 sizeof(param->StateIndexes)); 1042 blob_write_uint32(metadata, param->UniformStorageIndex); 1043 blob_write_uint32(metadata, param->MainUniformStorageIndex); 1044 1045 i++; 1046 } 1047 1048 blob_write_bytes(metadata, params->ParameterValues, 1049 sizeof(gl_constant_value) * params->NumParameterValues); 1050 1051 blob_write_uint32(metadata, params->StateFlags); 1052 blob_write_uint32(metadata, params->UniformBytes); 1053 blob_write_uint32(metadata, params->FirstStateVarIndex); 1054 blob_write_uint32(metadata, params->LastStateVarIndex); 1055} 1056 1057static void 1058read_shader_parameters(struct blob_reader *metadata, 1059 struct gl_program_parameter_list *params) 1060{ 1061 gl_state_index16 state_indexes[STATE_LENGTH]; 1062 uint32_t i = 0; 1063 uint32_t num_parameters = blob_read_uint32(metadata); 1064 1065 _mesa_reserve_parameter_storage(params, num_parameters, num_parameters); 1066 while (i < num_parameters) { 1067 gl_register_file type = (gl_register_file) blob_read_uint32(metadata); 1068 const char *name = blob_read_string(metadata); 1069 unsigned size = blob_read_uint32(metadata); 1070 bool padded = blob_read_uint32(metadata); 1071 unsigned data_type = blob_read_uint32(metadata); 1072 blob_copy_bytes(metadata, (uint8_t *) state_indexes, 1073 sizeof(state_indexes)); 1074 1075 _mesa_add_parameter(params, type, name, size, data_type, 1076 NULL, state_indexes, padded); 1077 1078 gl_program_parameter *param = ¶ms->Parameters[i]; 1079 param->UniformStorageIndex = blob_read_uint32(metadata); 1080 param->MainUniformStorageIndex = blob_read_uint32(metadata); 1081 1082 i++; 1083 } 1084 1085 blob_copy_bytes(metadata, (uint8_t *) params->ParameterValues, 1086 sizeof(gl_constant_value) * params->NumParameterValues); 1087 1088 params->StateFlags = blob_read_uint32(metadata); 1089 params->UniformBytes = blob_read_uint32(metadata); 1090 params->FirstStateVarIndex = blob_read_uint32(metadata); 1091 params->LastStateVarIndex = blob_read_uint32(metadata); 1092} 1093 1094static void 1095write_shader_metadata(struct blob *metadata, gl_linked_shader *shader) 1096{ 1097 assert(shader->Program); 1098 struct gl_program *glprog = shader->Program; 1099 unsigned i; 1100 1101 blob_write_uint64(metadata, glprog->DualSlotInputs); 1102 blob_write_bytes(metadata, glprog->TexturesUsed, 1103 sizeof(glprog->TexturesUsed)); 1104 blob_write_uint64(metadata, glprog->SamplersUsed); 1105 1106 blob_write_bytes(metadata, glprog->SamplerUnits, 1107 sizeof(glprog->SamplerUnits)); 1108 blob_write_bytes(metadata, glprog->sh.SamplerTargets, 1109 sizeof(glprog->sh.SamplerTargets)); 1110 blob_write_uint32(metadata, glprog->ShadowSamplers); 1111 blob_write_uint32(metadata, glprog->ExternalSamplersUsed); 1112 blob_write_uint32(metadata, glprog->sh.ShaderStorageBlocksWriteAccess); 1113 1114 blob_write_bytes(metadata, glprog->sh.ImageAccess, 1115 sizeof(glprog->sh.ImageAccess)); 1116 blob_write_bytes(metadata, glprog->sh.ImageUnits, 1117 sizeof(glprog->sh.ImageUnits)); 1118 1119 size_t ptr_size = sizeof(GLvoid *); 1120 1121 blob_write_uint32(metadata, glprog->sh.NumBindlessSamplers); 1122 blob_write_uint32(metadata, glprog->sh.HasBoundBindlessSampler); 1123 for (i = 0; i < glprog->sh.NumBindlessSamplers; i++) { 1124 blob_write_bytes(metadata, &glprog->sh.BindlessSamplers[i], 1125 sizeof(struct gl_bindless_sampler) - ptr_size); 1126 } 1127 1128 blob_write_uint32(metadata, glprog->sh.NumBindlessImages); 1129 blob_write_uint32(metadata, glprog->sh.HasBoundBindlessImage); 1130 for (i = 0; i < glprog->sh.NumBindlessImages; i++) { 1131 blob_write_bytes(metadata, &glprog->sh.BindlessImages[i], 1132 sizeof(struct gl_bindless_image) - ptr_size); 1133 } 1134 1135 write_shader_parameters(metadata, glprog->Parameters); 1136 1137 assert((glprog->driver_cache_blob == NULL) == 1138 (glprog->driver_cache_blob_size == 0)); 1139 blob_write_uint32(metadata, (uint32_t)glprog->driver_cache_blob_size); 1140 if (glprog->driver_cache_blob_size > 0) { 1141 blob_write_bytes(metadata, glprog->driver_cache_blob, 1142 glprog->driver_cache_blob_size); 1143 } 1144} 1145 1146static void 1147read_shader_metadata(struct blob_reader *metadata, 1148 struct gl_program *glprog, 1149 gl_linked_shader *linked) 1150{ 1151 unsigned i; 1152 1153 glprog->DualSlotInputs = blob_read_uint64(metadata); 1154 blob_copy_bytes(metadata, (uint8_t *) glprog->TexturesUsed, 1155 sizeof(glprog->TexturesUsed)); 1156 glprog->SamplersUsed = blob_read_uint64(metadata); 1157 1158 blob_copy_bytes(metadata, (uint8_t *) glprog->SamplerUnits, 1159 sizeof(glprog->SamplerUnits)); 1160 blob_copy_bytes(metadata, (uint8_t *) glprog->sh.SamplerTargets, 1161 sizeof(glprog->sh.SamplerTargets)); 1162 glprog->ShadowSamplers = blob_read_uint32(metadata); 1163 glprog->ExternalSamplersUsed = blob_read_uint32(metadata); 1164 glprog->sh.ShaderStorageBlocksWriteAccess = blob_read_uint32(metadata); 1165 1166 blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageAccess, 1167 sizeof(glprog->sh.ImageAccess)); 1168 blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageUnits, 1169 sizeof(glprog->sh.ImageUnits)); 1170 1171 size_t ptr_size = sizeof(GLvoid *); 1172 1173 glprog->sh.NumBindlessSamplers = blob_read_uint32(metadata); 1174 glprog->sh.HasBoundBindlessSampler = blob_read_uint32(metadata); 1175 if (glprog->sh.NumBindlessSamplers > 0) { 1176 glprog->sh.BindlessSamplers = 1177 rzalloc_array(glprog, gl_bindless_sampler, 1178 glprog->sh.NumBindlessSamplers); 1179 1180 for (i = 0; i < glprog->sh.NumBindlessSamplers; i++) { 1181 blob_copy_bytes(metadata, (uint8_t *) &glprog->sh.BindlessSamplers[i], 1182 sizeof(struct gl_bindless_sampler) - ptr_size); 1183 } 1184 } 1185 1186 glprog->sh.NumBindlessImages = blob_read_uint32(metadata); 1187 glprog->sh.HasBoundBindlessImage = blob_read_uint32(metadata); 1188 if (glprog->sh.NumBindlessImages > 0) { 1189 glprog->sh.BindlessImages = 1190 rzalloc_array(glprog, gl_bindless_image, 1191 glprog->sh.NumBindlessImages); 1192 1193 for (i = 0; i < glprog->sh.NumBindlessImages; i++) { 1194 blob_copy_bytes(metadata, (uint8_t *) &glprog->sh.BindlessImages[i], 1195 sizeof(struct gl_bindless_image) - ptr_size); 1196 } 1197 } 1198 1199 glprog->Parameters = _mesa_new_parameter_list(); 1200 read_shader_parameters(metadata, glprog->Parameters); 1201 1202 glprog->driver_cache_blob_size = (size_t)blob_read_uint32(metadata); 1203 if (glprog->driver_cache_blob_size > 0) { 1204 glprog->driver_cache_blob = 1205 (uint8_t*)ralloc_size(glprog, glprog->driver_cache_blob_size); 1206 blob_copy_bytes(metadata, glprog->driver_cache_blob, 1207 glprog->driver_cache_blob_size); 1208 } 1209} 1210 1211static void 1212get_shader_info_and_pointer_sizes(size_t *s_info_size, size_t *s_info_ptrs, 1213 shader_info *info) 1214{ 1215 *s_info_size = sizeof(shader_info); 1216 *s_info_ptrs = sizeof(info->name) + sizeof(info->label); 1217} 1218 1219static void 1220create_linked_shader_and_program(struct gl_context *ctx, 1221 gl_shader_stage stage, 1222 struct gl_shader_program *prog, 1223 struct blob_reader *metadata) 1224{ 1225 struct gl_program *glprog; 1226 1227 struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader); 1228 linked->Stage = stage; 1229 1230 glprog = ctx->Driver.NewProgram(ctx, stage, prog->Name, false); 1231 glprog->info.stage = stage; 1232 linked->Program = glprog; 1233 1234 read_shader_metadata(metadata, glprog, linked); 1235 1236 glprog->info.name = ralloc_strdup(glprog, blob_read_string(metadata)); 1237 glprog->info.label = ralloc_strdup(glprog, blob_read_string(metadata)); 1238 1239 size_t s_info_size, s_info_ptrs; 1240 get_shader_info_and_pointer_sizes(&s_info_size, &s_info_ptrs, 1241 &glprog->info); 1242 1243 /* Restore shader info */ 1244 blob_copy_bytes(metadata, ((uint8_t *) &glprog->info) + s_info_ptrs, 1245 s_info_size - s_info_ptrs); 1246 1247 _mesa_reference_shader_program_data(&glprog->sh.data, prog->data); 1248 _mesa_reference_program(ctx, &linked->Program, glprog); 1249 prog->_LinkedShaders[stage] = linked; 1250} 1251 1252extern "C" void 1253serialize_glsl_program(struct blob *blob, struct gl_context *ctx, 1254 struct gl_shader_program *prog) 1255{ 1256 blob_write_bytes(blob, prog->data->sha1, sizeof(prog->data->sha1)); 1257 1258 write_uniforms(blob, prog); 1259 1260 write_hash_tables(blob, prog); 1261 1262 blob_write_uint32(blob, prog->data->Version); 1263 blob_write_uint32(blob, prog->IsES); 1264 blob_write_uint32(blob, prog->data->linked_stages); 1265 1266 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 1267 struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 1268 if (sh) { 1269 write_shader_metadata(blob, sh); 1270 1271 if (sh->Program->info.name) 1272 blob_write_string(blob, sh->Program->info.name); 1273 else 1274 blob_write_string(blob, ""); 1275 1276 if (sh->Program->info.label) 1277 blob_write_string(blob, sh->Program->info.label); 1278 else 1279 blob_write_string(blob, ""); 1280 1281 size_t s_info_size, s_info_ptrs; 1282 get_shader_info_and_pointer_sizes(&s_info_size, &s_info_ptrs, 1283 &sh->Program->info); 1284 1285 /* Store shader info */ 1286 blob_write_bytes(blob, 1287 ((char *) &sh->Program->info) + s_info_ptrs, 1288 s_info_size - s_info_ptrs); 1289 } 1290 } 1291 1292 write_xfb(blob, prog); 1293 1294 write_uniform_remap_tables(blob, prog); 1295 1296 write_atomic_buffers(blob, prog); 1297 1298 write_buffer_blocks(blob, prog); 1299 1300 write_subroutines(blob, prog); 1301 1302 write_program_resource_list(blob, prog); 1303} 1304 1305extern "C" bool 1306deserialize_glsl_program(struct blob_reader *blob, struct gl_context *ctx, 1307 struct gl_shader_program *prog) 1308{ 1309 /* Fixed function programs generated by Mesa can't be serialized. */ 1310 if (prog->Name == 0) 1311 return false; 1312 1313 assert(prog->data->UniformStorage == NULL); 1314 1315 blob_copy_bytes(blob, prog->data->sha1, sizeof(prog->data->sha1)); 1316 1317 read_uniforms(blob, prog); 1318 1319 read_hash_tables(blob, prog); 1320 1321 prog->data->Version = blob_read_uint32(blob); 1322 prog->IsES = blob_read_uint32(blob); 1323 prog->data->linked_stages = blob_read_uint32(blob); 1324 1325 unsigned mask = prog->data->linked_stages; 1326 while (mask) { 1327 const int j = u_bit_scan(&mask); 1328 create_linked_shader_and_program(ctx, (gl_shader_stage) j, prog, 1329 blob); 1330 } 1331 1332 read_xfb(blob, prog); 1333 1334 read_uniform_remap_tables(blob, prog); 1335 1336 read_atomic_buffers(blob, prog); 1337 1338 read_buffer_blocks(blob, prog); 1339 1340 read_subroutines(blob, prog); 1341 1342 read_program_resource_list(blob, prog); 1343 1344 return !blob->overrun; 1345} 1346