Implement conservative depth layout qualifiers. Based partly on a submission.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27758 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
d6c72a44ab
commit
d1888f83f6
12
Test/420.frag
Normal file
12
Test/420.frag
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 420 core
|
||||||
|
|
||||||
|
layout(depth_any) out float gl_FragDepth;
|
||||||
|
layout(depth_greater) out float gl_FragDepth; // ERROR: redeclaration with different qualifier
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragDepth = 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(depth_less) in float depth; // ERROR: depth_less only applies to gl_FragDepth
|
||||||
|
layout(depth_any) out float gl_FragDepth; // ERROR, done after use
|
||||||
42
Test/baseResults/420.frag.out
Normal file
42
Test/baseResults/420.frag.out
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
420.frag
|
||||||
|
Warning, version 420 is not yet complete; most version-specific features are present, but some are missing.
|
||||||
|
ERROR: 0:4: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth
|
||||||
|
ERROR: 0:11: 'layout qualifier' : can only apply depth layout to gl_FragDepth
|
||||||
|
ERROR: 0:12: 'gl_FragDepth' : cannot redeclare after use
|
||||||
|
ERROR: 3 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
|
Shader version: 420
|
||||||
|
using depth_any
|
||||||
|
ERROR: node is still EOpNull!
|
||||||
|
0:6 Function Definition: main( (void)
|
||||||
|
0:6 Function Parameters:
|
||||||
|
0:8 Sequence
|
||||||
|
0:8 move second child to first child (float)
|
||||||
|
0:8 'gl_FragDepth' (gl_FragDepth float)
|
||||||
|
0:8 Constant:
|
||||||
|
0:8 0.300000
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'gl_FragDepth' (gl_FragDepth float)
|
||||||
|
0:? 'gl_FragDepth' (gl_FragDepth float)
|
||||||
|
0:? 'depth' (smooth in float)
|
||||||
|
|
||||||
|
|
||||||
|
Linked fragment stage:
|
||||||
|
|
||||||
|
|
||||||
|
Shader version: 420
|
||||||
|
using depth_any
|
||||||
|
ERROR: node is still EOpNull!
|
||||||
|
0:6 Function Definition: main( (void)
|
||||||
|
0:6 Function Parameters:
|
||||||
|
0:8 Sequence
|
||||||
|
0:8 move second child to first child (float)
|
||||||
|
0:8 'gl_FragDepth' (gl_FragDepth float)
|
||||||
|
0:8 Constant:
|
||||||
|
0:8 0.300000
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'gl_FragDepth' (gl_FragDepth float)
|
||||||
|
0:? 'gl_FragDepth' (gl_FragDepth float)
|
||||||
|
0:? 'depth' (smooth in float)
|
||||||
|
|
||||||
@ -16,11 +16,9 @@ ERROR: 0:100: 'local_size_x' : there is no such layout identifier for this stage
|
|||||||
ERROR: 0:102: 'color' : redefinition
|
ERROR: 0:102: 'color' : redefinition
|
||||||
ERROR: 0:103: 'index' : there is no such layout identifier for this stage taking an assigned value
|
ERROR: 0:103: 'index' : there is no such layout identifier for this stage taking an assigned value
|
||||||
ERROR: 0:104: 'location' : overlapping use of location 3
|
ERROR: 0:104: 'location' : overlapping use of location 3
|
||||||
ERROR: 0:106: 'depth_greater' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)
|
ERROR: 0:112: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth
|
||||||
ERROR: 0:112: 'depth_any' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)
|
ERROR: 0:118: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth
|
||||||
ERROR: 0:115: 'depth_greater' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)
|
ERROR: 0:121: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth
|
||||||
ERROR: 0:118: 'depth_less' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)
|
|
||||||
ERROR: 0:121: 'depth_unchanged' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)
|
|
||||||
ERROR: 0:150: 'constructor' : constructing from a non-dereferenced array
|
ERROR: 0:150: 'constructor' : constructing from a non-dereferenced array
|
||||||
ERROR: 0:150: '=' : cannot convert from 'const float' to '3-element array of 4-component vector of float'
|
ERROR: 0:150: '=' : cannot convert from 'const float' to '3-element array of 4-component vector of float'
|
||||||
ERROR: 0:152: 'constructor' : cannot convert parameter 1 from 'const 2-element array of 4-component vector of float' to '4-component vector of float'
|
ERROR: 0:152: 'constructor' : cannot convert parameter 1 from 'const 2-element array of 4-component vector of float' to '4-component vector of float'
|
||||||
@ -45,7 +43,7 @@ ERROR: 0:226: 'in' : not allowed in nested scope
|
|||||||
ERROR: 0:227: 'in' : not allowed in nested scope
|
ERROR: 0:227: 'in' : not allowed in nested scope
|
||||||
ERROR: 0:228: 'in' : not allowed in nested scope
|
ERROR: 0:228: 'in' : not allowed in nested scope
|
||||||
ERROR: 0:232: 'out' : not allowed in nested scope
|
ERROR: 0:232: 'out' : not allowed in nested scope
|
||||||
ERROR: 45 compilation errors. No code generated.
|
ERROR: 43 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
Shader version: 430
|
Shader version: 430
|
||||||
@ -53,6 +51,7 @@ Requested GL_3DL_array_objects
|
|||||||
gl_FragCoord pixel center is integer
|
gl_FragCoord pixel center is integer
|
||||||
gl_FragCoord origin is upper left
|
gl_FragCoord origin is upper left
|
||||||
using early_fragment_tests
|
using early_fragment_tests
|
||||||
|
using depth_greater
|
||||||
ERROR: node is still EOpNull!
|
ERROR: node is still EOpNull!
|
||||||
0:5 Sequence
|
0:5 Sequence
|
||||||
0:5 move second child to first child (int)
|
0:5 move second child to first child (int)
|
||||||
@ -306,6 +305,7 @@ Requested GL_3DL_array_objects
|
|||||||
gl_FragCoord pixel center is integer
|
gl_FragCoord pixel center is integer
|
||||||
gl_FragCoord origin is upper left
|
gl_FragCoord origin is upper left
|
||||||
using early_fragment_tests
|
using early_fragment_tests
|
||||||
|
using depth_greater
|
||||||
ERROR: node is still EOpNull!
|
ERROR: node is still EOpNull!
|
||||||
0:5 Sequence
|
0:5 Sequence
|
||||||
0:5 move second child to first child (int)
|
0:5 move second child to first child (int)
|
||||||
|
|||||||
@ -53,6 +53,7 @@ tokenLength.vert
|
|||||||
110scope.vert
|
110scope.vert
|
||||||
300scope.vert
|
300scope.vert
|
||||||
400.frag
|
400.frag
|
||||||
|
420.frag
|
||||||
420.vert
|
420.vert
|
||||||
420.geom
|
420.geom
|
||||||
420_size_gl_in.geom
|
420_size_gl_in.geom
|
||||||
|
|||||||
@ -305,6 +305,16 @@ enum TLayoutFormat {
|
|||||||
ElfCount
|
ElfCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TLayoutDepth {
|
||||||
|
EldNone,
|
||||||
|
EldAny,
|
||||||
|
EldGreater,
|
||||||
|
EldLess,
|
||||||
|
EldUnchanged,
|
||||||
|
|
||||||
|
EldCount
|
||||||
|
};
|
||||||
|
|
||||||
class TQualifier {
|
class TQualifier {
|
||||||
public:
|
public:
|
||||||
void clear()
|
void clear()
|
||||||
@ -645,6 +655,16 @@ public:
|
|||||||
default: return "none";
|
default: return "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static const char* getLayoutDepthString(TLayoutDepth d)
|
||||||
|
{
|
||||||
|
switch (d) {
|
||||||
|
case EldAny: return "depth_any";
|
||||||
|
case EldGreater: return "depth_greater";
|
||||||
|
case EldLess: return "depth_less";
|
||||||
|
case EldUnchanged: return "depth_unchanged";
|
||||||
|
default: return "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
static const char* getGeometryString(TLayoutGeometry geometry)
|
static const char* getGeometryString(TLayoutGeometry geometry)
|
||||||
{
|
{
|
||||||
switch (geometry) {
|
switch (geometry) {
|
||||||
@ -703,6 +723,7 @@ struct TShaderQualifiers {
|
|||||||
bool pointMode;
|
bool pointMode;
|
||||||
int localSize[3]; // compute shader
|
int localSize[3]; // compute shader
|
||||||
bool earlyFragmentTests; // fragment input
|
bool earlyFragmentTests; // fragment input
|
||||||
|
TLayoutDepth layoutDepth;
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
@ -718,6 +739,7 @@ struct TShaderQualifiers {
|
|||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
localSize[2] = 1;
|
localSize[2] = 1;
|
||||||
earlyFragmentTests = false;
|
earlyFragmentTests = false;
|
||||||
|
layoutDepth = EldNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge in characteristics from the 'src' qualifier. They can override when
|
// Merge in characteristics from the 'src' qualifier. They can override when
|
||||||
@ -746,6 +768,8 @@ struct TShaderQualifiers {
|
|||||||
}
|
}
|
||||||
if (src.earlyFragmentTests)
|
if (src.earlyFragmentTests)
|
||||||
earlyFragmentTests = true;
|
earlyFragmentTests = true;
|
||||||
|
if (src.layoutDepth)
|
||||||
|
layoutDepth = src.layoutDepth;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1160,10 +1184,8 @@ public:
|
|||||||
p += snprintf(p, end - p, "offset=%d ", qualifier.layoutOffset);
|
p += snprintf(p, end - p, "offset=%d ", qualifier.layoutOffset);
|
||||||
if (qualifier.hasAlign())
|
if (qualifier.hasAlign())
|
||||||
p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign);
|
p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign);
|
||||||
|
|
||||||
if (qualifier.hasFormat())
|
if (qualifier.hasFormat())
|
||||||
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutFormatString(qualifier.layoutFormat));
|
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutFormatString(qualifier.layoutFormat));
|
||||||
|
|
||||||
if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset())
|
if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset())
|
||||||
p += snprintf(p, end - p, "xfb_buffer=%d ", qualifier.layoutXfbBuffer);
|
p += snprintf(p, end - p, "xfb_buffer=%d ", qualifier.layoutXfbBuffer);
|
||||||
if (qualifier.hasXfbOffset())
|
if (qualifier.hasXfbOffset())
|
||||||
|
|||||||
@ -2565,8 +2565,14 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
|
|||||||
error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
|
error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
|
||||||
if (qualifier.storage != EvqVaryingOut)
|
if (qualifier.storage != EvqVaryingOut)
|
||||||
error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
|
error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
|
||||||
// TODO 4.2: gl_FragDepth redeclaration
|
if (publicType.layoutDepth != EldNone) {
|
||||||
}
|
if (intermediate.inIoAccessed("gl_FragDepth"))
|
||||||
|
error(loc, "cannot redeclare after use", "gl_FragDepth", "");
|
||||||
|
if (! intermediate.setDepth(publicType.layoutDepth))
|
||||||
|
error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
// TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
|
// TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
@ -2965,8 +2971,8 @@ void TParseContext::finalErrorCheck()
|
|||||||
// Layout qualifier stuff.
|
// Layout qualifier stuff.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Put the id's layout qualification into the public type. This is before we know any
|
// Put the id's layout qualification into the public type, for qualifiers not having a number set.
|
||||||
// type information for error checking.
|
// This is before we know any type information for error checking.
|
||||||
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id)
|
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id)
|
||||||
{
|
{
|
||||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||||
@ -3105,12 +3111,20 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
|
|||||||
publicType.shaderQualifiers.earlyFragmentTests = true;
|
publicType.shaderQualifiers.earlyFragmentTests = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) {
|
||||||
|
if (id == TQualifier::getLayoutDepthString(depth)) {
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier");
|
||||||
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 0, "depth layout qualifier");
|
||||||
|
publicType.shaderQualifiers.layoutDepth = depth;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
|
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the id's layout qualifier value into the public type. This is before we know any
|
// Put the id's layout qualifier value into the public type, for qualifiers having a number set.
|
||||||
// type information for error checking.
|
// This is before we know any type information for error checking.
|
||||||
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, const TIntermTyped* node)
|
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, const TIntermTyped* node)
|
||||||
{
|
{
|
||||||
const char* feature = "layout-id value";
|
const char* feature = "layout-id value";
|
||||||
@ -3742,6 +3756,8 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
|||||||
|
|
||||||
if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
|
if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
|
||||||
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.layoutDepth != EldNone)
|
||||||
|
error(loc, "can only apply depth layout to gl_FragDepth", "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
|
||||||
bool newDeclaration = false; // true if a new entry gets added to the symbol table
|
bool newDeclaration = false; // true if a new entry gets added to the symbol table
|
||||||
|
|||||||
@ -621,6 +621,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
|||||||
infoSink.debug << "gl_FragCoord origin is upper left\n";
|
infoSink.debug << "gl_FragCoord origin is upper left\n";
|
||||||
if (earlyFragmentTests)
|
if (earlyFragmentTests)
|
||||||
infoSink.debug << "using early_fragment_tests\n";
|
infoSink.debug << "using early_fragment_tests\n";
|
||||||
|
if (depthLayout != EldNone)
|
||||||
|
infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
|
|||||||
@ -83,6 +83,11 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
if (! earlyFragmentTests)
|
if (! earlyFragmentTests)
|
||||||
earlyFragmentTests = unit.earlyFragmentTests;
|
earlyFragmentTests = unit.earlyFragmentTests;
|
||||||
|
|
||||||
|
if (depthLayout == EldNone)
|
||||||
|
depthLayout = unit.depthLayout;
|
||||||
|
else if (depthLayout != unit.depthLayout)
|
||||||
|
error(infoSink, "Contradictory depth layouts");
|
||||||
|
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
inputPrimitive = unit.inputPrimitive;
|
inputPrimitive = unit.inputPrimitive;
|
||||||
else if (inputPrimitive != unit.inputPrimitive)
|
else if (inputPrimitive != unit.inputPrimitive)
|
||||||
|
|||||||
@ -112,7 +112,7 @@ public:
|
|||||||
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v),
|
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v),
|
||||||
numMains(0), numErrors(0), recursive(false),
|
numMains(0), numErrors(0), recursive(false),
|
||||||
invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false),
|
invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false),
|
||||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), xfbMode(false)
|
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), depthLayout(EldNone), xfbMode(false)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
@ -250,6 +250,14 @@ public:
|
|||||||
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
||||||
void setEarlyFragmentTests() { earlyFragmentTests = true; }
|
void setEarlyFragmentTests() { earlyFragmentTests = true; }
|
||||||
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
|
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
|
||||||
|
bool setDepth(TLayoutDepth d)
|
||||||
|
{
|
||||||
|
if (depthLayout != EldNone)
|
||||||
|
return depthLayout == d;
|
||||||
|
depthLayout = d;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
TLayoutDepth getDepth() const { return depthLayout; }
|
||||||
|
|
||||||
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
||||||
void merge(TInfoSink&, TIntermediate&);
|
void merge(TInfoSink&, TIntermediate&);
|
||||||
@ -304,6 +312,7 @@ protected:
|
|||||||
bool pointMode;
|
bool pointMode;
|
||||||
int localSize[3];
|
int localSize[3];
|
||||||
bool earlyFragmentTests;
|
bool earlyFragmentTests;
|
||||||
|
TLayoutDepth depthLayout;
|
||||||
bool xfbMode;
|
bool xfbMode;
|
||||||
|
|
||||||
typedef std::list<TCall> TGraph;
|
typedef std::list<TCall> TGraph;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user