Add array sizing/checking/overlapping semantics for tessellation inputs.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24594 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich
2013-12-20 18:36:27 +00:00
parent e8fe7b81d7
commit 08d182470b
8 changed files with 152 additions and 21 deletions

View File

@@ -42,4 +42,19 @@ layout(vertices = 5) out; // ERROR
void foo() void foo()
{ {
gl_out[4].gl_PointSize; // ERROR gl_out[4].gl_PointSize; // ERROR
} }
in vec2 ina; // ERROR, not array
in vec2 inb[];
in vec2 inc[18]; // ERROR, wrong size
in vec2 ind[gl_MaxPatchVertices];
#extension GL_ARB_separate_shader_objects : enable
layout(location = 3) in vec4 ivla[];
layout(location = 4) in vec4 ivlb[];
layout(location = 4) in vec4 ivlc[]; // ERROR
layout(location = 3) out vec4 ovla[];
layout(location = 4) out vec4 ovlb[];
layout(location = 4) out vec4 ovlc[]; // ERROR

View File

@@ -59,7 +59,7 @@ float gl_ClipDistance[1];
in gl_PerVertex in gl_PerVertex
{ {
float gl_ClipDistance[1]; float gl_ClipDistance[1];
} gl_in[gl_MaxPatchVertices]; } gl_in[];
layout(quads, cw) out; // ERROR layout(quads, cw) out; // ERROR
layout(triangles) out; // ERROR layout(triangles) out; // ERROR
@@ -70,3 +70,30 @@ layout(equal_spacing) out; // ERROR
layout(fractional_even_spacing) out; // ERROR layout(fractional_even_spacing) out; // ERROR
layout(point_mode) out; // ERROR layout(point_mode) out; // ERROR
in vec2 ina; // ERROR, not array
in vec2 inb[];
in vec2 inc[18]; // ERROR, wrong size
in vec2 ind[gl_MaxPatchVertices];
in testbla {
int f;
} bla; // ERROR, not array
in testblb {
int f;
} blb[];
in testblc {
int f;
} blc[18]; // ERROR wrong size
in testbld {
int f;
} bld[gl_MaxPatchVertices];
layout(location = 23) in vec4 ivla[];
layout(location = 24) in vec4 ivlb[];
layout(location = 24) in vec4 ivlc[]; // ERROR
layout(location = 23) out vec4 ovla[2];
layout(location = 24) out vec4 ovlb[2]; // ERROR

View File

@@ -219,7 +219,11 @@ ERROR: 0:10: 'patch' : can only use on output in tessellation-control shader
ERROR: 0:39: 'vertices' : can only apply to 'out' ERROR: 0:39: 'vertices' : can only apply to 'out'
ERROR: 0:40: 'vertices' : cannot change previously set layout value ERROR: 0:40: 'vertices' : cannot change previously set layout value
ERROR: 0:44: '[' : array index out of range '4' ERROR: 0:44: '[' : array index out of range '4'
ERROR: 7 compilation errors. No code generated. ERROR: 0:47: 'in' : type must be an array: ina
ERROR: 0:49: '[]' : tessellation input array size must be gl_MaxPatchVertices or unsized
ERROR: 0:56: 'location' : repeated use of location 4
ERROR: 0:60: 'location' : repeated use of location 4
ERROR: 11 compilation errors. No code generated.
vertices = 4 vertices = 4
@@ -337,6 +341,16 @@ ERROR: node is still EOpNull!
0:? 'patchIn' (patch in 4-component vector of float) 0:? 'patchIn' (patch in 4-component vector of float)
0:? 'patchOut' (patch out 4-component vector of float) 0:? 'patchOut' (patch out 4-component vector of float)
0:? 'gl_out' (out 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance}) 0:? 'gl_out' (out 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
0:? 'ina' (in 2-component vector of float)
0:? 'inb' (in 32-element array of 2-component vector of float)
0:? 'inc' (in 32-element array of 2-component vector of float)
0:? 'ind' (in 32-element array of 2-component vector of float)
0:? 'ivla' (layout(location=3 ) in 32-element array of 4-component vector of float)
0:? 'ivlb' (layout(location=4 ) in 32-element array of 4-component vector of float)
0:? 'ivlc' (layout(location=4 ) in 32-element array of 4-component vector of float)
0:? 'ovla' (layout(location=3 ) out 4-element array of 4-component vector of float)
0:? 'ovlb' (layout(location=4 ) out 4-element array of 4-component vector of float)
0:? 'ovlc' (layout(location=4 ) out 4-element array of 4-component vector of float)
400.tese 400.tese
Warning, version 400 is not yet complete; some version-specific features are present, but many are missing. Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.
@@ -363,7 +377,13 @@ ERROR: 0:68: 'fractional_odd_spacing' : can only apply to 'in'
ERROR: 0:69: 'equal_spacing' : can only apply to 'in' ERROR: 0:69: 'equal_spacing' : can only apply to 'in'
ERROR: 0:70: 'fractional_even_spacing' : can only apply to 'in' ERROR: 0:70: 'fractional_even_spacing' : can only apply to 'in'
ERROR: 0:71: 'point_mode' : can only apply to 'in' ERROR: 0:71: 'point_mode' : can only apply to 'in'
ERROR: 23 compilation errors. No code generated. ERROR: 0:73: 'in' : type must be an array: ina
ERROR: 0:75: '[]' : tessellation input array size must be gl_MaxPatchVertices or unsized
ERROR: 0:78: 'in' : type must be an array: bla
ERROR: 0:86: '[]' : tessellation input array size must be gl_MaxPatchVertices or unsized
ERROR: 0:96: 'location' : repeated use of location 24
ERROR: 0:99: 'location' : repeated use of location 24
ERROR: 29 compilation errors. No code generated.
input primitive = quads input primitive = quads
@@ -469,6 +489,19 @@ ERROR: node is still EOpNull!
0:? 'badp3' (noperspective patch in 4-component vector of float) 0:? 'badp3' (noperspective patch in 4-component vector of float)
0:? 'badp4' (patch sample in 3-component vector of float) 0:? 'badp4' (patch sample in 3-component vector of float)
0:? 'gl_in' (in 32-element array of block{gl_ClipDistance}) 0:? 'gl_in' (in 32-element array of block{gl_ClipDistance})
0:? 'ina' (in 2-component vector of float)
0:? 'inb' (in 32-element array of 2-component vector of float)
0:? 'inc' (in 32-element array of 2-component vector of float)
0:? 'ind' (in 32-element array of 2-component vector of float)
0:? 'bla' (in block{f})
0:? 'blb' (in 32-element array of block{f})
0:? 'blc' (in 32-element array of block{f})
0:? 'bld' (in 32-element array of block{f})
0:? 'ivla' (layout(location=23 ) in 32-element array of 4-component vector of float)
0:? 'ivlb' (layout(location=24 ) in 32-element array of 4-component vector of float)
0:? 'ivlc' (layout(location=24 ) in 32-element array of 4-component vector of float)
0:? 'ovla' (layout(location=23 ) out 2-element array of 4-component vector of float)
0:? 'ovlb' (layout(location=24 ) out 2-element array of 4-component vector of float)
410.tesc 410.tesc
Warning, version 400 is not yet complete; some version-specific features are present, but many are missing. Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.
@@ -1036,6 +1069,16 @@ vertices = 4
0:? 'patchOut' (patch out 4-component vector of float) 0:? 'patchOut' (patch out 4-component vector of float)
0:? 'gl_out' (out 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance}) 0:? 'gl_out' (out 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})
0:? 'patchIn' (patch in 4-component vector of float) 0:? 'patchIn' (patch in 4-component vector of float)
0:? 'ina' (in 2-component vector of float)
0:? 'inb' (in 32-element array of 2-component vector of float)
0:? 'inc' (in 32-element array of 2-component vector of float)
0:? 'ind' (in 32-element array of 2-component vector of float)
0:? 'ivla' (layout(location=3 ) in 32-element array of 4-component vector of float)
0:? 'ivlb' (layout(location=4 ) in 32-element array of 4-component vector of float)
0:? 'ivlc' (layout(location=4 ) in 32-element array of 4-component vector of float)
0:? 'ovla' (layout(location=3 ) out 4-element array of 4-component vector of float)
0:? 'ovlb' (layout(location=4 ) out 4-element array of 4-component vector of float)
0:? 'ovlc' (layout(location=4 ) out 4-element array of 4-component vector of float)
0:? 'a' (out 3-element array of int) 0:? 'a' (out 3-element array of int)
0:? 'outb' (out 5-element array of int) 0:? 'outb' (out 5-element array of int)
0:? 'outc' (out 4-element array of int) 0:? 'outc' (out 4-element array of int)
@@ -1307,6 +1350,19 @@ ERROR: node is still EOpNull!
0:? 'badp3' (noperspective patch in 4-component vector of float) 0:? 'badp3' (noperspective patch in 4-component vector of float)
0:? 'badp4' (patch sample in 3-component vector of float) 0:? 'badp4' (patch sample in 3-component vector of float)
0:? 'gl_in' (in 32-element array of block{gl_ClipDistance}) 0:? 'gl_in' (in 32-element array of block{gl_ClipDistance})
0:? 'ina' (in 2-component vector of float)
0:? 'inb' (in 32-element array of 2-component vector of float)
0:? 'inc' (in 32-element array of 2-component vector of float)
0:? 'ind' (in 32-element array of 2-component vector of float)
0:? 'bla' (in block{f})
0:? 'blb' (in 32-element array of block{f})
0:? 'blc' (in 32-element array of block{f})
0:? 'bld' (in 32-element array of block{f})
0:? 'ivla' (layout(location=23 ) in 32-element array of 4-component vector of float)
0:? 'ivlb' (layout(location=24 ) in 32-element array of 4-component vector of float)
0:? 'ivlc' (layout(location=24 ) in 32-element array of 4-component vector of float)
0:? 'ovla' (layout(location=23 ) out 2-element array of 4-component vector of float)
0:? 'ovlb' (layout(location=24 ) out 2-element array of 4-component vector of float)
0:? 'a' (const 2X2 matrix of float) 0:? 'a' (const 2X2 matrix of float)
0:? 1.000000 0:? 1.000000
0:? 0.000000 0:? 0.000000

View File

@@ -3,6 +3,7 @@
TARGETDIR=localResults TARGETDIR=localResults
BASEDIR=baseResults BASEDIR=baseResults
EXE=./glslangValidator.exe EXE=./glslangValidator.exe
mkdir -p localResults
# #
# configuration file tests # configuration file tests

View File

@@ -9,5 +9,5 @@
// source have to figure out how to create revision.h just to get a build // source have to figure out how to create revision.h just to get a build
// going. However, if it is not updated, it can be a version behind. // going. However, if it is not updated, it can be a version behind.
#define GLSLANG_REVISION "24551" #define GLSLANG_REVISION "24569"
#define GLSLANG_DATE "2013/12/17 20:06:24" #define GLSLANG_DATE "2013/12/18 11:47:12"

View File

@@ -518,9 +518,9 @@ void TParseContext::handleIndexLimits(TSourceLoc loc, TIntermTyped* base, TInter
(! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) || (! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) ||
(! limits.generalConstantMatrixVectorIndexing && base->getAsConstantUnion()) || (! limits.generalConstantMatrixVectorIndexing && base->getAsConstantUnion()) ||
(! limits.generalVariableIndexing && ! base->getType().getQualifier().isUniform() && (! limits.generalVariableIndexing && ! base->getType().getQualifier().isUniform() &&
! base->getType().getQualifier().isPipeInput() && ! base->getType().getQualifier().isPipeInput() &&
! base->getType().getQualifier().isPipeOutput() && ! base->getType().getQualifier().isPipeOutput() &&
base->getType().getQualifier().storage != EvqConst) || base->getType().getQualifier().storage != EvqConst) ||
(! limits.generalVaryingIndexing && (base->getType().getQualifier().isPipeInput() || (! limits.generalVaryingIndexing && (base->getType().getQualifier().isPipeInput() ||
base->getType().getQualifier().isPipeOutput()))) { base->getType().getQualifier().isPipeOutput()))) {
// it's too early to know what the inductive variables are, save it for post processing // it's too early to know what the inductive variables are, save it for post processing
@@ -536,14 +536,35 @@ bool TParseContext::isIoResizeArray(const TType& type) const
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch)); (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch));
} }
// If an array is not isIoResizeArray() but is an io array, make sure it has the right size
void TParseContext::fixIoArraySize(TSourceLoc loc, TType& type)
{
if (! type.isArray() || type.getQualifier().patch || symbolTable.atBuiltInLevel())
return;
assert(! isIoResizeArray(type));
if (type.getQualifier().storage != EvqVaryingIn || type.getQualifier().patch)
return;
if (language == EShLangTessControl || language == EShLangTessEvaluation) {
if (type.getArraySize() != resources.maxPatchVertices) {
if (type.getArraySize() != 0)
error(loc, "tessellation input array size must be gl_MaxPatchVertices or unsized", "[]", "");
type.changeArraySize(resources.maxPatchVertices);
}
}
}
// Issue any errors if the non-array object is missing arrayness WRT // Issue any errors if the non-array object is missing arrayness WRT
// shader I/O that has array requirements. // shader I/O that has array requirements.
// All arrayness checking is handled in array paths, this is for // All arrayness checking is handled in array paths, this is for
void TParseContext::ioArrayCheck(TSourceLoc loc, const TType& type, const TString& identifier) void TParseContext::ioArrayCheck(TSourceLoc loc, const TType& type, const TString& identifier)
{ {
if (! type.isArray() && ! symbolTable.atBuiltInLevel()) { if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
if ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) || if ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch)) (language == EShLangTessControl && (type.getQualifier().storage == EvqVaryingOut || type.getQualifier().storage == EvqVaryingIn) && ! type.getQualifier().patch) ||
(language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn && ! type.getQualifier().patch))
error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str()); error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
} }
} }
@@ -2067,9 +2088,12 @@ void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TTyp
symbolTable.insert(*symbol); symbolTable.insert(*symbol);
newDeclaration = true; newDeclaration = true;
if (! symbolTable.atBuiltInLevel() && isIoResizeArray(type)) { if (! symbolTable.atBuiltInLevel()) {
ioArraySymbolResizeList.push_back(symbol); if (isIoResizeArray(type)) {
checkIoArraysConsistency(loc, true); ioArraySymbolResizeList.push_back(symbol);
checkIoArraysConsistency(loc, true);
} else
fixIoArraySize(loc, symbol->getWritableType());
} }
return; return;
@@ -2410,7 +2434,8 @@ void TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& newTypeList
if (isIoResizeArray(block->getType())) { if (isIoResizeArray(block->getType())) {
ioArraySymbolResizeList.push_back(block); ioArraySymbolResizeList.push_back(block);
checkIoArraysConsistency(loc, true); checkIoArraysConsistency(loc, true);
} } else if (block->getType().isArray())
fixIoArraySize(loc, block->getWritableType());
// Save it in the AST for linker use. // Save it in the AST for linker use.
intermediate.addSymbolLinkageNode(linkage, *block); intermediate.addSymbolLinkageNode(linkage, *block);
@@ -3754,7 +3779,8 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
if (isIoResizeArray(blockType)) { if (isIoResizeArray(blockType)) {
ioArraySymbolResizeList.push_back(&variable); ioArraySymbolResizeList.push_back(&variable);
checkIoArraysConsistency(loc, true); checkIoArraysConsistency(loc, true);
} } else
fixIoArraySize(loc, variable.getWritableType());
// Save it in the AST for linker use. // Save it in the AST for linker use.
intermediate.addSymbolLinkageNode(linkage, variable); intermediate.addSymbolLinkageNode(linkage, variable);

View File

@@ -86,6 +86,7 @@ public:
void handleIndexLimits(TSourceLoc, TIntermTyped* base, TIntermTyped* index); void handleIndexLimits(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
bool isIoResizeArray(const TType&) const; bool isIoResizeArray(const TType&) const;
void fixIoArraySize(TSourceLoc, TType&);
void ioArrayCheck(TSourceLoc, const TType&, const TString& identifier); void ioArrayCheck(TSourceLoc, const TType&, const TString& identifier);
void handleIoResizeArrayAccess(TSourceLoc, TIntermTyped* base); void handleIoResizeArrayAccess(TSourceLoc, TIntermTyped* base);
void checkIoArraysConsistency(TSourceLoc, bool tailOnly = false); void checkIoArraysConsistency(TSourceLoc, bool tailOnly = false);

View File

@@ -500,9 +500,10 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
else else
size = 1; size = 1;
} else { } else {
if (type.isArray() && if (type.isArray() && ! qualifier.patch &&
(language == EShLangGeometry && qualifier.isPipeInput() || (language == EShLangGeometry && qualifier.isPipeInput()) ||
(language == EShLangTessControl && qualifier.isPipeOutput() && ! qualifier.patch))) { language == EShLangTessControl ||
(language == EShLangTessEvaluation && qualifier.isPipeInput())) {
TType elementType(type, 0); TType elementType(type, 0);
size = computeTypeLocationSize(elementType); size = computeTypeLocationSize(elementType);
} else } else
@@ -534,8 +535,12 @@ int TIntermediate::computeTypeLocationSize(const TType& type)
// "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n // "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n
// consecutive locations..." // consecutive locations..."
if (type.isArray()) { if (type.isArray()) {
TType elementType(type, 0); TType elementType(type, 0);
return type.getArraySize() * computeTypeLocationSize(elementType); if (type.getArraySize() == 0) {
// TODO: are there valid cases of having an unsized array with a location? If so, running this code too early.
return computeTypeLocationSize(elementType);
} else
return type.getArraySize() * computeTypeLocationSize(elementType);
} }
// "The locations consumed by block and structure members are determined by applying the rules above // "The locations consumed by block and structure members are determined by applying the rules above