SPV: Fix #723: construct vectors from matrices.
This commit is contained in:
parent
36852b838d
commit
0302bdf04a
4 changed files with 87 additions and 19 deletions
|
|
@ -1832,34 +1832,72 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
|
|||
if (sources.size() == 1 && isScalar(sources[0]) && numTargetComponents > 1)
|
||||
return smearScalar(precision, sources[0], resultTypeId);
|
||||
|
||||
// accumulate the arguments for OpCompositeConstruct
|
||||
std::vector<Id> constituents;
|
||||
Id scalarTypeId = getScalarTypeId(resultTypeId);
|
||||
std::vector<Id> constituents; // accumulate the arguments for OpCompositeConstruct
|
||||
for (unsigned int i = 0; i < sources.size(); ++i) {
|
||||
assert(! isAggregate(sources[i]));
|
||||
unsigned int sourceSize = getNumComponents(sources[i]);
|
||||
|
||||
// lambda to store the result of visiting an argument component
|
||||
const auto latchResult = [&](Id comp) {
|
||||
if (numTargetComponents > 1)
|
||||
constituents.push_back(comp);
|
||||
else
|
||||
result = comp;
|
||||
++targetComponent;
|
||||
};
|
||||
|
||||
// lambda to visit a vector argument's components
|
||||
const auto accumulateVectorConstituents = [&](Id sourceArg) {
|
||||
unsigned int sourceSize = getNumComponents(sourceArg);
|
||||
unsigned int sourcesToUse = sourceSize;
|
||||
if (sourcesToUse + targetComponent > numTargetComponents)
|
||||
sourcesToUse = numTargetComponents - targetComponent;
|
||||
|
||||
for (unsigned int s = 0; s < sourcesToUse; ++s) {
|
||||
Id arg = sources[i];
|
||||
if (sourceSize > 1) {
|
||||
std::vector<unsigned> swiz;
|
||||
swiz.push_back(s);
|
||||
arg = createRvalueSwizzle(precision, scalarTypeId, arg, swiz);
|
||||
}
|
||||
|
||||
if (numTargetComponents > 1)
|
||||
constituents.push_back(arg);
|
||||
else
|
||||
result = arg;
|
||||
++targetComponent;
|
||||
std::vector<unsigned> swiz;
|
||||
swiz.push_back(s);
|
||||
latchResult(createRvalueSwizzle(precision, scalarTypeId, sourceArg, swiz));
|
||||
}
|
||||
};
|
||||
|
||||
// lambda to visit a matrix argument's components
|
||||
const auto accumulateMatrixConstituents = [&](Id sourceArg) {
|
||||
unsigned int sourceSize = getNumColumns(sourceArg) * getNumRows(sourceArg);
|
||||
unsigned int sourcesToUse = sourceSize;
|
||||
if (sourcesToUse + targetComponent > numTargetComponents)
|
||||
sourcesToUse = numTargetComponents - targetComponent;
|
||||
|
||||
int col = 0;
|
||||
int row = 0;
|
||||
for (unsigned int s = 0; s < sourcesToUse; ++s) {
|
||||
if (row >= getNumRows(sourceArg)) {
|
||||
row = 0;
|
||||
col++;
|
||||
}
|
||||
std::vector<Id> indexes;
|
||||
indexes.push_back(col);
|
||||
indexes.push_back(row);
|
||||
latchResult(createCompositeExtract(sourceArg, scalarTypeId, indexes));
|
||||
row++;
|
||||
}
|
||||
};
|
||||
|
||||
// Go through the source arguments, each one could have either
|
||||
// a single or multiple components to contribute.
|
||||
for (unsigned int i = 0; i < sources.size(); ++i) {
|
||||
if (isScalar(sources[i]))
|
||||
latchResult(sources[i]);
|
||||
else if (isVector(sources[i]))
|
||||
accumulateVectorConstituents(sources[i]);
|
||||
else if (isMatrix(sources[i]))
|
||||
accumulateMatrixConstituents(sources[i]);
|
||||
else
|
||||
assert(0);
|
||||
|
||||
if (targetComponent >= numTargetComponents)
|
||||
break;
|
||||
}
|
||||
|
||||
// If the result is a vector, make it from the gathered constituents.
|
||||
if (constituents.size() > 0)
|
||||
result = createCompositeConstruct(resultTypeId, constituents);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue