2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 // Copyright (C) 2016 LunarG, Inc.
4 // Copyright (C) 2017 ARM Limited.
5 // Copyright (C) 2015-2018 Google, Inc.
7 // All rights reserved.
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions
13 // Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
16 // Redistributions in binary form must reproduce the above
17 // copyright notice, this list of conditions and the following
18 // disclaimer in the documentation and/or other materials provided
19 // with the distribution.
21 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
22 // contributors may be used to endorse or promote products derived
23 // from this software without specific prior written permission.
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 // POSSIBILITY OF SUCH DAMAGE.
39 #ifndef _LOCAL_INTERMEDIATE_INCLUDED_
40 #define _LOCAL_INTERMEDIATE_INCLUDED_
42 #include "../Include/intermediate.h"
43 #include "../Public/ShaderLang.h"
56 struct TMatrixSelector {
57 int coord1; // stay agnostic about column/row; this is parse order
61 typedef int TVectorSelector;
63 const int MaxSwizzleSelectors = 4;
65 template<typename selectorType>
66 class TSwizzleSelectors {
68 TSwizzleSelectors() : size_(0) { }
70 void push_back(selectorType comp)
72 if (size_ < MaxSwizzleSelectors)
73 components[size_++] = comp;
80 int size() const { return size_; }
81 selectorType operator[](int i) const
83 assert(i < MaxSwizzleSelectors);
89 selectorType components[MaxSwizzleSelectors];
93 // Some helper structures for TIntermediate. Their contents are encapsulated
97 // Used for call-graph algorithms for detecting recursion, missing bodies, and dead bodies.
98 // A "call" is a pair: <caller, callee>.
99 // There can be duplicates. General assumption is the list is small.
101 TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { }
107 int calleeBodyPosition;
110 // A generic 1-D range.
112 TRange(int start, int last) : start(start), last(last) { }
113 bool overlap(const TRange& rhs) const
115 return last >= rhs.start && start <= rhs.last;
121 // An IO range is a 3-D rectangle; the set of (location, component, index) triples all lying
122 // within the same location range, component range, and index value. Locations don't alias unless
123 // all other dimensions of their range overlap.
125 TIoRange(TRange location, TRange component, TBasicType basicType, int index)
126 : location(location), component(component), basicType(basicType), index(index) { }
127 bool overlap(const TIoRange& rhs) const
129 return location.overlap(rhs.location) && component.overlap(rhs.component) && index == rhs.index;
133 TBasicType basicType;
137 // An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying
138 // within the same binding and offset range.
139 struct TOffsetRange {
140 TOffsetRange(TRange binding, TRange offset)
141 : binding(binding), offset(offset) { }
142 bool overlap(const TOffsetRange& rhs) const
144 return binding.overlap(rhs.binding) && offset.overlap(rhs.offset);
151 // Things that need to be tracked per xfb buffer.
153 TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false),
154 contains32BitType(false), contains16BitType(false) { }
155 std::vector<TRange> ranges; // byte offsets that have already been assigned
157 unsigned int implicitStride;
158 bool contains64BitType;
159 bool contains32BitType;
160 bool contains16BitType;
164 // Track a set of strings describing how the module was processed.
165 // This includes command line options, transforms, etc., ideally inclusive enough
166 // to reproduce the steps used to transform the input source to the output.
167 // E.g., see SPIR-V OpModuleProcessed.
168 // Each "process" or "transform" uses is expressed in the form:
169 // process arg0 arg1 arg2 ...
170 // process arg0 arg1 arg2 ...
171 // where everything is textual, and there can be zero or more arguments
177 void addProcess(const char* process)
179 processes.push_back(process);
181 void addProcess(const std::string& process)
183 processes.push_back(process);
185 void addArgument(int arg)
187 processes.back().append(" ");
188 std::string argString = std::to_string(arg);
189 processes.back().append(argString);
191 void addArgument(const char* arg)
193 processes.back().append(" ");
194 processes.back().append(arg);
196 void addArgument(const std::string& arg)
198 processes.back().append(" ");
199 processes.back().append(arg);
201 void addIfNonZero(const char* process, int value)
209 const std::vector<std::string>& getProcesses() const { return processes; }
212 std::vector<std::string> processes;
220 // Texture and Sampler transformation mode.
222 enum ComputeDerivativeMode {
223 LayoutDerivativeNone, // default layout as SPV_NV_compute_shader_derivatives not enabled
224 LayoutDerivativeGroupQuads, // derivative_group_quadsNV
225 LayoutDerivativeGroupLinear, // derivative_group_linearNV
229 // Status type on AST level. Some uncalled status or functions would be reset in call graph.
230 // Currently we will keep status set by explicitly declared layout or variable decl.
233 AstRefTypeVar, // Status set by variable decl
234 AstRefTypeFunc, // Status set by function decl
235 AstRefTypeLayout, // Status set by layout decl
240 TMap<TString, long long>& operator[](long long i) { return maps[i]; }
241 const TMap<TString, long long>& operator[](long long i) const { return maps[i]; }
243 TMap<TString, long long> maps[EsiCount];
246 class TNumericFeatures {
248 TNumericFeatures() : features(0) { }
249 TNumericFeatures(const TNumericFeatures&) = delete;
250 TNumericFeatures& operator=(const TNumericFeatures&) = delete;
251 typedef enum : unsigned int {
252 shader_explicit_arithmetic_types = 1 << 0,
253 shader_explicit_arithmetic_types_int8 = 1 << 1,
254 shader_explicit_arithmetic_types_int16 = 1 << 2,
255 shader_explicit_arithmetic_types_int32 = 1 << 3,
256 shader_explicit_arithmetic_types_int64 = 1 << 4,
257 shader_explicit_arithmetic_types_float16 = 1 << 5,
258 shader_explicit_arithmetic_types_float32 = 1 << 6,
259 shader_explicit_arithmetic_types_float64 = 1 << 7,
260 shader_implicit_conversions = 1 << 8,
261 gpu_shader_fp64 = 1 << 9,
262 gpu_shader_int16 = 1 << 10,
263 gpu_shader_half_float = 1 << 11,
265 void insert(feature f) { features |= f; }
266 void erase(feature f) { features &= ~f; }
267 bool contains(feature f) const { return (features & f) != 0; }
269 unsigned int features;
272 // MustBeAssigned wraps a T, asserting that it has been assigned with
273 // operator =() before attempting to read with operator T() or operator ->().
274 // Used to catch cases where fields are read before they have been assigned.
279 MustBeAssigned() = default;
280 MustBeAssigned(const T& v) : value(v) {}
281 operator const T&() const { assert(isSet); return value; }
282 const T* operator ->() const { assert(isSet); return &value; }
283 MustBeAssigned& operator = (const T& v) { value = v; isSet = true; return *this; }
290 // Set of helper functions to help parse and build the tree.
292 class TIntermediate {
294 explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
296 profile(p), version(v),
298 resources(TBuiltInResource{}),
299 numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
304 useStorageBuffer(false),
306 nanMinMaxClamp(false),
307 depthReplacing(false),
308 stencilReplacing(false),
310 globalUniformBlockName(""),
311 atomicCounterBlockName(""),
312 globalUniformBlockSet(TQualifier::layoutSetEnd),
313 globalUniformBlockBinding(TQualifier::layoutBindingEnd),
314 atomicCounterBlockSet(TQualifier::layoutSetEnd)
317 implicitThisName("@this"), implicitCounterName("@count"),
318 source(EShSourceNone),
319 useVulkanMemoryModel(false),
320 invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
321 inputPrimitive(ElgNone), outputPrimitive(ElgNone),
322 pixelCenterInteger(false), originUpperLeft(false),texCoordBuiltinRedeclared(false),
323 vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
324 postDepthCoverage(false), earlyAndLateFragmentTestsAMD(false), depthLayout(EldNone), stencilLayout(ElsNone),
325 hlslFunctionality1(false),
326 blendEquations(0), xfbMode(false), multiStream(false),
327 layoutOverrideCoverage(false),
328 geoPassthroughEXT(false),
329 numShaderRecordBlocks(0),
330 computeDerivativeMode(LayoutDerivativeNone),
331 primitives(TQualifier::layoutNotSet),
333 layoutPrimitiveCulling(false),
334 numTaskEXTPayloads(0),
335 autoMapBindings(false),
336 autoMapLocations(false),
337 flattenUniformArrays(false),
338 useUnknownFormat(false),
340 hlslIoMapping(false),
341 useVariablePointers(false),
342 textureSamplerTransformMode(EShTexSampTransKeep),
343 needToLegalize(false),
344 binaryDoubleOutput(false),
345 subgroupUniformControlFlow(false),
346 usePhysicalStorageBuffer(false),
347 spirvRequirement(nullptr),
348 spirvExecutionMode(nullptr),
349 uniformLocationBase(0)
355 localSizeNotDefault[0] = false;
356 localSizeNotDefault[1] = false;
357 localSizeNotDefault[2] = false;
358 localSizeSpecId[0] = TQualifier::layoutNotSet;
359 localSizeSpecId[1] = TQualifier::layoutNotSet;
360 localSizeSpecId[2] = TQualifier::layoutNotSet;
362 xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
363 shiftBinding.fill(0);
367 void setVersion(int v)
371 void setProfile(EProfile p)
376 int getVersion() const { return version; }
377 EProfile getProfile() const { return profile; }
378 void setSpv(const SpvVersion& s)
383 if (spvVersion.vulkan > 0)
384 processes.addProcess("client vulkan100");
385 if (spvVersion.openGl > 0)
386 processes.addProcess("client opengl100");
389 switch (spvVersion.spv) {
392 case EShTargetSpv_1_0:
394 case EShTargetSpv_1_1:
395 processes.addProcess("target-env spirv1.1");
397 case EShTargetSpv_1_2:
398 processes.addProcess("target-env spirv1.2");
400 case EShTargetSpv_1_3:
401 processes.addProcess("target-env spirv1.3");
403 case EShTargetSpv_1_4:
404 processes.addProcess("target-env spirv1.4");
406 case EShTargetSpv_1_5:
407 processes.addProcess("target-env spirv1.5");
409 case EShTargetSpv_1_6:
410 processes.addProcess("target-env spirv1.6");
413 processes.addProcess("target-env spirvUnknown");
417 // target-environment processes
418 switch (spvVersion.vulkan) {
421 case EShTargetVulkan_1_0:
422 processes.addProcess("target-env vulkan1.0");
424 case EShTargetVulkan_1_1:
425 processes.addProcess("target-env vulkan1.1");
427 case EShTargetVulkan_1_2:
428 processes.addProcess("target-env vulkan1.2");
430 case EShTargetVulkan_1_3:
431 processes.addProcess("target-env vulkan1.3");
434 processes.addProcess("target-env vulkanUnknown");
437 if (spvVersion.openGl > 0)
438 processes.addProcess("target-env opengl");
440 const SpvVersion& getSpv() const { return spvVersion; }
441 EShLanguage getStage() const { return language; }
442 void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); }
443 const std::set<std::string>& getRequestedExtensions() const { return requestedExtensions; }
444 bool isRayTracingStage() const {
445 return language >= EShLangRayGen && language <= EShLangCallableNV;
448 void setTreeRoot(TIntermNode* r) { treeRoot = r; }
449 TIntermNode* getTreeRoot() const { return treeRoot; }
450 void incrementEntryPointCount() { ++numEntryPoints; }
451 int getNumEntryPoints() const { return numEntryPoints; }
452 int getNumErrors() const { return numErrors; }
453 void addPushConstantCount() { ++numPushConstants; }
454 void setLimits(const TBuiltInResource& r) { resources = r; }
455 const TBuiltInResource& getLimits() const { return resources; }
457 bool postProcess(TIntermNode*, EShLanguage);
460 void setEntryPointName(const char* ep)
463 processes.addProcess("entry-point");
464 processes.addArgument(entryPointName);
466 void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
467 const std::string& getEntryPointName() const { return entryPointName; }
468 const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
470 void setDebugInfo(bool debuginfo)
472 debugInfo = debuginfo;
474 bool getDebugInfo() const { return debugInfo; }
476 void setInvertY(bool invert)
480 processes.addProcess("invert-y");
482 bool getInvertY() const { return invertY; }
484 void setDxPositionW(bool dxPosW)
486 dxPositionW = dxPosW;
488 processes.addProcess("dx-position-w");
490 bool getDxPositionW() const { return dxPositionW; }
492 void setEnhancedMsgs()
496 bool getEnhancedMsgs() const { return enhancedMsgs && getSource() == EShSourceGlsl; }
499 void setSource(EShSource s) { source = s; }
500 EShSource getSource() const { return source; }
502 void setSource(EShSource s) { assert(s == EShSourceGlsl); (void)s; }
503 EShSource getSource() const { return EShSourceGlsl; }
506 bool isRecursive() const { return recursive; }
508 TIntermSymbol* addSymbol(const TVariable&);
509 TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&);
510 TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
511 TIntermSymbol* addSymbol(const TIntermSymbol&);
512 TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
513 std::tuple<TIntermTyped*, TIntermTyped*> addPairConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1);
514 TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*);
515 TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const;
516 void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
517 TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
518 TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
519 TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
520 TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&);
521 TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, const TSourceLoc&);
522 TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType);
523 bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const;
524 bool isIntegralPromotion(TBasicType from, TBasicType to) const;
525 bool isFPPromotion(TBasicType from, TBasicType to) const;
526 bool isIntegralConversion(TBasicType from, TBasicType to) const;
527 bool isFPConversion(TBasicType from, TBasicType to) const;
528 bool isFPIntegralConversion(TBasicType from, TBasicType to) const;
529 TOperator mapTypeToConstructorOp(const TType&) const;
530 TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
531 TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
532 TIntermAggregate* makeAggregate(TIntermNode* node);
533 TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
534 TIntermAggregate* makeAggregate(const TSourceLoc&);
535 TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, const TSourceLoc&);
536 bool areAllChildConst(TIntermAggregate* aggrNode);
537 TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
538 TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
539 TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
540 TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
541 TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
542 TIntermConstantUnion* addConstantUnion(signed char, const TSourceLoc&, bool literal = false) const;
543 TIntermConstantUnion* addConstantUnion(unsigned char, const TSourceLoc&, bool literal = false) const;
544 TIntermConstantUnion* addConstantUnion(signed short, const TSourceLoc&, bool literal = false) const;
545 TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const;
546 TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const;
547 TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
548 TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const;
549 TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
550 TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
551 TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
552 TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
553 TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
554 bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
555 TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
556 TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst,
557 const TSourceLoc&, TIntermLoop*&);
558 TIntermBranch* addBranch(TOperator, const TSourceLoc&);
559 TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
560 template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
562 // Low level functions to add nodes (no conversions or other higher level transformations)
563 // If a type is provided, the node's type will be set to it.
564 TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&) const;
565 TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&,
567 TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc&) const;
568 TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc&, const TType&) const;
570 // Constant folding (in Constant.cpp)
571 TIntermTyped* fold(TIntermAggregate* aggrNode);
572 TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
573 TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&);
574 TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
577 static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false);
580 void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
581 void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
582 TIntermAggregate* findLinkerObjects() const;
584 void setGlobalUniformBlockName(const char* name) { globalUniformBlockName = std::string(name); }
585 const char* getGlobalUniformBlockName() const { return globalUniformBlockName.c_str(); }
586 void setGlobalUniformSet(unsigned int set) { globalUniformBlockSet = set; }
587 unsigned int getGlobalUniformSet() const { return globalUniformBlockSet; }
588 void setGlobalUniformBinding(unsigned int binding) { globalUniformBlockBinding = binding; }
589 unsigned int getGlobalUniformBinding() const { return globalUniformBlockBinding; }
591 void setAtomicCounterBlockName(const char* name) { atomicCounterBlockName = std::string(name); }
592 const char* getAtomicCounterBlockName() const { return atomicCounterBlockName.c_str(); }
593 void setAtomicCounterBlockSet(unsigned int set) { atomicCounterBlockSet = set; }
594 unsigned int getAtomicCounterBlockSet() const { return atomicCounterBlockSet; }
597 void setUseStorageBuffer() { useStorageBuffer = true; }
598 bool usingStorageBuffer() const { return useStorageBuffer; }
599 void setInvariantAll() { invariantAll = true; }
600 bool isInvariantAll() const { return invariantAll; }
601 void setDepthReplacing() { depthReplacing = true; }
602 bool isDepthReplacing() const { return depthReplacing; }
603 void setStencilReplacing() { stencilReplacing = true; }
604 bool isStencilReplacing() const { return stencilReplacing; }
605 bool setLocalSize(int dim, int size)
607 if (localSizeNotDefault[dim])
608 return size == localSize[dim];
609 localSizeNotDefault[dim] = true;
610 localSize[dim] = size;
613 unsigned int getLocalSize(int dim) const { return localSize[dim]; }
614 bool isLocalSizeSet() const
616 // Return true if any component has been set (i.e. any component is not default).
617 return localSizeNotDefault[0] || localSizeNotDefault[1] || localSizeNotDefault[2];
619 bool setLocalSizeSpecId(int dim, int id)
621 if (localSizeSpecId[dim] != TQualifier::layoutNotSet)
622 return id == localSizeSpecId[dim];
623 localSizeSpecId[dim] = id;
626 int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
627 bool isLocalSizeSpecialized() const
629 // Return true if any component has been specialized.
630 return localSizeSpecId[0] != TQualifier::layoutNotSet ||
631 localSizeSpecId[1] != TQualifier::layoutNotSet ||
632 localSizeSpecId[2] != TQualifier::layoutNotSet;
635 void output(TInfoSink&, bool tree) { }
637 bool isEsProfile() const { return false; }
638 bool getXfbMode() const { return false; }
639 bool isMultiStream() const { return false; }
640 TLayoutGeometry getOutputPrimitive() const { return ElgNone; }
641 bool getPostDepthCoverage() const { return false; }
642 bool getEarlyFragmentTests() const { return false; }
643 TLayoutDepth getDepth() const { return EldNone; }
644 bool getPixelCenterInteger() const { return false; }
645 void setOriginUpperLeft() { }
646 bool getOriginUpperLeft() const { return true; }
647 TInterlockOrdering getInterlockOrdering() const { return EioNone; }
649 bool getAutoMapBindings() const { return false; }
650 bool getAutoMapLocations() const { return false; }
651 int getNumPushConstants() const { return 0; }
652 void addShaderRecordCount() { }
653 void addTaskNVCount() { }
654 void addTaskPayloadEXTCount() { }
655 void setUseVulkanMemoryModel() { }
656 bool usingVulkanMemoryModel() const { return false; }
657 bool usingPhysicalStorageBuffer() const { return false; }
658 bool usingVariablePointers() const { return false; }
659 unsigned getXfbStride(int buffer) const { return 0; }
660 bool hasLayoutDerivativeModeNone() const { return false; }
661 ComputeDerivativeMode getLayoutDerivativeModeNone() const { return LayoutDerivativeNone; }
663 void output(TInfoSink&, bool tree);
665 bool isEsProfile() const { return profile == EEsProfile; }
667 void setShiftBinding(TResourceType res, unsigned int shift)
669 shiftBinding[res] = shift;
671 const char* name = getResourceName(res);
673 processes.addIfNonZero(name, shift);
676 unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
678 void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
680 if (shift == 0) // ignore if there's no shift: it's a no-op.
683 shiftBindingForSet[res][set] = shift;
685 const char* name = getResourceName(res);
686 if (name != nullptr) {
687 processes.addProcess(name);
688 processes.addArgument(shift);
689 processes.addArgument(set);
693 int getShiftBindingForSet(TResourceType res, unsigned int set) const
695 const auto shift = shiftBindingForSet[res].find(set);
696 return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
698 bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
700 void setResourceSetBinding(const std::vector<std::string>& shift)
702 resourceSetBinding = shift;
703 if (shift.size() > 0) {
704 processes.addProcess("resource-set-binding");
705 for (int s = 0; s < (int)shift.size(); ++s)
706 processes.addArgument(shift[s]);
709 const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
710 void setAutoMapBindings(bool map)
712 autoMapBindings = map;
714 processes.addProcess("auto-map-bindings");
716 bool getAutoMapBindings() const { return autoMapBindings; }
717 void setAutoMapLocations(bool map)
719 autoMapLocations = map;
720 if (autoMapLocations)
721 processes.addProcess("auto-map-locations");
723 bool getAutoMapLocations() const { return autoMapLocations; }
726 void setFlattenUniformArrays(bool flatten)
728 flattenUniformArrays = flatten;
729 if (flattenUniformArrays)
730 processes.addProcess("flatten-uniform-arrays");
732 bool getFlattenUniformArrays() const { return flattenUniformArrays; }
734 void setNoStorageFormat(bool b)
736 useUnknownFormat = b;
737 if (useUnknownFormat)
738 processes.addProcess("no-storage-format");
740 bool getNoStorageFormat() const { return useUnknownFormat; }
741 void setUseVulkanMemoryModel()
743 useVulkanMemoryModel = true;
744 processes.addProcess("use-vulkan-memory-model");
746 bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
747 void setUsePhysicalStorageBuffer()
749 usePhysicalStorageBuffer = true;
751 bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
752 void setUseVariablePointers()
754 useVariablePointers = true;
755 processes.addProcess("use-variable-pointers");
757 // Set the global flag for bindless texture
758 void setBindlessTextureMode(const TString& currentCaller, AstRefType type)
760 // When type is not func, currentCaller should be "" (empty string)
761 bindlessTextureModeCaller[currentCaller] = type;
764 // Get the global flag for bindless texture
765 bool getBindlessTextureMode() const
767 return (bindlessTextureModeCaller.size() > 0);
770 // Set the global flag for bindless image
771 void setBindlessImageMode(const TString& currentCaller, AstRefType type)
773 // When type is not func, currentCaller should be "" (empty string)
774 bindlessImageModeCaller[currentCaller] = type;
777 // Get the global flag for bindless image
778 bool getBindlessImageMode() const
780 return (bindlessImageModeCaller.size() > 0);
783 // Get the global flag for bindless texture
784 bool resetTopLevelUncalledStatus(const TString& deadCaller)
786 // For reflection collection purpose, currently uniform layout setting and some
787 // flags introduced by variables (IO, global, etc,.) won't be reset here.
788 // Remove each global status (AST top level) introduced by uncalled functions.
789 // If a status is set by several functions, keep those which in call graph.
792 // For two types of bindless mode flag, we would only reset which is set by an uncalled function.
793 // If one status flag's key in caller vec is empty, it should be come from a non-function setting.
794 if (!bindlessTextureModeCaller.empty()) {
795 auto caller = bindlessTextureModeCaller.find(deadCaller);
796 if (caller != bindlessTextureModeCaller.end() && bindlessTextureModeCaller[deadCaller] == AstRefTypeFunc) {
797 bindlessTextureModeCaller.erase(caller);
801 if (!bindlessImageModeCaller.empty()) {
802 auto caller = bindlessImageModeCaller.find(deadCaller);
803 if (caller != bindlessImageModeCaller.end() && bindlessImageModeCaller[deadCaller] == AstRefTypeFunc) {
804 bindlessImageModeCaller.erase(caller);
811 bool getBindlessMode() const
813 return getBindlessTextureMode() || getBindlessImageMode();
816 bool usingVariablePointers() const { return useVariablePointers; }
819 template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
820 bool hasCounterBufferName(const TString& name) const {
821 size_t len = strlen(implicitCounterName);
822 return name.size() > len &&
823 name.compare(name.size() - len, len, implicitCounterName) == 0;
827 void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
828 int getNumPushConstants() const { return numPushConstants; }
829 void addShaderRecordCount() { ++numShaderRecordBlocks; }
830 void addTaskNVCount() { ++numTaskNVBlocks; }
831 void addTaskPayloadEXTCount() { ++numTaskEXTPayloads; }
833 bool setInvocations(int i)
835 if (invocations != TQualifier::layoutNotSet)
836 return invocations == i;
840 int getInvocations() const { return invocations; }
841 bool setVertices(int m)
843 if (vertices != TQualifier::layoutNotSet)
844 return vertices == m;
848 int getVertices() const { return vertices; }
849 bool setInputPrimitive(TLayoutGeometry p)
851 if (inputPrimitive != ElgNone)
852 return inputPrimitive == p;
856 TLayoutGeometry getInputPrimitive() const { return inputPrimitive; }
857 bool setVertexSpacing(TVertexSpacing s)
859 if (vertexSpacing != EvsNone)
860 return vertexSpacing == s;
864 TVertexSpacing getVertexSpacing() const { return vertexSpacing; }
865 bool setVertexOrder(TVertexOrder o)
867 if (vertexOrder != EvoNone)
868 return vertexOrder == o;
872 TVertexOrder getVertexOrder() const { return vertexOrder; }
873 void setPointMode() { pointMode = true; }
874 bool getPointMode() const { return pointMode; }
876 bool setInterlockOrdering(TInterlockOrdering o)
878 if (interlockOrdering != EioNone)
879 return interlockOrdering == o;
880 interlockOrdering = o;
883 TInterlockOrdering getInterlockOrdering() const { return interlockOrdering; }
885 void setXfbMode() { xfbMode = true; }
886 bool getXfbMode() const { return xfbMode; }
887 void setMultiStream() { multiStream = true; }
888 bool isMultiStream() const { return multiStream; }
889 bool setOutputPrimitive(TLayoutGeometry p)
891 if (outputPrimitive != ElgNone)
892 return outputPrimitive == p;
896 TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; }
897 void setPostDepthCoverage() { postDepthCoverage = true; }
898 bool getPostDepthCoverage() const { return postDepthCoverage; }
899 void setEarlyFragmentTests() { earlyFragmentTests = true; }
900 void setEarlyAndLateFragmentTestsAMD() { earlyAndLateFragmentTestsAMD = true; }
901 bool getEarlyFragmentTests() const { return earlyFragmentTests; }
902 bool getEarlyAndLateFragmentTestsAMD() const { return earlyAndLateFragmentTestsAMD; }
903 bool setDepth(TLayoutDepth d)
905 if (depthLayout != EldNone)
906 return depthLayout == d;
910 bool setStencil(TLayoutStencil s)
912 if (stencilLayout != ElsNone)
913 return stencilLayout == s;
917 TLayoutDepth getDepth() const { return depthLayout; }
918 TLayoutStencil getStencil() const { return stencilLayout; }
919 void setOriginUpperLeft() { originUpperLeft = true; }
920 bool getOriginUpperLeft() const { return originUpperLeft; }
921 void setPixelCenterInteger() { pixelCenterInteger = true; }
922 bool getPixelCenterInteger() const { return pixelCenterInteger; }
923 void setTexCoordRedeclared() { texCoordBuiltinRedeclared = true; }
924 bool getTexCoordRedeclared() const { return texCoordBuiltinRedeclared; }
925 void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
926 unsigned int getBlendEquations() const { return blendEquations; }
927 bool setXfbBufferStride(int buffer, unsigned stride)
929 if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
930 return xfbBuffers[buffer].stride == stride;
931 xfbBuffers[buffer].stride = stride;
934 unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
935 int addXfbBufferOffset(const TType&);
936 unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
937 unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
938 void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
939 bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
940 void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
941 bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
942 void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
943 bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; }
944 ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
945 void setLayoutPrimitiveCulling() { layoutPrimitiveCulling = true; }
946 bool getLayoutPrimitiveCulling() const { return layoutPrimitiveCulling; }
947 bool setPrimitives(int m)
949 if (primitives != TQualifier::layoutNotSet)
950 return primitives == m;
954 int getPrimitives() const { return primitives; }
955 const char* addSemanticName(const TString& name)
957 return semanticNameSet.insert(name).first->c_str();
959 void addUniformLocationOverride(const char* nameStr, int location)
961 std::string name = nameStr;
962 uniformLocationOverrides[name] = location;
965 int getUniformLocationOverride(const char* nameStr) const
967 std::string name = nameStr;
968 auto pos = uniformLocationOverrides.find(name);
969 if (pos == uniformLocationOverrides.end())
975 void setUniformLocationBase(int base) { uniformLocationBase = base; }
976 int getUniformLocationBase() const { return uniformLocationBase; }
978 void setNeedsLegalization() { needToLegalize = true; }
979 bool needsLegalization() const { return needToLegalize; }
981 void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
982 bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
984 void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; }
985 bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; }
987 // GL_EXT_spirv_intrinsics
988 void insertSpirvRequirement(const TSpirvRequirement* spirvReq);
989 bool hasSpirvRequirement() const { return spirvRequirement != nullptr; }
990 const TSpirvRequirement& getSpirvRequirement() const { return *spirvRequirement; }
991 void insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args = nullptr);
992 void insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args);
993 bool hasSpirvExecutionMode() const { return spirvExecutionMode != nullptr; }
994 const TSpirvExecutionMode& getSpirvExecutionMode() const { return *spirvExecutionMode; }
995 #endif // GLSLANG_WEB
997 void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing)
999 std::string name(nameStr);
1000 blockBackingOverrides[name] = backing;
1002 TBlockStorageClass getBlockStorageOverride(const char* nameStr) const
1004 std::string name = nameStr;
1005 auto pos = blockBackingOverrides.find(name);
1006 if (pos == blockBackingOverrides.end())
1012 void setHlslFunctionality1() { hlslFunctionality1 = true; }
1013 bool getHlslFunctionality1() const { return hlslFunctionality1; }
1014 void setHlslOffsets()
1018 processes.addProcess("hlsl-offsets");
1020 bool usingHlslOffsets() const { return hlslOffsets; }
1021 void setHlslIoMapping(bool b)
1025 processes.addProcess("hlsl-iomap");
1027 bool usingHlslIoMapping() { return hlslIoMapping; }
1029 bool getHlslFunctionality1() const { return false; }
1030 bool usingHlslOffsets() const { return false; }
1031 bool usingHlslIoMapping() { return false; }
1034 bool usingScalarBlockLayout() const {
1035 for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) {
1036 if (*extIt == E_GL_EXT_scalar_block_layout)
1042 bool IsRequestedExtension(const char* extension) const
1044 return (requestedExtensions.find(extension) != requestedExtensions.end());
1047 void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
1048 void merge(TInfoSink&, TIntermediate&);
1049 void finalCheck(TInfoSink&, bool keepUncalled);
1051 void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly);
1052 void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit);
1053 void checkStageIO(TInfoSink&, TIntermediate&);
1055 bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const;
1056 TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
1058 void addIoAccessed(const TString& name) { ioAccessed.insert(name); }
1059 bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
1061 int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
1062 int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision);
1063 int checkLocationRT(int set, int location);
1064 int addUsedOffsets(int binding, int offset, int numOffsets);
1065 bool addUsedConstantId(int id);
1066 static int computeTypeLocationSize(const TType&, EShLanguage);
1067 static int computeTypeUniformLocationSize(const TType&);
1069 static int getBaseAlignmentScalar(const TType&, int& size);
1070 static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
1071 static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
1072 static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
1073 static bool improperStraddle(const TType& type, int size, int offset);
1074 static void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize);
1075 static int getOffset(const TType& type, int index);
1076 static int getBlockSize(const TType& blockType);
1077 static int computeBufferReferenceTypeSize(const TType&);
1078 static bool isIoResizeArray(const TType& type, EShLanguage language);
1080 bool promote(TIntermOperator*);
1081 void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
1082 bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
1084 void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; }
1085 const std::string& getSourceFile() const { return sourceFile; }
1086 void addSourceText(const char* text, size_t len) { sourceText.append(text, len); }
1087 const std::string& getSourceText() const { return sourceText; }
1088 const std::map<std::string, std::string>& getIncludeText() const { return includeText; }
1089 void addIncludeText(const char* name, const char* text, size_t len) { includeText[name].assign(text,len); }
1090 void addProcesses(const std::vector<std::string>& p)
1092 for (int i = 0; i < (int)p.size(); ++i)
1093 processes.addProcess(p[i]);
1095 void addProcess(const std::string& process) { processes.addProcess(process); }
1096 void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
1097 const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
1098 unsigned long long getUniqueId() const { return uniqueId; }
1099 void setUniqueId(unsigned long long id) { uniqueId = id; }
1101 // Certain explicit conversions are allowed conditionally
1103 bool getArithemeticInt8Enabled() const { return false; }
1104 bool getArithemeticInt16Enabled() const { return false; }
1105 bool getArithemeticFloat16Enabled() const { return false; }
1106 void updateNumericFeature(TNumericFeatures::feature f, bool on) { }
1108 bool getArithemeticInt8Enabled() const {
1109 return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
1110 numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8);
1112 bool getArithemeticInt16Enabled() const {
1113 return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
1114 numericFeatures.contains(TNumericFeatures::gpu_shader_int16) ||
1115 numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16);
1118 bool getArithemeticFloat16Enabled() const {
1119 return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
1120 numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) ||
1121 numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16);
1123 void updateNumericFeature(TNumericFeatures::feature f, bool on)
1124 { on ? numericFeatures.insert(f) : numericFeatures.erase(f); }
1128 TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
1129 void error(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
1130 void warn(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
1131 void mergeCallGraphs(TInfoSink&, TIntermediate&);
1132 void mergeModes(TInfoSink&, TIntermediate&);
1133 void mergeTrees(TInfoSink&, TIntermediate&);
1134 void seedIdMap(TIdMaps& idMaps, long long& IdShift);
1135 void remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate&);
1136 void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
1137 void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage);
1138 void mergeBlockDefinitions(TInfoSink&, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unitRoot);
1139 void mergeImplicitArraySizes(TType&, const TType&);
1140 void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, EShLanguage);
1141 void checkCallGraphCycles(TInfoSink&);
1142 void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
1143 void inOutLocationCheck(TInfoSink&);
1144 void sharedBlockCheck(TInfoSink&);
1145 bool userOutputUsed() const;
1146 bool isSpecializationOperation(const TIntermOperator&) const;
1147 bool isNonuniformPropagating(TOperator) const;
1148 bool promoteUnary(TIntermUnary&);
1149 bool promoteBinary(TIntermBinary&);
1150 void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
1151 bool promoteAggregate(TIntermAggregate&);
1152 void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
1153 void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
1154 bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
1155 void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
1156 bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
1157 std::tuple<TBasicType, TBasicType> getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const;
1159 static const char* getResourceName(TResourceType);
1161 const EShLanguage language; // stage, known at construction time
1162 std::string entryPointName;
1163 std::string entryPointMangledName;
1164 typedef std::list<TCall> TGraph;
1167 EProfile profile; // source profile
1168 int version; // source version
1169 SpvVersion spvVersion;
1170 TIntermNode* treeRoot;
1171 std::set<std::string> requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
1172 MustBeAssigned<TBuiltInResource> resources;
1175 int numPushConstants;
1181 bool useStorageBuffer;
1183 bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
1184 bool depthReplacing;
1185 bool stencilReplacing;
1187 bool localSizeNotDefault[3];
1188 int localSizeSpecId[3];
1189 unsigned long long uniqueId;
1191 std::string globalUniformBlockName;
1192 std::string atomicCounterBlockName;
1193 unsigned int globalUniformBlockSet;
1194 unsigned int globalUniformBlockBinding;
1195 unsigned int atomicCounterBlockSet;
1199 const char* const implicitThisName;
1200 const char* const implicitCounterName;
1202 EShSource source; // source language, known a bit later
1203 bool useVulkanMemoryModel;
1206 TLayoutGeometry inputPrimitive;
1207 TLayoutGeometry outputPrimitive;
1208 bool pixelCenterInteger;
1209 bool originUpperLeft;
1210 bool texCoordBuiltinRedeclared;
1211 TVertexSpacing vertexSpacing;
1212 TVertexOrder vertexOrder;
1213 TInterlockOrdering interlockOrdering;
1215 bool earlyFragmentTests;
1216 bool postDepthCoverage;
1217 bool earlyAndLateFragmentTestsAMD;
1218 TLayoutDepth depthLayout;
1219 TLayoutStencil stencilLayout;
1220 bool hlslFunctionality1;
1221 int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
1223 std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
1225 bool layoutOverrideCoverage;
1226 bool geoPassthroughEXT;
1227 int numShaderRecordBlocks;
1228 ComputeDerivativeMode computeDerivativeMode;
1230 int numTaskNVBlocks;
1231 bool layoutPrimitiveCulling;
1232 int numTaskEXTPayloads;
1234 // Base shift values
1235 std::array<unsigned int, EResCount> shiftBinding;
1237 // Per-descriptor-set shift values
1238 std::array<std::map<int, int>, EResCount> shiftBindingForSet;
1240 std::vector<std::string> resourceSetBinding;
1241 bool autoMapBindings;
1242 bool autoMapLocations;
1243 bool flattenUniformArrays;
1244 bool useUnknownFormat;
1247 bool useVariablePointers;
1249 std::set<TString> semanticNameSet;
1251 EShTextureSamplerTransformMode textureSamplerTransformMode;
1253 bool needToLegalize;
1254 bool binaryDoubleOutput;
1255 bool subgroupUniformControlFlow;
1256 bool usePhysicalStorageBuffer;
1258 TSpirvRequirement* spirvRequirement;
1259 TSpirvExecutionMode* spirvExecutionMode;
1260 std::map<TString, AstRefType> bindlessTextureModeCaller;
1261 std::map<TString, AstRefType> bindlessImageModeCaller;
1262 std::unordered_map<std::string, int> uniformLocationOverrides;
1263 int uniformLocationBase;
1264 TNumericFeatures numericFeatures;
1266 std::unordered_map<std::string, TBlockStorageClass> blockBackingOverrides;
1268 std::unordered_set<int> usedConstantId; // specialization constant ids used
1269 std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
1270 std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
1271 std::vector<TRange> usedIoRT[2]; // sets of used location, one for rayPayload/rayPayloadIN and other
1272 // for callableData/callableDataIn
1273 // set of names of statically read/written I/O that might need extra checking
1274 std::set<TString> ioAccessed;
1276 // source code of shader, useful as part of debug information
1277 std::string sourceFile;
1278 std::string sourceText;
1280 // Included text. First string is a name, second is the included text
1281 std::map<std::string, std::string> includeText;
1283 // for OpModuleProcessed, or equivalent
1284 TProcesses processes;
1287 void operator=(TIntermediate&); // prevent assignments
1290 } // end namespace glslang
1292 #endif // _LOCAL_INTERMEDIATE_INCLUDED_