Commit b3e24e43 by John Kessenich

SPV: Fix issue #506: generalize struct deep copy to include arrays.

parent cd0a78a0
...@@ -2283,13 +2283,13 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I ...@@ -2283,13 +2283,13 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
// Implicitly uses the existing builder.accessChain as the storage target. // Implicitly uses the existing builder.accessChain as the storage target.
void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id rValue) void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id rValue)
{ {
// we only do the complex path here if it's a structure // we only do the complex path here if it's an aggregate
if (! type.isStruct()) { if (! type.isStruct() && ! type.isArray()) {
accessChainStore(type, rValue); accessChainStore(type, rValue);
return; return;
} }
// and, it has to be a case of structure type aliasing // and, it has to be a case of type aliasing
spv::Id rType = builder.getTypeId(rValue); spv::Id rType = builder.getTypeId(rValue);
spv::Id lValue = builder.accessChainGetLValue(); spv::Id lValue = builder.accessChainGetLValue();
spv::Id lType = builder.getContainedTypeId(builder.getTypeId(lValue)); spv::Id lType = builder.getContainedTypeId(builder.getTypeId(lValue));
...@@ -2298,26 +2298,46 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id ...@@ -2298,26 +2298,46 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
return; return;
} }
// Recursively (as needed) copy a struct type to a different struct type, // Recursively (as needed) copy an aggregate type to a different aggregate type,
// where the two types were the same type in GLSL. This requires member // where the two types were the same type in GLSL. This requires member
// by member copy, recursively. // by member copy, recursively.
// loop over members // If an array, copy element by element.
const glslang::TTypeList& members = *type.getStruct(); if (type.isArray()) {
for (int m = 0; m < (int)members.size(); ++m) { glslang::TType glslangElementType(type, 0);
const glslang::TType& glslangMemberType = *members[m].type; spv::Id elementRType = builder.getContainedTypeId(rType);
for (int index = 0; index < type.getOuterArraySize(); ++index) {
// get the source member
spv::Id elementRValue = builder.createCompositeExtract(rValue, elementRType, index);
// get the source member // set up the target storage
spv::Id memberRType = builder.getContainedTypeId(rType, m); builder.clearAccessChain();
spv::Id memberRValue = builder.createCompositeExtract(rValue, memberRType, m); builder.setAccessChainLValue(lValue);
builder.accessChainPush(builder.makeIntConstant(index));
// set up the target storage // store the member
builder.clearAccessChain(); multiTypeStore(glslangElementType, elementRValue);
builder.setAccessChainLValue(lValue); }
builder.accessChainPush(builder.makeIntConstant(m)); } else {
assert(type.isStruct());
// store the member // loop over structure members
multiTypeStore(glslangMemberType, memberRValue); const glslang::TTypeList& members = *type.getStruct();
for (int m = 0; m < (int)members.size(); ++m) {
const glslang::TType& glslangMemberType = *members[m].type;
// get the source member
spv::Id memberRType = builder.getContainedTypeId(rType, m);
spv::Id memberRValue = builder.createCompositeExtract(rValue, memberRType, m);
// set up the target storage
builder.clearAccessChain();
builder.setAccessChainLValue(lValue);
builder.accessChainPush(builder.makeIntConstant(m));
// store the member
multiTypeStore(glslangMemberType, memberRValue);
}
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
struct MyStruct struct MyStruct
{ {
vec4 foo; vec2 foo[2];
bool sb; bool sb;
}; };
...@@ -23,7 +23,7 @@ layout(binding = 2, std140) uniform UBO ...@@ -23,7 +23,7 @@ layout(binding = 2, std140) uniform UBO
struct Nested { struct Nested {
float f; float f;
MyStruct S; MyStruct S[2];
}; };
layout(binding = 2, std140) uniform UBON layout(binding = 2, std140) uniform UBON
......
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
// 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 "Overload400-PrecQual.1481" #define GLSLANG_REVISION "Overload400-PrecQual.1481"
#define GLSLANG_DATE "10-Sep-2016" #define GLSLANG_DATE "11-Sep-2016"
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