Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
1f4d0468
Commit
1f4d0468
authored
Jan 12, 2019
by
John Kessenich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SPV 1.4: Implement the 5 new loop controls.
parent
0c1e71a1
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
312 additions
and
35 deletions
+312
-35
GlslangToSpv.cpp
SPIRV/GlslangToSpv.cpp
+28
-6
SpvBuilder.cpp
SPIRV/SpvBuilder.cpp
+3
-3
SpvBuilder.h
SPIRV/SpvBuilder.h
+1
-1
doc.cpp
SPIRV/doc.cpp
+10
-5
460.frag.out
Test/baseResults/460.frag.out
+1
-1
spv.1.4.LoopControl.frag.out
Test/baseResults/spv.1.4.LoopControl.frag.out
+110
-0
spv.controlFlowAttributes.frag.out
Test/baseResults/spv.controlFlowAttributes.frag.out
+3
-3
spv.1.4.LoopControl.frag
Test/spv.1.4.LoopControl.frag
+19
-0
intermediate.h
glslang/Include/intermediate.h
+34
-2
attribute.cpp
glslang/MachineIndependent/attribute.cpp
+96
-13
attribute.h
glslang/MachineIndependent/attribute.h
+6
-1
Spv.FromFile.cpp
gtests/Spv.FromFile.cpp
+1
-0
No files found.
SPIRV/GlslangToSpv.cpp
View file @
1f4d0468
...
@@ -135,7 +135,7 @@ protected:
...
@@ -135,7 +135,7 @@ protected:
spv
::
ImageFormat
TranslateImageFormat
(
const
glslang
::
TType
&
type
);
spv
::
ImageFormat
TranslateImageFormat
(
const
glslang
::
TType
&
type
);
spv
::
SelectionControlMask
TranslateSelectionControl
(
const
glslang
::
TIntermSelection
&
)
const
;
spv
::
SelectionControlMask
TranslateSelectionControl
(
const
glslang
::
TIntermSelection
&
)
const
;
spv
::
SelectionControlMask
TranslateSwitchControl
(
const
glslang
::
TIntermSwitch
&
)
const
;
spv
::
SelectionControlMask
TranslateSwitchControl
(
const
glslang
::
TIntermSwitch
&
)
const
;
spv
::
LoopControlMask
TranslateLoopControl
(
const
glslang
::
TIntermLoop
&
,
unsigned
int
&
dependencyLength
)
const
;
spv
::
LoopControlMask
TranslateLoopControl
(
const
glslang
::
TIntermLoop
&
,
std
::
vector
<
unsigned
int
>&
operands
)
const
;
spv
::
StorageClass
TranslateStorageClass
(
const
glslang
::
TType
&
);
spv
::
StorageClass
TranslateStorageClass
(
const
glslang
::
TType
&
);
void
addIndirectionIndexCapabilities
(
const
glslang
::
TType
&
baseType
,
const
glslang
::
TType
&
indexType
);
void
addIndirectionIndexCapabilities
(
const
glslang
::
TType
&
baseType
,
const
glslang
::
TType
&
indexType
);
spv
::
Id
createSpvVariable
(
const
glslang
::
TIntermSymbol
*
);
spv
::
Id
createSpvVariable
(
const
glslang
::
TIntermSymbol
*
);
...
@@ -1055,7 +1055,7 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const g
...
@@ -1055,7 +1055,7 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const g
// return a non-0 dependency if the dependency argument must be set
// return a non-0 dependency if the dependency argument must be set
spv
::
LoopControlMask
TGlslangToSpvTraverser
::
TranslateLoopControl
(
const
glslang
::
TIntermLoop
&
loopNode
,
spv
::
LoopControlMask
TGlslangToSpvTraverser
::
TranslateLoopControl
(
const
glslang
::
TIntermLoop
&
loopNode
,
unsigned
int
&
dependencyLength
)
const
std
::
vector
<
unsigned
int
>&
operands
)
const
{
{
spv
::
LoopControlMask
control
=
spv
::
LoopControlMaskNone
;
spv
::
LoopControlMask
control
=
spv
::
LoopControlMaskNone
;
...
@@ -1067,7 +1067,29 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang:
...
@@ -1067,7 +1067,29 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang:
control
=
control
|
spv
::
LoopControlDependencyInfiniteMask
;
control
=
control
|
spv
::
LoopControlDependencyInfiniteMask
;
else
if
(
loopNode
.
getLoopDependency
()
>
0
)
{
else
if
(
loopNode
.
getLoopDependency
()
>
0
)
{
control
=
control
|
spv
::
LoopControlDependencyLengthMask
;
control
=
control
|
spv
::
LoopControlDependencyLengthMask
;
dependencyLength
=
loopNode
.
getLoopDependency
();
operands
.
push_back
((
unsigned
int
)
loopNode
.
getLoopDependency
());
}
if
(
glslangIntermediate
->
getSpv
().
spv
>=
glslang
::
EShTargetSpv_1_4
)
{
if
(
loopNode
.
getMinIterations
()
>
0
)
{
control
=
control
|
spv
::
LoopControlMinIterationsMask
;
operands
.
push_back
(
loopNode
.
getMinIterations
());
}
if
(
loopNode
.
getMaxIterations
()
<
glslang
::
TIntermLoop
::
iterationsInfinite
)
{
control
=
control
|
spv
::
LoopControlMaxIterationsMask
;
operands
.
push_back
(
loopNode
.
getMaxIterations
());
}
if
(
loopNode
.
getIterationMultiple
()
>
1
)
{
control
=
control
|
spv
::
LoopControlIterationMultipleMask
;
operands
.
push_back
(
loopNode
.
getIterationMultiple
());
}
if
(
loopNode
.
getPeelCount
()
>
0
)
{
control
=
control
|
spv
::
LoopControlPeelCountMask
;
operands
.
push_back
(
loopNode
.
getPeelCount
());
}
if
(
loopNode
.
getPartialCount
()
>
0
)
{
control
=
control
|
spv
::
LoopControlPartialCountMask
;
operands
.
push_back
(
loopNode
.
getPartialCount
());
}
}
}
return
control
;
return
control
;
...
@@ -2841,8 +2863,8 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
...
@@ -2841,8 +2863,8 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
builder
.
createBranch
(
&
blocks
.
head
);
builder
.
createBranch
(
&
blocks
.
head
);
// Loop control:
// Loop control:
unsigned
int
dependencyLength
=
glslang
::
TIntermLoop
::
dependencyInfinite
;
std
::
vector
<
unsigned
int
>
operands
;
const
spv
::
LoopControlMask
control
=
TranslateLoopControl
(
*
node
,
dependencyLength
);
const
spv
::
LoopControlMask
control
=
TranslateLoopControl
(
*
node
,
operands
);
// Spec requires back edges to target header blocks, and every header block
// 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
// must dominate its merge block. Make a header block first to ensure these
...
@@ -2852,7 +2874,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
...
@@ -2852,7 +2874,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
// including merges of its own.
// including merges of its own.
builder
.
setLine
(
node
->
getLoc
().
line
,
node
->
getLoc
().
getFilename
());
builder
.
setLine
(
node
->
getLoc
().
line
,
node
->
getLoc
().
getFilename
());
builder
.
setBuildPoint
(
&
blocks
.
head
);
builder
.
setBuildPoint
(
&
blocks
.
head
);
builder
.
createLoopMerge
(
&
blocks
.
merge
,
&
blocks
.
continue_target
,
control
,
dependencyLength
);
builder
.
createLoopMerge
(
&
blocks
.
merge
,
&
blocks
.
continue_target
,
control
,
operands
);
if
(
node
->
testFirst
()
&&
node
->
getTest
())
{
if
(
node
->
testFirst
()
&&
node
->
getTest
())
{
spv
::
Block
&
test
=
builder
.
makeNewBlock
();
spv
::
Block
&
test
=
builder
.
makeNewBlock
();
builder
.
createBranch
(
&
test
);
builder
.
createBranch
(
&
test
);
...
...
SPIRV/SpvBuilder.cpp
View file @
1f4d0468
...
@@ -2956,14 +2956,14 @@ void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)
...
@@ -2956,14 +2956,14 @@ void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)
}
}
void
Builder
::
createLoopMerge
(
Block
*
mergeBlock
,
Block
*
continueBlock
,
unsigned
int
control
,
void
Builder
::
createLoopMerge
(
Block
*
mergeBlock
,
Block
*
continueBlock
,
unsigned
int
control
,
unsigned
int
dependencyLength
)
const
std
::
vector
<
unsigned
int
>&
operands
)
{
{
Instruction
*
merge
=
new
Instruction
(
OpLoopMerge
);
Instruction
*
merge
=
new
Instruction
(
OpLoopMerge
);
merge
->
addIdOperand
(
mergeBlock
->
getId
());
merge
->
addIdOperand
(
mergeBlock
->
getId
());
merge
->
addIdOperand
(
continueBlock
->
getId
());
merge
->
addIdOperand
(
continueBlock
->
getId
());
merge
->
addImmediateOperand
(
control
);
merge
->
addImmediateOperand
(
control
);
if
((
control
&
LoopControlDependencyLengthMask
)
!=
0
)
for
(
int
op
=
0
;
op
<
(
int
)
operands
.
size
();
++
op
)
merge
->
addImmediateOperand
(
dependencyLength
);
merge
->
addImmediateOperand
(
operands
[
op
]
);
buildPoint
->
addInstruction
(
std
::
unique_ptr
<
Instruction
>
(
merge
));
buildPoint
->
addInstruction
(
std
::
unique_ptr
<
Instruction
>
(
merge
));
}
}
...
...
SPIRV/SpvBuilder.h
View file @
1f4d0468
...
@@ -662,7 +662,7 @@ public:
...
@@ -662,7 +662,7 @@ public:
void
createBranch
(
Block
*
block
);
void
createBranch
(
Block
*
block
);
void
createConditionalBranch
(
Id
condition
,
Block
*
thenBlock
,
Block
*
elseBlock
);
void
createConditionalBranch
(
Id
condition
,
Block
*
thenBlock
,
Block
*
elseBlock
);
void
createLoopMerge
(
Block
*
mergeBlock
,
Block
*
continueBlock
,
unsigned
int
control
,
unsigned
int
dependencyLength
);
void
createLoopMerge
(
Block
*
mergeBlock
,
Block
*
continueBlock
,
unsigned
int
control
,
const
std
::
vector
<
unsigned
int
>&
operands
);
// Sets to generate opcode for specialization constants.
// Sets to generate opcode for specialization constants.
void
setToSpecConstCodeGenMode
()
{
generatingOpCodeForSpecConst
=
true
;
}
void
setToSpecConstCodeGenMode
()
{
generatingOpCodeForSpecConst
=
true
;
}
...
...
SPIRV/doc.cpp
View file @
1f4d0468
...
@@ -674,15 +674,20 @@ const char* SelectControlString(int cont)
...
@@ -674,15 +674,20 @@ const char* SelectControlString(int cont)
}
}
}
}
const
int
LoopControlCeiling
=
4
;
const
int
LoopControlCeiling
=
LoopControlPartialCountShift
+
1
;
const
char
*
LoopControlString
(
int
cont
)
const
char
*
LoopControlString
(
int
cont
)
{
{
switch
(
cont
)
{
switch
(
cont
)
{
case
0
:
return
"Unroll"
;
case
LoopControlUnrollShift
:
return
"Unroll"
;
case
1
:
return
"DontUnroll"
;
case
LoopControlDontUnrollShift
:
return
"DontUnroll"
;
case
2
:
return
"DependencyInfinite"
;
case
LoopControlDependencyInfiniteShift
:
return
"DependencyInfinite"
;
case
3
:
return
"DependencyLength"
;
case
LoopControlDependencyLengthShift
:
return
"DependencyLength"
;
case
LoopControlMinIterationsShift
:
return
"MinIterations"
;
case
LoopControlMaxIterationsShift
:
return
"MaxIterations"
;
case
LoopControlIterationMultipleShift
:
return
"IterationMultiple"
;
case
LoopControlPeelCountShift
:
return
"PeelCount"
;
case
LoopControlPartialCountShift
:
return
"PartialCount"
;
case
LoopControlCeiling
:
case
LoopControlCeiling
:
default:
return
"Bad"
;
default:
return
"Bad"
;
...
...
Test/baseResults/460.frag.out
View file @
1f4d0468
...
@@ -56,7 +56,7 @@ ERROR: node is still EOpNull!
...
@@ -56,7 +56,7 @@ ERROR: node is still EOpNull!
0:28 Function Definition: attExt( ( global void)
0:28 Function Definition: attExt( ( global void)
0:28 Function Parameters:
0:28 Function Parameters:
0:30 Sequence
0:30 Sequence
0:30 Loop with condition not tested first
: Dependency -3
0:30 Loop with condition not tested first
0:30 Loop Condition
0:30 Loop Condition
0:30 Constant:
0:30 Constant:
0:30 true (const bool)
0:30 true (const bool)
...
...
Test/baseResults/spv.1.4.LoopControl.frag.out
0 → 100644
View file @
1f4d0468
spv.1.4.LoopControl.frag
WARNING: 0:15: 'min_iterations' : expected a single integer argument
WARNING: 0:15: 'max_iterations' : expected a single integer argument
Validation failed
// Module Version 10400
// Generated by (magic number): 80007
// Id's are bound by 54
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 53
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_control_flow_attributes"
Name 4 "main"
Name 8 "i"
Name 32 "i"
Name 42 "i"
Name 53 "cond"
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
16: 6(int) Constant 8
17: TypeBool
20: 6(int) Constant 1
27: 17(bool) ConstantTrue
52: TypePointer Private 17(bool)
53(cond): 52(ptr) Variable Private
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
32(i): 7(ptr) Variable Function
42(i): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
LoopMerge 12 13 MinIterations MaxIterations 3 7
Branch 14
14: Label
15: 6(int) Load 8(i)
18: 17(bool) SLessThan 15 16
BranchConditional 18 11 12
11: Label
Branch 13
13: Label
19: 6(int) Load 8(i)
21: 6(int) IAdd 19 20
Store 8(i) 21
Branch 10
12: Label
Branch 22
22: Label
LoopMerge 24 25 IterationMultiple 2
Branch 26
26: Label
BranchConditional 27 23 24
23: Label
Branch 25
25: Label
Branch 22
24: Label
Branch 28
28: Label
LoopMerge 30 31 PeelCount 5
Branch 29
29: Label
Branch 31
31: Label
BranchConditional 27 28 30
30: Label
Store 32(i) 9
Branch 33
33: Label
LoopMerge 35 36 PartialCount 4
Branch 37
37: Label
38: 6(int) Load 32(i)
39: 17(bool) SLessThan 38 16
BranchConditional 39 34 35
34: Label
Branch 36
36: Label
40: 6(int) Load 32(i)
41: 6(int) IAdd 40 20
Store 32(i) 41
Branch 33
35: Label
Store 42(i) 9
Branch 43
43: Label
LoopMerge 45 46 None
Branch 47
47: Label
48: 6(int) Load 42(i)
49: 17(bool) SLessThan 48 16
BranchConditional 49 44 45
44: Label
Branch 46
46: Label
50: 6(int) Load 42(i)
51: 6(int) IAdd 50 20
Store 42(i) 51
Branch 43
45: Label
Return
FunctionEnd
Test/baseResults/spv.controlFlowAttributes.frag.out
View file @
1f4d0468
spv.controlFlowAttributes.frag
spv.controlFlowAttributes.frag
WARNING: 0:20: '
' : attribute with arguments not recognized, skipping
WARNING: 0:20: '
unroll' : expected no arguments
WARNING: 0:21: '
' : attribute with arguments not recognized, skipping
WARNING: 0:21: '
dont_unroll' : expected no arguments
WARNING: 0:22: '
' : attribute with arguments not recognized, skipping
WARNING: 0:22: '
dependency_infinite' : expected no arguments
WARNING: 0:23: 'dependency_length' : expected a single integer argument
WARNING: 0:23: 'dependency_length' : expected a single integer argument
WARNING: 0:24: '' : attribute with arguments not recognized, skipping
WARNING: 0:24: '' : attribute with arguments not recognized, skipping
WARNING: 0:25: '' : attribute with arguments not recognized, skipping
WARNING: 0:25: '' : attribute with arguments not recognized, skipping
...
...
Test/spv.1.4.LoopControl.frag
0 → 100644
View file @
1f4d0468
#version 450
#extension GL_EXT_control_flow_attributes : enable
bool
cond
;
void
main
()
{
[[
min_iterations
(
3
),
max_iterations
(
7
)]]
for
(
int
i
=
0
;
i
<
8
;
++
i
)
{
}
[[
iteration_multiple
(
2
)]]
while
(
true
)
{
}
[[
peel_count
(
5
)]]
do
{
}
while
(
true
);
[[
partial_count
(
4
)]]
for
(
int
i
=
0
;
i
<
8
;
++
i
)
{
}
// warnings on all these
[[
min_iterations
,
max_iterations
]]
for
(
int
i
=
0
;
i
<
8
;
++
i
)
{
}
//[[iteration_multiple(0)]] while(true) { }
//[[peel_count]] do { } while(true);
//[[partial_count]] for (int i = 0; i < 8; ++i) { }
}
glslang/Include/intermediate.h
View file @
1f4d0468
...
@@ -1116,7 +1116,12 @@ public:
...
@@ -1116,7 +1116,12 @@ public:
first
(
testFirst
),
first
(
testFirst
),
unroll
(
false
),
unroll
(
false
),
dontUnroll
(
false
),
dontUnroll
(
false
),
dependency
(
0
)
dependency
(
0
),
minIterations
(
0
),
maxIterations
(
iterationsInfinite
),
iterationMultiple
(
1
),
peelCount
(
0
),
partialCount
(
0
)
{
}
{
}
virtual
TIntermLoop
*
getAsLoopNode
()
{
return
this
;
}
virtual
TIntermLoop
*
getAsLoopNode
()
{
return
this
;
}
...
@@ -1128,14 +1133,36 @@ public:
...
@@ -1128,14 +1133,36 @@ public:
bool
testFirst
()
const
{
return
first
;
}
bool
testFirst
()
const
{
return
first
;
}
void
setUnroll
()
{
unroll
=
true
;
}
void
setUnroll
()
{
unroll
=
true
;
}
void
setDontUnroll
()
{
dontUnroll
=
true
;
}
void
setDontUnroll
()
{
dontUnroll
=
true
;
peelCount
=
0
;
partialCount
=
0
;
}
bool
getUnroll
()
const
{
return
unroll
;
}
bool
getUnroll
()
const
{
return
unroll
;
}
bool
getDontUnroll
()
const
{
return
dontUnroll
;
}
bool
getDontUnroll
()
const
{
return
dontUnroll
;
}
static
const
unsigned
int
dependencyInfinite
=
0xFFFFFFFF
;
static
const
unsigned
int
dependencyInfinite
=
0xFFFFFFFF
;
static
const
unsigned
int
iterationsInfinite
=
0xFFFFFFFF
;
void
setLoopDependency
(
int
d
)
{
dependency
=
d
;
}
void
setLoopDependency
(
int
d
)
{
dependency
=
d
;
}
int
getLoopDependency
()
const
{
return
dependency
;
}
int
getLoopDependency
()
const
{
return
dependency
;
}
void
setMinIterations
(
unsigned
int
v
)
{
minIterations
=
v
;
}
unsigned
int
getMinIterations
()
const
{
return
minIterations
;
}
void
setMaxIterations
(
unsigned
int
v
)
{
maxIterations
=
v
;
}
unsigned
int
getMaxIterations
()
const
{
return
maxIterations
;
}
void
setIterationMultiple
(
unsigned
int
v
)
{
iterationMultiple
=
v
;
}
unsigned
int
getIterationMultiple
()
const
{
return
iterationMultiple
;
}
void
setPeelCount
(
unsigned
int
v
)
{
peelCount
=
v
;
dontUnroll
=
false
;
}
unsigned
int
getPeelCount
()
const
{
return
peelCount
;
}
void
setPartialCount
(
unsigned
int
v
)
{
partialCount
=
v
;
dontUnroll
=
false
;
}
unsigned
int
getPartialCount
()
const
{
return
partialCount
;
}
protected
:
protected
:
TIntermNode
*
body
;
// code to loop over
TIntermNode
*
body
;
// code to loop over
TIntermTyped
*
test
;
// exit condition associated with loop, could be 0 for 'for' loops
TIntermTyped
*
test
;
// exit condition associated with loop, could be 0 for 'for' loops
...
@@ -1144,6 +1171,11 @@ protected:
...
@@ -1144,6 +1171,11 @@ protected:
bool
unroll
;
// true if unroll requested
bool
unroll
;
// true if unroll requested
bool
dontUnroll
;
// true if request to not unroll
bool
dontUnroll
;
// true if request to not unroll
unsigned
int
dependency
;
// loop dependency hint; 0 means not set or unknown
unsigned
int
dependency
;
// loop dependency hint; 0 means not set or unknown
unsigned
int
minIterations
;
// as per the SPIR-V specification
unsigned
int
maxIterations
;
// as per the SPIR-V specification
unsigned
int
iterationMultiple
;
// as per the SPIR-V specification
unsigned
int
peelCount
;
// as per the SPIR-V specification
unsigned
int
partialCount
;
// as per the SPIR-V specification
};
};
//
//
...
...
glslang/MachineIndependent/attribute.cpp
View file @
1f4d0468
...
@@ -52,6 +52,7 @@ bool TAttributeArgs::getInt(int& value, int argNum) const
...
@@ -52,6 +52,7 @@ bool TAttributeArgs::getInt(int& value, int argNum) const
return
true
;
return
true
;
}
}
// extract strings out of attribute arguments stored in attribute aggregate.
// extract strings out of attribute arguments stored in attribute aggregate.
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
bool
TAttributeArgs
::
getString
(
TString
&
value
,
int
argNum
,
bool
convertToLower
)
const
bool
TAttributeArgs
::
getString
(
TString
&
value
,
int
argNum
,
bool
convertToLower
)
const
...
@@ -110,6 +111,16 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
...
@@ -110,6 +111,16 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
return
EatDependencyInfinite
;
return
EatDependencyInfinite
;
else
if
(
name
==
"dependency_length"
)
else
if
(
name
==
"dependency_length"
)
return
EatDependencyLength
;
return
EatDependencyLength
;
else
if
(
name
==
"min_iterations"
)
return
EatMinIterations
;
else
if
(
name
==
"max_iterations"
)
return
EatMaxIterations
;
else
if
(
name
==
"iteration_multiple"
)
return
EatIterationMultiple
;
else
if
(
name
==
"peel_count"
)
return
EatPeelCount
;
else
if
(
name
==
"partial_count"
)
return
EatPartialCount
;
else
else
return
EatNone
;
return
EatNone
;
}
}
...
@@ -225,29 +236,101 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
...
@@ -225,29 +236,101 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
}
}
for
(
auto
it
=
attributes
.
begin
();
it
!=
attributes
.
end
();
++
it
)
{
for
(
auto
it
=
attributes
.
begin
();
it
!=
attributes
.
end
();
++
it
)
{
if
(
it
->
name
!=
EatDependencyLength
&&
it
->
size
()
>
0
)
{
warn
(
node
->
getLoc
(),
"attribute with arguments not recognized, skipping"
,
""
,
""
);
continue
;
}
int
value
;
const
auto
noArgument
=
[
&
](
const
char
*
feature
)
{
if
(
it
->
size
()
>
0
)
{
warn
(
node
->
getLoc
(),
"expected no arguments"
,
feature
,
""
);
return
false
;
}
return
true
;
};
const
auto
positiveSignedArgument
=
[
&
](
const
char
*
feature
,
int
&
value
)
{
if
(
it
->
size
()
==
1
&&
it
->
getInt
(
value
))
{
if
(
value
<=
0
)
{
error
(
node
->
getLoc
(),
"must be positive"
,
feature
,
""
);
return
false
;
}
}
else
{
warn
(
node
->
getLoc
(),
"expected a single integer argument"
,
feature
,
""
);
return
false
;
}
return
true
;
};
const
auto
unsignedArgument
=
[
&
](
const
char
*
feature
,
unsigned
int
&
uiValue
)
{
int
value
;
if
(
!
(
it
->
size
()
==
1
&&
it
->
getInt
(
value
)))
{
warn
(
node
->
getLoc
(),
"expected a single integer argument"
,
feature
,
""
);
return
false
;
}
uiValue
=
(
unsigned
int
)
value
;
return
true
;
};
const
auto
positiveUnsignedArgument
=
[
&
](
const
char
*
feature
,
unsigned
int
&
uiValue
)
{
int
value
;
if
(
it
->
size
()
==
1
&&
it
->
getInt
(
value
))
{
if
(
value
==
0
)
{
error
(
node
->
getLoc
(),
"must be greater than or equal to 1"
,
feature
,
""
);
return
false
;
}
}
else
{
warn
(
node
->
getLoc
(),
"expected a single integer argument"
,
feature
,
""
);
return
false
;
}
uiValue
=
(
unsigned
int
)
value
;
return
true
;
};
const
auto
spirv14
=
[
&
](
const
char
*
feature
)
{
if
(
spvVersion
.
spv
>
0
&&
spvVersion
.
spv
<
EShTargetSpv_1_4
)
warn
(
node
->
getLoc
(),
"attribute requires a SPIR-V 1.4 target-env"
,
feature
,
""
);
};
int
value
=
0
;
unsigned
uiValue
=
0
;
switch
(
it
->
name
)
{
switch
(
it
->
name
)
{
case
EatUnroll
:
case
EatUnroll
:
loop
->
setUnroll
();
if
(
noArgument
(
"unroll"
))
loop
->
setUnroll
();
break
;
break
;
case
EatLoop
:
case
EatLoop
:
loop
->
setDontUnroll
();
if
(
noArgument
(
"dont_unroll"
))
loop
->
setDontUnroll
();
break
;
break
;
case
EatDependencyInfinite
:
case
EatDependencyInfinite
:
loop
->
setLoopDependency
(
TIntermLoop
::
dependencyInfinite
);
if
(
noArgument
(
"dependency_infinite"
))
loop
->
setLoopDependency
(
TIntermLoop
::
dependencyInfinite
);
break
;
break
;
case
EatDependencyLength
:
case
EatDependencyLength
:
if
(
it
->
size
()
==
1
&&
it
->
getInt
(
value
))
{
if
(
positiveSignedArgument
(
"dependency_length"
,
value
))
if
(
value
<=
0
)
error
(
node
->
getLoc
(),
"must be positive"
,
"dependency_length"
,
""
);
loop
->
setLoopDependency
(
value
);
loop
->
setLoopDependency
(
value
);
}
else
break
;
warn
(
node
->
getLoc
(),
"expected a single integer argument"
,
"dependency_length"
,
""
);
case
EatMinIterations
:
spirv14
(
"min_iterations"
);
if
(
unsignedArgument
(
"min_iterations"
,
uiValue
))
loop
->
setMinIterations
(
uiValue
);
break
;
case
EatMaxIterations
:
spirv14
(
"max_iterations"
);
if
(
unsignedArgument
(
"max_iterations"
,
uiValue
))
loop
->
setMaxIterations
(
uiValue
);
break
;
case
EatIterationMultiple
:
spirv14
(
"iteration_multiple"
);
if
(
positiveUnsignedArgument
(
"iteration_multiple"
,
uiValue
))
loop
->
setIterationMultiple
(
uiValue
);
break
;
case
EatPeelCount
:
spirv14
(
"peel_count"
);
if
(
unsignedArgument
(
"peel_count"
,
uiValue
))
loop
->
setPeelCount
(
uiValue
);
break
;
case
EatPartialCount
:
spirv14
(
"partial_count"
);
if
(
unsignedArgument
(
"partial_count"
,
uiValue
))
loop
->
setPartialCount
(
uiValue
);
break
;
break
;
default
:
default
:
warn
(
node
->
getLoc
(),
"attribute does not apply to a loop"
,
""
,
""
);
warn
(
node
->
getLoc
(),
"attribute does not apply to a loop"
,
""
,
""
);
...
...
glslang/MachineIndependent/attribute.h
View file @
1f4d0468
...
@@ -71,7 +71,12 @@ namespace glslang {
...
@@ -71,7 +71,12 @@ namespace glslang {
EatPushConstant
,
EatPushConstant
,
EatConstantId
,
EatConstantId
,
EatDependencyInfinite
,
EatDependencyInfinite
,
EatDependencyLength
EatDependencyLength
,
EatMinIterations
,
EatMaxIterations
,
EatIterationMultiple
,
EatPeelCount
,
EatPartialCount
};
};
class
TIntermAggregate
;
class
TIntermAggregate
;
...
...
gtests/Spv.FromFile.cpp
View file @
1f4d0468
...
@@ -467,6 +467,7 @@ INSTANTIATE_TEST_CASE_P(
...
@@ -467,6 +467,7 @@ INSTANTIATE_TEST_CASE_P(
::
testing
::
ValuesIn
(
std
::
vector
<
std
::
string
>
({
::
testing
::
ValuesIn
(
std
::
vector
<
std
::
string
>
({
"spv.1.4.OpEntryPoint.frag"
,
"spv.1.4.OpEntryPoint.frag"
,
"spv.1.4.OpSelect.frag"
,
"spv.1.4.OpSelect.frag"
,
"spv.1.4.LoopControl.frag"
,
})),
})),
FileNameAsCustomTestSuffix
FileNameAsCustomTestSuffix
);
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment