Commit 6e56a47c by John Kessenich

Merge branch GitHub 'master' into GitLab master

parents 1f2c9771 3ac051e4
...@@ -91,11 +91,11 @@ protected: ...@@ -91,11 +91,11 @@ protected:
spv::Id createSpvVariable(const glslang::TIntermSymbol*); spv::Id createSpvVariable(const glslang::TIntermSymbol*);
spv::Id getSampledType(const glslang::TSampler&); spv::Id getSampledType(const glslang::TSampler&);
spv::Id convertGlslangToSpvType(const glslang::TType& type); spv::Id convertGlslangToSpvType(const glslang::TType& type);
spv::Id convertGlslangToSpvType(const glslang::TType& type, bool explicitLayout); spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, glslang::TLayoutMatrix);
bool requiresExplicitLayout(const glslang::TType& type) const; glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
int getArrayStride(const glslang::TType& arrayType); int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
int getMatrixStride(const glslang::TType& matrixType); int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset); void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset, glslang::TLayoutPacking, glslang::TLayoutMatrix);
bool isShaderEntrypoint(const glslang::TIntermAggregate* node); bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
void makeFunctions(const glslang::TIntermSequence&); void makeFunctions(const glslang::TIntermSequence&);
...@@ -140,7 +140,7 @@ protected: ...@@ -140,7 +140,7 @@ protected:
std::unordered_map<int, spv::Id> symbolValues; std::unordered_map<int, spv::Id> symbolValues;
std::unordered_set<int> constReadOnlyParameters; // set of formal function parameters that have glslang qualifier constReadOnly, so we know they are not local function "const" that are write-once std::unordered_set<int> constReadOnlyParameters; // set of formal function parameters that have glslang qualifier constReadOnly, so we know they are not local function "const" that are write-once
std::unordered_map<std::string, spv::Function*> functionMap; std::unordered_map<std::string, spv::Function*> functionMap;
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap; std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper; // for mapping glslang block indices to spv indices (e.g., due to hidden members) std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper; // for mapping glslang block indices to spv indices (e.g., due to hidden members)
std::stack<bool> breakForLoop; // false means break for switch std::stack<bool> breakForLoop; // false means break for switch
std::stack<glslang::TIntermTyped*> loopTerminal; // code from the last part of a for loop: for(...; ...; terminal), needed for e.g., continue }; std::stack<glslang::TIntermTyped*> loopTerminal; // code from the last part of a for loop: for(...; ...; terminal), needed for e.g., continue };
...@@ -229,7 +229,7 @@ spv::Dim TranslateDimensionality(const glslang::TSampler& sampler) ...@@ -229,7 +229,7 @@ spv::Dim TranslateDimensionality(const glslang::TSampler& sampler)
spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type) spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
{ {
switch (type.getQualifier().precision) { switch (type.getQualifier().precision) {
case glslang::EpqLow: return spv::DecorationRelaxedPrecision; // TODO: Map instead to 16-bit types? case glslang::EpqLow: return spv::DecorationRelaxedPrecision;
case glslang::EpqMedium: return spv::DecorationRelaxedPrecision; case glslang::EpqMedium: return spv::DecorationRelaxedPrecision;
case glslang::EpqHigh: return spv::NoPrecision; case glslang::EpqHigh: return spv::NoPrecision;
default: default:
...@@ -256,14 +256,17 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type) ...@@ -256,14 +256,17 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type)
} }
// Translate glslang type to SPIR-V layout decorations. // Translate glslang type to SPIR-V layout decorations.
spv::Decoration TranslateLayoutDecoration(const glslang::TType& type) spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::TLayoutMatrix matrixLayout)
{ {
if (type.isMatrix()) { if (type.isMatrix()) {
switch (type.getQualifier().layoutMatrix) { switch (matrixLayout) {
case glslang::ElmRowMajor: case glslang::ElmRowMajor:
return spv::DecorationRowMajor; return spv::DecorationRowMajor;
default: case glslang::ElmColumnMajor:
return spv::DecorationColMajor; return spv::DecorationColMajor;
default:
// opaque layouts don't need a majorness
return (spv::Decoration)spv::BadValue;
} }
} else { } else {
switch (type.getBasicType()) { switch (type.getBasicType()) {
...@@ -1451,16 +1454,17 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler) ...@@ -1451,16 +1454,17 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
} }
} }
// Convert from a glslang type to an SPV type, by calling into // Convert from a glslang type to an SPV type, by calling into a
// recursive version of this function. // recursive version of this function. This establishes the inherited
// layout state rooted from the top-level type.
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type) spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type)
{ {
return convertGlslangToSpvType(type, requiresExplicitLayout(type)); return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier().layoutMatrix);
} }
// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id. // Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
// explicitLayout can be kept the same throughout the heirarchical recursive walk. // explicitLayout can be kept the same throughout the heirarchical recursive walk.
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, bool explicitLayout) spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
{ {
spv::Id spvType = 0; spv::Id spvType = 0;
...@@ -1505,7 +1509,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1505,7 +1509,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
// If we've seen this struct type, return it // If we've seen this struct type, return it
const glslang::TTypeList* glslangStruct = type.getStruct(); const glslang::TTypeList* glslangStruct = type.getStruct();
std::vector<spv::Id> structFields; std::vector<spv::Id> structFields;
spvType = structMap[glslangStruct]; spvType = structMap[explicitLayout][matrixLayout][glslangStruct];
if (spvType) if (spvType)
break; break;
...@@ -1524,13 +1528,16 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1524,13 +1528,16 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
} else { } else {
if (type.getBasicType() == glslang::EbtBlock) if (type.getBasicType() == glslang::EbtBlock)
memberRemapper[glslangStruct][i] = i - memberDelta; memberRemapper[glslangStruct][i] = i - memberDelta;
structFields.push_back(convertGlslangToSpvType(glslangType, explicitLayout)); // modify just the children's view of matrix layout, if there is one for this member
glslang::TLayoutMatrix subMatrixLayout = glslangType.getQualifier().layoutMatrix;
structFields.push_back(convertGlslangToSpvType(glslangType, explicitLayout,
subMatrixLayout != glslang::ElmNone ? subMatrixLayout : matrixLayout));
} }
} }
// Make the SPIR-V type // Make the SPIR-V type
spvType = builder.makeStructType(structFields, type.getTypeName().c_str()); spvType = builder.makeStructType(structFields, type.getTypeName().c_str());
structMap[glslangStruct] = spvType; structMap[explicitLayout][matrixLayout][glslangStruct] = spvType;
// Name and decorate the non-hidden members // Name and decorate the non-hidden members
int offset = -1; int offset = -1;
...@@ -1539,10 +1546,16 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1539,10 +1546,16 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
int member = i; int member = i;
if (type.getBasicType() == glslang::EbtBlock) if (type.getBasicType() == glslang::EbtBlock)
member = memberRemapper[glslangStruct][i]; member = memberRemapper[glslangStruct][i];
// modify just the children's view of matrix layout, if there is one for this member
glslang::TLayoutMatrix subMatrixLayout = glslangType.getQualifier().layoutMatrix;
if (subMatrixLayout == glslang::ElmNone)
subMatrixLayout = matrixLayout;
// using -1 above to indicate a hidden member // using -1 above to indicate a hidden member
if (member >= 0) { if (member >= 0) {
builder.addMemberName(spvType, member, glslangType.getFieldName().c_str()); builder.addMemberName(spvType, member, glslangType.getFieldName().c_str());
addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangType)); addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangType, subMatrixLayout));
addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangType)); addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangType));
addMemberDecoration(spvType, member, TranslateInterpolationDecoration(glslangType)); addMemberDecoration(spvType, member, TranslateInterpolationDecoration(glslangType));
addMemberDecoration(spvType, member, TranslateInvariantDecoration(glslangType)); addMemberDecoration(spvType, member, TranslateInvariantDecoration(glslangType));
...@@ -1552,18 +1565,17 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1552,18 +1565,17 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent); builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent);
if (glslangType.getQualifier().hasXfbOffset()) if (glslangType.getQualifier().hasXfbOffset())
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset); builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset);
else if (explicitLayout) { else if (explicitLayout != glslang::ElpNone) {
// figure out what to do with offset, which is accumulating // figure out what to do with offset, which is accumulating
int nextOffset; int nextOffset;
updateMemberOffset(type, glslangType, offset, nextOffset); updateMemberOffset(type, glslangType, offset, nextOffset, explicitLayout, subMatrixLayout);
if (offset >= 0) if (offset >= 0)
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset); builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
offset = nextOffset; offset = nextOffset;
} }
if (glslangType.isMatrix() && explicitLayout) { if (glslangType.isMatrix() && explicitLayout != glslang::ElpNone)
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangType)); builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangType, explicitLayout, subMatrixLayout));
}
// built-in variable decorations // built-in variable decorations
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn); spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn);
...@@ -1573,7 +1585,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1573,7 +1585,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
} }
// Decorate the structure // Decorate the structure
addDecoration(spvType, TranslateLayoutDecoration(type)); addDecoration(spvType, TranslateLayoutDecoration(type, matrixLayout));
addDecoration(spvType, TranslateBlockDecoration(type)); addDecoration(spvType, TranslateBlockDecoration(type));
if (type.getQualifier().hasStream()) if (type.getQualifier().hasStream())
builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream); builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
...@@ -1621,30 +1633,45 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1621,30 +1633,45 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
// except for the very top if it is an array of blocks; that array is // except for the very top if it is an array of blocks; that array is
// not laid out in memory in a way needing a stride. // not laid out in memory in a way needing a stride.
if (explicitLayout && type.getBasicType() != glslang::EbtBlock) if (explicitLayout && type.getBasicType() != glslang::EbtBlock)
builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type)); builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type, explicitLayout, matrixLayout));
} }
return spvType; return spvType;
} }
bool TGlslangToSpvTraverser::requiresExplicitLayout(const glslang::TType& type) const // Decide whether or not this type should be
// decorated with offsets and strides, and if so
// whether std140 or std430 rules should be applied.
glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang::TType& type) const
{ {
return type.getBasicType() == glslang::EbtBlock && // has to be a block
type.getQualifier().layoutPacking != glslang::ElpShared && if (type.getBasicType() != glslang::EbtBlock)
type.getQualifier().layoutPacking != glslang::ElpPacked && return glslang::ElpNone;
(type.getQualifier().storage == glslang::EvqUniform ||
type.getQualifier().storage == glslang::EvqBuffer); // has to be a uniform or buffer block
if (type.getQualifier().storage != glslang::EvqUniform &&
type.getQualifier().storage != glslang::EvqBuffer)
return glslang::ElpNone;
// return the layout to use
switch (type.getQualifier().layoutPacking) {
case glslang::ElpStd140:
case glslang::ElpStd430:
return type.getQualifier().layoutPacking;
default:
return glslang::ElpNone;
}
} }
// Given an array type, returns the integer stride required for that array // Given an array type, returns the integer stride required for that array
int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType) int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
{ {
int size; int size;
int stride = glslangIntermediate->getBaseAlignment(arrayType, size, arrayType.getQualifier().layoutPacking == glslang::ElpStd140); int stride = glslangIntermediate->getBaseAlignment(arrayType, size, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
if (arrayType.isMatrix()) { if (arrayType.isMatrix()) {
// GLSL strides are set to alignments of the matrix flattened to individual rows/cols, // GLSL strides are set to alignments of the matrix flattened to individual rows/cols,
// but SPV needs an array stride for the whole matrix, not the rows/cols // but SPV needs an array stride for the whole matrix, not the rows/cols
if (arrayType.getQualifier().layoutMatrix == glslang::ElmRowMajor) if (matrixLayout == glslang::ElmRowMajor)
stride *= arrayType.getMatrixRows(); stride *= arrayType.getMatrixRows();
else else
stride *= arrayType.getMatrixCols(); stride *= arrayType.getMatrixCols();
...@@ -1655,10 +1682,10 @@ int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType) ...@@ -1655,10 +1682,10 @@ int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType)
// Given a matrix type, returns the integer stride required for that matrix // Given a matrix type, returns the integer stride required for that matrix
// when used as a member of an interface block // when used as a member of an interface block
int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType) int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
{ {
int size; int size;
return glslangIntermediate->getBaseAlignment(matrixType, size, matrixType.getQualifier().layoutPacking == glslang::ElpStd140); return glslangIntermediate->getBaseAlignment(matrixType, size, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
} }
// Given a member type of a struct, realign the current offset for it, and compute // Given a member type of a struct, realign the current offset for it, and compute
...@@ -1667,14 +1694,12 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType) ...@@ -1667,14 +1694,12 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType)
// 'currentOffset' should be passed in already initialized, ready to modify, and reflecting // 'currentOffset' should be passed in already initialized, ready to modify, and reflecting
// the migration of data from nextOffset -> currentOffset. It should be -1 on the first call. // the migration of data from nextOffset -> currentOffset. It should be -1 on the first call.
// -1 means a non-forced member offset (no decoration needed). // -1 means a non-forced member offset (no decoration needed).
void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset) void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset,
glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
{ {
// this will get a positive value when deemed necessary // this will get a positive value when deemed necessary
nextOffset = -1; nextOffset = -1;
bool forceOffset = structType.getQualifier().layoutPacking == glslang::ElpStd140 ||
structType.getQualifier().layoutPacking == glslang::ElpStd430;
// override anything in currentOffset with user-set offset // override anything in currentOffset with user-set offset
if (memberType.getQualifier().hasOffset()) if (memberType.getQualifier().hasOffset())
currentOffset = memberType.getQualifier().layoutOffset; currentOffset = memberType.getQualifier().layoutOffset;
...@@ -1684,14 +1709,14 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType ...@@ -1684,14 +1709,14 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
// once cross-compilation unit GLSL validation is done, as the original user // once cross-compilation unit GLSL validation is done, as the original user
// settings are needed in layoutOffset, and then the following will come into play. // settings are needed in layoutOffset, and then the following will come into play.
if (! forceOffset) { if (explicitLayout == glslang::ElpNone) {
if (! memberType.getQualifier().hasOffset()) if (! memberType.getQualifier().hasOffset())
currentOffset = -1; currentOffset = -1;
return; return;
} }
// Getting this far means we are forcing offsets // Getting this far means we need explicit offsets
if (currentOffset < 0) if (currentOffset < 0)
currentOffset = 0; currentOffset = 0;
...@@ -1699,7 +1724,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType ...@@ -1699,7 +1724,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
// but possibly not yet correctly aligned. // but possibly not yet correctly aligned.
int memberSize; int memberSize;
int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, memberType.getQualifier().layoutPacking == glslang::ElpStd140); int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
glslang::RoundToPow2(currentOffset, memberAlignment); glslang::RoundToPow2(currentOffset, memberAlignment);
nextOffset = currentOffset + memberSize; nextOffset = currentOffset + memberSize;
} }
...@@ -1889,15 +1914,19 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ...@@ -1889,15 +1914,19 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
auto opIt = arguments.begin(); auto opIt = arguments.begin();
operands.push_back(*(opIt++)); operands.push_back(*(opIt++));
operands.push_back(*(opIt++)); operands.push_back(*(opIt++));
if (node->getOp() == glslang::EOpImageStore)
operands.push_back(*(opIt++));
if (node->getOp() == glslang::EOpImageLoad) { if (node->getOp() == glslang::EOpImageLoad) {
if (sampler.ms) { if (sampler.ms) {
operands.push_back(spv::ImageOperandsSampleMask); operands.push_back(spv::ImageOperandsSampleMask);
operands.push_back(*(opIt++)); operands.push_back(*opIt);
} }
return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), operands); return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), operands);
} else if (node->getOp() == glslang::EOpImageStore) { } else if (node->getOp() == glslang::EOpImageStore) {
if (sampler.ms) {
operands.push_back(*(opIt + 1));
operands.push_back(spv::ImageOperandsSampleMask);
operands.push_back(*opIt);
} else
operands.push_back(*opIt);
builder.createNoResultOp(spv::OpImageWrite, operands); builder.createNoResultOp(spv::OpImageWrite, operands);
return spv::NoResult; return spv::NoResult;
} else { } else {
...@@ -2531,6 +2560,13 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv: ...@@ -2531,6 +2560,13 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
unaryOp = spv::OpIsInf; unaryOp = spv::OpIsInf;
break; break;
case glslang::EOpFloatBitsToInt:
case glslang::EOpFloatBitsToUint:
case glslang::EOpIntBitsToFloat:
case glslang::EOpUintBitsToFloat:
unaryOp = spv::OpBitcast;
break;
case glslang::EOpPackSnorm2x16: case glslang::EOpPackSnorm2x16:
libCall = spv::GLSLstd450PackSnorm2x16; libCall = spv::GLSLstd450PackSnorm2x16;
break; break;
......
...@@ -827,7 +827,7 @@ int C_DECL main(int argc, char* argv[]) ...@@ -827,7 +827,7 @@ int C_DECL main(int argc, char* argv[])
// Print out all the resulting infologs // Print out all the resulting infologs
for (int w = 0; w < NumWorkItems; ++w) { for (int w = 0; w < NumWorkItems; ++w) {
if (Work[w]) { if (Work[w]) {
if (printShaderNames) if (printShaderNames || Work[w]->results.size() > 0)
PutsIfNonEmpty(Work[w]->name.c_str()); PutsIfNonEmpty(Work[w]->name.c_str());
PutsIfNonEmpty(Work[w]->results.c_str()); PutsIfNonEmpty(Work[w]->results.c_str());
delete Work[w]; delete Work[w];
......
100Limits.vert
ERROR: 0:24: 'limitation' : while loops not available ERROR: 0:24: 'limitation' : while loops not available
ERROR: 0:26: 'limitation' : do-while loops not available ERROR: 0:26: 'limitation' : do-while loops not available
ERROR: 0:28: 'limitations' : inductive-loop init-declaration requires the form "type-specifier loop-index = constant-expression" ERROR: 0:28: 'limitations' : inductive-loop init-declaration requires the form "type-specifier loop-index = constant-expression"
......
...@@ -257,6 +257,19 @@ ERROR: node is still EOpNull! ...@@ -257,6 +257,19 @@ ERROR: node is still EOpNull!
0:120 1.000000 0:120 1.000000
0:120 Constant: 0:120 Constant:
0:120 3 (const int) 0:120 3 (const int)
0:126 Function Definition: foo3( (global void)
0:126 Function Parameters:
0:128 Sequence
0:128 Sequence
0:128 move second child to first child (temp 3X2 matrix of float)
0:128 'r32' (temp 3X2 matrix of float)
0:128 Constant:
0:128 43.000000
0:128 64.000000
0:128 51.000000
0:128 76.000000
0:128 59.000000
0:128 88.000000
0:? Linker Objects 0:? Linker Objects
0:? 'a' (const int) 0:? 'a' (const int)
0:? 1 (const int) 0:? 1 (const int)
...@@ -331,6 +344,18 @@ ERROR: node is still EOpNull! ...@@ -331,6 +344,18 @@ ERROR: node is still EOpNull!
0:? 4.000000 0:? 4.000000
0:? 5.000000 0:? 5.000000
0:? 'a4' (global 2-element array of float) 0:? 'a4' (global 2-element array of float)
0:? 'mm2' (const 2X2 matrix of float)
0:? 1.000000
0:? 2.000000
0:? 3.000000
0:? 4.000000
0:? 'mm32' (const 3X2 matrix of float)
0:? 10.000000
0:? 11.000000
0:? 12.000000
0:? 13.000000
0:? 14.000000
0:? 15.000000
Linked fragment stage: Linked fragment stage:
...@@ -584,6 +609,19 @@ ERROR: node is still EOpNull! ...@@ -584,6 +609,19 @@ ERROR: node is still EOpNull!
0:120 1.000000 0:120 1.000000
0:120 Constant: 0:120 Constant:
0:120 3 (const int) 0:120 3 (const int)
0:126 Function Definition: foo3( (global void)
0:126 Function Parameters:
0:128 Sequence
0:128 Sequence
0:128 move second child to first child (temp 3X2 matrix of float)
0:128 'r32' (temp 3X2 matrix of float)
0:128 Constant:
0:128 43.000000
0:128 64.000000
0:128 51.000000
0:128 76.000000
0:128 59.000000
0:128 88.000000
0:? Linker Objects 0:? Linker Objects
0:? 'a' (const int) 0:? 'a' (const int)
0:? 1 (const int) 0:? 1 (const int)
...@@ -658,4 +696,16 @@ ERROR: node is still EOpNull! ...@@ -658,4 +696,16 @@ ERROR: node is still EOpNull!
0:? 4.000000 0:? 4.000000
0:? 5.000000 0:? 5.000000
0:? 'a4' (global 2-element array of float) 0:? 'a4' (global 2-element array of float)
0:? 'mm2' (const 2X2 matrix of float)
0:? 1.000000
0:? 2.000000
0:? 3.000000
0:? 4.000000
0:? 'mm32' (const 3X2 matrix of float)
0:? 10.000000
0:? 11.000000
0:? 12.000000
0:? 13.000000
0:? 14.000000
0:? 15.000000
spv.bitCast.frag
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Linked fragment stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 172
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 154
ExecutionMode 4 OriginLowerLeft
Source GLSL 450
Name 4 "main"
Name 9 "idata"
Name 14 "f1"
Name 26 "f2"
Name 37 "f3"
Name 48 "f4"
Name 55 "udata"
Name 85 "fdata"
Name 89 "i1"
Name 98 "i2"
Name 107 "i3"
Name 116 "i4"
Name 122 "u1"
Name 130 "u2"
Name 139 "u3"
Name 148 "u4"
Name 154 "fragColor"
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypeVector 6(int) 4
8: TypePointer Function 7(ivec4)
10: 6(int) Constant 0
11: 7(ivec4) ConstantComposite 10 10 10 10
12: TypeFloat 32
13: TypePointer UniformConstant 12(float)
14(f1): 13(ptr) Variable UniformConstant
17: TypeInt 32 0
18: 17(int) Constant 0
19: TypePointer Function 6(int)
24: TypeVector 12(float) 2
25: TypePointer UniformConstant 24(fvec2)
26(f2): 25(ptr) Variable UniformConstant
28: TypeVector 6(int) 2
35: TypeVector 12(float) 3
36: TypePointer UniformConstant 35(fvec3)
37(f3): 36(ptr) Variable UniformConstant
39: TypeVector 6(int) 3
46: TypeVector 12(float) 4
47: TypePointer UniformConstant 46(fvec4)
48(f4): 47(ptr) Variable UniformConstant
53: TypeVector 17(int) 4
54: TypePointer Function 53(ivec4)
56: 53(ivec4) ConstantComposite 18 18 18 18
59: TypePointer Function 17(int)
65: TypeVector 17(int) 2
73: TypeVector 17(int) 3
84: TypePointer Function 46(fvec4)
86: 12(float) Constant 0
87: 46(fvec4) ConstantComposite 86 86 86 86
88: TypePointer UniformConstant 6(int)
89(i1): 88(ptr) Variable UniformConstant
92: TypePointer Function 12(float)
97: TypePointer UniformConstant 28(ivec2)
98(i2): 97(ptr) Variable UniformConstant
106: TypePointer UniformConstant 39(ivec3)
107(i3): 106(ptr) Variable UniformConstant
115: TypePointer UniformConstant 7(ivec4)
116(i4): 115(ptr) Variable UniformConstant
121: TypePointer UniformConstant 17(int)
122(u1): 121(ptr) Variable UniformConstant
129: TypePointer UniformConstant 65(ivec2)
130(u2): 129(ptr) Variable UniformConstant
138: TypePointer UniformConstant 73(ivec3)
139(u3): 138(ptr) Variable UniformConstant
147: TypePointer UniformConstant 53(ivec4)
148(u4): 147(ptr) Variable UniformConstant
153: TypePointer Output 46(fvec4)
154(fragColor): 153(ptr) Variable Output
159: TypeBool
160: TypeVector 159(bool) 4
168: 12(float) Constant 1045220557
169: 46(fvec4) ConstantComposite 168 168 168 168
4(main): 2 Function None 3
5: Label
9(idata): 8(ptr) Variable Function
55(udata): 54(ptr) Variable Function
85(fdata): 84(ptr) Variable Function
155: 84(ptr) Variable Function
Store 9(idata) 11
15: 12(float) Load 14(f1)
16: 6(int) Bitcast 15
20: 19(ptr) AccessChain 9(idata) 18
21: 6(int) Load 20
22: 6(int) IAdd 21 16
23: 19(ptr) AccessChain 9(idata) 18
Store 23 22
27: 24(fvec2) Load 26(f2)
29: 28(ivec2) Bitcast 27
30: 7(ivec4) Load 9(idata)
31: 28(ivec2) VectorShuffle 30 30 0 1
32: 28(ivec2) IAdd 31 29
33: 7(ivec4) Load 9(idata)
34: 7(ivec4) VectorShuffle 33 32 4 5 2 3
Store 9(idata) 34
38: 35(fvec3) Load 37(f3)
40: 39(ivec3) Bitcast 38
41: 7(ivec4) Load 9(idata)
42: 39(ivec3) VectorShuffle 41 41 0 1 2
43: 39(ivec3) IAdd 42 40
44: 7(ivec4) Load 9(idata)
45: 7(ivec4) VectorShuffle 44 43 4 5 6 3
Store 9(idata) 45
49: 46(fvec4) Load 48(f4)
50: 7(ivec4) Bitcast 49
51: 7(ivec4) Load 9(idata)
52: 7(ivec4) IAdd 51 50
Store 9(idata) 52
Store 55(udata) 56
57: 12(float) Load 14(f1)
58: 17(int) Bitcast 57
60: 59(ptr) AccessChain 55(udata) 18
61: 17(int) Load 60
62: 17(int) IAdd 61 58
63: 59(ptr) AccessChain 55(udata) 18
Store 63 62
64: 24(fvec2) Load 26(f2)
66: 65(ivec2) Bitcast 64
67: 53(ivec4) Load 55(udata)
68: 65(ivec2) VectorShuffle 67 67 0 1
69: 65(ivec2) IAdd 68 66
70: 53(ivec4) Load 55(udata)
71: 53(ivec4) VectorShuffle 70 69 4 5 2 3
Store 55(udata) 71
72: 35(fvec3) Load 37(f3)
74: 73(ivec3) Bitcast 72
75: 53(ivec4) Load 55(udata)
76: 73(ivec3) VectorShuffle 75 75 0 1 2
77: 73(ivec3) IAdd 76 74
78: 53(ivec4) Load 55(udata)
79: 53(ivec4) VectorShuffle 78 77 4 5 6 3
Store 55(udata) 79
80: 46(fvec4) Load 48(f4)
81: 53(ivec4) Bitcast 80
82: 53(ivec4) Load 55(udata)
83: 53(ivec4) IAdd 82 81
Store 55(udata) 83
Store 85(fdata) 87
90: 6(int) Load 89(i1)
91: 12(float) Bitcast 90
93: 92(ptr) AccessChain 85(fdata) 18
94: 12(float) Load 93
95: 12(float) FAdd 94 91
96: 92(ptr) AccessChain 85(fdata) 18
Store 96 95
99: 28(ivec2) Load 98(i2)
100: 24(fvec2) Bitcast 99
101: 46(fvec4) Load 85(fdata)
102: 24(fvec2) VectorShuffle 101 101 0 1
103: 24(fvec2) FAdd 102 100
104: 46(fvec4) Load 85(fdata)
105: 46(fvec4) VectorShuffle 104 103 4 5 2 3
Store 85(fdata) 105
108: 39(ivec3) Load 107(i3)
109: 35(fvec3) Bitcast 108
110: 46(fvec4) Load 85(fdata)
111: 35(fvec3) VectorShuffle 110 110 0 1 2
112: 35(fvec3) FAdd 111 109
113: 46(fvec4) Load 85(fdata)
114: 46(fvec4) VectorShuffle 113 112 4 5 6 3
Store 85(fdata) 114
117: 7(ivec4) Load 116(i4)
118: 46(fvec4) Bitcast 117
119: 46(fvec4) Load 85(fdata)
120: 46(fvec4) FAdd 119 118
Store 85(fdata) 120
123: 17(int) Load 122(u1)
124: 12(float) Bitcast 123
125: 92(ptr) AccessChain 85(fdata) 18
126: 12(float) Load 125
127: 12(float) FAdd 126 124
128: 92(ptr) AccessChain 85(fdata) 18
Store 128 127
131: 65(ivec2) Load 130(u2)
132: 24(fvec2) Bitcast 131
133: 46(fvec4) Load 85(fdata)
134: 24(fvec2) VectorShuffle 133 133 0 1
135: 24(fvec2) FAdd 134 132
136: 46(fvec4) Load 85(fdata)
137: 46(fvec4) VectorShuffle 136 135 4 5 2 3
Store 85(fdata) 137
140: 73(ivec3) Load 139(u3)
141: 35(fvec3) Bitcast 140
142: 46(fvec4) Load 85(fdata)
143: 35(fvec3) VectorShuffle 142 142 0 1 2
144: 35(fvec3) FAdd 143 141
145: 46(fvec4) Load 85(fdata)
146: 46(fvec4) VectorShuffle 145 144 4 5 6 3
Store 85(fdata) 146
149: 53(ivec4) Load 148(u4)
150: 46(fvec4) Bitcast 149
151: 46(fvec4) Load 85(fdata)
152: 46(fvec4) FAdd 151 150
Store 85(fdata) 152
156: 7(ivec4) Load 9(idata)
157: 53(ivec4) Bitcast 156
158: 53(ivec4) Load 55(udata)
161: 160(bvec4) IEqual 157 158
162: 159(bool) All 161
SelectionMerge 164 None
BranchConditional 162 163 166
163: Label
165: 46(fvec4) Load 85(fdata)
Store 155 165
Branch 164
166: Label
167: 46(fvec4) Load 85(fdata)
170: 46(fvec4) FAdd 167 169
Store 155 170
Branch 164
164: Label
171: 46(fvec4) Load 155
Store 154(fragColor) 171
Return
FunctionEnd
...@@ -333,7 +333,7 @@ Linked fragment stage: ...@@ -333,7 +333,7 @@ Linked fragment stage:
214: 96 Load 98(i2DMS) 214: 96 Load 98(i2DMS)
215: 29(ivec2) Load 142(ic2D) 215: 29(ivec2) Load 142(ic2D)
217: 125(fvec4) Load 127(v) 217: 125(fvec4) Load 127(v)
ImageWrite 214 215 216 ImageWrite 214 215 217 Sample 216
218: 106 Load 108(i2DMSArray) 218: 106 Load 108(i2DMSArray)
219: 7(ivec3) Load 152(ic3D) 219: 7(ivec3) Load 152(ic3D)
221: 125(fvec4) ImageRead 218 219 Sample 220 221: 125(fvec4) ImageRead 218 219 Sample 220
...@@ -343,7 +343,7 @@ Linked fragment stage: ...@@ -343,7 +343,7 @@ Linked fragment stage:
224: 106 Load 108(i2DMSArray) 224: 106 Load 108(i2DMSArray)
225: 7(ivec3) Load 152(ic3D) 225: 7(ivec3) Load 152(ic3D)
227: 125(fvec4) Load 127(v) 227: 125(fvec4) Load 127(v)
ImageWrite 224 225 226 ImageWrite 224 225 227 Sample 226
Store 229(ui) 19 Store 229(ui) 19
233: 6(int) Load 132(ic1D) 233: 6(int) Load 132(ic1D)
236: 235(ptr) ImageTexelPointer 232(ii1D) 233 0 236: 235(ptr) ImageTexelPointer 232(ii1D) 233 0
......
spv.layoutNested.vert
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 63
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 61 62
Source GLSL 450
Name 4 "main"
Name 14 "S"
MemberName 14(S) 0 "a"
MemberName 14(S) 1 "b"
MemberName 14(S) 2 "c"
Name 19 "Block140"
MemberName 19(Block140) 0 "u"
MemberName 19(Block140) 1 "s"
MemberName 19(Block140) 2 "v"
Name 21 "inst140"
Name 22 "S"
MemberName 22(S) 0 "a"
MemberName 22(S) 1 "b"
MemberName 22(S) 2 "c"
Name 25 "Block430"
MemberName 25(Block430) 0 "u"
MemberName 25(Block430) 1 "s"
MemberName 25(Block430) 2 "v"
Name 27 "inst430"
Name 28 "S"
MemberName 28(S) 0 "a"
MemberName 28(S) 1 "b"
MemberName 28(S) 2 "c"
Name 30 "s"
Name 31 "T"
MemberName 31(T) 0 "m"
MemberName 31(T) 1 "a"
Name 33 "t"
Name 34 "T"
MemberName 34(T) 0 "m"
MemberName 34(T) 1 "a"
Name 35 "Nestor"
MemberName 35(Nestor) 0 "nestorT"
Name 36 "Bt1"
MemberName 36(Bt1) 0 "nt"
Name 38 "Btn1"
Name 39 "T"
MemberName 39(T) 0 "m"
MemberName 39(T) 1 "a"
Name 40 "Nestor"
MemberName 40(Nestor) 0 "nestorT"
Name 41 "Bt2"
MemberName 41(Bt2) 0 "nt"
Name 43 "Btn2"
Name 44 "Bt3"
MemberName 44(Bt3) 0 "ntcol"
MemberName 44(Bt3) 1 "ntrow"
Name 46 "Btn3"
Name 47 "T"
MemberName 47(T) 0 "m"
MemberName 47(T) 1 "a"
Name 48 "Nestor"
MemberName 48(Nestor) 0 "nestorT"
Name 49 "bBt1"
MemberName 49(bBt1) 0 "nt"
Name 51 "bBtn1"
Name 52 "T"
MemberName 52(T) 0 "m"
MemberName 52(T) 1 "a"
Name 53 "Nestor"
MemberName 53(Nestor) 0 "nestorT"
Name 54 "bBt2"
MemberName 54(bBt2) 0 "nt"
Name 56 "bBtn2"
Name 57 "bBt3"
MemberName 57(bBt3) 0 "ntcol"
MemberName 57(bBt3) 1 "ntrow"
Name 59 "bBtn3"
Name 61 "gl_VertexID"
Name 62 "gl_InstanceID"
Decorate 13 ArrayStride 32
MemberDecorate 14(S) 0 Offset 0
MemberDecorate 14(S) 1 ColMajor
MemberDecorate 14(S) 1 Offset 16
MemberDecorate 14(S) 1 MatrixStride 16
MemberDecorate 14(S) 2 Offset 144
Decorate 18 ArrayStride 16
MemberDecorate 19(Block140) 0 Offset 0
MemberDecorate 19(Block140) 1 Offset 16
MemberDecorate 19(Block140) 2 Offset 976
Decorate 19(Block140) Block
Decorate 21(inst140) DescriptorSet 0
Decorate 21(inst140) Binding 0
Decorate 13 ArrayStride 16
MemberDecorate 22(S) 0 Offset 0
MemberDecorate 22(S) 1 ColMajor
MemberDecorate 22(S) 1 Offset 16
MemberDecorate 22(S) 1 MatrixStride 8
MemberDecorate 22(S) 2 Offset 80
Decorate 24 ArrayStride 16
MemberDecorate 25(Block430) 0 Offset 0
MemberDecorate 25(Block430) 1 Offset 16
MemberDecorate 25(Block430) 2 Offset 592
Decorate 25(Block430) BufferBlock
Decorate 27(inst430) DescriptorSet 0
Decorate 27(inst430) Binding 1
MemberDecorate 34(T) 0 RowMajor
MemberDecorate 34(T) 0 Offset 0
MemberDecorate 34(T) 0 MatrixStride 16
MemberDecorate 34(T) 1 Offset 32
MemberDecorate 35(Nestor) 0 Offset 0
MemberDecorate 36(Bt1) 0 Offset 0
Decorate 36(Bt1) Block
Decorate 38(Btn1) DescriptorSet 1
Decorate 38(Btn1) Binding 0
MemberDecorate 39(T) 0 ColMajor
MemberDecorate 39(T) 0 Offset 0
MemberDecorate 39(T) 0 MatrixStride 16
MemberDecorate 39(T) 1 Offset 32
MemberDecorate 40(Nestor) 0 Offset 0
MemberDecorate 41(Bt2) 0 Offset 0
Decorate 41(Bt2) Block
Decorate 43(Btn2) DescriptorSet 1
Decorate 43(Btn2) Binding 0
MemberDecorate 44(Bt3) 0 Offset 0
MemberDecorate 44(Bt3) 1 Offset 48
Decorate 44(Bt3) Block
Decorate 46(Btn3) DescriptorSet 1
Decorate 46(Btn3) Binding 0
MemberDecorate 47(T) 0 RowMajor
MemberDecorate 47(T) 0 Offset 0
MemberDecorate 47(T) 0 MatrixStride 8
MemberDecorate 47(T) 1 Offset 16
MemberDecorate 48(Nestor) 0 Offset 0
MemberDecorate 49(bBt1) 0 Offset 0
Decorate 49(bBt1) BufferBlock
Decorate 51(bBtn1) DescriptorSet 1
Decorate 51(bBtn1) Binding 0
MemberDecorate 52(T) 0 ColMajor
MemberDecorate 52(T) 0 Offset 0
MemberDecorate 52(T) 0 MatrixStride 8
MemberDecorate 52(T) 1 Offset 16
MemberDecorate 53(Nestor) 0 Offset 0
MemberDecorate 54(bBt2) 0 Offset 0
Decorate 54(bBt2) BufferBlock
Decorate 56(bBtn2) DescriptorSet 1
Decorate 56(bBtn2) Binding 0
MemberDecorate 57(bBt3) 0 Offset 0
MemberDecorate 57(bBt3) 1 Offset 24
Decorate 57(bBt3) BufferBlock
Decorate 59(bBtn3) DescriptorSet 1
Decorate 59(bBtn3) Binding 0
Decorate 61(gl_VertexID) BuiltIn VertexId
Decorate 62(gl_InstanceID) BuiltIn InstanceId
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypeInt 32 0
8: TypeVector 7(int) 3
9: TypeFloat 32
10: TypeVector 9(float) 2
11: TypeMatrix 10(fvec2) 2
12: 7(int) Constant 4
13: TypeArray 11 12
14(S): TypeStruct 8(ivec3) 13 7(int)
15: 7(int) Constant 3
16: TypeArray 14(S) 15
17: 7(int) Constant 2
18: TypeArray 16 17
19(Block140): TypeStruct 6(int) 18 10(fvec2)
20: TypePointer Uniform 19(Block140)
21(inst140): 20(ptr) Variable Uniform
22(S): TypeStruct 8(ivec3) 13 7(int)
23: TypeArray 22(S) 15
24: TypeArray 23 17
25(Block430): TypeStruct 6(int) 24 10(fvec2)
26: TypePointer Uniform 25(Block430)
27(inst430): 26(ptr) Variable Uniform
28(S): TypeStruct 8(ivec3) 13 7(int)
29: TypePointer Private 28(S)
30(s): 29(ptr) Variable Private
31(T): TypeStruct 11 6(int)
32: TypePointer Private 31(T)
33(t): 32(ptr) Variable Private
34(T): TypeStruct 11 6(int)
35(Nestor): TypeStruct 34(T)
36(Bt1): TypeStruct 35(Nestor)
37: TypePointer Uniform 36(Bt1)
38(Btn1): 37(ptr) Variable Uniform
39(T): TypeStruct 11 6(int)
40(Nestor): TypeStruct 39(T)
41(Bt2): TypeStruct 40(Nestor)
42: TypePointer Uniform 41(Bt2)
43(Btn2): 42(ptr) Variable Uniform
44(Bt3): TypeStruct 40(Nestor) 35(Nestor)
45: TypePointer Uniform 44(Bt3)
46(Btn3): 45(ptr) Variable Uniform
47(T): TypeStruct 11 6(int)
48(Nestor): TypeStruct 47(T)
49(bBt1): TypeStruct 48(Nestor)
50: TypePointer Uniform 49(bBt1)
51(bBtn1): 50(ptr) Variable Uniform
52(T): TypeStruct 11 6(int)
53(Nestor): TypeStruct 52(T)
54(bBt2): TypeStruct 53(Nestor)
55: TypePointer Uniform 54(bBt2)
56(bBtn2): 55(ptr) Variable Uniform
57(bBt3): TypeStruct 48(Nestor) 53(Nestor)
58: TypePointer Uniform 57(bBt3)
59(bBtn3): 58(ptr) Variable Uniform
60: TypePointer Input 6(int)
61(gl_VertexID): 60(ptr) Variable Input
62(gl_InstanceID): 60(ptr) Variable Input
4(main): 2 Function None 3
5: Label
Return
FunctionEnd
...@@ -119,3 +119,11 @@ void foo2() ...@@ -119,3 +119,11 @@ void foo2()
float f = vec4(7.8 < 2.4 ? -1.333 : 1.444).a; float f = vec4(7.8 < 2.4 ? -1.333 : 1.444).a;
f = vec4(inv.x < 2.4 ? -1.0 : 1.0).a; // not folded, ensuring no propagation f = vec4(inv.x < 2.4 ? -1.0 : 1.0).a; // not folded, ensuring no propagation
} }
const mat2 mm2 = mat2(1.0, 2.0, 3.0, 4.0);
const mat3x2 mm32 = mat3x2(10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
void foo3()
{
mat3x2 r32 = mm2 * mm32;
}
#version 450
uniform int i1;
uniform ivec2 i2;
uniform ivec3 i3;
uniform ivec4 i4;
uniform uint u1;
uniform uvec2 u2;
uniform uvec3 u3;
uniform uvec4 u4;
uniform float f1;
uniform vec2 f2;
uniform vec3 f3;
uniform vec4 f4;
out vec4 fragColor;
void main()
{
ivec4 idata = ivec4(0);
idata.x += floatBitsToInt(f1);
idata.xy += floatBitsToInt(f2);
idata.xyz += floatBitsToInt(f3);
idata += floatBitsToInt(f4);
uvec4 udata = uvec4(0);
udata.x += floatBitsToUint(f1);
udata.xy += floatBitsToUint(f2);
udata.xyz += floatBitsToUint(f3);
udata += floatBitsToUint(f4);
vec4 fdata = vec4(0.0);
fdata.x += intBitsToFloat(i1);
fdata.xy += intBitsToFloat(i2);
fdata.xyz += intBitsToFloat(i3);
fdata += intBitsToFloat(i4);
fdata.x += uintBitsToFloat(u1);
fdata.xy += uintBitsToFloat(u2);
fdata.xyz += uintBitsToFloat(u3);
fdata += uintBitsToFloat(u4);
fragColor = (idata == udata) ? fdata : fdata + vec4(0.2);
}
\ No newline at end of file
#version 450
// should get 3 SPV types for S: no layout, 140, and 430
struct S
{
highp uvec3 a;
mediump mat2 b[4];
lowp uint c;
};
layout(set = 0, binding = 0, std140) uniform Block140
{
mediump int u;
S s[2][3];
mediump vec2 v;
} inst140;
layout(set = 0, binding = 1, std430) buffer Block430
{
mediump int u;
S s[2][3];
mediump vec2 v;
} inst430;
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()
{
}
...@@ -30,6 +30,7 @@ spv.accessChain.frag ...@@ -30,6 +30,7 @@ spv.accessChain.frag
spv.aggOps.frag spv.aggOps.frag
spv.always-discard.frag spv.always-discard.frag
spv.always-discard2.frag spv.always-discard2.frag
spv.bitCast.frag
spv.bool.vert spv.bool.vert
spv.conditionalDiscard.frag spv.conditionalDiscard.frag
spv.conversion.frag spv.conversion.frag
...@@ -47,6 +48,7 @@ spv.forwardFun.frag ...@@ -47,6 +48,7 @@ spv.forwardFun.frag
spv.functionCall.frag spv.functionCall.frag
spv.functionSemantics.frag spv.functionSemantics.frag
spv.interpOps.frag spv.interpOps.frag
spv.layoutNested.vert
spv.length.frag spv.length.frag
spv.localAggregates.frag spv.localAggregates.frag
spv.loops.frag spv.loops.frag
......
...@@ -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.845" #define GLSLANG_REVISION "SPIRV99.861"
#define GLSLANG_DATE "13-Dec-2015" #define GLSLANG_DATE "20-Dec-2015"
...@@ -81,11 +81,12 @@ namespace glslang { ...@@ -81,11 +81,12 @@ namespace glslang {
// //
// //
// Do folding between a pair of nodes // Do folding between a pair of nodes.
// 'this' is the left-hand operand and 'rightConstantNode' is the right-hand operand.
// //
// Returns a new node representing the result. // Returns a new node representing the result.
// //
TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* constantNode) const TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* rightConstantNode) const
{ {
// For most cases, the return type matches the argument type, so set that // For most cases, the return type matches the argument type, so set that
// up and just code to exceptions below. // up and just code to exceptions below.
...@@ -96,37 +97,37 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const ...@@ -96,37 +97,37 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
// A pair of nodes is to be folded together // A pair of nodes is to be folded together
// //
const TIntermConstantUnion *node = constantNode->getAsConstantUnion(); const TIntermConstantUnion *rightNode = rightConstantNode->getAsConstantUnion();
TConstUnionArray unionArray = getConstArray(); TConstUnionArray leftUnionArray = getConstArray();
TConstUnionArray rightUnionArray = node->getConstArray(); TConstUnionArray rightUnionArray = rightNode->getConstArray();
// Figure out the size of the result // Figure out the size of the result
int newComps; int newComps;
int constComps; int constComps;
switch(op) { switch(op) {
case EOpMatrixTimesMatrix: case EOpMatrixTimesMatrix:
newComps = getMatrixRows() * node->getMatrixCols(); newComps = rightNode->getMatrixCols() * getMatrixRows();
break; break;
case EOpMatrixTimesVector: case EOpMatrixTimesVector:
newComps = getMatrixRows(); newComps = getMatrixRows();
break; break;
case EOpVectorTimesMatrix: case EOpVectorTimesMatrix:
newComps = node->getMatrixCols(); newComps = rightNode->getMatrixCols();
break; break;
default: default:
newComps = getType().computeNumComponents(); newComps = getType().computeNumComponents();
constComps = constantNode->getType().computeNumComponents(); constComps = rightConstantNode->getType().computeNumComponents();
if (constComps == 1 && newComps > 1) { if (constComps == 1 && newComps > 1) {
// for a case like vec4 f = vec4(2,3,4,5) + 1.2; // for a case like vec4 f = vec4(2,3,4,5) + 1.2;
TConstUnionArray smearedArray(newComps, node->getConstArray()[0]); TConstUnionArray smearedArray(newComps, rightNode->getConstArray()[0]);
rightUnionArray = smearedArray; rightUnionArray = smearedArray;
} else if (constComps > 1 && newComps == 1) { } else if (constComps > 1 && newComps == 1) {
// for a case like vec4 f = 1.2 + vec4(2,3,4,5); // for a case like vec4 f = 1.2 + vec4(2,3,4,5);
newComps = constComps; newComps = constComps;
rightUnionArray = node->getConstArray(); rightUnionArray = rightNode->getConstArray();
TConstUnionArray smearedArray(newComps, getConstArray()[0]); TConstUnionArray smearedArray(newComps, getConstArray()[0]);
unionArray = smearedArray; leftUnionArray = smearedArray;
returnType.shallowCopy(node->getType()); returnType.shallowCopy(rightNode->getType());
} }
break; break;
} }
...@@ -137,52 +138,52 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const ...@@ -137,52 +138,52 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
switch(op) { switch(op) {
case EOpAdd: case EOpAdd:
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] + rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] + rightUnionArray[i];
break; break;
case EOpSub: case EOpSub:
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] - rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] - rightUnionArray[i];
break; break;
case EOpMul: case EOpMul:
case EOpVectorTimesScalar: case EOpVectorTimesScalar:
case EOpMatrixTimesScalar: case EOpMatrixTimesScalar:
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] * rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] * rightUnionArray[i];
break; break;
case EOpMatrixTimesMatrix: case EOpMatrixTimesMatrix:
for (int row = 0; row < getMatrixRows(); row++) { for (int row = 0; row < getMatrixRows(); row++) {
for (int column = 0; column < node->getMatrixCols(); column++) { for (int column = 0; column < rightNode->getMatrixCols(); column++) {
double sum = 0.0f; double sum = 0.0f;
for (int i = 0; i < node->getMatrixRows(); i++) for (int i = 0; i < rightNode->getMatrixRows(); i++)
sum += unionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * node->getMatrixRows() + i].getDConst(); sum += leftUnionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * rightNode->getMatrixRows() + i].getDConst();
newConstArray[column * getMatrixRows() + row].setDConst(sum); newConstArray[column * getMatrixRows() + row].setDConst(sum);
} }
} }
returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols())); returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, rightNode->getMatrixCols(), getMatrixRows()));
break; break;
case EOpDiv: case EOpDiv:
for (int i = 0; i < newComps; i++) { for (int i = 0; i < newComps; i++) {
switch (getType().getBasicType()) { switch (getType().getBasicType()) {
case EbtDouble: case EbtDouble:
case EbtFloat: case EbtFloat:
newConstArray[i].setDConst(unionArray[i].getDConst() / rightUnionArray[i].getDConst()); newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst());
break; break;
case EbtInt: case EbtInt:
if (rightUnionArray[i] == 0) if (rightUnionArray[i] == 0)
newConstArray[i].setIConst(0x7FFFFFFF); newConstArray[i].setIConst(0x7FFFFFFF);
else if (rightUnionArray[i].getIConst() == -1 && unionArray[i].getIConst() == 0x80000000) else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == 0x80000000)
newConstArray[i].setIConst(0x80000000); newConstArray[i].setIConst(0x80000000);
else else
newConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst()); newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
break; break;
case EbtUint: case EbtUint:
if (rightUnionArray[i] == 0) { if (rightUnionArray[i] == 0) {
newConstArray[i].setUConst(0xFFFFFFFF); newConstArray[i].setUConst(0xFFFFFFFF);
} else } else
newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst()); newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
break; break;
default: default:
return 0; return 0;
...@@ -193,8 +194,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const ...@@ -193,8 +194,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
case EOpMatrixTimesVector: case EOpMatrixTimesVector:
for (int i = 0; i < getMatrixRows(); i++) { for (int i = 0; i < getMatrixRows(); i++) {
double sum = 0.0f; double sum = 0.0f;
for (int j = 0; j < node->getVectorSize(); j++) { for (int j = 0; j < rightNode->getVectorSize(); j++) {
sum += unionArray[j*getMatrixRows() + i].getDConst() * rightUnionArray[j].getDConst(); sum += leftUnionArray[j*getMatrixRows() + i].getDConst() * rightUnionArray[j].getDConst();
} }
newConstArray[i].setDConst(sum); newConstArray[i].setDConst(sum);
} }
...@@ -203,89 +204,89 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const ...@@ -203,89 +204,89 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
break; break;
case EOpVectorTimesMatrix: case EOpVectorTimesMatrix:
for (int i = 0; i < node->getMatrixCols(); i++) { for (int i = 0; i < rightNode->getMatrixCols(); i++) {
double sum = 0.0f; double sum = 0.0f;
for (int j = 0; j < getVectorSize(); j++) for (int j = 0; j < getVectorSize(); j++)
sum += unionArray[j].getDConst() * rightUnionArray[i*node->getMatrixRows() + j].getDConst(); sum += leftUnionArray[j].getDConst() * rightUnionArray[i*rightNode->getMatrixRows() + j].getDConst();
newConstArray[i].setDConst(sum); newConstArray[i].setDConst(sum);
} }
returnType.shallowCopy(TType(getBasicType(), EvqConst, node->getMatrixCols())); returnType.shallowCopy(TType(getBasicType(), EvqConst, rightNode->getMatrixCols()));
break; break;
case EOpMod: case EOpMod:
for (int i = 0; i < newComps; i++) { for (int i = 0; i < newComps; i++) {
if (rightUnionArray[i] == 0) if (rightUnionArray[i] == 0)
newConstArray[i] = unionArray[i]; newConstArray[i] = leftUnionArray[i];
else else
newConstArray[i] = unionArray[i] % rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] % rightUnionArray[i];
} }
break; break;
case EOpRightShift: case EOpRightShift:
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] >> rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] >> rightUnionArray[i];
break; break;
case EOpLeftShift: case EOpLeftShift:
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] << rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] << rightUnionArray[i];
break; break;
case EOpAnd: case EOpAnd:
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] & rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] & rightUnionArray[i];
break; break;
case EOpInclusiveOr: case EOpInclusiveOr:
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] | rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] | rightUnionArray[i];
break; break;
case EOpExclusiveOr: case EOpExclusiveOr:
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] ^ rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] ^ rightUnionArray[i];
break; break;
case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] && rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] && rightUnionArray[i];
break; break;
case EOpLogicalOr: // this code is written for possible future use, will not get executed currently case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
for (int i = 0; i < newComps; i++) for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] || rightUnionArray[i]; newConstArray[i] = leftUnionArray[i] || rightUnionArray[i];
break; break;
case EOpLogicalXor: case EOpLogicalXor:
for (int i = 0; i < newComps; i++) { for (int i = 0; i < newComps; i++) {
switch (getType().getBasicType()) { switch (getType().getBasicType()) {
case EbtBool: newConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break; case EbtBool: newConstArray[i].setBConst((leftUnionArray[i] == rightUnionArray[i]) ? false : true); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
} }
break; break;
case EOpLessThan: case EOpLessThan:
newConstArray[0].setBConst(unionArray[0] < rightUnionArray[0]); newConstArray[0].setBConst(leftUnionArray[0] < rightUnionArray[0]);
returnType.shallowCopy(constBool); returnType.shallowCopy(constBool);
break; break;
case EOpGreaterThan: case EOpGreaterThan:
newConstArray[0].setBConst(unionArray[0] > rightUnionArray[0]); newConstArray[0].setBConst(leftUnionArray[0] > rightUnionArray[0]);
returnType.shallowCopy(constBool); returnType.shallowCopy(constBool);
break; break;
case EOpLessThanEqual: case EOpLessThanEqual:
newConstArray[0].setBConst(! (unionArray[0] > rightUnionArray[0])); newConstArray[0].setBConst(! (leftUnionArray[0] > rightUnionArray[0]));
returnType.shallowCopy(constBool); returnType.shallowCopy(constBool);
break; break;
case EOpGreaterThanEqual: case EOpGreaterThanEqual:
newConstArray[0].setBConst(! (unionArray[0] < rightUnionArray[0])); newConstArray[0].setBConst(! (leftUnionArray[0] < rightUnionArray[0]));
returnType.shallowCopy(constBool); returnType.shallowCopy(constBool);
break; break;
case EOpEqual: case EOpEqual:
newConstArray[0].setBConst(node->getConstArray() == unionArray); newConstArray[0].setBConst(rightNode->getConstArray() == leftUnionArray);
returnType.shallowCopy(constBool); returnType.shallowCopy(constBool);
break; break;
case EOpNotEqual: case EOpNotEqual:
newConstArray[0].setBConst(node->getConstArray() != unionArray); newConstArray[0].setBConst(rightNode->getConstArray() != leftUnionArray);
returnType.shallowCopy(constBool); returnType.shallowCopy(constBool);
break; break;
......
...@@ -3048,7 +3048,7 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, EShLanguage langua ...@@ -3048,7 +3048,7 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, EShLanguage langua
SpecialQualifier("gl_FragColor", EvqFragColor, EbvFragColor, symbolTable); SpecialQualifier("gl_FragColor", EvqFragColor, EbvFragColor, symbolTable);
SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable); SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable);
SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable); SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable);
SpecialQualifier("gl_HelperInvocation", EvqIn, EbvHelperInvocation, symbolTable); SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable);
BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable); BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable);
BuiltInVariable("gl_CullDistance", EbvCullDistance, symbolTable); BuiltInVariable("gl_CullDistance", EbvCullDistance, symbolTable);
......
...@@ -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."
......
...@@ -309,7 +309,7 @@ struct str_hash ...@@ -309,7 +309,7 @@ struct str_hash
unsigned long hash = 5381; unsigned long hash = 5381;
int c; int c;
while (c = *str++) while ((c = *str++))
hash = ((hash << 5) + hash) + c; hash = ((hash << 5) + hash) + c;
return hash; return hash;
......
...@@ -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