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