Merge master branch from upstream
This commit is contained in:
@@ -506,7 +506,7 @@ TGlslangToSpvTraverser::~TGlslangToSpvTraverser()
|
||||
if (! mainTerminated) {
|
||||
spv::Block* lastMainBlock = shaderEntry->getLastBlock();
|
||||
builder.setBuildPoint(lastMainBlock);
|
||||
builder.leaveFunction(true);
|
||||
builder.leaveFunction();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -918,7 +918,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||
} else {
|
||||
if (inMain)
|
||||
mainTerminated = true;
|
||||
builder.leaveFunction(inMain);
|
||||
builder.leaveFunction();
|
||||
inMain = false;
|
||||
}
|
||||
|
||||
@@ -1351,12 +1351,10 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
||||
builder.createLoopContinue();
|
||||
break;
|
||||
case glslang::EOpReturn:
|
||||
if (inMain)
|
||||
builder.makeMainReturn();
|
||||
else if (node->getExpression())
|
||||
if (node->getExpression())
|
||||
builder.makeReturn(false, builder.accessChainLoad(convertGlslangToSpvType(node->getExpression()->getType())));
|
||||
else
|
||||
builder.makeReturn();
|
||||
builder.makeReturn(false);
|
||||
|
||||
builder.clearAccessChain();
|
||||
break;
|
||||
@@ -2664,20 +2662,23 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
|
||||
// Sort out the operands
|
||||
// - mapping from glslang -> SPV
|
||||
// - there are extra SPV operands with no glslang source
|
||||
// - compare-exchange swaps the value and comparator
|
||||
// - compare-exchange has an extra memory semantics
|
||||
std::vector<spv::Id> spvAtomicOperands; // hold the spv operands
|
||||
auto opIt = operands.begin(); // walk the glslang operands
|
||||
spvAtomicOperands.push_back(*(opIt++));
|
||||
|
||||
// Add scope and memory semantics
|
||||
spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice)); // TBD: what is the correct scope?
|
||||
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics?
|
||||
if (opCode == spv::OpAtomicCompareExchange) {
|
||||
// There are 2 memory semantics for compare-exchange
|
||||
// There are 2 memory semantics for compare-exchange. And the operand order of "comparator" and "new value" in GLSL
|
||||
// differs from that in SPIR-V. Hence, special processing is required.
|
||||
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone));
|
||||
spvAtomicOperands.push_back(*(opIt + 1));
|
||||
spvAtomicOperands.push_back(*opIt);
|
||||
opIt += 2;
|
||||
}
|
||||
|
||||
// Add the rest of the operands, skipping the first one, which was dealt with above.
|
||||
// For some ops, there are none, for some 1, for compare-exchange, 2.
|
||||
// Add the rest of the operands, skipping any that were dealt with above.
|
||||
for (; opIt != operands.end(); ++opIt)
|
||||
spvAtomicOperands.push_back(*opIt);
|
||||
|
||||
|
||||
@@ -65,8 +65,7 @@ Builder::Builder(unsigned int userNumber) :
|
||||
builderNumber(userNumber << 16 | SpvBuilderMagic),
|
||||
buildPoint(0),
|
||||
uniqueId(0),
|
||||
mainFunction(0),
|
||||
stageExit(0)
|
||||
mainFunction(0)
|
||||
{
|
||||
clearAccessChain();
|
||||
}
|
||||
@@ -723,19 +722,10 @@ Function* Builder::makeMain()
|
||||
std::vector<Id> params;
|
||||
|
||||
mainFunction = makeFunctionEntry(makeVoidType(), "main", params, &entry);
|
||||
stageExit = new Block(getUniqueId(), *mainFunction);
|
||||
|
||||
return mainFunction;
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
void Builder::closeMain()
|
||||
{
|
||||
setBuildPoint(stageExit);
|
||||
stageExit->addInstruction(new Instruction(NoResult, NoType, OpReturn));
|
||||
mainFunction->addBlock(stageExit);
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
Function* Builder::makeFunctionEntry(Id returnType, const char* name, std::vector<Id>& paramTypes, Block **entry)
|
||||
{
|
||||
@@ -756,14 +746,9 @@ Function* Builder::makeFunctionEntry(Id returnType, const char* name, std::vecto
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
void Builder::makeReturn(bool implicit, Id retVal, bool isMain)
|
||||
void Builder::makeReturn(bool implicit, Id retVal)
|
||||
{
|
||||
if (isMain && retVal)
|
||||
MissingFunctionality("return value from main()");
|
||||
|
||||
if (isMain)
|
||||
createBranch(stageExit);
|
||||
else if (retVal) {
|
||||
if (retVal) {
|
||||
Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue);
|
||||
inst->addIdOperand(retVal);
|
||||
buildPoint->addInstruction(inst);
|
||||
@@ -775,7 +760,7 @@ void Builder::makeReturn(bool implicit, Id retVal, bool isMain)
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
void Builder::leaveFunction(bool main)
|
||||
void Builder::leaveFunction()
|
||||
{
|
||||
Block* block = buildPoint;
|
||||
Function& function = buildPoint->getParent();
|
||||
@@ -791,10 +776,8 @@ void Builder::leaveFunction(bool main)
|
||||
// Given that this block is at the end of a function, it must be right after an
|
||||
// explicit return, just remove it.
|
||||
function.popBlock(block);
|
||||
} else if (main)
|
||||
makeMainReturn(true);
|
||||
else {
|
||||
// We're get a return instruction at the end of the current block,
|
||||
} else {
|
||||
// We'll add a return instruction at the end of the current block,
|
||||
// which for a non-void function is really error recovery (?), as the source
|
||||
// being translated should have had an explicit return, which would have been
|
||||
// followed by an unreachable block, which was handled above.
|
||||
@@ -805,9 +788,6 @@ void Builder::leaveFunction(bool main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (main)
|
||||
closeMain();
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
@@ -1244,6 +1224,23 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, b
|
||||
}
|
||||
}
|
||||
|
||||
// See if the result type is expecting a smeared result.
|
||||
// This happens when a legacy shadow*() call is made, which
|
||||
// gets a vec4 back instead of a float.
|
||||
Id smearedType = resultType;
|
||||
if (! isScalarType(resultType)) {
|
||||
switch (opCode) {
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
case OpImageSampleDrefExplicitLod:
|
||||
case OpImageSampleProjDrefImplicitLod:
|
||||
case OpImageSampleProjDrefExplicitLod:
|
||||
resultType = getScalarTypeId(resultType);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);
|
||||
for (int op = 0; op < optArgNum; ++op)
|
||||
textureInst->addIdOperand(texArgs[op]);
|
||||
@@ -1254,7 +1251,14 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, b
|
||||
setPrecision(textureInst->getResultId(), precision);
|
||||
buildPoint->addInstruction(textureInst);
|
||||
|
||||
return textureInst->getResultId();
|
||||
Id resultId = textureInst->getResultId();
|
||||
|
||||
// When a smear is needed, do it, as per what was computed
|
||||
// above when resultType was changed to a scalar type.
|
||||
if (resultType != smearedType)
|
||||
resultId = smearScalar(precision, resultId, smearedType);
|
||||
|
||||
return resultId;
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
|
||||
@@ -195,23 +195,16 @@ public:
|
||||
// Make the main function.
|
||||
Function* makeMain();
|
||||
|
||||
// Return from main. Implicit denotes a return at the very end of main.
|
||||
void makeMainReturn(bool implicit = false) { makeReturn(implicit, 0, true); }
|
||||
|
||||
// Close the main function.
|
||||
void closeMain();
|
||||
|
||||
// Make a shader-style function, and create its entry block if entry is non-zero.
|
||||
// Return the function, pass back the entry.
|
||||
Function* makeFunctionEntry(Id returnType, const char* name, std::vector<Id>& paramTypes, Block **entry = 0);
|
||||
|
||||
// Create a return. Pass whether it is a return form main, and the return
|
||||
// value (if applicable). In the case of an implicit return, no post-return
|
||||
// block is inserted.
|
||||
void makeReturn(bool implicit = false, Id retVal = 0, bool isMain = false);
|
||||
// Create a return. An 'implicit' return is one not appearing in the source
|
||||
// code. In the case of an implicit return, no post-return block is inserted.
|
||||
void makeReturn(bool implicit, Id retVal = 0);
|
||||
|
||||
// Generate all the code needed to finish up a function.
|
||||
void leaveFunction(bool main);
|
||||
void leaveFunction();
|
||||
|
||||
// Create a discard.
|
||||
void makeDiscard();
|
||||
@@ -517,7 +510,6 @@ protected:
|
||||
Block* buildPoint;
|
||||
Id uniqueId;
|
||||
Function* mainFunction;
|
||||
Block* stageExit;
|
||||
AccessChain accessChain;
|
||||
|
||||
// special blocks of instructions for output
|
||||
|
||||
Reference in New Issue
Block a user