Reflection: Implement the std140 block offset calculation rules.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24027 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
c043498b02
commit
568bc3ae55
@ -8,26 +8,54 @@ Linked vertex stage:
|
|||||||
|
|
||||||
|
|
||||||
Uniform reflection:
|
Uniform reflection:
|
||||||
0:anonMember3: offset 32, type 35666, arraySize 1, index 0
|
0: anonMember3: offset 80, type 35666, arraySize 1, index 0
|
||||||
1: s.a: offset -1, type 35666, arraySize 1, index -1
|
1: s.a: offset -1, type 35666, arraySize 1, index -1
|
||||||
2:anonMember1: offset 0, type 35666, arraySize 1, index 0
|
2: ablock.scalar: offset 12, type 35666, arraySize 1, index 1
|
||||||
3:uf1: offset -1, type 35666, arraySize 1, index -1
|
3: m23: offset 16, type 35666, arraySize 1, index 0
|
||||||
4:uf2: offset -1, type 35666, arraySize 1, index -1
|
4: scalarAfterm23: offset 48, type 35666, arraySize 1, index 0
|
||||||
5:ablock.member3: offset 32, type 35666, arraySize 1, index 1
|
5: c_m23: offset 16, type 35666, arraySize 1, index 2
|
||||||
|
6: c_scalarAfterm23: offset 64, type 35666, arraySize 1, index 2
|
||||||
|
7: scalarBeforeArray: offset 96, type 35666, arraySize 1, index 0
|
||||||
|
8: floatArray: offset 112, type 35666, arraySize 5, index 0
|
||||||
|
9: scalarAfterArray: offset 192, type 35666, arraySize 1, index 0
|
||||||
|
10: ablock.memvec2: offset 48, type 35666, arraySize 1, index 1
|
||||||
|
11: ablock.memf1: offset 56, type 35666, arraySize 1, index 1
|
||||||
|
12: ablock.memf2: offset 60, type 35666, arraySize 1, index 1
|
||||||
|
13: ablock.memf3: offset 64, type 35666, arraySize 1, index 1
|
||||||
|
14: ablock.memvec2a: offset 72, type 35666, arraySize 1, index 1
|
||||||
|
15: anonMember1: offset 0, type 35666, arraySize 1, index 0
|
||||||
|
16: uf1: offset -1, type 35666, arraySize 1, index -1
|
||||||
|
17: uf2: offset -1, type 35666, arraySize 1, index -1
|
||||||
|
18: ablock.member3: offset 32, type 35666, arraySize 1, index 1
|
||||||
|
|
||||||
Uniform block reflection:
|
Uniform block reflection:
|
||||||
0: nameless: offset -1, type -1, arraySize 1, index -1
|
0: nameless: offset -1, type -1, arraySize 1, index -1
|
||||||
1: ablock: offset -1, type -1, arraySize 1, index -1
|
1: ablock: offset -1, type -1, arraySize 1, index -1
|
||||||
|
2: c_nameless: offset -1, type -1, arraySize 1, index -1
|
||||||
|
|
||||||
Live names
|
Live names
|
||||||
ablock: 1
|
ablock: 1
|
||||||
ablock.member3: 5
|
ablock.member3: 18
|
||||||
anonMember1: 2
|
ablock.memf1: 11
|
||||||
|
ablock.memf2: 12
|
||||||
|
ablock.memf3: 13
|
||||||
|
ablock.memvec2: 10
|
||||||
|
ablock.memvec2a: 14
|
||||||
|
ablock.scalar: 2
|
||||||
|
anonMember1: 15
|
||||||
anonMember3: 0
|
anonMember3: 0
|
||||||
|
c_m23: 5
|
||||||
|
c_nameless: 2
|
||||||
|
c_scalarAfterm23: 6
|
||||||
|
floatArray: 8
|
||||||
liveFunction1(: -1
|
liveFunction1(: -1
|
||||||
liveFunction2(: -1
|
liveFunction2(: -1
|
||||||
|
m23: 3
|
||||||
nameless: 0
|
nameless: 0
|
||||||
s.a: 1
|
s.a: 1
|
||||||
uf1: 3
|
scalarAfterArray: 9
|
||||||
uf2: 4
|
scalarAfterm23: 4
|
||||||
|
scalarBeforeArray: 7
|
||||||
|
uf1: 16
|
||||||
|
uf2: 17
|
||||||
|
|
||||||
|
@ -1,22 +1,41 @@
|
|||||||
#version 440 core
|
#version 440 core
|
||||||
|
|
||||||
uniform nameless {
|
layout(std140, row_major) uniform nameless {
|
||||||
vec3 anonMember1;
|
vec3 anonMember1;
|
||||||
|
mat3x2 m23;
|
||||||
|
int scalarAfterm23;
|
||||||
vec4 anonDeadMember2;
|
vec4 anonDeadMember2;
|
||||||
vec4 anonMember3;
|
vec4 anonMember3;
|
||||||
|
int scalarBeforeArray;
|
||||||
|
float floatArray[5];
|
||||||
|
int scalarAfterArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform named {
|
layout(std140, column_major) uniform c_nameless {
|
||||||
|
vec3 c_anonMember1;
|
||||||
|
mat3x2 c_m23;
|
||||||
|
int c_scalarAfterm23;
|
||||||
|
vec4 c_anonDeadMember2;
|
||||||
|
vec4 c_anonMember3;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform named {
|
||||||
vec3 deadMember1;
|
vec3 deadMember1;
|
||||||
|
int scalar;
|
||||||
vec4 member2;
|
vec4 member2;
|
||||||
vec4 member3;
|
vec4 member3;
|
||||||
|
vec2 memvec2;
|
||||||
|
float memf1;
|
||||||
|
bool memf2;
|
||||||
|
int memf3;
|
||||||
|
vec2 memvec2a;
|
||||||
} ablock;
|
} ablock;
|
||||||
|
|
||||||
uniform namelessdead {
|
layout(std140) uniform namelessdead {
|
||||||
int a;
|
int a;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform namedDead {
|
layout(std140) uniform namedDead {
|
||||||
int b;
|
int b;
|
||||||
} bblock;
|
} bblock;
|
||||||
|
|
||||||
@ -68,6 +87,17 @@ void main()
|
|||||||
liveFunction2();
|
liveFunction2();
|
||||||
f = anonMember3.z;
|
f = anonMember3.z;
|
||||||
f = s.a;
|
f = s.a;
|
||||||
|
f = ablock.scalar;
|
||||||
|
f = m23[1].y + scalarAfterm23;
|
||||||
|
f = c_m23[1].y + c_scalarAfterm23;
|
||||||
|
f += scalarBeforeArray;
|
||||||
|
f += floatArray[2];
|
||||||
|
f += scalarAfterArray;
|
||||||
|
f += ablock.memvec2.x;
|
||||||
|
f += ablock.memf1;
|
||||||
|
f += float(ablock.memf2);
|
||||||
|
f += ablock.memf3;
|
||||||
|
f += ablock.memvec2a.y;
|
||||||
} else
|
} else
|
||||||
f = ufDead3;
|
f = ufDead3;
|
||||||
}
|
}
|
||||||
|
@ -490,6 +490,8 @@ typedef std::map<TTypeList*, TTypeList*>::const_iterator TStructureMapIterator;
|
|||||||
class TType {
|
class TType {
|
||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
|
|
||||||
|
// for "empty" type (no args) or simple scalar/vector/matrix
|
||||||
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
|
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
|
||||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||||
structure(0), structureSize(0), fieldName(0), typeName(0)
|
structure(0), structureSize(0), fieldName(0), typeName(0)
|
||||||
@ -498,6 +500,7 @@ public:
|
|||||||
qualifier.clear();
|
qualifier.clear();
|
||||||
qualifier.storage = q;
|
qualifier.storage = q;
|
||||||
}
|
}
|
||||||
|
// for explicit precision qualifier
|
||||||
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) :
|
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) :
|
||||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||||
structure(0), structureSize(0), fieldName(0), typeName(0)
|
structure(0), structureSize(0), fieldName(0), typeName(0)
|
||||||
@ -508,6 +511,7 @@ public:
|
|||||||
qualifier.precision = p;
|
qualifier.precision = p;
|
||||||
assert(p >= 0 && p <= EpqHigh);
|
assert(p >= 0 && p <= EpqHigh);
|
||||||
}
|
}
|
||||||
|
// for turning a TPublicType into a TType
|
||||||
explicit TType(const TPublicType& p) :
|
explicit TType(const TPublicType& p) :
|
||||||
basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
|
basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
|
||||||
structure(0), structureSize(0), fieldName(0), typeName(0)
|
structure(0), structureSize(0), fieldName(0), typeName(0)
|
||||||
@ -522,6 +526,23 @@ public:
|
|||||||
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// to efficiently make a dereferenced type
|
||||||
|
// without ever duplicating the outer structure that will be thrown away
|
||||||
|
// and using only shallow copy
|
||||||
|
TType(const TType& type, int derefIndex)
|
||||||
|
{
|
||||||
|
if (! type.isArray() && (type.basicType == EbtStruct || type.basicType == EbtBlock)) {
|
||||||
|
// do a structure dereference
|
||||||
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
shallowCopy(*memberList[derefIndex].type);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// do an array/vector/matrix dereference
|
||||||
|
shallowCopy(type);
|
||||||
|
dereference();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for making structures, ...
|
||||||
TType(TTypeList* userDef, const TString& n) :
|
TType(TTypeList* userDef, const TString& n) :
|
||||||
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0),
|
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0),
|
||||||
arraySizes(0), structure(userDef), fieldName(0)
|
arraySizes(0), structure(userDef), fieldName(0)
|
||||||
|
@ -500,13 +500,11 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
|
|||||||
result = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), loc);
|
result = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), loc);
|
||||||
} else {
|
} else {
|
||||||
// Insert valid dereferenced result
|
// Insert valid dereferenced result
|
||||||
TType newType;
|
TType newType(base->getType(), 0); // dereferenced type
|
||||||
newType.shallowCopy(base->getType());
|
|
||||||
if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst)
|
if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst)
|
||||||
newType.getQualifier().storage = EvqConst;
|
newType.getQualifier().storage = EvqConst;
|
||||||
else
|
else
|
||||||
newType.getQualifier().storage = EvqTemporary;
|
newType.getQualifier().storage = EvqTemporary;
|
||||||
newType.dereference();
|
|
||||||
result->setType(newType);
|
result->setType(newType);
|
||||||
|
|
||||||
if (anyIndexLimits)
|
if (anyIndexLimits)
|
||||||
@ -3024,9 +3022,7 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
|
|||||||
arrayType.shallowCopy(type);
|
arrayType.shallowCopy(type);
|
||||||
arrayType.setArraySizes(type);
|
arrayType.setArraySizes(type);
|
||||||
arrayType.changeArraySize(initList->getSequence().size());
|
arrayType.changeArraySize(initList->getSequence().size());
|
||||||
TType elementType;
|
TType elementType(arrayType, 0); // dereferenced type
|
||||||
elementType.shallowCopy(arrayType); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
|
|
||||||
elementType.dereference();
|
|
||||||
for (size_t i = 0; i < initList->getSequence().size(); ++i) {
|
for (size_t i = 0; i < initList->getSequence().size(); ++i) {
|
||||||
initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
|
initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
|
||||||
if (initList->getSequence()[i] == 0)
|
if (initList->getSequence()[i] == 0)
|
||||||
@ -3049,9 +3045,7 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
|
|||||||
error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
|
error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
TType vectorType;
|
TType vectorType(type, 0); // dereferenced type
|
||||||
vectorType.shallowCopy(type); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
|
|
||||||
vectorType.dereference();
|
|
||||||
for (int i = 0; i < type.getMatrixCols(); ++i) {
|
for (int i = 0; i < type.getMatrixCols(); ++i) {
|
||||||
initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
|
initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
|
||||||
if (initList->getSequence()[i] == 0)
|
if (initList->getSequence()[i] == 0)
|
||||||
@ -3088,10 +3082,11 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
|
|||||||
if (op == EOpConstructStruct)
|
if (op == EOpConstructStruct)
|
||||||
memberTypes = type.getStruct()->begin();
|
memberTypes = type.getStruct()->begin();
|
||||||
|
|
||||||
TType elementType;
|
const TType* elementType;
|
||||||
elementType.shallowCopy(type);
|
|
||||||
if (type.isArray())
|
if (type.isArray())
|
||||||
elementType.dereference(); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
|
elementType = &TType(type, 0); // dereferenced type
|
||||||
|
else
|
||||||
|
elementType = &type;
|
||||||
|
|
||||||
bool singleArg;
|
bool singleArg;
|
||||||
if (aggrNode) {
|
if (aggrNode) {
|
||||||
@ -3107,7 +3102,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
|
|||||||
// If structure constructor or array constructor is being called
|
// If structure constructor or array constructor is being called
|
||||||
// for only one parameter inside the structure, we need to call constructStruct function once.
|
// for only one parameter inside the structure, we need to call constructStruct function once.
|
||||||
if (type.isArray())
|
if (type.isArray())
|
||||||
newNode = constructStruct(node, elementType, 1, node->getLoc());
|
newNode = constructStruct(node, *elementType, 1, node->getLoc());
|
||||||
else if (op == EOpConstructStruct)
|
else if (op == EOpConstructStruct)
|
||||||
newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc());
|
newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc());
|
||||||
else
|
else
|
||||||
@ -3135,7 +3130,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
|
|||||||
for (TIntermSequence::iterator p = sequenceVector.begin();
|
for (TIntermSequence::iterator p = sequenceVector.begin();
|
||||||
p != sequenceVector.end(); p++, paramCount++) {
|
p != sequenceVector.end(); p++, paramCount++) {
|
||||||
if (type.isArray())
|
if (type.isArray())
|
||||||
newNode = constructStruct(*p, elementType, paramCount+1, node->getLoc());
|
newNode = constructStruct(*p, *elementType, paramCount+1, node->getLoc());
|
||||||
else if (op == EOpConstructStruct)
|
else if (op == EOpConstructStruct)
|
||||||
newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
|
newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
|
||||||
else
|
else
|
||||||
@ -3724,9 +3719,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(TSourceLoc loc, int index, TInte
|
|||||||
//
|
//
|
||||||
TIntermTyped* TParseContext::addConstArrayNode(TSourceLoc loc, int index, TIntermTyped* node)
|
TIntermTyped* TParseContext::addConstArrayNode(TSourceLoc loc, int index, TIntermTyped* node)
|
||||||
{
|
{
|
||||||
TType arrayElementType;
|
TType arrayElementType(node->getType(), 0); // dereferenced type
|
||||||
arrayElementType.shallowCopy(node->getType()); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
|
|
||||||
arrayElementType.dereference();
|
|
||||||
|
|
||||||
if (index >= node->getType().getArraySize() || index < 0) {
|
if (index >= node->getType().getArraySize() || index < 0) {
|
||||||
error(loc, "", "[", "array index '%d' out of range", index);
|
error(loc, "", "[", "array index '%d' out of range", index);
|
||||||
|
@ -65,7 +65,7 @@ namespace glslang {
|
|||||||
//
|
//
|
||||||
// The traverser: mostly pass through, except
|
// The traverser: mostly pass through, except
|
||||||
// - processing function-call nodes to push live functions onto the stack of functions to process
|
// - processing function-call nodes to push live functions onto the stack of functions to process
|
||||||
// - processing binary nodes to see if they are dereferences of aggregates to track
|
// - processing binary nodes to see if they are dereferences of an aggregates to track
|
||||||
// - processing symbol nodes to see if they are non-aggregate objects to track
|
// - processing symbol nodes to see if they are non-aggregate objects to track
|
||||||
// - processing selection nodes to trim semantically dead code
|
// - processing selection nodes to trim semantically dead code
|
||||||
//
|
//
|
||||||
@ -87,7 +87,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a simple uniform variable reference to the uniform database, no derefence involved.
|
// Add a simple uniform variable reference to the uniform database, no dereference involved.
|
||||||
void addUniform(const TIntermSymbol& symbol)
|
void addUniform(const TIntermSymbol& symbol)
|
||||||
{
|
{
|
||||||
if (reflection.nameToIndex.find(symbol.getName()) == reflection.nameToIndex.end()) {
|
if (reflection.nameToIndex.find(symbol.getName()) == reflection.nameToIndex.end()) {
|
||||||
@ -98,7 +98,126 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a complex uniform reference where blocks/struct/arrays are involved in tha access.
|
static const int baseAlignmentVec4Std140 = 16;
|
||||||
|
|
||||||
|
// align a value: if 'value' is not aligned to 'alignment', move it up to a multiple of alignment
|
||||||
|
void align(int& value, int alignment)
|
||||||
|
{
|
||||||
|
int error = value % alignment;
|
||||||
|
if (error)
|
||||||
|
value += alignment - error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the size and alignment of a scalar
|
||||||
|
int getBaseAlignmentScalar(const TType& type, int& size)
|
||||||
|
{
|
||||||
|
switch (type.getBasicType()) {
|
||||||
|
case EbtDouble: size = 8; return 8;
|
||||||
|
default: size = 4; return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement base-alignment and size rules from section 7.6.2.2 Standard Uniform Block Layout
|
||||||
|
// Operates recursively.
|
||||||
|
// If std140 is true, it does the rounding up to vec4 size required by std140,
|
||||||
|
// otherwise it does not, yielding std430 rules.
|
||||||
|
//
|
||||||
|
// Returns the size of the type.
|
||||||
|
int getBaseAlignment(const TType& type, int& size, bool std140)
|
||||||
|
{
|
||||||
|
int alignment;
|
||||||
|
|
||||||
|
// rules 4, 6, and 8
|
||||||
|
if (type.isArray()) {
|
||||||
|
TType derefType(type, 0);
|
||||||
|
alignment = getBaseAlignment(derefType, size, std140);
|
||||||
|
if (std140)
|
||||||
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
|
align(size, alignment);
|
||||||
|
size *= type.getArraySize();
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rule 9
|
||||||
|
if (type.getBasicType() == EbtStruct) {
|
||||||
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
int maxAlignment = std140 ? baseAlignmentVec4Std140 : 0;
|
||||||
|
for (size_t m = 0; m < memberList.size(); ++m) {
|
||||||
|
int memberSize;
|
||||||
|
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, std140);
|
||||||
|
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||||
|
align(size, memberAlignment);
|
||||||
|
size += memberSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rule 1
|
||||||
|
if (type.isScalar())
|
||||||
|
return getBaseAlignmentScalar(type, size);
|
||||||
|
|
||||||
|
// rules 2 and 3
|
||||||
|
if (type.isVector()) {
|
||||||
|
int scalarAlign = getBaseAlignmentScalar(type, size);
|
||||||
|
switch (type.getVectorSize()) {
|
||||||
|
case 2:
|
||||||
|
size *= 2;
|
||||||
|
return 2 * scalarAlign;
|
||||||
|
default:
|
||||||
|
size *= type.getVectorSize();
|
||||||
|
return 4 * scalarAlign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rules 5 and 7
|
||||||
|
if (type.isMatrix()) {
|
||||||
|
TType derefType(type, 0);
|
||||||
|
|
||||||
|
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
||||||
|
if (type.getQualifier().layoutMatrix == ElmRowMajor)
|
||||||
|
derefType.setElementType(derefType.getBasicType(), type.getMatrixCols(), 0, 0, 0);
|
||||||
|
|
||||||
|
alignment = getBaseAlignment(derefType, size, std140);
|
||||||
|
if (std140)
|
||||||
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
|
align(size, alignment);
|
||||||
|
if (type.getQualifier().layoutMatrix == ElmRowMajor)
|
||||||
|
size *= type.getMatrixRows();
|
||||||
|
else
|
||||||
|
size *= type.getMatrixCols();
|
||||||
|
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0); // all cases should be covered above
|
||||||
|
size = baseAlignmentVec4Std140;
|
||||||
|
return baseAlignmentVec4Std140;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the offset of a block member, using the recursively defined
|
||||||
|
// block offset rules.
|
||||||
|
int getBlockMemberOffset(const TType& blockType, int index)
|
||||||
|
{
|
||||||
|
// TODO: reflection performance: cache these results instead of recomputing them
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
const TTypeList& memberList = *blockType.getStruct();
|
||||||
|
int memberSize;
|
||||||
|
for (int m = 0; m < index; ++m) {
|
||||||
|
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, blockType.getQualifier().layoutPacking == ElpStd140);
|
||||||
|
align(offset, memberAlignment);
|
||||||
|
offset += memberSize;
|
||||||
|
}
|
||||||
|
int memberAlignment = getBaseAlignment(*memberList[index].type, memberSize, blockType.getQualifier().layoutPacking == ElpStd140);
|
||||||
|
align(offset, memberAlignment);
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a complex uniform reference where blocks/struct/arrays are involved in the access.
|
||||||
void addDereferencedUniform(TIntermSymbol* base, TIntermBinary* node)
|
void addDereferencedUniform(TIntermSymbol* base, TIntermBinary* node)
|
||||||
{
|
{
|
||||||
bool block = base->getBasicType() == EbtBlock;
|
bool block = base->getBasicType() == EbtBlock;
|
||||||
@ -133,7 +252,7 @@ public:
|
|||||||
}
|
}
|
||||||
int structIndex = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
int structIndex = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
if (block)
|
if (block)
|
||||||
offset = structIndex * 16; // TODO: reflection: compute std140 offsets
|
offset = getBlockMemberOffset(base->getType(), structIndex);
|
||||||
name.append((*base->getType().getStruct())[structIndex].type->getFieldName().c_str());
|
name.append((*base->getType().getStruct())[structIndex].type->getFieldName().c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user