Commit 6090df0f by John Kessenich

SPV: Non-functional: break up big function into three smaller ones.

Also, improve variable names. This grew to be overly hard to understand.
parent 266b1d3e
...@@ -115,6 +115,10 @@ protected: ...@@ -115,6 +115,10 @@ protected:
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, glslang::TLayoutPacking, const glslang::TQualifier&); spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&);
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
glslang::TLayoutPacking, const glslang::TQualifier&);
void decorateStructType(const glslang::TType&, const glslang::TTypeList* glslangStruct, glslang::TLayoutPacking,
const glslang::TQualifier&, spv::Id);
spv::Id makeArraySizeId(const glslang::TArraySizes&, int dim); spv::Id makeArraySizeId(const glslang::TArraySizes&, int dim);
spv::Id accessChainLoad(const glslang::TType& type); spv::Id accessChainLoad(const glslang::TType& type);
void accessChainStore(const glslang::TType& type, spv::Id rvalue); void accessChainStore(const glslang::TType& type, spv::Id rvalue);
...@@ -1789,6 +1793,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1789,6 +1793,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
// 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 hierarchical recursive walk. // explicitLayout can be kept the same throughout the hierarchical recursive walk.
// Mutually recursive with convertGlslangStructToSpvType().
spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier) spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier)
{ {
spv::Id spvType = spv::NoResult; spv::Id spvType = spv::NoResult;
...@@ -1851,82 +1856,165 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1851,82 +1856,165 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
case glslang::EbtBlock: case glslang::EbtBlock:
{ {
// 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* glslangMembers = type.getStruct();
std::vector<spv::Id> structFields;
// Try to share structs for different layouts, but not yet for other // Try to share structs for different layouts, but not yet for other
// kinds of qualification (primarily not yet including interpolant qualification). // kinds of qualification (primarily not yet including interpolant qualification).
if (! HasNonLayoutQualifiers(qualifier)) if (! HasNonLayoutQualifiers(qualifier))
spvType = structMap[explicitLayout][qualifier.layoutMatrix][glslangStruct]; spvType = structMap[explicitLayout][qualifier.layoutMatrix][glslangMembers];
if (spvType != spv::NoResult) if (spvType != spv::NoResult)
break; break;
// else, we haven't seen it... // else, we haven't seen it...
if (type.getBasicType() == glslang::EbtBlock)
memberRemapper[glslangMembers].resize(glslangMembers->size());
spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier);
}
break;
default:
assert(0);
break;
}
if (type.isMatrix())
spvType = builder.makeMatrixType(spvType, type.getMatrixCols(), type.getMatrixRows());
else {
// If this variable has a vector element count greater than 1, create a SPIR-V vector
if (type.getVectorSize() > 1)
spvType = builder.makeVectorType(spvType, type.getVectorSize());
}
if (type.isArray()) {
int stride = 0; // keep this 0 unless doing an explicit layout; 0 will mean no decoration, no stride
// Do all but the outer dimension
if (type.getArraySizes()->getNumDims() > 1) {
// We need to decorate array strides for types needing explicit layout, except blocks.
if (explicitLayout != glslang::ElpNone && type.getBasicType() != glslang::EbtBlock) {
// Use a dummy glslang type for querying internal strides of
// arrays of arrays, but using just a one-dimensional array.
glslang::TType simpleArrayType(type, 0); // deference type of the array
while (simpleArrayType.getArraySizes().getNumDims() > 1)
simpleArrayType.getArraySizes().dereference();
// Will compute the higher-order strides here, rather than making a whole
// pile of types and doing repetitive recursion on their contents.
stride = getArrayStride(simpleArrayType, explicitLayout, qualifier.layoutMatrix);
}
// make the arrays
for (int dim = type.getArraySizes()->getNumDims() - 1; dim > 0; --dim) {
spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), dim), stride);
if (stride > 0)
builder.addDecoration(spvType, spv::DecorationArrayStride, stride);
stride *= type.getArraySizes()->getDimSize(dim);
}
} else {
// single-dimensional array, and don't yet have stride
// We need to decorate array strides for types needing explicit layout, except blocks.
if (explicitLayout != glslang::ElpNone && type.getBasicType() != glslang::EbtBlock)
stride = getArrayStride(type, explicitLayout, qualifier.layoutMatrix);
}
// Do the outer dimension, which might not be known for a runtime-sized array
if (type.isRuntimeSizedArray()) {
spvType = builder.makeRuntimeArray(spvType);
} else {
assert(type.getOuterArraySize() > 0);
spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
}
if (stride > 0)
builder.addDecoration(spvType, spv::DecorationArrayStride, stride);
}
return spvType;
}
// Do full recursive conversion of a glslang structure (or block) type to a SPIR-V Id.
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
// Mutually recursive with convertGlslangToSpvType().
spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TType& type,
const glslang::TTypeList* glslangMembers,
glslang::TLayoutPacking explicitLayout,
const glslang::TQualifier& qualifier)
{
// Create a vector of struct types for SPIR-V to consume // Create a vector of struct types for SPIR-V to consume
std::vector<spv::Id> spvMembers;
int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
if (type.getBasicType() == glslang::EbtBlock)
memberRemapper[glslangStruct].resize(glslangStruct->size());
int locationOffset = 0; // for use across struct members, when they are called recursively int locationOffset = 0; // for use across struct members, when they are called recursively
for (int i = 0; i < (int)glslangStruct->size(); i++) { for (int i = 0; i < (int)glslangMembers->size(); i++) {
glslang::TType& glslangType = *(*glslangStruct)[i].type; glslang::TType& glslangMember = *(*glslangMembers)[i].type;
if (glslangType.hiddenMember()) { if (glslangMember.hiddenMember()) {
++memberDelta; ++memberDelta;
if (type.getBasicType() == glslang::EbtBlock) if (type.getBasicType() == glslang::EbtBlock)
memberRemapper[glslangStruct][i] = -1; memberRemapper[glslangMembers][i] = -1;
} else { } else {
if (type.getBasicType() == glslang::EbtBlock) if (type.getBasicType() == glslang::EbtBlock)
memberRemapper[glslangStruct][i] = i - memberDelta; memberRemapper[glslangMembers][i] = i - memberDelta;
// modify just this child's view of the qualifier // modify just this child's view of the qualifier
glslang::TQualifier subQualifier = glslangType.getQualifier(); glslang::TQualifier memberQualifier = glslangMember.getQualifier();
InheritQualifiers(subQualifier, qualifier); InheritQualifiers(memberQualifier, qualifier);
// manually inherit location; it's more complex // manually inherit location; it's more complex
if (! subQualifier.hasLocation() && qualifier.hasLocation()) if (! memberQualifier.hasLocation() && qualifier.hasLocation())
subQualifier.layoutLocation = qualifier.layoutLocation + locationOffset; memberQualifier.layoutLocation = qualifier.layoutLocation + locationOffset;
if (qualifier.hasLocation()) if (qualifier.hasLocation())
locationOffset += glslangIntermediate->computeTypeLocationSize(glslangType); locationOffset += glslangIntermediate->computeTypeLocationSize(glslangMember);
// recurse // recurse
structFields.push_back(convertGlslangToSpvType(glslangType, explicitLayout, subQualifier)); spvMembers.push_back(convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier));
} }
} }
// Make the SPIR-V type // Make the SPIR-V type
spvType = builder.makeStructType(structFields, type.getTypeName().c_str()); spv::Id spvType = builder.makeStructType(spvMembers, type.getTypeName().c_str());
if (! HasNonLayoutQualifiers(qualifier)) if (! HasNonLayoutQualifiers(qualifier))
structMap[explicitLayout][qualifier.layoutMatrix][glslangStruct] = spvType; structMap[explicitLayout][qualifier.layoutMatrix][glslangMembers] = spvType;
// Decorate it
decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType);
return spvType;
}
void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
const glslang::TTypeList* glslangMembers,
glslang::TLayoutPacking explicitLayout,
const glslang::TQualifier& qualifier,
spv::Id spvType)
{
// Name and decorate the non-hidden members // Name and decorate the non-hidden members
int offset = -1; int offset = -1;
locationOffset = 0; // for use within the members of this struct, right now int locationOffset = 0; // for use within the members of this struct
for (int i = 0; i < (int)glslangStruct->size(); i++) { for (int i = 0; i < (int)glslangMembers->size(); i++) {
glslang::TType& glslangType = *(*glslangStruct)[i].type; glslang::TType& glslangMember = *(*glslangMembers)[i].type;
int member = i; int member = i;
if (type.getBasicType() == glslang::EbtBlock) if (type.getBasicType() == glslang::EbtBlock)
member = memberRemapper[glslangStruct][i]; member = memberRemapper[glslangMembers][i];
// modify just this child's view of the qualifier // modify just this child's view of the qualifier
glslang::TQualifier subQualifier = glslangType.getQualifier(); glslang::TQualifier memberQualifier = glslangMember.getQualifier();
InheritQualifiers(subQualifier, qualifier); InheritQualifiers(memberQualifier, qualifier);
// 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, glslangMember.getFieldName().c_str());
addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangType, subQualifier.layoutMatrix)); addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix));
addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangType)); addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember));
// Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes // Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes
if (type.getQualifier().storage == glslang::EvqVaryingIn || type.getQualifier().storage == glslang::EvqVaryingOut) { if (type.getQualifier().storage == glslang::EvqVaryingIn || type.getQualifier().storage == glslang::EvqVaryingOut) {
if (type.getBasicType() == glslang::EbtBlock) { if (type.getBasicType() == glslang::EbtBlock) {
addMemberDecoration(spvType, member, TranslateInterpolationDecoration(subQualifier)); addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(subQualifier)); addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
} }
} }
addMemberDecoration(spvType, member, TranslateInvariantDecoration(subQualifier)); addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
if (qualifier.storage == glslang::EvqBuffer) { if (qualifier.storage == glslang::EvqBuffer) {
std::vector<spv::Decoration> memory; std::vector<spv::Decoration> memory;
TranslateMemoryDecoration(subQualifier, memory); TranslateMemoryDecoration(memberQualifier, memory);
for (unsigned int i = 0; i < memory.size(); ++i) for (unsigned int i = 0; i < memory.size(); ++i)
addMemberDecoration(spvType, member, memory[i]); addMemberDecoration(spvType, member, memory[i]);
} }
...@@ -1936,40 +2024,39 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1936,40 +2024,39 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
// probably move to the linker stage of the front end proper, and just have the // probably move to the linker stage of the front end proper, and just have the
// answer sitting already distributed throughout the individual member locations. // answer sitting already distributed throughout the individual member locations.
int location = -1; // will only decorate if present or inherited int location = -1; // will only decorate if present or inherited
if (subQualifier.hasLocation()) { // no inheritance, or override of inheritance if (memberQualifier.hasLocation()) { // no inheritance, or override of inheritance
// struct members should not have explicit locations // struct members should not have explicit locations
assert(type.getBasicType() != glslang::EbtStruct); assert(type.getBasicType() != glslang::EbtStruct);
location = subQualifier.layoutLocation; location = memberQualifier.layoutLocation;
} else if (type.getBasicType() != glslang::EbtBlock) { } else if (type.getBasicType() != glslang::EbtBlock) {
// If it is a not a Block, (...) Its members are assigned consecutive locations (...) // If it is a not a Block, (...) Its members are assigned consecutive locations (...)
// The members, and their nested types, must not themselves have Location decorations. // The members, and their nested types, must not themselves have Location decorations.
} } else if (qualifier.hasLocation()) // inheritance
else if (qualifier.hasLocation()) // inheritance
location = qualifier.layoutLocation + locationOffset; location = qualifier.layoutLocation + locationOffset;
if (qualifier.hasLocation()) // track for upcoming inheritance if (qualifier.hasLocation()) // track for upcoming inheritance
locationOffset += glslangIntermediate->computeTypeLocationSize(glslangType); locationOffset += glslangIntermediate->computeTypeLocationSize(glslangMember);
if (location >= 0) if (location >= 0)
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, location); builder.addMemberDecoration(spvType, member, spv::DecorationLocation, location);
// component, XFB, others // component, XFB, others
if (glslangType.getQualifier().hasComponent()) if (glslangMember.getQualifier().hasComponent())
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent); builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangMember.getQualifier().layoutComponent);
if (glslangType.getQualifier().hasXfbOffset()) if (glslangMember.getQualifier().hasXfbOffset())
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset); builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangMember.getQualifier().layoutXfbOffset);
else if (explicitLayout != glslang::ElpNone) { 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, explicitLayout, subQualifier.layoutMatrix); updateMemberOffset(type, glslangMember, offset, nextOffset, explicitLayout, memberQualifier.layoutMatrix);
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 != glslang::ElpNone) if (glslangMember.isMatrix() && explicitLayout != glslang::ElpNone)
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangType, explicitLayout, subQualifier.layoutMatrix)); builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangMember, explicitLayout, memberQualifier.layoutMatrix));
// built-in variable decorations // built-in variable decorations
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn, true); spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
if (builtIn != spv::BadValue) if (builtIn != spv::BadValue)
addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn); addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
} }
...@@ -1989,66 +2076,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty ...@@ -1989,66 +2076,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
if (type.getQualifier().hasXfbBuffer()) if (type.getQualifier().hasXfbBuffer())
builder.addDecoration(spvType, spv::DecorationXfbBuffer, type.getQualifier().layoutXfbBuffer); builder.addDecoration(spvType, spv::DecorationXfbBuffer, type.getQualifier().layoutXfbBuffer);
} }
}
break;
default:
assert(0);
break;
}
if (type.isMatrix())
spvType = builder.makeMatrixType(spvType, type.getMatrixCols(), type.getMatrixRows());
else {
// If this variable has a vector element count greater than 1, create a SPIR-V vector
if (type.getVectorSize() > 1)
spvType = builder.makeVectorType(spvType, type.getVectorSize());
}
if (type.isArray()) {
int stride = 0; // keep this 0 unless doing an explicit layout; 0 will mean no decoration, no stride
// Do all but the outer dimension
if (type.getArraySizes()->getNumDims() > 1) {
// We need to decorate array strides for types needing explicit layout, except blocks.
if (explicitLayout != glslang::ElpNone && type.getBasicType() != glslang::EbtBlock) {
// Use a dummy glslang type for querying internal strides of
// arrays of arrays, but using just a one-dimensional array.
glslang::TType simpleArrayType(type, 0); // deference type of the array
while (simpleArrayType.getArraySizes().getNumDims() > 1)
simpleArrayType.getArraySizes().dereference();
// Will compute the higher-order strides here, rather than making a whole
// pile of types and doing repetitive recursion on their contents.
stride = getArrayStride(simpleArrayType, explicitLayout, qualifier.layoutMatrix);
}
// make the arrays
for (int dim = type.getArraySizes()->getNumDims() - 1; dim > 0; --dim) {
spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), dim), stride);
if (stride > 0)
builder.addDecoration(spvType, spv::DecorationArrayStride, stride);
stride *= type.getArraySizes()->getDimSize(dim);
}
} else {
// single-dimensional array, and don't yet have stride
// We need to decorate array strides for types needing explicit layout, except blocks.
if (explicitLayout != glslang::ElpNone && type.getBasicType() != glslang::EbtBlock)
stride = getArrayStride(type, explicitLayout, qualifier.layoutMatrix);
}
// Do the outer dimension, which might not be known for a runtime-sized array
if (type.isRuntimeSizedArray()) {
spvType = builder.makeRuntimeArray(spvType);
} else {
assert(type.getOuterArraySize() > 0);
spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
}
if (stride > 0)
builder.addDecoration(spvType, spv::DecorationArrayStride, stride);
}
return spvType;
} }
// Turn the expression forming the array size into an id. // Turn the expression forming the array size into an id.
......
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