|
@@ -2988,6 +2988,12 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
|
|
if (isEsProfile() && intermediate.getEarlyFragmentTests())
|
|
if (isEsProfile() && intermediate.getEarlyFragmentTests())
|
|
message = "can't modify gl_FragDepth if using early_fragment_tests";
|
|
message = "can't modify gl_FragDepth if using early_fragment_tests";
|
|
break;
|
|
break;
|
|
|
|
+ case EvqFragStencil:
|
|
|
|
+ intermediate.setStencilReplacing();
|
|
|
|
+ // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader."
|
|
|
|
+ if (isEsProfile() && intermediate.getEarlyFragmentTests())
|
|
|
|
+ message = "can't modify EvqFragStencil if using early_fragment_tests";
|
|
|
|
+ break;
|
|
|
|
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
@@ -4709,10 +4715,22 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
|
|
if (! intermediate.setDepth(publicType.layoutDepth))
|
|
if (! intermediate.setDepth(publicType.layoutDepth))
|
|
error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
|
|
error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
|
|
}
|
|
}
|
|
|
|
+ } else if (identifier == "gl_FragStencilRefARB") {
|
|
|
|
+ if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
|
|
|
|
+ qualifier.isMemory() || qualifier.isAuxiliary())
|
|
|
|
+ error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
|
|
|
|
+ if (qualifier.storage != EvqVaryingOut)
|
|
|
|
+ error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
|
|
|
|
+ if (publicType.layoutStencil != ElsNone) {
|
|
|
|
+ if (intermediate.inIoAccessed("gl_FragStencilRefARB"))
|
|
|
|
+ error(loc, "cannot redeclare after use", "gl_FragStencilRefARB", "");
|
|
|
|
+ if (!intermediate.setStencil(publicType.layoutStencil))
|
|
|
|
+ error(loc, "all redeclarations must use the same stencil layout on", "redeclaration",
|
|
|
|
+ symbol->getName().c_str());
|
|
|
|
+ }
|
|
}
|
|
}
|
|
else if (
|
|
else if (
|
|
- identifier == "gl_PrimitiveIndicesNV" ||
|
|
|
|
- identifier == "gl_FragStencilRefARB") {
|
|
|
|
|
|
+ identifier == "gl_PrimitiveIndicesNV") {
|
|
if (qualifier.hasLayout())
|
|
if (qualifier.hasLayout())
|
|
error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
|
|
error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
|
|
if (qualifier.storage != EvqVaryingOut)
|
|
if (qualifier.storage != EvqVaryingOut)
|
|
@@ -5546,6 +5564,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|
publicType.shaderQualifiers.earlyFragmentTests = true;
|
|
publicType.shaderQualifiers.earlyFragmentTests = true;
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ if (id == "early_and_late_fragment_tests_amd") {
|
|
|
|
+ profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_AMD_shader_early_and_late_fragment_tests, "early_and_late_fragment_tests_amd");
|
|
|
|
+ profileRequires(loc, EEsProfile, 310, nullptr, "early_and_late_fragment_tests_amd");
|
|
|
|
+ publicType.shaderQualifiers.earlyAndLateFragmentTestsAMD = true;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
if (id == "post_depth_coverage") {
|
|
if (id == "post_depth_coverage") {
|
|
requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage");
|
|
requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage");
|
|
if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) {
|
|
if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) {
|
|
@@ -5562,6 +5586,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ for (TLayoutStencil stencil = (TLayoutStencil)(ElsNone + 1); stencil < ElsCount; stencil = (TLayoutStencil)(stencil+1)) {
|
|
|
|
+ if (id == TQualifier::getLayoutStencilString(stencil)) {
|
|
|
|
+ requireProfile(loc, ECoreProfile | ECompatibilityProfile, "stencil layout qualifier");
|
|
|
|
+ profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, nullptr, "stencil layout qualifier");
|
|
|
|
+ publicType.shaderQualifiers.layoutStencil = stencil;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) {
|
|
for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) {
|
|
if (id == TQualifier::getInterlockOrderingString(order)) {
|
|
if (id == TQualifier::getInterlockOrderingString(order)) {
|
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier");
|
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier");
|
|
@@ -7259,6 +7291,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
|
error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
|
|
error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
|
|
if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.getDepth() != EldNone)
|
|
if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.getDepth() != EldNone)
|
|
error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", "");
|
|
error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", "");
|
|
|
|
+ if (identifier != "gl_FragStencilRefARB" && publicType.shaderQualifiers.getStencil() != ElsNone)
|
|
|
|
+ error(loc, "can only apply depth layout to gl_FragStencilRefARB", "layout qualifier", "");
|
|
|
|
|
|
// Check for redeclaration of built-ins and/or attempting to declare a reserved name
|
|
// Check for redeclaration of built-ins and/or attempting to declare a reserved name
|
|
TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers);
|
|
TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers);
|
|
@@ -9091,6 +9125,12 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
|
|
else
|
|
else
|
|
error(loc, "can only apply to 'in'", "early_fragment_tests", "");
|
|
error(loc, "can only apply to 'in'", "early_fragment_tests", "");
|
|
}
|
|
}
|
|
|
|
+ if (publicType.shaderQualifiers.earlyAndLateFragmentTestsAMD) {
|
|
|
|
+ if (publicType.qualifier.storage == EvqVaryingIn)
|
|
|
|
+ intermediate.setEarlyAndLateFragmentTestsAMD();
|
|
|
|
+ else
|
|
|
|
+ error(loc, "can only apply to 'in'", "early_and_late_fragment_tests_amd", "");
|
|
|
|
+ }
|
|
if (publicType.shaderQualifiers.postDepthCoverage) {
|
|
if (publicType.shaderQualifiers.postDepthCoverage) {
|
|
if (publicType.qualifier.storage == EvqVaryingIn)
|
|
if (publicType.qualifier.storage == EvqVaryingIn)
|
|
intermediate.setPostDepthCoverage();
|
|
intermediate.setPostDepthCoverage();
|