HLSL: Translate directive [flatten] and [branch] to SPV control mask.
This commit is contained in:
parent
423fae4858
commit
57e65929e4
@ -122,6 +122,7 @@ protected:
|
|||||||
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
||||||
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
||||||
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
|
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
|
||||||
|
spv::SelectionControlMask TranslateSelectionControl(glslang::TSelectionControl) const;
|
||||||
spv::LoopControlMask TranslateLoopControl(glslang::TLoopControl) const;
|
spv::LoopControlMask TranslateLoopControl(glslang::TLoopControl) const;
|
||||||
spv::StorageClass TranslateStorageClass(const glslang::TType&);
|
spv::StorageClass TranslateStorageClass(const glslang::TType&);
|
||||||
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
|
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
|
||||||
@ -741,6 +742,16 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(glslang::TSelectionControl selectionControl) const
|
||||||
|
{
|
||||||
|
switch (selectionControl) {
|
||||||
|
case glslang::ESelectionControlNone: return spv::SelectionControlMaskNone;
|
||||||
|
case glslang::ESelectionControlFlatten: return spv::SelectionControlFlattenMask;
|
||||||
|
case glslang::ESelectionControlDontFlatten: return spv::SelectionControlDontFlattenMask;
|
||||||
|
default: return spv::SelectionControlMaskNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(glslang::TLoopControl loopControl) const
|
spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(glslang::TLoopControl loopControl) const
|
||||||
{
|
{
|
||||||
switch (loopControl) {
|
switch (loopControl) {
|
||||||
@ -1941,8 +1952,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instead, emit control flow...
|
// Instead, emit control flow...
|
||||||
|
|
||||||
// Don't handle results as temporaries, because there will be two names
|
// Don't handle results as temporaries, because there will be two names
|
||||||
// and better to leave SSA to later passes.
|
// and better to leave SSA to later passes.
|
||||||
spv::Id result = (node->getBasicType() == glslang::EbtVoid)
|
spv::Id result = (node->getBasicType() == glslang::EbtVoid)
|
||||||
@ -1952,8 +1962,11 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
|||||||
// emit the condition before doing anything with selection
|
// emit the condition before doing anything with selection
|
||||||
node->getCondition()->traverse(this);
|
node->getCondition()->traverse(this);
|
||||||
|
|
||||||
|
// Selection control:
|
||||||
|
const spv::SelectionControlMask control = TranslateSelectionControl(node->getSelectionControl());
|
||||||
|
|
||||||
// make an "if" based on the value created by the condition
|
// make an "if" based on the value created by the condition
|
||||||
spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), builder);
|
spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), control, builder);
|
||||||
|
|
||||||
// emit the "then" statement
|
// emit the "then" statement
|
||||||
if (node->getTrueBlock() != nullptr) {
|
if (node->getTrueBlock() != nullptr) {
|
||||||
@ -1991,6 +2004,9 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
|
|||||||
node->getCondition()->traverse(this);
|
node->getCondition()->traverse(this);
|
||||||
spv::Id selector = accessChainLoad(node->getCondition()->getAsTyped()->getType());
|
spv::Id selector = accessChainLoad(node->getCondition()->getAsTyped()->getType());
|
||||||
|
|
||||||
|
// Selection control:
|
||||||
|
const spv::SelectionControlMask control = TranslateSelectionControl(node->getSelectionControl());
|
||||||
|
|
||||||
// browse the children to sort out code segments
|
// browse the children to sort out code segments
|
||||||
int defaultSegment = -1;
|
int defaultSegment = -1;
|
||||||
std::vector<TIntermNode*> codeSegments;
|
std::vector<TIntermNode*> codeSegments;
|
||||||
@ -2016,7 +2032,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
|
|||||||
|
|
||||||
// make the switch statement
|
// make the switch statement
|
||||||
std::vector<spv::Block*> segmentBlocks; // returned, as the blocks allocated in the call
|
std::vector<spv::Block*> segmentBlocks; // returned, as the blocks allocated in the call
|
||||||
builder.makeSwitch(selector, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks);
|
builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks);
|
||||||
|
|
||||||
// emit all the code in the segments
|
// emit all the code in the segments
|
||||||
breakForLoop.push(false);
|
breakForLoop.push(false);
|
||||||
@ -5707,7 +5723,7 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan
|
|||||||
leftId = builder.createUnaryOp(spv::OpLogicalNot, boolTypeId, leftId);
|
leftId = builder.createUnaryOp(spv::OpLogicalNot, boolTypeId, leftId);
|
||||||
|
|
||||||
// make an "if" based on the left value
|
// make an "if" based on the left value
|
||||||
spv::Builder::If ifBuilder(leftId, builder);
|
spv::Builder::If ifBuilder(leftId, spv::SelectionControlMaskNone, builder);
|
||||||
|
|
||||||
// emit right operand as the "then" part of the "if"
|
// emit right operand as the "then" part of the "if"
|
||||||
builder.clearAccessChain();
|
builder.clearAccessChain();
|
||||||
|
@ -2009,9 +2009,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Builder::If::If(Id cond, Builder& gb) :
|
Builder::If::If(Id cond, unsigned int ctrl, Builder& gb) :
|
||||||
builder(gb),
|
builder(gb),
|
||||||
condition(cond),
|
condition(cond),
|
||||||
|
control(ctrl),
|
||||||
elseBlock(0)
|
elseBlock(0)
|
||||||
{
|
{
|
||||||
function = &builder.getBuildPoint()->getParent();
|
function = &builder.getBuildPoint()->getParent();
|
||||||
@ -2052,7 +2053,7 @@ void Builder::If::makeEndIf()
|
|||||||
|
|
||||||
// Go back to the headerBlock and make the flow control split
|
// Go back to the headerBlock and make the flow control split
|
||||||
builder.setBuildPoint(headerBlock);
|
builder.setBuildPoint(headerBlock);
|
||||||
builder.createSelectionMerge(mergeBlock, SelectionControlMaskNone);
|
builder.createSelectionMerge(mergeBlock, control);
|
||||||
if (elseBlock)
|
if (elseBlock)
|
||||||
builder.createConditionalBranch(condition, thenBlock, elseBlock);
|
builder.createConditionalBranch(condition, thenBlock, elseBlock);
|
||||||
else
|
else
|
||||||
@ -2064,7 +2065,7 @@ void Builder::If::makeEndIf()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::makeSwitch(Id selector, int numSegments, const std::vector<int>& caseValues,
|
void Builder::makeSwitch(Id selector, unsigned int control, int numSegments, const std::vector<int>& caseValues,
|
||||||
const std::vector<int>& valueIndexToSegment, int defaultSegment,
|
const std::vector<int>& valueIndexToSegment, int defaultSegment,
|
||||||
std::vector<Block*>& segmentBlocks)
|
std::vector<Block*>& segmentBlocks)
|
||||||
{
|
{
|
||||||
@ -2077,7 +2078,7 @@ void Builder::makeSwitch(Id selector, int numSegments, const std::vector<int>& c
|
|||||||
Block* mergeBlock = new Block(getUniqueId(), function);
|
Block* mergeBlock = new Block(getUniqueId(), function);
|
||||||
|
|
||||||
// make and insert the switch's selection-merge instruction
|
// make and insert the switch's selection-merge instruction
|
||||||
createSelectionMerge(mergeBlock, SelectionControlMaskNone);
|
createSelectionMerge(mergeBlock, control);
|
||||||
|
|
||||||
// make the switch instruction
|
// make the switch instruction
|
||||||
Instruction* switchInst = new Instruction(NoResult, NoType, OpSwitch);
|
Instruction* switchInst = new Instruction(NoResult, NoType, OpSwitch);
|
||||||
|
@ -385,7 +385,7 @@ public:
|
|||||||
// Helper to use for building nested control flow with if-then-else.
|
// Helper to use for building nested control flow with if-then-else.
|
||||||
class If {
|
class If {
|
||||||
public:
|
public:
|
||||||
If(Id condition, Builder& builder);
|
If(Id condition, unsigned int ctrl, Builder& builder);
|
||||||
~If() {}
|
~If() {}
|
||||||
|
|
||||||
void makeBeginElse();
|
void makeBeginElse();
|
||||||
@ -397,6 +397,7 @@ public:
|
|||||||
|
|
||||||
Builder& builder;
|
Builder& builder;
|
||||||
Id condition;
|
Id condition;
|
||||||
|
unsigned int control;
|
||||||
Function* function;
|
Function* function;
|
||||||
Block* headerBlock;
|
Block* headerBlock;
|
||||||
Block* thenBlock;
|
Block* thenBlock;
|
||||||
@ -416,7 +417,7 @@ public:
|
|||||||
// Returns the right set of basic blocks to start each code segment with, so that the caller's
|
// Returns the right set of basic blocks to start each code segment with, so that the caller's
|
||||||
// recursion stack can hold the memory for it.
|
// recursion stack can hold the memory for it.
|
||||||
//
|
//
|
||||||
void makeSwitch(Id condition, int numSegments, const std::vector<int>& caseValues,
|
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
|
||||||
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
|
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
|
||||||
|
|
||||||
// Add a branch to the innermost switch's merge block.
|
// Add a branch to the innermost switch's merge block.
|
||||||
|
@ -637,13 +637,15 @@ const char* SelectControlString(int cont)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int LoopControlCeiling = 2;
|
const int LoopControlCeiling = 4;
|
||||||
|
|
||||||
const char* LoopControlString(int cont)
|
const char* LoopControlString(int cont)
|
||||||
{
|
{
|
||||||
switch (cont) {
|
switch (cont) {
|
||||||
case 0: return "Unroll";
|
case 0: return "Unroll";
|
||||||
case 1: return "DontUnroll";
|
case 1: return "DontUnroll";
|
||||||
|
case 2: return "DependencyInfinite";
|
||||||
|
case 3: return "DependencyLength";
|
||||||
|
|
||||||
case LoopControlCeiling:
|
case LoopControlCeiling:
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
|
@ -90,7 +90,7 @@ gl_FragCoord origin is upper left
|
|||||||
11(@PixelShaderFunction(vf4;): 2 Function None 9
|
11(@PixelShaderFunction(vf4;): 2 Function None 9
|
||||||
10(input): 8(ptr) FunctionParameter
|
10(input): 8(ptr) FunctionParameter
|
||||||
12: Label
|
12: Label
|
||||||
SelectionMerge 16 None
|
SelectionMerge 16 DontFlatten
|
||||||
BranchConditional 14 15 16
|
BranchConditional 14 15 16
|
||||||
15: Label
|
15: Label
|
||||||
Branch 16
|
Branch 16
|
||||||
|
@ -319,7 +319,7 @@ gl_FragCoord origin is upper left
|
|||||||
48: 7(fvec4) Load 10(input)
|
48: 7(fvec4) Load 10(input)
|
||||||
49: 16(bvec4) FOrdEqual 47 48
|
49: 16(bvec4) FOrdEqual 47 48
|
||||||
50: 15(bool) All 49
|
50: 15(bool) All 49
|
||||||
SelectionMerge 52 None
|
SelectionMerge 52 Flatten
|
||||||
BranchConditional 50 51 52
|
BranchConditional 50 51 52
|
||||||
51: Label
|
51: Label
|
||||||
53: 7(fvec4) Load 10(input)
|
53: 7(fvec4) Load 10(input)
|
||||||
|
@ -399,7 +399,7 @@ gl_FragCoord origin is upper left
|
|||||||
Branch 25
|
Branch 25
|
||||||
25: Label
|
25: Label
|
||||||
36: 9(int) Load 13(c)
|
36: 9(int) Load 13(c)
|
||||||
SelectionMerge 40 None
|
SelectionMerge 40 DontFlatten
|
||||||
Switch 36 39
|
Switch 36 39
|
||||||
case 1: 37
|
case 1: 37
|
||||||
case 2: 38
|
case 2: 38
|
||||||
|
@ -18,7 +18,7 @@ float4 PixelShaderFunction(float4 input, int c, int d) : COLOR0
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c) {
|
[branch] switch (c) {
|
||||||
case 1:
|
case 1:
|
||||||
++input;
|
++input;
|
||||||
break;
|
break;
|
||||||
|
@ -861,6 +861,15 @@ protected:
|
|||||||
TType type;
|
TType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selection control hints
|
||||||
|
//
|
||||||
|
enum TSelectionControl {
|
||||||
|
ESelectionControlNone,
|
||||||
|
ESelectionControlFlatten,
|
||||||
|
ESelectionControlDontFlatten,
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Loop control hints
|
// Loop control hints
|
||||||
//
|
//
|
||||||
@ -1285,19 +1294,22 @@ protected:
|
|||||||
class TIntermSelection : public TIntermTyped {
|
class TIntermSelection : public TIntermTyped {
|
||||||
public:
|
public:
|
||||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
|
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
|
||||||
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
|
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {}
|
||||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
|
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
|
||||||
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
|
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {}
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
virtual TIntermTyped* getCondition() const { return condition; }
|
virtual TIntermTyped* getCondition() const { return condition; }
|
||||||
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
||||||
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
||||||
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
||||||
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
||||||
|
void setSelectionControl(TSelectionControl c) { control = c; }
|
||||||
|
TSelectionControl getSelectionControl() const { return control; }
|
||||||
protected:
|
protected:
|
||||||
TIntermTyped* condition;
|
TIntermTyped* condition;
|
||||||
TIntermNode* trueBlock;
|
TIntermNode* trueBlock;
|
||||||
TIntermNode* falseBlock;
|
TIntermNode* falseBlock;
|
||||||
|
TSelectionControl control; // selection control hint
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1308,15 +1320,18 @@ protected:
|
|||||||
//
|
//
|
||||||
class TIntermSwitch : public TIntermNode {
|
class TIntermSwitch : public TIntermNode {
|
||||||
public:
|
public:
|
||||||
TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b) { }
|
TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b), control(ESelectionControlNone) { }
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
virtual TIntermNode* getCondition() const { return condition; }
|
virtual TIntermNode* getCondition() const { return condition; }
|
||||||
virtual TIntermAggregate* getBody() const { return body; }
|
virtual TIntermAggregate* getBody() const { return body; }
|
||||||
virtual TIntermSwitch* getAsSwitchNode() { return this; }
|
virtual TIntermSwitch* getAsSwitchNode() { return this; }
|
||||||
virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
|
virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
|
||||||
|
void setSelectionControl(TSelectionControl c) { control = c; }
|
||||||
|
TSelectionControl getSelectionControl() const { return control; }
|
||||||
protected:
|
protected:
|
||||||
TIntermTyped* condition;
|
TIntermTyped* condition;
|
||||||
TIntermAggregate* body;
|
TIntermAggregate* body;
|
||||||
|
TSelectionControl control; // selection control hint
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TVisit
|
enum TVisit
|
||||||
|
@ -1614,7 +1614,7 @@ TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc)
|
|||||||
//
|
//
|
||||||
// Returns the selection node created.
|
// Returns the selection node created.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
|
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc, TSelectionControl control)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Don't prune the false path for compile-time constants; it's needed
|
// Don't prune the false path for compile-time constants; it's needed
|
||||||
@ -1623,6 +1623,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair no
|
|||||||
|
|
||||||
TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
|
TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
|
||||||
node->setLoc(loc);
|
node->setLoc(loc);
|
||||||
|
node->setSelectionControl(control);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@ -1665,12 +1666,12 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
|
|||||||
//
|
//
|
||||||
// Returns the selection node created, or nullptr if one could not be.
|
// Returns the selection node created, or nullptr if one could not be.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
|
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc, TSelectionControl control)
|
||||||
{
|
{
|
||||||
// If it's void, go to the if-then-else selection()
|
// If it's void, go to the if-then-else selection()
|
||||||
if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
|
if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
|
||||||
TIntermNodePair pair = { trueBlock, falseBlock };
|
TIntermNodePair pair = { trueBlock, falseBlock };
|
||||||
return addSelection(cond, pair, loc);
|
return addSelection(cond, pair, loc, control);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -276,8 +276,8 @@ public:
|
|||||||
TIntermAggregate* makeAggregate(const TSourceLoc&);
|
TIntermAggregate* makeAggregate(const TSourceLoc&);
|
||||||
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
|
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
|
||||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||||
TIntermTyped* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
|
TIntermTyped* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&, TSelectionControl = ESelectionControlNone);
|
||||||
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
|
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&, TSelectionControl = ESelectionControlNone);
|
||||||
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
|
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
|
||||||
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
|
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
|
||||||
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
|
||||||
|
@ -3201,10 +3201,10 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement)
|
|||||||
return acceptScopedCompoundStatement(statement);
|
return acceptScopedCompoundStatement(statement);
|
||||||
|
|
||||||
case EHTokIf:
|
case EHTokIf:
|
||||||
return acceptSelectionStatement(statement);
|
return acceptSelectionStatement(statement, attributes);
|
||||||
|
|
||||||
case EHTokSwitch:
|
case EHTokSwitch:
|
||||||
return acceptSwitchStatement(statement);
|
return acceptSwitchStatement(statement, attributes);
|
||||||
|
|
||||||
case EHTokFor:
|
case EHTokFor:
|
||||||
case EHTokDo:
|
case EHTokDo:
|
||||||
@ -3317,10 +3317,12 @@ void HlslGrammar::acceptAttributes(TAttributeMap& attributes)
|
|||||||
// : IF LEFT_PAREN expression RIGHT_PAREN statement
|
// : IF LEFT_PAREN expression RIGHT_PAREN statement
|
||||||
// : IF LEFT_PAREN expression RIGHT_PAREN statement ELSE statement
|
// : IF LEFT_PAREN expression RIGHT_PAREN statement ELSE statement
|
||||||
//
|
//
|
||||||
bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
|
bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement, const TAttributeMap& attributes)
|
||||||
{
|
{
|
||||||
TSourceLoc loc = token.loc;
|
TSourceLoc loc = token.loc;
|
||||||
|
|
||||||
|
const TSelectionControl control = parseContext.handleSelectionControl(attributes);
|
||||||
|
|
||||||
// IF
|
// IF
|
||||||
if (! acceptTokenClass(EHTokIf))
|
if (! acceptTokenClass(EHTokIf))
|
||||||
return false;
|
return false;
|
||||||
@ -3358,7 +3360,7 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Put the pieces together
|
// Put the pieces together
|
||||||
statement = intermediate.addSelection(condition, thenElse, loc);
|
statement = intermediate.addSelection(condition, thenElse, loc, control);
|
||||||
parseContext.popScope();
|
parseContext.popScope();
|
||||||
--parseContext.controlFlowNestingLevel;
|
--parseContext.controlFlowNestingLevel;
|
||||||
|
|
||||||
@ -3368,10 +3370,13 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
|
|||||||
// switch_statement
|
// switch_statement
|
||||||
// : SWITCH LEFT_PAREN expression RIGHT_PAREN compound_statement
|
// : SWITCH LEFT_PAREN expression RIGHT_PAREN compound_statement
|
||||||
//
|
//
|
||||||
bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement)
|
bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement, const TAttributeMap& attributes)
|
||||||
{
|
{
|
||||||
// SWITCH
|
// SWITCH
|
||||||
TSourceLoc loc = token.loc;
|
TSourceLoc loc = token.loc;
|
||||||
|
|
||||||
|
const TSelectionControl control = parseContext.handleSelectionControl(attributes);
|
||||||
|
|
||||||
if (! acceptTokenClass(EHTokSwitch))
|
if (! acceptTokenClass(EHTokSwitch))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -3391,7 +3396,7 @@ bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement)
|
|||||||
--parseContext.controlFlowNestingLevel;
|
--parseContext.controlFlowNestingLevel;
|
||||||
|
|
||||||
if (statementOkay)
|
if (statementOkay)
|
||||||
statement = parseContext.addSwitch(loc, switchExpression, statement ? statement->getAsAggregate() : nullptr);
|
statement = parseContext.addSwitch(loc, switchExpression, statement ? statement->getAsAggregate() : nullptr, control);
|
||||||
|
|
||||||
parseContext.popSwitchSequence();
|
parseContext.popSwitchSequence();
|
||||||
parseContext.popScope();
|
parseContext.popScope();
|
||||||
|
@ -116,8 +116,8 @@ namespace glslang {
|
|||||||
bool acceptStatement(TIntermNode*&);
|
bool acceptStatement(TIntermNode*&);
|
||||||
bool acceptNestedStatement(TIntermNode*&);
|
bool acceptNestedStatement(TIntermNode*&);
|
||||||
void acceptAttributes(TAttributeMap&);
|
void acceptAttributes(TAttributeMap&);
|
||||||
bool acceptSelectionStatement(TIntermNode*&);
|
bool acceptSelectionStatement(TIntermNode*&, const TAttributeMap&);
|
||||||
bool acceptSwitchStatement(TIntermNode*&);
|
bool acceptSwitchStatement(TIntermNode*&, const TAttributeMap&);
|
||||||
bool acceptIterationStatement(TIntermNode*&, const TAttributeMap&);
|
bool acceptIterationStatement(TIntermNode*&, const TAttributeMap&);
|
||||||
bool acceptJumpStatement(TIntermNode*&);
|
bool acceptJumpStatement(TIntermNode*&);
|
||||||
bool acceptCaseLabel(TIntermNode*&);
|
bool acceptCaseLabel(TIntermNode*&);
|
||||||
|
@ -8273,6 +8273,19 @@ bool HlslParseContext::handleOutputGeometry(const TSourceLoc& loc, const TLayout
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selection hints
|
||||||
|
//
|
||||||
|
TSelectionControl HlslParseContext::handleSelectionControl(const TAttributeMap& attributes) const
|
||||||
|
{
|
||||||
|
if (attributes.contains(EatFlatten))
|
||||||
|
return ESelectionControlFlatten;
|
||||||
|
else if (attributes.contains(EatBranch))
|
||||||
|
return ESelectionControlDontFlatten;
|
||||||
|
else
|
||||||
|
return ESelectionControlNone;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Loop hints
|
// Loop hints
|
||||||
//
|
//
|
||||||
@ -8286,7 +8299,6 @@ TLoopControl HlslParseContext::handleLoopControl(const TAttributeMap& attributes
|
|||||||
return ELoopControlNone;
|
return ELoopControlNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Updating default qualifier for the case of a declaration with just a qualifier,
|
// Updating default qualifier for the case of a declaration with just a qualifier,
|
||||||
// no type, block, or identifier.
|
// no type, block, or identifier.
|
||||||
@ -8425,7 +8437,7 @@ void HlslParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIn
|
|||||||
// Turn the top-level node sequence built up of wrapupSwitchSubsequence
|
// Turn the top-level node sequence built up of wrapupSwitchSubsequence
|
||||||
// into a switch node.
|
// into a switch node.
|
||||||
//
|
//
|
||||||
TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements)
|
TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements, TSelectionControl control)
|
||||||
{
|
{
|
||||||
wrapupSwitchSubsequence(lastStatements, nullptr);
|
wrapupSwitchSubsequence(lastStatements, nullptr);
|
||||||
|
|
||||||
@ -8452,6 +8464,7 @@ TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* ex
|
|||||||
|
|
||||||
TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
|
TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
|
||||||
switchNode->setLoc(loc);
|
switchNode->setLoc(loc);
|
||||||
|
switchNode->setSelectionControl(control);
|
||||||
|
|
||||||
return switchNode;
|
return switchNode;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ public:
|
|||||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||||
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
||||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body, TSelectionControl control);
|
||||||
|
|
||||||
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
|
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
|
||||||
|
|
||||||
@ -198,6 +198,9 @@ public:
|
|||||||
bool handleOutputGeometry(const TSourceLoc&, const TLayoutGeometry& geometry);
|
bool handleOutputGeometry(const TSourceLoc&, const TLayoutGeometry& geometry);
|
||||||
bool handleInputGeometry(const TSourceLoc&, const TLayoutGeometry& geometry);
|
bool handleInputGeometry(const TSourceLoc&, const TLayoutGeometry& geometry);
|
||||||
|
|
||||||
|
// Determine selection control from attributes
|
||||||
|
TSelectionControl handleSelectionControl(const TAttributeMap& attributes) const;
|
||||||
|
|
||||||
// Determine loop control from attributes
|
// Determine loop control from attributes
|
||||||
TLoopControl handleLoopControl(const TAttributeMap& attributes) const;
|
TLoopControl handleLoopControl(const TAttributeMap& attributes) const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user