aboutsummaryrefslogtreecommitdiff
path: root/glslang/MachineIndependent
diff options
context:
space:
mode:
Diffstat (limited to 'glslang/MachineIndependent')
-rw-r--r--glslang/MachineIndependent/Constant.cpp33
-rw-r--r--glslang/MachineIndependent/Initialize.cpp77
-rw-r--r--glslang/MachineIndependent/Intermediate.cpp10
-rw-r--r--glslang/MachineIndependent/ParseContextBase.cpp3
-rw-r--r--glslang/MachineIndependent/ParseHelper.cpp163
-rw-r--r--glslang/MachineIndependent/ShaderLang.cpp27
-rw-r--r--glslang/MachineIndependent/SymbolTable.cpp13
-rw-r--r--glslang/MachineIndependent/SymbolTable.h2
-rw-r--r--glslang/MachineIndependent/Versions.cpp3
-rw-r--r--glslang/MachineIndependent/Versions.h1
-rw-r--r--glslang/MachineIndependent/glslang.m46
-rw-r--r--glslang/MachineIndependent/glslang.y6
-rw-r--r--glslang/MachineIndependent/glslang_tab.cpp6
-rw-r--r--glslang/MachineIndependent/intermOut.cpp31
-rw-r--r--glslang/MachineIndependent/iomapper.cpp59
-rw-r--r--glslang/MachineIndependent/iomapper.h9
-rw-r--r--glslang/MachineIndependent/linkValidate.cpp334
-rw-r--r--glslang/MachineIndependent/localintermediate.h34
18 files changed, 521 insertions, 296 deletions
diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp
index 7f5d4c4f..5fc61dbb 100644
--- a/glslang/MachineIndependent/Constant.cpp
+++ b/glslang/MachineIndependent/Constant.cpp
@@ -46,35 +46,6 @@ namespace {
using namespace glslang;
-typedef union {
- double d;
- int i[2];
-} DoubleIntUnion;
-
-// Some helper functions
-
-bool isNan(double x)
-{
- DoubleIntUnion u;
- // tough to find a platform independent library function, do it directly
- u.d = x;
- int bitPatternL = u.i[0];
- int bitPatternH = u.i[1];
- return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
- ((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
-}
-
-bool isInf(double x)
-{
- DoubleIntUnion u;
- // tough to find a platform independent library function, do it directly
- u.d = x;
- int bitPatternL = u.i[0];
- int bitPatternH = u.i[1];
- return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
- (bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
-}
-
const double pi = 3.1415926535897932384626433832795;
} // end anonymous namespace
@@ -663,12 +634,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EOpIsNan:
{
- newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
+ newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
break;
}
case EOpIsInf:
{
- newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
+ newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
break;
}
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 728cd4a6..03fdce9f 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -316,6 +316,7 @@ const CustomFunction CustomFunctions[] = {
{ EOpTextureQuerySize, "textureSize", nullptr },
{ EOpTextureQueryLod, "textureQueryLod", nullptr },
+ { EOpTextureQueryLod, "textureQueryLOD", nullptr }, // extension GL_ARB_texture_query_lod
{ EOpTextureQueryLevels, "textureQueryLevels", nullptr },
{ EOpTextureQuerySamples, "textureSamples", nullptr },
{ EOpTexture, "texture", nullptr },
@@ -4269,7 +4270,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
//
//============================================================================
- if (profile != EEsProfile && version >= 400) {
+ if (profile != EEsProfile && (version >= 400 || version == 150)) {
stageBuiltins[EShLangGeometry].append(
"void EmitStreamVertex(int);"
"void EndStreamPrimitive(int);"
@@ -4553,11 +4554,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
- // GL_ARB_shader_clock
+ // GL_ARB_shader_clock& GL_EXT_shader_realtime_clock
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append(
"uvec2 clock2x32ARB();"
"uint64_t clockARB();"
+ "uvec2 clockRealtime2x32EXT();"
+ "uint64_t clockRealtimeEXT();"
"\n");
}
@@ -6245,38 +6248,44 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
//
// textureQueryLod(), fragment stage only
// Also enabled with extension GL_ARB_texture_query_lod
+ // Extension GL_ARB_texture_query_lod says that textureQueryLOD() also exist at extension.
if (profile != EEsProfile && version >= 150 && sampler.isCombined() && sampler.dim != EsdRect &&
! sampler.isMultiSample() && ! sampler.isBuffer()) {
- for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
- if (f16TexAddr && sampler.type != EbtFloat16)
- continue;
- stageBuiltins[EShLangFragment].append("vec2 textureQueryLod(");
- stageBuiltins[EShLangFragment].append(typeName);
+
+ const TString funcName[2] = {"vec2 textureQueryLod(", "vec2 textureQueryLOD("};
+
+ for (int i = 0; i < 2; ++i){
+ for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
+ if (f16TexAddr && sampler.type != EbtFloat16)
+ continue;
+ stageBuiltins[EShLangFragment].append(funcName[i]);
+ stageBuiltins[EShLangFragment].append(typeName);
+ if (dimMap[sampler.dim] == 1)
+ if (f16TexAddr)
+ stageBuiltins[EShLangFragment].append(", float16_t");
+ else
+ stageBuiltins[EShLangFragment].append(", float");
+ else {
+ if (f16TexAddr)
+ stageBuiltins[EShLangFragment].append(", f16vec");
+ else
+ stageBuiltins[EShLangFragment].append(", vec");
+ stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]);
+ }
+ stageBuiltins[EShLangFragment].append(");\n");
+ }
+
+ stageBuiltins[EShLangCompute].append(funcName[i]);
+ stageBuiltins[EShLangCompute].append(typeName);
if (dimMap[sampler.dim] == 1)
- if (f16TexAddr)
- stageBuiltins[EShLangFragment].append(", float16_t");
- else
- stageBuiltins[EShLangFragment].append(", float");
+ stageBuiltins[EShLangCompute].append(", float");
else {
- if (f16TexAddr)
- stageBuiltins[EShLangFragment].append(", f16vec");
- else
- stageBuiltins[EShLangFragment].append(", vec");
- stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]);
+ stageBuiltins[EShLangCompute].append(", vec");
+ stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]);
}
- stageBuiltins[EShLangFragment].append(");\n");
+ stageBuiltins[EShLangCompute].append(");\n");
}
-
- stageBuiltins[EShLangCompute].append("vec2 textureQueryLod(");
- stageBuiltins[EShLangCompute].append(typeName);
- if (dimMap[sampler.dim] == 1)
- stageBuiltins[EShLangCompute].append(", float");
- else {
- stageBuiltins[EShLangCompute].append(", vec");
- stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]);
- }
- stageBuiltins[EShLangCompute].append(");\n");
}
//
@@ -8061,7 +8070,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
}
if (profile != EEsProfile && version < 400) {
- symbolTable.setFunctionExtensions("textureQueryLod", 1, &E_GL_ARB_texture_query_lod);
+ symbolTable.setFunctionExtensions("textureQueryLOD", 1, &E_GL_ARB_texture_query_lod);
}
if (profile != EEsProfile && version >= 460) {
@@ -8324,6 +8333,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("clockARB", 1, &E_GL_ARB_shader_clock);
symbolTable.setFunctionExtensions("clock2x32ARB", 1, &E_GL_ARB_shader_clock);
+ symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock);
+ symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock);
+
if (profile == EEsProfile && version < 320) {
symbolTable.setVariableExtensions("gl_PrimitiveID", Num_AEP_geometry_shader, AEP_geometry_shader);
symbolTable.setVariableExtensions("gl_Layer", Num_AEP_geometry_shader, AEP_geometry_shader);
@@ -8341,10 +8353,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
}
if (profile != EEsProfile && version < 330 ) {
- symbolTable.setFunctionExtensions("floatBitsToInt", 1, &E_GL_ARB_shader_bit_encoding);
- symbolTable.setFunctionExtensions("floatBitsToUint", 1, &E_GL_ARB_shader_bit_encoding);
- symbolTable.setFunctionExtensions("intBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding);
- symbolTable.setFunctionExtensions("uintBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding);
+ const char* bitsConvertExt[2] = {E_GL_ARB_shader_bit_encoding, E_GL_ARB_gpu_shader5};
+ symbolTable.setFunctionExtensions("floatBitsToInt", 2, bitsConvertExt);
+ symbolTable.setFunctionExtensions("floatBitsToUint", 2, bitsConvertExt);
+ symbolTable.setFunctionExtensions("intBitsToFloat", 2, bitsConvertExt);
+ symbolTable.setFunctionExtensions("uintBitsToFloat", 2, bitsConvertExt);
}
if (profile != EEsProfile && version < 430 ) {
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index 1283f449..14fd053a 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -2766,7 +2766,7 @@ void TIntermBranch::updatePrecision(TPrecisionQualifier parentPrecision)
return;
if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint ||
- exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) {
+ exp->getBasicType() == EbtFloat) {
if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) {
exp->propagatePrecision(parentPrecision);
}
@@ -3284,7 +3284,7 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
void TIntermUnary::updatePrecision()
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
- getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
+ getBasicType() == EbtFloat) {
if (operand->getQualifier().precision > getQualifier().precision)
getQualifier().precision = operand->getQualifier().precision;
}
@@ -3785,7 +3785,7 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
void TIntermAggregate::updatePrecision()
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
- getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
+ getBasicType() == EbtFloat) {
TPrecisionQualifier maxPrecision = EpqNone;
TIntermSequence operands = getSequence();
for (unsigned int i = 0; i < operands.size(); ++i) {
@@ -3807,7 +3807,7 @@ void TIntermAggregate::updatePrecision()
void TIntermBinary::updatePrecision()
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
- getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
+ getBasicType() == EbtFloat) {
if (op == EOpRightShift || op == EOpLeftShift) {
// For shifts get precision from left side only and thus no need to propagate
getQualifier().precision = left->getQualifier().precision;
@@ -3902,7 +3902,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
case EbtDouble: PROMOTE(setDConst, double, Get); break; \
- case EbtInt8: PROMOTE(setI8Const, char, Get); break; \
+ case EbtInt8: PROMOTE(setI8Const, signed char, Get); break; \
case EbtInt16: PROMOTE(setI16Const, short, Get); break; \
case EbtInt: PROMOTE(setIConst, int, Get); break; \
case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \
diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp
index 1da50d62..616580f9 100644
--- a/glslang/MachineIndependent/ParseContextBase.cpp
+++ b/glslang/MachineIndependent/ParseContextBase.cpp
@@ -74,6 +74,9 @@ void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason
{
if (messages & EShMsgOnlyPreprocessor)
return;
+ // If enhanced msg readability, only print one error
+ if (messages & EShMsgEnhanced && numErrors > 0)
+ return;
va_list args;
va_start(args, szExtraInfoFormat);
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 7f2f171b..496a9a13 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -902,8 +902,10 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char*
result = intermediate.addBinaryMath(op, left, right, loc);
}
- if (result == nullptr)
- binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
+ if (result == nullptr) {
+ bool enhanced = intermediate.getEnhancedMsgs();
+ binaryOpError(loc, str, left->getCompleteString(enhanced), right->getCompleteString(enhanced));
+ }
return result;
}
@@ -926,8 +928,10 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char*
if (result)
return result;
- else
- unaryOpError(loc, str, childNode->getCompleteString());
+ else {
+ bool enhanced = intermediate.getEnhancedMsgs();
+ unaryOpError(loc, str, childNode->getCompleteString(enhanced));
+ }
return childNode;
}
@@ -953,8 +957,8 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
requireProfile(loc, ~EEsProfile, feature);
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
} else if (!base->getType().isCoopMat()) {
- error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str());
-
+ bool enhanced = intermediate.getEnhancedMsgs();
+ error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString(enhanced).c_str());
return base;
}
@@ -1005,10 +1009,16 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
intermediate.addIoAccessed(field);
}
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
- } else
- error(loc, "no such field in structure", field.c_str(), "");
+ } else {
+ auto baseSymbol = base;
+ while (baseSymbol->getAsSymbolNode() == nullptr)
+ baseSymbol = baseSymbol->getAsBinaryNode()->getLeft();
+ TString structName;
+ structName.append("\'").append(baseSymbol->getAsSymbolNode()->getName().c_str()).append( "\'");
+ error(loc, "no such field in structure", field.c_str(), structName.c_str());
+ }
} else
- error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str());
+ error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
// Propagate noContraction up the dereference chain
if (base->getQualifier().isNoContraction())
@@ -1314,14 +1324,14 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
//
result = addConstructor(loc, arguments, type);
if (result == nullptr)
- error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
+ error(loc, "cannot construct with these arguments", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str(), "");
}
} else {
//
// Find it in the symbol table.
//
const TFunction* fnCandidate;
- bool builtIn;
+ bool builtIn {false};
fnCandidate = findFunction(loc, *function, builtIn);
if (fnCandidate) {
// This is a declared function that might map to
@@ -1494,7 +1504,7 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo
else
error(arguments->getLoc(), " wrong operand type", "Internal Error",
"built in unary operator function. Type: %s",
- static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str());
+ static_cast<TIntermTyped*>(arguments)->getCompleteString(intermediate.getEnhancedMsgs()).c_str());
} else if (result->getAsOperator())
builtInOpCheck(loc, function, *result->getAsOperator());
@@ -2495,6 +2505,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
case EOpEmitStreamVertex:
case EOpEndStreamPrimitive:
+ if (version == 150)
+ requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the verison is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5");
intermediate.setMultiStream();
break;
@@ -2597,23 +2609,24 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
// Check that if extended types are being used that the correct extensions are enabled.
if (arg0 != nullptr) {
const TType& type = arg0->getType();
+ bool enhanced = intermediate.getEnhancedMsgs();
switch (type.getBasicType()) {
default:
break;
case EbtInt8:
case EbtUint8:
- requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString().c_str());
+ requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString(enhanced).c_str());
break;
case EbtInt16:
case EbtUint16:
- requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString().c_str());
+ requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString(enhanced).c_str());
break;
case EbtInt64:
case EbtUint64:
- requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString().c_str());
+ requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString(enhanced).c_str());
break;
case EbtFloat16:
- requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString().c_str());
+ requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString(enhanced).c_str());
break;
}
}
@@ -2786,7 +2799,10 @@ TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPu
TOperator op = intermediate.mapTypeToConstructorOp(type);
if (op == EOpNull) {
- error(loc, "cannot construct this type", type.getBasicString(), "");
+ if (intermediate.getEnhancedMsgs() && type.getBasicType() == EbtSampler)
+ error(loc, "function not supported in this version; use texture() instead", "texture*D*", "");
+ else
+ error(loc, "cannot construct this type", type.getBasicString(), "");
op = EOpConstructFloat;
TType errorType(EbtFloat);
type.shallowCopy(errorType);
@@ -3196,6 +3212,12 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
break;
}
+ TString constructorString;
+ if (intermediate.getEnhancedMsgs())
+ constructorString.append(type.getCompleteString(true, false, false, true)).append(" constructor");
+ else
+ constructorString.append("constructor");
+
// See if it's a matrix
bool constructingMatrix = false;
switch (op) {
@@ -3253,7 +3275,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
if (function[arg].type->isArray()) {
if (function[arg].type->isUnsizedArray()) {
// Can't construct from an unsized array.
- error(loc, "array argument must be sized", "constructor", "");
+ error(loc, "array argument must be sized", constructorString.c_str(), "");
return true;
}
arrayArg = true;
@@ -3283,13 +3305,13 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
intArgument = true;
if (type.isStruct()) {
if (function[arg].type->contains16BitFloat()) {
- requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
+ requireFloat16Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 16-bit type");
}
if (function[arg].type->contains16BitInt()) {
- requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
+ requireInt16Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 16-bit type");
}
if (function[arg].type->contains8BitInt()) {
- requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type");
+ requireInt8Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 8-bit type");
}
}
}
@@ -3303,9 +3325,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
case EOpConstructF16Vec3:
case EOpConstructF16Vec4:
if (type.isArray())
- requireFloat16Arithmetic(loc, "constructor", "16-bit arrays not supported");
+ requireFloat16Arithmetic(loc, constructorString.c_str(), "16-bit arrays not supported");
if (type.isVector() && function.getParamCount() != 1)
- requireFloat16Arithmetic(loc, "constructor", "16-bit vectors only take vector types");
+ requireFloat16Arithmetic(loc, constructorString.c_str(), "16-bit vectors only take vector types");
break;
case EOpConstructUint16:
case EOpConstructU16Vec2:
@@ -3316,9 +3338,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
case EOpConstructI16Vec3:
case EOpConstructI16Vec4:
if (type.isArray())
- requireInt16Arithmetic(loc, "constructor", "16-bit arrays not supported");
+ requireInt16Arithmetic(loc, constructorString.c_str(), "16-bit arrays not supported");
if (type.isVector() && function.getParamCount() != 1)
- requireInt16Arithmetic(loc, "constructor", "16-bit vectors only take vector types");
+ requireInt16Arithmetic(loc, constructorString.c_str(), "16-bit vectors only take vector types");
break;
case EOpConstructUint8:
case EOpConstructU8Vec2:
@@ -3329,9 +3351,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
case EOpConstructI8Vec3:
case EOpConstructI8Vec4:
if (type.isArray())
- requireInt8Arithmetic(loc, "constructor", "8-bit arrays not supported");
+ requireInt8Arithmetic(loc, constructorString.c_str(), "8-bit arrays not supported");
if (type.isVector() && function.getParamCount() != 1)
- requireInt8Arithmetic(loc, "constructor", "8-bit vectors only take vector types");
+ requireInt8Arithmetic(loc, constructorString.c_str(), "8-bit vectors only take vector types");
break;
default:
break;
@@ -3413,7 +3435,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
if (type.isArray()) {
if (function.getParamCount() == 0) {
- error(loc, "array constructor must have at least one argument", "constructor", "");
+ error(loc, "array constructor must have at least one argument", constructorString.c_str(), "");
return true;
}
@@ -3421,7 +3443,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
// auto adapt the constructor type to the number of arguments
type.changeOuterArraySize(function.getParamCount());
} else if (type.getOuterArraySize() != function.getParamCount()) {
- error(loc, "array constructor needs one argument per array element", "constructor", "");
+ error(loc, "array constructor needs one argument per array element", constructorString.c_str(), "");
return true;
}
@@ -3434,7 +3456,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
// At least the dimensionalities have to match.
if (! function[0].type->isArray() ||
arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) {
- error(loc, "array constructor argument not correct type to construct array element", "constructor", "");
+ error(loc, "array constructor argument not correct type to construct array element", constructorString.c_str(), "");
return true;
}
@@ -3451,7 +3473,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
}
if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
- error(loc, "constructing non-array constituent from array argument", "constructor", "");
+ error(loc, "constructing non-array constituent from array argument", constructorString.c_str(), "");
return true;
}
@@ -3461,51 +3483,51 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
// "If a matrix argument is given to a matrix constructor,
// it is a compile-time error to have any other arguments."
if (function.getParamCount() != 1)
- error(loc, "matrix constructed from matrix can only have one argument", "constructor", "");
+ error(loc, "matrix constructed from matrix can only have one argument", constructorString.c_str(), "");
return false;
}
if (overFull) {
- error(loc, "too many arguments", "constructor", "");
+ error(loc, "too many arguments", constructorString.c_str(), "");
return true;
}
if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
- error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
+ error(loc, "Number of constructor parameters does not match the number of structure fields", constructorString.c_str(), "");
return true;
}
if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
(op == EOpConstructStruct && size < type.computeNumComponents())) {
- error(loc, "not enough data provided for construction", "constructor", "");
+ error(loc, "not enough data provided for construction", constructorString.c_str(), "");
return true;
}
if (type.isCoopMat() && function.getParamCount() != 1) {
- error(loc, "wrong number of arguments", "constructor", "");
+ error(loc, "wrong number of arguments", constructorString.c_str(), "");
return true;
}
if (type.isCoopMat() &&
!(function[0].type->isScalar() || function[0].type->isCoopMat())) {
- error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", "");
+ error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", constructorString.c_str(), "");
return true;
}
TIntermTyped* typed = node->getAsTyped();
if (typed == nullptr) {
- error(loc, "constructor argument does not have a type", "constructor", "");
+ error(loc, "constructor argument does not have a type", constructorString.c_str(), "");
return true;
}
if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
- error(loc, "cannot convert a sampler", "constructor", "");
+ error(loc, "cannot convert a sampler", constructorString.c_str(), "");
return true;
}
if (op != EOpConstructStruct && typed->isAtomic()) {
- error(loc, "cannot convert an atomic_uint", "constructor", "");
+ error(loc, "cannot convert an atomic_uint", constructorString.c_str(), "");
return true;
}
if (typed->getBasicType() == EbtVoid) {
- error(loc, "cannot convert a void", "constructor", "");
+ error(loc, "cannot convert a void", constructorString.c_str(), "");
return true;
}
@@ -4589,7 +4611,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
if (ssoPre150 ||
(identifier == "gl_FragDepth" && ((nonEsRedecls && version >= 420) || esRedecls)) ||
- (identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 150) || esRedecls)) ||
+ (identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 140) || esRedecls)) ||
identifier == "gl_ClipDistance" ||
identifier == "gl_CullDistance" ||
identifier == "gl_ShadingRateEXT" ||
@@ -4658,7 +4680,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
symbolQualifier.storage != qualifier.storage)
error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
} else if (identifier == "gl_FragCoord") {
- if (intermediate.inIoAccessed("gl_FragCoord"))
+ if (!intermediate.getTexCoordRedeclared() && intermediate.inIoAccessed("gl_FragCoord"))
error(loc, "cannot redeclare after use", "gl_FragCoord", "");
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
qualifier.isMemory() || qualifier.isAuxiliary())
@@ -4668,6 +4690,9 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
+
+
+ intermediate.setTexCoordRedeclared();
if (publicType.pixelCenterInteger)
intermediate.setPixelCenterInteger();
if (publicType.originUpperLeft)
@@ -5499,12 +5524,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
}
if (language == EShLangFragment) {
if (id == "origin_upper_left") {
- requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left");
+ requireProfile(loc, ECoreProfile | ECompatibilityProfile | ENoProfile, "origin_upper_left");
+ if (profile == ENoProfile) {
+ profileRequires(loc,ECoreProfile | ECompatibilityProfile, 140, E_GL_ARB_fragment_coord_conventions, "origin_upper_left");
+ }
+
publicType.shaderQualifiers.originUpperLeft = true;
return;
}
if (id == "pixel_center_integer") {
- requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer");
+ requireProfile(loc, ECoreProfile | ECompatibilityProfile | ENoProfile, "pixel_center_integer");
+ if (profile == ENoProfile) {
+ profileRequires(loc,ECoreProfile | ECompatibilityProfile, 140, E_GL_ARB_fragment_coord_conventions, "pixel_center_integer");
+ }
publicType.shaderQualifiers.pixelCenterInteger = true;
return;
}
@@ -6210,11 +6242,13 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
#ifndef GLSLANG_WEB
if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
- int repeated = intermediate.addXfbBufferOffset(type);
- if (repeated >= 0)
- error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
- if (type.isUnsizedArray())
+ if (type.isUnsizedArray()) {
error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer);
+ } else {
+ int repeated = intermediate.addXfbBufferOffset(type);
+ if (repeated >= 0)
+ error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
+ }
// "The offset must be a multiple of the size of the first component of the first
// qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
@@ -6334,8 +6368,12 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
}
- if (qualifier.isPushConstant() && type.getBasicType() != EbtBlock)
- error(loc, "can only be used with a block", "push_constant", "");
+ if (qualifier.isPushConstant()) {
+ if (type.getBasicType() != EbtBlock)
+ error(loc, "can only be used with a block", "push_constant", "");
+ if (type.isArray())
+ error(loc, "Push constants blocks can't be an array", "push_constant", "");
+ }
if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "buffer_reference", "");
@@ -6652,8 +6690,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
: findFunctionExact(loc, call, builtIn));
else if (version < 120)
function = findFunctionExact(loc, call, builtIn);
- else if (version < 400)
- function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
+ else if (version < 400) {
+ bool needfindFunction400 = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) || extensionTurnedOn(E_GL_ARB_gpu_shader5);
+ function = needfindFunction400 ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
+ }
else if (explicitTypesEnabled)
function = findFunctionExplicitTypes(loc, call, builtIn);
else
@@ -7424,14 +7464,14 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
// Uniforms require a compile-time constant initializer
if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) {
error(loc, "uniform initializers must be constant", "=", "'%s'",
- variable->getType().getCompleteString().c_str());
+ variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
variable->getWritableType().getQualifier().makeTemporary();
return nullptr;
}
// Global consts require a constant initializer (specialization constant is okay)
if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
error(loc, "global const initializers must be constant", "=", "'%s'",
- variable->getType().getCompleteString().c_str());
+ variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
variable->getWritableType().getQualifier().makeTemporary();
return nullptr;
}
@@ -7494,7 +7534,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
if (! initNode)
- assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
+ assignError(loc, "=", intermSymbol->getCompleteString(intermediate.getEnhancedMsgs()), initializer->getCompleteString(intermediate.getEnhancedMsgs()));
return initNode;
}
@@ -7565,7 +7605,7 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
}
} else if (type.isMatrix()) {
if (type.getMatrixCols() != (int)initList->getSequence().size()) {
- error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
+ error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str());
return nullptr;
}
TType vectorType(type, 0); // dereferenced type
@@ -7576,20 +7616,20 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
}
} else if (type.isVector()) {
if (type.getVectorSize() != (int)initList->getSequence().size()) {
- error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str());
+ error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str());
return nullptr;
}
TBasicType destType = type.getBasicType();
for (int i = 0; i < type.getVectorSize(); ++i) {
TBasicType initType = initList->getSequence()[i]->getAsTyped()->getBasicType();
if (destType != initType && !intermediate.canImplicitlyPromote(initType, destType)) {
- error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString().c_str());
+ error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str());
return nullptr;
}
}
} else {
- error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str());
+ error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str());
return nullptr;
}
@@ -8097,8 +8137,9 @@ TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType&
{
TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
if (! converted || converted->getType() != type) {
+ bool enhanced = intermediate.getEnhancedMsgs();
error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
- node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str());
+ node->getAsTyped()->getType().getCompleteString(enhanced).c_str(), type.getCompleteString(enhanced).c_str());
return nullptr;
}
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index a2dd71cf..a5ba40e6 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -813,6 +813,7 @@ bool ProcessDeferred(
// set version/profile to defaultVersion/defaultProfile regardless of the #version
// directive in the source code
bool forceDefaultVersionAndProfile,
+ int overrideVersion, // overrides version specified by #verison or default version
bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out
TIntermediate& intermediate, // returned tree, etc.
@@ -900,6 +901,9 @@ bool ProcessDeferred(
version = defaultVersion;
profile = defaultProfile;
}
+ if (source == EShSourceGlsl && overrideVersion != 0) {
+ version = overrideVersion;
+ }
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
versionNotFirst, defaultVersion, source, version, profile, spvVersion);
@@ -1275,6 +1279,7 @@ bool PreprocessDeferred(
int defaultVersion, // use 100 for ES environment, 110 for desktop
EProfile defaultProfile,
bool forceDefaultVersionAndProfile,
+ int overrideVersion, // use 0 if not overriding GLSL version
bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out
TShader::Includer& includer,
@@ -1285,7 +1290,7 @@ bool PreprocessDeferred(
DoPreprocessing parser(outputString);
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
preamble, optLevel, resources, defaultVersion,
- defaultProfile, forceDefaultVersionAndProfile,
+ defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, intermediate, parser,
false, includer, "", environment);
}
@@ -1314,6 +1319,7 @@ bool CompileDeferred(
int defaultVersion, // use 100 for ES environment, 110 for desktop
EProfile defaultProfile,
bool forceDefaultVersionAndProfile,
+ int overrideVersion, // use 0 if not overriding GLSL version
bool forwardCompatible, // give errors for use of deprecated features
EShMessages messages, // warnings/errors/AST; things to print out
TIntermediate& intermediate,// returned tree, etc.
@@ -1324,7 +1330,7 @@ bool CompileDeferred(
DoFullParse parser;
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
preamble, optLevel, resources, defaultVersion,
- defaultProfile, forceDefaultVersionAndProfile,
+ defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, intermediate, parser,
true, includer, sourceEntryPointName, environment);
}
@@ -1498,7 +1504,7 @@ int ShCompile(
TIntermediate intermediate(compiler->getLanguage());
TShader::ForbidIncluder includer;
bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr,
- "", optLevel, resources, defaultVersion, ENoProfile, false,
+ "", optLevel, resources, defaultVersion, ENoProfile, false, 0,
forwardCompatible, messages, intermediate, includer);
//
@@ -1759,7 +1765,7 @@ public:
};
TShader::TShader(EShLanguage s)
- : stage(s), lengths(nullptr), stringNames(nullptr), preamble("")
+ : stage(s), lengths(nullptr), stringNames(nullptr), preamble(""), overrideVersion(0)
{
pool = new TPoolAllocator;
infoSink = new TInfoSink;
@@ -1828,7 +1834,14 @@ void TShader::setUniqueId(unsigned long long id)
intermediate->setUniqueId(id);
}
+void TShader::setOverrideVersion(int version)
+{
+ overrideVersion = version;
+}
+
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
+void TShader::setDxPositionW(bool invert) { intermediate->setDxPositionW(invert); }
+void TShader::setEnhancedMsgs() { intermediate->setEnhancedMsgs(); }
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
#ifndef GLSLANG_WEB
@@ -1908,7 +1921,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
return CompileDeferred(compiler, strings, numStrings, lengths, stringNames,
preamble, EShOptNone, builtInResources, defaultVersion,
- defaultProfile, forceDefaultVersionAndProfile,
+ defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName,
&environment);
}
@@ -1935,7 +1948,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
EShOptNone, builtInResources, defaultVersion,
- defaultProfile, forceDefaultVersionAndProfile,
+ defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
forwardCompatible, message, includer, *intermediate, output_string,
&environment);
}
@@ -2048,6 +2061,8 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
firstIntermediate->getVersion(),
firstIntermediate->getProfile());
intermediate[stage]->setLimits(firstIntermediate->getLimits());
+ if (firstIntermediate->getEnhancedMsgs())
+ intermediate[stage]->setEnhancedMsgs();
// The new TIntermediate must use the same origin as the original TIntermediates.
// Otherwise linking will fail due to different coordinate systems.
diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp
index 5b7e27fa..a3ffa0c4 100644
--- a/glslang/MachineIndependent/SymbolTable.cpp
+++ b/glslang/MachineIndependent/SymbolTable.cpp
@@ -426,12 +426,7 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
symTableLevel->thisLevel = thisLevel;
symTableLevel->retargetedSymbols.clear();
for (auto &s : retargetedSymbols) {
- // Extra constructions to make sure they use the correct allocator pool
- TString newFrom;
- newFrom = s.first;
- TString newTo;
- newTo = s.second;
- symTableLevel->retargetedSymbols.push_back({std::move(newFrom), std::move(newTo)});
+ symTableLevel->retargetedSymbols.push_back({s.first, s.second});
}
std::vector<bool> containerCopied(anonId, false);
tLevel::const_iterator iter;
@@ -462,11 +457,7 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
TSymbol* sym = symTableLevel->find(s.second);
if (!sym)
continue;
-
- // Need to declare and assign so newS is using the correct pool allocator
- TString newS;
- newS = s.first;
- symTableLevel->insert(newS, sym);
+ symTableLevel->insert(s.first, sym);
}
return symTableLevel;
diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h
index 720999a3..31312ecb 100644
--- a/glslang/MachineIndependent/SymbolTable.h
+++ b/glslang/MachineIndependent/SymbolTable.h
@@ -84,7 +84,7 @@ typedef TVector<const char*> TExtensionList;
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
- explicit TSymbol(const TString *n) : name(n), extensions(0), writable(true) { }
+ 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
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 2fc0d9e0..8d96e0e1 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -226,6 +226,8 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable;
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable;
extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable;
+ extensionBehavior[E_GL_ARB_fragment_coord_conventions] = EBhDisable;
+
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
@@ -467,6 +469,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_ARB_texture_query_lod 1\n"
"#define GL_ARB_vertex_attrib_64bit 1\n"
"#define GL_ARB_draw_instanced 1\n"
+ "#define GL_ARB_fragment_coord_conventions 1\n"
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
"#define GL_EXT_shader_image_load_formatted 1\n"
"#define GL_EXT_post_depth_coverage 1\n"
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index 2dbac0b4..96a6e1fc 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -162,6 +162,7 @@ const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_langua
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";
diff --git a/glslang/MachineIndependent/glslang.m4 b/glslang/MachineIndependent/glslang.m4
index d4cc5bc9..624add5a 100644
--- a/glslang/MachineIndependent/glslang.m4
+++ b/glslang/MachineIndependent/glslang.m4
@@ -798,7 +798,7 @@ conditional_expression
parseContext.rValueErrorCheck($5.loc, ":", $6);
$$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc);
if ($$ == 0) {
- parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(), $6->getCompleteString());
+ parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $6->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $6;
}
}
@@ -815,7 +815,7 @@ assignment_expression
parseContext.rValueErrorCheck($2.loc, "assign", $3);
$$ = parseContext.addAssign($2.loc, $2.op, $1, $3);
if ($$ == 0) {
- parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());
+ parseContext.assignError($2.loc, "assign", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $1;
}
}
@@ -877,7 +877,7 @@ expression
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
$$ = parseContext.intermediate.addComma($1, $3, $2.loc);
if ($$ == 0) {
- parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString());
+ parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $3;
}
}
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
index df53eb5b..93c98995 100644
--- a/glslang/MachineIndependent/glslang.y
+++ b/glslang/MachineIndependent/glslang.y
@@ -798,7 +798,7 @@ conditional_expression
parseContext.rValueErrorCheck($5.loc, ":", $6);
$$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc);
if ($$ == 0) {
- parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(), $6->getCompleteString());
+ parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $6->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $6;
}
}
@@ -815,7 +815,7 @@ assignment_expression
parseContext.rValueErrorCheck($2.loc, "assign", $3);
$$ = parseContext.addAssign($2.loc, $2.op, $1, $3);
if ($$ == 0) {
- parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());
+ parseContext.assignError($2.loc, "assign", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $1;
}
}
@@ -877,7 +877,7 @@ expression
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
$$ = parseContext.intermediate.addComma($1, $3, $2.loc);
if ($$ == 0) {
- parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString());
+ parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
$$ = $3;
}
}
diff --git a/glslang/MachineIndependent/glslang_tab.cpp b/glslang/MachineIndependent/glslang_tab.cpp
index 5ba6a6d4..0b216b62 100644
--- a/glslang/MachineIndependent/glslang_tab.cpp
+++ b/glslang/MachineIndependent/glslang_tab.cpp
@@ -5878,7 +5878,7 @@ yyreduce:
parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[0].interm.intermTypedNode));
(yyval.interm.intermTypedNode) = parseContext.intermediate.addSelection((yyvsp[-5].interm.intermTypedNode), (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-4].lex).loc);
if ((yyval.interm.intermTypedNode) == 0) {
- parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString());
+ parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
}
}
@@ -5902,7 +5902,7 @@ yyreduce:
parseContext.rValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[0].interm.intermTypedNode));
(yyval.interm.intermTypedNode) = parseContext.addAssign((yyvsp[-1].interm).loc, (yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode));
if ((yyval.interm.intermTypedNode) == 0) {
- parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString());
+ parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
(yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode);
}
}
@@ -6023,7 +6023,7 @@ yyreduce:
parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode));
(yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc);
if ((yyval.interm.intermTypedNode) == 0) {
- parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString());
+ parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()));
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
}
}
diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp
index a0fade16..d8a3aab5 100644
--- a/glslang/MachineIndependent/intermOut.cpp
+++ b/glslang/MachineIndependent/intermOut.cpp
@@ -48,37 +48,6 @@
#endif
#include <cstdint>
-namespace {
-
-bool IsInfinity(double x) {
-#ifdef _MSC_VER
- switch (_fpclass(x)) {
- case _FPCLASS_NINF:
- case _FPCLASS_PINF:
- return true;
- default:
- return false;
- }
-#else
- return std::isinf(x);
-#endif
-}
-
-bool IsNan(double x) {
-#ifdef _MSC_VER
- switch (_fpclass(x)) {
- case _FPCLASS_SNAN:
- case _FPCLASS_QNAN:
- return true;
- default:
- return false;
- }
-#else
- return std::isnan(x);
-#endif
-}
-
-}
namespace glslang {
diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp
index 19eabdf4..4250e92d 100644
--- a/glslang/MachineIndependent/iomapper.cpp
+++ b/glslang/MachineIndependent/iomapper.cpp
@@ -203,11 +203,7 @@ struct TResolverUniformAdaptor {
inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey) {
TVarEntryInfo& ent = entKey.second;
- ent.newLocation = -1;
- ent.newComponent = -1;
- ent.newBinding = -1;
- ent.newSet = -1;
- ent.newIndex = -1;
+ ent.clearNewAssignments();
const bool isValid = resolver.validateBinding(stage, ent);
if (isValid) {
resolver.resolveSet(ent.stage, ent);
@@ -281,11 +277,7 @@ struct TResolverInOutAdaptor {
inline void operator()(std::pair<const TString, TVarEntryInfo>& entKey)
{
TVarEntryInfo& ent = entKey.second;
- ent.newLocation = -1;
- ent.newComponent = -1;
- ent.newBinding = -1;
- ent.newSet = -1;
- ent.newIndex = -1;
+ ent.clearNewAssignments();
const bool isValid = resolver.validateInOut(ent.stage, ent);
if (isValid) {
resolver.resolveInOutLocation(stage, ent);
@@ -514,6 +506,24 @@ struct TSymbolValidater
return;
}
else {
+ // Deal with input/output pairs where one is a block member but the other is loose,
+ // e.g. with ARB_separate_shader_objects
+ if (type1.getBasicType() == EbtBlock &&
+ type1.isStruct() && !type2.isStruct()) {
+ // Iterate through block members tracking layout
+ glslang::TString name;
+ type1.getStruct()->begin()->type->appendMangledName(name);
+ if (name == mangleName2
+ && type1.getQualifier().layoutLocation == type2.getQualifier().layoutLocation) return;
+ }
+ if (type2.getBasicType() == EbtBlock &&
+ type2.isStruct() && !type1.isStruct()) {
+ // Iterate through block members tracking layout
+ glslang::TString name;
+ type2.getStruct()->begin()->type->appendMangledName(name);
+ if (name == mangleName1
+ && type1.getQualifier().layoutLocation == type2.getQualifier().layoutLocation) return;
+ }
TString err = "Invalid In/Out variable type : " + entKey.first;
infoSink.info.message(EPrefixInternalError, err.c_str());
hadError = true;
@@ -827,7 +837,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
}
// no locations added if already present, a built-in variable, a block, or an opaque
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
- type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
+ type.isAtomic() || type.isSpirvType() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@@ -855,8 +865,8 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf
return ent.newLocation = -1;
}
- // no locations added if already present, or a built-in variable
- if (type.getQualifier().hasLocation() || type.isBuiltIn()) {
+ // no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
+ if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
return ent.newLocation = -1;
}
@@ -942,8 +952,8 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
if (type.getQualifier().hasLocation()) {
return ent.newLocation = type.getQualifier().layoutLocation;
}
- // no locations added if already present, or a built-in variable
- if (type.isBuiltIn()) {
+ // no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
+ if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@@ -1024,7 +1034,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
} else {
// no locations added if already present, a built-in variable, a block, or an opaque
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
- type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
+ type.isAtomic() || type.isSpirvType() ||
+ (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@@ -1651,6 +1662,10 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
if (size <= int(autoPushConstantMaxSize)) {
qualifier.setBlockStorage(EbsPushConstant);
qualifier.layoutPacking = autoPushConstantBlockPacking;
+ // Push constants don't have set/binding etc. decorations, remove those.
+ qualifier.layoutSet = TQualifier::layoutSetEnd;
+ at->second.clearNewAssignments();
+
upgraded = true;
}
}
@@ -1658,10 +1673,14 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
// If it's been upgraded to push_constant, then remove it from the uniformVector
// so it doesn't get a set/binding assigned to it.
if (upgraded) {
- auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
- [this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
- if (at != uniformVector.end())
- uniformVector.erase(at);
+ while (1) {
+ auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
+ [this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
+ if (at != uniformVector.end())
+ uniformVector.erase(at);
+ else
+ break;
+ }
}
}
for (size_t stage = 0; stage < EShLangCount; stage++) {
diff --git a/glslang/MachineIndependent/iomapper.h b/glslang/MachineIndependent/iomapper.h
index c43864e3..ba7bc3bb 100644
--- a/glslang/MachineIndependent/iomapper.h
+++ b/glslang/MachineIndependent/iomapper.h
@@ -61,6 +61,15 @@ struct TVarEntryInfo {
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; }
};
diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp
index b1adfc93..9b45570e 100644
--- a/glslang/MachineIndependent/linkValidate.cpp
+++ b/glslang/MachineIndependent/linkValidate.cpp
@@ -55,22 +55,28 @@ namespace glslang {
//
// Link-time error emitter.
//
-void TIntermediate::error(TInfoSink& infoSink, const char* message)
+void TIntermediate::error(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
{
#ifndef GLSLANG_WEB
infoSink.info.prefix(EPrefixError);
- infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
+ if (unitStage < EShLangCount)
+ infoSink.info << "Linking " << StageName(getStage()) << " and " << StageName(unitStage) << " stages: " << message << "\n";
+ else
+ infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
#endif
++numErrors;
}
// Link-time warning.
-void TIntermediate::warn(TInfoSink& infoSink, const char* message)
+void TIntermediate::warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
{
#ifndef GLSLANG_WEB
infoSink.info.prefix(EPrefixWarning);
- infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
+ if (unitStage < EShLangCount)
+ infoSink.info << "Linking " << StageName(language) << " and " << StageName(unitStage) << " stages: " << message << "\n";
+ else
+ infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
#endif
}
@@ -312,6 +318,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
MERGE_TRUE(autoMapBindings);
MERGE_TRUE(autoMapLocations);
MERGE_TRUE(invertY);
+ MERGE_TRUE(dxPositionW);
MERGE_TRUE(flattenUniformArrays);
MERGE_TRUE(useUnknownFormat);
MERGE_TRUE(hlslOffsets);
@@ -579,9 +586,6 @@ void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate&
}
void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) {
- if (block->getType() == unitBlock->getType()) {
- return;
- }
if (block->getType().getTypeName() != unitBlock->getType().getTypeName() ||
block->getType().getBasicType() != unitBlock->getType().getBasicType() ||
@@ -628,44 +632,42 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
}
}
- TType unitType;
- unitType.shallowCopy(unitBlock->getType());
-
// update symbol node in unit tree,
// and other nodes that may reference it
class TMergeBlockTraverser : public TIntermTraverser {
public:
- TMergeBlockTraverser(const glslang::TType &type, const glslang::TType& unitType,
- glslang::TIntermediate& unit,
- const std::map<unsigned int, unsigned int>& memberIdxUpdates) :
- newType(type), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates)
- { }
- virtual ~TMergeBlockTraverser() { }
-
- const glslang::TType& newType; // type with modifications
- const glslang::TType& unitType; // copy of original type
- glslang::TIntermediate& unit; // intermediate that is being updated
- const std::map<unsigned int, unsigned int>& memberIndexUpdates;
-
- virtual void visitSymbol(TIntermSymbol* symbol)
+ TMergeBlockTraverser(const TIntermSymbol* newSym)
+ : newSymbol(newSym), unitType(nullptr), unit(nullptr), memberIndexUpdates(nullptr)
+ {
+ }
+ TMergeBlockTraverser(const TIntermSymbol* newSym, const glslang::TType* unitType, glslang::TIntermediate* unit,
+ const std::map<unsigned int, unsigned int>* memberIdxUpdates)
+ : newSymbol(newSym), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates)
{
- glslang::TType& symType = symbol->getWritableType();
+ }
+ virtual ~TMergeBlockTraverser() {}
- if (symType == unitType) {
- // each symbol node has a local copy of the unitType
- // if merging involves changing properties that aren't shared objects
- // they should be updated in all instances
+ const TIntermSymbol* newSymbol;
+ const glslang::TType* unitType; // copy of original type
+ glslang::TIntermediate* unit; // intermediate that is being updated
+ const std::map<unsigned int, unsigned int>* memberIndexUpdates;
- // e.g. the struct list is a ptr to an object, so it can be updated
- // once, outside the traverser
- //*symType.getWritableStruct() = *newType.getStruct();
+ virtual void visitSymbol(TIntermSymbol* symbol)
+ {
+ if (newSymbol->getAccessName() == symbol->getAccessName() &&
+ newSymbol->getQualifier().getBlockStorage() == symbol->getQualifier().getBlockStorage()) {
+ // Each symbol node may have a local copy of the block structure.
+ // Update those structures to match the new one post-merge
+ *(symbol->getWritableType().getWritableStruct()) = *(newSymbol->getType().getStruct());
}
-
}
virtual bool visitBinary(TVisit, glslang::TIntermBinary* node)
{
- if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == unitType) {
+ if (!unit || !unitType || !memberIndexUpdates || memberIndexUpdates->empty())
+ return true;
+
+ if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == *unitType) {
// this is a dereference to a member of the block since the
// member list changed, need to update this to point to the
// right index
@@ -673,8 +675,8 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion();
unsigned int memberIdx = constNode->getConstArray()[0].getUConst();
- unsigned int newIdx = memberIndexUpdates.at(memberIdx);
- TIntermTyped* newConstNode = unit.addConstantUnion(newIdx, node->getRight()->getLoc());
+ unsigned int newIdx = memberIndexUpdates->at(memberIdx);
+ TIntermTyped* newConstNode = unit->addConstantUnion(newIdx, node->getRight()->getLoc());
node->setRight(newConstNode);
delete constNode;
@@ -683,10 +685,20 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
}
return true;
}
- } finalLinkTraverser(block->getType(), unitType, *unit, memberIndexUpdates);
+ };
+
+ // 'this' may have symbols that are using the old block structure, so traverse the tree to update those
+ // in 'visitSymbol'
+ TMergeBlockTraverser finalLinkTraverser(block);
+ getTreeRoot()->traverse(&finalLinkTraverser);
- // update the tree to use the new type
- unit->getTreeRoot()->traverse(&finalLinkTraverser);
+ // The 'unit' intermediate needs the block structures update, but also structure entry indices
+ // may have changed from the old block to the new one that it was merged into, so update those
+ // in 'visitBinary'
+ TType unitType;
+ unitType.shallowCopy(unitBlock->getType());
+ TMergeBlockTraverser unitFinalLinkTraverser(block, &unitType, unit, &memberIndexUpdates);
+ unit->getTreeRoot()->traverse(&unitFinalLinkTraverser);
// update the member list
(*unitMemberList) = (*memberList);
@@ -759,7 +771,10 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
auto checkName = [this, unitSymbol, &infoSink](const TString& name) {
for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) {
- if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()) {
+ if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()
+ && !((*unitSymbol->getType().getStruct())[i].type->getQualifier().hasLocation()
+ || unitSymbol->getType().getQualifier().hasLocation())
+ ) {
error(infoSink, "Anonymous member name used for global variable or other anonymous member: ");
infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n";
}
@@ -815,6 +830,10 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
bool crossStage = getStage() != unitStage;
bool writeTypeComparison = false;
+ bool errorReported = false;
+ bool printQualifiers = false;
+ bool printPrecision = false;
+ bool printType = false;
// Types have to match
{
@@ -846,11 +865,48 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()));
}
- if (!symbol.getType().sameElementType(unitSymbol.getType()) ||
- !symbol.getType().sameTypeParameters(unitSymbol.getType()) ||
- !arraysMatch ) {
+ int lpidx = -1;
+ int rpidx = -1;
+ if (!symbol.getType().sameElementType(unitSymbol.getType(), &lpidx, &rpidx)) {
+ if (lpidx >= 0 && rpidx >= 0) {
+ error(infoSink, "Member names and types must match:", unitStage);
+ infoSink.info << " Block: " << symbol.getType().getTypeName() << "\n";
+ infoSink.info << " " << StageName(getStage()) << " stage: \""
+ << (*symbol.getType().getStruct())[lpidx].type->getCompleteString(true, false, false, true,
+ (*symbol.getType().getStruct())[lpidx].type->getFieldName()) << "\"\n";
+ infoSink.info << " " << StageName(unitStage) << " stage: \""
+ << (*unitSymbol.getType().getStruct())[rpidx].type->getCompleteString(true, false, false, true,
+ (*unitSymbol.getType().getStruct())[rpidx].type->getFieldName()) << "\"\n";
+ errorReported = true;
+ } else if (lpidx >= 0 && rpidx == -1) {
+ TString errmsg = StageName(getStage());
+ errmsg.append(" block member has no corresponding member in ").append(StageName(unitStage)).append(" block:");
+ error(infoSink, errmsg.c_str(), unitStage);
+ infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: "
+ << (*symbol.getType().getStruct())[lpidx].type->getFieldName() << "\n";
+ infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: n/a \n";
+ errorReported = true;
+ } else if (lpidx == -1 && rpidx >= 0) {
+ TString errmsg = StageName(unitStage);
+ errmsg.append(" block member has no corresponding member in ").append(StageName(getStage())).append(" block:");
+ error(infoSink, errmsg.c_str(), unitStage);
+ infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: "
+ << (*unitSymbol.getType().getStruct())[rpidx].type->getFieldName() << "\n";
+ infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: n/a \n";
+ errorReported = true;
+ } else {
+ error(infoSink, "Types must match:", unitStage);
+ writeTypeComparison = true;
+ printType = true;
+ }
+ } else if (!arraysMatch) {
+ error(infoSink, "Array sizes must be compatible:", unitStage);
writeTypeComparison = true;
- error(infoSink, "Types must match:");
+ printType = true;
+ } else if (!symbol.getType().sameTypeParameters(unitSymbol.getType())) {
+ error(infoSink, "Type parameters must match:", unitStage);
+ writeTypeComparison = true;
+ printType = true;
}
}
@@ -871,13 +927,35 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
}
const TQualifier& qualifier = (*symbol.getType().getStruct())[li].type->getQualifier();
const TQualifier & unitQualifier = (*unitSymbol.getType().getStruct())[ri].type->getQualifier();
- if (qualifier.layoutMatrix != unitQualifier.layoutMatrix ||
- qualifier.layoutOffset != unitQualifier.layoutOffset ||
- qualifier.layoutAlign != unitQualifier.layoutAlign ||
- qualifier.layoutLocation != unitQualifier.layoutLocation ||
- qualifier.layoutComponent != unitQualifier.layoutComponent) {
- error(infoSink, "Interface block member layout qualifiers must match:");
- writeTypeComparison = true;
+ bool layoutQualifierError = false;
+ if (qualifier.layoutMatrix != unitQualifier.layoutMatrix) {
+ error(infoSink, "Interface block member layout matrix qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (qualifier.layoutOffset != unitQualifier.layoutOffset) {
+ error(infoSink, "Interface block member layout offset qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (qualifier.layoutAlign != unitQualifier.layoutAlign) {
+ error(infoSink, "Interface block member layout align qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (qualifier.layoutLocation != unitQualifier.layoutLocation) {
+ error(infoSink, "Interface block member layout location qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (qualifier.layoutComponent != unitQualifier.layoutComponent) {
+ error(infoSink, "Interface block member layout component qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (layoutQualifierError) {
+ infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: "
+ << (*symbol.getType().getStruct())[li].type->getFieldName() << " \""
+ << (*symbol.getType().getStruct())[li].type->getCompleteString(true, true, false, false) << "\"\n";
+ infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: "
+ << (*unitSymbol.getType().getStruct())[ri].type->getFieldName() << " \""
+ << (*unitSymbol.getType().getStruct())[ri].type->getCompleteString(true, true, false, false) << "\"\n";
+ errorReported = true;
}
++li;
++ri;
@@ -891,8 +969,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
// Qualifiers have to (almost) match
// Storage...
if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
- error(infoSink, "Storage qualifiers must match:");
+ error(infoSink, "Storage qualifiers must match:", unitStage);
writeTypeComparison = true;
+ printQualifiers = true;
}
// Uniform and buffer blocks must either both have an instance name, or
@@ -900,33 +979,36 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
if (symbol.getQualifier().isUniformOrBuffer() &&
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) {
error(infoSink, "Matched Uniform or Storage blocks must all be anonymous,"
- " or all be named:");
+ " or all be named:", unitStage);
writeTypeComparison = true;
}
if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage &&
(IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) ||
(!IsAnonymous(symbol.getName()) && symbol.getName() != unitSymbol.getName()))) {
- warn(infoSink, "Matched shader interfaces are using different instance names.");
+ warn(infoSink, "Matched shader interfaces are using different instance names.", unitStage);
writeTypeComparison = true;
}
// Precision...
if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
- error(infoSink, "Precision qualifiers must match:");
+ error(infoSink, "Precision qualifiers must match:", unitStage);
writeTypeComparison = true;
+ printPrecision = true;
}
// Invariance...
if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) {
- error(infoSink, "Presence of invariant qualifier must match:");
+ error(infoSink, "Presence of invariant qualifier must match:", unitStage);
writeTypeComparison = true;
+ printQualifiers = true;
}
// Precise...
if (! crossStage && symbol.getQualifier().isNoContraction() != unitSymbol.getQualifier().isNoContraction()) {
- error(infoSink, "Presence of precise qualifier must match:");
+ error(infoSink, "Presence of precise qualifier must match:", unitStage);
writeTypeComparison = true;
+ printPrecision = true;
}
// Auxiliary and interpolation...
@@ -940,57 +1022,137 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) {
- error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
+ error(infoSink, "Interpolation and auxiliary storage qualifiers must match:", unitStage);
writeTypeComparison = true;
+ printQualifiers = true;
}
// Memory...
- if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
- symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent ||
- symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent ||
- symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
- symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent ||
- symbol.getQualifier().shadercallcoherent!= unitSymbol.getQualifier().shadercallcoherent ||
- symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate ||
- symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
- symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
- symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
- symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
- error(infoSink, "Memory qualifiers must match:");
- writeTypeComparison = true;
+ bool memoryQualifierError = false;
+ if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent) {
+ error(infoSink, "Memory coherent qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent) {
+ error(infoSink, "Memory devicecoherent qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent) {
+ error(infoSink, "Memory queuefamilycoherent qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent) {
+ error(infoSink, "Memory workgroupcoherent qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent) {
+ error(infoSink, "Memory subgroupcoherent qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().shadercallcoherent != unitSymbol.getQualifier().shadercallcoherent) {
+ error(infoSink, "Memory shadercallcoherent qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate) {
+ error(infoSink, "Memory nonprivate qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil) {
+ error(infoSink, "Memory volatil qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict) {
+ error(infoSink, "Memory restrict qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly) {
+ error(infoSink, "Memory readonly qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
+ error(infoSink, "Memory writeonly qualifier must match:", unitStage);
+ memoryQualifierError = true;
+ }
+ if (memoryQualifierError) {
+ writeTypeComparison = true;
+ printQualifiers = true;
}
// Layouts...
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
// requires separate user-supplied offset from actual computed offset, but
// current implementation only has one offset.
- if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
- symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
- (symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) ||
- symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent ||
- symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex ||
- (symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) ||
- (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) {
- error(infoSink, "Layout qualification must match:");
+ bool layoutQualifierError = false;
+ if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix) {
+ error(infoSink, "Layout matrix qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking) {
+ error(infoSink, "Layout packing qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) {
+ error(infoSink, "Layout location qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent) {
+ error(infoSink, "Layout component qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex) {
+ error(infoSink, "Layout index qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) {
+ error(infoSink, "Layout binding qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset)) {
+ error(infoSink, "Layout offset qualifier must match:", unitStage);
+ layoutQualifierError = true;
+ }
+ if (layoutQualifierError) {
writeTypeComparison = true;
+ printQualifiers = true;
}
// Initializers have to match, if both are present, and if we don't already know the types don't match
- if (! writeTypeComparison) {
+ if (! writeTypeComparison && ! errorReported) {
if (! symbol.getConstArray().empty() && ! unitSymbol.getConstArray().empty()) {
if (symbol.getConstArray() != unitSymbol.getConstArray()) {
- error(infoSink, "Initializers must match:");
+ error(infoSink, "Initializers must match:", unitStage);
infoSink.info << " " << symbol.getName() << "\n";
}
}
}
if (writeTypeComparison) {
- infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus ";
- if (symbol.getName() != unitSymbol.getName())
- infoSink.info << unitSymbol.getName() << ": ";
-
- infoSink.info << "\"" << unitSymbol.getType().getCompleteString() << "\"\n";
+ if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
+ symbol.getType().getStruct() && unitSymbol.getType().getStruct()) {
+ if (printType) {
+ infoSink.info << " " << StageName(getStage()) << " stage: \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision,
+ printType, symbol.getName(), symbol.getType().getTypeName()) << "\"\n";
+ infoSink.info << " " << StageName(unitStage) << " stage: \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision,
+ printType, unitSymbol.getName(), unitSymbol.getType().getTypeName()) << "\"\n";
+ } else {
+ infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << " Instance: " << symbol.getName()
+ << ": \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
+ infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << " Instance: " << unitSymbol.getName()
+ << ": \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
+ }
+ } else {
+ if (printType) {
+ infoSink.info << " " << StageName(getStage()) << " stage: \""
+ << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, symbol.getName()) << "\"\n";
+ infoSink.info << " " << StageName(unitStage) << " stage: \""
+ << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, unitSymbol.getName()) << "\"\n";
+ } else {
+ infoSink.info << " " << StageName(getStage()) << " stage: " << symbol.getName() << " \""
+ << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
+ infoSink.info << " " << StageName(unitStage) << " stage: " << unitSymbol.getName() << " \""
+ << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n";
+ }
+ }
}
#endif
}
@@ -1798,7 +1960,7 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
return size;
}
- int numComponents;
+ int numComponents {0};
if (type.isScalar())
numComponents = 1;
else if (type.isVector())
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index 6aa9399d..581e9aa2 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -290,6 +290,8 @@ public:
resources(TBuiltInResource{}),
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
invertY(false),
+ dxPositionW(false),
+ enhancedMsgs(false),
useStorageBuffer(false),
invariantAll(false),
nanMinMaxClamp(false),
@@ -307,7 +309,7 @@ public:
useVulkanMemoryModel(false),
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
- pixelCenterInteger(false), originUpperLeft(false),
+ pixelCenterInteger(false), originUpperLeft(false),texCoordBuiltinRedeclared(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
postDepthCoverage(false), depthLayout(EldNone),
hlslFunctionality1(false),
@@ -397,6 +399,9 @@ public:
case EShTargetSpv_1_5:
processes.addProcess("target-env spirv1.5");
break;
+ case EShTargetSpv_1_6:
+ processes.addProcess("target-env spirv1.6");
+ break;
default:
processes.addProcess("target-env spirvUnknown");
break;
@@ -415,6 +420,9 @@ public:
case EShTargetVulkan_1_2:
processes.addProcess("target-env vulkan1.2");
break;
+ case EShTargetVulkan_1_3:
+ processes.addProcess("target-env vulkan1.3");
+ break;
default:
processes.addProcess("target-env vulkanUnknown");
break;
@@ -460,6 +468,20 @@ public:
}
bool getInvertY() const { return invertY; }
+ void setDxPositionW(bool dxPosW)
+ {
+ dxPositionW = dxPosW;
+ if (dxPositionW)
+ processes.addProcess("dx-position-w");
+ }
+ bool getDxPositionW() const { return dxPositionW; }
+
+ void setEnhancedMsgs()
+ {
+ enhancedMsgs = true;
+ }
+ bool getEnhancedMsgs() const { return enhancedMsgs && source == EShSourceGlsl; }
+
#ifdef ENABLE_HLSL
void setSource(EShSource s) { source = s; }
EShSource getSource() const { return source; }
@@ -812,6 +834,8 @@ public:
bool getOriginUpperLeft() const { return originUpperLeft; }
void setPixelCenterInteger() { pixelCenterInteger = true; }
bool getPixelCenterInteger() const { return pixelCenterInteger; }
+ void setTexCoordRedeclared() { texCoordBuiltinRedeclared = true; }
+ bool getTexCoordRedeclared() const { return texCoordBuiltinRedeclared; }
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
unsigned int getBlendEquations() const { return blendEquations; }
bool setXfbBufferStride(int buffer, unsigned stride)
@@ -1016,8 +1040,8 @@ public:
protected:
TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
- void error(TInfoSink& infoSink, const char*);
- void warn(TInfoSink& infoSink, const char*);
+ void error(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
+ void warn(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
void mergeCallGraphs(TInfoSink&, TIntermediate&);
void mergeModes(TInfoSink&, TIntermediate&);
void mergeTrees(TInfoSink&, TIntermediate&);
@@ -1070,6 +1094,8 @@ protected:
int numPushConstants;
bool recursive;
bool invertY;
+ bool dxPositionW;
+ bool enhancedMsgs;
bool useStorageBuffer;
bool invariantAll;
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
@@ -1098,6 +1124,7 @@ protected:
TLayoutGeometry outputPrimitive;
bool pixelCenterInteger;
bool originUpperLeft;
+ bool texCoordBuiltinRedeclared;
TVertexSpacing vertexSpacing;
TVertexOrder vertexOrder;
TInterlockOrdering interlockOrdering;
@@ -1158,6 +1185,7 @@ protected:
// for callableData/callableDataIn
// set of names of statically read/written I/O that might need extra checking
std::set<TString> ioAccessed;
+
// source code of shader, useful as part of debug information
std::string sourceFile;
std::string sourceText;