Commit c7776ec3 by John Kessenich

GL_ARB_enhanced_layouts, part 4: Numerical side of xfb_*: offset computation,…

GL_ARB_enhanced_layouts, part 4: Numerical side of xfb_*: offset computation, size computation, alias detection, paddings, overflow, implicit strides, gl_Max* checks, etc. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@25014 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent f359199c
......@@ -192,6 +192,8 @@ const char* DefaultConfig =
"MaxFragmentAtomicCounterBuffers 1\n"
"MaxCombinedAtomicCounterBuffers 1\n"
"MaxAtomicCounterBufferSize 16384\n"
"MaxTransformFeedbackBuffers 4\n"
"MaxTransformFeedbackInterleavedComponents 64\n"
"nonInductiveForLoops 1\n"
"whileLoops 1\n"
......@@ -390,6 +392,10 @@ void ProcessConfigFile()
Resources.maxCombinedAtomicCounterBuffers = value;
else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
Resources.maxAtomicCounterBufferSize = value;
else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
Resources.maxTransformFeedbackBuffers = value;
else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
Resources.maxTransformFeedbackInterleavedComponents = value;
else if (strcmp(token, "nonInductiveForLoops") == 0)
Resources.limits.nonInductiveForLoops = (value != 0);
......
......@@ -48,8 +48,8 @@ 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
#extension GL_ARB_separate_shader_objects : enable
layout(location = 3) in vec4 ivla[];
layout(location = 4) in vec4 ivlb[];
......
......@@ -68,31 +68,94 @@ out bblck1 {
} bbinst1;
out bblck2 {
layout(xfb_offset=16) vec4 bbv;
layout(xfb_offset=64) vec4 bbv;
} bbinst2;
layout(xfb_buffer = 3, xfb_stride = 16) out;
layout(xfb_buffer = 3, xfb_stride = 64) out; // default buffer is 3
out bblck3 {
layout(xfb_offset=16) vec4 bbv;
layout(xfb_offset=16) vec4 bbv; // in xfb_buffer 3
} bbinst3;
uniform ubblck3 {
layout(xfb_offset=16) vec4 bbv; // ERROR
layout(xfb_offset=16) vec4 bbv; // ERROR, not in a uniform
} ubbinst3;
layout(xfb_buffer=2, xfb_offset=32, xfb_stride=64) out vec4 bg;
layout(xfb_buffer=2, xfb_offset=48, xfb_stride=80) out vec4 bg;
layout( xfb_offset=32, xfb_stride=64) out vec4 bh;
layout(xfb_offset=48) out; // ERROR
layout(xfb_stride=32, xfb_buffer=2, xfb_offset=16) out bblck4 {
layout(xfb_stride=80, xfb_buffer=2, xfb_offset=16) out bblck4 {
vec4 bbv1;
vec4 bbv2;
} bbinst4;
out bblck5 {
layout(xfb_offset=0) vec4 bbv1;
layout(xfb_stride=32, xfb_buffer=3, xfb_offset=16) vec4 bbv2;
layout(xfb_stride=64, xfb_buffer=3, xfb_offset=48) vec4 bbv2;
layout(xfb_buffer=2) vec4 bbv3; // ERROR, wrong buffer
} bbinst5;
out layout(xfb_buffer=2) bblck6 {
layout(xfb_offset=0) vec4 bbv1;
layout(xfb_stride=64, xfb_buffer=3, xfb_offset=32) vec4 bbv2; // ERROR, overlap 32 from bh, and buffer contradiction
layout(xfb_buffer=2, xfb_offset=0) vec4 bbv3; // ERROR, overlap 0 from bbinst5
layout(xfb_buffer=2) vec4 bbv5;
layout(xfb_offset=24) float bbf6; // ERROR, overlap 24 from bbv1 in bbinst4
} bbinst6;
layout(xfb_stride=48) out; // ERROR, stride of buffer 3
layout(xfb_buffer=1) out; // default buffer is 1
layout(xfb_offset=4) out float bj;
layout(xfb_offset=0) out ivec2 bk; // ERROR, overlap 4
layout(xfb_buffer=3, xfb_stride=48) out; // ERROR, stride of buffer 3 (default is now 3)
layout(xfb_stride=48) out float bl; // ERROR, stride of buffer 3
layout(xfb_stride=48) out bblck7 { // ERROR, stride of buffer 3
layout(xfb_stride=64) vec4 bbv1;
layout(xfb_stride=32) vec4 bbv2; // ERROR, stride of buffer 3
} bbinst7;
struct S5 {
int i; // 4 bytes plus 4 byte hole
double d; // 8 bytes
float f; // 4 bytes
}; // total size = 20
struct T {
bool b; // 4 plus 4 byte hole
S5 s; // 20
vec2 v2; // 8
}; // total size = 36
out layout(xfb_buffer=0, xfb_offset=0, xfb_stride=92) bblck8 { // ERROR, stride not multiple of 8
bool b; // offset 0
T t; // offset 8, size 40
int i; // offset 40 + 4 = 48
mat3x3 m3; // offset 52
float f; // offset 52 + 9*4 = 88
float g; // ERROR, overflow stride
} bbinst8;
out layout(xfb_buffer=4) bblck9 {
layout(xfb_offset=1) bool b; // ERROR
layout(xfb_offset=12) T t; // ERROR
layout(xfb_offset=52) mat3x3 m3; // non-multiple of 8 okay
layout(xfb_offset=90) int i; // ERROR
layout(xfb_offset=98) double d; // ERROR
layout(xfb_offset=108) S s; // non-multiple of 8 okay
} bbinst9;
layout(xfb_buffer=5, xfb_stride=6) out; // link ERROR, stride not multiple of 4
layout(xfb_offset=0) out float bm;
layout(xfb_buffer=6, xfb_stride=2000) out; // ERROR, stride too big
out layout(xfb_buffer=7, xfb_offset=0) bblck10 { // link ERROR, implicit stride too big
dmat4x4 m1;
dmat4x4 m2;
float f;
} bbinst10;
......@@ -22,7 +22,27 @@ ERROR: 0:61: 'location' : cannot declare a default, use a full declaration
ERROR: 0:81: 'xfb layout qualifier' : can only be used on an output
ERROR: 0:87: 'xfb_offset' : cannot declare a default, use a full declaration
ERROR: 0:97: 'xfb_buffer' : member cannot contradict block (or what block inherited from global)
ERROR: 22 compilation errors. No code generated.
ERROR: 0:102: 'xfb_buffer' : member cannot contradict block (or what block inherited from global)
ERROR: 0:102: 'xfb_offset' : overlapping offsets at offset 32 in buffer 3
ERROR: 0:103: 'xfb_offset' : overlapping offsets at offset 0 in buffer 2
ERROR: 0:105: 'xfb_offset' : overlapping offsets at offset 24 in buffer 2
ERROR: 0:108: 'xfb_stride' : all stride settings must match for xfb buffer 15
ERROR: 0:112: 'xfb_offset' : overlapping offsets at offset 4 in buffer 1
ERROR: 0:114: 'xfb_stride' : all stride settings must match for xfb buffer 3
ERROR: 0:115: 'xfb_stride' : all stride settings must match for xfb buffer 3
ERROR: 0:119: 'xfb_stride' : all stride settings must match for xfb buffer 3
ERROR: 0:117: 'xfb_stride' : all stride settings must match for xfb buffer 3
ERROR: 0:138: 'xfb_offset' : overlapping offsets at offset 64 in buffer 0
ERROR: 0:143: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
ERROR: 0:144: 'xfb_offset' : must be a multiple of size of first component
ERROR: 0:145: 'xfb_offset' : type contains double; xfb_offset must be a multiple of 8
ERROR: 0:147: 'xfb_offset' : must be a multiple of size of first component
ERROR: 0:148: 'xfb_offset' : type contains double; xfb_offset must be a multiple of 8
ERROR: 0:152: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
ERROR: 0:155: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
ERROR: 0:155: 'xfb_stride' : 1/4 stride is too large: gl_MaxTransformFeedbackInterleavedComponents is 64
ERROR: 0:157: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
ERROR: 42 compilation errors. No code generated.
in xfb mode
......@@ -60,13 +80,22 @@ ERROR: node is still EOpNull!
0:? 'be' (layout(location=50 component=3 ) smooth out int)
0:? 'bf' (layout(location=50 component=0 ) smooth out 3-component vector of float)
0:? 'bbinst1' (out block{out 4-component vector of float bbv})
0:? 'bbinst2' (out block{layout(xfb_buffer=0 xfb_offset=16 ) out 4-component vector of float bbv})
0:? 'bbinst2' (out block{layout(xfb_buffer=0 xfb_offset=64 ) out 4-component vector of float bbv})
0:? 'bbinst3' (out block{layout(xfb_buffer=3 xfb_offset=16 ) out 4-component vector of float bbv})
0:? 'ubbinst3' (layout(column_major shared ) uniform block{layout(column_major shared xfb_offset=16 ) uniform 4-component vector of float bbv})
0:? 'bg' (layout(xfb_buffer=2 xfb_offset=32 xfb_stride=64 ) smooth out 4-component vector of float)
0:? 'bg' (layout(xfb_buffer=2 xfb_offset=48 xfb_stride=80 ) smooth out 4-component vector of float)
0:? 'bh' (layout(xfb_buffer=3 xfb_offset=32 xfb_stride=64 ) smooth out 4-component vector of float)
0:? 'bbinst4' (layout(xfb_buffer=2 xfb_offset=16 xfb_stride=32 ) out block{layout(xfb_buffer=2 xfb_offset=16 ) out 4-component vector of float bbv1, layout(xfb_buffer=2 xfb_offset=16 ) out 4-component vector of float bbv2})
0:? 'bbinst5' (out block{layout(xfb_buffer=3 xfb_offset=0 ) out 4-component vector of float bbv1, layout(xfb_buffer=3 xfb_offset=16 xfb_stride=32 ) out 4-component vector of float bbv2, out 4-component vector of float bbv3})
0:? 'bbinst4' (layout(xfb_stride=80 ) out block{layout(xfb_buffer=2 xfb_offset=16 ) out 4-component vector of float bbv1, layout(xfb_buffer=2 xfb_offset=32 ) out 4-component vector of float bbv2})
0:? 'bbinst5' (out block{layout(xfb_buffer=3 xfb_offset=0 ) out 4-component vector of float bbv1, layout(xfb_buffer=3 xfb_offset=48 xfb_stride=64 ) out 4-component vector of float bbv2, out 4-component vector of float bbv3})
0:? 'bbinst6' (out block{layout(xfb_buffer=2 xfb_offset=0 ) out 4-component vector of float bbv1, layout(xfb_buffer=3 xfb_offset=32 xfb_stride=64 ) out 4-component vector of float bbv2, layout(xfb_buffer=2 xfb_offset=0 ) out 4-component vector of float bbv3, out 4-component vector of float bbv5, layout(xfb_buffer=2 xfb_offset=24 ) out float bbf6})
0:? 'bj' (layout(xfb_buffer=1 xfb_offset=4 ) smooth out float)
0:? 'bk' (layout(xfb_buffer=1 xfb_offset=0 ) smooth out 2-component vector of int)
0:? 'bl' (layout(xfb_stride=48 ) smooth out float)
0:? 'bbinst7' (layout(xfb_stride=48 ) out block{layout(xfb_stride=64 ) out 4-component vector of float bbv1, layout(xfb_stride=32 ) out 4-component vector of float bbv2})
0:? 'bbinst8' (layout(xfb_stride=92 ) out block{layout(xfb_buffer=0 xfb_offset=0 ) out bool b, layout(xfb_buffer=0 xfb_offset=8 ) out structure{bool b, structure{int i, double d, float f} s, 2-component vector of float v2} t, layout(xfb_buffer=0 xfb_offset=48 ) out int i, layout(xfb_buffer=0 xfb_offset=52 ) out 3X3 matrix of float m3, layout(xfb_buffer=0 xfb_offset=88 ) out float f, layout(xfb_buffer=0 xfb_offset=92 ) out float g})
0:? 'bbinst9' (out block{layout(xfb_buffer=4 xfb_offset=1 ) out bool b, layout(xfb_buffer=4 xfb_offset=12 ) out structure{bool b, structure{int i, double d, float f} s, 2-component vector of float v2} t, layout(xfb_buffer=4 xfb_offset=52 ) out 3X3 matrix of float m3, layout(xfb_buffer=4 xfb_offset=90 ) out int i, layout(xfb_buffer=4 xfb_offset=98 ) out double d, layout(xfb_buffer=4 xfb_offset=108 ) out structure{int a} s})
0:? 'bm' (layout(xfb_buffer=5 xfb_offset=0 ) smooth out float)
0:? 'bbinst10' (out block{layout(xfb_buffer=7 xfb_offset=0 ) out 4X4 matrix of double m1, layout(xfb_buffer=7 xfb_offset=128 ) out 4X4 matrix of double m2, layout(xfb_buffer=7 xfb_offset=256 ) out float f})
0:? 'gl_VertexID' (gl_VertexId int)
0:? 'gl_InstanceID' (gl_InstanceId int)
......@@ -74,6 +103,14 @@ ERROR: node is still EOpNull!
Linked vertex stage:
ERROR: Linking vertex stage: Missing entry point: Each stage requires one "void main()" entry point
ERROR: Linking vertex stage: xfb_stride is too small to hold all buffer entries:
ERROR: xfb_buffer 0, xfb_stride 92, minimum stride needed: 96
ERROR: Linking vertex stage: xfb_stride must be multiple of 8 for buffer holding a double:
ERROR: xfb_buffer 0, xfb_stride 92
ERROR: Linking vertex stage: xfb_stride must be multiple of 4:
ERROR: xfb_buffer 5, xfb_stride 6
ERROR: Linking vertex stage: xfb_stride is too large:
ERROR: xfb_buffer 7, components (1/4 stride) needed are 66, gl_MaxTransformFeedbackInterleavedComponents is 64
in xfb mode
......@@ -75,6 +75,8 @@ MaxGeometryAtomicCounterBuffers 0
MaxFragmentAtomicCounterBuffers 1
MaxCombinedAtomicCounterBuffers 1
MaxAtomicCounterBufferSize 16384
MaxTransformFeedbackBuffers 4
MaxTransformFeedbackInterleavedComponents 64
nonInductiveForLoops 1
whileLoops 1
doWhileLoops 1
......
......@@ -185,6 +185,20 @@ typedef TMap<TString, TString>::tAllocator TPragmaTableAllocator;
const int GlslangMaxTokenLength = 1024;
// Round number up to a multiple of the given powerOf2, which is not
// a power, just a number that must be a power of 2.
template <class T> void RoundToPow2(T& number, int powerOf2)
{
assert((powerOf2 & (powerOf2 - 1)) == 0);
number = (number + powerOf2 - 1) & ~(powerOf2 - 1);
}
template <class T> bool IsMultipleOfPow2(T number, int powerOf2)
{
assert((powerOf2 & (powerOf2 - 1)) == 0);
return ! (number & (powerOf2 - 1));
}
} // end namespace glslang
#endif // _COMMON_INCLUDED_
......@@ -127,6 +127,8 @@ struct TBuiltInResource {
int maxFragmentAtomicCounterBuffers;
int maxCombinedAtomicCounterBuffers;
int maxAtomicCounterBufferSize;
int maxTransformFeedbackBuffers;
int maxTransformFeedbackInterleavedComponents;
TLimits limits;
};
......
......@@ -373,24 +373,32 @@ public:
hasStream() ||
hasXfb();
}
TLayoutMatrix layoutMatrix : 3;
TLayoutPacking layoutPacking : 4;
TLayoutMatrix layoutMatrix : 3;
TLayoutPacking layoutPacking : 4;
int layoutOffset;
int layoutAlign;
unsigned int layoutLocation : 7;
static const unsigned int layoutLocationEnd = 0x3F;
unsigned int layoutComponent : 3;
static const unsigned int layoutComponentEnd = 4;
unsigned int layoutBinding : 8;
static const unsigned int layoutBindingEnd = 0xFF;
unsigned int layoutStream : 8;
static const unsigned int layoutStreamEnd = 0xFF;
unsigned int layoutXfbBuffer : 4;
static const unsigned int layoutXfbBufferEnd = 0xF;
unsigned int layoutXfbStride : 8;
static const unsigned int layoutXfbStrideEnd = 0xFF;
unsigned int layoutXfbOffset : 8;
static const unsigned int layoutXfbOffsetEnd = 0xFF;
unsigned int layoutLocation : 7;
static const unsigned int layoutLocationEnd = 0x3F;
unsigned int layoutComponent : 3;
static const unsigned int layoutComponentEnd = 4;
unsigned int layoutBinding : 8;
static const unsigned int layoutBindingEnd = 0xFF;
unsigned int layoutStream : 8;
static const unsigned int layoutStreamEnd = 0xFF;
unsigned int layoutXfbBuffer : 4;
static const unsigned int layoutXfbBufferEnd = 0xF;
unsigned int layoutXfbStride : 10;
static const unsigned int layoutXfbStrideEnd = 0x3FF;
unsigned int layoutXfbOffset : 10;
static const unsigned int layoutXfbOffsetEnd = 0x3FF;
bool hasUniformLayout() const
{
return layoutMatrix != ElmNone ||
......@@ -805,6 +813,20 @@ public:
virtual bool isArray() const { return arraySizes != 0; }
virtual bool isStruct() const { return structure != 0; }
// Recursively checks if the type contains the given basic type
virtual bool containsBasicType(TBasicType checkType) const
{
if (basicType == checkType)
return true;
if (! structure)
return false;
for (unsigned int i = 0; i < structure->size(); ++i) {
if ((*structure)[i].type->containsBasicType(checkType))
return true;
}
return false;
}
// Recursively check the structure for any arrays, needed for some error checks
virtual bool containsArray() const
{
......
......@@ -9,5 +9,5 @@
// 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.
#define GLSLANG_REVISION "24964"
#define GLSLANG_DATE "2014/01/22 17:35:24"
#define GLSLANG_REVISION "24977"
#define GLSLANG_DATE "2014/01/23 14:40:33"
......@@ -165,6 +165,7 @@ public:
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
void declareBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
void fixBlockLocations(TSourceLoc, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
void fixBlockXfbOffsets(TSourceLoc, TQualifier&, TTypeList&);
void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier);
void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
void invariantCheck(TSourceLoc, const TType&, const TString& identifier);
......
......@@ -51,6 +51,55 @@ struct TVectorFields {
int num;
};
//
// Some helper structures for TIntermediate. Their contents are encapsulated
// by TIntermediate.
//
// Used for detecting recursion: A "call" is a pair: <caller, callee>.
struct TCall {
TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { }
TString caller;
TString callee;
bool visited;
bool currentPath;
bool errorGiven;
};
// A generic 1-D range.
struct TRange {
TRange(int start, int last) : start(start), last(last) { }
bool overlap(const TRange& rhs) const
{
return last >= rhs.start && start <= rhs.last;
}
int start;
int last;
};
// A *location* range is a 2-D rectangle; the set of (location, component) pairs all lying
// both within the location range and the component range. Locations don't alias unless
// both dimensions of their range overlap.
struct TIoRange {
TIoRange(TRange location, TRange component, TBasicType basicType) : location(location), component(component), basicType(basicType) { }
bool overlap(const TIoRange& rhs) const
{
return location.overlap(rhs.location) && component.overlap(rhs.component);
}
TRange location;
TRange component;
TBasicType basicType;
};
// Things that need to be tracked per xfb buffer.
struct TXfbBuffer {
TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), containsDouble(false) { }
std::vector<TRange> ranges; // byte offsets that have already been assigned
unsigned int stride;
unsigned int implicitStride;
bool containsDouble;
};
class TSymbolTable;
class TSymbol;
......@@ -62,7 +111,12 @@ public:
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v),
numMains(0), numErrors(0), recursive(false),
invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), xfbMode(false) { }
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), xfbMode(false)
{
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
}
void setLimits(const TBuiltInResource& r) { resources = r; }
bool postProcess(TIntermNode*, EShLanguage);
void output(TInfoSink&, bool tree);
void removeTree();
......@@ -176,6 +230,16 @@ public:
int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
int computeTypeLocationSize(const TType&);
bool setXfbBufferStride(int buffer, int stride)
{
if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
return xfbBuffers[buffer].stride == stride;
xfbBuffers[buffer].stride = stride;
return true;
}
int addXfbBufferOffset(const TType&);
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
protected:
void error(TInfoSink& infoSink, const char*);
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
......@@ -191,6 +255,7 @@ protected:
TIntermNode* treeRoot;
EProfile profile;
int version;
TBuiltInResource resources;
int numMains;
int numErrors;
bool recursive;
......@@ -205,33 +270,12 @@ protected:
bool pointMode;
bool xfbMode;
// for detecting recursion: pair is <caller, callee>
struct TCall {
TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { }
TString caller;
TString callee;
bool visited;
bool currentPath;
bool errorGiven;
};
typedef std::list<TCall> TGraph;
TGraph callGraph;
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
// A location range is a 2-D rectangle; the set of (location, component) pairs all lying
// both within the location range and the component range.
// The following are entirely encapsulated by addUsedLocation().
struct TRange {
int start;
int last;
};
struct TIoRange {
TRange location;
TRange component;
TBasicType basicType;
};
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
std::vector<TIoRange> usedIo[3]; // sets of used locations, one for each of in, out, and uniform
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
private:
void operator=(TIntermediate&); // prevent assignments
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment