Skip to content
Snippets Groups Projects
Commit fb57e7cc authored by John Kessenich's avatar John Kessenich
Browse files

Add ES 3.0 fragment output link-time test for outputs having or not having location qualifiers.

Also split linker validation into its own file, removed dead "QualifierAlive" files, printed errors for parsing problems with built-in symbols,  updated the Windows binary, and added some tests.


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23490 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent 27b72e42
No related branches found
No related tags found
No related merge requests found
Showing
with 167 additions and 430 deletions
No preview for this file type
#version 150 core
in vec4 iv4;
uniform float ps;
invariant gl_Position;
void main()
{
gl_Position = iv4;
gl_PointSize = ps;
gl_ClipDistance[2] = iv4.x;
}
float gl_ClipDistance[4];
uniform foob {
int a[];
};
int a[5]; // ERROR, resizing user-block member
#version 300 es
precision highp float;
out vec4 color1;
out vec4 color2;
void main() {}
#version 300 es
precision mediump float;
in vec4 pos;
layout(location = 1) out vec4 c;
layout(location = 5) out vec4 p;
layout(location = 9) out vec4 q[2];
void main()
{
}
#version 300 es
precision highp float;
out vec4 color1;
void main() {}
#version 410 core
void main()
{
gl_ViewportIndex = 7;
}
Warning, version 150 is not yet complete; some version-specific features are present, but many are missing.
ERROR: 0:13: 'gl_ClipDistance' : undeclared identifier
ERROR: 0:13: 'gl_ClipDistance' : left of '[' is not of type array, matrix, or vector
ERROR: 0:13: 'assign' : l-value required (can't modify a const)
ERROR: 0:16: 'gl_' : reserved built-in name
ERROR: 0:21: 'a' : cannot redeclare a user-block member array
ERROR: 5 compilation errors. No code generated.
ERROR: node is still EOpNull!
0:9 Function Definition: main( (void)
0:9 Function Parameters:
0:11 Sequence
0:11 move second child to first child (4-component vector of float)
0:11 'gl_Position' (invariant gl_Position 4-component vector of float)
0:11 'iv4' (in 4-component vector of float)
0:12 move second child to first child (float)
0:12 'gl_PointSize' (gl_PointSize float)
0:12 'ps' (uniform float)
0:13 move second child to first child (float)
0:13 Constant:
0:13 0.000000
0:13 direct index (float)
0:13 'iv4' (in 4-component vector of float)
0:13 Constant:
0:13 0 (const int)
0:? Linker Objects
0:? 'iv4' (in 4-component vector of float)
0:? 'ps' (uniform float)
0:? 'gl_ClipDistance' (4-element array of float)
0:? '__anon__0' (layout(shared ) uniform block)
0:? 'gl_VertexID' (gl_VertexId int)
0:? 'gl_InstanceID' (gl_InstanceId int)
300link.frag
0:? Sequence
0:8 Function Definition: main( (void)
0:8 Function Parameters:
0:? Linker Objects
0:? 'color1' (out highp 4-component vector of float)
0:? 'color2' (out highp 4-component vector of float)
Linked fragment stage:
ERROR: Linking fragment stage: when more than one fragment shader output, all must have location qualifiers
300link2.frag
0:? Sequence
0:9 Function Definition: main( (void)
0:9 Function Parameters:
0:? Linker Objects
0:? 'pos' (smooth in mediump 4-component vector of float)
0:? 'c' (layout(location=1 ) out mediump 4-component vector of float)
0:? 'p' (layout(location=5 ) out mediump 4-component vector of float)
0:? 'q' (layout(location=9 ) out 2-element array of mediump 4-component vector of float)
Linked fragment stage:
300link3.frag
0:? Sequence
0:7 Function Definition: main( (void)
0:7 Function Parameters:
0:? Linker Objects
0:? 'color1' (out highp 4-component vector of float)
Linked fragment stage:
Warning, version 410 is not yet complete; some version-specific features are present, but many are missing.
ERROR: 0:5: 'gl_ViewportIndex' : undeclared identifier
ERROR: 1 compilation errors. No code generated.
ERROR: node is still EOpNull!
0:3 Function Definition: main( (void)
0:3 Function Parameters:
0:5 Sequence
0:5 move second child to first child (float)
0:5 'gl_ViewportIndex' (float)
0:5 Constant:
0:5 7.000000
0:? Linker Objects
...@@ -38,6 +38,9 @@ runLinkTest mains1.frag mains2.frag noMain1.geom noMain2.geom ...@@ -38,6 +38,9 @@ runLinkTest mains1.frag mains2.frag noMain1.geom noMain2.geom
runLinkTest noMain.vert mains.frag runLinkTest noMain.vert mains.frag
runLinkTest link1.frag link2.frag link3.frag runLinkTest link1.frag link2.frag link3.frag
runLinkTest recurse1.vert recurse1.frag recurse2.frag runLinkTest recurse1.vert recurse1.frag recurse2.frag
runLinkTest 300link.frag
runLinkTest 300link2.frag
runLinkTest 300link3.frag
# #
# multi-threaded test # multi-threaded test
......
...@@ -12,6 +12,7 @@ versionsErrors.vert ...@@ -12,6 +12,7 @@ versionsErrors.vert
120.frag 120.frag
130.frag 130.frag
140.frag 140.frag
150.vert
150.geom 150.geom
precision.frag precision.frag
precision.vert precision.vert
...@@ -52,6 +53,7 @@ numeral.frag ...@@ -52,6 +53,7 @@ numeral.frag
400.geom 400.geom
400.tesc 400.tesc
400.tese 400.tese
410.geom
420.tese 420.tese
430.comp 430.comp
dce.frag dce.frag
......
...@@ -8,25 +8,25 @@ Link Validation ...@@ -8,25 +8,25 @@ Link Validation
Cross-stage linking Cross-stage linking
- type consistency check of uniform and ins <-> outs, both variables and blocks, stage-specific arrayness matching - type consistency check of uniform and ins <-> outs, both variables and blocks, stage-specific arrayness matching
- location/binding/index check - location/binding/index check
- matching initializers for uniforms
- mixed es/non-es profiles - mixed es/non-es profiles
- statically consumed input not produced by previous stage - statically consumed input not produced by previous stage
- matching between gl_PerVertex blocks and gl_PerFragment blocks
- compute shader not combined with any other stages
- give error for sharing a packed block - give error for sharing a packed block
- 1.2: matching initializers for uniforms
- 1.5: matching between gl_PerVertex blocks and gl_PerFragment blocks
- 1.3: deprecated mixing fixed vertex/fragment stage with programmable fragment/vertex stage. - 1.3: deprecated mixing fixed vertex/fragment stage with programmable fragment/vertex stage.
- 4.3: compute shader not combined with any other stages
- 4.3: remove cross-version linking restrictions. - 4.3: remove cross-version linking restrictions.
- 4.3: Allow mismatches in interpolation and auxiliary qualification across stages. - 4.3: Allow mismatches in interpolation and auxiliary qualification across stages.
- 4.4: A stage contains two different blocks, each with no instance name, where the blocks contain a member with the same name. - 4.4: A stage contains two different blocks, each with no instance name, where the blocks contain a member with the same name.
Intra-stage linking Intra-stage linking
- ES 3.0: location aliasing/overlap (except desktop vertex shader inputs)
+ ES 3.0: fragment outputs all have locations, if more than one
+ exactly one main + exactly one main
+ Non ES: type consistency check of uniforms, globals, ins, and outs + Non ES: type consistency check of uniforms, globals, ins, and outs
+ Non ES: value checking of global const initializers + Non ES: value checking of global const initializers
+ Non ES: value checking of uniform initializers + Non ES: value checking of uniform initializers
+ Non ES: location match + Non ES: location match
- gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords - Non ES: gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords
- location aliasing/overlap (except desktop vertex shader inputs)
- 1.0: count the number of uniforms and varyings, compare against limits
+ recursion for functions + recursion for functions
- Non ES: block matching - Non ES: block matching
- Non ES: component/binding/index/offset match check - Non ES: component/binding/index/offset match check
...@@ -46,8 +46,8 @@ Link Validation ...@@ -46,8 +46,8 @@ Link Validation
Shader Functionality to Implement/Finish Shader Functionality to Implement/Finish
ESSL 2.0 (#version 100) ESSL 2.0 (#version 100)
- implement non-inductive loop limitation detection + implement non-inductive loop limitation detection
- implement non-inductive array accesses limitation detection + implement non-inductive array accesses limitation detection
ESSL 3.0 ESSL 3.0
- "const" compile-time constant propagation in the front-end has to be complete, for all built-in functions - "const" compile-time constant propagation in the front-end has to be complete, for all built-in functions
GLSL 1.2 GLSL 1.2
...@@ -72,7 +72,7 @@ Shader Functionality to Implement/Finish ...@@ -72,7 +72,7 @@ Shader Functionality to Implement/Finish
- Built-in uniforms except for depth range parameters - Built-in uniforms except for depth range parameters
- Built-in interface between vertex and fragment: gl_TexCoord, gl_FogFragCoord, and all the color values. - Built-in interface between vertex and fragment: gl_TexCoord, gl_FogFragCoord, and all the color values.
- Built-in two-sided coloring. - Built-in two-sided coloring.
- Fixed functionality for a programmable stage. Supply shaders for all stages currently being used. - Fixed functionality for a programmable stage.
- ftransform(). Use invariant outputs instead. - ftransform(). Use invariant outputs instead.
GLSL 1.5 (Non-ES) GLSL 1.5 (Non-ES)
- Deprecated gl_MaxVaryingComponents - Deprecated gl_MaxVaryingComponents
......
...@@ -157,6 +157,7 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command> ...@@ -157,6 +157,7 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" /> <ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" />
<ClCompile Include="glslang\MachineIndependent\Initialize.cpp" /> <ClCompile Include="glslang\MachineIndependent\Initialize.cpp" />
<ClCompile Include="glslang\MachineIndependent\limits.cpp" /> <ClCompile Include="glslang\MachineIndependent\limits.cpp" />
<ClCompile Include="glslang\MachineIndependent\linkValidate.cpp" />
<ClCompile Include="glslang\MachineIndependent\preprocessor\Pp.cpp" /> <ClCompile Include="glslang\MachineIndependent\preprocessor\Pp.cpp" />
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpAtom.cpp" /> <ClCompile Include="glslang\MachineIndependent\preprocessor\PpAtom.cpp" />
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpMemory.cpp" /> <ClCompile Include="glslang\MachineIndependent\preprocessor\PpMemory.cpp" />
...@@ -171,7 +172,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command> ...@@ -171,7 +172,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
<ClCompile Include="glslang\MachineIndependent\Intermediate.cpp" /> <ClCompile Include="glslang\MachineIndependent\Intermediate.cpp" />
<ClCompile Include="glslang\MachineIndependent\ParseHelper.cpp" /> <ClCompile Include="glslang\MachineIndependent\ParseHelper.cpp" />
<ClCompile Include="glslang\MachineIndependent\PoolAlloc.cpp" /> <ClCompile Include="glslang\MachineIndependent\PoolAlloc.cpp" />
<ClCompile Include="glslang\MachineIndependent\QualifierAlive.cpp" />
<ClCompile Include="glslang\MachineIndependent\RemoveTree.cpp" /> <ClCompile Include="glslang\MachineIndependent\RemoveTree.cpp" />
<ClCompile Include="glslang\MachineIndependent\ShaderLang.cpp" /> <ClCompile Include="glslang\MachineIndependent\ShaderLang.cpp" />
<ClCompile Include="glslang\MachineIndependent\SymbolTable.cpp" /> <ClCompile Include="glslang\MachineIndependent\SymbolTable.cpp" />
...@@ -192,7 +192,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command> ...@@ -192,7 +192,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
<ClInclude Include="glslang\MachineIndependent\ParseHelper.h" /> <ClInclude Include="glslang\MachineIndependent\ParseHelper.h" />
<ClInclude Include="glslang\MachineIndependent\preprocessor\PpContext.h" /> <ClInclude Include="glslang\MachineIndependent\preprocessor\PpContext.h" />
<ClInclude Include="glslang\MachineIndependent\preprocessor\PpTokens.h" /> <ClInclude Include="glslang\MachineIndependent\preprocessor\PpTokens.h" />
<ClInclude Include="glslang\MachineIndependent\QualifierAlive.h" />
<ClInclude Include="glslang\MachineIndependent\RemoveTree.h" /> <ClInclude Include="glslang\MachineIndependent\RemoveTree.h" />
<ClInclude Include="glslang\MachineIndependent\localintermediate.h" /> <ClInclude Include="glslang\MachineIndependent\localintermediate.h" />
<ClInclude Include="glslang\Include\BaseTypes.h" /> <ClInclude Include="glslang\Include\BaseTypes.h" />
......
...@@ -49,9 +49,6 @@ ...@@ -49,9 +49,6 @@
<ClCompile Include="glslang\MachineIndependent\PoolAlloc.cpp"> <ClCompile Include="glslang\MachineIndependent\PoolAlloc.cpp">
<Filter>Machine Independent</Filter> <Filter>Machine Independent</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="glslang\MachineIndependent\QualifierAlive.cpp">
<Filter>Machine Independent</Filter>
</ClCompile>
<ClCompile Include="glslang\MachineIndependent\RemoveTree.cpp"> <ClCompile Include="glslang\MachineIndependent\RemoveTree.cpp">
<Filter>Machine Independent</Filter> <Filter>Machine Independent</Filter>
</ClCompile> </ClCompile>
...@@ -112,6 +109,9 @@ ...@@ -112,6 +109,9 @@
<ClCompile Include="glslang\MachineIndependent\limits.cpp"> <ClCompile Include="glslang\MachineIndependent\limits.cpp">
<Filter>Machine Independent</Filter> <Filter>Machine Independent</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="glslang\MachineIndependent\linkValidate.cpp">
<Filter>Machine Independent</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="glslang\MachineIndependent\Initialize.h"> <ClInclude Include="glslang\MachineIndependent\Initialize.h">
...@@ -120,9 +120,6 @@ ...@@ -120,9 +120,6 @@
<ClInclude Include="glslang\MachineIndependent\ParseHelper.h"> <ClInclude Include="glslang\MachineIndependent\ParseHelper.h">
<Filter>Machine Independent</Filter> <Filter>Machine Independent</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="glslang\MachineIndependent\QualifierAlive.h">
<Filter>Machine Independent</Filter>
</ClInclude>
<ClInclude Include="glslang\MachineIndependent\RemoveTree.h"> <ClInclude Include="glslang\MachineIndependent\RemoveTree.h">
<Filter>Machine Independent</Filter> <Filter>Machine Independent</Filter>
</ClInclude> </ClInclude>
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
// //
#include "localintermediate.h" #include "localintermediate.h"
#include "QualifierAlive.h"
#include "RemoveTree.h" #include "RemoveTree.h"
#include "SymbolTable.h" #include "SymbolTable.h"
...@@ -928,275 +927,6 @@ void TIntermediate::addToCallGraph(TInfoSink& infoSink, const TString& caller, c ...@@ -928,275 +927,6 @@ void TIntermediate::addToCallGraph(TInfoSink& infoSink, const TString& caller, c
callGraph.push_front(TCall(caller, callee)); callGraph.push_front(TCall(caller, callee));
} }
//
// Merge the information from 'unit' into 'this'
//
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
{
numMains += unit.numMains;
numErrors += unit.numErrors;
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
if ((profile != EEsProfile && unit.profile == EEsProfile) ||
(profile == EEsProfile && unit.profile != EEsProfile))
error(infoSink, "Cannot mix ES profile with non-ES profile shaders\n");
if (unit.treeRoot == 0)
return;
if (treeRoot == 0) {
version = unit.version;
treeRoot = unit.treeRoot;
return;
} else
version = std::max(version, unit.version);
// Get the top-level globals of each level
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence();
// Get the last members of the sequences, expected to be the linker-object lists
assert(globals.back()->getAsAggregate()->getOp() == EOpLinkerObjects);
assert(unitGlobals.back()->getAsAggregate()->getOp() == EOpLinkerObjects);
TIntermSequence& linkerObjects = globals.back()->getAsAggregate()->getSequence();
TIntermSequence& unitLinkerObjects = unitGlobals.back()->getAsAggregate()->getSequence();
mergeBodies(infoSink, globals, unitGlobals);
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
}
//
// Merge the function bodies and global-level initalizers from unitGlobals into globals.
// Will error check duplication of function bodies for the same signature.
//
void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, const TIntermSequence& unitGlobals)
{
// TODO: Performance: Processing in alphabetical order will be faster
// Error check the global objects, not including the linker objects
for (unsigned int child = 0; child < globals.size() - 1; ++child) {
for (unsigned int unitChild = 0; unitChild < unitGlobals.size() - 1; ++unitChild) {
TIntermAggregate* body = globals[child]->getAsAggregate();
TIntermAggregate* unitBody = unitGlobals[unitChild]->getAsAggregate();
if (body && unitBody && body->getOp() == EOpFunction && unitBody->getOp() == EOpFunction && body->getName() == unitBody->getName()) {
error(infoSink, "Multiple function bodies in multiple compilation units for the same signature in the same stage:");
infoSink.info << " " << globals[child]->getAsAggregate()->getName() << "\n";
}
}
}
// Merge the global objects, just in front of the linker objects
globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1);
}
//
// Merge the linker objects from unitLinkerObjects into linkerObjects.
// Duplication is expected and filtered out, but contradictions are an error.
//
void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects)
{
// Error check and merge the linker objects (duplicates should not be merged)
std::size_t initialNumLinkerObjects = linkerObjects.size();
for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) {
bool merge = true;
for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
assert(symbol && unitSymbol);
if (symbol->getName() == unitSymbol->getName()) {
// filter out copy
merge = false;
// but if one has an initializer and the other does not, update
// the initializer
if (symbol->getConstArray().empty() && ! unitSymbol->getConstArray().empty())
symbol->setConstArray(unitSymbol->getConstArray());
// Check for consistent types/qualification/initializers etc.
linkErrorCheck(infoSink, *symbol, *unitSymbol, false);
}
}
if (merge)
linkerObjects.push_back(unitLinkerObjects[unitLinkObj]);
}
}
//
// Do final link-time error checking of a complete (merged) intermediate representation.
// (Most error checking was done during merging).
//
void TIntermediate::errorCheck(TInfoSink& infoSink)
{
if (numMains < 1)
error(infoSink, "Missing entry point: Each stage requires one \"void main()\" entry point");
checkCallGraphCycles(infoSink);
}
//
// See if the call graph contains any static recursion, which is disallowed
// by the specification.
//
void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink)
{
// Reset everything, once.
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
call->visited = false;
call->subGraph = false;
call->errorGiven = false;
}
//
// Loop, looking for a new connected subgraph. One subgraph is handled per loop iteration.
//
TCall* newRoot;
do {
// See if we have unvisited parts of the graph.
newRoot = 0;
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
if (! call->visited) {
newRoot = &(*call);
break;
}
}
// If not, we are done.
if (! newRoot)
break;
// Otherwise, we found a new subgraph, process it:
// See what all can be reached by this new root, and if any of
// that is recursive. This is done by marking processed calls as active,
// and if a new call is found that is already active, we looped,
// thereby detecting recursion.
std::list<TCall*> stack;
stack.push_back(newRoot);
newRoot->subGraph = true;
while (! stack.empty()) {
// get a caller
TCall* call = stack.back();
stack.pop_back();
// Add to the stack all the callees of the last subgraph node popped from the stack.
// This algorithm always terminates, because only subGraph == false causes a push
// and all pushes change subGraph to true, and nothing changes subGraph to false.
for (TGraph::iterator child = callGraph.begin(); child != callGraph.end(); ++child) {
if (call->callee == child->caller) {
if (child->subGraph) {
if (! child->errorGiven) {
error(infoSink, "Recursion detected:");
infoSink.info << " " << call->callee << " calling " << child->callee << "\n";
child->errorGiven = true;
}
} else {
child->subGraph = true;
stack.push_back(&(*child));
}
}
}
} // end while, meaning nothing left to process in this subtree
// Mark all the subGraph nodes as visited, closing out this subgraph.
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
if (call->subGraph)
call->visited = true;
}
} while (newRoot); // redundant loop check; should always exit via the 'break' above
}
void TIntermediate::error(TInfoSink& infoSink, const char* message)
{
infoSink.info.prefix(EPrefixError);
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
++numErrors;
}
//
// Compare two global objects from two compilation units and see if they match
// well enough. Rules can be different for intra- vs. cross-stage matching.
//
// This function only does one of intra- or cross-stage matching per call.
//
// TODO: Linker Functionality: this function is under active development
//
void TIntermediate::linkErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
{
bool writeTypeComparison = false;
// Types have to match
if (symbol.getType() != unitSymbol.getType()) {
error(infoSink, "Types must match:");
writeTypeComparison = true;
}
// Qualifiers have to (almost) match
// Storage...
if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
error(infoSink, "Storage qualifiers must match:");
writeTypeComparison = true;
}
// Precision...
if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
error(infoSink, "Precision qualifiers must match:");
writeTypeComparison = true;
}
// Invariance...
if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) {
error(infoSink, "Presence of invariant qualifier must match:");
writeTypeComparison = true;
}
// Auxiliary and interpolation...
if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid ||
symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth ||
symbol.getQualifier().flat != unitSymbol.getQualifier().flat ||
symbol.getQualifier().sample != unitSymbol.getQualifier().sample ||
symbol.getQualifier().patch != unitSymbol.getQualifier().patch ||
symbol.getQualifier().nopersp != unitSymbol.getQualifier().nopersp) {
error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
writeTypeComparison = true;
}
// Memory...
if (symbol.getQualifier().shared != unitSymbol.getQualifier().shared ||
symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
error(infoSink, "Memory qualifiers must match:");
writeTypeComparison = true;
}
// Layouts...
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
symbol.getQualifier().layoutSlotLocation != unitSymbol.getQualifier().layoutSlotLocation) {
error(infoSink, "Layout qualification must match:");
writeTypeComparison = true;
}
// Initializers have to match, if both are present, and if we don't already know the types don't match
if (! writeTypeComparison) {
if (! symbol.getConstArray().empty() && ! unitSymbol.getConstArray().empty()) {
if (symbol.getConstArray() != unitSymbol.getConstArray()) {
error(infoSink, "Initializers must match:");
infoSink.info << " " << symbol.getName() << "\n";
}
}
}
if (writeTypeComparison)
infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" <<
unitSymbol.getType().getCompleteString() << "\"\n";
}
// //
// This deletes the tree. // This deletes the tree.
// //
......
...@@ -9,12 +9,12 @@ LIBOSDEPENDENT=./../OSDependent/Linux/libOssource.a ...@@ -9,12 +9,12 @@ LIBOSDEPENDENT=./../OSDependent/Linux/libOssource.a
LIBINITIALISATION=./../../OGLCompilersDLL/libInitializeDll.a LIBINITIALISATION=./../../OGLCompilersDLL/libInitializeDll.a
LIBCODEGEN=./../GenericCodeGen/libCodeGen.a LIBCODEGEN=./../GenericCodeGen/libCodeGen.a
OBJECTS= Initialize.o IntermTraverse.o \ OBJECTS= Initialize.o IntermTraverse.o \
Intermediate.o ParseHelper.o PoolAlloc.o QualifierAlive.o \ Intermediate.o ParseHelper.o PoolAlloc.o \
RemoveTree.o ShaderLang.o intermOut.o parseConst.o SymbolTable.o \ RemoveTree.o ShaderLang.o intermOut.o parseConst.o SymbolTable.o \
InfoSink.o Versions.o Constant.o Scan.o limits.o InfoSink.o Versions.o Constant.o Scan.o limits.o linkValidate.o
SRCS= gen_glslang_tab.cpp Initialize.cpp IntermTraverse.cpp \ SRCS= gen_glslang_tab.cpp Initialize.cpp IntermTraverse.cpp \
Intermediate.cpp ParseHelper.cpp PoolAlloc.cp QualifierAlive.cpp \ Intermediate.cpp ParseHelper.cpp PoolAlloc.cp \
RemoveTree.cpp ShaderLang.cpp SymbolTable.cpp intermOut.cpp \ RemoveTree.cpp ShaderLang.cpp SymbolTable.cpp intermOut.cpp \
parseConst.cpp InfoSink.cpp Versions.cpp Constant.cpp Scan.cpp parseConst.cpp InfoSink.cpp Versions.cpp Constant.cpp Scan.cpp
CPPFLAGS=$(DEFINE) $(INCLUDE) -fPIC CPPFLAGS=$(DEFINE) $(INCLUDE) -fPIC
...@@ -98,7 +98,7 @@ Intermediate.o: localintermediate.h ../Include/intermediate.h ...@@ -98,7 +98,7 @@ Intermediate.o: localintermediate.h ../Include/intermediate.h
Intermediate.o: ../Public/ShaderLang.h SymbolTable.h ../Include/Common.h Intermediate.o: ../Public/ShaderLang.h SymbolTable.h ../Include/Common.h
Intermediate.o: ../Include/intermediate.h ../Include/Types.h Intermediate.o: ../Include/intermediate.h ../Include/Types.h
Intermediate.o: ../Include/BaseTypes.h ../Include/ConstantUnion.h Intermediate.o: ../Include/BaseTypes.h ../Include/ConstantUnion.h
Intermediate.o: ../Include/InfoSink.h QualifierAlive.h RemoveTree.h Intermediate.o: ../Include/InfoSink.h RemoveTree.h
ParseHelper.o: ParseHelper.h ../Include/ShHandle.h ParseHelper.o: ParseHelper.h ../Include/ShHandle.h
ParseHelper.o: ../Public/ShaderLang.h ../Include/InfoSink.h ParseHelper.o: ../Public/ShaderLang.h ../Include/InfoSink.h
ParseHelper.o: ../Include/Common.h ../Include/PoolAlloc.h SymbolTable.h ParseHelper.o: ../Include/Common.h ../Include/PoolAlloc.h SymbolTable.h
...@@ -109,7 +109,6 @@ ParseHelper.o: localintermediate.h ../Include/intermediate.h ...@@ -109,7 +109,6 @@ ParseHelper.o: localintermediate.h ../Include/intermediate.h
ParseHelper.o: ../Public/ShaderLang.h ParseHelper.o: ../Public/ShaderLang.h
ParseHelper.o: ../OSDependent/Linux/osinclude.h ParseHelper.o: ../OSDependent/Linux/osinclude.h
ParseHelper.o: ../Include/InitializeGlobals.h ../Include/PoolAlloc.h ParseHelper.o: ../Include/InitializeGlobals.h ../Include/PoolAlloc.h
QualifierAlive.o: ../Include/intermediate.h
Scan.o: Scan.h Scan.o: Scan.h
Scan.o: ParseHelper.h SymbolTable.h Scan.o: ParseHelper.h SymbolTable.h
Scan.o: glslang_tab.cpp.h Scan.o: glslang_tab.cpp.h
...@@ -147,3 +146,4 @@ InfoSink.o: ../Include/InfoSink.h ...@@ -147,3 +146,4 @@ InfoSink.o: ../Include/InfoSink.h
Versions.o: ParseHelper.h Versions.h ../Include/ShHandle.h SymbolTable.h localintermediate.h Versions.o: ParseHelper.h Versions.h ../Include/ShHandle.h SymbolTable.h localintermediate.h
Constant.o: localintermediate.h ../Include/intermediate.h ../Public/ShaderLang.h SymbolTable.h Versions.h Constant.o: localintermediate.h ../Include/intermediate.h ../Public/ShaderLang.h SymbolTable.h Versions.h
limits.o: ParseHelper.h limits.o: ParseHelper.h
linkValidate.o: localintermediate.h
//
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
//are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE.
//
#ifdef USE_QUALIFIER_ALIVE
#include "../Include/intermediate.h"
namespace glslang {
class TAliveTraverser : public TIntermTraverser {
public:
TAliveTraverser(TStorageQualifier q) : TIntermTraverser(), found(false), qualifier(q)
{
visitSymbol = AliveSymbol;
visitSelection = AliveSelection;
rightToLeft = true;
}
bool wasFound() { return found; }
protected:
bool found;
TStorageQualifier qualifier;
friend void AliveSymbol(TIntermSymbol*, TIntermTraverser*);
friend bool AliveSelection(bool, TIntermSelection*, TIntermTraverser*);
};
//
// Report whether or not a variable of the given qualifier type
// is guaranteed written. Not always possible to determine if
// it is written conditionally.
//
// It does not do this well yet, this is just a place holder
// that simply determines if it was reference at all, anywhere.
//
bool QualifierWritten(TIntermNode* node, TStorageQualifier qualifier)
{
TAliveTraverser it(qualifier);
if (node)
node->traverse(&it);
return it.wasFound();
}
void AliveSymbol(TIntermSymbol* node, TIntermTraverser* it)
{
TAliveTraverser* lit = static_cast<TAliveTraverser*>(it);
//
// If it's what we're looking for, record it.
//
if (node->getQualifier().storage == lit->qualifier)
lit->found = true;
}
bool AliveSelection(bool preVisit, TIntermSelection* node, TIntermTraverser* it)
{
TAliveTraverser* lit = static_cast<TAliveTraverser*>(it);
if (lit->wasFound())
return false;
return true;
}
} // end namespace glslang
#endif
//
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
//are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE.
//
namespace glslang {
bool QualifierWritten(TIntermNode* root, TStorageQualifier);
} // end namespace glslang
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment