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 = &params->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