aboutsummaryrefslogtreecommitdiff
path: root/glslang
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
parent68c1880c09c36843dcf4346ea87cf69f5c7dbf9e (diff)
downloadglslang-070863af690bcc160da6e49d913f5d2e45bf095c.tar.gz
Add SPV_AMD_shader_early_and_late_fragment_tests
Diffstat (limited to 'glslang')
-rw-r--r--glslang/Include/BaseTypes.h2
-rw-r--r--glslang/Include/Types.h35
-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
7 files changed, 99 insertions, 3 deletions
diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h
index 3eec5973..6a429fd4 100644
--- a/glslang/Include/BaseTypes.h
+++ b/glslang/Include/BaseTypes.h
@@ -128,6 +128,7 @@ enum TStorageQualifier {
// built-ins written by fragment shader
EvqFragColor,
EvqFragDepth,
+ EvqFragStencil,
// end of list
EvqLast
@@ -353,6 +354,7 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
case EvqPointCoord: return "gl_PointCoord"; break;
case EvqFragColor: return "fragColor"; break;
case EvqFragDepth: return "gl_FragDepth"; break;
+ case EvqFragStencil: return "gl_FragStencilRefARB"; break;
case EvqPayload: return "rayPayloadNV"; break;
case EvqPayloadIn: return "rayPayloadInNV"; break;
case EvqHitAttr: return "hitAttributeNV"; break;
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 682d124c..93909a30 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -443,6 +443,18 @@ enum TLayoutDepth {
EldCount
};
+enum TLayoutStencil {
+ ElsNone,
+ ElsRefUnchangedFrontAMD,
+ ElsRefGreaterFrontAMD,
+ ElsRefLessFrontAMD,
+ ElsRefUnchangedBackAMD,
+ ElsRefGreaterBackAMD,
+ ElsRefLessBackAMD,
+
+ ElsCount
+};
+
enum TBlendEquationShift {
// No 'EBlendNone':
// These are used as bit-shift amounts. A mask of such shifts will have type 'int',
@@ -705,6 +717,7 @@ public:
case EvqVaryingOut:
case EvqFragColor:
case EvqFragDepth:
+ case EvqFragStencil:
return true;
default:
return false;
@@ -772,6 +785,7 @@ public:
case EvqVaryingOut:
case EvqFragColor:
case EvqFragDepth:
+ case EvqFragStencil:
return true;
default:
return false;
@@ -1239,6 +1253,18 @@ public:
default: return "none";
}
}
+ static const char* getLayoutStencilString(TLayoutStencil s)
+ {
+ switch (s) {
+ case ElsRefUnchangedFrontAMD: return "stencil_ref_unchanged_front_amd";
+ case ElsRefGreaterFrontAMD: return "stencil_ref_greater_front_amd";
+ case ElsRefLessFrontAMD: return "stencil_ref_less_front_amd";
+ case ElsRefUnchangedBackAMD: return "stencil_ref_unchanged_back_amd";
+ case ElsRefGreaterBackAMD: return "stencil_ref_greater_back_amd";
+ case ElsRefLessBackAMD: return "stencil_ref_less_back_amd";
+ default: return "none";
+ }
+ }
static const char* getBlendEquationString(TBlendEquationShift e)
{
switch (e) {
@@ -1336,7 +1362,9 @@ struct TShaderQualifiers {
#ifndef GLSLANG_WEB
bool earlyFragmentTests; // fragment input
bool postDepthCoverage; // fragment input
+ bool earlyAndLateFragmentTestsAMD; //fragment input
TLayoutDepth layoutDepth;
+ TLayoutStencil layoutStencil;
bool blendEquation; // true if any blend equation was specified
int numViews; // multiview extenstions
TInterlockOrdering interlockOrdering;
@@ -1346,6 +1374,7 @@ struct TShaderQualifiers {
int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // true if layout derivative_group_linearNV set
bool layoutPrimitiveCulling; // true if layout primitive_culling set
TLayoutDepth getDepth() const { return layoutDepth; }
+ TLayoutStencil getStencil() const { return layoutStencil; }
#else
TLayoutDepth getDepth() const { return EldNone; }
#endif
@@ -1371,8 +1400,10 @@ struct TShaderQualifiers {
localSizeSpecId[2] = TQualifier::layoutNotSet;
#ifndef GLSLANG_WEB
earlyFragmentTests = false;
+ earlyAndLateFragmentTestsAMD = false;
postDepthCoverage = false;
layoutDepth = EldNone;
+ layoutStencil = ElsNone;
blendEquation = false;
numViews = TQualifier::layoutNotSet;
layoutOverrideCoverage = false;
@@ -1424,10 +1455,14 @@ struct TShaderQualifiers {
#ifndef GLSLANG_WEB
if (src.earlyFragmentTests)
earlyFragmentTests = true;
+ if (src.earlyAndLateFragmentTestsAMD)
+ earlyAndLateFragmentTestsAMD = true;
if (src.postDepthCoverage)
postDepthCoverage = true;
if (src.layoutDepth)
layoutDepth = src.layoutDepth;
+ if (src.layoutStencil)
+ layoutStencil = src.layoutStencil;
if (src.blendEquation)
blendEquation = src.blendEquation;
if (src.numViews != TQualifier::layoutNotSet)
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;