Commit 68d78fd3 by John Kessenich

Updated command-line options, adding -o for saving binaries, -G for OpenGL…

Updated command-line options, adding -o for saving binaries, -G for OpenGL SPIR-V validation, -v etc. Old uses should still work as they did before. Also encapsulated use of these flags during parsing, for the parse context. Added SPIR-V version to -v.
parent b329715c
...@@ -2543,13 +2543,18 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangT ...@@ -2543,13 +2543,18 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangT
namespace glslang { namespace glslang {
void GetSpirvVersion(std::string& version)
{
char buf[10];
snprintf(buf, "0.%d", spv::Version);
version = buf;
}
// Write SPIR-V out to a binary file // Write SPIR-V out to a binary file
void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName) void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName)
{ {
std::ofstream out; std::ofstream out;
std::string fileName(baseName); out.open(baseName, std::ios::binary | std::ios::out);
fileName.append(".spv");
out.open(fileName.c_str(), std::ios::binary | std::ios::out);
for (int i = 0; i < (int)spirv.size(); ++i) { for (int i = 0; i < (int)spirv.size(); ++i) {
unsigned int word = spirv[i]; unsigned int word = spirv[i];
out.write((const char*)&word, 4); out.write((const char*)&word, 4);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
namespace glslang { namespace glslang {
void GetSpirvVersion(std::string&);
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv); void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv);
void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName); void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName);
......
...@@ -50,10 +50,10 @@ namespace glslang { ...@@ -50,10 +50,10 @@ namespace glslang {
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is, TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is,
bool fc, EShMessages m) : bool fc, EShMessages m) :
intermediate(interm), symbolTable(symt), infoSink(is), language(L), intermediate(interm), symbolTable(symt), infoSink(is), language(L),
version(v), profile(p), forwardCompatible(fc), messages(m), version(v), profile(p), forwardCompatible(fc),
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0), contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
postMainReturn(false), postMainReturn(false),
tokensBeforeEOF(false), limits(resources.limits), currentScanner(0), tokensBeforeEOF(false), limits(resources.limits), messages(m), currentScanner(0),
numErrors(0), parsingBuiltins(pb), afterEOF(false), numErrors(0), parsingBuiltins(pb), afterEOF(false),
atomicUintOffsets(0), anyIndexLimits(false) atomicUintOffsets(0), anyIndexLimits(false)
{ {
...@@ -364,7 +364,7 @@ void C_DECL TParseContext::error(TSourceLoc loc, const char* szReason, const cha ...@@ -364,7 +364,7 @@ void C_DECL TParseContext::error(TSourceLoc loc, const char* szReason, const cha
void C_DECL TParseContext::warn(TSourceLoc loc, const char* szReason, const char* szToken, void C_DECL TParseContext::warn(TSourceLoc loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) const char* szExtraInfoFormat, ...)
{ {
if (messages & EShMsgSuppressWarnings) if (suppressWarnings())
return; return;
const int maxSize = GlslangMaxTokenLength + 200; const int maxSize = GlslangMaxTokenLength + 200;
...@@ -1852,7 +1852,7 @@ bool TParseContext::lineContinuationCheck(TSourceLoc loc, bool endOfComment) ...@@ -1852,7 +1852,7 @@ bool TParseContext::lineContinuationCheck(TSourceLoc loc, bool endOfComment)
return lineContinuationAllowed; return lineContinuationAllowed;
} }
if (messages & EShMsgRelaxedErrors) { if (relaxedErrors()) {
if (! lineContinuationAllowed) if (! lineContinuationAllowed)
warn(loc, "not allowed in this version", message, ""); warn(loc, "not allowed in this version", message, "");
return true; return true;
...@@ -2347,7 +2347,7 @@ void TParseContext::precisionQualifierCheck(TSourceLoc loc, TBasicType baseType, ...@@ -2347,7 +2347,7 @@ void TParseContext::precisionQualifierCheck(TSourceLoc loc, TBasicType baseType,
if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) { if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) {
if (qualifier.precision == EpqNone) { if (qualifier.precision == EpqNone) {
if (messages & EShMsgRelaxedErrors) if (relaxedErrors())
warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "substituting 'mediump'"); warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "substituting 'mediump'");
else else
error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), ""); error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "");
...@@ -4265,7 +4265,7 @@ TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TIntermTyped* ini ...@@ -4265,7 +4265,7 @@ TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TIntermTyped* ini
// qualifier any initializer must be a constant expression." // qualifier any initializer must be a constant expression."
if (symbolTable.atGlobalLevel() && initializer->getType().getQualifier().storage != EvqConst) { if (symbolTable.atGlobalLevel() && initializer->getType().getQualifier().storage != EvqConst) {
const char* initFeature = "non-constant global initializer"; const char* initFeature = "non-constant global initializer";
if (messages & EShMsgRelaxedErrors) if (relaxedErrors())
warn(loc, "not allowed in this version", initFeature, ""); warn(loc, "not allowed in this version", initFeature, "");
else else
requireProfile(loc, ~EEsProfile, initFeature); requireProfile(loc, ~EEsProfile, initFeature);
...@@ -5211,7 +5211,7 @@ TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression, ...@@ -5211,7 +5211,7 @@ TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression,
// "it is an error to have no statement between a label and the end of the switch statement." // "it is an error to have no statement between a label and the end of the switch statement."
// The specifications were updated to remove this (being ill-defined what a "statement" was), // The specifications were updated to remove this (being ill-defined what a "statement" was),
// so, this became a warning. However, 3.0 tests still check for the error. // so, this became a warning. However, 3.0 tests still check for the error.
if (profile == EEsProfile && version <= 300 && (messages & EShMsgRelaxedErrors) == 0) if (profile == EEsProfile && version <= 300 && ! relaxedErrors())
error(loc, "last case/default label not followed by statements", "switch", ""); error(loc, "last case/default label not followed by statements", "switch", "");
else else
warn(loc, "last case/default label not followed by statements", "switch", ""); warn(loc, "last case/default label not followed by statements", "switch", "");
......
...@@ -78,6 +78,12 @@ public: ...@@ -78,6 +78,12 @@ public:
const char* szExtraInfoFormat, ...); const char* szExtraInfoFormat, ...);
void C_DECL warn(TSourceLoc, const char* szReason, const char* szToken, void C_DECL warn(TSourceLoc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...); const char* szExtraInfoFormat, ...);
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
bool vulkanRules() const { return (messages & EShMsgVulkanRules) != 0; }
bool spirvRules() const { return (messages & EShMsgSpvRules) != 0; }
void reservedErrorCheck(TSourceLoc, const TString&); void reservedErrorCheck(TSourceLoc, const TString&);
void reservedPpErrorCheck(TSourceLoc, const char* name, const char* op); void reservedPpErrorCheck(TSourceLoc, const char* name, const char* op);
bool lineContinuationCheck(TSourceLoc, bool endOfComment); bool lineContinuationCheck(TSourceLoc, bool endOfComment);
...@@ -258,7 +264,6 @@ public: ...@@ -258,7 +264,6 @@ public:
int version; // version, updated by #version in the shader int version; // version, updated by #version in the shader
EProfile profile; // the declared profile in the shader (core by default) EProfile profile; // the declared profile in the shader (core by default)
bool forwardCompatible; // true if errors are to be given for use of deprecated features bool forwardCompatible; // true if errors are to be given for use of deprecated features
EShMessages messages; // errors/warnings
// Current state of parsing // Current state of parsing
struct TPragma contextPragma; struct TPragma contextPragma;
...@@ -284,6 +289,7 @@ protected: ...@@ -284,6 +289,7 @@ protected:
TParseContext(TParseContext&); TParseContext(TParseContext&);
TParseContext& operator=(TParseContext&); TParseContext& operator=(TParseContext&);
EShMessages messages; // errors/warnings/rule-sets
TScanContext* scanContext; TScanContext* scanContext;
TPpContext* ppContext; TPpContext* ppContext;
TInputScanner* currentScanner; TInputScanner* currentScanner;
......
...@@ -897,7 +897,7 @@ int TScanContext::tokenizeIdentifier() ...@@ -897,7 +897,7 @@ int TScanContext::tokenizeIdentifier()
if (parseContext.profile == EEsProfile) if (parseContext.profile == EEsProfile)
reservedWord(); reservedWord();
else if (parseContext.version < 140 && ! parseContext.symbolTable.atBuiltInLevel() && ! parseContext.extensionsTurnedOn(1, &E_GL_ARB_texture_rectangle)) { else if (parseContext.version < 140 && ! parseContext.symbolTable.atBuiltInLevel() && ! parseContext.extensionsTurnedOn(1, &E_GL_ARB_texture_rectangle)) {
if (parseContext.messages & EShMsgRelaxedErrors) if (parseContext.relaxedErrors())
parseContext.requireExtensions(loc, 1, &E_GL_ARB_texture_rectangle, "texture-rectangle sampler keyword"); parseContext.requireExtensions(loc, 1, &E_GL_ARB_texture_rectangle, "texture-rectangle sampler keyword");
else else
reservedWord(); reservedWord();
......
...@@ -505,7 +505,7 @@ bool ProcessDeferred( ...@@ -505,7 +505,7 @@ bool ProcessDeferred(
bool versionNotFirst = userInput.scanVersion(version, profile, versionNotFirstToken); bool versionNotFirst = userInput.scanVersion(version, profile, versionNotFirstToken);
bool versionNotFound = version == 0; bool versionNotFound = version == 0;
if (forceDefaultVersionAndProfile) { if (forceDefaultVersionAndProfile) {
if (!(messages & EShMsgSuppressWarnings) && !versionNotFound && if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
(version != defaultVersion || profile != defaultProfile)) { (version != defaultVersion || profile != defaultProfile)) {
compiler->infoSink.info << "Warning, (version, profile) forced to be (" compiler->infoSink.info << "Warning, (version, profile) forced to be ("
<< defaultVersion << ", " << ProfileName(defaultProfile) << defaultVersion << ", " << ProfileName(defaultProfile)
......
...@@ -377,7 +377,7 @@ void TParseContext::checkDeprecated(TSourceLoc loc, int profileMask, int depVers ...@@ -377,7 +377,7 @@ void TParseContext::checkDeprecated(TSourceLoc loc, int profileMask, int depVers
if (version >= depVersion) { if (version >= depVersion) {
if (forwardCompatible) if (forwardCompatible)
error(loc, "deprecated, may be removed in future release", featureDesc, ""); error(loc, "deprecated, may be removed in future release", featureDesc, "");
else if (! (messages & EShMsgSuppressWarnings)) else if (! suppressWarnings())
infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " + infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " +
String(depVersion) + "; may be removed in future release").c_str(), loc); String(depVersion) + "; may be removed in future release").c_str(), loc);
} }
...@@ -417,7 +417,7 @@ void TParseContext::requireExtensions(TSourceLoc loc, int numExtensions, const c ...@@ -417,7 +417,7 @@ void TParseContext::requireExtensions(TSourceLoc loc, int numExtensions, const c
bool warned = false; bool warned = false;
for (int i = 0; i < numExtensions; ++i) { for (int i = 0; i < numExtensions; ++i) {
TExtensionBehavior behavior = getExtensionBehavior(extensions[i]); TExtensionBehavior behavior = getExtensionBehavior(extensions[i]);
if (behavior == EBhDisable && (messages & EShMsgRelaxedErrors)) { if (behavior == EBhDisable && relaxedErrors()) {
infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc); infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc);
behavior = EBhWarn; behavior = EBhWarn;
} }
......
...@@ -357,7 +357,7 @@ int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token) ...@@ -357,7 +357,7 @@ int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
else else
label = ""; label = "";
if (parseContext.messages & EShMsgRelaxedErrors) if (parseContext.relaxedErrors())
parseContext.warn(ppToken->loc, message, label, ""); parseContext.warn(ppToken->loc, message, label, "");
else else
parseContext.error(ppToken->loc, message, label, ""); parseContext.error(ppToken->loc, message, label, "");
...@@ -553,7 +553,7 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T ...@@ -553,7 +553,7 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T
if (! shortCircuit && parseContext.profile == EEsProfile) { if (! shortCircuit && parseContext.profile == EEsProfile) {
const char* message = "undefined macro in expression not allowed in es profile"; const char* message = "undefined macro in expression not allowed in es profile";
const char* name = GetAtomString(ppToken->atom); const char* name = GetAtomString(ppToken->atom);
if (parseContext.messages & EShMsgRelaxedErrors) if (parseContext.relaxedErrors())
parseContext.warn(ppToken->loc, message, "preprocessor evaluation", name); parseContext.warn(ppToken->loc, message, "preprocessor evaluation", name);
else else
parseContext.error(ppToken->loc, message, "preprocessor evaluation", name); parseContext.error(ppToken->loc, message, "preprocessor evaluation", name);
......
...@@ -204,7 +204,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) ...@@ -204,7 +204,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
} }
} else if (ch == 'f' || ch == 'F') { } else if (ch == 'f' || ch == 'F') {
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix"); parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
if ((parseContext.messages & EShMsgRelaxedErrors) == 0) if (! parseContext.relaxedErrors())
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix"); parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix");
if (! HasDecimalOrExponent) if (! HasDecimalOrExponent)
parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
......
...@@ -129,6 +129,8 @@ enum EShMessages { ...@@ -129,6 +129,8 @@ enum EShMessages {
EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input
EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification
EShMsgAST = (1 << 2), // print the AST intermediate representation EShMsgAST = (1 << 2), // print the AST intermediate representation
EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation
EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V
}; };
// //
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment