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