• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2022 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // CompiledShaderState.cpp:
7 //   Implements CompiledShaderState, and helper functions for serializing and deserializing
8 //   shader variables.
9 //
10 
11 #include "common/CompiledShaderState.h"
12 
13 #include "common/BinaryStream.h"
14 #include "common/utilities.h"
15 
16 namespace gl
17 {
18 namespace
19 {
20 template <typename VarT>
GetActiveShaderVariables(const std::vector<VarT> * variableList)21 std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList)
22 {
23     ASSERT(variableList);
24     std::vector<VarT> result;
25     for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++)
26     {
27         const VarT &var = variableList->at(varIndex);
28         if (var.active)
29         {
30             result.push_back(var);
31         }
32     }
33     return result;
34 }
35 
36 template <typename VarT>
GetShaderVariables(const std::vector<VarT> * variableList)37 const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList)
38 {
39     ASSERT(variableList);
40     return *variableList;
41 }
42 }  // namespace
43 
44 // true if varying x has a higher priority in packing than y
CompareShaderVar(const sh::ShaderVariable & x,const sh::ShaderVariable & y)45 bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y)
46 {
47     if (x.type == y.type)
48     {
49         return x.getArraySizeProduct() > y.getArraySizeProduct();
50     }
51 
52     // Special case for handling structs: we sort these to the end of the list
53     if (x.type == GL_NONE)
54     {
55         return false;
56     }
57 
58     if (y.type == GL_NONE)
59     {
60         return true;
61     }
62 
63     return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
64 }
65 
WriteShaderVar(gl::BinaryOutputStream * stream,const sh::ShaderVariable & var)66 void WriteShaderVar(gl::BinaryOutputStream *stream, const sh::ShaderVariable &var)
67 {
68     stream->writeInt(var.type);
69     stream->writeInt(var.precision);
70     stream->writeString(var.name);
71     stream->writeString(var.mappedName);
72     stream->writeIntVector(var.arraySizes);
73     stream->writeBool(var.staticUse);
74     stream->writeBool(var.active);
75     stream->writeInt<size_t>(var.fields.size());
76     for (const sh::ShaderVariable &shaderVariable : var.fields)
77     {
78         WriteShaderVar(stream, shaderVariable);
79     }
80     stream->writeString(var.structOrBlockName);
81     stream->writeString(var.mappedStructOrBlockName);
82     stream->writeBool(var.isRowMajorLayout);
83     stream->writeInt(var.location);
84     stream->writeBool(var.hasImplicitLocation);
85     stream->writeInt(var.binding);
86     stream->writeInt(var.imageUnitFormat);
87     stream->writeInt(var.offset);
88     stream->writeBool(var.rasterOrdered);
89     stream->writeBool(var.readonly);
90     stream->writeBool(var.writeonly);
91     stream->writeBool(var.isFragmentInOut);
92     stream->writeInt(var.index);
93     stream->writeBool(var.yuv);
94     stream->writeEnum(var.interpolation);
95     stream->writeBool(var.isInvariant);
96     stream->writeBool(var.isShaderIOBlock);
97     stream->writeBool(var.isPatch);
98     stream->writeBool(var.texelFetchStaticUse);
99     stream->writeInt(var.getFlattenedOffsetInParentArrays());
100     stream->writeInt(var.id);
101 }
102 
LoadShaderVar(gl::BinaryInputStream * stream,sh::ShaderVariable * var)103 void LoadShaderVar(gl::BinaryInputStream *stream, sh::ShaderVariable *var)
104 {
105     var->type      = stream->readInt<GLenum>();
106     var->precision = stream->readInt<GLenum>();
107     stream->readString(&var->name);
108     stream->readString(&var->mappedName);
109     stream->readIntVector<unsigned int>(&var->arraySizes);
110     var->staticUse      = stream->readBool();
111     var->active         = stream->readBool();
112     size_t elementCount = stream->readInt<size_t>();
113     var->fields.resize(elementCount);
114     for (sh::ShaderVariable &variable : var->fields)
115     {
116         LoadShaderVar(stream, &variable);
117     }
118     stream->readString(&var->structOrBlockName);
119     stream->readString(&var->mappedStructOrBlockName);
120     var->isRowMajorLayout    = stream->readBool();
121     var->location            = stream->readInt<int>();
122     var->hasImplicitLocation = stream->readBool();
123     var->binding             = stream->readInt<int>();
124     var->imageUnitFormat     = stream->readInt<GLenum>();
125     var->offset              = stream->readInt<int>();
126     var->rasterOrdered       = stream->readBool();
127     var->readonly            = stream->readBool();
128     var->writeonly           = stream->readBool();
129     var->isFragmentInOut     = stream->readBool();
130     var->index               = stream->readInt<int>();
131     var->yuv                 = stream->readBool();
132     var->interpolation       = stream->readEnum<sh::InterpolationType>();
133     var->isInvariant         = stream->readBool();
134     var->isShaderIOBlock     = stream->readBool();
135     var->isPatch             = stream->readBool();
136     var->texelFetchStaticUse = stream->readBool();
137     var->setParentArrayIndex(stream->readInt<int>());
138     var->id = stream->readInt<uint32_t>();
139 }
140 
WriteShInterfaceBlock(gl::BinaryOutputStream * stream,const sh::InterfaceBlock & block)141 void WriteShInterfaceBlock(gl::BinaryOutputStream *stream, const sh::InterfaceBlock &block)
142 {
143     stream->writeString(block.name);
144     stream->writeString(block.mappedName);
145     stream->writeString(block.instanceName);
146     stream->writeInt(block.arraySize);
147     stream->writeEnum(block.layout);
148     stream->writeBool(block.isRowMajorLayout);
149     stream->writeInt(block.binding);
150     stream->writeBool(block.staticUse);
151     stream->writeBool(block.active);
152     stream->writeEnum(block.blockType);
153     stream->writeInt(block.id);
154 
155     stream->writeInt<size_t>(block.fields.size());
156     for (const sh::ShaderVariable &shaderVariable : block.fields)
157     {
158         WriteShaderVar(stream, shaderVariable);
159     }
160 }
161 
LoadShInterfaceBlock(gl::BinaryInputStream * stream,sh::InterfaceBlock * block)162 void LoadShInterfaceBlock(gl::BinaryInputStream *stream, sh::InterfaceBlock *block)
163 {
164     block->name             = stream->readString();
165     block->mappedName       = stream->readString();
166     block->instanceName     = stream->readString();
167     block->arraySize        = stream->readInt<unsigned int>();
168     block->layout           = stream->readEnum<sh::BlockLayoutType>();
169     block->isRowMajorLayout = stream->readBool();
170     block->binding          = stream->readInt<int>();
171     block->staticUse        = stream->readBool();
172     block->active           = stream->readBool();
173     block->blockType        = stream->readEnum<sh::BlockType>();
174     block->id               = stream->readInt<uint32_t>();
175 
176     block->fields.resize(stream->readInt<size_t>());
177     for (sh::ShaderVariable &variable : block->fields)
178     {
179         LoadShaderVar(stream, &variable);
180     }
181 }
182 
CompiledShaderState(gl::ShaderType type)183 CompiledShaderState::CompiledShaderState(gl::ShaderType type)
184     : shaderType(type), shaderVersion(100), numViews(-1), geometryShaderInvocations(1)
185 {
186     localSize.fill(-1);
187 }
188 
~CompiledShaderState()189 CompiledShaderState::~CompiledShaderState() {}
190 
buildCompiledShaderState(const ShHandle compilerHandle,const bool isBinaryOutput)191 void CompiledShaderState::buildCompiledShaderState(const ShHandle compilerHandle,
192                                                    const bool isBinaryOutput)
193 {
194     if (isBinaryOutput)
195     {
196         compiledBinary = sh::GetObjectBinaryBlob(compilerHandle);
197     }
198     else
199     {
200         translatedSource = sh::GetObjectCode(compilerHandle);
201     }
202 
203     // Gather the shader information
204     shaderVersion = sh::GetShaderVersion(compilerHandle);
205 
206     uniforms            = GetShaderVariables(sh::GetUniforms(compilerHandle));
207     uniformBlocks       = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
208     shaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
209     specConstUsageBits  = SpecConstUsageBits(sh::GetShaderSpecConstUsageBits(compilerHandle));
210 
211     switch (shaderType)
212     {
213         case gl::ShaderType::Compute:
214         {
215             allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
216             activeAttributes = GetActiveShaderVariables(&allAttributes);
217             localSize        = sh::GetComputeShaderLocalGroupSize(compilerHandle);
218             break;
219         }
220         case gl::ShaderType::Vertex:
221         {
222             outputVaryings   = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
223             allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
224             activeAttributes = GetActiveShaderVariables(&allAttributes);
225             hasClipDistance  = sh::HasClipDistanceInVertexShader(compilerHandle);
226             numViews         = sh::GetVertexShaderNumViews(compilerHandle);
227             break;
228         }
229         case gl::ShaderType::Fragment:
230         {
231             allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
232             activeAttributes = GetActiveShaderVariables(&allAttributes);
233             inputVaryings    = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
234             // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
235             std::sort(inputVaryings.begin(), inputVaryings.end(), CompareShaderVar);
236             activeOutputVariables =
237                 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
238             hasDiscard              = sh::HasDiscardInFragmentShader(compilerHandle);
239             enablesPerSampleShading = sh::EnablesPerSampleShading(compilerHandle);
240             advancedBlendEquations =
241                 gl::BlendEquationBitSet(sh::GetAdvancedBlendEquations(compilerHandle));
242             break;
243         }
244         case gl::ShaderType::Geometry:
245         {
246             inputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
247             outputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
248 
249             if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle))
250             {
251                 geometryShaderInputPrimitiveType = gl::FromGLenum<gl::PrimitiveMode>(
252                     sh::GetGeometryShaderInputPrimitiveType(compilerHandle));
253             }
254             if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle))
255             {
256                 geometryShaderOutputPrimitiveType = gl::FromGLenum<gl::PrimitiveMode>(
257                     sh::GetGeometryShaderOutputPrimitiveType(compilerHandle));
258             }
259             if (sh::HasValidGeometryShaderMaxVertices(compilerHandle))
260             {
261                 geometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle);
262             }
263             geometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
264             break;
265         }
266         case gl::ShaderType::TessControl:
267         {
268             inputVaryings             = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
269             outputVaryings            = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
270             tessControlShaderVertices = sh::GetTessControlShaderVertices(compilerHandle);
271             break;
272         }
273         case gl::ShaderType::TessEvaluation:
274         {
275             inputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
276             outputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
277             if (sh::HasValidTessGenMode(compilerHandle))
278             {
279                 tessGenMode = sh::GetTessGenMode(compilerHandle);
280             }
281             if (sh::HasValidTessGenSpacing(compilerHandle))
282             {
283                 tessGenSpacing = sh::GetTessGenSpacing(compilerHandle);
284             }
285             if (sh::HasValidTessGenVertexOrder(compilerHandle))
286             {
287                 tessGenVertexOrder = sh::GetTessGenVertexOrder(compilerHandle);
288             }
289             if (sh::HasValidTessGenPointMode(compilerHandle))
290             {
291                 tessGenPointMode = sh::GetTessGenPointMode(compilerHandle);
292             }
293             break;
294         }
295 
296         default:
297             UNREACHABLE();
298     }
299 }
300 
serialize(gl::BinaryOutputStream & stream) const301 void CompiledShaderState::serialize(gl::BinaryOutputStream &stream) const
302 {
303     stream.writeInt(shaderVersion);
304 
305     stream.writeInt(uniforms.size());
306     for (const sh::ShaderVariable &shaderVariable : uniforms)
307     {
308         WriteShaderVar(&stream, shaderVariable);
309     }
310 
311     stream.writeInt(uniformBlocks.size());
312     for (const sh::InterfaceBlock &interfaceBlock : uniformBlocks)
313     {
314         WriteShInterfaceBlock(&stream, interfaceBlock);
315     }
316 
317     stream.writeInt(shaderStorageBlocks.size());
318     for (const sh::InterfaceBlock &interfaceBlock : shaderStorageBlocks)
319     {
320         WriteShInterfaceBlock(&stream, interfaceBlock);
321     }
322 
323     stream.writeInt(specConstUsageBits.bits());
324 
325     switch (shaderType)
326     {
327         case gl::ShaderType::Compute:
328         {
329             stream.writeInt(allAttributes.size());
330             for (const sh::ShaderVariable &shaderVariable : allAttributes)
331             {
332                 WriteShaderVar(&stream, shaderVariable);
333             }
334             stream.writeInt(activeAttributes.size());
335             for (const sh::ShaderVariable &shaderVariable : activeAttributes)
336             {
337                 WriteShaderVar(&stream, shaderVariable);
338             }
339             stream.writeInt(localSize[0]);
340             stream.writeInt(localSize[1]);
341             stream.writeInt(localSize[2]);
342             break;
343         }
344 
345         case gl::ShaderType::Vertex:
346         {
347             stream.writeInt(outputVaryings.size());
348             for (const sh::ShaderVariable &shaderVariable : outputVaryings)
349             {
350                 WriteShaderVar(&stream, shaderVariable);
351             }
352             stream.writeInt(allAttributes.size());
353             for (const sh::ShaderVariable &shaderVariable : allAttributes)
354             {
355                 WriteShaderVar(&stream, shaderVariable);
356             }
357             stream.writeInt(activeAttributes.size());
358             for (const sh::ShaderVariable &shaderVariable : activeAttributes)
359             {
360                 WriteShaderVar(&stream, shaderVariable);
361             }
362             stream.writeBool(hasClipDistance);
363             stream.writeInt(numViews);
364             break;
365         }
366         case gl::ShaderType::Fragment:
367         {
368             stream.writeInt(inputVaryings.size());
369             for (const sh::ShaderVariable &shaderVariable : inputVaryings)
370             {
371                 WriteShaderVar(&stream, shaderVariable);
372             }
373             stream.writeInt(activeOutputVariables.size());
374             for (const sh::ShaderVariable &shaderVariable : activeOutputVariables)
375             {
376                 WriteShaderVar(&stream, shaderVariable);
377             }
378             stream.writeBool(hasDiscard);
379             stream.writeBool(enablesPerSampleShading);
380             stream.writeInt(advancedBlendEquations.bits());
381             break;
382         }
383         case gl::ShaderType::Geometry:
384         {
385             bool valid;
386 
387             stream.writeInt(inputVaryings.size());
388             for (const sh::ShaderVariable &shaderVariable : inputVaryings)
389             {
390                 WriteShaderVar(&stream, shaderVariable);
391             }
392             stream.writeInt(outputVaryings.size());
393             for (const sh::ShaderVariable &shaderVariable : outputVaryings)
394             {
395                 WriteShaderVar(&stream, shaderVariable);
396             }
397 
398             valid = (bool)geometryShaderInputPrimitiveType.valid();
399             stream.writeBool(valid);
400             if (valid)
401             {
402                 unsigned char value = (unsigned char)geometryShaderInputPrimitiveType.value();
403                 stream.writeBytes(&value, 1);
404             }
405             valid = (bool)geometryShaderOutputPrimitiveType.valid();
406             stream.writeBool(valid);
407             if (valid)
408             {
409                 unsigned char value = (unsigned char)geometryShaderOutputPrimitiveType.value();
410                 stream.writeBytes(&value, 1);
411             }
412             valid = geometryShaderMaxVertices.valid();
413             stream.writeBool(valid);
414             if (valid)
415             {
416                 int value = (int)geometryShaderMaxVertices.value();
417                 stream.writeInt(value);
418             }
419 
420             stream.writeInt(geometryShaderInvocations);
421             break;
422         }
423         case gl::ShaderType::TessControl:
424         {
425             stream.writeInt(inputVaryings.size());
426             for (const sh::ShaderVariable &shaderVariable : inputVaryings)
427             {
428                 WriteShaderVar(&stream, shaderVariable);
429             }
430             stream.writeInt(outputVaryings.size());
431             for (const sh::ShaderVariable &shaderVariable : outputVaryings)
432             {
433                 WriteShaderVar(&stream, shaderVariable);
434             }
435             stream.writeInt(tessControlShaderVertices);
436             break;
437         }
438         case gl::ShaderType::TessEvaluation:
439         {
440             unsigned int value;
441 
442             stream.writeInt(inputVaryings.size());
443             for (const sh::ShaderVariable &shaderVariable : inputVaryings)
444             {
445                 WriteShaderVar(&stream, shaderVariable);
446             }
447             stream.writeInt(outputVaryings.size());
448             for (const sh::ShaderVariable &shaderVariable : outputVaryings)
449             {
450                 WriteShaderVar(&stream, shaderVariable);
451             }
452 
453             value = (unsigned int)(tessGenMode);
454             stream.writeInt(value);
455 
456             value = (unsigned int)tessGenSpacing;
457             stream.writeInt(value);
458 
459             value = (unsigned int)tessGenVertexOrder;
460             stream.writeInt(value);
461 
462             value = (unsigned int)tessGenPointMode;
463             stream.writeInt(value);
464             break;
465         }
466         default:
467             UNREACHABLE();
468     }
469 
470     stream.writeIntVector(compiledBinary);
471 }
472 
deserialize(gl::BinaryInputStream & stream)473 void CompiledShaderState::deserialize(gl::BinaryInputStream &stream)
474 {
475     stream.readInt(&shaderVersion);
476 
477     size_t size;
478     size = stream.readInt<size_t>();
479     uniforms.resize(size);
480     for (sh::ShaderVariable &shaderVariable : uniforms)
481     {
482         LoadShaderVar(&stream, &shaderVariable);
483     }
484 
485     size = stream.readInt<size_t>();
486     uniformBlocks.resize(size);
487     for (sh::InterfaceBlock &interfaceBlock : uniformBlocks)
488     {
489         LoadShInterfaceBlock(&stream, &interfaceBlock);
490     }
491 
492     size = stream.readInt<size_t>();
493     shaderStorageBlocks.resize(size);
494     for (sh::InterfaceBlock &interfaceBlock : shaderStorageBlocks)
495     {
496         LoadShInterfaceBlock(&stream, &interfaceBlock);
497     }
498 
499     specConstUsageBits = SpecConstUsageBits(stream.readInt<uint32_t>());
500 
501     switch (shaderType)
502     {
503         case gl::ShaderType::Compute:
504         {
505             size = stream.readInt<size_t>();
506             allAttributes.resize(size);
507             for (sh::ShaderVariable &shaderVariable : allAttributes)
508             {
509                 LoadShaderVar(&stream, &shaderVariable);
510             }
511             size = stream.readInt<size_t>();
512             activeAttributes.resize(size);
513             for (sh::ShaderVariable &shaderVariable : activeAttributes)
514             {
515                 LoadShaderVar(&stream, &shaderVariable);
516             }
517             stream.readInt(&localSize[0]);
518             stream.readInt(&localSize[1]);
519             stream.readInt(&localSize[2]);
520             break;
521         }
522         case gl::ShaderType::Vertex:
523         {
524             size = stream.readInt<size_t>();
525             outputVaryings.resize(size);
526             for (sh::ShaderVariable &shaderVariable : outputVaryings)
527             {
528                 LoadShaderVar(&stream, &shaderVariable);
529             }
530             size = stream.readInt<size_t>();
531             allAttributes.resize(size);
532             for (sh::ShaderVariable &shaderVariable : allAttributes)
533             {
534                 LoadShaderVar(&stream, &shaderVariable);
535             }
536             size = stream.readInt<size_t>();
537             activeAttributes.resize(size);
538             for (sh::ShaderVariable &shaderVariable : activeAttributes)
539             {
540                 LoadShaderVar(&stream, &shaderVariable);
541             }
542             stream.readBool(&hasClipDistance);
543             stream.readInt(&numViews);
544             break;
545         }
546         case gl::ShaderType::Fragment:
547         {
548             size = stream.readInt<size_t>();
549             inputVaryings.resize(size);
550             for (sh::ShaderVariable &shaderVariable : inputVaryings)
551             {
552                 LoadShaderVar(&stream, &shaderVariable);
553             }
554             size = stream.readInt<size_t>();
555             activeOutputVariables.resize(size);
556             for (sh::ShaderVariable &shaderVariable : activeOutputVariables)
557             {
558                 LoadShaderVar(&stream, &shaderVariable);
559             }
560             stream.readBool(&hasDiscard);
561             stream.readBool(&enablesPerSampleShading);
562             int advancedBlendEquationBits;
563             stream.readInt(&advancedBlendEquationBits);
564             advancedBlendEquations = gl::BlendEquationBitSet(advancedBlendEquationBits);
565             break;
566         }
567         case gl::ShaderType::Geometry:
568         {
569             bool valid;
570 
571             size = stream.readInt<size_t>();
572             inputVaryings.resize(size);
573             for (sh::ShaderVariable &shaderVariable : inputVaryings)
574             {
575                 LoadShaderVar(&stream, &shaderVariable);
576             }
577             size = stream.readInt<size_t>();
578             outputVaryings.resize(size);
579             for (sh::ShaderVariable &shaderVariable : outputVaryings)
580             {
581                 LoadShaderVar(&stream, &shaderVariable);
582             }
583 
584             stream.readBool(&valid);
585             if (valid)
586             {
587                 unsigned char value;
588                 stream.readBytes(&value, 1);
589                 geometryShaderInputPrimitiveType = static_cast<gl::PrimitiveMode>(value);
590             }
591             else
592             {
593                 geometryShaderInputPrimitiveType.reset();
594             }
595 
596             stream.readBool(&valid);
597             if (valid)
598             {
599                 unsigned char value;
600                 stream.readBytes(&value, 1);
601                 geometryShaderOutputPrimitiveType = static_cast<gl::PrimitiveMode>(value);
602             }
603             else
604             {
605                 geometryShaderOutputPrimitiveType.reset();
606             }
607 
608             stream.readBool(&valid);
609             if (valid)
610             {
611                 int value;
612                 stream.readInt(&value);
613                 geometryShaderMaxVertices = static_cast<GLint>(value);
614             }
615             else
616             {
617                 geometryShaderMaxVertices.reset();
618             }
619 
620             stream.readInt(&geometryShaderInvocations);
621             break;
622         }
623         case gl::ShaderType::TessControl:
624         {
625             size = stream.readInt<size_t>();
626             inputVaryings.resize(size);
627             for (sh::ShaderVariable &shaderVariable : inputVaryings)
628             {
629                 LoadShaderVar(&stream, &shaderVariable);
630             }
631             size = stream.readInt<size_t>();
632             outputVaryings.resize(size);
633             for (sh::ShaderVariable &shaderVariable : outputVaryings)
634             {
635                 LoadShaderVar(&stream, &shaderVariable);
636             }
637             stream.readInt(&tessControlShaderVertices);
638             break;
639         }
640         case gl::ShaderType::TessEvaluation:
641         {
642             unsigned int value;
643 
644             size = stream.readInt<size_t>();
645             inputVaryings.resize(size);
646             for (sh::ShaderVariable &shaderVariable : inputVaryings)
647             {
648                 LoadShaderVar(&stream, &shaderVariable);
649             }
650             size = stream.readInt<size_t>();
651             outputVaryings.resize(size);
652             for (sh::ShaderVariable &shaderVariable : outputVaryings)
653             {
654                 LoadShaderVar(&stream, &shaderVariable);
655             }
656 
657             stream.readInt(&value);
658             tessGenMode = (GLenum)value;
659 
660             stream.readInt(&value);
661             tessGenSpacing = (GLenum)value;
662 
663             stream.readInt(&value);
664             tessGenVertexOrder = (GLenum)value;
665 
666             stream.readInt(&value);
667             tessGenPointMode = (GLenum)value;
668             break;
669         }
670         default:
671             UNREACHABLE();
672     }
673 
674     stream.readIntVector<unsigned int>(&compiledBinary);
675 }
676 }  // namespace gl
677