serialize.cpp revision 01e04c3f
101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2014 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg/** 2501e04c3fSmrg * \file serialize.cpp 2601e04c3fSmrg * 2701e04c3fSmrg * GLSL serialization 2801e04c3fSmrg * 2901e04c3fSmrg * Supports serializing and deserializing glsl programs using a blob. 3001e04c3fSmrg */ 3101e04c3fSmrg 3201e04c3fSmrg#include "compiler/glsl_types.h" 3301e04c3fSmrg#include "compiler/shader_info.h" 3401e04c3fSmrg#include "ir_uniform.h" 3501e04c3fSmrg#include "main/mtypes.h" 3601e04c3fSmrg#include "main/shaderobj.h" 3701e04c3fSmrg#include "program/program.h" 3801e04c3fSmrg#include "string_to_uint_map.h" 3901e04c3fSmrg#include "util/bitscan.h" 4001e04c3fSmrg 4101e04c3fSmrg 4201e04c3fSmrgstatic void 4301e04c3fSmrgwrite_subroutines(struct blob *metadata, struct gl_shader_program *prog) 4401e04c3fSmrg{ 4501e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 4601e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 4701e04c3fSmrg if (!sh) 4801e04c3fSmrg continue; 4901e04c3fSmrg 5001e04c3fSmrg struct gl_program *glprog = sh->Program; 5101e04c3fSmrg 5201e04c3fSmrg blob_write_uint32(metadata, glprog->sh.NumSubroutineUniforms); 5301e04c3fSmrg blob_write_uint32(metadata, glprog->sh.MaxSubroutineFunctionIndex); 5401e04c3fSmrg blob_write_uint32(metadata, glprog->sh.NumSubroutineFunctions); 5501e04c3fSmrg for (unsigned j = 0; j < glprog->sh.NumSubroutineFunctions; j++) { 5601e04c3fSmrg int num_types = glprog->sh.SubroutineFunctions[j].num_compat_types; 5701e04c3fSmrg 5801e04c3fSmrg blob_write_string(metadata, glprog->sh.SubroutineFunctions[j].name); 5901e04c3fSmrg blob_write_uint32(metadata, glprog->sh.SubroutineFunctions[j].index); 6001e04c3fSmrg blob_write_uint32(metadata, num_types); 6101e04c3fSmrg 6201e04c3fSmrg for (int k = 0; k < num_types; k++) { 6301e04c3fSmrg encode_type_to_blob(metadata, 6401e04c3fSmrg glprog->sh.SubroutineFunctions[j].types[k]); 6501e04c3fSmrg } 6601e04c3fSmrg } 6701e04c3fSmrg } 6801e04c3fSmrg} 6901e04c3fSmrg 7001e04c3fSmrgstatic void 7101e04c3fSmrgread_subroutines(struct blob_reader *metadata, struct gl_shader_program *prog) 7201e04c3fSmrg{ 7301e04c3fSmrg struct gl_subroutine_function *subs; 7401e04c3fSmrg 7501e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 7601e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 7701e04c3fSmrg if (!sh) 7801e04c3fSmrg continue; 7901e04c3fSmrg 8001e04c3fSmrg struct gl_program *glprog = sh->Program; 8101e04c3fSmrg 8201e04c3fSmrg glprog->sh.NumSubroutineUniforms = blob_read_uint32(metadata); 8301e04c3fSmrg glprog->sh.MaxSubroutineFunctionIndex = blob_read_uint32(metadata); 8401e04c3fSmrg glprog->sh.NumSubroutineFunctions = blob_read_uint32(metadata); 8501e04c3fSmrg 8601e04c3fSmrg subs = rzalloc_array(prog, struct gl_subroutine_function, 8701e04c3fSmrg glprog->sh.NumSubroutineFunctions); 8801e04c3fSmrg glprog->sh.SubroutineFunctions = subs; 8901e04c3fSmrg 9001e04c3fSmrg for (unsigned j = 0; j < glprog->sh.NumSubroutineFunctions; j++) { 9101e04c3fSmrg subs[j].name = ralloc_strdup(prog, blob_read_string (metadata)); 9201e04c3fSmrg subs[j].index = (int) blob_read_uint32(metadata); 9301e04c3fSmrg subs[j].num_compat_types = (int) blob_read_uint32(metadata); 9401e04c3fSmrg 9501e04c3fSmrg subs[j].types = rzalloc_array(prog, const struct glsl_type *, 9601e04c3fSmrg subs[j].num_compat_types); 9701e04c3fSmrg for (int k = 0; k < subs[j].num_compat_types; k++) { 9801e04c3fSmrg subs[j].types[k] = decode_type_from_blob(metadata); 9901e04c3fSmrg } 10001e04c3fSmrg } 10101e04c3fSmrg } 10201e04c3fSmrg} 10301e04c3fSmrg 10401e04c3fSmrgstatic void 10501e04c3fSmrgwrite_buffer_block(struct blob *metadata, struct gl_uniform_block *b) 10601e04c3fSmrg{ 10701e04c3fSmrg blob_write_string(metadata, b->Name); 10801e04c3fSmrg blob_write_uint32(metadata, b->NumUniforms); 10901e04c3fSmrg blob_write_uint32(metadata, b->Binding); 11001e04c3fSmrg blob_write_uint32(metadata, b->UniformBufferSize); 11101e04c3fSmrg blob_write_uint32(metadata, b->stageref); 11201e04c3fSmrg 11301e04c3fSmrg for (unsigned j = 0; j < b->NumUniforms; j++) { 11401e04c3fSmrg blob_write_string(metadata, b->Uniforms[j].Name); 11501e04c3fSmrg blob_write_string(metadata, b->Uniforms[j].IndexName); 11601e04c3fSmrg encode_type_to_blob(metadata, b->Uniforms[j].Type); 11701e04c3fSmrg blob_write_uint32(metadata, b->Uniforms[j].Offset); 11801e04c3fSmrg } 11901e04c3fSmrg} 12001e04c3fSmrg 12101e04c3fSmrgstatic void 12201e04c3fSmrgwrite_buffer_blocks(struct blob *metadata, struct gl_shader_program *prog) 12301e04c3fSmrg{ 12401e04c3fSmrg blob_write_uint32(metadata, prog->data->NumUniformBlocks); 12501e04c3fSmrg blob_write_uint32(metadata, prog->data->NumShaderStorageBlocks); 12601e04c3fSmrg 12701e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) { 12801e04c3fSmrg write_buffer_block(metadata, &prog->data->UniformBlocks[i]); 12901e04c3fSmrg } 13001e04c3fSmrg 13101e04c3fSmrg for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) { 13201e04c3fSmrg write_buffer_block(metadata, &prog->data->ShaderStorageBlocks[i]); 13301e04c3fSmrg } 13401e04c3fSmrg 13501e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 13601e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 13701e04c3fSmrg if (!sh) 13801e04c3fSmrg continue; 13901e04c3fSmrg 14001e04c3fSmrg struct gl_program *glprog = sh->Program; 14101e04c3fSmrg 14201e04c3fSmrg blob_write_uint32(metadata, glprog->info.num_ubos); 14301e04c3fSmrg blob_write_uint32(metadata, glprog->info.num_ssbos); 14401e04c3fSmrg 14501e04c3fSmrg for (unsigned j = 0; j < glprog->info.num_ubos; j++) { 14601e04c3fSmrg uint32_t offset = 14701e04c3fSmrg glprog->sh.UniformBlocks[j] - prog->data->UniformBlocks; 14801e04c3fSmrg blob_write_uint32(metadata, offset); 14901e04c3fSmrg } 15001e04c3fSmrg 15101e04c3fSmrg for (unsigned j = 0; j < glprog->info.num_ssbos; j++) { 15201e04c3fSmrg uint32_t offset = glprog->sh.ShaderStorageBlocks[j] - 15301e04c3fSmrg prog->data->ShaderStorageBlocks; 15401e04c3fSmrg blob_write_uint32(metadata, offset); 15501e04c3fSmrg } 15601e04c3fSmrg } 15701e04c3fSmrg} 15801e04c3fSmrg 15901e04c3fSmrgstatic void 16001e04c3fSmrgread_buffer_block(struct blob_reader *metadata, struct gl_uniform_block *b, 16101e04c3fSmrg struct gl_shader_program *prog) 16201e04c3fSmrg{ 16301e04c3fSmrg b->Name = ralloc_strdup(prog->data, blob_read_string (metadata)); 16401e04c3fSmrg b->NumUniforms = blob_read_uint32(metadata); 16501e04c3fSmrg b->Binding = blob_read_uint32(metadata); 16601e04c3fSmrg b->UniformBufferSize = blob_read_uint32(metadata); 16701e04c3fSmrg b->stageref = blob_read_uint32(metadata); 16801e04c3fSmrg 16901e04c3fSmrg b->Uniforms = 17001e04c3fSmrg rzalloc_array(prog->data, struct gl_uniform_buffer_variable, 17101e04c3fSmrg b->NumUniforms); 17201e04c3fSmrg for (unsigned j = 0; j < b->NumUniforms; j++) { 17301e04c3fSmrg b->Uniforms[j].Name = ralloc_strdup(prog->data, 17401e04c3fSmrg blob_read_string (metadata)); 17501e04c3fSmrg 17601e04c3fSmrg char *index_name = blob_read_string(metadata); 17701e04c3fSmrg if (strcmp(b->Uniforms[j].Name, index_name) == 0) { 17801e04c3fSmrg b->Uniforms[j].IndexName = b->Uniforms[j].Name; 17901e04c3fSmrg } else { 18001e04c3fSmrg b->Uniforms[j].IndexName = ralloc_strdup(prog->data, index_name); 18101e04c3fSmrg } 18201e04c3fSmrg 18301e04c3fSmrg b->Uniforms[j].Type = decode_type_from_blob(metadata); 18401e04c3fSmrg b->Uniforms[j].Offset = blob_read_uint32(metadata); 18501e04c3fSmrg } 18601e04c3fSmrg} 18701e04c3fSmrg 18801e04c3fSmrgstatic void 18901e04c3fSmrgread_buffer_blocks(struct blob_reader *metadata, 19001e04c3fSmrg struct gl_shader_program *prog) 19101e04c3fSmrg{ 19201e04c3fSmrg prog->data->NumUniformBlocks = blob_read_uint32(metadata); 19301e04c3fSmrg prog->data->NumShaderStorageBlocks = blob_read_uint32(metadata); 19401e04c3fSmrg 19501e04c3fSmrg prog->data->UniformBlocks = 19601e04c3fSmrg rzalloc_array(prog->data, struct gl_uniform_block, 19701e04c3fSmrg prog->data->NumUniformBlocks); 19801e04c3fSmrg 19901e04c3fSmrg prog->data->ShaderStorageBlocks = 20001e04c3fSmrg rzalloc_array(prog->data, struct gl_uniform_block, 20101e04c3fSmrg prog->data->NumShaderStorageBlocks); 20201e04c3fSmrg 20301e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) { 20401e04c3fSmrg read_buffer_block(metadata, &prog->data->UniformBlocks[i], prog); 20501e04c3fSmrg } 20601e04c3fSmrg 20701e04c3fSmrg for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) { 20801e04c3fSmrg read_buffer_block(metadata, &prog->data->ShaderStorageBlocks[i], prog); 20901e04c3fSmrg } 21001e04c3fSmrg 21101e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 21201e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 21301e04c3fSmrg if (!sh) 21401e04c3fSmrg continue; 21501e04c3fSmrg 21601e04c3fSmrg struct gl_program *glprog = sh->Program; 21701e04c3fSmrg 21801e04c3fSmrg glprog->info.num_ubos = blob_read_uint32(metadata); 21901e04c3fSmrg glprog->info.num_ssbos = blob_read_uint32(metadata); 22001e04c3fSmrg 22101e04c3fSmrg glprog->sh.UniformBlocks = 22201e04c3fSmrg rzalloc_array(glprog, gl_uniform_block *, glprog->info.num_ubos); 22301e04c3fSmrg glprog->sh.ShaderStorageBlocks = 22401e04c3fSmrg rzalloc_array(glprog, gl_uniform_block *, glprog->info.num_ssbos); 22501e04c3fSmrg 22601e04c3fSmrg for (unsigned j = 0; j < glprog->info.num_ubos; j++) { 22701e04c3fSmrg uint32_t offset = blob_read_uint32(metadata); 22801e04c3fSmrg glprog->sh.UniformBlocks[j] = prog->data->UniformBlocks + offset; 22901e04c3fSmrg } 23001e04c3fSmrg 23101e04c3fSmrg for (unsigned j = 0; j < glprog->info.num_ssbos; j++) { 23201e04c3fSmrg uint32_t offset = blob_read_uint32(metadata); 23301e04c3fSmrg glprog->sh.ShaderStorageBlocks[j] = 23401e04c3fSmrg prog->data->ShaderStorageBlocks + offset; 23501e04c3fSmrg } 23601e04c3fSmrg } 23701e04c3fSmrg} 23801e04c3fSmrg 23901e04c3fSmrgstatic void 24001e04c3fSmrgwrite_atomic_buffers(struct blob *metadata, struct gl_shader_program *prog) 24101e04c3fSmrg{ 24201e04c3fSmrg blob_write_uint32(metadata, prog->data->NumAtomicBuffers); 24301e04c3fSmrg 24401e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 24501e04c3fSmrg if (prog->_LinkedShaders[i]) { 24601e04c3fSmrg struct gl_program *glprog = prog->_LinkedShaders[i]->Program; 24701e04c3fSmrg blob_write_uint32(metadata, glprog->info.num_abos); 24801e04c3fSmrg } 24901e04c3fSmrg } 25001e04c3fSmrg 25101e04c3fSmrg for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) { 25201e04c3fSmrg blob_write_uint32(metadata, prog->data->AtomicBuffers[i].Binding); 25301e04c3fSmrg blob_write_uint32(metadata, prog->data->AtomicBuffers[i].MinimumSize); 25401e04c3fSmrg blob_write_uint32(metadata, prog->data->AtomicBuffers[i].NumUniforms); 25501e04c3fSmrg 25601e04c3fSmrg blob_write_bytes(metadata, prog->data->AtomicBuffers[i].StageReferences, 25701e04c3fSmrg sizeof(prog->data->AtomicBuffers[i].StageReferences)); 25801e04c3fSmrg 25901e04c3fSmrg for (unsigned j = 0; j < prog->data->AtomicBuffers[i].NumUniforms; j++) { 26001e04c3fSmrg blob_write_uint32(metadata, prog->data->AtomicBuffers[i].Uniforms[j]); 26101e04c3fSmrg } 26201e04c3fSmrg } 26301e04c3fSmrg} 26401e04c3fSmrg 26501e04c3fSmrgstatic void 26601e04c3fSmrgread_atomic_buffers(struct blob_reader *metadata, 26701e04c3fSmrg struct gl_shader_program *prog) 26801e04c3fSmrg{ 26901e04c3fSmrg prog->data->NumAtomicBuffers = blob_read_uint32(metadata); 27001e04c3fSmrg prog->data->AtomicBuffers = 27101e04c3fSmrg rzalloc_array(prog, gl_active_atomic_buffer, 27201e04c3fSmrg prog->data->NumAtomicBuffers); 27301e04c3fSmrg 27401e04c3fSmrg struct gl_active_atomic_buffer **stage_buff_list[MESA_SHADER_STAGES]; 27501e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 27601e04c3fSmrg if (prog->_LinkedShaders[i]) { 27701e04c3fSmrg struct gl_program *glprog = prog->_LinkedShaders[i]->Program; 27801e04c3fSmrg 27901e04c3fSmrg glprog->info.num_abos = blob_read_uint32(metadata); 28001e04c3fSmrg glprog->sh.AtomicBuffers = 28101e04c3fSmrg rzalloc_array(glprog, gl_active_atomic_buffer *, 28201e04c3fSmrg glprog->info.num_abos); 28301e04c3fSmrg stage_buff_list[i] = glprog->sh.AtomicBuffers; 28401e04c3fSmrg } 28501e04c3fSmrg } 28601e04c3fSmrg 28701e04c3fSmrg for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) { 28801e04c3fSmrg prog->data->AtomicBuffers[i].Binding = blob_read_uint32(metadata); 28901e04c3fSmrg prog->data->AtomicBuffers[i].MinimumSize = blob_read_uint32(metadata); 29001e04c3fSmrg prog->data->AtomicBuffers[i].NumUniforms = blob_read_uint32(metadata); 29101e04c3fSmrg 29201e04c3fSmrg blob_copy_bytes(metadata, 29301e04c3fSmrg (uint8_t *) &prog->data->AtomicBuffers[i].StageReferences, 29401e04c3fSmrg sizeof(prog->data->AtomicBuffers[i].StageReferences)); 29501e04c3fSmrg 29601e04c3fSmrg prog->data->AtomicBuffers[i].Uniforms = rzalloc_array(prog, unsigned, 29701e04c3fSmrg prog->data->AtomicBuffers[i].NumUniforms); 29801e04c3fSmrg 29901e04c3fSmrg for (unsigned j = 0; j < prog->data->AtomicBuffers[i].NumUniforms; j++) { 30001e04c3fSmrg prog->data->AtomicBuffers[i].Uniforms[j] = blob_read_uint32(metadata); 30101e04c3fSmrg } 30201e04c3fSmrg 30301e04c3fSmrg for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) { 30401e04c3fSmrg if (prog->data->AtomicBuffers[i].StageReferences[j]) { 30501e04c3fSmrg *stage_buff_list[j] = &prog->data->AtomicBuffers[i]; 30601e04c3fSmrg stage_buff_list[j]++; 30701e04c3fSmrg } 30801e04c3fSmrg } 30901e04c3fSmrg } 31001e04c3fSmrg} 31101e04c3fSmrg 31201e04c3fSmrgstatic void 31301e04c3fSmrgwrite_xfb(struct blob *metadata, struct gl_shader_program *shProg) 31401e04c3fSmrg{ 31501e04c3fSmrg struct gl_program *prog = shProg->last_vert_prog; 31601e04c3fSmrg 31701e04c3fSmrg if (!prog) { 31801e04c3fSmrg blob_write_uint32(metadata, ~0u); 31901e04c3fSmrg return; 32001e04c3fSmrg } 32101e04c3fSmrg 32201e04c3fSmrg struct gl_transform_feedback_info *ltf = prog->sh.LinkedTransformFeedback; 32301e04c3fSmrg 32401e04c3fSmrg blob_write_uint32(metadata, prog->info.stage); 32501e04c3fSmrg 32601e04c3fSmrg /* Data set by glTransformFeedbackVaryings. */ 32701e04c3fSmrg blob_write_uint32(metadata, shProg->TransformFeedback.BufferMode); 32801e04c3fSmrg blob_write_bytes(metadata, shProg->TransformFeedback.BufferStride, 32901e04c3fSmrg sizeof(shProg->TransformFeedback.BufferStride)); 33001e04c3fSmrg blob_write_uint32(metadata, shProg->TransformFeedback.NumVarying); 33101e04c3fSmrg for (unsigned i = 0; i < shProg->TransformFeedback.NumVarying; i++) 33201e04c3fSmrg blob_write_string(metadata, shProg->TransformFeedback.VaryingNames[i]); 33301e04c3fSmrg 33401e04c3fSmrg blob_write_uint32(metadata, ltf->NumOutputs); 33501e04c3fSmrg blob_write_uint32(metadata, ltf->ActiveBuffers); 33601e04c3fSmrg blob_write_uint32(metadata, ltf->NumVarying); 33701e04c3fSmrg 33801e04c3fSmrg blob_write_bytes(metadata, ltf->Outputs, 33901e04c3fSmrg sizeof(struct gl_transform_feedback_output) * 34001e04c3fSmrg ltf->NumOutputs); 34101e04c3fSmrg 34201e04c3fSmrg for (int i = 0; i < ltf->NumVarying; i++) { 34301e04c3fSmrg blob_write_string(metadata, ltf->Varyings[i].Name); 34401e04c3fSmrg blob_write_uint32(metadata, ltf->Varyings[i].Type); 34501e04c3fSmrg blob_write_uint32(metadata, ltf->Varyings[i].BufferIndex); 34601e04c3fSmrg blob_write_uint32(metadata, ltf->Varyings[i].Size); 34701e04c3fSmrg blob_write_uint32(metadata, ltf->Varyings[i].Offset); 34801e04c3fSmrg } 34901e04c3fSmrg 35001e04c3fSmrg blob_write_bytes(metadata, ltf->Buffers, 35101e04c3fSmrg sizeof(struct gl_transform_feedback_buffer) * 35201e04c3fSmrg MAX_FEEDBACK_BUFFERS); 35301e04c3fSmrg} 35401e04c3fSmrg 35501e04c3fSmrgstatic void 35601e04c3fSmrgread_xfb(struct blob_reader *metadata, struct gl_shader_program *shProg) 35701e04c3fSmrg{ 35801e04c3fSmrg unsigned xfb_stage = blob_read_uint32(metadata); 35901e04c3fSmrg 36001e04c3fSmrg if (xfb_stage == ~0u) 36101e04c3fSmrg return; 36201e04c3fSmrg 36301e04c3fSmrg if (shProg->TransformFeedback.VaryingNames) { 36401e04c3fSmrg for (unsigned i = 0; i < shProg->TransformFeedback.NumVarying; ++i) 36501e04c3fSmrg free(shProg->TransformFeedback.VaryingNames[i]); 36601e04c3fSmrg } 36701e04c3fSmrg 36801e04c3fSmrg /* Data set by glTransformFeedbackVaryings. */ 36901e04c3fSmrg shProg->TransformFeedback.BufferMode = blob_read_uint32(metadata); 37001e04c3fSmrg blob_copy_bytes(metadata, &shProg->TransformFeedback.BufferStride, 37101e04c3fSmrg sizeof(shProg->TransformFeedback.BufferStride)); 37201e04c3fSmrg shProg->TransformFeedback.NumVarying = blob_read_uint32(metadata); 37301e04c3fSmrg 37401e04c3fSmrg shProg->TransformFeedback.VaryingNames = (char **) 37501e04c3fSmrg realloc(shProg->TransformFeedback.VaryingNames, 37601e04c3fSmrg shProg->TransformFeedback.NumVarying * sizeof(GLchar *)); 37701e04c3fSmrg /* Note, malloc used with VaryingNames. */ 37801e04c3fSmrg for (unsigned i = 0; i < shProg->TransformFeedback.NumVarying; i++) 37901e04c3fSmrg shProg->TransformFeedback.VaryingNames[i] = 38001e04c3fSmrg strdup(blob_read_string(metadata)); 38101e04c3fSmrg 38201e04c3fSmrg struct gl_program *prog = shProg->_LinkedShaders[xfb_stage]->Program; 38301e04c3fSmrg struct gl_transform_feedback_info *ltf = 38401e04c3fSmrg rzalloc(prog, struct gl_transform_feedback_info); 38501e04c3fSmrg 38601e04c3fSmrg prog->sh.LinkedTransformFeedback = ltf; 38701e04c3fSmrg shProg->last_vert_prog = prog; 38801e04c3fSmrg 38901e04c3fSmrg ltf->NumOutputs = blob_read_uint32(metadata); 39001e04c3fSmrg ltf->ActiveBuffers = blob_read_uint32(metadata); 39101e04c3fSmrg ltf->NumVarying = blob_read_uint32(metadata); 39201e04c3fSmrg 39301e04c3fSmrg ltf->Outputs = rzalloc_array(prog, struct gl_transform_feedback_output, 39401e04c3fSmrg ltf->NumOutputs); 39501e04c3fSmrg 39601e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) ltf->Outputs, 39701e04c3fSmrg sizeof(struct gl_transform_feedback_output) * 39801e04c3fSmrg ltf->NumOutputs); 39901e04c3fSmrg 40001e04c3fSmrg ltf->Varyings = rzalloc_array(prog, 40101e04c3fSmrg struct gl_transform_feedback_varying_info, 40201e04c3fSmrg ltf->NumVarying); 40301e04c3fSmrg 40401e04c3fSmrg for (int i = 0; i < ltf->NumVarying; i++) { 40501e04c3fSmrg ltf->Varyings[i].Name = ralloc_strdup(prog, blob_read_string(metadata)); 40601e04c3fSmrg ltf->Varyings[i].Type = blob_read_uint32(metadata); 40701e04c3fSmrg ltf->Varyings[i].BufferIndex = blob_read_uint32(metadata); 40801e04c3fSmrg ltf->Varyings[i].Size = blob_read_uint32(metadata); 40901e04c3fSmrg ltf->Varyings[i].Offset = blob_read_uint32(metadata); 41001e04c3fSmrg } 41101e04c3fSmrg 41201e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) ltf->Buffers, 41301e04c3fSmrg sizeof(struct gl_transform_feedback_buffer) * 41401e04c3fSmrg MAX_FEEDBACK_BUFFERS); 41501e04c3fSmrg} 41601e04c3fSmrg 41701e04c3fSmrgstatic bool 41801e04c3fSmrghas_uniform_storage(struct gl_shader_program *prog, unsigned idx) 41901e04c3fSmrg{ 42001e04c3fSmrg if (!prog->data->UniformStorage[idx].builtin && 42101e04c3fSmrg !prog->data->UniformStorage[idx].is_shader_storage && 42201e04c3fSmrg prog->data->UniformStorage[idx].block_index == -1) 42301e04c3fSmrg return true; 42401e04c3fSmrg 42501e04c3fSmrg return false; 42601e04c3fSmrg} 42701e04c3fSmrg 42801e04c3fSmrgstatic void 42901e04c3fSmrgwrite_uniforms(struct blob *metadata, struct gl_shader_program *prog) 43001e04c3fSmrg{ 43101e04c3fSmrg blob_write_uint32(metadata, prog->SamplersValidated); 43201e04c3fSmrg blob_write_uint32(metadata, prog->data->NumUniformStorage); 43301e04c3fSmrg blob_write_uint32(metadata, prog->data->NumUniformDataSlots); 43401e04c3fSmrg 43501e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 43601e04c3fSmrg encode_type_to_blob(metadata, prog->data->UniformStorage[i].type); 43701e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].array_elements); 43801e04c3fSmrg blob_write_string(metadata, prog->data->UniformStorage[i].name); 43901e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].builtin); 44001e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].remap_location); 44101e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].block_index); 44201e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].atomic_buffer_index); 44301e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].offset); 44401e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].array_stride); 44501e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].hidden); 44601e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].is_shader_storage); 44701e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].active_shader_mask); 44801e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].matrix_stride); 44901e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].row_major); 45001e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].is_bindless); 45101e04c3fSmrg blob_write_uint32(metadata, 45201e04c3fSmrg prog->data->UniformStorage[i].num_compatible_subroutines); 45301e04c3fSmrg blob_write_uint32(metadata, 45401e04c3fSmrg prog->data->UniformStorage[i].top_level_array_size); 45501e04c3fSmrg blob_write_uint32(metadata, 45601e04c3fSmrg prog->data->UniformStorage[i].top_level_array_stride); 45701e04c3fSmrg 45801e04c3fSmrg if (has_uniform_storage(prog, i)) { 45901e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].storage - 46001e04c3fSmrg prog->data->UniformDataSlots); 46101e04c3fSmrg } 46201e04c3fSmrg 46301e04c3fSmrg blob_write_bytes(metadata, prog->data->UniformStorage[i].opaque, 46401e04c3fSmrg sizeof(prog->data->UniformStorage[i].opaque)); 46501e04c3fSmrg } 46601e04c3fSmrg 46701e04c3fSmrg /* Here we cache all uniform values. We do this to retain values for 46801e04c3fSmrg * uniforms with initialisers and also hidden uniforms that may be lowered 46901e04c3fSmrg * constant arrays. We could possibly just store the values we need but for 47001e04c3fSmrg * now we just store everything. 47101e04c3fSmrg */ 47201e04c3fSmrg blob_write_uint32(metadata, prog->data->NumHiddenUniforms); 47301e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 47401e04c3fSmrg if (has_uniform_storage(prog, i)) { 47501e04c3fSmrg unsigned vec_size = 47601e04c3fSmrg prog->data->UniformStorage[i].type->component_slots() * 47701e04c3fSmrg MAX2(prog->data->UniformStorage[i].array_elements, 1); 47801e04c3fSmrg unsigned slot = 47901e04c3fSmrg prog->data->UniformStorage[i].storage - 48001e04c3fSmrg prog->data->UniformDataSlots; 48101e04c3fSmrg blob_write_bytes(metadata, &prog->data->UniformDataDefaults[slot], 48201e04c3fSmrg sizeof(union gl_constant_value) * vec_size); 48301e04c3fSmrg } 48401e04c3fSmrg } 48501e04c3fSmrg} 48601e04c3fSmrg 48701e04c3fSmrgstatic void 48801e04c3fSmrgread_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog) 48901e04c3fSmrg{ 49001e04c3fSmrg struct gl_uniform_storage *uniforms; 49101e04c3fSmrg union gl_constant_value *data; 49201e04c3fSmrg 49301e04c3fSmrg prog->SamplersValidated = blob_read_uint32(metadata); 49401e04c3fSmrg prog->data->NumUniformStorage = blob_read_uint32(metadata); 49501e04c3fSmrg prog->data->NumUniformDataSlots = blob_read_uint32(metadata); 49601e04c3fSmrg 49701e04c3fSmrg uniforms = rzalloc_array(prog->data, struct gl_uniform_storage, 49801e04c3fSmrg prog->data->NumUniformStorage); 49901e04c3fSmrg prog->data->UniformStorage = uniforms; 50001e04c3fSmrg 50101e04c3fSmrg data = rzalloc_array(uniforms, union gl_constant_value, 50201e04c3fSmrg prog->data->NumUniformDataSlots); 50301e04c3fSmrg prog->data->UniformDataSlots = data; 50401e04c3fSmrg prog->data->UniformDataDefaults = 50501e04c3fSmrg rzalloc_array(uniforms, union gl_constant_value, 50601e04c3fSmrg prog->data->NumUniformDataSlots); 50701e04c3fSmrg 50801e04c3fSmrg prog->UniformHash = new string_to_uint_map; 50901e04c3fSmrg 51001e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 51101e04c3fSmrg uniforms[i].type = decode_type_from_blob(metadata); 51201e04c3fSmrg uniforms[i].array_elements = blob_read_uint32(metadata); 51301e04c3fSmrg uniforms[i].name = ralloc_strdup(prog, blob_read_string (metadata)); 51401e04c3fSmrg uniforms[i].builtin = blob_read_uint32(metadata); 51501e04c3fSmrg uniforms[i].remap_location = blob_read_uint32(metadata); 51601e04c3fSmrg uniforms[i].block_index = blob_read_uint32(metadata); 51701e04c3fSmrg uniforms[i].atomic_buffer_index = blob_read_uint32(metadata); 51801e04c3fSmrg uniforms[i].offset = blob_read_uint32(metadata); 51901e04c3fSmrg uniforms[i].array_stride = blob_read_uint32(metadata); 52001e04c3fSmrg uniforms[i].hidden = blob_read_uint32(metadata); 52101e04c3fSmrg uniforms[i].is_shader_storage = blob_read_uint32(metadata); 52201e04c3fSmrg uniforms[i].active_shader_mask = blob_read_uint32(metadata); 52301e04c3fSmrg uniforms[i].matrix_stride = blob_read_uint32(metadata); 52401e04c3fSmrg uniforms[i].row_major = blob_read_uint32(metadata); 52501e04c3fSmrg uniforms[i].is_bindless = blob_read_uint32(metadata); 52601e04c3fSmrg uniforms[i].num_compatible_subroutines = blob_read_uint32(metadata); 52701e04c3fSmrg uniforms[i].top_level_array_size = blob_read_uint32(metadata); 52801e04c3fSmrg uniforms[i].top_level_array_stride = blob_read_uint32(metadata); 52901e04c3fSmrg prog->UniformHash->put(i, uniforms[i].name); 53001e04c3fSmrg 53101e04c3fSmrg if (has_uniform_storage(prog, i)) { 53201e04c3fSmrg uniforms[i].storage = data + blob_read_uint32(metadata); 53301e04c3fSmrg } 53401e04c3fSmrg 53501e04c3fSmrg memcpy(uniforms[i].opaque, 53601e04c3fSmrg blob_read_bytes(metadata, sizeof(uniforms[i].opaque)), 53701e04c3fSmrg sizeof(uniforms[i].opaque)); 53801e04c3fSmrg } 53901e04c3fSmrg 54001e04c3fSmrg /* Restore uniform values. */ 54101e04c3fSmrg prog->data->NumHiddenUniforms = blob_read_uint32(metadata); 54201e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 54301e04c3fSmrg if (has_uniform_storage(prog, i)) { 54401e04c3fSmrg unsigned vec_size = 54501e04c3fSmrg prog->data->UniformStorage[i].type->component_slots() * 54601e04c3fSmrg MAX2(prog->data->UniformStorage[i].array_elements, 1); 54701e04c3fSmrg unsigned slot = 54801e04c3fSmrg prog->data->UniformStorage[i].storage - 54901e04c3fSmrg prog->data->UniformDataSlots; 55001e04c3fSmrg blob_copy_bytes(metadata, 55101e04c3fSmrg (uint8_t *) &prog->data->UniformDataSlots[slot], 55201e04c3fSmrg sizeof(union gl_constant_value) * vec_size); 55301e04c3fSmrg 55401e04c3fSmrg assert(vec_size + prog->data->UniformStorage[i].storage <= 55501e04c3fSmrg data + prog->data->NumUniformDataSlots); 55601e04c3fSmrg } 55701e04c3fSmrg } 55801e04c3fSmrg 55901e04c3fSmrg memcpy(prog->data->UniformDataDefaults, prog->data->UniformDataSlots, 56001e04c3fSmrg sizeof(union gl_constant_value) * prog->data->NumUniformDataSlots); 56101e04c3fSmrg} 56201e04c3fSmrg 56301e04c3fSmrgenum uniform_remap_type 56401e04c3fSmrg{ 56501e04c3fSmrg remap_type_inactive_explicit_location, 56601e04c3fSmrg remap_type_null_ptr, 56701e04c3fSmrg remap_type_uniform_offset 56801e04c3fSmrg}; 56901e04c3fSmrg 57001e04c3fSmrgstatic void 57101e04c3fSmrgwrite_uniform_remap_table_entry(struct blob *metadata, 57201e04c3fSmrg gl_uniform_storage *uniform_storage, 57301e04c3fSmrg gl_uniform_storage *entry) 57401e04c3fSmrg{ 57501e04c3fSmrg if (entry == INACTIVE_UNIFORM_EXPLICIT_LOCATION) { 57601e04c3fSmrg blob_write_uint32(metadata, remap_type_inactive_explicit_location); 57701e04c3fSmrg } else if (entry == NULL) { 57801e04c3fSmrg blob_write_uint32(metadata, remap_type_null_ptr); 57901e04c3fSmrg } else { 58001e04c3fSmrg blob_write_uint32(metadata, remap_type_uniform_offset); 58101e04c3fSmrg 58201e04c3fSmrg uint32_t offset = entry - uniform_storage; 58301e04c3fSmrg blob_write_uint32(metadata, offset); 58401e04c3fSmrg } 58501e04c3fSmrg} 58601e04c3fSmrg 58701e04c3fSmrgstatic void 58801e04c3fSmrgwrite_uniform_remap_tables(struct blob *metadata, 58901e04c3fSmrg struct gl_shader_program *prog) 59001e04c3fSmrg{ 59101e04c3fSmrg blob_write_uint32(metadata, prog->NumUniformRemapTable); 59201e04c3fSmrg 59301e04c3fSmrg for (unsigned i = 0; i < prog->NumUniformRemapTable; i++) { 59401e04c3fSmrg write_uniform_remap_table_entry(metadata, prog->data->UniformStorage, 59501e04c3fSmrg prog->UniformRemapTable[i]); 59601e04c3fSmrg } 59701e04c3fSmrg 59801e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 59901e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 60001e04c3fSmrg if (sh) { 60101e04c3fSmrg struct gl_program *glprog = sh->Program; 60201e04c3fSmrg blob_write_uint32(metadata, glprog->sh.NumSubroutineUniformRemapTable); 60301e04c3fSmrg 60401e04c3fSmrg for (unsigned j = 0; j < glprog->sh.NumSubroutineUniformRemapTable; j++) { 60501e04c3fSmrg write_uniform_remap_table_entry(metadata, 60601e04c3fSmrg prog->data->UniformStorage, 60701e04c3fSmrg glprog->sh.SubroutineUniformRemapTable[j]); 60801e04c3fSmrg } 60901e04c3fSmrg } 61001e04c3fSmrg } 61101e04c3fSmrg} 61201e04c3fSmrg 61301e04c3fSmrgstatic void 61401e04c3fSmrgread_uniform_remap_table_entry(struct blob_reader *metadata, 61501e04c3fSmrg gl_uniform_storage *uniform_storage, 61601e04c3fSmrg gl_uniform_storage **entry, 61701e04c3fSmrg enum uniform_remap_type type) 61801e04c3fSmrg{ 61901e04c3fSmrg if (type == remap_type_inactive_explicit_location) { 62001e04c3fSmrg *entry = INACTIVE_UNIFORM_EXPLICIT_LOCATION; 62101e04c3fSmrg } else if (type == remap_type_null_ptr) { 62201e04c3fSmrg *entry = NULL; 62301e04c3fSmrg } else { 62401e04c3fSmrg uint32_t uni_offset = blob_read_uint32(metadata); 62501e04c3fSmrg *entry = uniform_storage + uni_offset; 62601e04c3fSmrg } 62701e04c3fSmrg} 62801e04c3fSmrg 62901e04c3fSmrgstatic void 63001e04c3fSmrgread_uniform_remap_tables(struct blob_reader *metadata, 63101e04c3fSmrg struct gl_shader_program *prog) 63201e04c3fSmrg{ 63301e04c3fSmrg prog->NumUniformRemapTable = blob_read_uint32(metadata); 63401e04c3fSmrg 63501e04c3fSmrg prog->UniformRemapTable = rzalloc_array(prog, struct gl_uniform_storage *, 63601e04c3fSmrg prog->NumUniformRemapTable); 63701e04c3fSmrg 63801e04c3fSmrg for (unsigned i = 0; i < prog->NumUniformRemapTable; i++) { 63901e04c3fSmrg enum uniform_remap_type type = 64001e04c3fSmrg (enum uniform_remap_type) blob_read_uint32(metadata); 64101e04c3fSmrg 64201e04c3fSmrg read_uniform_remap_table_entry(metadata, prog->data->UniformStorage, 64301e04c3fSmrg &prog->UniformRemapTable[i], type); 64401e04c3fSmrg } 64501e04c3fSmrg 64601e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 64701e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 64801e04c3fSmrg if (sh) { 64901e04c3fSmrg struct gl_program *glprog = sh->Program; 65001e04c3fSmrg glprog->sh.NumSubroutineUniformRemapTable = blob_read_uint32(metadata); 65101e04c3fSmrg 65201e04c3fSmrg glprog->sh.SubroutineUniformRemapTable = 65301e04c3fSmrg rzalloc_array(glprog, struct gl_uniform_storage *, 65401e04c3fSmrg glprog->sh.NumSubroutineUniformRemapTable); 65501e04c3fSmrg 65601e04c3fSmrg for (unsigned j = 0; j < glprog->sh.NumSubroutineUniformRemapTable; j++) { 65701e04c3fSmrg enum uniform_remap_type type = 65801e04c3fSmrg (enum uniform_remap_type) blob_read_uint32(metadata); 65901e04c3fSmrg 66001e04c3fSmrg read_uniform_remap_table_entry(metadata, 66101e04c3fSmrg prog->data->UniformStorage, 66201e04c3fSmrg &glprog->sh.SubroutineUniformRemapTable[j], 66301e04c3fSmrg type); 66401e04c3fSmrg } 66501e04c3fSmrg } 66601e04c3fSmrg } 66701e04c3fSmrg} 66801e04c3fSmrg 66901e04c3fSmrgstruct whte_closure 67001e04c3fSmrg{ 67101e04c3fSmrg struct blob *blob; 67201e04c3fSmrg size_t num_entries; 67301e04c3fSmrg}; 67401e04c3fSmrg 67501e04c3fSmrgstatic void 67601e04c3fSmrgwrite_hash_table_entry(const char *key, unsigned value, void *closure) 67701e04c3fSmrg{ 67801e04c3fSmrg struct whte_closure *whte = (struct whte_closure *) closure; 67901e04c3fSmrg 68001e04c3fSmrg blob_write_string(whte->blob, key); 68101e04c3fSmrg blob_write_uint32(whte->blob, value); 68201e04c3fSmrg 68301e04c3fSmrg whte->num_entries++; 68401e04c3fSmrg} 68501e04c3fSmrg 68601e04c3fSmrgstatic void 68701e04c3fSmrgwrite_hash_table(struct blob *metadata, struct string_to_uint_map *hash) 68801e04c3fSmrg{ 68901e04c3fSmrg size_t offset; 69001e04c3fSmrg struct whte_closure whte; 69101e04c3fSmrg 69201e04c3fSmrg whte.blob = metadata; 69301e04c3fSmrg whte.num_entries = 0; 69401e04c3fSmrg 69501e04c3fSmrg offset = metadata->size; 69601e04c3fSmrg 69701e04c3fSmrg /* Write a placeholder for the hashtable size. */ 69801e04c3fSmrg blob_write_uint32 (metadata, 0); 69901e04c3fSmrg 70001e04c3fSmrg hash->iterate(write_hash_table_entry, &whte); 70101e04c3fSmrg 70201e04c3fSmrg /* Overwrite with the computed number of entries written. */ 70301e04c3fSmrg blob_overwrite_uint32 (metadata, offset, whte.num_entries); 70401e04c3fSmrg} 70501e04c3fSmrg 70601e04c3fSmrgstatic void 70701e04c3fSmrgread_hash_table(struct blob_reader *metadata, struct string_to_uint_map *hash) 70801e04c3fSmrg{ 70901e04c3fSmrg size_t i, num_entries; 71001e04c3fSmrg const char *key; 71101e04c3fSmrg uint32_t value; 71201e04c3fSmrg 71301e04c3fSmrg num_entries = blob_read_uint32 (metadata); 71401e04c3fSmrg 71501e04c3fSmrg for (i = 0; i < num_entries; i++) { 71601e04c3fSmrg key = blob_read_string(metadata); 71701e04c3fSmrg value = blob_read_uint32(metadata); 71801e04c3fSmrg 71901e04c3fSmrg hash->put(value, key); 72001e04c3fSmrg } 72101e04c3fSmrg} 72201e04c3fSmrg 72301e04c3fSmrgstatic void 72401e04c3fSmrgwrite_hash_tables(struct blob *metadata, struct gl_shader_program *prog) 72501e04c3fSmrg{ 72601e04c3fSmrg write_hash_table(metadata, prog->AttributeBindings); 72701e04c3fSmrg write_hash_table(metadata, prog->FragDataBindings); 72801e04c3fSmrg write_hash_table(metadata, prog->FragDataIndexBindings); 72901e04c3fSmrg} 73001e04c3fSmrg 73101e04c3fSmrgstatic void 73201e04c3fSmrgread_hash_tables(struct blob_reader *metadata, struct gl_shader_program *prog) 73301e04c3fSmrg{ 73401e04c3fSmrg read_hash_table(metadata, prog->AttributeBindings); 73501e04c3fSmrg read_hash_table(metadata, prog->FragDataBindings); 73601e04c3fSmrg read_hash_table(metadata, prog->FragDataIndexBindings); 73701e04c3fSmrg} 73801e04c3fSmrg 73901e04c3fSmrgstatic void 74001e04c3fSmrgwrite_shader_subroutine_index(struct blob *metadata, 74101e04c3fSmrg struct gl_linked_shader *sh, 74201e04c3fSmrg struct gl_program_resource *res) 74301e04c3fSmrg{ 74401e04c3fSmrg assert(sh); 74501e04c3fSmrg 74601e04c3fSmrg for (unsigned j = 0; j < sh->Program->sh.NumSubroutineFunctions; j++) { 74701e04c3fSmrg if (strcmp(((gl_subroutine_function *)res->Data)->name, 74801e04c3fSmrg sh->Program->sh.SubroutineFunctions[j].name) == 0) { 74901e04c3fSmrg blob_write_uint32(metadata, j); 75001e04c3fSmrg break; 75101e04c3fSmrg } 75201e04c3fSmrg } 75301e04c3fSmrg} 75401e04c3fSmrg 75501e04c3fSmrgstatic void 75601e04c3fSmrgget_shader_var_and_pointer_sizes(size_t *s_var_size, size_t *s_var_ptrs, 75701e04c3fSmrg const gl_shader_variable *var) 75801e04c3fSmrg{ 75901e04c3fSmrg *s_var_size = sizeof(gl_shader_variable); 76001e04c3fSmrg *s_var_ptrs = 76101e04c3fSmrg sizeof(var->type) + 76201e04c3fSmrg sizeof(var->interface_type) + 76301e04c3fSmrg sizeof(var->outermost_struct_type) + 76401e04c3fSmrg sizeof(var->name); 76501e04c3fSmrg} 76601e04c3fSmrg 76701e04c3fSmrgenum uniform_type 76801e04c3fSmrg{ 76901e04c3fSmrg uniform_remapped, 77001e04c3fSmrg uniform_not_remapped 77101e04c3fSmrg}; 77201e04c3fSmrg 77301e04c3fSmrgstatic void 77401e04c3fSmrgwrite_program_resource_data(struct blob *metadata, 77501e04c3fSmrg struct gl_shader_program *prog, 77601e04c3fSmrg struct gl_program_resource *res) 77701e04c3fSmrg{ 77801e04c3fSmrg struct gl_linked_shader *sh; 77901e04c3fSmrg 78001e04c3fSmrg switch(res->Type) { 78101e04c3fSmrg case GL_PROGRAM_INPUT: 78201e04c3fSmrg case GL_PROGRAM_OUTPUT: { 78301e04c3fSmrg const gl_shader_variable *var = (gl_shader_variable *)res->Data; 78401e04c3fSmrg 78501e04c3fSmrg encode_type_to_blob(metadata, var->type); 78601e04c3fSmrg encode_type_to_blob(metadata, var->interface_type); 78701e04c3fSmrg encode_type_to_blob(metadata, var->outermost_struct_type); 78801e04c3fSmrg 78901e04c3fSmrg blob_write_string(metadata, var->name); 79001e04c3fSmrg 79101e04c3fSmrg size_t s_var_size, s_var_ptrs; 79201e04c3fSmrg get_shader_var_and_pointer_sizes(&s_var_size, &s_var_ptrs, var); 79301e04c3fSmrg 79401e04c3fSmrg /* Write gl_shader_variable skipping over the pointers */ 79501e04c3fSmrg blob_write_bytes(metadata, ((char *)var) + s_var_ptrs, 79601e04c3fSmrg s_var_size - s_var_ptrs); 79701e04c3fSmrg break; 79801e04c3fSmrg } 79901e04c3fSmrg case GL_UNIFORM_BLOCK: 80001e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) { 80101e04c3fSmrg if (strcmp(((gl_uniform_block *)res->Data)->Name, 80201e04c3fSmrg prog->data->UniformBlocks[i].Name) == 0) { 80301e04c3fSmrg blob_write_uint32(metadata, i); 80401e04c3fSmrg break; 80501e04c3fSmrg } 80601e04c3fSmrg } 80701e04c3fSmrg break; 80801e04c3fSmrg case GL_SHADER_STORAGE_BLOCK: 80901e04c3fSmrg for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) { 81001e04c3fSmrg if (strcmp(((gl_uniform_block *)res->Data)->Name, 81101e04c3fSmrg prog->data->ShaderStorageBlocks[i].Name) == 0) { 81201e04c3fSmrg blob_write_uint32(metadata, i); 81301e04c3fSmrg break; 81401e04c3fSmrg } 81501e04c3fSmrg } 81601e04c3fSmrg break; 81701e04c3fSmrg case GL_BUFFER_VARIABLE: 81801e04c3fSmrg case GL_VERTEX_SUBROUTINE_UNIFORM: 81901e04c3fSmrg case GL_GEOMETRY_SUBROUTINE_UNIFORM: 82001e04c3fSmrg case GL_FRAGMENT_SUBROUTINE_UNIFORM: 82101e04c3fSmrg case GL_COMPUTE_SUBROUTINE_UNIFORM: 82201e04c3fSmrg case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 82301e04c3fSmrg case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 82401e04c3fSmrg case GL_UNIFORM: 82501e04c3fSmrg if (((gl_uniform_storage *)res->Data)->builtin || 82601e04c3fSmrg res->Type != GL_UNIFORM) { 82701e04c3fSmrg blob_write_uint32(metadata, uniform_not_remapped); 82801e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 82901e04c3fSmrg if (strcmp(((gl_uniform_storage *)res->Data)->name, 83001e04c3fSmrg prog->data->UniformStorage[i].name) == 0) { 83101e04c3fSmrg blob_write_uint32(metadata, i); 83201e04c3fSmrg break; 83301e04c3fSmrg } 83401e04c3fSmrg } 83501e04c3fSmrg } else { 83601e04c3fSmrg blob_write_uint32(metadata, uniform_remapped); 83701e04c3fSmrg blob_write_uint32(metadata, ((gl_uniform_storage *)res->Data)->remap_location); 83801e04c3fSmrg } 83901e04c3fSmrg break; 84001e04c3fSmrg case GL_ATOMIC_COUNTER_BUFFER: 84101e04c3fSmrg for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) { 84201e04c3fSmrg if (((gl_active_atomic_buffer *)res->Data)->Binding == 84301e04c3fSmrg prog->data->AtomicBuffers[i].Binding) { 84401e04c3fSmrg blob_write_uint32(metadata, i); 84501e04c3fSmrg break; 84601e04c3fSmrg } 84701e04c3fSmrg } 84801e04c3fSmrg break; 84901e04c3fSmrg case GL_TRANSFORM_FEEDBACK_BUFFER: 85001e04c3fSmrg for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) { 85101e04c3fSmrg if (((gl_transform_feedback_buffer *)res->Data)->Binding == 85201e04c3fSmrg prog->last_vert_prog->sh.LinkedTransformFeedback->Buffers[i].Binding) { 85301e04c3fSmrg blob_write_uint32(metadata, i); 85401e04c3fSmrg break; 85501e04c3fSmrg } 85601e04c3fSmrg } 85701e04c3fSmrg break; 85801e04c3fSmrg case GL_TRANSFORM_FEEDBACK_VARYING: 85901e04c3fSmrg for (int i = 0; i < prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying; i++) { 86001e04c3fSmrg if (strcmp(((gl_transform_feedback_varying_info *)res->Data)->Name, 86101e04c3fSmrg prog->last_vert_prog->sh.LinkedTransformFeedback->Varyings[i].Name) == 0) { 86201e04c3fSmrg blob_write_uint32(metadata, i); 86301e04c3fSmrg break; 86401e04c3fSmrg } 86501e04c3fSmrg } 86601e04c3fSmrg break; 86701e04c3fSmrg case GL_VERTEX_SUBROUTINE: 86801e04c3fSmrg case GL_TESS_CONTROL_SUBROUTINE: 86901e04c3fSmrg case GL_TESS_EVALUATION_SUBROUTINE: 87001e04c3fSmrg case GL_GEOMETRY_SUBROUTINE: 87101e04c3fSmrg case GL_FRAGMENT_SUBROUTINE: 87201e04c3fSmrg case GL_COMPUTE_SUBROUTINE: 87301e04c3fSmrg sh = 87401e04c3fSmrg prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)]; 87501e04c3fSmrg write_shader_subroutine_index(metadata, sh, res); 87601e04c3fSmrg break; 87701e04c3fSmrg default: 87801e04c3fSmrg assert(!"Support for writing resource not yet implemented."); 87901e04c3fSmrg } 88001e04c3fSmrg} 88101e04c3fSmrg 88201e04c3fSmrgstatic void 88301e04c3fSmrgread_program_resource_data(struct blob_reader *metadata, 88401e04c3fSmrg struct gl_shader_program *prog, 88501e04c3fSmrg struct gl_program_resource *res) 88601e04c3fSmrg{ 88701e04c3fSmrg struct gl_linked_shader *sh; 88801e04c3fSmrg 88901e04c3fSmrg switch(res->Type) { 89001e04c3fSmrg case GL_PROGRAM_INPUT: 89101e04c3fSmrg case GL_PROGRAM_OUTPUT: { 89201e04c3fSmrg gl_shader_variable *var = ralloc(prog, struct gl_shader_variable); 89301e04c3fSmrg 89401e04c3fSmrg var->type = decode_type_from_blob(metadata); 89501e04c3fSmrg var->interface_type = decode_type_from_blob(metadata); 89601e04c3fSmrg var->outermost_struct_type = decode_type_from_blob(metadata); 89701e04c3fSmrg 89801e04c3fSmrg var->name = ralloc_strdup(prog, blob_read_string(metadata)); 89901e04c3fSmrg 90001e04c3fSmrg size_t s_var_size, s_var_ptrs; 90101e04c3fSmrg get_shader_var_and_pointer_sizes(&s_var_size, &s_var_ptrs, var); 90201e04c3fSmrg 90301e04c3fSmrg blob_copy_bytes(metadata, ((uint8_t *) var) + s_var_ptrs, 90401e04c3fSmrg s_var_size - s_var_ptrs); 90501e04c3fSmrg 90601e04c3fSmrg res->Data = var; 90701e04c3fSmrg break; 90801e04c3fSmrg } 90901e04c3fSmrg case GL_UNIFORM_BLOCK: 91001e04c3fSmrg res->Data = &prog->data->UniformBlocks[blob_read_uint32(metadata)]; 91101e04c3fSmrg break; 91201e04c3fSmrg case GL_SHADER_STORAGE_BLOCK: 91301e04c3fSmrg res->Data = &prog->data->ShaderStorageBlocks[blob_read_uint32(metadata)]; 91401e04c3fSmrg break; 91501e04c3fSmrg case GL_BUFFER_VARIABLE: 91601e04c3fSmrg case GL_VERTEX_SUBROUTINE_UNIFORM: 91701e04c3fSmrg case GL_GEOMETRY_SUBROUTINE_UNIFORM: 91801e04c3fSmrg case GL_FRAGMENT_SUBROUTINE_UNIFORM: 91901e04c3fSmrg case GL_COMPUTE_SUBROUTINE_UNIFORM: 92001e04c3fSmrg case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 92101e04c3fSmrg case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 92201e04c3fSmrg case GL_UNIFORM: { 92301e04c3fSmrg enum uniform_type type = (enum uniform_type) blob_read_uint32(metadata); 92401e04c3fSmrg if (type == uniform_not_remapped) { 92501e04c3fSmrg res->Data = &prog->data->UniformStorage[blob_read_uint32(metadata)]; 92601e04c3fSmrg } else { 92701e04c3fSmrg res->Data = prog->UniformRemapTable[blob_read_uint32(metadata)]; 92801e04c3fSmrg } 92901e04c3fSmrg break; 93001e04c3fSmrg } 93101e04c3fSmrg case GL_ATOMIC_COUNTER_BUFFER: 93201e04c3fSmrg res->Data = &prog->data->AtomicBuffers[blob_read_uint32(metadata)]; 93301e04c3fSmrg break; 93401e04c3fSmrg case GL_TRANSFORM_FEEDBACK_BUFFER: 93501e04c3fSmrg res->Data = &prog->last_vert_prog-> 93601e04c3fSmrg sh.LinkedTransformFeedback->Buffers[blob_read_uint32(metadata)]; 93701e04c3fSmrg break; 93801e04c3fSmrg case GL_TRANSFORM_FEEDBACK_VARYING: 93901e04c3fSmrg res->Data = &prog->last_vert_prog-> 94001e04c3fSmrg sh.LinkedTransformFeedback->Varyings[blob_read_uint32(metadata)]; 94101e04c3fSmrg break; 94201e04c3fSmrg case GL_VERTEX_SUBROUTINE: 94301e04c3fSmrg case GL_TESS_CONTROL_SUBROUTINE: 94401e04c3fSmrg case GL_TESS_EVALUATION_SUBROUTINE: 94501e04c3fSmrg case GL_GEOMETRY_SUBROUTINE: 94601e04c3fSmrg case GL_FRAGMENT_SUBROUTINE: 94701e04c3fSmrg case GL_COMPUTE_SUBROUTINE: 94801e04c3fSmrg sh = 94901e04c3fSmrg prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)]; 95001e04c3fSmrg res->Data = 95101e04c3fSmrg &sh->Program->sh.SubroutineFunctions[blob_read_uint32(metadata)]; 95201e04c3fSmrg break; 95301e04c3fSmrg default: 95401e04c3fSmrg assert(!"Support for reading resource not yet implemented."); 95501e04c3fSmrg } 95601e04c3fSmrg} 95701e04c3fSmrg 95801e04c3fSmrgstatic void 95901e04c3fSmrgwrite_program_resource_list(struct blob *metadata, 96001e04c3fSmrg struct gl_shader_program *prog) 96101e04c3fSmrg{ 96201e04c3fSmrg blob_write_uint32(metadata, prog->data->NumProgramResourceList); 96301e04c3fSmrg 96401e04c3fSmrg for (unsigned i = 0; i < prog->data->NumProgramResourceList; i++) { 96501e04c3fSmrg blob_write_uint32(metadata, prog->data->ProgramResourceList[i].Type); 96601e04c3fSmrg write_program_resource_data(metadata, prog, 96701e04c3fSmrg &prog->data->ProgramResourceList[i]); 96801e04c3fSmrg blob_write_bytes(metadata, 96901e04c3fSmrg &prog->data->ProgramResourceList[i].StageReferences, 97001e04c3fSmrg sizeof(prog->data->ProgramResourceList[i].StageReferences)); 97101e04c3fSmrg } 97201e04c3fSmrg} 97301e04c3fSmrg 97401e04c3fSmrgstatic void 97501e04c3fSmrgread_program_resource_list(struct blob_reader *metadata, 97601e04c3fSmrg struct gl_shader_program *prog) 97701e04c3fSmrg{ 97801e04c3fSmrg prog->data->NumProgramResourceList = blob_read_uint32(metadata); 97901e04c3fSmrg 98001e04c3fSmrg prog->data->ProgramResourceList = 98101e04c3fSmrg ralloc_array(prog->data, gl_program_resource, 98201e04c3fSmrg prog->data->NumProgramResourceList); 98301e04c3fSmrg 98401e04c3fSmrg for (unsigned i = 0; i < prog->data->NumProgramResourceList; i++) { 98501e04c3fSmrg prog->data->ProgramResourceList[i].Type = blob_read_uint32(metadata); 98601e04c3fSmrg read_program_resource_data(metadata, prog, 98701e04c3fSmrg &prog->data->ProgramResourceList[i]); 98801e04c3fSmrg blob_copy_bytes(metadata, 98901e04c3fSmrg (uint8_t *) &prog->data->ProgramResourceList[i].StageReferences, 99001e04c3fSmrg sizeof(prog->data->ProgramResourceList[i].StageReferences)); 99101e04c3fSmrg } 99201e04c3fSmrg} 99301e04c3fSmrg 99401e04c3fSmrgstatic void 99501e04c3fSmrgwrite_shader_parameters(struct blob *metadata, 99601e04c3fSmrg struct gl_program_parameter_list *params) 99701e04c3fSmrg{ 99801e04c3fSmrg blob_write_uint32(metadata, params->NumParameters); 99901e04c3fSmrg blob_write_uint32(metadata, params->NumParameterValues); 100001e04c3fSmrg uint32_t i = 0; 100101e04c3fSmrg 100201e04c3fSmrg while (i < params->NumParameters) { 100301e04c3fSmrg struct gl_program_parameter *param = ¶ms->Parameters[i]; 100401e04c3fSmrg 100501e04c3fSmrg blob_write_uint32(metadata, param->Type); 100601e04c3fSmrg blob_write_string(metadata, param->Name); 100701e04c3fSmrg blob_write_uint32(metadata, param->Size); 100801e04c3fSmrg blob_write_uint32(metadata, param->DataType); 100901e04c3fSmrg blob_write_bytes(metadata, param->StateIndexes, 101001e04c3fSmrg sizeof(param->StateIndexes)); 101101e04c3fSmrg 101201e04c3fSmrg i++; 101301e04c3fSmrg } 101401e04c3fSmrg 101501e04c3fSmrg blob_write_bytes(metadata, params->ParameterValues, 101601e04c3fSmrg sizeof(gl_constant_value) * params->NumParameterValues); 101701e04c3fSmrg 101801e04c3fSmrg blob_write_bytes(metadata, params->ParameterValueOffset, 101901e04c3fSmrg sizeof(uint32_t) * params->NumParameters); 102001e04c3fSmrg 102101e04c3fSmrg blob_write_uint32(metadata, params->StateFlags); 102201e04c3fSmrg} 102301e04c3fSmrg 102401e04c3fSmrgstatic void 102501e04c3fSmrgread_shader_parameters(struct blob_reader *metadata, 102601e04c3fSmrg struct gl_program_parameter_list *params) 102701e04c3fSmrg{ 102801e04c3fSmrg gl_state_index16 state_indexes[STATE_LENGTH]; 102901e04c3fSmrg uint32_t i = 0; 103001e04c3fSmrg uint32_t num_parameters = blob_read_uint32(metadata); 103101e04c3fSmrg uint32_t num_parameters_values = blob_read_uint32(metadata); 103201e04c3fSmrg 103301e04c3fSmrg _mesa_reserve_parameter_storage(params, num_parameters); 103401e04c3fSmrg while (i < num_parameters) { 103501e04c3fSmrg gl_register_file type = (gl_register_file) blob_read_uint32(metadata); 103601e04c3fSmrg const char *name = blob_read_string(metadata); 103701e04c3fSmrg unsigned size = blob_read_uint32(metadata); 103801e04c3fSmrg unsigned data_type = blob_read_uint32(metadata); 103901e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) state_indexes, 104001e04c3fSmrg sizeof(state_indexes)); 104101e04c3fSmrg 104201e04c3fSmrg _mesa_add_parameter(params, type, name, size, data_type, 104301e04c3fSmrg NULL, state_indexes, false); 104401e04c3fSmrg 104501e04c3fSmrg i++; 104601e04c3fSmrg } 104701e04c3fSmrg 104801e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) params->ParameterValues, 104901e04c3fSmrg sizeof(gl_constant_value) * num_parameters_values); 105001e04c3fSmrg 105101e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) params->ParameterValueOffset, 105201e04c3fSmrg sizeof(uint32_t) * num_parameters); 105301e04c3fSmrg 105401e04c3fSmrg params->StateFlags = blob_read_uint32(metadata); 105501e04c3fSmrg} 105601e04c3fSmrg 105701e04c3fSmrgstatic void 105801e04c3fSmrgwrite_shader_metadata(struct blob *metadata, gl_linked_shader *shader) 105901e04c3fSmrg{ 106001e04c3fSmrg assert(shader->Program); 106101e04c3fSmrg struct gl_program *glprog = shader->Program; 106201e04c3fSmrg unsigned i; 106301e04c3fSmrg 106401e04c3fSmrg blob_write_uint64(metadata, glprog->DualSlotInputs); 106501e04c3fSmrg blob_write_bytes(metadata, glprog->TexturesUsed, 106601e04c3fSmrg sizeof(glprog->TexturesUsed)); 106701e04c3fSmrg blob_write_uint64(metadata, glprog->SamplersUsed); 106801e04c3fSmrg 106901e04c3fSmrg blob_write_bytes(metadata, glprog->SamplerUnits, 107001e04c3fSmrg sizeof(glprog->SamplerUnits)); 107101e04c3fSmrg blob_write_bytes(metadata, glprog->sh.SamplerTargets, 107201e04c3fSmrg sizeof(glprog->sh.SamplerTargets)); 107301e04c3fSmrg blob_write_uint32(metadata, glprog->ShadowSamplers); 107401e04c3fSmrg blob_write_uint32(metadata, glprog->ExternalSamplersUsed); 107501e04c3fSmrg 107601e04c3fSmrg blob_write_bytes(metadata, glprog->sh.ImageAccess, 107701e04c3fSmrg sizeof(glprog->sh.ImageAccess)); 107801e04c3fSmrg blob_write_bytes(metadata, glprog->sh.ImageUnits, 107901e04c3fSmrg sizeof(glprog->sh.ImageUnits)); 108001e04c3fSmrg 108101e04c3fSmrg size_t ptr_size = sizeof(GLvoid *); 108201e04c3fSmrg 108301e04c3fSmrg blob_write_uint32(metadata, glprog->sh.NumBindlessSamplers); 108401e04c3fSmrg blob_write_uint32(metadata, glprog->sh.HasBoundBindlessSampler); 108501e04c3fSmrg for (i = 0; i < glprog->sh.NumBindlessSamplers; i++) { 108601e04c3fSmrg blob_write_bytes(metadata, &glprog->sh.BindlessSamplers[i], 108701e04c3fSmrg sizeof(struct gl_bindless_sampler) - ptr_size); 108801e04c3fSmrg } 108901e04c3fSmrg 109001e04c3fSmrg blob_write_uint32(metadata, glprog->sh.NumBindlessImages); 109101e04c3fSmrg blob_write_uint32(metadata, glprog->sh.HasBoundBindlessImage); 109201e04c3fSmrg for (i = 0; i < glprog->sh.NumBindlessImages; i++) { 109301e04c3fSmrg blob_write_bytes(metadata, &glprog->sh.BindlessImages[i], 109401e04c3fSmrg sizeof(struct gl_bindless_image) - ptr_size); 109501e04c3fSmrg } 109601e04c3fSmrg 109701e04c3fSmrg blob_write_bytes(metadata, &glprog->sh.fs.BlendSupport, 109801e04c3fSmrg sizeof(glprog->sh.fs.BlendSupport)); 109901e04c3fSmrg 110001e04c3fSmrg write_shader_parameters(metadata, glprog->Parameters); 110101e04c3fSmrg 110201e04c3fSmrg assert((glprog->driver_cache_blob == NULL) == 110301e04c3fSmrg (glprog->driver_cache_blob_size == 0)); 110401e04c3fSmrg blob_write_uint32(metadata, (uint32_t)glprog->driver_cache_blob_size); 110501e04c3fSmrg if (glprog->driver_cache_blob_size > 0) { 110601e04c3fSmrg blob_write_bytes(metadata, glprog->driver_cache_blob, 110701e04c3fSmrg glprog->driver_cache_blob_size); 110801e04c3fSmrg } 110901e04c3fSmrg} 111001e04c3fSmrg 111101e04c3fSmrgstatic void 111201e04c3fSmrgread_shader_metadata(struct blob_reader *metadata, 111301e04c3fSmrg struct gl_program *glprog, 111401e04c3fSmrg gl_linked_shader *linked) 111501e04c3fSmrg{ 111601e04c3fSmrg unsigned i; 111701e04c3fSmrg 111801e04c3fSmrg glprog->DualSlotInputs = blob_read_uint64(metadata); 111901e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->TexturesUsed, 112001e04c3fSmrg sizeof(glprog->TexturesUsed)); 112101e04c3fSmrg glprog->SamplersUsed = blob_read_uint64(metadata); 112201e04c3fSmrg 112301e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->SamplerUnits, 112401e04c3fSmrg sizeof(glprog->SamplerUnits)); 112501e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->sh.SamplerTargets, 112601e04c3fSmrg sizeof(glprog->sh.SamplerTargets)); 112701e04c3fSmrg glprog->ShadowSamplers = blob_read_uint32(metadata); 112801e04c3fSmrg glprog->ExternalSamplersUsed = blob_read_uint32(metadata); 112901e04c3fSmrg 113001e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageAccess, 113101e04c3fSmrg sizeof(glprog->sh.ImageAccess)); 113201e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageUnits, 113301e04c3fSmrg sizeof(glprog->sh.ImageUnits)); 113401e04c3fSmrg 113501e04c3fSmrg size_t ptr_size = sizeof(GLvoid *); 113601e04c3fSmrg 113701e04c3fSmrg glprog->sh.NumBindlessSamplers = blob_read_uint32(metadata); 113801e04c3fSmrg glprog->sh.HasBoundBindlessSampler = blob_read_uint32(metadata); 113901e04c3fSmrg if (glprog->sh.NumBindlessSamplers > 0) { 114001e04c3fSmrg glprog->sh.BindlessSamplers = 114101e04c3fSmrg rzalloc_array(glprog, gl_bindless_sampler, 114201e04c3fSmrg glprog->sh.NumBindlessSamplers); 114301e04c3fSmrg 114401e04c3fSmrg for (i = 0; i < glprog->sh.NumBindlessSamplers; i++) { 114501e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) &glprog->sh.BindlessSamplers[i], 114601e04c3fSmrg sizeof(struct gl_bindless_sampler) - ptr_size); 114701e04c3fSmrg } 114801e04c3fSmrg } 114901e04c3fSmrg 115001e04c3fSmrg glprog->sh.NumBindlessImages = blob_read_uint32(metadata); 115101e04c3fSmrg glprog->sh.HasBoundBindlessImage = blob_read_uint32(metadata); 115201e04c3fSmrg if (glprog->sh.NumBindlessImages > 0) { 115301e04c3fSmrg glprog->sh.BindlessImages = 115401e04c3fSmrg rzalloc_array(glprog, gl_bindless_image, 115501e04c3fSmrg glprog->sh.NumBindlessImages); 115601e04c3fSmrg 115701e04c3fSmrg for (i = 0; i < glprog->sh.NumBindlessImages; i++) { 115801e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) &glprog->sh.BindlessImages[i], 115901e04c3fSmrg sizeof(struct gl_bindless_image) - ptr_size); 116001e04c3fSmrg } 116101e04c3fSmrg } 116201e04c3fSmrg 116301e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) &glprog->sh.fs.BlendSupport, 116401e04c3fSmrg sizeof(glprog->sh.fs.BlendSupport)); 116501e04c3fSmrg 116601e04c3fSmrg glprog->Parameters = _mesa_new_parameter_list(); 116701e04c3fSmrg read_shader_parameters(metadata, glprog->Parameters); 116801e04c3fSmrg 116901e04c3fSmrg glprog->driver_cache_blob_size = (size_t)blob_read_uint32(metadata); 117001e04c3fSmrg if (glprog->driver_cache_blob_size > 0) { 117101e04c3fSmrg glprog->driver_cache_blob = 117201e04c3fSmrg (uint8_t*)ralloc_size(glprog, glprog->driver_cache_blob_size); 117301e04c3fSmrg blob_copy_bytes(metadata, glprog->driver_cache_blob, 117401e04c3fSmrg glprog->driver_cache_blob_size); 117501e04c3fSmrg } 117601e04c3fSmrg} 117701e04c3fSmrg 117801e04c3fSmrgstatic void 117901e04c3fSmrgget_shader_info_and_pointer_sizes(size_t *s_info_size, size_t *s_info_ptrs, 118001e04c3fSmrg shader_info *info) 118101e04c3fSmrg{ 118201e04c3fSmrg *s_info_size = sizeof(shader_info); 118301e04c3fSmrg *s_info_ptrs = sizeof(info->name) + sizeof(info->label); 118401e04c3fSmrg} 118501e04c3fSmrg 118601e04c3fSmrgstatic void 118701e04c3fSmrgcreate_linked_shader_and_program(struct gl_context *ctx, 118801e04c3fSmrg gl_shader_stage stage, 118901e04c3fSmrg struct gl_shader_program *prog, 119001e04c3fSmrg struct blob_reader *metadata) 119101e04c3fSmrg{ 119201e04c3fSmrg struct gl_program *glprog; 119301e04c3fSmrg 119401e04c3fSmrg struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader); 119501e04c3fSmrg linked->Stage = stage; 119601e04c3fSmrg 119701e04c3fSmrg glprog = ctx->Driver.NewProgram(ctx, _mesa_shader_stage_to_program(stage), 119801e04c3fSmrg prog->Name, false); 119901e04c3fSmrg glprog->info.stage = stage; 120001e04c3fSmrg linked->Program = glprog; 120101e04c3fSmrg 120201e04c3fSmrg read_shader_metadata(metadata, glprog, linked); 120301e04c3fSmrg 120401e04c3fSmrg glprog->info.name = ralloc_strdup(glprog, blob_read_string(metadata)); 120501e04c3fSmrg glprog->info.label = ralloc_strdup(glprog, blob_read_string(metadata)); 120601e04c3fSmrg 120701e04c3fSmrg size_t s_info_size, s_info_ptrs; 120801e04c3fSmrg get_shader_info_and_pointer_sizes(&s_info_size, &s_info_ptrs, 120901e04c3fSmrg &glprog->info); 121001e04c3fSmrg 121101e04c3fSmrg /* Restore shader info */ 121201e04c3fSmrg blob_copy_bytes(metadata, ((uint8_t *) &glprog->info) + s_info_ptrs, 121301e04c3fSmrg s_info_size - s_info_ptrs); 121401e04c3fSmrg 121501e04c3fSmrg _mesa_reference_shader_program_data(ctx, &glprog->sh.data, prog->data); 121601e04c3fSmrg _mesa_reference_program(ctx, &linked->Program, glprog); 121701e04c3fSmrg prog->_LinkedShaders[stage] = linked; 121801e04c3fSmrg} 121901e04c3fSmrg 122001e04c3fSmrgextern "C" void 122101e04c3fSmrgserialize_glsl_program(struct blob *blob, struct gl_context *ctx, 122201e04c3fSmrg struct gl_shader_program *prog) 122301e04c3fSmrg{ 122401e04c3fSmrg blob_write_bytes(blob, prog->data->sha1, sizeof(prog->data->sha1)); 122501e04c3fSmrg 122601e04c3fSmrg write_uniforms(blob, prog); 122701e04c3fSmrg 122801e04c3fSmrg write_hash_tables(blob, prog); 122901e04c3fSmrg 123001e04c3fSmrg blob_write_uint32(blob, prog->data->Version); 123101e04c3fSmrg blob_write_uint32(blob, prog->data->linked_stages); 123201e04c3fSmrg 123301e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 123401e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 123501e04c3fSmrg if (sh) { 123601e04c3fSmrg write_shader_metadata(blob, sh); 123701e04c3fSmrg 123801e04c3fSmrg if (sh->Program->info.name) 123901e04c3fSmrg blob_write_string(blob, sh->Program->info.name); 124001e04c3fSmrg else 124101e04c3fSmrg blob_write_string(blob, ""); 124201e04c3fSmrg 124301e04c3fSmrg if (sh->Program->info.label) 124401e04c3fSmrg blob_write_string(blob, sh->Program->info.label); 124501e04c3fSmrg else 124601e04c3fSmrg blob_write_string(blob, ""); 124701e04c3fSmrg 124801e04c3fSmrg size_t s_info_size, s_info_ptrs; 124901e04c3fSmrg get_shader_info_and_pointer_sizes(&s_info_size, &s_info_ptrs, 125001e04c3fSmrg &sh->Program->info); 125101e04c3fSmrg 125201e04c3fSmrg /* Store shader info */ 125301e04c3fSmrg blob_write_bytes(blob, 125401e04c3fSmrg ((char *) &sh->Program->info) + s_info_ptrs, 125501e04c3fSmrg s_info_size - s_info_ptrs); 125601e04c3fSmrg } 125701e04c3fSmrg } 125801e04c3fSmrg 125901e04c3fSmrg write_xfb(blob, prog); 126001e04c3fSmrg 126101e04c3fSmrg write_uniform_remap_tables(blob, prog); 126201e04c3fSmrg 126301e04c3fSmrg write_atomic_buffers(blob, prog); 126401e04c3fSmrg 126501e04c3fSmrg write_buffer_blocks(blob, prog); 126601e04c3fSmrg 126701e04c3fSmrg write_subroutines(blob, prog); 126801e04c3fSmrg 126901e04c3fSmrg write_program_resource_list(blob, prog); 127001e04c3fSmrg} 127101e04c3fSmrg 127201e04c3fSmrgextern "C" bool 127301e04c3fSmrgdeserialize_glsl_program(struct blob_reader *blob, struct gl_context *ctx, 127401e04c3fSmrg struct gl_shader_program *prog) 127501e04c3fSmrg{ 127601e04c3fSmrg /* Fixed function programs generated by Mesa can't be serialized. */ 127701e04c3fSmrg if (prog->Name == 0) 127801e04c3fSmrg return false; 127901e04c3fSmrg 128001e04c3fSmrg assert(prog->data->UniformStorage == NULL); 128101e04c3fSmrg 128201e04c3fSmrg blob_copy_bytes(blob, prog->data->sha1, sizeof(prog->data->sha1)); 128301e04c3fSmrg 128401e04c3fSmrg read_uniforms(blob, prog); 128501e04c3fSmrg 128601e04c3fSmrg read_hash_tables(blob, prog); 128701e04c3fSmrg 128801e04c3fSmrg prog->data->Version = blob_read_uint32(blob); 128901e04c3fSmrg prog->data->linked_stages = blob_read_uint32(blob); 129001e04c3fSmrg 129101e04c3fSmrg unsigned mask = prog->data->linked_stages; 129201e04c3fSmrg while (mask) { 129301e04c3fSmrg const int j = u_bit_scan(&mask); 129401e04c3fSmrg create_linked_shader_and_program(ctx, (gl_shader_stage) j, prog, 129501e04c3fSmrg blob); 129601e04c3fSmrg } 129701e04c3fSmrg 129801e04c3fSmrg read_xfb(blob, prog); 129901e04c3fSmrg 130001e04c3fSmrg read_uniform_remap_tables(blob, prog); 130101e04c3fSmrg 130201e04c3fSmrg read_atomic_buffers(blob, prog); 130301e04c3fSmrg 130401e04c3fSmrg read_buffer_blocks(blob, prog); 130501e04c3fSmrg 130601e04c3fSmrg read_subroutines(blob, prog); 130701e04c3fSmrg 130801e04c3fSmrg read_program_resource_list(blob, prog); 130901e04c3fSmrg 131001e04c3fSmrg return !blob->overrun; 131101e04c3fSmrg} 1312