Fix #1759: Check for specialization constants when literals required.
This commit is contained in:
parent
86c72c9486
commit
5cb2fa2ad2
7 changed files with 93 additions and 5 deletions
|
|
@ -5003,6 +5003,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
integerCheck(node, feature);
|
||||
const TIntermConstantUnion* constUnion = node->getAsConstantUnion();
|
||||
int value;
|
||||
bool nonLiteral = false;
|
||||
if (constUnion) {
|
||||
value = constUnion->getConstArray()[0].getIConst();
|
||||
if (! constUnion->isLiteral()) {
|
||||
|
|
@ -5012,6 +5013,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
} else {
|
||||
// grammar should have give out the error message
|
||||
value = 0;
|
||||
nonLiteral = true;
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
|
|
@ -5033,6 +5035,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
profileRequires(loc, EEsProfile, 310, nullptr, feature);
|
||||
}
|
||||
publicType.qualifier.layoutOffset = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "offset", "");
|
||||
return;
|
||||
} else if (id == "align") {
|
||||
const char* feature = "uniform buffer-member align";
|
||||
|
|
@ -5045,6 +5049,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "must be a power of 2", "align", "");
|
||||
else
|
||||
publicType.qualifier.layoutAlign = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "align", "");
|
||||
return;
|
||||
} else if (id == "location") {
|
||||
profileRequires(loc, EEsProfile, 300, nullptr, "location");
|
||||
|
|
@ -5054,6 +5060,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "location is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutLocation = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "location", "");
|
||||
return;
|
||||
} else if (id == "set") {
|
||||
if ((unsigned int)value >= TQualifier::layoutSetEnd)
|
||||
|
|
@ -5062,6 +5070,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
publicType.qualifier.layoutSet = value;
|
||||
if (value != 0)
|
||||
requireVulkan(loc, "descriptor set");
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "set", "");
|
||||
return;
|
||||
} else if (id == "binding") {
|
||||
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding");
|
||||
|
|
@ -5070,6 +5080,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "binding is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutBinding = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "binding", "");
|
||||
return;
|
||||
} else if (id == "component") {
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component");
|
||||
|
|
@ -5078,6 +5090,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "component is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutComponent = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "component", "");
|
||||
return;
|
||||
} else if (id.compare(0, 4, "xfb_") == 0) {
|
||||
// "Any shader making any static use (after preprocessing) of any of these
|
||||
|
|
@ -5098,12 +5112,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1);
|
||||
else
|
||||
publicType.qualifier.layoutXfbBuffer = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "xfb_buffer", "");
|
||||
return;
|
||||
} else if (id == "xfb_offset") {
|
||||
if (value >= (int)TQualifier::layoutXfbOffsetEnd)
|
||||
error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1);
|
||||
else
|
||||
publicType.qualifier.layoutXfbOffset = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "xfb_offset", "");
|
||||
return;
|
||||
} else if (id == "xfb_stride") {
|
||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||
|
|
@ -5116,6 +5134,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1);
|
||||
else
|
||||
publicType.qualifier.layoutXfbStride = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "xfb_stride", "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -5126,6 +5146,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "attachment index is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutAttachment = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "input_attachment_index", "");
|
||||
return;
|
||||
}
|
||||
if (id == "constant_id") {
|
||||
|
|
@ -5138,11 +5160,15 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
if (! intermediate.addUsedConstantId(value))
|
||||
error(loc, "specialization-constant id already used", id.c_str(), "");
|
||||
}
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "constant_id", "");
|
||||
return;
|
||||
}
|
||||
if (id == "num_views") {
|
||||
requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views");
|
||||
publicType.shaderQualifiers.numViews = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "num_views", "");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5154,6 +5180,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
if (id == "secondary_view_offset") {
|
||||
requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering");
|
||||
publicType.qualifier.layoutSecondaryViewportRelativeOffset = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "secondary_view_offset", "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -5165,6 +5193,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "must be a power of 2", "buffer_reference_align", "");
|
||||
else
|
||||
publicType.qualifier.layoutBufferReferenceAlign = (unsigned int)std::log2(value);
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "buffer_reference_align", "");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5178,6 +5208,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "must be greater than 0", "vertices", "");
|
||||
else
|
||||
publicType.shaderQualifiers.vertices = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "vertices", "");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
@ -5192,12 +5224,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
error(loc, "must be at least 1", "invocations", "");
|
||||
else
|
||||
publicType.shaderQualifiers.invocations = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "invocations", "");
|
||||
return;
|
||||
}
|
||||
if (id == "max_vertices") {
|
||||
publicType.shaderQualifiers.vertices = value;
|
||||
if (value > resources.maxGeometryOutputVertices)
|
||||
error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "max_vertices", "");
|
||||
return;
|
||||
}
|
||||
if (id == "stream") {
|
||||
|
|
@ -5205,6 +5241,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
publicType.qualifier.layoutStream = value;
|
||||
if (value > 0)
|
||||
intermediate.setMultiStream();
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "stream", "");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
@ -5222,6 +5260,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
}
|
||||
|
||||
publicType.qualifier.layoutIndex = value;
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "index", "");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
@ -5233,6 +5273,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
publicType.shaderQualifiers.vertices = value;
|
||||
if (value > resources.maxMeshOutputVerticesNV)
|
||||
error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", "");
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "max_vertices", "");
|
||||
return;
|
||||
}
|
||||
if (id == "max_primitives") {
|
||||
|
|
@ -5240,6 +5282,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
publicType.shaderQualifiers.primitives = value;
|
||||
if (value > resources.maxMeshOutputPrimitivesNV)
|
||||
error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", "");
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "max_primitives", "");
|
||||
return;
|
||||
}
|
||||
// Fall through
|
||||
|
|
@ -5259,6 +5303,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
|
||||
profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
|
||||
}
|
||||
if (nonLiteral)
|
||||
error(loc, "needs a literal integer", "local_size", "");
|
||||
if (id.size() == 12 && value == 0) {
|
||||
error(loc, "must be at least 1", id.c_str(), "");
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue