aboutsummaryrefslogtreecommitdiff
path: root/glslang/MachineIndependent
diff options
context:
space:
mode:
authordwang102 <dong.wang@amd.com>2022-07-15 14:36:03 +0800
committerdwang102 <dong.wang@amd.com>2022-07-18 14:20:18 +0800
commit070863af690bcc160da6e49d913f5d2e45bf095c (patch)
treec78fdf42410d7b14c64815a2b5c9e9e279d09c99 /glslang/MachineIndependent
parent68c1880c09c36843dcf4346ea87cf69f5c7dbf9e (diff)
downloadglslang-070863af690bcc160da6e49d913f5d2e45bf095c.tar.gz
Add SPV_AMD_shader_early_and_late_fragment_tests
Diffstat (limited to 'glslang/MachineIndependent')
-rw-r--r--glslang/MachineIndependent/Initialize.cpp1
-rw-r--r--glslang/MachineIndependent/ParseHelper.cpp44
-rw-r--r--glslang/MachineIndependent/Versions.cpp1
-rw-r--r--glslang/MachineIndependent/Versions.h1
-rw-r--r--glslang/MachineIndependent/localintermediate.h18
5 files changed, 62 insertions, 3 deletions
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index b18b2575..ff3db7cd 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -8065,6 +8065,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable);
#ifndef GLSLANG_WEB
SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable);
+ SpecialQualifier("gl_FragStencilRefARB", EvqFragStencil, EbvFragStencilRef, symbolTable);
SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable);
BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable);
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 45a72d93..143d6214 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -2988,6 +2988,12 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
if (isEsProfile() && intermediate.getEarlyFragmentTests())
message = "can't modify gl_FragDepth if using early_fragment_tests";
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:
break;
@@ -4709,10 +4715,22 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
if (! intermediate.setDepth(publicType.layoutDepth))
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 (
- identifier == "gl_PrimitiveIndicesNV" ||
- identifier == "gl_FragStencilRefARB") {
+ identifier == "gl_PrimitiveIndicesNV") {
if (qualifier.hasLayout())
error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
if (qualifier.storage != EvqVaryingOut)
@@ -5546,6 +5564,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.shaderQualifiers.earlyFragmentTests = true;
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") {
requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage");
if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) {
@@ -5562,6 +5586,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
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)) {
if (id == TQualifier::getInterlockOrderingString(order)) {
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", "");
if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.getDepth() != EldNone)
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
TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers);
@@ -9091,6 +9125,12 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
else
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.qualifier.storage == EvqVaryingIn)
intermediate.setPostDepthCoverage();
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 52c1e1cc..e24d5c54 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -275,6 +275,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable;
extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable;
extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch] = EBhDisable;
+ extensionBehavior[E_GL_AMD_shader_early_and_late_fragment_tests] = EBhDisable;
extensionBehavior[E_GL_INTEL_shader_integer_functions2] = EBhDisable;
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index c411f5b6..6817cff2 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -238,6 +238,7 @@ const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_sh
const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod";
const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask";
const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch";
+const char* const E_GL_AMD_shader_early_and_late_fragment_tests = "GL_AMD_shader_early_and_late_fragment_tests";
const char* const E_GL_INTEL_shader_integer_functions2 = "GL_INTEL_shader_integer_functions2";
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index d3e86f9e..ddeaa353 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -296,6 +296,7 @@ public:
invariantAll(false),
nanMinMaxClamp(false),
depthReplacing(false),
+ stencilReplacing(false),
uniqueId(0),
globalUniformBlockName(""),
atomicCounterBlockName(""),
@@ -311,7 +312,7 @@ public:
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
pixelCenterInteger(false), originUpperLeft(false),texCoordBuiltinRedeclared(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
- postDepthCoverage(false), depthLayout(EldNone),
+ postDepthCoverage(false), earlyAndLateFragmentTestsAMD(false), depthLayout(EldNone), stencilLayout(ElsNone),
hlslFunctionality1(false),
blendEquations(0), xfbMode(false), multiStream(false),
layoutOverrideCoverage(false),
@@ -587,6 +588,8 @@ public:
bool isInvariantAll() const { return invariantAll; }
void setDepthReplacing() { depthReplacing = true; }
bool isDepthReplacing() const { return depthReplacing; }
+ void setStencilReplacing() { stencilReplacing = true; }
+ bool isStencilReplacing() const { return stencilReplacing; }
bool setLocalSize(int dim, int size)
{
if (localSizeNotDefault[dim])
@@ -821,7 +824,9 @@ public:
void setPostDepthCoverage() { postDepthCoverage = true; }
bool getPostDepthCoverage() const { return postDepthCoverage; }
void setEarlyFragmentTests() { earlyFragmentTests = true; }
+ void setEarlyAndLateFragmentTestsAMD() { earlyAndLateFragmentTestsAMD = true; }
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
+ bool getEarlyAndLateFragmentTestsAMD() const { return earlyAndLateFragmentTestsAMD; }
bool setDepth(TLayoutDepth d)
{
if (depthLayout != EldNone)
@@ -829,7 +834,15 @@ public:
depthLayout = d;
return true;
}
+ bool setStencil(TLayoutStencil s)
+ {
+ if (stencilLayout != ElsNone)
+ return stencilLayout == s;
+ stencilLayout = s;
+ return true;
+ }
TLayoutDepth getDepth() const { return depthLayout; }
+ TLayoutStencil getStencil() const { return stencilLayout; }
void setOriginUpperLeft() { originUpperLeft = true; }
bool getOriginUpperLeft() const { return originUpperLeft; }
void setPixelCenterInteger() { pixelCenterInteger = true; }
@@ -1100,6 +1113,7 @@ protected:
bool invariantAll;
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
bool depthReplacing;
+ bool stencilReplacing;
int localSize[3];
bool localSizeNotDefault[3];
int localSizeSpecId[3];
@@ -1131,7 +1145,9 @@ protected:
bool pointMode;
bool earlyFragmentTests;
bool postDepthCoverage;
+ bool earlyAndLateFragmentTestsAMD;
TLayoutDepth depthLayout;
+ TLayoutStencil stencilLayout;
bool hlslFunctionality1;
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
bool xfbMode;