GLSL: Implement GL_EXT_control_flow_attributes.

See https://github.com/KhronosGroup/GLSL/pull/11.
This commit is contained in:
John Kessenich
2018-01-31 08:11:18 -07:00
parent e18fd20d5c
commit a2858d9bdd
21 changed files with 3120 additions and 2405 deletions

View File

@@ -131,7 +131,7 @@ protected:
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const;
spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const;
spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&) const;
spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, unsigned int& dependencyLength) const;
spv::StorageClass TranslateStorageClass(const glslang::TType&);
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
spv::Id getSampledType(const glslang::TSampler&);
@@ -767,7 +767,9 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const g
return spv::SelectionControlMaskNone;
}
spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang::TIntermLoop& loopNode) const
// return a non-0 dependency if the dependency argument must be set
spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang::TIntermLoop& loopNode,
unsigned int& dependencyLength) const
{
spv::LoopControlMask control = spv::LoopControlMaskNone;
@@ -775,6 +777,12 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang:
control = control | spv::LoopControlDontUnrollMask;
if (loopNode.getUnroll())
control = control | spv::LoopControlUnrollMask;
if (loopNode.getLoopDependency() == glslang::TIntermLoop::dependencyInfinite)
control = control | spv::LoopControlDependencyInfiniteMask;
else if (loopNode.getLoopDependency() > 0) {
control = control | spv::LoopControlDependencyLengthMask;
dependencyLength = loopNode.getLoopDependency();
}
return control;
}
@@ -2137,9 +2145,8 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
builder.createBranch(&blocks.head);
// Loop control:
const spv::LoopControlMask control = TranslateLoopControl(*node);
// TODO: dependency length
unsigned int dependencyLength = glslang::TIntermLoop::dependencyInfinite;
const spv::LoopControlMask control = TranslateLoopControl(*node, dependencyLength);
// Spec requires back edges to target header blocks, and every header block
// must dominate its merge block. Make a header block first to ensure these
@@ -2149,7 +2156,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
// including merges of its own.
builder.setLine(node->getLoc().line);
builder.setBuildPoint(&blocks.head);
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control);
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, dependencyLength);
if (node->testFirst() && node->getTest()) {
spv::Block& test = builder.makeNewBlock();
builder.createBranch(&test);

View File

@@ -2573,12 +2573,15 @@ void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)
buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
}
void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control)
void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
unsigned int dependencyLength)
{
Instruction* merge = new Instruction(OpLoopMerge);
merge->addIdOperand(mergeBlock->getId());
merge->addIdOperand(continueBlock->getId());
merge->addImmediateOperand(control);
if ((control & LoopControlDependencyLengthMask) != 0)
merge->addImmediateOperand(dependencyLength);
buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
}

View File

@@ -561,7 +561,7 @@ public:
void createBranch(Block* block);
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, unsigned int dependencyLength);
// Sets to generate opcode for specialization constants.
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }

View File

@@ -2558,6 +2558,7 @@ void Parameterize()
InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Merge Block'");
InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Continue Target'");
InstructionDesc[OpLoopMerge].operands.push(OperandLoop, "");
InstructionDesc[OpLoopMerge].operands.push(OperandOptionalLiteral, "");
InstructionDesc[OpSelectionMerge].operands.push(OperandId, "'Merge Block'");
InstructionDesc[OpSelectionMerge].operands.push(OperandSelect, "");