SPV: Reduce spurious type generation by removing intermediate types in the middle of access chains.
This generally simplifies access chain generation, with far fewer type conversions. It is particularly important to future SPIR-V changes where there is less aggregate type uniqueness due to carrying different layout information with the type.
This commit is contained in:
@@ -530,12 +530,12 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
||||
// evaluate the right
|
||||
builder.clearAccessChain();
|
||||
node->getRight()->traverse(this);
|
||||
spv::Id rValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
|
||||
spv::Id rValue = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
|
||||
|
||||
if (node->getOp() != glslang::EOpAssign) {
|
||||
// the left is also an r-value
|
||||
builder.setAccessChain(lValue);
|
||||
spv::Id leftRValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
|
||||
spv::Id leftRValue = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType()));
|
||||
|
||||
// do the operation
|
||||
rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()),
|
||||
@@ -587,10 +587,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
||||
// so short circuit the access-chain stuff with a swizzle.
|
||||
std::vector<unsigned> swizzle;
|
||||
swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst());
|
||||
builder.accessChainPushSwizzle(swizzle);
|
||||
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
|
||||
} else {
|
||||
// normal case for indexing array or structure or block
|
||||
builder.accessChainPush(builder.makeIntConstant(index), convertGlslangToSpvType(node->getType()));
|
||||
builder.accessChainPush(builder.makeIntConstant(index));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -611,15 +611,15 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
||||
// compute the next index in the chain
|
||||
builder.clearAccessChain();
|
||||
node->getRight()->traverse(this);
|
||||
spv::Id index = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
|
||||
spv::Id index = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
|
||||
|
||||
// restore the saved access chain
|
||||
builder.setAccessChain(partial);
|
||||
|
||||
if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
|
||||
builder.accessChainPushComponent(index);
|
||||
builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()));
|
||||
else
|
||||
builder.accessChainPush(index, convertGlslangToSpvType(node->getType()));
|
||||
builder.accessChainPush(index);
|
||||
}
|
||||
return false;
|
||||
case glslang::EOpVectorSwizzle:
|
||||
@@ -629,7 +629,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
||||
std::vector<unsigned> swizzle;
|
||||
for (int i = 0; i < (int)swizzleSequence.size(); ++i)
|
||||
swizzle.push_back(swizzleSequence[i]->getAsConstantUnion()->getConstArray()[0].getIConst());
|
||||
builder.accessChainPushSwizzle(swizzle);
|
||||
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
@@ -641,11 +641,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
||||
// Get the operands
|
||||
builder.clearAccessChain();
|
||||
node->getLeft()->traverse(this);
|
||||
spv::Id left = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
|
||||
spv::Id left = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType()));
|
||||
|
||||
builder.clearAccessChain();
|
||||
node->getRight()->traverse(this);
|
||||
spv::Id right = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
|
||||
spv::Id right = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
|
||||
|
||||
spv::Id result;
|
||||
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
|
||||
@@ -702,7 +702,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
||||
|
||||
builder.clearAccessChain();
|
||||
node->getOperand()->traverse(this);
|
||||
spv::Id operand = builder.accessChainLoad(TranslatePrecisionDecoration(node->getOperand()->getType()));
|
||||
spv::Id operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType()));
|
||||
|
||||
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
|
||||
|
||||
@@ -1038,11 +1038,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||
|
||||
builder.clearAccessChain();
|
||||
left->traverse(this);
|
||||
spv::Id leftId = builder.accessChainLoad(TranslatePrecisionDecoration(left->getType()));
|
||||
spv::Id leftId = builder.accessChainLoad(convertGlslangToSpvType(left->getType()));
|
||||
|
||||
builder.clearAccessChain();
|
||||
right->traverse(this);
|
||||
spv::Id rightId = builder.accessChainLoad(TranslatePrecisionDecoration(right->getType()));
|
||||
spv::Id rightId = builder.accessChainLoad(convertGlslangToSpvType(right->getType()));
|
||||
|
||||
result = createBinaryOperation(binOp, precision,
|
||||
convertGlslangToSpvType(node->getType()), leftId, rightId,
|
||||
@@ -1084,7 +1084,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||
if (lvalue)
|
||||
operands.push_back(builder.accessChainGetLValue());
|
||||
else
|
||||
operands.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangOperands[arg]->getAsTyped()->getType())));
|
||||
operands.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangOperands[arg]->getAsTyped()->getType())));
|
||||
}
|
||||
|
||||
if (atomic) {
|
||||
@@ -1134,13 +1134,13 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
node->getCondition()->traverse(this);
|
||||
|
||||
// make an "if" based on the value created by the condition
|
||||
spv::Builder::If ifBuilder(builder.accessChainLoad(spv::NoPrecision), builder);
|
||||
spv::Builder::If ifBuilder(builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getType())), builder);
|
||||
|
||||
if (node->getTrueBlock()) {
|
||||
// emit the "then" statement
|
||||
node->getTrueBlock()->traverse(this);
|
||||
if (result)
|
||||
builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getTrueBlock()->getAsTyped()->getType())), result);
|
||||
builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getTrueBlock()->getAsTyped()->getType())), result);
|
||||
}
|
||||
|
||||
if (node->getFalseBlock()) {
|
||||
@@ -1148,7 +1148,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
// emit the "else" statement
|
||||
node->getFalseBlock()->traverse(this);
|
||||
if (result)
|
||||
builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getFalseBlock()->getAsTyped()->getType())), result);
|
||||
builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getFalseBlock()->getAsTyped()->getType())), result);
|
||||
}
|
||||
|
||||
ifBuilder.makeEndIf();
|
||||
@@ -1169,7 +1169,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
|
||||
{
|
||||
// emit and get the condition before doing anything with switch
|
||||
node->getCondition()->traverse(this);
|
||||
spv::Id selector = builder.accessChainLoad(TranslatePrecisionDecoration(node->getCondition()->getAsTyped()->getType()));
|
||||
spv::Id selector = builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getAsTyped()->getType()));
|
||||
|
||||
// browse the children to sort out code segments
|
||||
int defaultSegment = -1;
|
||||
@@ -1233,7 +1233,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
||||
if (node->getTest()) {
|
||||
node->getTest()->traverse(this);
|
||||
// the AST only contained the test computation, not the branch, we have to add it
|
||||
spv::Id condition = builder.accessChainLoad(TranslatePrecisionDecoration(node->getTest()->getType()));
|
||||
spv::Id condition = builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
|
||||
builder.createLoopTestBranch(condition);
|
||||
} else {
|
||||
builder.createBranchToBody();
|
||||
@@ -1279,7 +1279,7 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
||||
if (inMain)
|
||||
builder.makeMainReturn();
|
||||
else if (node->getExpression())
|
||||
builder.makeReturn(false, builder.accessChainLoad(TranslatePrecisionDecoration(node->getExpression()->getType())));
|
||||
builder.makeReturn(false, builder.accessChainLoad(convertGlslangToSpvType(node->getExpression()->getType())));
|
||||
else
|
||||
builder.makeReturn();
|
||||
|
||||
@@ -1664,7 +1664,7 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermSequence&
|
||||
for (int i = 0; i < (int)glslangArguments.size(); ++i) {
|
||||
builder.clearAccessChain();
|
||||
glslangArguments[i]->traverse(this);
|
||||
arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArguments[i]->getAsTyped()->getType())));
|
||||
arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1672,7 +1672,7 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std
|
||||
{
|
||||
builder.clearAccessChain();
|
||||
node.getOperand()->traverse(this);
|
||||
arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(node.getAsTyped()->getType())));
|
||||
arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(node.getOperand()->getType())));
|
||||
}
|
||||
|
||||
spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
|
||||
@@ -1806,17 +1806,19 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
||||
// 1. Evaluate the arguments
|
||||
std::vector<spv::Builder::AccessChain> lValues;
|
||||
std::vector<spv::Id> rValues;
|
||||
std::vector<spv::Id> argTypes;
|
||||
for (int a = 0; a < (int)glslangArgs.size(); ++a) {
|
||||
// build l-value
|
||||
builder.clearAccessChain();
|
||||
glslangArgs[a]->traverse(this);
|
||||
argTypes.push_back(convertGlslangToSpvType(glslangArgs[a]->getAsTyped()->getType()));
|
||||
// keep outputs as l-values, evaluate input-only as r-values
|
||||
if (qualifiers[a] != glslang::EvqConstReadOnly) {
|
||||
// save l-value
|
||||
lValues.push_back(builder.getAccessChain());
|
||||
} else {
|
||||
// process r-value
|
||||
rValues.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArgs[a]->getAsTyped()->getType())));
|
||||
rValues.push_back(builder.accessChainLoad(argTypes.back()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1836,7 +1838,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
||||
if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
|
||||
// need to copy the input into output space
|
||||
builder.setAccessChain(lValues[lValueCount]);
|
||||
spv::Id copy = builder.accessChainLoad(spv::NoPrecision); // TODO: get precision
|
||||
spv::Id copy = builder.accessChainLoad(argTypes[a]);
|
||||
builder.createStore(copy, arg);
|
||||
}
|
||||
++lValueCount;
|
||||
|
||||
Reference in New Issue
Block a user