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