• 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->writeVector(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->readVector(&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),
185       shaderVersion(100),
186       numViews(-1),
187       geometryShaderInputPrimitiveType(gl::PrimitiveMode::Triangles),
188       geometryShaderOutputPrimitiveType(gl::PrimitiveMode::Triangles),
189       geometryShaderMaxVertices(0),
190       geometryShaderInvocations(1),
191       tessControlShaderVertices(0),
192       tessGenMode(0),
193       tessGenSpacing(0),
194       tessGenVertexOrder(0),
195       tessGenPointMode(0)
196 {
197     localSize.fill(-1);
198 }
199 
~CompiledShaderState()200 CompiledShaderState::~CompiledShaderState() {}
201 
buildCompiledShaderState(const ShHandle compilerHandle,const bool isBinaryOutput)202 void CompiledShaderState::buildCompiledShaderState(const ShHandle compilerHandle,
203                                                    const bool isBinaryOutput)
204 {
205     if (isBinaryOutput)
206     {
207         compiledBinary = sh::GetObjectBinaryBlob(compilerHandle);
208     }
209     else
210     {
211         translatedSource = sh::GetObjectCode(compilerHandle);
212     }
213 
214     // Gather the shader information
215     shaderVersion = sh::GetShaderVersion(compilerHandle);
216 
217     uniforms            = GetShaderVariables(sh::GetUniforms(compilerHandle));
218     uniformBlocks       = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
219     shaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
220     metadataFlags       = sh::CompilerMetadataFlags(sh::GetMetadataFlags(compilerHandle));
221     specConstUsageBits  = SpecConstUsageBits(sh::GetShaderSpecConstUsageBits(compilerHandle));
222 
223     switch (shaderType)
224     {
225         case gl::ShaderType::Compute:
226         {
227             allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
228             activeAttributes = GetActiveShaderVariables(&allAttributes);
229             localSize        = sh::GetComputeShaderLocalGroupSize(compilerHandle);
230             break;
231         }
232         case gl::ShaderType::Vertex:
233         {
234             outputVaryings   = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
235             allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
236             activeAttributes = GetActiveShaderVariables(&allAttributes);
237             numViews         = sh::GetVertexShaderNumViews(compilerHandle);
238             break;
239         }
240         case gl::ShaderType::Fragment:
241         {
242             allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
243             activeAttributes = GetActiveShaderVariables(&allAttributes);
244             inputVaryings    = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
245             // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
246             std::sort(inputVaryings.begin(), inputVaryings.end(), CompareShaderVar);
247             activeOutputVariables =
248                 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
249             advancedBlendEquations =
250                 gl::BlendEquationBitSet(sh::GetAdvancedBlendEquations(compilerHandle));
251             break;
252         }
253         case gl::ShaderType::Geometry:
254         {
255             inputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
256             outputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
257 
258             if (metadataFlags[sh::MetadataFlags::HasValidGeometryShaderInputPrimitiveType])
259             {
260                 geometryShaderInputPrimitiveType = gl::FromGLenum<gl::PrimitiveMode>(
261                     sh::GetGeometryShaderInputPrimitiveType(compilerHandle));
262             }
263             if (metadataFlags[sh::MetadataFlags::HasValidGeometryShaderOutputPrimitiveType])
264             {
265                 geometryShaderOutputPrimitiveType = gl::FromGLenum<gl::PrimitiveMode>(
266                     sh::GetGeometryShaderOutputPrimitiveType(compilerHandle));
267             }
268             if (metadataFlags[sh::MetadataFlags::HasValidGeometryShaderMaxVertices])
269             {
270                 geometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle);
271             }
272             geometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
273             break;
274         }
275         case gl::ShaderType::TessControl:
276         {
277             inputVaryings             = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
278             outputVaryings            = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
279             tessControlShaderVertices = sh::GetTessControlShaderVertices(compilerHandle);
280             break;
281         }
282         case gl::ShaderType::TessEvaluation:
283         {
284             inputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
285             outputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
286             if (metadataFlags[sh::MetadataFlags::HasValidTessGenMode])
287             {
288                 tessGenMode = sh::GetTessGenMode(compilerHandle);
289             }
290             if (metadataFlags[sh::MetadataFlags::HasValidTessGenSpacing])
291             {
292                 tessGenSpacing = sh::GetTessGenSpacing(compilerHandle);
293             }
294             if (metadataFlags[sh::MetadataFlags::HasValidTessGenVertexOrder])
295             {
296                 tessGenVertexOrder = sh::GetTessGenVertexOrder(compilerHandle);
297             }
298             if (metadataFlags[sh::MetadataFlags::HasValidTessGenPointMode])
299             {
300                 tessGenPointMode = sh::GetTessGenPointMode(compilerHandle);
301             }
302             break;
303         }
304 
305         default:
306             UNREACHABLE();
307     }
308 }
309 
serialize(gl::BinaryOutputStream & stream) const310 void CompiledShaderState::serialize(gl::BinaryOutputStream &stream) const
311 {
312     stream.writeInt(shaderVersion);
313 
314     stream.writeInt(uniforms.size());
315     for (const sh::ShaderVariable &shaderVariable : uniforms)
316     {
317         WriteShaderVar(&stream, shaderVariable);
318     }
319 
320     stream.writeInt(uniformBlocks.size());
321     for (const sh::InterfaceBlock &interfaceBlock : uniformBlocks)
322     {
323         WriteShInterfaceBlock(&stream, interfaceBlock);
324     }
325 
326     stream.writeInt(shaderStorageBlocks.size());
327     for (const sh::InterfaceBlock &interfaceBlock : shaderStorageBlocks)
328     {
329         WriteShInterfaceBlock(&stream, interfaceBlock);
330     }
331 
332     stream.writeInt(metadataFlags.bits());
333     stream.writeInt(specConstUsageBits.bits());
334 
335     switch (shaderType)
336     {
337         case gl::ShaderType::Compute:
338         {
339             stream.writeInt(allAttributes.size());
340             for (const sh::ShaderVariable &shaderVariable : allAttributes)
341             {
342                 WriteShaderVar(&stream, shaderVariable);
343             }
344             stream.writeInt(activeAttributes.size());
345             for (const sh::ShaderVariable &shaderVariable : activeAttributes)
346             {
347                 WriteShaderVar(&stream, shaderVariable);
348             }
349             stream.writeInt(localSize[0]);
350             stream.writeInt(localSize[1]);
351             stream.writeInt(localSize[2]);
352             break;
353         }
354 
355         case gl::ShaderType::Vertex:
356         {
357             stream.writeInt(outputVaryings.size());
358             for (const sh::ShaderVariable &shaderVariable : outputVaryings)
359             {
360                 WriteShaderVar(&stream, shaderVariable);
361             }
362             stream.writeInt(allAttributes.size());
363             for (const sh::ShaderVariable &shaderVariable : allAttributes)
364             {
365                 WriteShaderVar(&stream, shaderVariable);
366             }
367             stream.writeInt(activeAttributes.size());
368             for (const sh::ShaderVariable &shaderVariable : activeAttributes)
369             {
370                 WriteShaderVar(&stream, shaderVariable);
371             }
372             stream.writeInt(numViews);
373             break;
374         }
375         case gl::ShaderType::Fragment:
376         {
377             stream.writeInt(inputVaryings.size());
378             for (const sh::ShaderVariable &shaderVariable : inputVaryings)
379             {
380                 WriteShaderVar(&stream, shaderVariable);
381             }
382             stream.writeInt(activeOutputVariables.size());
383             for (const sh::ShaderVariable &shaderVariable : activeOutputVariables)
384             {
385                 WriteShaderVar(&stream, shaderVariable);
386             }
387             stream.writeInt(advancedBlendEquations.bits());
388             break;
389         }
390         case gl::ShaderType::Geometry:
391         {
392             stream.writeInt(inputVaryings.size());
393             for (const sh::ShaderVariable &shaderVariable : inputVaryings)
394             {
395                 WriteShaderVar(&stream, shaderVariable);
396             }
397             stream.writeInt(outputVaryings.size());
398             for (const sh::ShaderVariable &shaderVariable : outputVaryings)
399             {
400                 WriteShaderVar(&stream, shaderVariable);
401             }
402 
403             {
404                 unsigned char value = static_cast<unsigned char>(geometryShaderInputPrimitiveType);
405                 stream.writeBytes(&value, 1);
406             }
407             {
408                 unsigned char value = static_cast<unsigned char>(geometryShaderOutputPrimitiveType);
409                 stream.writeBytes(&value, 1);
410             }
411             {
412                 int value = static_cast<int>(geometryShaderMaxVertices);
413                 stream.writeInt(value);
414             }
415 
416             stream.writeInt(geometryShaderInvocations);
417             break;
418         }
419         case gl::ShaderType::TessControl:
420         {
421             stream.writeInt(inputVaryings.size());
422             for (const sh::ShaderVariable &shaderVariable : inputVaryings)
423             {
424                 WriteShaderVar(&stream, shaderVariable);
425             }
426             stream.writeInt(outputVaryings.size());
427             for (const sh::ShaderVariable &shaderVariable : outputVaryings)
428             {
429                 WriteShaderVar(&stream, shaderVariable);
430             }
431             stream.writeInt(tessControlShaderVertices);
432             break;
433         }
434         case gl::ShaderType::TessEvaluation:
435         {
436             unsigned int value;
437 
438             stream.writeInt(inputVaryings.size());
439             for (const sh::ShaderVariable &shaderVariable : inputVaryings)
440             {
441                 WriteShaderVar(&stream, shaderVariable);
442             }
443             stream.writeInt(outputVaryings.size());
444             for (const sh::ShaderVariable &shaderVariable : outputVaryings)
445             {
446                 WriteShaderVar(&stream, shaderVariable);
447             }
448 
449             value = (unsigned int)(tessGenMode);
450             stream.writeInt(value);
451 
452             value = (unsigned int)tessGenSpacing;
453             stream.writeInt(value);
454 
455             value = (unsigned int)tessGenVertexOrder;
456             stream.writeInt(value);
457 
458             value = (unsigned int)tessGenPointMode;
459             stream.writeInt(value);
460             break;
461         }
462         default:
463             UNREACHABLE();
464     }
465 
466     stream.writeVector(compiledBinary);
467 }
468 
deserialize(gl::BinaryInputStream & stream)469 void CompiledShaderState::deserialize(gl::BinaryInputStream &stream)
470 {
471     stream.readInt(&shaderVersion);
472 
473     size_t size;
474     size = stream.readInt<size_t>();
475     uniforms.resize(size);
476     for (sh::ShaderVariable &shaderVariable : uniforms)
477     {
478         LoadShaderVar(&stream, &shaderVariable);
479     }
480 
481     size = stream.readInt<size_t>();
482     uniformBlocks.resize(size);
483     for (sh::InterfaceBlock &interfaceBlock : uniformBlocks)
484     {
485         LoadShInterfaceBlock(&stream, &interfaceBlock);
486     }
487 
488     size = stream.readInt<size_t>();
489     shaderStorageBlocks.resize(size);
490     for (sh::InterfaceBlock &interfaceBlock : shaderStorageBlocks)
491     {
492         LoadShInterfaceBlock(&stream, &interfaceBlock);
493     }
494 
495     metadataFlags      = sh::CompilerMetadataFlags(stream.readInt<uint32_t>());
496     specConstUsageBits = SpecConstUsageBits(stream.readInt<uint32_t>());
497 
498     switch (shaderType)
499     {
500         case gl::ShaderType::Compute:
501         {
502             size = stream.readInt<size_t>();
503             allAttributes.resize(size);
504             for (sh::ShaderVariable &shaderVariable : allAttributes)
505             {
506                 LoadShaderVar(&stream, &shaderVariable);
507             }
508             size = stream.readInt<size_t>();
509             activeAttributes.resize(size);
510             for (sh::ShaderVariable &shaderVariable : activeAttributes)
511             {
512                 LoadShaderVar(&stream, &shaderVariable);
513             }
514             stream.readInt(&localSize[0]);
515             stream.readInt(&localSize[1]);
516             stream.readInt(&localSize[2]);
517             break;
518         }
519         case gl::ShaderType::Vertex:
520         {
521             size = stream.readInt<size_t>();
522             outputVaryings.resize(size);
523             for (sh::ShaderVariable &shaderVariable : outputVaryings)
524             {
525                 LoadShaderVar(&stream, &shaderVariable);
526             }
527             size = stream.readInt<size_t>();
528             allAttributes.resize(size);
529             for (sh::ShaderVariable &shaderVariable : allAttributes)
530             {
531                 LoadShaderVar(&stream, &shaderVariable);
532             }
533             size = stream.readInt<size_t>();
534             activeAttributes.resize(size);
535             for (sh::ShaderVariable &shaderVariable : activeAttributes)
536             {
537                 LoadShaderVar(&stream, &shaderVariable);
538             }
539             stream.readInt(&numViews);
540             break;
541         }
542         case gl::ShaderType::Fragment:
543         {
544             size = stream.readInt<size_t>();
545             inputVaryings.resize(size);
546             for (sh::ShaderVariable &shaderVariable : inputVaryings)
547             {
548                 LoadShaderVar(&stream, &shaderVariable);
549             }
550             size = stream.readInt<size_t>();
551             activeOutputVariables.resize(size);
552             for (sh::ShaderVariable &shaderVariable : activeOutputVariables)
553             {
554                 LoadShaderVar(&stream, &shaderVariable);
555             }
556             int advancedBlendEquationBits;
557             stream.readInt(&advancedBlendEquationBits);
558             advancedBlendEquations = gl::BlendEquationBitSet(advancedBlendEquationBits);
559             break;
560         }
561         case gl::ShaderType::Geometry:
562         {
563             size = stream.readInt<size_t>();
564             inputVaryings.resize(size);
565             for (sh::ShaderVariable &shaderVariable : inputVaryings)
566             {
567                 LoadShaderVar(&stream, &shaderVariable);
568             }
569             size = stream.readInt<size_t>();
570             outputVaryings.resize(size);
571             for (sh::ShaderVariable &shaderVariable : outputVaryings)
572             {
573                 LoadShaderVar(&stream, &shaderVariable);
574             }
575 
576             {
577                 unsigned char value;
578                 stream.readBytes(&value, 1);
579                 geometryShaderInputPrimitiveType = static_cast<gl::PrimitiveMode>(value);
580             }
581 
582             {
583                 unsigned char value;
584                 stream.readBytes(&value, 1);
585                 geometryShaderOutputPrimitiveType = static_cast<gl::PrimitiveMode>(value);
586             }
587 
588             {
589                 int value;
590                 stream.readInt(&value);
591                 geometryShaderMaxVertices = static_cast<GLint>(value);
592             }
593 
594             stream.readInt(&geometryShaderInvocations);
595             break;
596         }
597         case gl::ShaderType::TessControl:
598         {
599             size = stream.readInt<size_t>();
600             inputVaryings.resize(size);
601             for (sh::ShaderVariable &shaderVariable : inputVaryings)
602             {
603                 LoadShaderVar(&stream, &shaderVariable);
604             }
605             size = stream.readInt<size_t>();
606             outputVaryings.resize(size);
607             for (sh::ShaderVariable &shaderVariable : outputVaryings)
608             {
609                 LoadShaderVar(&stream, &shaderVariable);
610             }
611             stream.readInt(&tessControlShaderVertices);
612             break;
613         }
614         case gl::ShaderType::TessEvaluation:
615         {
616             unsigned int value;
617 
618             size = stream.readInt<size_t>();
619             inputVaryings.resize(size);
620             for (sh::ShaderVariable &shaderVariable : inputVaryings)
621             {
622                 LoadShaderVar(&stream, &shaderVariable);
623             }
624             size = stream.readInt<size_t>();
625             outputVaryings.resize(size);
626             for (sh::ShaderVariable &shaderVariable : outputVaryings)
627             {
628                 LoadShaderVar(&stream, &shaderVariable);
629             }
630 
631             stream.readInt(&value);
632             tessGenMode = (GLenum)value;
633 
634             stream.readInt(&value);
635             tessGenSpacing = (GLenum)value;
636 
637             stream.readInt(&value);
638             tessGenVertexOrder = (GLenum)value;
639 
640             stream.readInt(&value);
641             tessGenPointMode = (GLenum)value;
642             break;
643         }
644         default:
645             UNREACHABLE();
646     }
647 
648     stream.readVector(&compiledBinary);
649 }
650 }  // namespace gl
651