serialize.cpp revision 7ec681f3
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 1427ec681f3Smrg blob_write_uint32(metadata, glprog->sh.NumUniformBlocks); 14301e04c3fSmrg blob_write_uint32(metadata, glprog->info.num_ssbos); 14401e04c3fSmrg 1457ec681f3Smrg for (unsigned j = 0; j < glprog->sh.NumUniformBlocks; 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 2187ec681f3Smrg glprog->sh.NumUniformBlocks = blob_read_uint32(metadata); 21901e04c3fSmrg glprog->info.num_ssbos = blob_read_uint32(metadata); 22001e04c3fSmrg 22101e04c3fSmrg glprog->sh.UniformBlocks = 2227ec681f3Smrg rzalloc_array(glprog, gl_uniform_block *, glprog->sh.NumUniformBlocks); 22301e04c3fSmrg glprog->sh.ShaderStorageBlocks = 22401e04c3fSmrg rzalloc_array(glprog, gl_uniform_block *, glprog->info.num_ssbos); 22501e04c3fSmrg 2267ec681f3Smrg for (unsigned j = 0; j < glprog->sh.NumUniformBlocks; 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); 4387ec681f3Smrg if (prog->data->UniformStorage[i].name) { 4397ec681f3Smrg blob_write_string(metadata, prog->data->UniformStorage[i].name); 4407ec681f3Smrg } else { 4417ec681f3Smrg blob_write_string(metadata, ""); 4427ec681f3Smrg } 44301e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].builtin); 44401e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].remap_location); 44501e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].block_index); 44601e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].atomic_buffer_index); 44701e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].offset); 44801e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].array_stride); 44901e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].hidden); 45001e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].is_shader_storage); 45101e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].active_shader_mask); 45201e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].matrix_stride); 45301e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].row_major); 45401e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].is_bindless); 45501e04c3fSmrg blob_write_uint32(metadata, 45601e04c3fSmrg prog->data->UniformStorage[i].num_compatible_subroutines); 45701e04c3fSmrg blob_write_uint32(metadata, 45801e04c3fSmrg prog->data->UniformStorage[i].top_level_array_size); 45901e04c3fSmrg blob_write_uint32(metadata, 46001e04c3fSmrg prog->data->UniformStorage[i].top_level_array_stride); 46101e04c3fSmrg 46201e04c3fSmrg if (has_uniform_storage(prog, i)) { 46301e04c3fSmrg blob_write_uint32(metadata, prog->data->UniformStorage[i].storage - 46401e04c3fSmrg prog->data->UniformDataSlots); 46501e04c3fSmrg } 46601e04c3fSmrg 46701e04c3fSmrg blob_write_bytes(metadata, prog->data->UniformStorage[i].opaque, 46801e04c3fSmrg sizeof(prog->data->UniformStorage[i].opaque)); 46901e04c3fSmrg } 47001e04c3fSmrg 47101e04c3fSmrg /* Here we cache all uniform values. We do this to retain values for 47201e04c3fSmrg * uniforms with initialisers and also hidden uniforms that may be lowered 47301e04c3fSmrg * constant arrays. We could possibly just store the values we need but for 47401e04c3fSmrg * now we just store everything. 47501e04c3fSmrg */ 47601e04c3fSmrg blob_write_uint32(metadata, prog->data->NumHiddenUniforms); 47701e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 47801e04c3fSmrg if (has_uniform_storage(prog, i)) { 47901e04c3fSmrg unsigned vec_size = 48001e04c3fSmrg prog->data->UniformStorage[i].type->component_slots() * 48101e04c3fSmrg MAX2(prog->data->UniformStorage[i].array_elements, 1); 48201e04c3fSmrg unsigned slot = 48301e04c3fSmrg prog->data->UniformStorage[i].storage - 48401e04c3fSmrg prog->data->UniformDataSlots; 48501e04c3fSmrg blob_write_bytes(metadata, &prog->data->UniformDataDefaults[slot], 48601e04c3fSmrg sizeof(union gl_constant_value) * vec_size); 48701e04c3fSmrg } 48801e04c3fSmrg } 48901e04c3fSmrg} 49001e04c3fSmrg 49101e04c3fSmrgstatic void 49201e04c3fSmrgread_uniforms(struct blob_reader *metadata, struct gl_shader_program *prog) 49301e04c3fSmrg{ 49401e04c3fSmrg struct gl_uniform_storage *uniforms; 49501e04c3fSmrg union gl_constant_value *data; 49601e04c3fSmrg 49701e04c3fSmrg prog->SamplersValidated = blob_read_uint32(metadata); 49801e04c3fSmrg prog->data->NumUniformStorage = blob_read_uint32(metadata); 49901e04c3fSmrg prog->data->NumUniformDataSlots = blob_read_uint32(metadata); 50001e04c3fSmrg 50101e04c3fSmrg uniforms = rzalloc_array(prog->data, struct gl_uniform_storage, 50201e04c3fSmrg prog->data->NumUniformStorage); 50301e04c3fSmrg prog->data->UniformStorage = uniforms; 50401e04c3fSmrg 50501e04c3fSmrg data = rzalloc_array(uniforms, union gl_constant_value, 50601e04c3fSmrg prog->data->NumUniformDataSlots); 50701e04c3fSmrg prog->data->UniformDataSlots = data; 50801e04c3fSmrg prog->data->UniformDataDefaults = 50901e04c3fSmrg rzalloc_array(uniforms, union gl_constant_value, 51001e04c3fSmrg prog->data->NumUniformDataSlots); 51101e04c3fSmrg 51201e04c3fSmrg prog->UniformHash = new string_to_uint_map; 51301e04c3fSmrg 51401e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 51501e04c3fSmrg uniforms[i].type = decode_type_from_blob(metadata); 51601e04c3fSmrg uniforms[i].array_elements = blob_read_uint32(metadata); 51701e04c3fSmrg uniforms[i].name = ralloc_strdup(prog, blob_read_string (metadata)); 51801e04c3fSmrg uniforms[i].builtin = blob_read_uint32(metadata); 51901e04c3fSmrg uniforms[i].remap_location = blob_read_uint32(metadata); 52001e04c3fSmrg uniforms[i].block_index = blob_read_uint32(metadata); 52101e04c3fSmrg uniforms[i].atomic_buffer_index = blob_read_uint32(metadata); 52201e04c3fSmrg uniforms[i].offset = blob_read_uint32(metadata); 52301e04c3fSmrg uniforms[i].array_stride = blob_read_uint32(metadata); 52401e04c3fSmrg uniforms[i].hidden = blob_read_uint32(metadata); 52501e04c3fSmrg uniforms[i].is_shader_storage = blob_read_uint32(metadata); 52601e04c3fSmrg uniforms[i].active_shader_mask = blob_read_uint32(metadata); 52701e04c3fSmrg uniforms[i].matrix_stride = blob_read_uint32(metadata); 52801e04c3fSmrg uniforms[i].row_major = blob_read_uint32(metadata); 52901e04c3fSmrg uniforms[i].is_bindless = blob_read_uint32(metadata); 53001e04c3fSmrg uniforms[i].num_compatible_subroutines = blob_read_uint32(metadata); 53101e04c3fSmrg uniforms[i].top_level_array_size = blob_read_uint32(metadata); 53201e04c3fSmrg uniforms[i].top_level_array_stride = blob_read_uint32(metadata); 53301e04c3fSmrg prog->UniformHash->put(i, uniforms[i].name); 53401e04c3fSmrg 53501e04c3fSmrg if (has_uniform_storage(prog, i)) { 53601e04c3fSmrg uniforms[i].storage = data + blob_read_uint32(metadata); 53701e04c3fSmrg } 53801e04c3fSmrg 53901e04c3fSmrg memcpy(uniforms[i].opaque, 54001e04c3fSmrg blob_read_bytes(metadata, sizeof(uniforms[i].opaque)), 54101e04c3fSmrg sizeof(uniforms[i].opaque)); 54201e04c3fSmrg } 54301e04c3fSmrg 54401e04c3fSmrg /* Restore uniform values. */ 54501e04c3fSmrg prog->data->NumHiddenUniforms = blob_read_uint32(metadata); 54601e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 54701e04c3fSmrg if (has_uniform_storage(prog, i)) { 54801e04c3fSmrg unsigned vec_size = 54901e04c3fSmrg prog->data->UniformStorage[i].type->component_slots() * 55001e04c3fSmrg MAX2(prog->data->UniformStorage[i].array_elements, 1); 55101e04c3fSmrg unsigned slot = 55201e04c3fSmrg prog->data->UniformStorage[i].storage - 55301e04c3fSmrg prog->data->UniformDataSlots; 55401e04c3fSmrg blob_copy_bytes(metadata, 55501e04c3fSmrg (uint8_t *) &prog->data->UniformDataSlots[slot], 55601e04c3fSmrg sizeof(union gl_constant_value) * vec_size); 55701e04c3fSmrg 55801e04c3fSmrg assert(vec_size + prog->data->UniformStorage[i].storage <= 55901e04c3fSmrg data + prog->data->NumUniformDataSlots); 56001e04c3fSmrg } 56101e04c3fSmrg } 56201e04c3fSmrg 56301e04c3fSmrg memcpy(prog->data->UniformDataDefaults, prog->data->UniformDataSlots, 56401e04c3fSmrg sizeof(union gl_constant_value) * prog->data->NumUniformDataSlots); 56501e04c3fSmrg} 56601e04c3fSmrg 56701e04c3fSmrgenum uniform_remap_type 56801e04c3fSmrg{ 56901e04c3fSmrg remap_type_inactive_explicit_location, 57001e04c3fSmrg remap_type_null_ptr, 5717ec681f3Smrg remap_type_uniform_offset, 5727ec681f3Smrg remap_type_uniform_offsets_equal, 57301e04c3fSmrg}; 57401e04c3fSmrg 57501e04c3fSmrgstatic void 5767ec681f3Smrgwrite_uniform_remap_table(struct blob *metadata, 5777ec681f3Smrg unsigned num_entries, 5787ec681f3Smrg gl_uniform_storage *uniform_storage, 5797ec681f3Smrg gl_uniform_storage **remap_table) 58001e04c3fSmrg{ 5817ec681f3Smrg blob_write_uint32(metadata, num_entries); 58201e04c3fSmrg 5837ec681f3Smrg for (unsigned i = 0; i < num_entries; i++) { 5847ec681f3Smrg gl_uniform_storage *entry = remap_table[i]; 58501e04c3fSmrg uint32_t offset = entry - uniform_storage; 5867ec681f3Smrg 5877ec681f3Smrg if (entry == INACTIVE_UNIFORM_EXPLICIT_LOCATION) { 5887ec681f3Smrg blob_write_uint32(metadata, remap_type_inactive_explicit_location); 5897ec681f3Smrg } else if (entry == NULL) { 5907ec681f3Smrg blob_write_uint32(metadata, remap_type_null_ptr); 5917ec681f3Smrg } else if (i+1 < num_entries && entry == remap_table[i+1]) { 5927ec681f3Smrg blob_write_uint32(metadata, remap_type_uniform_offsets_equal); 5937ec681f3Smrg 5947ec681f3Smrg /* If many offsets are equal, write only one offset and the number 5957ec681f3Smrg * of consecutive entries being equal. 5967ec681f3Smrg */ 5977ec681f3Smrg unsigned count = 1; 5987ec681f3Smrg for (unsigned j = i + 1; j < num_entries; j++) { 5997ec681f3Smrg if (entry != remap_table[j]) 6007ec681f3Smrg break; 6017ec681f3Smrg 6027ec681f3Smrg count++; 6037ec681f3Smrg } 6047ec681f3Smrg 6057ec681f3Smrg blob_write_uint32(metadata, offset); 6067ec681f3Smrg blob_write_uint32(metadata, count); 6077ec681f3Smrg i += count - 1; 6087ec681f3Smrg } else { 6097ec681f3Smrg blob_write_uint32(metadata, remap_type_uniform_offset); 6107ec681f3Smrg 6117ec681f3Smrg blob_write_uint32(metadata, offset); 6127ec681f3Smrg } 61301e04c3fSmrg } 61401e04c3fSmrg} 61501e04c3fSmrg 61601e04c3fSmrgstatic void 61701e04c3fSmrgwrite_uniform_remap_tables(struct blob *metadata, 61801e04c3fSmrg struct gl_shader_program *prog) 61901e04c3fSmrg{ 6207ec681f3Smrg write_uniform_remap_table(metadata, prog->NumUniformRemapTable, 6217ec681f3Smrg prog->data->UniformStorage, 6227ec681f3Smrg prog->UniformRemapTable); 62301e04c3fSmrg 62401e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 62501e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 62601e04c3fSmrg if (sh) { 6277ec681f3Smrg write_uniform_remap_table(metadata, 6287ec681f3Smrg sh->Program->sh.NumSubroutineUniformRemapTable, 6297ec681f3Smrg prog->data->UniformStorage, 6307ec681f3Smrg sh->Program->sh.SubroutineUniformRemapTable); 63101e04c3fSmrg } 63201e04c3fSmrg } 63301e04c3fSmrg} 63401e04c3fSmrg 6357ec681f3Smrgstatic struct gl_uniform_storage ** 6367ec681f3Smrgread_uniform_remap_table(struct blob_reader *metadata, 6377ec681f3Smrg struct gl_shader_program *prog, 6387ec681f3Smrg unsigned *num_entries, 6397ec681f3Smrg gl_uniform_storage *uniform_storage) 64001e04c3fSmrg{ 6417ec681f3Smrg unsigned num = blob_read_uint32(metadata); 6427ec681f3Smrg *num_entries = num; 6437ec681f3Smrg 6447ec681f3Smrg struct gl_uniform_storage **remap_table = 6457ec681f3Smrg rzalloc_array(prog, struct gl_uniform_storage *, num); 6467ec681f3Smrg 6477ec681f3Smrg for (unsigned i = 0; i < num; i++) { 6487ec681f3Smrg enum uniform_remap_type type = 6497ec681f3Smrg (enum uniform_remap_type) blob_read_uint32(metadata); 6507ec681f3Smrg 6517ec681f3Smrg if (type == remap_type_inactive_explicit_location) { 6527ec681f3Smrg remap_table[i] = INACTIVE_UNIFORM_EXPLICIT_LOCATION; 6537ec681f3Smrg } else if (type == remap_type_null_ptr) { 6547ec681f3Smrg remap_table[i] = NULL; 6557ec681f3Smrg } else if (type == remap_type_uniform_offsets_equal) { 6567ec681f3Smrg uint32_t uni_offset = blob_read_uint32(metadata); 6577ec681f3Smrg uint32_t count = blob_read_uint32(metadata); 6587ec681f3Smrg struct gl_uniform_storage *entry = uniform_storage + uni_offset; 6597ec681f3Smrg 6607ec681f3Smrg for (unsigned j = 0; j < count; j++) 6617ec681f3Smrg remap_table[i+j] = entry; 6627ec681f3Smrg i += count - 1; 6637ec681f3Smrg } else { 6647ec681f3Smrg uint32_t uni_offset = blob_read_uint32(metadata); 6657ec681f3Smrg remap_table[i] = uniform_storage + uni_offset; 6667ec681f3Smrg } 66701e04c3fSmrg } 6687ec681f3Smrg return remap_table; 66901e04c3fSmrg} 67001e04c3fSmrg 67101e04c3fSmrgstatic void 67201e04c3fSmrgread_uniform_remap_tables(struct blob_reader *metadata, 67301e04c3fSmrg struct gl_shader_program *prog) 67401e04c3fSmrg{ 6757ec681f3Smrg prog->UniformRemapTable = 6767ec681f3Smrg read_uniform_remap_table(metadata, prog, &prog->NumUniformRemapTable, 6777ec681f3Smrg prog->data->UniformStorage); 67801e04c3fSmrg 67901e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 68001e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 68101e04c3fSmrg if (sh) { 68201e04c3fSmrg struct gl_program *glprog = sh->Program; 68301e04c3fSmrg 68401e04c3fSmrg glprog->sh.SubroutineUniformRemapTable = 6857ec681f3Smrg read_uniform_remap_table(metadata, prog, 6867ec681f3Smrg &glprog->sh.NumSubroutineUniformRemapTable, 6877ec681f3Smrg prog->data->UniformStorage); 68801e04c3fSmrg } 68901e04c3fSmrg } 69001e04c3fSmrg} 69101e04c3fSmrg 69201e04c3fSmrgstruct whte_closure 69301e04c3fSmrg{ 69401e04c3fSmrg struct blob *blob; 69501e04c3fSmrg size_t num_entries; 69601e04c3fSmrg}; 69701e04c3fSmrg 69801e04c3fSmrgstatic void 69901e04c3fSmrgwrite_hash_table_entry(const char *key, unsigned value, void *closure) 70001e04c3fSmrg{ 70101e04c3fSmrg struct whte_closure *whte = (struct whte_closure *) closure; 70201e04c3fSmrg 70301e04c3fSmrg blob_write_string(whte->blob, key); 70401e04c3fSmrg blob_write_uint32(whte->blob, value); 70501e04c3fSmrg 70601e04c3fSmrg whte->num_entries++; 70701e04c3fSmrg} 70801e04c3fSmrg 70901e04c3fSmrgstatic void 71001e04c3fSmrgwrite_hash_table(struct blob *metadata, struct string_to_uint_map *hash) 71101e04c3fSmrg{ 71201e04c3fSmrg size_t offset; 71301e04c3fSmrg struct whte_closure whte; 71401e04c3fSmrg 71501e04c3fSmrg whte.blob = metadata; 71601e04c3fSmrg whte.num_entries = 0; 71701e04c3fSmrg 71801e04c3fSmrg offset = metadata->size; 71901e04c3fSmrg 72001e04c3fSmrg /* Write a placeholder for the hashtable size. */ 72101e04c3fSmrg blob_write_uint32 (metadata, 0); 72201e04c3fSmrg 72301e04c3fSmrg hash->iterate(write_hash_table_entry, &whte); 72401e04c3fSmrg 72501e04c3fSmrg /* Overwrite with the computed number of entries written. */ 72601e04c3fSmrg blob_overwrite_uint32 (metadata, offset, whte.num_entries); 72701e04c3fSmrg} 72801e04c3fSmrg 72901e04c3fSmrgstatic void 73001e04c3fSmrgread_hash_table(struct blob_reader *metadata, struct string_to_uint_map *hash) 73101e04c3fSmrg{ 73201e04c3fSmrg size_t i, num_entries; 73301e04c3fSmrg const char *key; 73401e04c3fSmrg uint32_t value; 73501e04c3fSmrg 73601e04c3fSmrg num_entries = blob_read_uint32 (metadata); 73701e04c3fSmrg 73801e04c3fSmrg for (i = 0; i < num_entries; i++) { 73901e04c3fSmrg key = blob_read_string(metadata); 74001e04c3fSmrg value = blob_read_uint32(metadata); 74101e04c3fSmrg 74201e04c3fSmrg hash->put(value, key); 74301e04c3fSmrg } 74401e04c3fSmrg} 74501e04c3fSmrg 74601e04c3fSmrgstatic void 74701e04c3fSmrgwrite_hash_tables(struct blob *metadata, struct gl_shader_program *prog) 74801e04c3fSmrg{ 74901e04c3fSmrg write_hash_table(metadata, prog->AttributeBindings); 75001e04c3fSmrg write_hash_table(metadata, prog->FragDataBindings); 75101e04c3fSmrg write_hash_table(metadata, prog->FragDataIndexBindings); 75201e04c3fSmrg} 75301e04c3fSmrg 75401e04c3fSmrgstatic void 75501e04c3fSmrgread_hash_tables(struct blob_reader *metadata, struct gl_shader_program *prog) 75601e04c3fSmrg{ 75701e04c3fSmrg read_hash_table(metadata, prog->AttributeBindings); 75801e04c3fSmrg read_hash_table(metadata, prog->FragDataBindings); 75901e04c3fSmrg read_hash_table(metadata, prog->FragDataIndexBindings); 76001e04c3fSmrg} 76101e04c3fSmrg 76201e04c3fSmrgstatic void 76301e04c3fSmrgwrite_shader_subroutine_index(struct blob *metadata, 76401e04c3fSmrg struct gl_linked_shader *sh, 76501e04c3fSmrg struct gl_program_resource *res) 76601e04c3fSmrg{ 76701e04c3fSmrg assert(sh); 76801e04c3fSmrg 76901e04c3fSmrg for (unsigned j = 0; j < sh->Program->sh.NumSubroutineFunctions; j++) { 77001e04c3fSmrg if (strcmp(((gl_subroutine_function *)res->Data)->name, 77101e04c3fSmrg sh->Program->sh.SubroutineFunctions[j].name) == 0) { 77201e04c3fSmrg blob_write_uint32(metadata, j); 77301e04c3fSmrg break; 77401e04c3fSmrg } 77501e04c3fSmrg } 77601e04c3fSmrg} 77701e04c3fSmrg 77801e04c3fSmrgstatic void 77901e04c3fSmrgget_shader_var_and_pointer_sizes(size_t *s_var_size, size_t *s_var_ptrs, 78001e04c3fSmrg const gl_shader_variable *var) 78101e04c3fSmrg{ 78201e04c3fSmrg *s_var_size = sizeof(gl_shader_variable); 78301e04c3fSmrg *s_var_ptrs = 78401e04c3fSmrg sizeof(var->type) + 78501e04c3fSmrg sizeof(var->interface_type) + 78601e04c3fSmrg sizeof(var->outermost_struct_type) + 78701e04c3fSmrg sizeof(var->name); 78801e04c3fSmrg} 78901e04c3fSmrg 79001e04c3fSmrgenum uniform_type 79101e04c3fSmrg{ 79201e04c3fSmrg uniform_remapped, 79301e04c3fSmrg uniform_not_remapped 79401e04c3fSmrg}; 79501e04c3fSmrg 79601e04c3fSmrgstatic void 79701e04c3fSmrgwrite_program_resource_data(struct blob *metadata, 79801e04c3fSmrg struct gl_shader_program *prog, 79901e04c3fSmrg struct gl_program_resource *res) 80001e04c3fSmrg{ 80101e04c3fSmrg struct gl_linked_shader *sh; 80201e04c3fSmrg 80301e04c3fSmrg switch(res->Type) { 80401e04c3fSmrg case GL_PROGRAM_INPUT: 80501e04c3fSmrg case GL_PROGRAM_OUTPUT: { 80601e04c3fSmrg const gl_shader_variable *var = (gl_shader_variable *)res->Data; 80701e04c3fSmrg 80801e04c3fSmrg encode_type_to_blob(metadata, var->type); 80901e04c3fSmrg encode_type_to_blob(metadata, var->interface_type); 81001e04c3fSmrg encode_type_to_blob(metadata, var->outermost_struct_type); 81101e04c3fSmrg 8127ec681f3Smrg if (var->name) { 8137ec681f3Smrg blob_write_string(metadata, var->name); 8147ec681f3Smrg } else { 8157ec681f3Smrg blob_write_string(metadata, ""); 8167ec681f3Smrg } 81701e04c3fSmrg 81801e04c3fSmrg size_t s_var_size, s_var_ptrs; 81901e04c3fSmrg get_shader_var_and_pointer_sizes(&s_var_size, &s_var_ptrs, var); 82001e04c3fSmrg 82101e04c3fSmrg /* Write gl_shader_variable skipping over the pointers */ 82201e04c3fSmrg blob_write_bytes(metadata, ((char *)var) + s_var_ptrs, 82301e04c3fSmrg s_var_size - s_var_ptrs); 82401e04c3fSmrg break; 82501e04c3fSmrg } 82601e04c3fSmrg case GL_UNIFORM_BLOCK: 82701e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) { 82801e04c3fSmrg if (strcmp(((gl_uniform_block *)res->Data)->Name, 82901e04c3fSmrg prog->data->UniformBlocks[i].Name) == 0) { 83001e04c3fSmrg blob_write_uint32(metadata, i); 83101e04c3fSmrg break; 83201e04c3fSmrg } 83301e04c3fSmrg } 83401e04c3fSmrg break; 83501e04c3fSmrg case GL_SHADER_STORAGE_BLOCK: 83601e04c3fSmrg for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) { 83701e04c3fSmrg if (strcmp(((gl_uniform_block *)res->Data)->Name, 83801e04c3fSmrg prog->data->ShaderStorageBlocks[i].Name) == 0) { 83901e04c3fSmrg blob_write_uint32(metadata, i); 84001e04c3fSmrg break; 84101e04c3fSmrg } 84201e04c3fSmrg } 84301e04c3fSmrg break; 84401e04c3fSmrg case GL_BUFFER_VARIABLE: 84501e04c3fSmrg case GL_VERTEX_SUBROUTINE_UNIFORM: 84601e04c3fSmrg case GL_GEOMETRY_SUBROUTINE_UNIFORM: 84701e04c3fSmrg case GL_FRAGMENT_SUBROUTINE_UNIFORM: 84801e04c3fSmrg case GL_COMPUTE_SUBROUTINE_UNIFORM: 84901e04c3fSmrg case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 85001e04c3fSmrg case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 85101e04c3fSmrg case GL_UNIFORM: 85201e04c3fSmrg if (((gl_uniform_storage *)res->Data)->builtin || 85301e04c3fSmrg res->Type != GL_UNIFORM) { 85401e04c3fSmrg blob_write_uint32(metadata, uniform_not_remapped); 85501e04c3fSmrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 85601e04c3fSmrg if (strcmp(((gl_uniform_storage *)res->Data)->name, 85701e04c3fSmrg prog->data->UniformStorage[i].name) == 0) { 85801e04c3fSmrg blob_write_uint32(metadata, i); 85901e04c3fSmrg break; 86001e04c3fSmrg } 86101e04c3fSmrg } 86201e04c3fSmrg } else { 86301e04c3fSmrg blob_write_uint32(metadata, uniform_remapped); 86401e04c3fSmrg blob_write_uint32(metadata, ((gl_uniform_storage *)res->Data)->remap_location); 86501e04c3fSmrg } 86601e04c3fSmrg break; 86701e04c3fSmrg case GL_ATOMIC_COUNTER_BUFFER: 86801e04c3fSmrg for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) { 86901e04c3fSmrg if (((gl_active_atomic_buffer *)res->Data)->Binding == 87001e04c3fSmrg prog->data->AtomicBuffers[i].Binding) { 87101e04c3fSmrg blob_write_uint32(metadata, i); 87201e04c3fSmrg break; 87301e04c3fSmrg } 87401e04c3fSmrg } 87501e04c3fSmrg break; 87601e04c3fSmrg case GL_TRANSFORM_FEEDBACK_BUFFER: 87701e04c3fSmrg for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) { 87801e04c3fSmrg if (((gl_transform_feedback_buffer *)res->Data)->Binding == 87901e04c3fSmrg prog->last_vert_prog->sh.LinkedTransformFeedback->Buffers[i].Binding) { 88001e04c3fSmrg blob_write_uint32(metadata, i); 88101e04c3fSmrg break; 88201e04c3fSmrg } 88301e04c3fSmrg } 88401e04c3fSmrg break; 88501e04c3fSmrg case GL_TRANSFORM_FEEDBACK_VARYING: 88601e04c3fSmrg for (int i = 0; i < prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying; i++) { 88701e04c3fSmrg if (strcmp(((gl_transform_feedback_varying_info *)res->Data)->Name, 88801e04c3fSmrg prog->last_vert_prog->sh.LinkedTransformFeedback->Varyings[i].Name) == 0) { 88901e04c3fSmrg blob_write_uint32(metadata, i); 89001e04c3fSmrg break; 89101e04c3fSmrg } 89201e04c3fSmrg } 89301e04c3fSmrg break; 89401e04c3fSmrg case GL_VERTEX_SUBROUTINE: 89501e04c3fSmrg case GL_TESS_CONTROL_SUBROUTINE: 89601e04c3fSmrg case GL_TESS_EVALUATION_SUBROUTINE: 89701e04c3fSmrg case GL_GEOMETRY_SUBROUTINE: 89801e04c3fSmrg case GL_FRAGMENT_SUBROUTINE: 89901e04c3fSmrg case GL_COMPUTE_SUBROUTINE: 90001e04c3fSmrg sh = 90101e04c3fSmrg prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)]; 90201e04c3fSmrg write_shader_subroutine_index(metadata, sh, res); 90301e04c3fSmrg break; 90401e04c3fSmrg default: 90501e04c3fSmrg assert(!"Support for writing resource not yet implemented."); 90601e04c3fSmrg } 90701e04c3fSmrg} 90801e04c3fSmrg 90901e04c3fSmrgstatic void 91001e04c3fSmrgread_program_resource_data(struct blob_reader *metadata, 91101e04c3fSmrg struct gl_shader_program *prog, 91201e04c3fSmrg struct gl_program_resource *res) 91301e04c3fSmrg{ 91401e04c3fSmrg struct gl_linked_shader *sh; 91501e04c3fSmrg 91601e04c3fSmrg switch(res->Type) { 91701e04c3fSmrg case GL_PROGRAM_INPUT: 91801e04c3fSmrg case GL_PROGRAM_OUTPUT: { 91901e04c3fSmrg gl_shader_variable *var = ralloc(prog, struct gl_shader_variable); 92001e04c3fSmrg 92101e04c3fSmrg var->type = decode_type_from_blob(metadata); 92201e04c3fSmrg var->interface_type = decode_type_from_blob(metadata); 92301e04c3fSmrg var->outermost_struct_type = decode_type_from_blob(metadata); 92401e04c3fSmrg 92501e04c3fSmrg var->name = ralloc_strdup(prog, blob_read_string(metadata)); 92601e04c3fSmrg 92701e04c3fSmrg size_t s_var_size, s_var_ptrs; 92801e04c3fSmrg get_shader_var_and_pointer_sizes(&s_var_size, &s_var_ptrs, var); 92901e04c3fSmrg 93001e04c3fSmrg blob_copy_bytes(metadata, ((uint8_t *) var) + s_var_ptrs, 93101e04c3fSmrg s_var_size - s_var_ptrs); 93201e04c3fSmrg 93301e04c3fSmrg res->Data = var; 93401e04c3fSmrg break; 93501e04c3fSmrg } 93601e04c3fSmrg case GL_UNIFORM_BLOCK: 93701e04c3fSmrg res->Data = &prog->data->UniformBlocks[blob_read_uint32(metadata)]; 93801e04c3fSmrg break; 93901e04c3fSmrg case GL_SHADER_STORAGE_BLOCK: 94001e04c3fSmrg res->Data = &prog->data->ShaderStorageBlocks[blob_read_uint32(metadata)]; 94101e04c3fSmrg break; 94201e04c3fSmrg case GL_BUFFER_VARIABLE: 94301e04c3fSmrg case GL_VERTEX_SUBROUTINE_UNIFORM: 94401e04c3fSmrg case GL_GEOMETRY_SUBROUTINE_UNIFORM: 94501e04c3fSmrg case GL_FRAGMENT_SUBROUTINE_UNIFORM: 94601e04c3fSmrg case GL_COMPUTE_SUBROUTINE_UNIFORM: 94701e04c3fSmrg case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 94801e04c3fSmrg case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 94901e04c3fSmrg case GL_UNIFORM: { 95001e04c3fSmrg enum uniform_type type = (enum uniform_type) blob_read_uint32(metadata); 95101e04c3fSmrg if (type == uniform_not_remapped) { 95201e04c3fSmrg res->Data = &prog->data->UniformStorage[blob_read_uint32(metadata)]; 95301e04c3fSmrg } else { 95401e04c3fSmrg res->Data = prog->UniformRemapTable[blob_read_uint32(metadata)]; 95501e04c3fSmrg } 95601e04c3fSmrg break; 95701e04c3fSmrg } 95801e04c3fSmrg case GL_ATOMIC_COUNTER_BUFFER: 95901e04c3fSmrg res->Data = &prog->data->AtomicBuffers[blob_read_uint32(metadata)]; 96001e04c3fSmrg break; 96101e04c3fSmrg case GL_TRANSFORM_FEEDBACK_BUFFER: 96201e04c3fSmrg res->Data = &prog->last_vert_prog-> 96301e04c3fSmrg sh.LinkedTransformFeedback->Buffers[blob_read_uint32(metadata)]; 96401e04c3fSmrg break; 96501e04c3fSmrg case GL_TRANSFORM_FEEDBACK_VARYING: 96601e04c3fSmrg res->Data = &prog->last_vert_prog-> 96701e04c3fSmrg sh.LinkedTransformFeedback->Varyings[blob_read_uint32(metadata)]; 96801e04c3fSmrg break; 96901e04c3fSmrg case GL_VERTEX_SUBROUTINE: 97001e04c3fSmrg case GL_TESS_CONTROL_SUBROUTINE: 97101e04c3fSmrg case GL_TESS_EVALUATION_SUBROUTINE: 97201e04c3fSmrg case GL_GEOMETRY_SUBROUTINE: 97301e04c3fSmrg case GL_FRAGMENT_SUBROUTINE: 97401e04c3fSmrg case GL_COMPUTE_SUBROUTINE: 97501e04c3fSmrg sh = 97601e04c3fSmrg prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)]; 97701e04c3fSmrg res->Data = 97801e04c3fSmrg &sh->Program->sh.SubroutineFunctions[blob_read_uint32(metadata)]; 97901e04c3fSmrg break; 98001e04c3fSmrg default: 98101e04c3fSmrg assert(!"Support for reading resource not yet implemented."); 98201e04c3fSmrg } 98301e04c3fSmrg} 98401e04c3fSmrg 98501e04c3fSmrgstatic void 98601e04c3fSmrgwrite_program_resource_list(struct blob *metadata, 98701e04c3fSmrg struct gl_shader_program *prog) 98801e04c3fSmrg{ 98901e04c3fSmrg blob_write_uint32(metadata, prog->data->NumProgramResourceList); 99001e04c3fSmrg 99101e04c3fSmrg for (unsigned i = 0; i < prog->data->NumProgramResourceList; i++) { 99201e04c3fSmrg blob_write_uint32(metadata, prog->data->ProgramResourceList[i].Type); 99301e04c3fSmrg write_program_resource_data(metadata, prog, 99401e04c3fSmrg &prog->data->ProgramResourceList[i]); 99501e04c3fSmrg blob_write_bytes(metadata, 99601e04c3fSmrg &prog->data->ProgramResourceList[i].StageReferences, 99701e04c3fSmrg sizeof(prog->data->ProgramResourceList[i].StageReferences)); 99801e04c3fSmrg } 99901e04c3fSmrg} 100001e04c3fSmrg 100101e04c3fSmrgstatic void 100201e04c3fSmrgread_program_resource_list(struct blob_reader *metadata, 100301e04c3fSmrg struct gl_shader_program *prog) 100401e04c3fSmrg{ 100501e04c3fSmrg prog->data->NumProgramResourceList = blob_read_uint32(metadata); 100601e04c3fSmrg 100701e04c3fSmrg prog->data->ProgramResourceList = 100801e04c3fSmrg ralloc_array(prog->data, gl_program_resource, 100901e04c3fSmrg prog->data->NumProgramResourceList); 101001e04c3fSmrg 101101e04c3fSmrg for (unsigned i = 0; i < prog->data->NumProgramResourceList; i++) { 101201e04c3fSmrg prog->data->ProgramResourceList[i].Type = blob_read_uint32(metadata); 101301e04c3fSmrg read_program_resource_data(metadata, prog, 101401e04c3fSmrg &prog->data->ProgramResourceList[i]); 101501e04c3fSmrg blob_copy_bytes(metadata, 101601e04c3fSmrg (uint8_t *) &prog->data->ProgramResourceList[i].StageReferences, 101701e04c3fSmrg sizeof(prog->data->ProgramResourceList[i].StageReferences)); 101801e04c3fSmrg } 101901e04c3fSmrg} 102001e04c3fSmrg 102101e04c3fSmrgstatic void 102201e04c3fSmrgwrite_shader_parameters(struct blob *metadata, 102301e04c3fSmrg struct gl_program_parameter_list *params) 102401e04c3fSmrg{ 102501e04c3fSmrg blob_write_uint32(metadata, params->NumParameters); 102601e04c3fSmrg uint32_t i = 0; 102701e04c3fSmrg 102801e04c3fSmrg while (i < params->NumParameters) { 102901e04c3fSmrg struct gl_program_parameter *param = ¶ms->Parameters[i]; 103001e04c3fSmrg blob_write_uint32(metadata, param->Type); 103101e04c3fSmrg blob_write_string(metadata, param->Name); 103201e04c3fSmrg blob_write_uint32(metadata, param->Size); 1033993e1d59Smrg blob_write_uint32(metadata, param->Padded); 103401e04c3fSmrg blob_write_uint32(metadata, param->DataType); 103501e04c3fSmrg blob_write_bytes(metadata, param->StateIndexes, 103601e04c3fSmrg sizeof(param->StateIndexes)); 10377ec681f3Smrg blob_write_uint32(metadata, param->UniformStorageIndex); 10387ec681f3Smrg blob_write_uint32(metadata, param->MainUniformStorageIndex); 103901e04c3fSmrg 104001e04c3fSmrg i++; 104101e04c3fSmrg } 104201e04c3fSmrg 104301e04c3fSmrg blob_write_bytes(metadata, params->ParameterValues, 104401e04c3fSmrg sizeof(gl_constant_value) * params->NumParameterValues); 104501e04c3fSmrg 104601e04c3fSmrg blob_write_uint32(metadata, params->StateFlags); 10477ec681f3Smrg blob_write_uint32(metadata, params->UniformBytes); 10487ec681f3Smrg blob_write_uint32(metadata, params->FirstStateVarIndex); 10497ec681f3Smrg blob_write_uint32(metadata, params->LastStateVarIndex); 105001e04c3fSmrg} 105101e04c3fSmrg 105201e04c3fSmrgstatic void 105301e04c3fSmrgread_shader_parameters(struct blob_reader *metadata, 105401e04c3fSmrg struct gl_program_parameter_list *params) 105501e04c3fSmrg{ 105601e04c3fSmrg gl_state_index16 state_indexes[STATE_LENGTH]; 105701e04c3fSmrg uint32_t i = 0; 105801e04c3fSmrg uint32_t num_parameters = blob_read_uint32(metadata); 105901e04c3fSmrg 10607ec681f3Smrg _mesa_reserve_parameter_storage(params, num_parameters, num_parameters); 106101e04c3fSmrg while (i < num_parameters) { 106201e04c3fSmrg gl_register_file type = (gl_register_file) blob_read_uint32(metadata); 106301e04c3fSmrg const char *name = blob_read_string(metadata); 106401e04c3fSmrg unsigned size = blob_read_uint32(metadata); 1065993e1d59Smrg bool padded = blob_read_uint32(metadata); 106601e04c3fSmrg unsigned data_type = blob_read_uint32(metadata); 106701e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) state_indexes, 106801e04c3fSmrg sizeof(state_indexes)); 106901e04c3fSmrg 107001e04c3fSmrg _mesa_add_parameter(params, type, name, size, data_type, 1071993e1d59Smrg NULL, state_indexes, padded); 107201e04c3fSmrg 10737ec681f3Smrg gl_program_parameter *param = ¶ms->Parameters[i]; 10747ec681f3Smrg param->UniformStorageIndex = blob_read_uint32(metadata); 10757ec681f3Smrg param->MainUniformStorageIndex = blob_read_uint32(metadata); 10767ec681f3Smrg 107701e04c3fSmrg i++; 107801e04c3fSmrg } 107901e04c3fSmrg 108001e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) params->ParameterValues, 1081993e1d59Smrg sizeof(gl_constant_value) * params->NumParameterValues); 108201e04c3fSmrg 108301e04c3fSmrg params->StateFlags = blob_read_uint32(metadata); 10847ec681f3Smrg params->UniformBytes = blob_read_uint32(metadata); 10857ec681f3Smrg params->FirstStateVarIndex = blob_read_uint32(metadata); 10867ec681f3Smrg params->LastStateVarIndex = blob_read_uint32(metadata); 108701e04c3fSmrg} 108801e04c3fSmrg 108901e04c3fSmrgstatic void 109001e04c3fSmrgwrite_shader_metadata(struct blob *metadata, gl_linked_shader *shader) 109101e04c3fSmrg{ 109201e04c3fSmrg assert(shader->Program); 109301e04c3fSmrg struct gl_program *glprog = shader->Program; 109401e04c3fSmrg unsigned i; 109501e04c3fSmrg 109601e04c3fSmrg blob_write_uint64(metadata, glprog->DualSlotInputs); 109701e04c3fSmrg blob_write_bytes(metadata, glprog->TexturesUsed, 109801e04c3fSmrg sizeof(glprog->TexturesUsed)); 109901e04c3fSmrg blob_write_uint64(metadata, glprog->SamplersUsed); 110001e04c3fSmrg 110101e04c3fSmrg blob_write_bytes(metadata, glprog->SamplerUnits, 110201e04c3fSmrg sizeof(glprog->SamplerUnits)); 110301e04c3fSmrg blob_write_bytes(metadata, glprog->sh.SamplerTargets, 110401e04c3fSmrg sizeof(glprog->sh.SamplerTargets)); 110501e04c3fSmrg blob_write_uint32(metadata, glprog->ShadowSamplers); 110601e04c3fSmrg blob_write_uint32(metadata, glprog->ExternalSamplersUsed); 11077e102996Smaya blob_write_uint32(metadata, glprog->sh.ShaderStorageBlocksWriteAccess); 110801e04c3fSmrg 110901e04c3fSmrg blob_write_bytes(metadata, glprog->sh.ImageAccess, 111001e04c3fSmrg sizeof(glprog->sh.ImageAccess)); 111101e04c3fSmrg blob_write_bytes(metadata, glprog->sh.ImageUnits, 111201e04c3fSmrg sizeof(glprog->sh.ImageUnits)); 111301e04c3fSmrg 111401e04c3fSmrg size_t ptr_size = sizeof(GLvoid *); 111501e04c3fSmrg 111601e04c3fSmrg blob_write_uint32(metadata, glprog->sh.NumBindlessSamplers); 111701e04c3fSmrg blob_write_uint32(metadata, glprog->sh.HasBoundBindlessSampler); 111801e04c3fSmrg for (i = 0; i < glprog->sh.NumBindlessSamplers; i++) { 111901e04c3fSmrg blob_write_bytes(metadata, &glprog->sh.BindlessSamplers[i], 112001e04c3fSmrg sizeof(struct gl_bindless_sampler) - ptr_size); 112101e04c3fSmrg } 112201e04c3fSmrg 112301e04c3fSmrg blob_write_uint32(metadata, glprog->sh.NumBindlessImages); 112401e04c3fSmrg blob_write_uint32(metadata, glprog->sh.HasBoundBindlessImage); 112501e04c3fSmrg for (i = 0; i < glprog->sh.NumBindlessImages; i++) { 112601e04c3fSmrg blob_write_bytes(metadata, &glprog->sh.BindlessImages[i], 112701e04c3fSmrg sizeof(struct gl_bindless_image) - ptr_size); 112801e04c3fSmrg } 112901e04c3fSmrg 113001e04c3fSmrg write_shader_parameters(metadata, glprog->Parameters); 113101e04c3fSmrg 113201e04c3fSmrg assert((glprog->driver_cache_blob == NULL) == 113301e04c3fSmrg (glprog->driver_cache_blob_size == 0)); 113401e04c3fSmrg blob_write_uint32(metadata, (uint32_t)glprog->driver_cache_blob_size); 113501e04c3fSmrg if (glprog->driver_cache_blob_size > 0) { 113601e04c3fSmrg blob_write_bytes(metadata, glprog->driver_cache_blob, 113701e04c3fSmrg glprog->driver_cache_blob_size); 113801e04c3fSmrg } 113901e04c3fSmrg} 114001e04c3fSmrg 114101e04c3fSmrgstatic void 114201e04c3fSmrgread_shader_metadata(struct blob_reader *metadata, 114301e04c3fSmrg struct gl_program *glprog, 114401e04c3fSmrg gl_linked_shader *linked) 114501e04c3fSmrg{ 114601e04c3fSmrg unsigned i; 114701e04c3fSmrg 114801e04c3fSmrg glprog->DualSlotInputs = blob_read_uint64(metadata); 114901e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->TexturesUsed, 115001e04c3fSmrg sizeof(glprog->TexturesUsed)); 115101e04c3fSmrg glprog->SamplersUsed = blob_read_uint64(metadata); 115201e04c3fSmrg 115301e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->SamplerUnits, 115401e04c3fSmrg sizeof(glprog->SamplerUnits)); 115501e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->sh.SamplerTargets, 115601e04c3fSmrg sizeof(glprog->sh.SamplerTargets)); 115701e04c3fSmrg glprog->ShadowSamplers = blob_read_uint32(metadata); 115801e04c3fSmrg glprog->ExternalSamplersUsed = blob_read_uint32(metadata); 11597e102996Smaya glprog->sh.ShaderStorageBlocksWriteAccess = blob_read_uint32(metadata); 116001e04c3fSmrg 116101e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageAccess, 116201e04c3fSmrg sizeof(glprog->sh.ImageAccess)); 116301e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageUnits, 116401e04c3fSmrg sizeof(glprog->sh.ImageUnits)); 116501e04c3fSmrg 116601e04c3fSmrg size_t ptr_size = sizeof(GLvoid *); 116701e04c3fSmrg 116801e04c3fSmrg glprog->sh.NumBindlessSamplers = blob_read_uint32(metadata); 116901e04c3fSmrg glprog->sh.HasBoundBindlessSampler = blob_read_uint32(metadata); 117001e04c3fSmrg if (glprog->sh.NumBindlessSamplers > 0) { 117101e04c3fSmrg glprog->sh.BindlessSamplers = 117201e04c3fSmrg rzalloc_array(glprog, gl_bindless_sampler, 117301e04c3fSmrg glprog->sh.NumBindlessSamplers); 117401e04c3fSmrg 117501e04c3fSmrg for (i = 0; i < glprog->sh.NumBindlessSamplers; i++) { 117601e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) &glprog->sh.BindlessSamplers[i], 117701e04c3fSmrg sizeof(struct gl_bindless_sampler) - ptr_size); 117801e04c3fSmrg } 117901e04c3fSmrg } 118001e04c3fSmrg 118101e04c3fSmrg glprog->sh.NumBindlessImages = blob_read_uint32(metadata); 118201e04c3fSmrg glprog->sh.HasBoundBindlessImage = blob_read_uint32(metadata); 118301e04c3fSmrg if (glprog->sh.NumBindlessImages > 0) { 118401e04c3fSmrg glprog->sh.BindlessImages = 118501e04c3fSmrg rzalloc_array(glprog, gl_bindless_image, 118601e04c3fSmrg glprog->sh.NumBindlessImages); 118701e04c3fSmrg 118801e04c3fSmrg for (i = 0; i < glprog->sh.NumBindlessImages; i++) { 118901e04c3fSmrg blob_copy_bytes(metadata, (uint8_t *) &glprog->sh.BindlessImages[i], 119001e04c3fSmrg sizeof(struct gl_bindless_image) - ptr_size); 119101e04c3fSmrg } 119201e04c3fSmrg } 119301e04c3fSmrg 119401e04c3fSmrg glprog->Parameters = _mesa_new_parameter_list(); 119501e04c3fSmrg read_shader_parameters(metadata, glprog->Parameters); 119601e04c3fSmrg 119701e04c3fSmrg glprog->driver_cache_blob_size = (size_t)blob_read_uint32(metadata); 119801e04c3fSmrg if (glprog->driver_cache_blob_size > 0) { 119901e04c3fSmrg glprog->driver_cache_blob = 120001e04c3fSmrg (uint8_t*)ralloc_size(glprog, glprog->driver_cache_blob_size); 120101e04c3fSmrg blob_copy_bytes(metadata, glprog->driver_cache_blob, 120201e04c3fSmrg glprog->driver_cache_blob_size); 120301e04c3fSmrg } 120401e04c3fSmrg} 120501e04c3fSmrg 120601e04c3fSmrgstatic void 120701e04c3fSmrgget_shader_info_and_pointer_sizes(size_t *s_info_size, size_t *s_info_ptrs, 120801e04c3fSmrg shader_info *info) 120901e04c3fSmrg{ 121001e04c3fSmrg *s_info_size = sizeof(shader_info); 121101e04c3fSmrg *s_info_ptrs = sizeof(info->name) + sizeof(info->label); 121201e04c3fSmrg} 121301e04c3fSmrg 121401e04c3fSmrgstatic void 121501e04c3fSmrgcreate_linked_shader_and_program(struct gl_context *ctx, 121601e04c3fSmrg gl_shader_stage stage, 121701e04c3fSmrg struct gl_shader_program *prog, 121801e04c3fSmrg struct blob_reader *metadata) 121901e04c3fSmrg{ 122001e04c3fSmrg struct gl_program *glprog; 122101e04c3fSmrg 122201e04c3fSmrg struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader); 122301e04c3fSmrg linked->Stage = stage; 122401e04c3fSmrg 12257ec681f3Smrg glprog = ctx->Driver.NewProgram(ctx, stage, prog->Name, false); 122601e04c3fSmrg glprog->info.stage = stage; 122701e04c3fSmrg linked->Program = glprog; 122801e04c3fSmrg 122901e04c3fSmrg read_shader_metadata(metadata, glprog, linked); 123001e04c3fSmrg 123101e04c3fSmrg glprog->info.name = ralloc_strdup(glprog, blob_read_string(metadata)); 123201e04c3fSmrg glprog->info.label = ralloc_strdup(glprog, blob_read_string(metadata)); 123301e04c3fSmrg 123401e04c3fSmrg size_t s_info_size, s_info_ptrs; 123501e04c3fSmrg get_shader_info_and_pointer_sizes(&s_info_size, &s_info_ptrs, 123601e04c3fSmrg &glprog->info); 123701e04c3fSmrg 123801e04c3fSmrg /* Restore shader info */ 123901e04c3fSmrg blob_copy_bytes(metadata, ((uint8_t *) &glprog->info) + s_info_ptrs, 124001e04c3fSmrg s_info_size - s_info_ptrs); 124101e04c3fSmrg 124201e04c3fSmrg _mesa_reference_shader_program_data(ctx, &glprog->sh.data, prog->data); 124301e04c3fSmrg _mesa_reference_program(ctx, &linked->Program, glprog); 124401e04c3fSmrg prog->_LinkedShaders[stage] = linked; 124501e04c3fSmrg} 124601e04c3fSmrg 124701e04c3fSmrgextern "C" void 124801e04c3fSmrgserialize_glsl_program(struct blob *blob, struct gl_context *ctx, 124901e04c3fSmrg struct gl_shader_program *prog) 125001e04c3fSmrg{ 125101e04c3fSmrg blob_write_bytes(blob, prog->data->sha1, sizeof(prog->data->sha1)); 125201e04c3fSmrg 125301e04c3fSmrg write_uniforms(blob, prog); 125401e04c3fSmrg 125501e04c3fSmrg write_hash_tables(blob, prog); 125601e04c3fSmrg 125701e04c3fSmrg blob_write_uint32(blob, prog->data->Version); 12587ec681f3Smrg blob_write_uint32(blob, prog->IsES); 125901e04c3fSmrg blob_write_uint32(blob, prog->data->linked_stages); 126001e04c3fSmrg 126101e04c3fSmrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 126201e04c3fSmrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 126301e04c3fSmrg if (sh) { 126401e04c3fSmrg write_shader_metadata(blob, sh); 126501e04c3fSmrg 126601e04c3fSmrg if (sh->Program->info.name) 126701e04c3fSmrg blob_write_string(blob, sh->Program->info.name); 126801e04c3fSmrg else 126901e04c3fSmrg blob_write_string(blob, ""); 127001e04c3fSmrg 127101e04c3fSmrg if (sh->Program->info.label) 127201e04c3fSmrg blob_write_string(blob, sh->Program->info.label); 127301e04c3fSmrg else 127401e04c3fSmrg blob_write_string(blob, ""); 127501e04c3fSmrg 127601e04c3fSmrg size_t s_info_size, s_info_ptrs; 127701e04c3fSmrg get_shader_info_and_pointer_sizes(&s_info_size, &s_info_ptrs, 127801e04c3fSmrg &sh->Program->info); 127901e04c3fSmrg 128001e04c3fSmrg /* Store shader info */ 128101e04c3fSmrg blob_write_bytes(blob, 128201e04c3fSmrg ((char *) &sh->Program->info) + s_info_ptrs, 128301e04c3fSmrg s_info_size - s_info_ptrs); 128401e04c3fSmrg } 128501e04c3fSmrg } 128601e04c3fSmrg 128701e04c3fSmrg write_xfb(blob, prog); 128801e04c3fSmrg 128901e04c3fSmrg write_uniform_remap_tables(blob, prog); 129001e04c3fSmrg 129101e04c3fSmrg write_atomic_buffers(blob, prog); 129201e04c3fSmrg 129301e04c3fSmrg write_buffer_blocks(blob, prog); 129401e04c3fSmrg 129501e04c3fSmrg write_subroutines(blob, prog); 129601e04c3fSmrg 129701e04c3fSmrg write_program_resource_list(blob, prog); 129801e04c3fSmrg} 129901e04c3fSmrg 130001e04c3fSmrgextern "C" bool 130101e04c3fSmrgdeserialize_glsl_program(struct blob_reader *blob, struct gl_context *ctx, 130201e04c3fSmrg struct gl_shader_program *prog) 130301e04c3fSmrg{ 130401e04c3fSmrg /* Fixed function programs generated by Mesa can't be serialized. */ 130501e04c3fSmrg if (prog->Name == 0) 130601e04c3fSmrg return false; 130701e04c3fSmrg 130801e04c3fSmrg assert(prog->data->UniformStorage == NULL); 130901e04c3fSmrg 131001e04c3fSmrg blob_copy_bytes(blob, prog->data->sha1, sizeof(prog->data->sha1)); 131101e04c3fSmrg 131201e04c3fSmrg read_uniforms(blob, prog); 131301e04c3fSmrg 131401e04c3fSmrg read_hash_tables(blob, prog); 131501e04c3fSmrg 131601e04c3fSmrg prog->data->Version = blob_read_uint32(blob); 13177ec681f3Smrg prog->IsES = blob_read_uint32(blob); 131801e04c3fSmrg prog->data->linked_stages = blob_read_uint32(blob); 131901e04c3fSmrg 132001e04c3fSmrg unsigned mask = prog->data->linked_stages; 132101e04c3fSmrg while (mask) { 132201e04c3fSmrg const int j = u_bit_scan(&mask); 132301e04c3fSmrg create_linked_shader_and_program(ctx, (gl_shader_stage) j, prog, 132401e04c3fSmrg blob); 132501e04c3fSmrg } 132601e04c3fSmrg 132701e04c3fSmrg read_xfb(blob, prog); 132801e04c3fSmrg 132901e04c3fSmrg read_uniform_remap_tables(blob, prog); 133001e04c3fSmrg 133101e04c3fSmrg read_atomic_buffers(blob, prog); 133201e04c3fSmrg 133301e04c3fSmrg read_buffer_blocks(blob, prog); 133401e04c3fSmrg 133501e04c3fSmrg read_subroutines(blob, prog); 133601e04c3fSmrg 133701e04c3fSmrg read_program_resource_list(blob, prog); 133801e04c3fSmrg 133901e04c3fSmrg return !blob->overrun; 134001e04c3fSmrg} 1341