first commit

This commit is contained in:
nqthai199@gmail.com
2022-09-15 09:26:49 +07:00
commit df3dd9a705
168 changed files with 67159 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2013-2016 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _INITIALIZE_INCLUDED_
#define _INITIALIZE_INCLUDED_
#include "../Include/ResourceLimits.h"
#include "../Include/Common.h"
#include "../Include/ShHandle.h"
#include "SymbolTable.h"
#include "Versions.h"
namespace glslang {
//
// This is made to hold parseable strings for almost all the built-in
// functions and variables for one specific combination of version
// and profile. (Some still need to be added programmatically.)
// This is a base class for language-specific derivations, which
// can be used for language independent builtins.
//
// The strings are organized by
// commonBuiltins: intersection of all stages' built-ins, processed just once
// stageBuiltins[]: anything a stage needs that's not in commonBuiltins
//
class TBuiltInParseables {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TBuiltInParseables();
virtual ~TBuiltInParseables();
virtual void initialize(int version, EProfile, const SpvVersion& spvVersion) = 0;
virtual void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage) = 0;
virtual const TString& getCommonString() const { return commonBuiltins; }
virtual const TString& getStageString(EShLanguage language) const { return stageBuiltins[language]; }
virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) = 0;
virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) = 0;
protected:
TString commonBuiltins;
TString stageBuiltins[EShLangCount];
};
//
// This is a GLSL specific derivation of TBuiltInParseables. To present a stable
// interface and match other similar code, it is called TBuiltIns, rather
// than TBuiltInParseablesGlsl.
//
class TBuiltIns : public TBuiltInParseables {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TBuiltIns();
virtual ~TBuiltIns();
void initialize(int version, EProfile, const SpvVersion& spvVersion);
void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage);
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable);
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
protected:
void addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion);
void relateTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage, TSymbolTable&);
void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile);
void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile);
void addImageFunctions(TSampler, const TString& typeName, int version, EProfile profile);
void addSamplingFunctions(TSampler, const TString& typeName, int version, EProfile profile);
void addGatherFunctions(TSampler, const TString& typeName, int version, EProfile profile);
// Helpers for making textual representations of the permutations
// of texturing/imaging functions.
const char* postfixes[5];
const char* prefixes[EbtNumTypes];
int dimMap[EsdNumDims];
};
} // end namespace glslang
#endif // _INITIALIZE_INCLUDED_

View File

@@ -0,0 +1,168 @@
//
// Copyright (C) 2016 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "../Include/Common.h"
#include "reflection.h"
#include "localintermediate.h"
#include "gl_types.h"
#include <list>
#include <unordered_set>
namespace glslang {
//
// The traverser: mostly pass through, except
// - processing function-call nodes to push live functions onto the stack of functions to process
// - processing selection nodes to trim semantically dead code
//
// This is in the glslang namespace directly so it can be a friend of TReflection.
// This can be derived from to implement reflection database traversers or
// binding mappers: anything that wants to traverse the live subset of the tree.
//
class TLiveTraverser : public TIntermTraverser {
public:
TLiveTraverser(const TIntermediate& i, bool traverseAll = false,
bool preVisit = true, bool inVisit = false, bool postVisit = false) :
TIntermTraverser(preVisit, inVisit, postVisit),
intermediate(i), traverseAll(traverseAll)
{ }
//
// Given a function name, find its subroot in the tree, and push it onto the stack of
// functions left to process.
//
void pushFunction(const TString& name)
{
TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence();
for (unsigned int f = 0; f < globals.size(); ++f) {
TIntermAggregate* candidate = globals[f]->getAsAggregate();
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
destinations.push_back(candidate);
break;
}
}
}
void pushGlobalReference(const TString& name)
{
TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence();
for (unsigned int f = 0; f < globals.size(); ++f) {
TIntermAggregate* candidate = globals[f]->getAsAggregate();
if (candidate && candidate->getOp() == EOpSequence &&
candidate->getSequence().size() == 1 &&
candidate->getSequence()[0]->getAsBinaryNode()) {
TIntermBinary* binary = candidate->getSequence()[0]->getAsBinaryNode();
TIntermSymbol* symbol = binary->getLeft()->getAsSymbolNode();
if (symbol && symbol->getQualifier().storage == EvqGlobal &&
symbol->getName() == name) {
destinations.push_back(candidate);
break;
}
}
}
}
typedef std::list<TIntermAggregate*> TDestinationStack;
TDestinationStack destinations;
protected:
// To catch which function calls are not dead, and hence which functions must be visited.
virtual bool visitAggregate(TVisit, TIntermAggregate* node)
{
if (!traverseAll)
if (node->getOp() == EOpFunctionCall)
addFunctionCall(node);
return true; // traverse this subtree
}
// To prune semantically dead paths.
virtual bool visitSelection(TVisit /* visit */, TIntermSelection* node)
{
if (traverseAll)
return true; // traverse all code
TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion();
if (constant) {
// cull the path that is dead
if (constant->getConstArray()[0].getBConst() == true && node->getTrueBlock())
node->getTrueBlock()->traverse(this);
if (constant->getConstArray()[0].getBConst() == false && node->getFalseBlock())
node->getFalseBlock()->traverse(this);
return false; // don't traverse any more, we did it all above
} else
return true; // traverse the whole subtree
}
// Track live functions as well as uniforms, so that we don't visit dead functions
// and only visit each function once.
void addFunctionCall(TIntermAggregate* call)
{
// just use the map to ensure we process each function at most once
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
liveFunctions.insert(call->getName());
pushFunction(call->getName());
}
}
void addGlobalReference(const TString& name)
{
// just use the map to ensure we process each global at most once
if (liveGlobals.find(name) == liveGlobals.end()) {
liveGlobals.insert(name);
pushGlobalReference(name);
}
}
const TIntermediate& intermediate;
typedef std::unordered_set<TString> TLiveFunctions;
TLiveFunctions liveFunctions;
typedef std::unordered_set<TString> TLiveGlobals;
TLiveGlobals liveGlobals;
bool traverseAll;
private:
// prevent copy & copy construct
TLiveTraverser(TLiveTraverser&);
TLiveTraverser& operator=(TLiveTraverser&);
};
} // namespace glslang

View File

@@ -0,0 +1,588 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2012-2013 LunarG, Inc.
// Copyright (C) 2015-2018 Google, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//
// This header defines a two-level parse-helper hierarchy, derived from
// TParseVersions:
// - TParseContextBase: sharable across multiple parsers
// - TParseContext: GLSL specific helper
//
#ifndef _PARSER_HELPER_INCLUDED_
#define _PARSER_HELPER_INCLUDED_
#include <cstdarg>
#include <functional>
#include "parseVersions.h"
#include "../Include/ShHandle.h"
#include "SymbolTable.h"
#include "localintermediate.h"
#include "Scan.h"
#include "attribute.h"
namespace glslang {
struct TPragma {
TPragma(bool o, bool d) : optimize(o), debug(d) { }
bool optimize;
bool debug;
TPragmaTable pragmaTable;
};
class TScanContext;
class TPpContext;
typedef std::set<long long> TIdSetType;
typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord;
//
// Sharable code (as well as what's in TParseVersions) across
// parse helpers.
//
class TParseContextBase : public TParseVersions {
public:
TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, int version,
EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages,
const TString* entryPoint = nullptr)
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
scopeMangler("::"),
symbolTable(symbolTable),
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), blockNestingLevel(0), controlFlowNestingLevel(0),
currentFunctionType(nullptr),
postEntryPointReturn(false),
contextPragma(true, false),
beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
limits(resources.limits),
globalUniformBlock(nullptr),
globalUniformBinding(TQualifier::layoutBindingEnd),
globalUniformSet(TQualifier::layoutSetEnd),
atomicCounterBlockSet(TQualifier::layoutSetEnd)
{
if (entryPoint != nullptr)
sourceEntryPointName = *entryPoint;
}
virtual ~TParseContextBase() { }
#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
#endif
virtual void setLimits(const TBuiltInResource&) = 0;
void checkIndex(const TSourceLoc&, const TType&, int& index);
EShLanguage getLanguage() const { return language; }
void setScanContext(TScanContext* c) { scanContext = c; }
TScanContext* getScanContext() const { return scanContext; }
void setPpContext(TPpContext* c) { ppContext = c; }
TPpContext* getPpContext() const { return ppContext; }
virtual void setLineCallback(const std::function<void(int, int, bool, int, const char*)>& func) { lineCallback = func; }
virtual void setExtensionCallback(const std::function<void(int, const char*, const char*)>& func) { extensionCallback = func; }
virtual void setVersionCallback(const std::function<void(int, int, const char*)>& func) { versionCallback = func; }
virtual void setPragmaCallback(const std::function<void(int, const TVector<TString>&)>& func) { pragmaCallback = func; }
virtual void setErrorCallback(const std::function<void(int, const char*)>& func) { errorCallback = func; }
virtual void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) = 0;
virtual bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) = 0;
virtual bool lineDirectiveShouldSetNextLine() const = 0;
virtual void handlePragma(const TSourceLoc&, const TVector<TString>&) = 0;
virtual bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) = 0;
virtual void notifyVersion(int line, int version, const char* type_string)
{
if (versionCallback)
versionCallback(line, version, type_string);
}
virtual void notifyErrorDirective(int line, const char* error_message)
{
if (errorCallback)
errorCallback(line, error_message);
}
virtual void notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName)
{
if (lineCallback)
lineCallback(curLineNo, newLineNo, hasSource, sourceNum, sourceName);
}
virtual void notifyExtensionDirective(int line, const char* extension, const char* behavior)
{
if (extensionCallback)
extensionCallback(line, extension, behavior);
}
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
// Manage global buffer (used for backing atomic counters in GLSL when using relaxed Vulkan semantics)
virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
// Potentially rename shader entry point function
void renameShaderFunction(TString*& name) const
{
// Replace the entry point name given in the shader with the real entry point name,
// if there is a substitution.
if (name != nullptr && *name == sourceEntryPointName && intermediate.getEntryPointName().size() > 0)
name = NewPoolTString(intermediate.getEntryPointName().c_str());
}
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
const char* const scopeMangler;
// Basic parsing state, easily accessible to the grammar
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
int statementNestingLevel; // 0 if outside all flow control or compound statements
int loopNestingLevel; // 0 if outside all loops
int structNestingLevel; // 0 if outside structures
int blockNestingLevel; // 0 if outside blocks
int controlFlowNestingLevel; // 0 if outside all flow control
const TType* currentFunctionType; // the return type of the function that's currently being parsed
bool functionReturnsValue; // true if a non-void function has a return
// if inside a function, true if the function is the entry point and this is after a return statement
bool postEntryPointReturn;
// case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
TList<TIntermSequence*> switchSequenceStack;
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
TList<int> switchLevel;
struct TPragma contextPragma;
int beginInvocationInterlockCount;
int endInvocationInterlockCount;
protected:
TParseContextBase(TParseContextBase&);
TParseContextBase& operator=(TParseContextBase&);
const bool parsingBuiltins; // true if parsing built-in symbols/functions
TVector<TSymbol*> linkageSymbols; // will be transferred to 'linkage', after all editing is done, order preserving
TScanContext* scanContext;
TPpContext* ppContext;
TBuiltInResource resources;
TLimits& limits;
TString sourceEntryPointName;
// These, if set, will be called when a line, pragma ... is preprocessed.
// They will be called with any parameters to the original directive.
std::function<void(int, int, bool, int, const char*)> lineCallback;
std::function<void(int, const TVector<TString>&)> pragmaCallback;
std::function<void(int, int, const char*)> versionCallback;
std::function<void(int, const char*, const char*)> extensionCallback;
std::function<void(int, const char*)> errorCallback;
// see implementation for detail
const TFunction* selectFunction(const TVector<const TFunction*>, const TFunction&,
std::function<bool(const TType&, const TType&, TOperator, int arg)>,
std::function<bool(const TType&, const TType&, const TType&)>,
/* output */ bool& tie);
virtual void parseSwizzleSelector(const TSourceLoc&, const TString&, int size,
TSwizzleSelectors<TVectorSelector>&);
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
TVariable* globalUniformBlock; // the actual block, inserted into the symbol table
unsigned int globalUniformBinding; // the block's binding number
unsigned int globalUniformSet; // the block's set number
int firstNewMember; // the index of the first member not yet inserted into the symbol table
// override this to set the language-specific name
virtual const char* getGlobalUniformBlockName() const { return ""; }
virtual void setUniformBlockDefaults(TType&) const { }
virtual void finalizeGlobalUniformBlockLayout(TVariable&) {}
// Manage the atomic counter block (used for atomic_uints with Vulkan-Relaxed)
TMap<int, TVariable*> atomicCounterBuffers;
unsigned int atomicCounterBlockSet;
TMap<int, int> atomicCounterBlockFirstNewMember;
// override this to set the language-specific name
virtual const char* getAtomicCounterBlockName() const { return ""; }
virtual void setAtomicCounterBlockDefaults(TType&) const {}
virtual void setInvariant(const TSourceLoc&, const char*) {}
virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
bool isAtomicCounterBlock(const TSymbol& symbol) {
const TVariable* var = symbol.getAsVariable();
if (!var)
return false;
const auto& at = atomicCounterBuffers.find(var->getType().getQualifier().layoutBinding);
return (at != atomicCounterBuffers.end() && (*at).second->getType() == var->getType());
}
virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, TPrefixType prefix,
va_list args);
virtual void trackLinkage(TSymbol& symbol);
virtual void makeEditable(TSymbol*&);
virtual TVariable* getEditableVariable(const char* name);
virtual void finish();
};
//
// Manage the state for when to respect precision qualifiers and when to warn about
// the defaults being different than might be expected.
//
class TPrecisionManager {
public:
TPrecisionManager() : obey(false), warn(false), explicitIntDefault(false), explicitFloatDefault(false){ }
virtual ~TPrecisionManager() {}
void respectPrecisionQualifiers() { obey = true; }
bool respectingPrecisionQualifiers() const { return obey; }
bool shouldWarnAboutDefaults() const { return warn; }
void defaultWarningGiven() { warn = false; }
void warnAboutDefaults() { warn = true; }
void explicitIntDefaultSeen()
{
explicitIntDefault = true;
if (explicitFloatDefault)
warn = false;
}
void explicitFloatDefaultSeen()
{
explicitFloatDefault = true;
if (explicitIntDefault)
warn = false;
}
protected:
bool obey; // respect precision qualifiers
bool warn; // need to give a warning about the defaults
bool explicitIntDefault; // user set the default for int/uint
bool explicitFloatDefault; // user set the default for float
};
//
// GLSL-specific parse helper. Should have GLSL in the name, but that's
// too big of a change for comparing branches at the moment, and perhaps
// impacts downstream consumers as well.
//
class TParseContext : public TParseContextBase {
public:
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&,
bool forwardCompatible = false, EShMessages messages = EShMsgDefault,
const TString* entryPoint = nullptr);
virtual ~TParseContext();
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }
void setPrecisionDefaults();
void setLimits(const TBuiltInResource&) override;
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
void parserError(const char* s); // for bison's yyerror
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
void reservedErrorCheck(const TSourceLoc&, const TString&);
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
bool lineDirectiveShouldSetNextLine() const override;
bool builtInName(const TString&);
void handlePragma(const TSourceLoc&, const TVector<TString>&) override;
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
#ifndef GLSLANG_WEB
void makeEditable(TSymbol*&) override;
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
#endif
bool isIoResizeArray(const TType&) const;
void fixIoArraySize(const TSourceLoc&, TType&);
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const;
void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
TIntermTyped* handleDotSwizzle(const TSourceLoc&, TIntermTyped* base, const TString& field);
void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName);
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
TIntermTyped* handleBuiltInFunctionCall(TSourceLoc, TIntermNode* arguments, const TFunction& function);
void computeBuiltinPrecisions(TIntermTyped&, const TFunction&);
TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
void checkLocation(const TSourceLoc&, TOperator);
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
TIntermTyped* addAssign(const TSourceLoc&, TOperator op, TIntermTyped* left, TIntermTyped* right);
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
void samplerConstructorLocationCheck(const TSourceLoc&, const char* token, TIntermNode*);
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode);
TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
// returns true if the variable was remapped to something else
bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&);
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
void variableCheck(TIntermTyped*& nodePtr);
bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
void constantValueCheck(TIntermTyped* node, const char* token);
void integerCheck(const TIntermTyped* node, const char* token);
void globalCheck(const TSourceLoc&, const char* token);
bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&);
void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType);
bool arrayQualifierError(const TSourceLoc&, const TQualifier&);
bool arrayError(const TSourceLoc&, const TType&);
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
void structArrayCheck(const TSourceLoc&, const TType& structure);
void arraySizesCheck(const TSourceLoc&, const TQualifier&, TArraySizes*, const TIntermTyped* initializer, bool lastMember);
void arrayOfArrayVersionCheck(const TSourceLoc&, const TArraySizes*);
bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType);
void boolCheck(const TSourceLoc&, const TIntermTyped*);
void boolCheck(const TSourceLoc&, const TPublicType&);
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
void memberQualifierCheck(glslang::TPublicType&);
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false);
void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
void setDefaultPrecision(const TSourceLoc&, TPublicType&, TPrecisionQualifier);
int computeSamplerTypeIndex(TSampler&);
TPrecisionQualifier getDefaultPrecision(TPublicType&);
void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&);
void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type);
bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&);
void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
void paramCheckFixStorage(const TSourceLoc&, const TStorageQualifier&, TType& type);
void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
void nestedBlockCheck(const TSourceLoc&);
void nestedStructCheck(const TSourceLoc&);
void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op);
void opaqueCheck(const TSourceLoc&, const TType&, const char* op);
void referenceCheck(const TSourceLoc&, const TType&, const char* op);
void storage16BitAssignmentCheck(const TSourceLoc&, const TType&, const char* op);
void specializationCheck(const TSourceLoc&, const TType&, const char* op);
void structTypeCheck(const TSourceLoc&, TPublicType&);
void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop);
void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature);
void inductiveLoopBodyCheck(TIntermNode*, long long loopIndexId, TSymbolTable&);
void constantIndexExpressionCheck(TIntermNode*);
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
void layoutMemberLocationArrayCheck(const TSourceLoc&, bool memberWithLocation, TArraySizes* arraySizes);
void layoutTypeCheck(const TSourceLoc&, const TType&);
void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
void fixOffset(const TSourceLoc&, TSymbol&);
const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
const TFunction* findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
void declareTypeDefaults(const TSourceLoc&, const TPublicType&);
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to);
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&);
void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
void fixXfbOffsets(TQualifier&, TTypeList&);
void fixBlockUniformOffsets(TQualifier&, TTypeList&);
void fixBlockUniformLayoutMatrix(TQualifier&, TTypeList*, TTypeList*);
void fixBlockUniformLayoutPacking(TQualifier&, TTypeList*, TTypeList*);
void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
void invariantCheck(const TSourceLoc&, const TQualifier&);
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*);
#ifndef GLSLANG_WEB
TAttributeType attributeFromName(const TString& name) const;
TAttributes* makeAttributes(const TString& identifier) const;
TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
TAttributes* mergeAttributes(TAttributes*, TAttributes*) const;
// Determine selection control from attributes
void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*);
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
// Determine loop control from attributes
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
// Function attributes
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
// GL_EXT_spirv_intrinsics
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
const TIntermAggregate* extensions, const TIntermAggregate* capabilities);
TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
TSpirvRequirement* spirvReq2);
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
TSpirvTypeParameters* spirvTypeParams2);
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value);
TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1,
TSpirvInstruction* spirvInst2);
#endif
void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);
protected:
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
void inheritGlobalDefaults(TQualifier& dst) const;
TVariable* makeInternalVariable(const char* name, const TType&) const;
TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&);
void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&);
void checkRuntimeSizable(const TSourceLoc&, const TIntermTyped&);
bool isRuntimeLength(const TIntermTyped&) const;
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
#ifndef GLSLANG_WEB
void finish() override;
#endif
virtual const char* getGlobalUniformBlockName() const override;
virtual void finalizeGlobalUniformBlockLayout(TVariable&) override;
virtual void setUniformBlockDefaults(TType& block) const override;
virtual const char* getAtomicCounterBlockName() const override;
virtual void finalizeAtomicCounterBlockLayout(TVariable&) override;
virtual void setAtomicCounterBlockDefaults(TType& block) const override;
virtual void setInvariant(const TSourceLoc& loc, const char* builtin) override;
public:
//
// Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access
//
// Current state of parsing
bool inMain; // if inside a function, true if the function is main
const TString* blockName;
TQualifier currentBlockQualifier;
TPrecisionQualifier defaultPrecision[EbtNumTypes];
TBuiltInResource resources;
TLimits& limits;
protected:
TParseContext(TParseContext&);
TParseContext& operator=(TParseContext&);
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2 * 2 * 2)); // see computeSamplerTypeIndex()
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
TPrecisionManager precisionManager;
TQualifier globalBufferDefaults;
TQualifier globalUniformDefaults;
TQualifier globalInputDefaults;
TQualifier globalOutputDefaults;
TQualifier globalSharedDefaults;
TString currentCaller; // name of last function body entered (not valid when at global scope)
#ifndef GLSLANG_WEB
int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point
bool anyIndexLimits;
TIdSetType inductiveLoopIds;
TVector<TIntermTyped*> needsIndexLimitationChecking;
TStructRecord matrixFixRecord;
TStructRecord packingFixRecord;
//
// Geometry shader input arrays:
// - array sizing is based on input primitive and/or explicit size
//
// Tessellation control output arrays:
// - array sizing is based on output layout(vertices=...) and/or explicit size
//
// Both:
// - array sizing is retroactive
// - built-in block redeclarations interact with this
//
// Design:
// - use a per-context "resize-list", a list of symbols whose array sizes
// can be fixed
//
// - the resize-list starts empty at beginning of user-shader compilation, it does
// not have built-ins in it
//
// - on built-in array use: copyUp() symbol and add it to the resize-list
//
// - on user array declaration: add it to the resize-list
//
// - on block redeclaration: copyUp() symbol and add it to the resize-list
// * note, that appropriately gives an error if redeclaring a block that
// was already used and hence already copied-up
//
// - on seeing a layout declaration that sizes the array, fix everything in the
// resize-list, giving errors for mismatch
//
// - on seeing an array size declaration, give errors on mismatch between it and previous
// array-sizing declarations
//
TVector<TSymbol*> ioArraySymbolResizeList;
#endif
};
} // end namespace glslang
#endif // _PARSER_HELPER_INCLUDED_

View File

@@ -0,0 +1,41 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
namespace glslang {
void RemoveAllTreeNodes(TIntermNode*);
} // end namespace glslang

View File

@@ -0,0 +1,276 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2013 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _GLSLANG_SCAN_INCLUDED_
#define _GLSLANG_SCAN_INCLUDED_
#include "Versions.h"
namespace glslang {
// Use a global end-of-input character, so no translation is needed across
// layers of encapsulation. Characters are all 8 bit, and positive, so there is
// no aliasing of character 255 onto -1, for example.
const int EndOfInput = -1;
//
// A character scanner that seamlessly, on read-only strings, reads across an
// array of strings without assuming null termination.
//
class TInputScanner {
public:
TInputScanner(int n, const char* const s[], size_t L[], const char* const* names = nullptr,
int b = 0, int f = 0, bool single = false) :
numSources(n),
// up to this point, common usage is "char*", but now we need positive 8-bit characters
sources(reinterpret_cast<const unsigned char* const *>(s)),
lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f), singleLogical(single),
endOfFileReached(false)
{
loc = new TSourceLoc[numSources];
for (int i = 0; i < numSources; ++i) {
loc[i].init(i - stringBias);
}
if (names != nullptr) {
for (int i = 0; i < numSources; ++i)
loc[i].name = names[i] != nullptr ? NewPoolTString(names[i]) : nullptr;
}
loc[currentSource].line = 1;
logicalSourceLoc.init(1);
logicalSourceLoc.name = loc[0].name;
}
virtual ~TInputScanner()
{
delete [] loc;
}
// retrieve the next character and advance one character
int get()
{
int ret = peek();
if (ret == EndOfInput)
return ret;
++loc[currentSource].column;
++logicalSourceLoc.column;
if (ret == '\n') {
++loc[currentSource].line;
++logicalSourceLoc.line;
logicalSourceLoc.column = 0;
loc[currentSource].column = 0;
}
advance();
return ret;
}
// retrieve the next character, no advance
int peek()
{
if (currentSource >= numSources) {
endOfFileReached = true;
return EndOfInput;
}
// Make sure we do not read off the end of a string.
// N.B. Sources can have a length of 0.
int sourceToRead = currentSource;
size_t charToRead = currentChar;
while(charToRead >= lengths[sourceToRead]) {
charToRead = 0;
sourceToRead += 1;
if (sourceToRead >= numSources) {
return EndOfInput;
}
}
// Here, we care about making negative valued characters positive
return sources[sourceToRead][charToRead];
}
// go back one character
void unget()
{
// Do not roll back once we've reached the end of the file.
if (endOfFileReached)
return;
if (currentChar > 0) {
--currentChar;
--loc[currentSource].column;
--logicalSourceLoc.column;
if (loc[currentSource].column < 0) {
// We've moved back past a new line. Find the
// previous newline (or start of the file) to compute
// the column count on the now current line.
size_t chIndex = currentChar;
while (chIndex > 0) {
if (sources[currentSource][chIndex] == '\n') {
break;
}
--chIndex;
}
logicalSourceLoc.column = (int)(currentChar - chIndex);
loc[currentSource].column = (int)(currentChar - chIndex);
}
} else {
do {
--currentSource;
} while (currentSource > 0 && lengths[currentSource] == 0);
if (lengths[currentSource] == 0) {
// set to 0 if we've backed up to the start of an empty string
currentChar = 0;
} else
currentChar = lengths[currentSource] - 1;
}
if (peek() == '\n') {
--loc[currentSource].line;
--logicalSourceLoc.line;
}
}
// for #line override
void setLine(int newLine)
{
logicalSourceLoc.line = newLine;
loc[getLastValidSourceIndex()].line = newLine;
}
// for #line override in filename based parsing
void setFile(const char* filename)
{
TString* fn_tstr = NewPoolTString(filename);
logicalSourceLoc.name = fn_tstr;
loc[getLastValidSourceIndex()].name = fn_tstr;
}
void setFile(const char* filename, int i)
{
TString* fn_tstr = NewPoolTString(filename);
if (i == getLastValidSourceIndex()) {
logicalSourceLoc.name = fn_tstr;
}
loc[i].name = fn_tstr;
}
void setString(int newString)
{
logicalSourceLoc.string = newString;
loc[getLastValidSourceIndex()].string = newString;
logicalSourceLoc.name = nullptr;
loc[getLastValidSourceIndex()].name = nullptr;
}
// for #include content indentation
void setColumn(int col)
{
logicalSourceLoc.column = col;
loc[getLastValidSourceIndex()].column = col;
}
void setEndOfInput()
{
endOfFileReached = true;
currentSource = numSources;
}
bool atEndOfInput() const { return endOfFileReached; }
const TSourceLoc& getSourceLoc() const
{
if (singleLogical) {
return logicalSourceLoc;
} else {
return loc[std::max(0, std::min(currentSource, numSources - finale - 1))];
}
}
// Returns the index (starting from 0) of the most recent valid source string we are reading from.
int getLastValidSourceIndex() const { return std::min(currentSource, numSources - 1); }
void consumeWhiteSpace(bool& foundNonSpaceTab);
bool consumeComment();
void consumeWhitespaceComment(bool& foundNonSpaceTab);
bool scanVersion(int& version, EProfile& profile, bool& notFirstToken);
protected:
// advance one character
void advance()
{
++currentChar;
if (currentChar >= lengths[currentSource]) {
++currentSource;
if (currentSource < numSources) {
loc[currentSource].string = loc[currentSource - 1].string + 1;
loc[currentSource].line = 1;
loc[currentSource].column = 0;
}
while (currentSource < numSources && lengths[currentSource] == 0) {
++currentSource;
if (currentSource < numSources) {
loc[currentSource].string = loc[currentSource - 1].string + 1;
loc[currentSource].line = 1;
loc[currentSource].column = 0;
}
}
currentChar = 0;
}
}
int numSources; // number of strings in source
const unsigned char* const *sources; // array of strings; must be converted to positive values on use, to avoid aliasing with -1 as EndOfInput
const size_t *lengths; // length of each string
int currentSource;
size_t currentChar;
// This is for reporting what string/line an error occurred on, and can be overridden by #line.
// It remembers the last state of each source string as it is left for the next one, so unget()
// can restore that state.
TSourceLoc* loc; // an array
int stringBias; // the first string that is the user's string number 0
int finale; // number of internal strings after user's last string
TSourceLoc logicalSourceLoc;
bool singleLogical; // treats the strings as a single logical string.
// locations will be reported from the first string.
// Set to true once peek() returns EndOfFile, so that we won't roll back
// once we've reached EndOfFile.
bool endOfFileReached;
};
} // end namespace glslang
#endif // _GLSLANG_SCAN_INCLUDED_

View File

@@ -0,0 +1,93 @@
//
// Copyright (C) 2013 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//
// This holds context specific to the GLSL scanner, which
// sits between the preprocessor scanner and parser.
//
#pragma once
#include "ParseHelper.h"
namespace glslang {
class TPpContext;
class TPpToken;
class TParserToken;
class TScanContext {
public:
explicit TScanContext(TParseContextBase& pc) :
parseContext(pc),
afterType(false), afterStruct(false),
field(false), afterBuffer(false) { }
virtual ~TScanContext() { }
static void fillInKeywordMap();
static void deleteKeywordMap();
int tokenize(TPpContext*, TParserToken&);
protected:
TScanContext(TScanContext&);
TScanContext& operator=(TScanContext&);
int tokenizeIdentifier();
int identifierOrType();
int reservedWord();
int identifierOrReserved(bool reserved);
int es30ReservedFromGLSL(int version);
int nonreservedKeyword(int esVersion, int nonEsVersion);
int precisionKeyword();
int matNxM();
int dMat();
int firstGenerationImage(bool inEs310);
int secondGenerationImage();
TParseContextBase& parseContext;
bool afterType; // true if we've recognized a type, so can only be looking for an identifier
bool afterStruct; // true if we've recognized the STRUCT keyword, so can only be looking for an identifier
bool field; // true if we're on a field, right after a '.'
bool afterBuffer; // true if we've recognized the BUFFER keyword
TSourceLoc loc;
TParserToken* parserToken;
TPpToken* ppToken;
const char* tokenText;
int keyword;
};
} // end namespace glslang

View File

@@ -0,0 +1,955 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2013 LunarG, Inc.
// Copyright (C) 2015-2018 Google, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _SYMBOL_TABLE_INCLUDED_
#define _SYMBOL_TABLE_INCLUDED_
//
// Symbol table for parsing. Has these design characteristics:
//
// * Same symbol table can be used to compile many shaders, to preserve
// effort of creating and loading with the large numbers of built-in
// symbols.
//
// --> This requires a copy mechanism, so initial pools used to create
// the shared information can be popped. Done through "clone"
// methods.
//
// * Name mangling will be used to give each function a unique name
// so that symbol table lookups are never ambiguous. This allows
// a simpler symbol table structure.
//
// * Pushing and popping of scope, so symbol table will really be a stack
// of symbol tables. Searched from the top, with new inserts going into
// the top.
//
// * Constants: Compile time constant symbols will keep their values
// in the symbol table. The parser can substitute constants at parse
// time, including doing constant folding and constant propagation.
//
// * No temporaries: Temporaries made from operations (+, --, .xy, etc.)
// are tracked in the intermediate representation, not the symbol table.
//
#include "../Include/Common.h"
#include "../Include/intermediate.h"
#include "../Include/InfoSink.h"
namespace glslang {
//
// Symbol base class. (Can build functions or variables out of these...)
//
class TVariable;
class TFunction;
class TAnonMember;
typedef TVector<const char*> TExtensionList;
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
explicit TSymbol(const TString *n) : name(n), uniqueId(0), extensions(0), writable(true) { }
virtual TSymbol* clone() const = 0;
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
virtual const TString& getName() const { return *name; }
virtual void changeName(const TString* newName) { name = newName; }
virtual void addPrefix(const char* prefix)
{
TString newName(prefix);
newName.append(*name);
changeName(NewPoolTString(newName.c_str()));
}
virtual const TString& getMangledName() const { return getName(); }
virtual TFunction* getAsFunction() { return 0; }
virtual const TFunction* getAsFunction() const { return 0; }
virtual TVariable* getAsVariable() { return 0; }
virtual const TVariable* getAsVariable() const { return 0; }
virtual const TAnonMember* getAsAnonMember() const { return 0; }
virtual const TType& getType() const = 0;
virtual TType& getWritableType() = 0;
virtual void setUniqueId(long long id) { uniqueId = id; }
virtual long long getUniqueId() const { return uniqueId; }
virtual void setExtensions(int numExts, const char* const exts[])
{
assert(extensions == 0);
assert(numExts > 0);
extensions = NewPoolObject(extensions);
for (int e = 0; e < numExts; ++e)
extensions->push_back(exts[e]);
}
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
virtual const char** getExtensions() const { return extensions->data(); }
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0;
void dumpExtensions(TInfoSink& infoSink) const;
#endif
virtual bool isReadOnly() const { return ! writable; }
virtual void makeReadOnly() { writable = false; }
protected:
explicit TSymbol(const TSymbol&);
TSymbol& operator=(const TSymbol&);
const TString *name;
unsigned long long uniqueId; // For cross-scope comparing during code generation
// For tracking what extensions must be present
// (don't use if correct version/profile is present).
TExtensionList* extensions; // an array of pointers to existing constant char strings
//
// N.B.: Non-const functions that will be generally used should assert on this,
// to avoid overwriting shared symbol-table information.
//
bool writable;
};
//
// Variable class, meaning a symbol that's not a function.
//
// There could be a separate class hierarchy for Constant variables;
// Only one of int, bool, or float, (or none) is correct for
// any particular use, but it's easy to do this way, and doesn't
// seem worth having separate classes, and "getConst" can't simply return
// different values for different types polymorphically, so this is
// just simple and pragmatic.
//
class TVariable : public TSymbol {
public:
TVariable(const TString *name, const TType& t, bool uT = false )
: TSymbol(name),
userType(uT),
constSubtree(nullptr),
memberExtensions(nullptr),
anonId(-1)
{ type.shallowCopy(t); }
virtual TVariable* clone() const;
virtual ~TVariable() { }
virtual TVariable* getAsVariable() { return this; }
virtual const TVariable* getAsVariable() const { return this; }
virtual const TType& getType() const { return type; }
virtual TType& getWritableType() { assert(writable); return type; }
virtual bool isUserType() const { return userType; }
virtual const TConstUnionArray& getConstArray() const { return constArray; }
virtual TConstUnionArray& getWritableConstArray() { assert(writable); return constArray; }
virtual void setConstArray(const TConstUnionArray& array) { constArray = array; }
virtual void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
virtual TIntermTyped* getConstSubtree() const { return constSubtree; }
virtual void setAnonId(int i) { anonId = i; }
virtual int getAnonId() const { return anonId; }
virtual void setMemberExtensions(int member, int numExts, const char* const exts[])
{
assert(type.isStruct());
assert(numExts > 0);
if (memberExtensions == nullptr) {
memberExtensions = NewPoolObject(memberExtensions);
memberExtensions->resize(type.getStruct()->size());
}
for (int e = 0; e < numExts; ++e)
(*memberExtensions)[member].push_back(exts[e]);
}
virtual bool hasMemberExtensions() const { return memberExtensions != nullptr; }
virtual int getNumMemberExtensions(int member) const
{
return memberExtensions == nullptr ? 0 : (int)(*memberExtensions)[member].size();
}
virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
virtual void dump(TInfoSink& infoSink, bool complete = false) const;
#endif
protected:
explicit TVariable(const TVariable&);
TVariable& operator=(const TVariable&);
TType type;
bool userType;
// we are assuming that Pool Allocator will free the memory allocated to unionArray
// when this object is destroyed
TConstUnionArray constArray; // for compile-time constant value
TIntermTyped* constSubtree; // for specialization constant computation
TVector<TExtensionList>* memberExtensions; // per-member extension list, allocated only when needed
int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose
};
//
// The function sub-class of symbols and the parser will need to
// share this definition of a function parameter.
//
struct TParameter {
TString *name;
TType* type;
TIntermTyped* defaultValue;
void copyParam(const TParameter& param)
{
if (param.name)
name = NewPoolTString(param.name->c_str());
else
name = 0;
type = param.type->clone();
defaultValue = param.defaultValue;
}
TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; }
};
//
// The function sub-class of a symbol.
//
class TFunction : public TSymbol {
public:
explicit TFunction(TOperator o) :
TSymbol(0),
op(o),
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { }
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
TSymbol(name),
mangledName(*name + '('),
op(tOp),
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0)
{
returnType.shallowCopy(retType);
declaredBuiltIn = retType.getQualifier().builtIn;
}
virtual TFunction* clone() const override;
virtual ~TFunction();
virtual TFunction* getAsFunction() override { return this; }
virtual const TFunction* getAsFunction() const override { return this; }
// Install 'p' as the (non-'this') last parameter.
// Non-'this' parameters are reflected in both the list of parameters and the
// mangled name.
virtual void addParameter(TParameter& p)
{
assert(writable);
parameters.push_back(p);
p.type->appendMangledName(mangledName);
if (p.defaultValue != nullptr)
defaultParamCount++;
}
// Install 'this' as the first parameter.
// 'this' is reflected in the list of parameters, but not the mangled name.
virtual void addThisParameter(TType& type, const char* name)
{
TParameter p = { NewPoolTString(name), new TType, nullptr };
p.type->shallowCopy(type);
parameters.insert(parameters.begin(), p);
}
virtual void addPrefix(const char* prefix) override
{
TSymbol::addPrefix(prefix);
mangledName.insert(0, prefix);
}
virtual void removePrefix(const TString& prefix)
{
assert(mangledName.compare(0, prefix.size(), prefix) == 0);
mangledName.erase(0, prefix.size());
}
virtual const TString& getMangledName() const override { return mangledName; }
virtual const TType& getType() const override { return returnType; }
virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
virtual TType& getWritableType() override { return returnType; }
virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
virtual TOperator getBuiltInOp() const { return op; }
virtual void setDefined() { assert(writable); defined = true; }
virtual bool isDefined() const { return defined; }
virtual void setPrototyped() { assert(writable); prototyped = true; }
virtual bool isPrototyped() const { return prototyped; }
virtual void setImplicitThis() { assert(writable); implicitThis = true; }
virtual bool hasImplicitThis() const { return implicitThis; }
virtual void setIllegalImplicitThis() { assert(writable); illegalImplicitThis = true; }
virtual bool hasIllegalImplicitThis() const { return illegalImplicitThis; }
// Return total number of parameters
virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
// Return number of parameters with default values.
virtual int getDefaultParamCount() const { return defaultParamCount; }
// Return number of fixed parameters (without default values)
virtual int getFixedParamCount() const { return getParamCount() - getDefaultParamCount(); }
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
virtual const TParameter& operator[](int i) const { return parameters[i]; }
#ifndef GLSLANG_WEB
virtual void setSpirvInstruction(const TSpirvInstruction& inst)
{
relateToOperator(EOpSpirvInst);
spirvInst = inst;
}
virtual const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
#endif
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
#endif
protected:
explicit TFunction(const TFunction&);
TFunction& operator=(const TFunction&);
typedef TVector<TParameter> TParamList;
TParamList parameters;
TType returnType;
TBuiltInVariable declaredBuiltIn;
TString mangledName;
TOperator op;
bool defined;
bool prototyped;
bool implicitThis; // True if this function is allowed to see all members of 'this'
bool illegalImplicitThis; // True if this function is not supposed to have access to dynamic members of 'this',
// even if it finds member variables in the symbol table.
// This is important for a static member function that has member variables in scope,
// but is not allowed to use them, or see hidden symbols instead.
int defaultParamCount;
#ifndef GLSLANG_WEB
TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers
#endif
};
//
// Members of anonymous blocks are a kind of TSymbol. They are not hidden in
// the symbol table behind a container; rather they are visible and point to
// their anonymous container. (The anonymous container is found through the
// member, not the other way around.)
//
class TAnonMember : public TSymbol {
public:
TAnonMember(const TString* n, unsigned int m, TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { }
virtual TAnonMember* clone() const override;
virtual ~TAnonMember() { }
virtual const TAnonMember* getAsAnonMember() const override { return this; }
virtual const TVariable& getAnonContainer() const { return anonContainer; }
virtual unsigned int getMemberNumber() const { return memberNumber; }
virtual const TType& getType() const override
{
const TTypeList& types = *anonContainer.getType().getStruct();
return *types[memberNumber].type;
}
virtual TType& getWritableType() override
{
assert(writable);
const TTypeList& types = *anonContainer.getType().getStruct();
return *types[memberNumber].type;
}
virtual void setExtensions(int numExts, const char* const exts[]) override
{
anonContainer.setMemberExtensions(memberNumber, numExts, exts);
}
virtual int getNumExtensions() const override { return anonContainer.getNumMemberExtensions(memberNumber); }
virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
virtual int getAnonId() const { return anonId; }
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
#endif
protected:
explicit TAnonMember(const TAnonMember&);
TAnonMember& operator=(const TAnonMember&);
TVariable& anonContainer;
unsigned int memberNumber;
int anonId;
};
class TSymbolTableLevel {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
~TSymbolTableLevel();
bool insert(const TString& name, TSymbol* symbol) {
return level.insert(tLevelPair(name, symbol)).second;
}
bool insert(TSymbol& symbol, bool separateNameSpaces, const TString& forcedKeyName = TString())
{
//
// returning true means symbol was added to the table with no semantic errors
//
const TString& name = symbol.getName();
if (forcedKeyName.length()) {
return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
}
else if (name == "") {
symbol.getAsVariable()->setAnonId(anonId++);
// An empty name means an anonymous container, exposing its members to the external scope.
// Give it a name and insert its members in the symbol table, pointing to the container.
char buf[20];
snprintf(buf, 20, "%s%d", AnonymousPrefix, symbol.getAsVariable()->getAnonId());
symbol.changeName(NewPoolTString(buf));
return insertAnonymousMembers(symbol, 0);
} else {
// Check for redefinition errors:
// - STL itself will tell us if there is a direct name collision, with name mangling, at this level
// - additionally, check for function-redefining-variable name collisions
const TString& insertName = symbol.getMangledName();
if (symbol.getAsFunction()) {
// make sure there isn't a variable of this name
if (! separateNameSpaces && level.find(name) != level.end())
return false;
// insert, and whatever happens is okay
level.insert(tLevelPair(insertName, &symbol));
return true;
} else
return level.insert(tLevelPair(insertName, &symbol)).second;
}
}
// Add more members to an already inserted aggregate object
bool amend(TSymbol& symbol, int firstNewMember)
{
// See insert() for comments on basic explanation of insert.
// This operates similarly, but more simply.
// Only supporting amend of anonymous blocks so far.
if (IsAnonymous(symbol.getName()))
return insertAnonymousMembers(symbol, firstNewMember);
else
return false;
}
bool insertAnonymousMembers(TSymbol& symbol, int firstMember)
{
const TTypeList& types = *symbol.getAsVariable()->getType().getStruct();
for (unsigned int m = firstMember; m < types.size(); ++m) {
TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, *symbol.getAsVariable(), symbol.getAsVariable()->getAnonId());
if (! level.insert(tLevelPair(member->getMangledName(), member)).second)
return false;
}
return true;
}
void retargetSymbol(const TString& from, const TString& to) {
tLevel::const_iterator fromIt = level.find(from);
tLevel::const_iterator toIt = level.find(to);
if (fromIt == level.end() || toIt == level.end())
return;
delete fromIt->second;
level[from] = toIt->second;
retargetedSymbols.push_back({from, to});
}
TSymbol* find(const TString& name) const
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
return 0;
else
return (*it).second;
}
void findFunctionNameList(const TString& name, TVector<const TFunction*>& list)
{
size_t parenAt = name.find_first_of('(');
TString base(name, 0, parenAt + 1);
tLevel::const_iterator begin = level.lower_bound(base);
base[parenAt] = ')'; // assume ')' is lexically after '('
tLevel::const_iterator end = level.upper_bound(base);
for (tLevel::const_iterator it = begin; it != end; ++it)
list.push_back(it->second->getAsFunction());
}
// See if there is already a function in the table having the given non-function-style name.
bool hasFunctionName(const TString& name) const
{
tLevel::const_iterator candidate = level.lower_bound(name);
if (candidate != level.end()) {
const TString& candidateName = (*candidate).first;
TString::size_type parenAt = candidateName.find_first_of('(');
if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0)
return true;
}
return false;
}
// See if there is a variable at this level having the given non-function-style name.
// Return true if name is found, and set variable to true if the name was a variable.
bool findFunctionVariableName(const TString& name, bool& variable) const
{
tLevel::const_iterator candidate = level.lower_bound(name);
if (candidate != level.end()) {
const TString& candidateName = (*candidate).first;
TString::size_type parenAt = candidateName.find_first_of('(');
if (parenAt == candidateName.npos) {
// not a mangled name
if (candidateName == name) {
// found a variable name match
variable = true;
return true;
}
} else {
// a mangled name
if (candidateName.compare(0, parenAt, name) == 0) {
// found a function name match
variable = false;
return true;
}
}
}
return false;
}
// Use this to do a lazy 'push' of precision defaults the first time
// a precision statement is seen in a new scope. Leave it at 0 for
// when no push was needed. Thus, it is not the current defaults,
// it is what to restore the defaults to when popping a level.
void setPreviousDefaultPrecisions(const TPrecisionQualifier *p)
{
// can call multiple times at one scope, will only latch on first call,
// as we're tracking the previous scope's values, not the current values
if (defaultPrecision != 0)
return;
defaultPrecision = new TPrecisionQualifier[EbtNumTypes];
for (int t = 0; t < EbtNumTypes; ++t)
defaultPrecision[t] = p[t];
}
void getPreviousDefaultPrecisions(TPrecisionQualifier *p)
{
// can be called for table level pops that didn't set the
// defaults
if (defaultPrecision == 0 || p == 0)
return;
for (int t = 0; t < EbtNumTypes; ++t)
p[t] = defaultPrecision[t];
}
void relateToOperator(const char* name, TOperator op);
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
void dump(TInfoSink& infoSink, bool complete = false) const;
#endif
TSymbolTableLevel* clone() const;
void readOnly();
void setThisLevel() { thisLevel = true; }
bool isThisLevel() const { return thisLevel; }
protected:
explicit TSymbolTableLevel(TSymbolTableLevel&);
TSymbolTableLevel& operator=(TSymbolTableLevel&);
typedef std::map<TString, TSymbol*, std::less<TString>, pool_allocator<std::pair<const TString, TSymbol*> > > tLevel;
typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult;
tLevel level; // named mappings
TPrecisionQualifier *defaultPrecision;
// pair<FromName, ToName>
TVector<std::pair<TString, TString>> retargetedSymbols;
int anonId;
bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
// that are supposed to see anonymous access to member variables.
};
class TSymbolTable {
public:
TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), separateNameSpaces(false), adoptedLevels(0)
{
//
// This symbol table cannot be used until push() is called.
//
}
~TSymbolTable()
{
// this can be called explicitly; safest to code it so it can be called multiple times
// don't deallocate levels passed in from elsewhere
while (table.size() > adoptedLevels)
pop(0);
}
void adoptLevels(TSymbolTable& symTable)
{
for (unsigned int level = 0; level < symTable.table.size(); ++level) {
table.push_back(symTable.table[level]);
++adoptedLevels;
}
uniqueId = symTable.uniqueId;
noBuiltInRedeclarations = symTable.noBuiltInRedeclarations;
separateNameSpaces = symTable.separateNameSpaces;
}
//
// While level adopting is generic, the methods below enact a the following
// convention for levels:
// 0: common built-ins shared across all stages, all compiles, only one copy for all symbol tables
// 1: per-stage built-ins, shared across all compiles, but a different copy per stage
// 2: built-ins specific to a compile, like resources that are context-dependent, or redeclared built-ins
// 3: user-shader globals
//
protected:
static const uint32_t LevelFlagBitOffset = 56;
static const int globalLevel = 3;
static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
static bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals
public:
bool isEmpty() { return table.size() == 0; }
bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
bool atGlobalLevel() { return isGlobalLevel(currentLevel()); }
static bool isBuiltInSymbol(long long uniqueId) {
int level = static_cast<int>(uniqueId >> LevelFlagBitOffset);
return isBuiltInLevel(level);
}
static constexpr uint64_t uniqueIdMask = (1LL << LevelFlagBitOffset) - 1;
static const uint32_t MaxLevelInUniqueID = 127;
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
void setSeparateNameSpaces() { separateNameSpaces = true; }
void push()
{
table.push_back(new TSymbolTableLevel);
updateUniqueIdLevelFlag();
}
// Make a new symbol-table level to represent the scope introduced by a structure
// containing member functions, such that the member functions can find anonymous
// references to member variables.
//
// 'thisSymbol' should have a name of "" to trigger anonymous structure-member
// symbol finds.
void pushThis(TSymbol& thisSymbol)
{
assert(thisSymbol.getName().size() == 0);
table.push_back(new TSymbolTableLevel);
updateUniqueIdLevelFlag();
table.back()->setThisLevel();
insert(thisSymbol);
}
void pop(TPrecisionQualifier *p)
{
table[currentLevel()]->getPreviousDefaultPrecisions(p);
delete table.back();
table.pop_back();
updateUniqueIdLevelFlag();
}
//
// Insert a visible symbol into the symbol table so it can
// be found later by name.
//
// Returns false if the was a name collision.
//
bool insert(TSymbol& symbol)
{
symbol.setUniqueId(++uniqueId);
// make sure there isn't a function of this variable name
if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName()))
return false;
// check for not overloading or redefining a built-in function
if (noBuiltInRedeclarations) {
if (atGlobalLevel() && currentLevel() > 0) {
if (table[0]->hasFunctionName(symbol.getName()))
return false;
if (currentLevel() > 1 && table[1]->hasFunctionName(symbol.getName()))
return false;
}
}
return table[currentLevel()]->insert(symbol, separateNameSpaces);
}
// Add more members to an already inserted aggregate object
bool amend(TSymbol& symbol, int firstNewMember)
{
// See insert() for comments on basic explanation of insert.
// This operates similarly, but more simply.
return table[currentLevel()]->amend(symbol, firstNewMember);
}
// Update the level info in symbol's unique ID to current level
void amendSymbolIdLevel(TSymbol& symbol)
{
// clamp level to avoid overflow
uint64_t level = (uint32_t)currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
uint64_t symbolId = symbol.getUniqueId();
symbolId &= uniqueIdMask;
symbolId |= (level << LevelFlagBitOffset);
symbol.setUniqueId(symbolId);
}
//
// To allocate an internal temporary, which will need to be uniquely
// identified by the consumer of the AST, but never need to
// found by doing a symbol table search by name, hence allowed an
// arbitrary name in the symbol with no worry of collision.
//
void makeInternalVariable(TSymbol& symbol)
{
symbol.setUniqueId(++uniqueId);
}
//
// Copy a variable or anonymous member's structure from a shared level so that
// it can be added (soon after return) to the symbol table where it can be
// modified without impacting other users of the shared table.
//
TSymbol* copyUpDeferredInsert(TSymbol* shared)
{
if (shared->getAsVariable()) {
TSymbol* copy = shared->clone();
copy->setUniqueId(shared->getUniqueId());
return copy;
} else {
const TAnonMember* anon = shared->getAsAnonMember();
assert(anon);
TVariable* container = anon->getAnonContainer().clone();
container->changeName(NewPoolTString(""));
container->setUniqueId(anon->getAnonContainer().getUniqueId());
return container;
}
}
TSymbol* copyUp(TSymbol* shared)
{
TSymbol* copy = copyUpDeferredInsert(shared);
table[globalLevel]->insert(*copy, separateNameSpaces);
if (shared->getAsVariable())
return copy;
else {
// return the copy of the anonymous member
return table[globalLevel]->find(shared->getName());
}
}
// Normal find of a symbol, that can optionally say whether the symbol was found
// at a built-in level or the current top-scope level.
TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0)
{
int level = currentLevel();
TSymbol* symbol;
int thisDepth = 0;
do {
if (table[level]->isThisLevel())
++thisDepth;
symbol = table[level]->find(name);
--level;
} while (symbol == nullptr && level >= 0);
level++;
if (builtIn)
*builtIn = isBuiltInLevel(level);
if (currentScope)
*currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals
if (thisDepthP != nullptr) {
if (! table[level]->isThisLevel())
thisDepth = 0;
*thisDepthP = thisDepth;
}
return symbol;
}
void retargetSymbol(const TString& from, const TString& to) {
int level = currentLevel();
table[level]->retargetSymbol(from, to);
}
// Find of a symbol that returns how many layers deep of nested
// structures-with-member-functions ('this' scopes) deep the symbol was
// found in.
TSymbol* find(const TString& name, int& thisDepth)
{
int level = currentLevel();
TSymbol* symbol;
thisDepth = 0;
do {
if (table[level]->isThisLevel())
++thisDepth;
symbol = table[level]->find(name);
--level;
} while (symbol == 0 && level >= 0);
if (! table[level + 1]->isThisLevel())
thisDepth = 0;
return symbol;
}
bool isFunctionNameVariable(const TString& name) const
{
if (separateNameSpaces)
return false;
int level = currentLevel();
do {
bool variable;
bool found = table[level]->findFunctionVariableName(name, variable);
if (found)
return variable;
--level;
} while (level >= 0);
return false;
}
void findFunctionNameList(const TString& name, TVector<const TFunction*>& list, bool& builtIn)
{
// For user levels, return the set found in the first scope with a match
builtIn = false;
int level = currentLevel();
do {
table[level]->findFunctionNameList(name, list);
--level;
} while (list.empty() && level >= globalLevel);
if (! list.empty())
return;
// Gather across all built-in levels; they don't hide each other
builtIn = true;
do {
table[level]->findFunctionNameList(name, list);
--level;
} while (level >= 0);
}
void relateToOperator(const char* name, TOperator op)
{
for (unsigned int level = 0; level < table.size(); ++level)
table[level]->relateToOperator(name, op);
}
void setFunctionExtensions(const char* name, int num, const char* const extensions[])
{
for (unsigned int level = 0; level < table.size(); ++level)
table[level]->setFunctionExtensions(name, num, extensions);
}
void setVariableExtensions(const char* name, int numExts, const char* const extensions[])
{
TSymbol* symbol = find(TString(name));
if (symbol == nullptr)
return;
symbol->setExtensions(numExts, extensions);
}
void setVariableExtensions(const char* blockName, const char* name, int numExts, const char* const extensions[])
{
TSymbol* symbol = find(TString(blockName));
if (symbol == nullptr)
return;
TVariable* variable = symbol->getAsVariable();
assert(variable != nullptr);
const TTypeList& structure = *variable->getAsVariable()->getType().getStruct();
for (int member = 0; member < (int)structure.size(); ++member) {
if (structure[member].type->getFieldName().compare(name) == 0) {
variable->setMemberExtensions(member, numExts, extensions);
return;
}
}
}
long long getMaxSymbolId() { return uniqueId; }
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
void dump(TInfoSink& infoSink, bool complete = false) const;
#endif
void copyTable(const TSymbolTable& copyOf);
void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
void readOnly()
{
for (unsigned int level = 0; level < table.size(); ++level)
table[level]->readOnly();
}
// Add current level in the high-bits of unique id
void updateUniqueIdLevelFlag() {
// clamp level to avoid overflow
uint64_t level = (uint32_t)currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
uniqueId &= uniqueIdMask;
uniqueId |= (level << LevelFlagBitOffset);
}
void overwriteUniqueId(long long id)
{
uniqueId = id;
updateUniqueIdLevelFlag();
}
protected:
TSymbolTable(TSymbolTable&);
TSymbolTable& operator=(TSymbolTableLevel&);
int currentLevel() const { return static_cast<int>(table.size()) - 1; }
std::vector<TSymbolTableLevel*> table;
long long uniqueId; // for unique identification in code generation
bool noBuiltInRedeclarations;
bool separateNameSpaces;
unsigned int adoptedLevels;
};
} // end namespace glslang
#endif // _SYMBOL_TABLE_INCLUDED_

View File

@@ -0,0 +1,348 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2012-2013 LunarG, Inc.
// Copyright (C) 2017 ARM Limited.
// Copyright (C) 2015-2018 Google, Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _VERSIONS_INCLUDED_
#define _VERSIONS_INCLUDED_
#define LAST_ELEMENT_MARKER(x) x
//
// Help manage multiple profiles, versions, extensions etc.
//
//
// Profiles are set up for masking operations, so queries can be done on multiple
// profiles at the same time.
//
// Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible
// defects from mixing the two different forms.
//
typedef enum : unsigned {
EBadProfile = 0,
ENoProfile = (1 << 0), // only for desktop, before profiles showed up
ECoreProfile = (1 << 1),
ECompatibilityProfile = (1 << 2),
EEsProfile = (1 << 3),
LAST_ELEMENT_MARKER(EProfileCount),
} EProfile;
namespace glslang {
//
// Map from profile enum to externally readable text name.
//
inline const char* ProfileName(EProfile profile)
{
switch (profile) {
case ENoProfile: return "none";
case ECoreProfile: return "core";
case ECompatibilityProfile: return "compatibility";
case EEsProfile: return "es";
default: return "unknown profile";
}
}
//
// What source rules, validation rules, target language, etc. are needed or
// desired for SPIR-V?
//
// 0 means a target or rule set is not enabled (ignore rules from that entity).
// Non-0 means to apply semantic rules arising from that version of its rule set.
// The union of all requested rule sets will be applied.
//
struct SpvVersion {
SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0), vulkanRelaxed(false) {}
unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header
int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX"
int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use
int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX"
bool vulkanRelaxed; // relax changes to GLSL for Vulkan, allowing some GL-specific to be compiled to Vulkan SPIR-V target
};
//
// The behaviors from the GLSL "#extension extension_name : behavior"
//
typedef enum {
EBhMissing = 0,
EBhRequire,
EBhEnable,
EBhWarn,
EBhDisable,
EBhDisablePartial // use as initial state of an extension that is only partially implemented
} TExtensionBehavior;
//
// Symbolic names for extensions. Strings may be directly used when calling the
// functions, but better to have the compiler do spelling checks.
//
const char* const E_GL_OES_texture_3D = "GL_OES_texture_3D";
const char* const E_GL_OES_standard_derivatives = "GL_OES_standard_derivatives";
const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth";
const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external";
const char* const E_GL_OES_EGL_image_external_essl3 = "GL_OES_EGL_image_external_essl3";
const char* const E_GL_EXT_YUV_target = "GL_EXT_YUV_target";
const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod";
const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers";
const char* const E_GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle";
const char* const E_GL_3DL_array_objects = "GL_3DL_array_objects";
const char* const E_GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420pack";
const char* const E_GL_ARB_texture_gather = "GL_ARB_texture_gather";
const char* const E_GL_ARB_gpu_shader5 = "GL_ARB_gpu_shader5";
const char* const E_GL_ARB_separate_shader_objects = "GL_ARB_separate_shader_objects";
const char* const E_GL_ARB_compute_shader = "GL_ARB_compute_shader";
const char* const E_GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader";
const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts";
const char* const E_GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array";
const char* const E_GL_ARB_texture_multisample = "GL_ARB_texture_multisample";
const char* const E_GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod";
const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location";
const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location";
const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store";
const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters";
const char* const E_GL_ARB_shader_atomic_counter_ops = "GL_ARB_shader_atomic_counter_ops";
const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters";
const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote";
const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control";
const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples";
const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array";
const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64";
const char* const E_GL_ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64";
const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot";
const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2";
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil_export";
// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage";
const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array";
const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shader_interlock";
const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock";
const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object";
const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading";
const char* const E_GL_ARB_shader_bit_encoding = "GL_ARB_shader_bit_encoding";
const char* const E_GL_ARB_shader_image_size = "GL_ARB_shader_image_size";
const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage_buffer_object";
const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing";
const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod";
const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit";
const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced";
const char* const E_GL_ARB_fragment_coord_conventions = "GL_ARB_fragment_coord_conventions";
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
const char* const E_GL_KHR_shader_subgroup_arithmetic = "GL_KHR_shader_subgroup_arithmetic";
const char* const E_GL_KHR_shader_subgroup_ballot = "GL_KHR_shader_subgroup_ballot";
const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_subgroup_shuffle";
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered";
const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad";
const char* const E_GL_KHR_memory_scope_semantics = "GL_KHR_memory_scope_semantics";
const char* const E_GL_EXT_shader_atomic_int64 = "GL_EXT_shader_atomic_int64";
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
const char* const E_GL_EXT_shader_16bit_storage = "GL_EXT_shader_16bit_storage";
const char* const E_GL_EXT_shader_8bit_storage = "GL_EXT_shader_8bit_storage";
// EXT extensions
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout";
const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density";
const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference";
const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_reference2";
const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2";
const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation";
const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock";
const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_printf";
const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing";
const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query";
const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling";
const char* const E_GL_EXT_ray_cull_mask = "GL_EXT_ray_cull_mask";
const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended";
const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions";
const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate";
const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64";
const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initializer";
const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block";
const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow";
const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics";
// Arrays of extensions for the above viewportEXTs duplications
const char* const post_depth_coverageEXTs[] = { E_GL_ARB_post_depth_coverage, E_GL_EXT_post_depth_coverage };
const int Num_post_depth_coverageEXTs = sizeof(post_depth_coverageEXTs) / sizeof(post_depth_coverageEXTs[0]);
// OVR extensions
const char* const E_GL_OVR_multiview = "GL_OVR_multiview";
const char* const E_GL_OVR_multiview2 = "GL_OVR_multiview2";
const char* const OVR_multiview_EXTs[] = { E_GL_OVR_multiview, E_GL_OVR_multiview2 };
const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multiview_EXTs[0]);
// #line and #include
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot";
const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax";
const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter";
const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader";
const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float";
const char* const E_GL_AMD_texture_gather_bias_lod = "GL_AMD_texture_gather_bias_lod";
const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_shader_int16";
const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod";
const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask";
const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch";
const char* const E_GL_INTEL_shader_integer_functions2 = "GL_INTEL_shader_integer_functions2";
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
const char* const E_GL_NV_viewport_array2 = "GL_NV_viewport_array2";
const char* const E_GL_NV_stereo_view_rendering = "GL_NV_stereo_view_rendering";
const char* const E_GL_NVX_multiview_per_view_attributes = "GL_NVX_multiview_per_view_attributes";
const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_atomic_int64";
const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation";
const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_noperspective_interpolation";
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image";
const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing";
const char* const E_GL_NV_ray_tracing_motion_blur = "GL_NV_ray_tracing_motion_blur";
const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric";
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_shader";
// Arrays of extensions for the above viewportEXTs duplications
const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix";
const char* const E_GL_NV_shader_sm_builtins = "GL_NV_shader_sm_builtins";
const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer_cooperative_matrix";
// AEP
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
const char* const E_GL_KHR_blend_equation_advanced = "GL_KHR_blend_equation_advanced";
const char* const E_GL_OES_sample_variables = "GL_OES_sample_variables";
const char* const E_GL_OES_shader_image_atomic = "GL_OES_shader_image_atomic";
const char* const E_GL_OES_shader_multisample_interpolation = "GL_OES_shader_multisample_interpolation";
const char* const E_GL_OES_texture_storage_multisample_2d_array = "GL_OES_texture_storage_multisample_2d_array";
const char* const E_GL_EXT_geometry_shader = "GL_EXT_geometry_shader";
const char* const E_GL_EXT_geometry_point_size = "GL_EXT_geometry_point_size";
const char* const E_GL_EXT_gpu_shader5 = "GL_EXT_gpu_shader5";
const char* const E_GL_EXT_primitive_bounding_box = "GL_EXT_primitive_bounding_box";
const char* const E_GL_EXT_shader_io_blocks = "GL_EXT_shader_io_blocks";
const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessellation_shader";
const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size";
const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer";
const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array";
const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix";
// OES matching AEP
const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader";
const char* const E_GL_OES_geometry_point_size = "GL_OES_geometry_point_size";
const char* const E_GL_OES_gpu_shader5 = "GL_OES_gpu_shader5";
const char* const E_GL_OES_primitive_bounding_box = "GL_OES_primitive_bounding_box";
const char* const E_GL_OES_shader_io_blocks = "GL_OES_shader_io_blocks";
const char* const E_GL_OES_tessellation_shader = "GL_OES_tessellation_shader";
const char* const E_GL_OES_tessellation_point_size = "GL_OES_tessellation_point_size";
const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer";
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
// EXT
const char* const E_GL_EXT_shader_explicit_arithmetic_types = "GL_EXT_shader_explicit_arithmetic_types";
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int8 = "GL_EXT_shader_explicit_arithmetic_types_int8";
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int16 = "GL_EXT_shader_explicit_arithmetic_types_int16";
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int32 = "GL_EXT_shader_explicit_arithmetic_types_int32";
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int64 = "GL_EXT_shader_explicit_arithmetic_types_int64";
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float16 = "GL_EXT_shader_explicit_arithmetic_types_float16";
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float32 = "GL_EXT_shader_explicit_arithmetic_types_float32";
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float64 = "GL_EXT_shader_explicit_arithmetic_types_float64";
const char* const E_GL_EXT_shader_subgroup_extended_types_int8 = "GL_EXT_shader_subgroup_extended_types_int8";
const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shader_subgroup_extended_types_int16";
const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64";
const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16";
const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation";
const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float";
const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2";
// Arrays of extensions for the above AEP duplications
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
const int Num_AEP_geometry_shader = sizeof(AEP_geometry_shader)/sizeof(AEP_geometry_shader[0]);
const char* const AEP_geometry_point_size[] = { E_GL_EXT_geometry_point_size, E_GL_OES_geometry_point_size };
const int Num_AEP_geometry_point_size = sizeof(AEP_geometry_point_size)/sizeof(AEP_geometry_point_size[0]);
const char* const AEP_gpu_shader5[] = { E_GL_EXT_gpu_shader5, E_GL_OES_gpu_shader5 };
const int Num_AEP_gpu_shader5 = sizeof(AEP_gpu_shader5)/sizeof(AEP_gpu_shader5[0]);
const char* const AEP_primitive_bounding_box[] = { E_GL_EXT_primitive_bounding_box, E_GL_OES_primitive_bounding_box };
const int Num_AEP_primitive_bounding_box = sizeof(AEP_primitive_bounding_box)/sizeof(AEP_primitive_bounding_box[0]);
const char* const AEP_shader_io_blocks[] = { E_GL_EXT_shader_io_blocks, E_GL_OES_shader_io_blocks };
const int Num_AEP_shader_io_blocks = sizeof(AEP_shader_io_blocks)/sizeof(AEP_shader_io_blocks[0]);
const char* const AEP_tessellation_shader[] = { E_GL_EXT_tessellation_shader, E_GL_OES_tessellation_shader };
const int Num_AEP_tessellation_shader = sizeof(AEP_tessellation_shader)/sizeof(AEP_tessellation_shader[0]);
const char* const AEP_tessellation_point_size[] = { E_GL_EXT_tessellation_point_size, E_GL_OES_tessellation_point_size };
const int Num_AEP_tessellation_point_size = sizeof(AEP_tessellation_point_size)/sizeof(AEP_tessellation_point_size[0]);
const char* const AEP_texture_buffer[] = { E_GL_EXT_texture_buffer, E_GL_OES_texture_buffer };
const int Num_AEP_texture_buffer = sizeof(AEP_texture_buffer)/sizeof(AEP_texture_buffer[0]);
const char* const AEP_texture_cube_map_array[] = { E_GL_EXT_texture_cube_map_array, E_GL_OES_texture_cube_map_array };
const int Num_AEP_texture_cube_map_array = sizeof(AEP_texture_cube_map_array)/sizeof(AEP_texture_cube_map_array[0]);
} // end namespace glslang
#endif // _VERSIONS_INCLUDED_

View File

@@ -0,0 +1,150 @@
//
// Copyright (C) 2017 LunarG, Inc.
// Copyright (C) 2018 Google, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _ATTRIBUTE_INCLUDED_
#define _ATTRIBUTE_INCLUDED_
#include "../Include/Common.h"
#include "../Include/ConstantUnion.h"
namespace glslang {
enum TAttributeType {
EatNone,
EatAllow_uav_condition,
EatBranch,
EatCall,
EatDomain,
EatEarlyDepthStencil,
EatFastOpt,
EatFlatten,
EatForceCase,
EatInstance,
EatMaxTessFactor,
EatNumThreads,
EatMaxVertexCount,
EatOutputControlPoints,
EatOutputTopology,
EatPartitioning,
EatPatchConstantFunc,
EatPatchSize,
EatUnroll,
EatLoop,
EatBinding,
EatGlobalBinding,
EatLocation,
EatInputAttachment,
EatBuiltIn,
EatPushConstant,
EatConstantId,
EatDependencyInfinite,
EatDependencyLength,
EatMinIterations,
EatMaxIterations,
EatIterationMultiple,
EatPeelCount,
EatPartialCount,
EatFormatRgba32f,
EatFormatRgba16f,
EatFormatR32f,
EatFormatRgba8,
EatFormatRgba8Snorm,
EatFormatRg32f,
EatFormatRg16f,
EatFormatR11fG11fB10f,
EatFormatR16f,
EatFormatRgba16,
EatFormatRgb10A2,
EatFormatRg16,
EatFormatRg8,
EatFormatR16,
EatFormatR8,
EatFormatRgba16Snorm,
EatFormatRg16Snorm,
EatFormatRg8Snorm,
EatFormatR16Snorm,
EatFormatR8Snorm,
EatFormatRgba32i,
EatFormatRgba16i,
EatFormatRgba8i,
EatFormatR32i,
EatFormatRg32i,
EatFormatRg16i,
EatFormatRg8i,
EatFormatR16i,
EatFormatR8i,
EatFormatRgba32ui,
EatFormatRgba16ui,
EatFormatRgba8ui,
EatFormatR32ui,
EatFormatRgb10a2ui,
EatFormatRg32ui,
EatFormatRg16ui,
EatFormatRg8ui,
EatFormatR16ui,
EatFormatR8ui,
EatFormatUnknown,
EatNonWritable,
EatNonReadable,
EatSubgroupUniformControlFlow,
};
class TIntermAggregate;
struct TAttributeArgs {
TAttributeType name;
const TIntermAggregate* args;
// Obtain attribute as integer
// Return false if it cannot be obtained
bool getInt(int& value, int argNum = 0) const;
// Obtain attribute as string, with optional to-lower transform
// Return false if it cannot be obtained
bool getString(TString& value, int argNum = 0, bool convertToLower = true) const;
// How many arguments were provided to the attribute?
int size() const;
protected:
const TConstUnion* getConstUnion(TBasicType basicType, int argNum) const;
};
typedef TList<TAttributeArgs> TAttributes;
} // end namespace glslang
#endif // _ATTRIBUTE_INCLUDED_

View File

@@ -0,0 +1,218 @@
/*
** Copyright (c) 2013 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#pragma once
#define GL_FLOAT 0x1406
#define GL_FLOAT_VEC2 0x8B50
#define GL_FLOAT_VEC3 0x8B51
#define GL_FLOAT_VEC4 0x8B52
#define GL_DOUBLE 0x140A
#define GL_DOUBLE_VEC2 0x8FFC
#define GL_DOUBLE_VEC3 0x8FFD
#define GL_DOUBLE_VEC4 0x8FFE
#define GL_INT 0x1404
#define GL_INT_VEC2 0x8B53
#define GL_INT_VEC3 0x8B54
#define GL_INT_VEC4 0x8B55
#define GL_UNSIGNED_INT 0x1405
#define GL_UNSIGNED_INT_VEC2 0x8DC6
#define GL_UNSIGNED_INT_VEC3 0x8DC7
#define GL_UNSIGNED_INT_VEC4 0x8DC8
#define GL_INT64_ARB 0x140E
#define GL_INT64_VEC2_ARB 0x8FE9
#define GL_INT64_VEC3_ARB 0x8FEA
#define GL_INT64_VEC4_ARB 0x8FEB
#define GL_UNSIGNED_INT64_ARB 0x140F
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6
#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7
#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
#define GL_INT16_NV 0x8FE4
#define GL_INT16_VEC2_NV 0x8FE5
#define GL_INT16_VEC3_NV 0x8FE6
#define GL_INT16_VEC4_NV 0x8FE7
#define GL_BOOL 0x8B56
#define GL_BOOL_VEC2 0x8B57
#define GL_BOOL_VEC3 0x8B58
#define GL_BOOL_VEC4 0x8B59
#define GL_FLOAT_MAT2 0x8B5A
#define GL_FLOAT_MAT3 0x8B5B
#define GL_FLOAT_MAT4 0x8B5C
#define GL_FLOAT_MAT2x3 0x8B65
#define GL_FLOAT_MAT2x4 0x8B66
#define GL_FLOAT_MAT3x2 0x8B67
#define GL_FLOAT_MAT3x4 0x8B68
#define GL_FLOAT_MAT4x2 0x8B69
#define GL_FLOAT_MAT4x3 0x8B6A
#define GL_DOUBLE_MAT2 0x8F46
#define GL_DOUBLE_MAT3 0x8F47
#define GL_DOUBLE_MAT4 0x8F48
#define GL_DOUBLE_MAT2x3 0x8F49
#define GL_DOUBLE_MAT2x4 0x8F4A
#define GL_DOUBLE_MAT3x2 0x8F4B
#define GL_DOUBLE_MAT3x4 0x8F4C
#define GL_DOUBLE_MAT4x2 0x8F4D
#define GL_DOUBLE_MAT4x3 0x8F4E
// Those constants are borrowed from extension NV_gpu_shader5
#define GL_FLOAT16_NV 0x8FF8
#define GL_FLOAT16_VEC2_NV 0x8FF9
#define GL_FLOAT16_VEC3_NV 0x8FFA
#define GL_FLOAT16_VEC4_NV 0x8FFB
#define GL_FLOAT16_MAT2_AMD 0x91C5
#define GL_FLOAT16_MAT3_AMD 0x91C6
#define GL_FLOAT16_MAT4_AMD 0x91C7
#define GL_FLOAT16_MAT2x3_AMD 0x91C8
#define GL_FLOAT16_MAT2x4_AMD 0x91C9
#define GL_FLOAT16_MAT3x2_AMD 0x91CA
#define GL_FLOAT16_MAT3x4_AMD 0x91CB
#define GL_FLOAT16_MAT4x2_AMD 0x91CC
#define GL_FLOAT16_MAT4x3_AMD 0x91CD
#define GL_SAMPLER_1D 0x8B5D
#define GL_SAMPLER_2D 0x8B5E
#define GL_SAMPLER_3D 0x8B5F
#define GL_SAMPLER_CUBE 0x8B60
#define GL_SAMPLER_BUFFER 0x8DC2
#define GL_SAMPLER_1D_ARRAY 0x8DC0
#define GL_SAMPLER_2D_ARRAY 0x8DC1
#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
#define GL_SAMPLER_1D_SHADOW 0x8B61
#define GL_SAMPLER_2D_SHADOW 0x8B62
#define GL_SAMPLER_2D_RECT 0x8B63
#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
#define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE
#define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF
#define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0
#define GL_FLOAT16_SAMPLER_CUBE_AMD 0x91D1
#define GL_FLOAT16_SAMPLER_2D_RECT_AMD 0x91D2
#define GL_FLOAT16_SAMPLER_1D_ARRAY_AMD 0x91D3
#define GL_FLOAT16_SAMPLER_2D_ARRAY_AMD 0x91D4
#define GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD 0x91D5
#define GL_FLOAT16_SAMPLER_BUFFER_AMD 0x91D6
#define GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD 0x91D7
#define GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD 0x91D8
#define GL_FLOAT16_SAMPLER_1D_SHADOW_AMD 0x91D9
#define GL_FLOAT16_SAMPLER_2D_SHADOW_AMD 0x91DA
#define GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD 0x91DB
#define GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD 0x91DC
#define GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD 0x91DD
#define GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD 0x91DE
#define GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD 0x91DF
#define GL_FLOAT16_IMAGE_1D_AMD 0x91E0
#define GL_FLOAT16_IMAGE_2D_AMD 0x91E1
#define GL_FLOAT16_IMAGE_3D_AMD 0x91E2
#define GL_FLOAT16_IMAGE_2D_RECT_AMD 0x91E3
#define GL_FLOAT16_IMAGE_CUBE_AMD 0x91E4
#define GL_FLOAT16_IMAGE_1D_ARRAY_AMD 0x91E5
#define GL_FLOAT16_IMAGE_2D_ARRAY_AMD 0x91E6
#define GL_FLOAT16_IMAGE_CUBE_MAP_ARRAY_AMD 0x91E7
#define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA
#define GL_INT_SAMPLER_1D 0x8DC9
#define GL_INT_SAMPLER_2D 0x8DCA
#define GL_INT_SAMPLER_3D 0x8DCB
#define GL_INT_SAMPLER_CUBE 0x8DCC
#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
#define GL_INT_SAMPLER_2D_RECT 0x8DCD
#define GL_INT_SAMPLER_BUFFER 0x8DD0
#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
#define GL_IMAGE_1D 0x904C
#define GL_IMAGE_2D 0x904D
#define GL_IMAGE_3D 0x904E
#define GL_IMAGE_2D_RECT 0x904F
#define GL_IMAGE_CUBE 0x9050
#define GL_IMAGE_BUFFER 0x9051
#define GL_IMAGE_1D_ARRAY 0x9052
#define GL_IMAGE_2D_ARRAY 0x9053
#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
#define GL_IMAGE_2D_MULTISAMPLE 0x9055
#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
#define GL_INT_IMAGE_1D 0x9057
#define GL_INT_IMAGE_2D 0x9058
#define GL_INT_IMAGE_3D 0x9059
#define GL_INT_IMAGE_2D_RECT 0x905A
#define GL_INT_IMAGE_CUBE 0x905B
#define GL_INT_IMAGE_BUFFER 0x905C
#define GL_INT_IMAGE_1D_ARRAY 0x905D
#define GL_INT_IMAGE_2D_ARRAY 0x905E
#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB

View File

@@ -0,0 +1,568 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 1
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Token kinds. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
YYEMPTY = -2,
YYEOF = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
CONST = 258, /* CONST */
BOOL = 259, /* BOOL */
INT = 260, /* INT */
UINT = 261, /* UINT */
FLOAT = 262, /* FLOAT */
BVEC2 = 263, /* BVEC2 */
BVEC3 = 264, /* BVEC3 */
BVEC4 = 265, /* BVEC4 */
IVEC2 = 266, /* IVEC2 */
IVEC3 = 267, /* IVEC3 */
IVEC4 = 268, /* IVEC4 */
UVEC2 = 269, /* UVEC2 */
UVEC3 = 270, /* UVEC3 */
UVEC4 = 271, /* UVEC4 */
VEC2 = 272, /* VEC2 */
VEC3 = 273, /* VEC3 */
VEC4 = 274, /* VEC4 */
MAT2 = 275, /* MAT2 */
MAT3 = 276, /* MAT3 */
MAT4 = 277, /* MAT4 */
MAT2X2 = 278, /* MAT2X2 */
MAT2X3 = 279, /* MAT2X3 */
MAT2X4 = 280, /* MAT2X4 */
MAT3X2 = 281, /* MAT3X2 */
MAT3X3 = 282, /* MAT3X3 */
MAT3X4 = 283, /* MAT3X4 */
MAT4X2 = 284, /* MAT4X2 */
MAT4X3 = 285, /* MAT4X3 */
MAT4X4 = 286, /* MAT4X4 */
SAMPLER2D = 287, /* SAMPLER2D */
SAMPLER3D = 288, /* SAMPLER3D */
SAMPLERCUBE = 289, /* SAMPLERCUBE */
SAMPLER2DSHADOW = 290, /* SAMPLER2DSHADOW */
SAMPLERCUBESHADOW = 291, /* SAMPLERCUBESHADOW */
SAMPLER2DARRAY = 292, /* SAMPLER2DARRAY */
SAMPLER2DARRAYSHADOW = 293, /* SAMPLER2DARRAYSHADOW */
ISAMPLER2D = 294, /* ISAMPLER2D */
ISAMPLER3D = 295, /* ISAMPLER3D */
ISAMPLERCUBE = 296, /* ISAMPLERCUBE */
ISAMPLER2DARRAY = 297, /* ISAMPLER2DARRAY */
USAMPLER2D = 298, /* USAMPLER2D */
USAMPLER3D = 299, /* USAMPLER3D */
USAMPLERCUBE = 300, /* USAMPLERCUBE */
USAMPLER2DARRAY = 301, /* USAMPLER2DARRAY */
SAMPLER = 302, /* SAMPLER */
SAMPLERSHADOW = 303, /* SAMPLERSHADOW */
TEXTURE2D = 304, /* TEXTURE2D */
TEXTURE3D = 305, /* TEXTURE3D */
TEXTURECUBE = 306, /* TEXTURECUBE */
TEXTURE2DARRAY = 307, /* TEXTURE2DARRAY */
ITEXTURE2D = 308, /* ITEXTURE2D */
ITEXTURE3D = 309, /* ITEXTURE3D */
ITEXTURECUBE = 310, /* ITEXTURECUBE */
ITEXTURE2DARRAY = 311, /* ITEXTURE2DARRAY */
UTEXTURE2D = 312, /* UTEXTURE2D */
UTEXTURE3D = 313, /* UTEXTURE3D */
UTEXTURECUBE = 314, /* UTEXTURECUBE */
UTEXTURE2DARRAY = 315, /* UTEXTURE2DARRAY */
ATTRIBUTE = 316, /* ATTRIBUTE */
VARYING = 317, /* VARYING */
FLOAT16_T = 318, /* FLOAT16_T */
FLOAT32_T = 319, /* FLOAT32_T */
DOUBLE = 320, /* DOUBLE */
FLOAT64_T = 321, /* FLOAT64_T */
INT64_T = 322, /* INT64_T */
UINT64_T = 323, /* UINT64_T */
INT32_T = 324, /* INT32_T */
UINT32_T = 325, /* UINT32_T */
INT16_T = 326, /* INT16_T */
UINT16_T = 327, /* UINT16_T */
INT8_T = 328, /* INT8_T */
UINT8_T = 329, /* UINT8_T */
I64VEC2 = 330, /* I64VEC2 */
I64VEC3 = 331, /* I64VEC3 */
I64VEC4 = 332, /* I64VEC4 */
U64VEC2 = 333, /* U64VEC2 */
U64VEC3 = 334, /* U64VEC3 */
U64VEC4 = 335, /* U64VEC4 */
I32VEC2 = 336, /* I32VEC2 */
I32VEC3 = 337, /* I32VEC3 */
I32VEC4 = 338, /* I32VEC4 */
U32VEC2 = 339, /* U32VEC2 */
U32VEC3 = 340, /* U32VEC3 */
U32VEC4 = 341, /* U32VEC4 */
I16VEC2 = 342, /* I16VEC2 */
I16VEC3 = 343, /* I16VEC3 */
I16VEC4 = 344, /* I16VEC4 */
U16VEC2 = 345, /* U16VEC2 */
U16VEC3 = 346, /* U16VEC3 */
U16VEC4 = 347, /* U16VEC4 */
I8VEC2 = 348, /* I8VEC2 */
I8VEC3 = 349, /* I8VEC3 */
I8VEC4 = 350, /* I8VEC4 */
U8VEC2 = 351, /* U8VEC2 */
U8VEC3 = 352, /* U8VEC3 */
U8VEC4 = 353, /* U8VEC4 */
DVEC2 = 354, /* DVEC2 */
DVEC3 = 355, /* DVEC3 */
DVEC4 = 356, /* DVEC4 */
DMAT2 = 357, /* DMAT2 */
DMAT3 = 358, /* DMAT3 */
DMAT4 = 359, /* DMAT4 */
F16VEC2 = 360, /* F16VEC2 */
F16VEC3 = 361, /* F16VEC3 */
F16VEC4 = 362, /* F16VEC4 */
F16MAT2 = 363, /* F16MAT2 */
F16MAT3 = 364, /* F16MAT3 */
F16MAT4 = 365, /* F16MAT4 */
F32VEC2 = 366, /* F32VEC2 */
F32VEC3 = 367, /* F32VEC3 */
F32VEC4 = 368, /* F32VEC4 */
F32MAT2 = 369, /* F32MAT2 */
F32MAT3 = 370, /* F32MAT3 */
F32MAT4 = 371, /* F32MAT4 */
F64VEC2 = 372, /* F64VEC2 */
F64VEC3 = 373, /* F64VEC3 */
F64VEC4 = 374, /* F64VEC4 */
F64MAT2 = 375, /* F64MAT2 */
F64MAT3 = 376, /* F64MAT3 */
F64MAT4 = 377, /* F64MAT4 */
DMAT2X2 = 378, /* DMAT2X2 */
DMAT2X3 = 379, /* DMAT2X3 */
DMAT2X4 = 380, /* DMAT2X4 */
DMAT3X2 = 381, /* DMAT3X2 */
DMAT3X3 = 382, /* DMAT3X3 */
DMAT3X4 = 383, /* DMAT3X4 */
DMAT4X2 = 384, /* DMAT4X2 */
DMAT4X3 = 385, /* DMAT4X3 */
DMAT4X4 = 386, /* DMAT4X4 */
F16MAT2X2 = 387, /* F16MAT2X2 */
F16MAT2X3 = 388, /* F16MAT2X3 */
F16MAT2X4 = 389, /* F16MAT2X4 */
F16MAT3X2 = 390, /* F16MAT3X2 */
F16MAT3X3 = 391, /* F16MAT3X3 */
F16MAT3X4 = 392, /* F16MAT3X4 */
F16MAT4X2 = 393, /* F16MAT4X2 */
F16MAT4X3 = 394, /* F16MAT4X3 */
F16MAT4X4 = 395, /* F16MAT4X4 */
F32MAT2X2 = 396, /* F32MAT2X2 */
F32MAT2X3 = 397, /* F32MAT2X3 */
F32MAT2X4 = 398, /* F32MAT2X4 */
F32MAT3X2 = 399, /* F32MAT3X2 */
F32MAT3X3 = 400, /* F32MAT3X3 */
F32MAT3X4 = 401, /* F32MAT3X4 */
F32MAT4X2 = 402, /* F32MAT4X2 */
F32MAT4X3 = 403, /* F32MAT4X3 */
F32MAT4X4 = 404, /* F32MAT4X4 */
F64MAT2X2 = 405, /* F64MAT2X2 */
F64MAT2X3 = 406, /* F64MAT2X3 */
F64MAT2X4 = 407, /* F64MAT2X4 */
F64MAT3X2 = 408, /* F64MAT3X2 */
F64MAT3X3 = 409, /* F64MAT3X3 */
F64MAT3X4 = 410, /* F64MAT3X4 */
F64MAT4X2 = 411, /* F64MAT4X2 */
F64MAT4X3 = 412, /* F64MAT4X3 */
F64MAT4X4 = 413, /* F64MAT4X4 */
ATOMIC_UINT = 414, /* ATOMIC_UINT */
ACCSTRUCTNV = 415, /* ACCSTRUCTNV */
ACCSTRUCTEXT = 416, /* ACCSTRUCTEXT */
RAYQUERYEXT = 417, /* RAYQUERYEXT */
FCOOPMATNV = 418, /* FCOOPMATNV */
ICOOPMATNV = 419, /* ICOOPMATNV */
UCOOPMATNV = 420, /* UCOOPMATNV */
SAMPLERCUBEARRAY = 421, /* SAMPLERCUBEARRAY */
SAMPLERCUBEARRAYSHADOW = 422, /* SAMPLERCUBEARRAYSHADOW */
ISAMPLERCUBEARRAY = 423, /* ISAMPLERCUBEARRAY */
USAMPLERCUBEARRAY = 424, /* USAMPLERCUBEARRAY */
SAMPLER1D = 425, /* SAMPLER1D */
SAMPLER1DARRAY = 426, /* SAMPLER1DARRAY */
SAMPLER1DARRAYSHADOW = 427, /* SAMPLER1DARRAYSHADOW */
ISAMPLER1D = 428, /* ISAMPLER1D */
SAMPLER1DSHADOW = 429, /* SAMPLER1DSHADOW */
SAMPLER2DRECT = 430, /* SAMPLER2DRECT */
SAMPLER2DRECTSHADOW = 431, /* SAMPLER2DRECTSHADOW */
ISAMPLER2DRECT = 432, /* ISAMPLER2DRECT */
USAMPLER2DRECT = 433, /* USAMPLER2DRECT */
SAMPLERBUFFER = 434, /* SAMPLERBUFFER */
ISAMPLERBUFFER = 435, /* ISAMPLERBUFFER */
USAMPLERBUFFER = 436, /* USAMPLERBUFFER */
SAMPLER2DMS = 437, /* SAMPLER2DMS */
ISAMPLER2DMS = 438, /* ISAMPLER2DMS */
USAMPLER2DMS = 439, /* USAMPLER2DMS */
SAMPLER2DMSARRAY = 440, /* SAMPLER2DMSARRAY */
ISAMPLER2DMSARRAY = 441, /* ISAMPLER2DMSARRAY */
USAMPLER2DMSARRAY = 442, /* USAMPLER2DMSARRAY */
SAMPLEREXTERNALOES = 443, /* SAMPLEREXTERNALOES */
SAMPLEREXTERNAL2DY2YEXT = 444, /* SAMPLEREXTERNAL2DY2YEXT */
ISAMPLER1DARRAY = 445, /* ISAMPLER1DARRAY */
USAMPLER1D = 446, /* USAMPLER1D */
USAMPLER1DARRAY = 447, /* USAMPLER1DARRAY */
F16SAMPLER1D = 448, /* F16SAMPLER1D */
F16SAMPLER2D = 449, /* F16SAMPLER2D */
F16SAMPLER3D = 450, /* F16SAMPLER3D */
F16SAMPLER2DRECT = 451, /* F16SAMPLER2DRECT */
F16SAMPLERCUBE = 452, /* F16SAMPLERCUBE */
F16SAMPLER1DARRAY = 453, /* F16SAMPLER1DARRAY */
F16SAMPLER2DARRAY = 454, /* F16SAMPLER2DARRAY */
F16SAMPLERCUBEARRAY = 455, /* F16SAMPLERCUBEARRAY */
F16SAMPLERBUFFER = 456, /* F16SAMPLERBUFFER */
F16SAMPLER2DMS = 457, /* F16SAMPLER2DMS */
F16SAMPLER2DMSARRAY = 458, /* F16SAMPLER2DMSARRAY */
F16SAMPLER1DSHADOW = 459, /* F16SAMPLER1DSHADOW */
F16SAMPLER2DSHADOW = 460, /* F16SAMPLER2DSHADOW */
F16SAMPLER1DARRAYSHADOW = 461, /* F16SAMPLER1DARRAYSHADOW */
F16SAMPLER2DARRAYSHADOW = 462, /* F16SAMPLER2DARRAYSHADOW */
F16SAMPLER2DRECTSHADOW = 463, /* F16SAMPLER2DRECTSHADOW */
F16SAMPLERCUBESHADOW = 464, /* F16SAMPLERCUBESHADOW */
F16SAMPLERCUBEARRAYSHADOW = 465, /* F16SAMPLERCUBEARRAYSHADOW */
IMAGE1D = 466, /* IMAGE1D */
IIMAGE1D = 467, /* IIMAGE1D */
UIMAGE1D = 468, /* UIMAGE1D */
IMAGE2D = 469, /* IMAGE2D */
IIMAGE2D = 470, /* IIMAGE2D */
UIMAGE2D = 471, /* UIMAGE2D */
IMAGE3D = 472, /* IMAGE3D */
IIMAGE3D = 473, /* IIMAGE3D */
UIMAGE3D = 474, /* UIMAGE3D */
IMAGE2DRECT = 475, /* IMAGE2DRECT */
IIMAGE2DRECT = 476, /* IIMAGE2DRECT */
UIMAGE2DRECT = 477, /* UIMAGE2DRECT */
IMAGECUBE = 478, /* IMAGECUBE */
IIMAGECUBE = 479, /* IIMAGECUBE */
UIMAGECUBE = 480, /* UIMAGECUBE */
IMAGEBUFFER = 481, /* IMAGEBUFFER */
IIMAGEBUFFER = 482, /* IIMAGEBUFFER */
UIMAGEBUFFER = 483, /* UIMAGEBUFFER */
IMAGE1DARRAY = 484, /* IMAGE1DARRAY */
IIMAGE1DARRAY = 485, /* IIMAGE1DARRAY */
UIMAGE1DARRAY = 486, /* UIMAGE1DARRAY */
IMAGE2DARRAY = 487, /* IMAGE2DARRAY */
IIMAGE2DARRAY = 488, /* IIMAGE2DARRAY */
UIMAGE2DARRAY = 489, /* UIMAGE2DARRAY */
IMAGECUBEARRAY = 490, /* IMAGECUBEARRAY */
IIMAGECUBEARRAY = 491, /* IIMAGECUBEARRAY */
UIMAGECUBEARRAY = 492, /* UIMAGECUBEARRAY */
IMAGE2DMS = 493, /* IMAGE2DMS */
IIMAGE2DMS = 494, /* IIMAGE2DMS */
UIMAGE2DMS = 495, /* UIMAGE2DMS */
IMAGE2DMSARRAY = 496, /* IMAGE2DMSARRAY */
IIMAGE2DMSARRAY = 497, /* IIMAGE2DMSARRAY */
UIMAGE2DMSARRAY = 498, /* UIMAGE2DMSARRAY */
F16IMAGE1D = 499, /* F16IMAGE1D */
F16IMAGE2D = 500, /* F16IMAGE2D */
F16IMAGE3D = 501, /* F16IMAGE3D */
F16IMAGE2DRECT = 502, /* F16IMAGE2DRECT */
F16IMAGECUBE = 503, /* F16IMAGECUBE */
F16IMAGE1DARRAY = 504, /* F16IMAGE1DARRAY */
F16IMAGE2DARRAY = 505, /* F16IMAGE2DARRAY */
F16IMAGECUBEARRAY = 506, /* F16IMAGECUBEARRAY */
F16IMAGEBUFFER = 507, /* F16IMAGEBUFFER */
F16IMAGE2DMS = 508, /* F16IMAGE2DMS */
F16IMAGE2DMSARRAY = 509, /* F16IMAGE2DMSARRAY */
I64IMAGE1D = 510, /* I64IMAGE1D */
U64IMAGE1D = 511, /* U64IMAGE1D */
I64IMAGE2D = 512, /* I64IMAGE2D */
U64IMAGE2D = 513, /* U64IMAGE2D */
I64IMAGE3D = 514, /* I64IMAGE3D */
U64IMAGE3D = 515, /* U64IMAGE3D */
I64IMAGE2DRECT = 516, /* I64IMAGE2DRECT */
U64IMAGE2DRECT = 517, /* U64IMAGE2DRECT */
I64IMAGECUBE = 518, /* I64IMAGECUBE */
U64IMAGECUBE = 519, /* U64IMAGECUBE */
I64IMAGEBUFFER = 520, /* I64IMAGEBUFFER */
U64IMAGEBUFFER = 521, /* U64IMAGEBUFFER */
I64IMAGE1DARRAY = 522, /* I64IMAGE1DARRAY */
U64IMAGE1DARRAY = 523, /* U64IMAGE1DARRAY */
I64IMAGE2DARRAY = 524, /* I64IMAGE2DARRAY */
U64IMAGE2DARRAY = 525, /* U64IMAGE2DARRAY */
I64IMAGECUBEARRAY = 526, /* I64IMAGECUBEARRAY */
U64IMAGECUBEARRAY = 527, /* U64IMAGECUBEARRAY */
I64IMAGE2DMS = 528, /* I64IMAGE2DMS */
U64IMAGE2DMS = 529, /* U64IMAGE2DMS */
I64IMAGE2DMSARRAY = 530, /* I64IMAGE2DMSARRAY */
U64IMAGE2DMSARRAY = 531, /* U64IMAGE2DMSARRAY */
TEXTURECUBEARRAY = 532, /* TEXTURECUBEARRAY */
ITEXTURECUBEARRAY = 533, /* ITEXTURECUBEARRAY */
UTEXTURECUBEARRAY = 534, /* UTEXTURECUBEARRAY */
TEXTURE1D = 535, /* TEXTURE1D */
ITEXTURE1D = 536, /* ITEXTURE1D */
UTEXTURE1D = 537, /* UTEXTURE1D */
TEXTURE1DARRAY = 538, /* TEXTURE1DARRAY */
ITEXTURE1DARRAY = 539, /* ITEXTURE1DARRAY */
UTEXTURE1DARRAY = 540, /* UTEXTURE1DARRAY */
TEXTURE2DRECT = 541, /* TEXTURE2DRECT */
ITEXTURE2DRECT = 542, /* ITEXTURE2DRECT */
UTEXTURE2DRECT = 543, /* UTEXTURE2DRECT */
TEXTUREBUFFER = 544, /* TEXTUREBUFFER */
ITEXTUREBUFFER = 545, /* ITEXTUREBUFFER */
UTEXTUREBUFFER = 546, /* UTEXTUREBUFFER */
TEXTURE2DMS = 547, /* TEXTURE2DMS */
ITEXTURE2DMS = 548, /* ITEXTURE2DMS */
UTEXTURE2DMS = 549, /* UTEXTURE2DMS */
TEXTURE2DMSARRAY = 550, /* TEXTURE2DMSARRAY */
ITEXTURE2DMSARRAY = 551, /* ITEXTURE2DMSARRAY */
UTEXTURE2DMSARRAY = 552, /* UTEXTURE2DMSARRAY */
F16TEXTURE1D = 553, /* F16TEXTURE1D */
F16TEXTURE2D = 554, /* F16TEXTURE2D */
F16TEXTURE3D = 555, /* F16TEXTURE3D */
F16TEXTURE2DRECT = 556, /* F16TEXTURE2DRECT */
F16TEXTURECUBE = 557, /* F16TEXTURECUBE */
F16TEXTURE1DARRAY = 558, /* F16TEXTURE1DARRAY */
F16TEXTURE2DARRAY = 559, /* F16TEXTURE2DARRAY */
F16TEXTURECUBEARRAY = 560, /* F16TEXTURECUBEARRAY */
F16TEXTUREBUFFER = 561, /* F16TEXTUREBUFFER */
F16TEXTURE2DMS = 562, /* F16TEXTURE2DMS */
F16TEXTURE2DMSARRAY = 563, /* F16TEXTURE2DMSARRAY */
SUBPASSINPUT = 564, /* SUBPASSINPUT */
SUBPASSINPUTMS = 565, /* SUBPASSINPUTMS */
ISUBPASSINPUT = 566, /* ISUBPASSINPUT */
ISUBPASSINPUTMS = 567, /* ISUBPASSINPUTMS */
USUBPASSINPUT = 568, /* USUBPASSINPUT */
USUBPASSINPUTMS = 569, /* USUBPASSINPUTMS */
F16SUBPASSINPUT = 570, /* F16SUBPASSINPUT */
F16SUBPASSINPUTMS = 571, /* F16SUBPASSINPUTMS */
SPIRV_INSTRUCTION = 572, /* SPIRV_INSTRUCTION */
SPIRV_EXECUTION_MODE = 573, /* SPIRV_EXECUTION_MODE */
SPIRV_EXECUTION_MODE_ID = 574, /* SPIRV_EXECUTION_MODE_ID */
SPIRV_DECORATE = 575, /* SPIRV_DECORATE */
SPIRV_DECORATE_ID = 576, /* SPIRV_DECORATE_ID */
SPIRV_DECORATE_STRING = 577, /* SPIRV_DECORATE_STRING */
SPIRV_TYPE = 578, /* SPIRV_TYPE */
SPIRV_STORAGE_CLASS = 579, /* SPIRV_STORAGE_CLASS */
SPIRV_BY_REFERENCE = 580, /* SPIRV_BY_REFERENCE */
SPIRV_LITERAL = 581, /* SPIRV_LITERAL */
LEFT_OP = 582, /* LEFT_OP */
RIGHT_OP = 583, /* RIGHT_OP */
INC_OP = 584, /* INC_OP */
DEC_OP = 585, /* DEC_OP */
LE_OP = 586, /* LE_OP */
GE_OP = 587, /* GE_OP */
EQ_OP = 588, /* EQ_OP */
NE_OP = 589, /* NE_OP */
AND_OP = 590, /* AND_OP */
OR_OP = 591, /* OR_OP */
XOR_OP = 592, /* XOR_OP */
MUL_ASSIGN = 593, /* MUL_ASSIGN */
DIV_ASSIGN = 594, /* DIV_ASSIGN */
ADD_ASSIGN = 595, /* ADD_ASSIGN */
MOD_ASSIGN = 596, /* MOD_ASSIGN */
LEFT_ASSIGN = 597, /* LEFT_ASSIGN */
RIGHT_ASSIGN = 598, /* RIGHT_ASSIGN */
AND_ASSIGN = 599, /* AND_ASSIGN */
XOR_ASSIGN = 600, /* XOR_ASSIGN */
OR_ASSIGN = 601, /* OR_ASSIGN */
SUB_ASSIGN = 602, /* SUB_ASSIGN */
STRING_LITERAL = 603, /* STRING_LITERAL */
LEFT_PAREN = 604, /* LEFT_PAREN */
RIGHT_PAREN = 605, /* RIGHT_PAREN */
LEFT_BRACKET = 606, /* LEFT_BRACKET */
RIGHT_BRACKET = 607, /* RIGHT_BRACKET */
LEFT_BRACE = 608, /* LEFT_BRACE */
RIGHT_BRACE = 609, /* RIGHT_BRACE */
DOT = 610, /* DOT */
COMMA = 611, /* COMMA */
COLON = 612, /* COLON */
EQUAL = 613, /* EQUAL */
SEMICOLON = 614, /* SEMICOLON */
BANG = 615, /* BANG */
DASH = 616, /* DASH */
TILDE = 617, /* TILDE */
PLUS = 618, /* PLUS */
STAR = 619, /* STAR */
SLASH = 620, /* SLASH */
PERCENT = 621, /* PERCENT */
LEFT_ANGLE = 622, /* LEFT_ANGLE */
RIGHT_ANGLE = 623, /* RIGHT_ANGLE */
VERTICAL_BAR = 624, /* VERTICAL_BAR */
CARET = 625, /* CARET */
AMPERSAND = 626, /* AMPERSAND */
QUESTION = 627, /* QUESTION */
INVARIANT = 628, /* INVARIANT */
HIGH_PRECISION = 629, /* HIGH_PRECISION */
MEDIUM_PRECISION = 630, /* MEDIUM_PRECISION */
LOW_PRECISION = 631, /* LOW_PRECISION */
PRECISION = 632, /* PRECISION */
PACKED = 633, /* PACKED */
RESOURCE = 634, /* RESOURCE */
SUPERP = 635, /* SUPERP */
FLOATCONSTANT = 636, /* FLOATCONSTANT */
INTCONSTANT = 637, /* INTCONSTANT */
UINTCONSTANT = 638, /* UINTCONSTANT */
BOOLCONSTANT = 639, /* BOOLCONSTANT */
IDENTIFIER = 640, /* IDENTIFIER */
TYPE_NAME = 641, /* TYPE_NAME */
CENTROID = 642, /* CENTROID */
IN = 643, /* IN */
OUT = 644, /* OUT */
INOUT = 645, /* INOUT */
STRUCT = 646, /* STRUCT */
VOID = 647, /* VOID */
WHILE = 648, /* WHILE */
BREAK = 649, /* BREAK */
CONTINUE = 650, /* CONTINUE */
DO = 651, /* DO */
ELSE = 652, /* ELSE */
FOR = 653, /* FOR */
IF = 654, /* IF */
DISCARD = 655, /* DISCARD */
RETURN = 656, /* RETURN */
SWITCH = 657, /* SWITCH */
CASE = 658, /* CASE */
DEFAULT = 659, /* DEFAULT */
TERMINATE_INVOCATION = 660, /* TERMINATE_INVOCATION */
TERMINATE_RAY = 661, /* TERMINATE_RAY */
IGNORE_INTERSECTION = 662, /* IGNORE_INTERSECTION */
UNIFORM = 663, /* UNIFORM */
SHARED = 664, /* SHARED */
BUFFER = 665, /* BUFFER */
FLAT = 666, /* FLAT */
SMOOTH = 667, /* SMOOTH */
LAYOUT = 668, /* LAYOUT */
DOUBLECONSTANT = 669, /* DOUBLECONSTANT */
INT16CONSTANT = 670, /* INT16CONSTANT */
UINT16CONSTANT = 671, /* UINT16CONSTANT */
FLOAT16CONSTANT = 672, /* FLOAT16CONSTANT */
INT32CONSTANT = 673, /* INT32CONSTANT */
UINT32CONSTANT = 674, /* UINT32CONSTANT */
INT64CONSTANT = 675, /* INT64CONSTANT */
UINT64CONSTANT = 676, /* UINT64CONSTANT */
SUBROUTINE = 677, /* SUBROUTINE */
DEMOTE = 678, /* DEMOTE */
PAYLOADNV = 679, /* PAYLOADNV */
PAYLOADINNV = 680, /* PAYLOADINNV */
HITATTRNV = 681, /* HITATTRNV */
CALLDATANV = 682, /* CALLDATANV */
CALLDATAINNV = 683, /* CALLDATAINNV */
PAYLOADEXT = 684, /* PAYLOADEXT */
PAYLOADINEXT = 685, /* PAYLOADINEXT */
HITATTREXT = 686, /* HITATTREXT */
CALLDATAEXT = 687, /* CALLDATAEXT */
CALLDATAINEXT = 688, /* CALLDATAINEXT */
PATCH = 689, /* PATCH */
SAMPLE = 690, /* SAMPLE */
NONUNIFORM = 691, /* NONUNIFORM */
COHERENT = 692, /* COHERENT */
VOLATILE = 693, /* VOLATILE */
RESTRICT = 694, /* RESTRICT */
READONLY = 695, /* READONLY */
WRITEONLY = 696, /* WRITEONLY */
DEVICECOHERENT = 697, /* DEVICECOHERENT */
QUEUEFAMILYCOHERENT = 698, /* QUEUEFAMILYCOHERENT */
WORKGROUPCOHERENT = 699, /* WORKGROUPCOHERENT */
SUBGROUPCOHERENT = 700, /* SUBGROUPCOHERENT */
NONPRIVATE = 701, /* NONPRIVATE */
SHADERCALLCOHERENT = 702, /* SHADERCALLCOHERENT */
NOPERSPECTIVE = 703, /* NOPERSPECTIVE */
EXPLICITINTERPAMD = 704, /* EXPLICITINTERPAMD */
PERVERTEXNV = 705, /* PERVERTEXNV */
PERPRIMITIVENV = 706, /* PERPRIMITIVENV */
PERVIEWNV = 707, /* PERVIEWNV */
PERTASKNV = 708, /* PERTASKNV */
PRECISE = 709 /* PRECISE */
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 97 "MachineIndependent/glslang.y"
struct {
glslang::TSourceLoc loc;
union {
glslang::TString *string;
int i;
unsigned int u;
long long i64;
unsigned long long u64;
bool b;
double d;
};
glslang::TSymbol* symbol;
} lex;
struct {
glslang::TSourceLoc loc;
glslang::TOperator op;
union {
TIntermNode* intermNode;
glslang::TIntermNodePair nodePair;
glslang::TIntermTyped* intermTypedNode;
glslang::TAttributes* attributes;
glslang::TSpirvRequirement* spirvReq;
glslang::TSpirvInstruction* spirvInst;
glslang::TSpirvTypeParameters* spirvTypeParams;
};
union {
glslang::TPublicType type;
glslang::TFunction* function;
glslang::TParameter param;
glslang::TTypeLoc typeLine;
glslang::TTypeList* typeList;
glslang::TArraySizes* arraySizes;
glslang::TIdentifierList* identifierList;
};
glslang::TArraySizes* typeParameters;
} interm;
#line 557 "MachineIndependent/glslang_tab.cpp.h"
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
int yyparse (glslang::TParseContext* pParseContext);
#endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */

View File

@@ -0,0 +1,361 @@
//
// Copyright (C) 2016 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
#ifndef _IOMAPPER_INCLUDED
#define _IOMAPPER_INCLUDED
#include <cstdint>
#include "LiveTraverser.h"
#include <unordered_map>
#include <unordered_set>
//
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
//
class TInfoSink;
namespace glslang {
class TIntermediate;
struct TVarEntryInfo {
long long id;
TIntermSymbol* symbol;
bool live;
int newBinding;
int newSet;
int newLocation;
int newComponent;
int newIndex;
EShLanguage stage;
void clearNewAssignments() {
newBinding = -1;
newSet = -1;
newLocation = -1;
newComponent = -1;
newIndex = -1;
}
struct TOrderById {
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
};
struct TOrderByPriority {
// ordering:
// 1) has both binding and set
// 2) has binding but no set
// 3) has no binding but set
// 4) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (lPoints == rPoints)
return l.id < r.id;
return lPoints > rPoints;
}
};
struct TOrderByPriorityAndLive {
// ordering:
// 1) do live variables first
// 2) has both binding and set
// 3) has binding but no set
// 4) has no binding but set
// 5) has no binding and no set
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
const TQualifier& lq = l.symbol->getQualifier();
const TQualifier& rq = r.symbol->getQualifier();
// simple rules:
// has binding gives 2 points
// has set gives 1 point
// who has the most points is more important.
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
if (l.live != r.live)
return l.live > r.live;
if (lPoints != rPoints)
return lPoints > rPoints;
return l.id < r.id;
}
};
};
// Base class for shared TIoMapResolver services, used by several derivations.
struct TDefaultIoResolverBase : public glslang::TIoMapResolver {
public:
TDefaultIoResolverBase(const TIntermediate& intermediate);
typedef std::vector<int> TSlotSet;
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
// grow the reflection stage by stage
void notifyBinding(EShLanguage, TVarEntryInfo& /*ent*/) override {}
void notifyInOut(EShLanguage, TVarEntryInfo& /*ent*/) override {}
void beginNotifications(EShLanguage) override {}
void endNotifications(EShLanguage) override {}
void beginResolve(EShLanguage) override {}
void endResolve(EShLanguage) override {}
void beginCollect(EShLanguage) override {}
void endCollect(EShLanguage) override {}
void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
int getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const;
const std::vector<std::string>& getResourceSetBinding(EShLanguage stage) const;
virtual TResourceType getResourceType(const glslang::TType& type) = 0;
bool doAutoBindingMapping() const;
bool doAutoLocationMapping() const;
TSlotSet::iterator findSlot(int set, int slot);
bool checkEmpty(int set, int slot);
bool validateInOut(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }
int reserveSlot(int set, int slot, int size = 1);
int getFreeSlot(int set, int base, int size = 1);
int resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
void addStage(EShLanguage stage, TIntermediate& stageIntermediate) override {
if (stage < EShLangCount) {
stageMask[stage] = true;
stageIntermediates[stage] = &stageIntermediate;
}
}
uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage);
TSlotSetMap slots;
bool hasError = false;
protected:
TDefaultIoResolverBase(TDefaultIoResolverBase&);
TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&);
const TIntermediate& referenceIntermediate;
int nextUniformLocation;
int nextInputLocation;
int nextOutputLocation;
bool stageMask[EShLangCount + 1];
const TIntermediate* stageIntermediates[EShLangCount];
// Return descriptor set specific base if there is one, and the generic base otherwise.
int selectBaseBinding(int base, int descriptorSetBase) const {
return descriptorSetBase != -1 ? descriptorSetBase : base;
}
static int getLayoutSet(const glslang::TType& type) {
if (type.getQualifier().hasSet())
return type.getQualifier().layoutSet;
else
return 0;
}
static bool isSamplerType(const glslang::TType& type) {
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler();
}
static bool isTextureType(const glslang::TType& type) {
return (type.getBasicType() == glslang::EbtSampler &&
(type.getSampler().isTexture() || type.getSampler().isSubpass()));
}
static bool isUboType(const glslang::TType& type) {
return type.getQualifier().storage == EvqUniform;
}
static bool isImageType(const glslang::TType& type) {
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage();
}
static bool isSsboType(const glslang::TType& type) {
return type.getQualifier().storage == EvqBuffer;
}
// Return true if this is a SRV (shader resource view) type:
static bool isSrvType(const glslang::TType& type) {
return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
}
// Return true if this is a UAV (unordered access view) type:
static bool isUavType(const glslang::TType& type) {
if (type.getQualifier().isReadOnly())
return false;
return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) ||
(type.getQualifier().storage == EvqBuffer);
}
};
// Default I/O resolver for OpenGL
struct TDefaultGlslIoResolver : public TDefaultIoResolverBase {
public:
typedef std::map<TString, int> TVarSlotMap; // <resourceName, location/binding>
typedef std::map<int, TVarSlotMap> TSlotMap; // <resourceKey, TVarSlotMap>
TDefaultGlslIoResolver(const TIntermediate& intermediate);
bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }
TResourceType getResourceType(const glslang::TType& type) override;
int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
void beginResolve(EShLanguage /*stage*/) override;
void endResolve(EShLanguage stage) override;
void beginCollect(EShLanguage) override;
void endCollect(EShLanguage) override;
void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
// in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol.
// We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage.
// if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key.
// Note: both stage and type must less then 0xffff.
int buildStorageKey(EShLanguage stage, TStorageQualifier type) {
assert(static_cast<uint32_t>(stage) <= 0x0000ffff && static_cast<uint32_t>(type) <= 0x0000ffff);
return (stage << 16) | type;
}
protected:
// Use for mark pre stage, to get more interface symbol information.
EShLanguage preStage;
// Use for mark current shader stage for resolver
EShLanguage currentStage;
// Slot map for storage resource(location of uniform and interface symbol) It's a program share slot
TSlotMap resourceSlotMap;
// Slot map for other resource(image, ubo, ssbo), It's a program share slot.
TSlotMap storageSlotMap;
};
typedef std::map<TString, TVarEntryInfo> TVarLiveMap;
// override function "operator=", if a vector<const _Kty, _Ty> being sort,
// when use vc++, the sort function will call :
// pair& operator=(const pair<_Other1, _Other2>& _Right)
// {
// first = _Right.first;
// second = _Right.second;
// return (*this);
// }
// that will make a const type handing on left.
// override this function can avoid a compiler error.
// In the future, if the vc++ compiler can handle such a situation,
// this part of the code will be removed.
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
TVarLivePair(const std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
TVarLivePair& operator=(const TVarLivePair& _Right) {
const_cast<TString&>(first) = _Right.first;
second = _Right.second;
return (*this);
}
TVarLivePair(const TVarLivePair& src) : pair(src) { }
};
typedef std::vector<TVarLivePair> TVarLiveVector;
// I/O mapper
class TIoMapper {
public:
TIoMapper() {}
virtual ~TIoMapper() {}
// grow the reflection stage by stage
bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
};
// I/O mapper for GLSL
class TGlslIoMapper : public TIoMapper {
public:
TGlslIoMapper() {
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
profile = ENoProfile;
version = 0;
autoPushConstantMaxSize = 128;
autoPushConstantBlockPacking = ElpStd430;
}
virtual ~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (inVarMaps[stage] != nullptr) {
delete inVarMaps[stage];
inVarMaps[stage] = nullptr;
}
if (outVarMaps[stage] != nullptr) {
delete outVarMaps[stage];
outVarMaps[stage] = nullptr;
}
if (uniformVarMap[stage] != nullptr) {
delete uniformVarMap[stage];
uniformVarMap[stage] = nullptr;
}
if (intermediates[stage] != nullptr)
intermediates[stage] = nullptr;
}
}
// If set, the uniform block with the given name will be changed to be backed by
// push_constant if it's size is <= maxSize
void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
autoPushConstantBlockName = name;
autoPushConstantMaxSize = maxSize;
autoPushConstantBlockPacking = packing;
}
// grow the reflection stage by stage
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
bool doMap(TIoMapResolver*, TInfoSink&) override;
TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount],
*uniformVarMap[EShLangCount];
TIntermediate* intermediates[EShLangCount];
bool hadError = false;
EProfile profile;
int version;
private:
TString autoPushConstantBlockName;
unsigned int autoPushConstantMaxSize;
TLayoutPacking autoPushConstantBlockPacking;
};
} // end namespace glslang
#endif // _IOMAPPER_INCLUDED
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,245 @@
//
// Copyright (C) 2015-2018 Google, Inc.
// Copyright (C) 2017 ARM Limited.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is implemented in Versions.cpp
#ifndef _PARSE_VERSIONS_INCLUDED_
#define _PARSE_VERSIONS_INCLUDED_
#include "../Public/ShaderLang.h"
#include "../Include/InfoSink.h"
#include "Scan.h"
#include <map>
namespace glslang {
//
// Base class for parse helpers.
// This just has version-related information and checking.
// This class should be sufficient for preprocessing.
//
class TParseVersions {
public:
TParseVersions(TIntermediate& interm, int version, EProfile profile,
const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
bool forwardCompatible, EShMessages messages)
:
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
forwardCompatible(forwardCompatible),
profile(profile),
#endif
infoSink(infoSink), version(version),
language(language),
spvVersion(spvVersion),
intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { }
virtual ~TParseVersions() { }
void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc);
void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
#ifdef GLSLANG_WEB
const EProfile profile = EEsProfile;
bool isEsProfile() const { return true; }
void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc)
{
if (! (EEsProfile & profileMask))
error(loc, "not supported with this profile:", featureDesc, ProfileName(profile));
}
void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions,
const char* const extensions[], const char* featureDesc)
{
if ((EEsProfile & profileMask) && (minVersion == 0 || version < minVersion))
error(loc, "not supported for this version or the enabled extensions", featureDesc, "");
}
void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension,
const char* featureDesc)
{
profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc);
}
void initializeExtensionBehavior() { }
void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { }
void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { }
void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
const char* featureDesc) { }
void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
const char* featureDesc) { }
TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; }
bool extensionTurnedOn(const char* const extension) { return false; }
bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; }
void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { }
void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { }
void checkExtensionStage(const TSourceLoc&, const char* const extension) { }
void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior) { }
void fullIntegerCheck(const TSourceLoc&, const char* op) { }
void doubleCheck(const TSourceLoc&, const char* op) { }
bool float16Arithmetic() { return false; }
void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
bool int16Arithmetic() { return false; }
void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
bool int8Arithmetic() { return false; }
void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
bool relaxedErrors() const { return false; }
bool suppressWarnings() const { return true; }
bool isForwardCompatible() const { return false; }
#else
#ifdef GLSLANG_ANGLE
const bool forwardCompatible = true;
const EProfile profile = ECoreProfile;
#else
bool forwardCompatible; // true if errors are to be given for use of deprecated features
EProfile profile; // the declared profile in the shader (core by default)
#endif
bool isEsProfile() const { return profile == EEsProfile; }
void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc);
void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions,
const char* const extensions[], const char* featureDesc);
void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension,
const char* featureDesc);
virtual void initializeExtensionBehavior();
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
const char* featureDesc);
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
const char* featureDesc);
virtual TExtensionBehavior getExtensionBehavior(const char*);
virtual bool extensionTurnedOn(const char* const extension);
virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[],
const char* featureDesc);
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
virtual void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior);
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
virtual void doubleCheck(const TSourceLoc&, const char* op);
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual bool float16Arithmetic();
virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc);
virtual void int16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual bool int16Arithmetic();
virtual void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc);
virtual void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual bool int8Arithmetic();
virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc);
virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void explicitInt8Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void explicitInt32Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void intcoopmatCheck(const TSourceLoc&, const char *op, bool builtIn = false);
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
bool isForwardCompatible() const { return forwardCompatible; }
#endif // GLSLANG_WEB
virtual void spvRemoved(const TSourceLoc&, const char* op);
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
virtual void requireVulkan(const TSourceLoc&, const char* op);
virtual void requireSpv(const TSourceLoc&, const char* op);
virtual void requireSpv(const TSourceLoc&, const char *op, unsigned int version);
#if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL)
void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) { addError(); }
void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) { }
void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) { addError(); }
void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) { }
#else
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) = 0;
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) = 0;
virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) = 0;
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) = 0;
#endif
void addError() { ++numErrors; }
int getNumErrors() const { return numErrors; }
void setScanner(TInputScanner* scanner) { currentScanner = scanner; }
TInputScanner* getScanner() const { return currentScanner; }
const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); }
void setCurrentLine(int line) { currentScanner->setLine(line); }
void setCurrentColumn(int col) { currentScanner->setColumn(col); }
void setCurrentSourceName(const char* name) { currentScanner->setFile(name); }
void setCurrentString(int string) { currentScanner->setString(string); }
void getPreamble(std::string&);
#ifdef ENABLE_HLSL
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; }
#else
bool isReadingHLSL() const { return false; }
#endif
TInfoSink& infoSink;
// compilation mode
int version; // version, updated by #version in the shader
EShLanguage language; // really the stage
SpvVersion spvVersion;
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
protected:
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is
TMap<TString, unsigned int> extensionMinSpv; // for each extension string, store minimum spirv required
EShMessages messages; // errors/warnings/rule-sets
int numErrors; // number of compile-time errors encountered
TInputScanner* currentScanner;
private:
explicit TParseVersions(const TParseVersions&);
TParseVersions& operator=(const TParseVersions&);
};
} // end namespace glslang
#endif // _PARSE_VERSIONS_INCLUDED_

View File

@@ -0,0 +1,703 @@
//
// Copyright (C) 2013 LunarG, Inc.
// Copyright (C) 2015-2018 Google, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
NVIDIA Corporation("NVIDIA") supplies this software to you in
consideration of your agreement to the following terms, and your use,
installation, modification or redistribution of this NVIDIA software
constitutes acceptance of these terms. If you do not agree with these
terms, please do not use, install, modify or redistribute this NVIDIA
software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, NVIDIA grants you a personal, non-exclusive
license, under NVIDIA's copyrights in this original NVIDIA software (the
"NVIDIA Software"), to use, reproduce, modify and redistribute the
NVIDIA Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the NVIDIA Software, you must
retain the copyright notice of NVIDIA, this notice and the following
text and disclaimers in all such redistributions of the NVIDIA Software.
Neither the name, trademarks, service marks nor logos of NVIDIA
Corporation may be used to endorse or promote products derived from the
NVIDIA Software without specific prior written permission from NVIDIA.
Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder.
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
PRODUCTS.
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
#ifndef PPCONTEXT_H
#define PPCONTEXT_H
#include <stack>
#include <unordered_map>
#include <sstream>
#include "../ParseHelper.h"
#include "PpTokens.h"
/* windows only pragma */
#ifdef _MSC_VER
#pragma warning(disable : 4127)
#endif
namespace glslang {
class TPpToken {
public:
TPpToken() { clear(); }
void clear()
{
space = false;
i64val = 0;
loc.init();
name[0] = 0;
}
// Used for comparing macro definitions, so checks what is relevant for that.
bool operator==(const TPpToken& right) const
{
return space == right.space &&
ival == right.ival && dval == right.dval && i64val == right.i64val &&
strncmp(name, right.name, MaxTokenLength) == 0;
}
bool operator!=(const TPpToken& right) const { return ! operator==(right); }
TSourceLoc loc;
// True if a space (for white space or a removed comment) should also be
// recognized, in front of the token returned:
bool space;
// Numeric value of the token:
union {
int ival;
double dval;
long long i64val;
};
// Text string of the token:
char name[MaxTokenLength + 1];
};
class TStringAtomMap {
//
// Implementation is in PpAtom.cpp
//
// Maintain a bi-directional mapping between relevant preprocessor strings and
// "atoms" which a unique integers (small, contiguous, not hash-like) per string.
//
public:
TStringAtomMap();
// Map string -> atom.
// Return 0 if no existing string.
int getAtom(const char* s) const
{
auto it = atomMap.find(s);
return it == atomMap.end() ? 0 : it->second;
}
// Map a new or existing string -> atom, inventing a new atom if necessary.
int getAddAtom(const char* s)
{
int atom = getAtom(s);
if (atom == 0) {
atom = nextAtom++;
addAtomFixed(s, atom);
}
return atom;
}
// Map atom -> string.
const char* getString(int atom) const { return stringMap[atom]->c_str(); }
protected:
TStringAtomMap(TStringAtomMap&);
TStringAtomMap& operator=(TStringAtomMap&);
TUnorderedMap<TString, int> atomMap;
TVector<const TString*> stringMap; // these point into the TString in atomMap
int nextAtom;
// Bad source characters can lead to bad atoms, so gracefully handle those by
// pre-filling the table with them (to avoid if tests later).
TString badToken;
// Add bi-directional mappings:
// - string -> atom
// - atom -> string
void addAtomFixed(const char* s, int atom)
{
auto it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
if (stringMap.size() < (size_t)atom + 1)
stringMap.resize(atom + 100, &badToken);
stringMap[atom] = &it->first;
}
};
class TInputScanner;
enum MacroExpandResult {
MacroExpandNotStarted, // macro not expanded, which might not be an error
MacroExpandError, // a clear error occurred while expanding, no expansion
MacroExpandStarted, // macro expansion process has started
MacroExpandUndef // macro is undefined and will be expanded
};
// This class is the result of turning a huge pile of C code communicating through globals
// into a class. This was done to allowing instancing to attain thread safety.
// Don't expect too much in terms of OO design.
class TPpContext {
public:
TPpContext(TParseContextBase&, const std::string& rootFileName, TShader::Includer&);
virtual ~TPpContext();
void setPreamble(const char* preamble, size_t length);
int tokenize(TPpToken& ppToken);
int tokenPaste(int token, TPpToken&);
class tInput {
public:
tInput(TPpContext* p) : done(false), pp(p) { }
virtual ~tInput() { }
virtual int scan(TPpToken*) = 0;
virtual int getch() = 0;
virtual void ungetch() = 0;
virtual bool peekPasting() { return false; } // true when about to see ##
virtual bool peekContinuedPasting(int) { return false; } // true when non-spaced tokens can paste
virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
virtual bool isMacroInput() { return false; }
// Will be called when we start reading tokens from this instance
virtual void notifyActivated() {}
// Will be called when we do not read tokens from this instance anymore
virtual void notifyDeleted() {}
protected:
bool done;
TPpContext* pp;
};
void setInput(TInputScanner& input, bool versionWillBeError);
void pushInput(tInput* in)
{
inputStack.push_back(in);
in->notifyActivated();
}
void popInput()
{
inputStack.back()->notifyDeleted();
delete inputStack.back();
inputStack.pop_back();
}
//
// From PpTokens.cpp
//
// Capture the needed parts of a token stream for macro recording/playback.
class TokenStream {
public:
// Manage a stream of these 'Token', which capture the relevant parts
// of a TPpToken, plus its atom.
class Token {
public:
Token(int atom, const TPpToken& ppToken) :
atom(atom),
space(ppToken.space),
i64val(ppToken.i64val),
name(ppToken.name) { }
int get(TPpToken& ppToken)
{
ppToken.clear();
ppToken.space = space;
ppToken.i64val = i64val;
snprintf(ppToken.name, sizeof(ppToken.name), "%s", name.c_str());
return atom;
}
bool isAtom(int a) const { return atom == a; }
int getAtom() const { return atom; }
bool nonSpaced() const { return !space; }
protected:
Token() {}
int atom;
bool space; // did a space precede the token?
long long i64val;
TString name;
};
TokenStream() : currentPos(0) { }
void putToken(int token, TPpToken* ppToken);
bool peekToken(int atom) { return !atEnd() && stream[currentPos].isAtom(atom); }
bool peekContinuedPasting(int atom)
{
// This is basically necessary because, for example, the PP
// tokenizer only accepts valid numeric-literals plus suffixes, so
// separates numeric-literals plus bad suffix into two tokens, which
// should get both pasted together as one token when token pasting.
//
// The following code is a bit more generalized than the above example.
if (!atEnd() && atom == PpAtomIdentifier && stream[currentPos].nonSpaced()) {
switch(stream[currentPos].getAtom()) {
case PpAtomConstInt:
case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
case PpAtomConstInt16:
case PpAtomConstUint16:
case PpAtomConstFloat:
case PpAtomConstDouble:
case PpAtomConstFloat16:
case PpAtomConstString:
case PpAtomIdentifier:
return true;
default:
break;
}
}
return false;
}
int getToken(TParseContextBase&, TPpToken*);
bool atEnd() { return currentPos >= stream.size(); }
bool peekTokenizedPasting(bool lastTokenPastes);
bool peekUntokenizedPasting();
void reset() { currentPos = 0; }
protected:
TVector<Token> stream;
size_t currentPos;
};
//
// From Pp.cpp
//
struct MacroSymbol {
MacroSymbol() : functionLike(0), busy(0), undef(0) { }
TVector<int> args;
TokenStream body;
unsigned functionLike : 1; // 0 means object-like, 1 means function-like
unsigned busy : 1;
unsigned undef : 1;
};
typedef TMap<int, MacroSymbol> TSymbolMap;
TSymbolMap macroDefs; // map atoms to macro definitions
MacroSymbol* lookupMacroDef(int atom)
{
auto existingMacroIt = macroDefs.find(atom);
return (existingMacroIt == macroDefs.end()) ? nullptr : &(existingMacroIt->second);
}
void addMacroDef(int atom, MacroSymbol& macroDef) { macroDefs[atom] = macroDef; }
protected:
TPpContext(TPpContext&);
TPpContext& operator=(TPpContext&);
TStringAtomMap atomStrings;
char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
int preambleLength;
char** strings; // official strings of shader, starting a string 0 line 1
size_t* lengths;
int numStrings; // how many official strings there are
int currentString; // which string we're currently parsing (-1 for preamble)
// Scanner data:
int previous_token;
TParseContextBase& parseContext;
// Get the next token from *stack* of input sources, popping input sources
// that are out of tokens, down until an input source is found that has a token.
// Return EndOfInput when there are no more tokens to be found by doing this.
int scanToken(TPpToken* ppToken)
{
int token = EndOfInput;
while (! inputStack.empty()) {
token = inputStack.back()->scan(ppToken);
if (token != EndOfInput || inputStack.empty())
break;
popInput();
}
return token;
}
int getChar() { return inputStack.back()->getch(); }
void ungetChar() { inputStack.back()->ungetch(); }
bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
bool peekContinuedPasting(int a)
{
return !inputStack.empty() && inputStack.back()->peekContinuedPasting(a);
}
bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
static const int maxIfNesting = 65;
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth
int elsetracker; // #if-#else and #endif constructs...Counter.
class tMacroInput : public tInput {
public:
tMacroInput(TPpContext* pp) : tInput(pp), prepaste(false), postpaste(false) { }
virtual ~tMacroInput()
{
for (size_t i = 0; i < args.size(); ++i)
delete args[i];
for (size_t i = 0; i < expandedArgs.size(); ++i)
delete expandedArgs[i];
}
virtual int scan(TPpToken*) override;
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
bool peekPasting() override { return prepaste; }
bool peekContinuedPasting(int a) override { return mac->body.peekContinuedPasting(a); }
bool endOfReplacementList() override { return mac->body.atEnd(); }
bool isMacroInput() override { return true; }
MacroSymbol *mac;
TVector<TokenStream*> args;
TVector<TokenStream*> expandedArgs;
protected:
bool prepaste; // true if we are just before ##
bool postpaste; // true if we are right after ##
};
class tMarkerInput : public tInput {
public:
tMarkerInput(TPpContext* pp) : tInput(pp) { }
virtual int scan(TPpToken*) override
{
if (done)
return EndOfInput;
done = true;
return marker;
}
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
static const int marker = -3;
};
class tZeroInput : public tInput {
public:
tZeroInput(TPpContext* pp) : tInput(pp) { }
virtual int scan(TPpToken*) override;
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
};
std::vector<tInput*> inputStack;
bool errorOnVersion;
bool versionSeen;
//
// from Pp.cpp
//
// Used to obtain #include content.
TShader::Includer& includer;
int CPPdefine(TPpToken * ppToken);
int CPPundef(TPpToken * ppToken);
int CPPelse(int matchelse, TPpToken * ppToken);
int extraTokenCheck(int atom, TPpToken* ppToken, int token);
int eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken * ppToken);
int evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken * ppToken);
int CPPif (TPpToken * ppToken);
int CPPifdef(int defined, TPpToken * ppToken);
int CPPinclude(TPpToken * ppToken);
int CPPline(TPpToken * ppToken);
int CPPerror(TPpToken * ppToken);
int CPPpragma(TPpToken * ppToken);
int CPPversion(TPpToken * ppToken);
int CPPextension(TPpToken * ppToken);
int readCPPline(TPpToken * ppToken);
int scanHeaderName(TPpToken* ppToken, char delimit);
TokenStream* PrescanMacroArg(TokenStream&, TPpToken*, bool newLineOkay);
MacroExpandResult MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay);
//
// From PpTokens.cpp
//
void pushTokenStreamInput(TokenStream&, bool pasting = false);
void UngetToken(int token, TPpToken*);
class tTokenInput : public tInput {
public:
tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) :
tInput(pp),
tokens(t),
lastTokenPastes(prepasting) { }
virtual int scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); }
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); }
bool peekContinuedPasting(int a) override { return tokens->peekContinuedPasting(a); }
protected:
TokenStream* tokens;
bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token
};
class tUngotTokenInput : public tInput {
public:
tUngotTokenInput(TPpContext* pp, int t, TPpToken* p) : tInput(pp), token(t), lval(*p) { }
virtual int scan(TPpToken *) override;
virtual int getch() override { assert(0); return EndOfInput; }
virtual void ungetch() override { assert(0); }
protected:
int token;
TPpToken lval;
};
//
// From PpScanner.cpp
//
class tStringInput : public tInput {
public:
tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
virtual int scan(TPpToken*) override;
// Scanner used to get source stream characters.
// - Escaped newlines are handled here, invisibly to the caller.
// - All forms of newline are handled, and turned into just a '\n'.
int getch() override
{
int ch = input->get();
if (ch == '\\') {
// Move past escaped newlines, as many as sequentially exist
do {
if (input->peek() == '\r' || input->peek() == '\n') {
bool allowed = pp->parseContext.lineContinuationCheck(input->getSourceLoc(), pp->inComment);
if (! allowed && pp->inComment)
return '\\';
// escape one newline now
ch = input->get();
int nextch = input->get();
if (ch == '\r' && nextch == '\n')
ch = input->get();
else
ch = nextch;
} else
return '\\';
} while (ch == '\\');
}
// handle any non-escaped newline
if (ch == '\r' || ch == '\n') {
if (ch == '\r' && input->peek() == '\n')
input->get();
return '\n';
}
return ch;
}
// Scanner used to backup the source stream characters. Newlines are
// handled here, invisibly to the caller, meaning have to undo exactly
// what getch() above does (e.g., don't leave things in the middle of a
// sequence of escaped newlines).
void ungetch() override
{
input->unget();
do {
int ch = input->peek();
if (ch == '\r' || ch == '\n') {
if (ch == '\n') {
// correct for two-character newline
input->unget();
if (input->peek() != '\r')
input->get();
}
// now in front of a complete newline, move past an escape character
input->unget();
if (input->peek() == '\\')
input->unget();
else {
input->get();
break;
}
} else
break;
} while (true);
}
protected:
TInputScanner* input;
};
// Holds a reference to included file data, as well as a
// prologue and an epilogue string. This can be scanned using the tInput
// interface and acts as a single source string.
class TokenizableIncludeFile : public tInput {
public:
// Copies prologue and epilogue. The includedFile must remain valid
// until this TokenizableIncludeFile is no longer used.
TokenizableIncludeFile(const TSourceLoc& startLoc,
const std::string& prologue,
TShader::Includer::IncludeResult* includedFile,
const std::string& epilogue,
TPpContext* pp)
: tInput(pp),
prologue_(prologue),
epilogue_(epilogue),
includedFile_(includedFile),
scanner(3, strings, lengths, nullptr, 0, 0, true),
prevScanner(nullptr),
stringInput(pp, scanner)
{
strings[0] = prologue_.data();
strings[1] = includedFile_->headerData;
strings[2] = epilogue_.data();
lengths[0] = prologue_.size();
lengths[1] = includedFile_->headerLength;
lengths[2] = epilogue_.size();
scanner.setLine(startLoc.line);
scanner.setString(startLoc.string);
scanner.setFile(startLoc.getFilenameStr(), 0);
scanner.setFile(startLoc.getFilenameStr(), 1);
scanner.setFile(startLoc.getFilenameStr(), 2);
}
// tInput methods:
int scan(TPpToken* t) override { return stringInput.scan(t); }
int getch() override { return stringInput.getch(); }
void ungetch() override { stringInput.ungetch(); }
void notifyActivated() override
{
prevScanner = pp->parseContext.getScanner();
pp->parseContext.setScanner(&scanner);
pp->push_include(includedFile_);
}
void notifyDeleted() override
{
pp->parseContext.setScanner(prevScanner);
pp->pop_include();
}
private:
TokenizableIncludeFile& operator=(const TokenizableIncludeFile&);
// Stores the prologue for this string.
const std::string prologue_;
// Stores the epilogue for this string.
const std::string epilogue_;
// Points to the IncludeResult that this TokenizableIncludeFile represents.
TShader::Includer::IncludeResult* includedFile_;
// Will point to prologue_, includedFile_->headerData and epilogue_
// This is passed to scanner constructor.
// These do not own the storage and it must remain valid until this
// object has been destroyed.
const char* strings[3];
// Length of str_, passed to scanner constructor.
size_t lengths[3];
// Scans over str_.
TInputScanner scanner;
// The previous effective scanner before the scanner in this instance
// has been activated.
TInputScanner* prevScanner;
// Delegate object implementing the tInput interface.
tStringInput stringInput;
};
int ScanFromString(char* s);
void missingEndifCheck();
int lFloatConst(int len, int ch, TPpToken* ppToken);
int characterLiteral(TPpToken* ppToken);
void push_include(TShader::Includer::IncludeResult* result)
{
currentSourceFile = result->headerName;
includeStack.push(result);
}
void pop_include()
{
TShader::Includer::IncludeResult* include = includeStack.top();
includeStack.pop();
includer.releaseInclude(include);
if (includeStack.empty()) {
currentSourceFile = rootFileName;
} else {
currentSourceFile = includeStack.top()->headerName;
}
}
bool inComment;
std::string rootFileName;
std::stack<TShader::Includer::IncludeResult*> includeStack;
std::string currentSourceFile;
std::istringstream strtodStream;
bool disableEscapeSequences;
};
} // end namespace glslang
#endif // PPCONTEXT_H

View File

@@ -0,0 +1,179 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
NVIDIA Corporation("NVIDIA") supplies this software to you in
consideration of your agreement to the following terms, and your use,
installation, modification or redistribution of this NVIDIA software
constitutes acceptance of these terms. If you do not agree with these
terms, please do not use, install, modify or redistribute this NVIDIA
software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, NVIDIA grants you a personal, non-exclusive
license, under NVIDIA's copyrights in this original NVIDIA software (the
"NVIDIA Software"), to use, reproduce, modify and redistribute the
NVIDIA Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the NVIDIA Software, you must
retain the copyright notice of NVIDIA, this notice and the following
text and disclaimers in all such redistributions of the NVIDIA Software.
Neither the name, trademarks, service marks nor logos of NVIDIA
Corporation may be used to endorse or promote products derived from the
NVIDIA Software without specific prior written permission from NVIDIA.
Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder.
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
PRODUCTS.
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
#ifndef PARSER_H
#define PARSER_H
namespace glslang {
// Multi-character tokens
enum EFixedAtoms {
// single character tokens get their own char value as their token; start here for multi-character tokens
PpAtomMaxSingle = 127,
// replace bad character tokens with this, to avoid accidental aliasing with the below
PpAtomBadToken,
// Operators
PPAtomAddAssign,
PPAtomSubAssign,
PPAtomMulAssign,
PPAtomDivAssign,
PPAtomModAssign,
PpAtomRight,
PpAtomLeft,
PpAtomRightAssign,
PpAtomLeftAssign,
PpAtomAndAssign,
PpAtomOrAssign,
PpAtomXorAssign,
PpAtomAnd,
PpAtomOr,
PpAtomXor,
PpAtomEQ,
PpAtomNE,
PpAtomGE,
PpAtomLE,
PpAtomDecrement,
PpAtomIncrement,
PpAtomColonColon,
PpAtomPaste,
// Constants
PpAtomConstInt,
PpAtomConstUint,
PpAtomConstInt64,
PpAtomConstUint64,
PpAtomConstInt16,
PpAtomConstUint16,
PpAtomConstFloat,
PpAtomConstDouble,
PpAtomConstFloat16,
PpAtomConstString,
// Identifiers
PpAtomIdentifier,
// preprocessor "keywords"
PpAtomDefine,
PpAtomUndef,
PpAtomIf,
PpAtomIfdef,
PpAtomIfndef,
PpAtomElse,
PpAtomElif,
PpAtomEndif,
PpAtomLine,
PpAtomPragma,
PpAtomError,
// #version ...
PpAtomVersion,
PpAtomCore,
PpAtomCompatibility,
PpAtomEs,
// #extension
PpAtomExtension,
// __LINE__, __FILE__, __VERSION__
PpAtomLineMacro,
PpAtomFileMacro,
PpAtomVersionMacro,
// #include
PpAtomInclude,
PpAtomLast,
};
} // end namespace glslang
#endif /* not PARSER_H */

View File

@@ -0,0 +1,55 @@
//
// Copyright (C) 2015-2016 Google, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Visit the nodes in the glslang intermediate tree representation to
// propagate 'noContraction' qualifier.
//
#pragma once
#include "../Include/intermediate.h"
namespace glslang {
// Propagates the 'precise' qualifier for objects (objects marked with
// 'noContraction' qualifier) from the shader source specified 'precise'
// variables to all the involved objects, and add 'noContraction' qualifier for
// the involved arithmetic operations.
// Note that the same qualifier: 'noContraction' is used in both object nodes
// and arithmetic operation nodes, but has different meaning. For object nodes,
// 'noContraction' means the object is 'precise'; and for arithmetic operation
// nodes, it means the operation should not be contracted.
void PropagateNoContraction(const glslang::TIntermediate& intermediate);
};

View File

@@ -0,0 +1,223 @@
//
// Copyright (C) 2013-2016 LunarG, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
#ifndef _REFLECTION_INCLUDED
#define _REFLECTION_INCLUDED
#include "../Public/ShaderLang.h"
#include "../Include/Types.h"
#include <list>
#include <set>
//
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
//
namespace glslang {
class TIntermediate;
class TIntermAggregate;
class TReflectionTraverser;
// The full reflection database
class TReflection {
public:
TReflection(EShReflectionOptions opts, EShLanguage first, EShLanguage last)
: options(opts), firstStage(first), lastStage(last), badReflection(TObjectReflection::badReflection())
{
for (int dim=0; dim<3; ++dim)
localSize[dim] = 0;
}
virtual ~TReflection() {}
// grow the reflection stage by stage
bool addStage(EShLanguage, const TIntermediate&);
// for mapping a uniform index to a uniform object's description
int getNumUniforms() { return (int)indexToUniform.size(); }
const TObjectReflection& getUniform(int i) const
{
if (i >= 0 && i < (int)indexToUniform.size())
return indexToUniform[i];
else
return badReflection;
}
// for mapping a block index to the block's description
int getNumUniformBlocks() const { return (int)indexToUniformBlock.size(); }
const TObjectReflection& getUniformBlock(int i) const
{
if (i >= 0 && i < (int)indexToUniformBlock.size())
return indexToUniformBlock[i];
else
return badReflection;
}
// for mapping an pipeline input index to the input's description
int getNumPipeInputs() { return (int)indexToPipeInput.size(); }
const TObjectReflection& getPipeInput(int i) const
{
if (i >= 0 && i < (int)indexToPipeInput.size())
return indexToPipeInput[i];
else
return badReflection;
}
// for mapping an pipeline output index to the output's description
int getNumPipeOutputs() { return (int)indexToPipeOutput.size(); }
const TObjectReflection& getPipeOutput(int i) const
{
if (i >= 0 && i < (int)indexToPipeOutput.size())
return indexToPipeOutput[i];
else
return badReflection;
}
// for mapping from an atomic counter to the uniform index
int getNumAtomicCounters() const { return (int)atomicCounterUniformIndices.size(); }
const TObjectReflection& getAtomicCounter(int i) const
{
if (i >= 0 && i < (int)atomicCounterUniformIndices.size())
return getUniform(atomicCounterUniformIndices[i]);
else
return badReflection;
}
// for mapping a buffer variable index to a buffer variable object's description
int getNumBufferVariables() { return (int)indexToBufferVariable.size(); }
const TObjectReflection& getBufferVariable(int i) const
{
if (i >= 0 && i < (int)indexToBufferVariable.size())
return indexToBufferVariable[i];
else
return badReflection;
}
// for mapping a storage block index to the storage block's description
int getNumStorageBuffers() const { return (int)indexToBufferBlock.size(); }
const TObjectReflection& getStorageBufferBlock(int i) const
{
if (i >= 0 && i < (int)indexToBufferBlock.size())
return indexToBufferBlock[i];
else
return badReflection;
}
// for mapping any name to its index (block names, uniform names and input/output names)
int getIndex(const char* name) const
{
TNameToIndex::const_iterator it = nameToIndex.find(name);
if (it == nameToIndex.end())
return -1;
else
return it->second;
}
// see getIndex(const char*)
int getIndex(const TString& name) const { return getIndex(name.c_str()); }
// for mapping any name to its index (only pipe input/output names)
int getPipeIOIndex(const char* name, const bool inOrOut) const
{
TNameToIndex::const_iterator it = inOrOut ? pipeInNameToIndex.find(name) : pipeOutNameToIndex.find(name);
if (it == (inOrOut ? pipeInNameToIndex.end() : pipeOutNameToIndex.end()))
return -1;
else
return it->second;
}
// see gePipeIOIndex(const char*, const bool)
int getPipeIOIndex(const TString& name, const bool inOrOut) const { return getPipeIOIndex(name.c_str(), inOrOut); }
// Thread local size
unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
void dump();
protected:
friend class glslang::TReflectionTraverser;
void buildCounterIndices(const TIntermediate&);
void buildUniformStageMask(const TIntermediate& intermediate);
void buildAttributeReflection(EShLanguage, const TIntermediate&);
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
typedef std::map<std::string, int> TNameToIndex;
typedef std::vector<TObjectReflection> TMapIndexToReflection;
typedef std::vector<int> TIndices;
TMapIndexToReflection& GetBlockMapForStorage(TStorageQualifier storage)
{
if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
return indexToBufferBlock;
return indexToUniformBlock;
}
TMapIndexToReflection& GetVariableMapForStorage(TStorageQualifier storage)
{
if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
return indexToBufferVariable;
return indexToUniform;
}
EShReflectionOptions options;
EShLanguage firstStage;
EShLanguage lastStage;
TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
TNameToIndex nameToIndex; // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
TNameToIndex pipeInNameToIndex; // maps pipe in names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers.
TNameToIndex pipeOutNameToIndex; // maps pipe out names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers.
TMapIndexToReflection indexToUniform;
TMapIndexToReflection indexToUniformBlock;
TMapIndexToReflection indexToBufferVariable;
TMapIndexToReflection indexToBufferBlock;
TMapIndexToReflection indexToPipeInput;
TMapIndexToReflection indexToPipeOutput;
TIndices atomicCounterUniformIndices;
unsigned int localSize[3];
};
} // end namespace glslang
#endif // _REFLECTION_INCLUDED
#endif // !GLSLANG_WEB && !GLSLANG_ANGLE