Commit 3ac051e4 by John Kessenich

SPV: recursively propagate row/col majorness through nested structures.

This includes doing structure uniqueness modulo majorness, for shared nested structures.
parent f85e806e
#version 450 #version 450
// should get 3 SPV types: no layout, 140, and 430 // should get 3 SPV types for S: no layout, 140, and 430
struct S struct S
{ {
highp uvec3 a; highp uvec3 a;
...@@ -24,8 +24,50 @@ layout(set = 0, binding = 1, std430) buffer Block430 ...@@ -24,8 +24,50 @@ layout(set = 0, binding = 1, std430) buffer Block430
S s; S s;
// should get 5 SPV types for T: no layout, 140/row, 140/col, 430/row, and 430/col
struct T {
mat2 m;
int a;
};
T t;
struct Nestor {
T nestorT;
};
layout(set = 1, binding = 0, std140) uniform Bt1
{
layout(row_major) Nestor nt;
} Btn1;
layout(set = 1, binding = 0, std140) uniform Bt2
{
layout(column_major) Nestor nt;
} Btn2;
layout(row_major, set = 1, binding = 0, std140) uniform Bt3
{
layout(column_major) Nestor ntcol;
Nestor ntrow; // should be row major decoration version of Nestor
} Btn3;
layout(set = 1, binding = 0, std430) buffer bBt1
{
layout(row_major) Nestor nt;
} bBtn1;
layout(set = 1, binding = 0, std430) buffer bBt2
{
layout(column_major) Nestor nt;
} bBtn2;
layout(set = 1, binding = 0, std430) buffer bBt3
{
layout(row_major) Nestor ntcol;
Nestor ntrow; // should be col major decoration version of Nestor
} bBtn3;
void main() void main()
{ {
s.c = inst140.u;
gl_Position = vec4(s.c);
} }
...@@ -186,15 +186,15 @@ enum TLayoutPacking { ...@@ -186,15 +186,15 @@ enum TLayoutPacking {
ElpShared, // default, but different than saying nothing ElpShared, // default, but different than saying nothing
ElpStd140, ElpStd140,
ElpStd430, ElpStd430,
ElpPacked ElpPacked,
// If expanding, see bitfield width below ElpCount // If expanding, see bitfield width below
}; };
enum TLayoutMatrix { enum TLayoutMatrix {
ElmNone, ElmNone,
ElmRowMajor, ElmRowMajor,
ElmColumnMajor // default, but different than saying nothing ElmColumnMajor, // default, but different than saying nothing
// If expanding, see bitfield width below ElmCount // If expanding, see bitfield width below
}; };
// Union of geometry shader and tessellation shader geometry types. // Union of geometry shader and tessellation shader geometry types.
......
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "SPIRV99.860" #define GLSLANG_REVISION "SPIRV99.861"
#define GLSLANG_DATE "19-Dec-2015" #define GLSLANG_DATE "20-Dec-2015"
...@@ -5345,8 +5345,11 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ ...@@ -5345,8 +5345,11 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
const TSourceLoc& memberLoc = typeList[member].loc; const TSourceLoc& memberLoc = typeList[member].loc;
// "When align is applied to an array, it effects only the start of the array, not the array's internal stride." // "When align is applied to an array, it effects only the start of the array, not the array's internal stride."
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, qualifier.layoutPacking == ElpStd140); // modify just the children's view of matrix layout, if there is one for this member
TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, qualifier.layoutPacking == ElpStd140,
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
if (memberQualifier.hasOffset()) { if (memberQualifier.hasOffset()) {
// "The specified offset must be a multiple // "The specified offset must be a multiple
// of the base alignment of the type of the block member it qualifies, or a compile-time error results." // of the base alignment of the type of the block member it qualifies, or a compile-time error results."
......
...@@ -859,7 +859,7 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) ...@@ -859,7 +859,7 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
// //
// The size is returned in the 'size' parameter // The size is returned in the 'size' parameter
// Return value is the alignment of the type. // Return value is the alignment of the type.
int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140) int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140, bool rowMajor)
{ {
int alignment; int alignment;
...@@ -921,7 +921,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140) ...@@ -921,7 +921,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140)
if (type.isArray()) { if (type.isArray()) {
// TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness // TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
TType derefType(type, 0); TType derefType(type, 0);
alignment = getBaseAlignment(derefType, size, std140); alignment = getBaseAlignment(derefType, size, std140, rowMajor);
if (std140) if (std140)
alignment = std::max(baseAlignmentVec4Std140, alignment); alignment = std::max(baseAlignmentVec4Std140, alignment);
RoundToPow2(size, alignment); RoundToPow2(size, alignment);
...@@ -937,7 +937,10 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140) ...@@ -937,7 +937,10 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140)
int maxAlignment = std140 ? baseAlignmentVec4Std140 : 0; int maxAlignment = std140 ? baseAlignmentVec4Std140 : 0;
for (size_t m = 0; m < memberList.size(); ++m) { for (size_t m = 0; m < memberList.size(); ++m) {
int memberSize; int memberSize;
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, std140); // modify just the children's view of matrix layout, if there is one for this member
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, std140,
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
maxAlignment = std::max(maxAlignment, memberAlignment); maxAlignment = std::max(maxAlignment, memberAlignment);
RoundToPow2(size, memberAlignment); RoundToPow2(size, memberAlignment);
size += memberSize; size += memberSize;
...@@ -968,11 +971,11 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140) ...@@ -968,11 +971,11 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140)
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows // rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
TType derefType(type, 0, type.getQualifier().layoutMatrix == ElmRowMajor); TType derefType(type, 0, type.getQualifier().layoutMatrix == ElmRowMajor);
alignment = getBaseAlignment(derefType, size, std140); alignment = getBaseAlignment(derefType, size, std140, rowMajor);
if (std140) if (std140)
alignment = std::max(baseAlignmentVec4Std140, alignment); alignment = std::max(baseAlignmentVec4Std140, alignment);
RoundToPow2(size, alignment); RoundToPow2(size, alignment);
if (type.getQualifier().layoutMatrix == ElmRowMajor) if (rowMajor)
size *= type.getMatrixRows(); size *= type.getMatrixRows();
else else
size *= type.getMatrixCols(); size *= type.getMatrixCols();
......
...@@ -305,7 +305,7 @@ public: ...@@ -305,7 +305,7 @@ public:
} }
int addXfbBufferOffset(const TType&); int addXfbBufferOffset(const TType&);
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const; unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
static int getBaseAlignment(const TType&, int& size, bool std140); static int getBaseAlignment(const TType&, int& size, bool std140, bool rowMajor);
protected: protected:
void error(TInfoSink& infoSink, const char*); void error(TInfoSink& infoSink, const char*);
......
...@@ -123,7 +123,10 @@ public: ...@@ -123,7 +123,10 @@ public:
int memberSize; int memberSize;
int offset = 0; int offset = 0;
for (int m = 0; m <= index; ++m) { for (int m = 0; m <= index; ++m) {
int memberAlignment = intermediate.getBaseAlignment(*memberList[m].type, memberSize, type.getQualifier().layoutPacking == ElpStd140); // modify just the children's view of matrix layout, if there is one for this member
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
int memberAlignment = intermediate.getBaseAlignment(*memberList[m].type, memberSize, type.getQualifier().layoutPacking == ElpStd140,
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : type.getQualifier().layoutMatrix == ElmRowMajor);
RoundToPow2(offset, memberAlignment); RoundToPow2(offset, memberAlignment);
if (m < index) if (m < index)
offset += memberSize; offset += memberSize;
...@@ -141,7 +144,8 @@ public: ...@@ -141,7 +144,8 @@ public:
int lastOffset = getOffset(blockType, lastIndex); int lastOffset = getOffset(blockType, lastIndex);
int lastMemberSize; int lastMemberSize;
intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, blockType.getQualifier().layoutPacking == ElpStd140); intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, blockType.getQualifier().layoutPacking == ElpStd140,
blockType.getQualifier().layoutMatrix == ElmRowMajor);
return lastOffset + lastMemberSize; return lastOffset + lastMemberSize;
} }
......
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