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
426394d0
Commit
426394d0
authored
Jul 23, 2015
by
John Kessenich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AST -> SPV: Add basic atomic_uint and atomic*() built-in function functionality.
parent
917ec4ac
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
311 additions
and
23 deletions
+311
-23
GlslangToSpv.cpp
SPIRV/GlslangToSpv.cpp
+110
-12
SpvBuilder.cpp
SPIRV/SpvBuilder.cpp
+15
-9
SpvBuilder.h
SPIRV/SpvBuilder.h
+5
-2
spv.atomic.comp.out
Test/baseResults/spv.atomic.comp.out
+142
-0
spv.atomic.comp
Test/spv.atomic.comp
+38
-0
test-spirv-list
Test/test-spirv-list
+1
-0
No files found.
SPIRV/GlslangToSpv.cpp
View file @
426394d0
...
...
@@ -99,6 +99,7 @@ protected:
spv
::
Id
createUnaryOperation
(
glslang
::
TOperator
op
,
spv
::
Decoration
precision
,
spv
::
Id
typeId
,
spv
::
Id
operand
,
bool
isFloat
);
spv
::
Id
createConversion
(
glslang
::
TOperator
op
,
spv
::
Decoration
precision
,
spv
::
Id
destTypeId
,
spv
::
Id
operand
);
spv
::
Id
makeSmearedConstant
(
spv
::
Id
constant
,
int
vectorSize
);
spv
::
Id
createAtomicOperation
(
glslang
::
TOperator
op
,
spv
::
Decoration
precision
,
spv
::
Id
typeId
,
std
::
vector
<
spv
::
Id
>&
operands
);
spv
::
Id
createMiscOperation
(
glslang
::
TOperator
op
,
spv
::
Decoration
precision
,
spv
::
Id
typeId
,
std
::
vector
<
spv
::
Id
>&
operands
);
spv
::
Id
createNoArgOperation
(
glslang
::
TOperator
op
);
spv
::
Id
getSymbolId
(
const
glslang
::
TIntermSymbol
*
node
);
...
...
@@ -718,6 +719,16 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
builder
.
createNoResultOp
(
spv
::
OpEndStreamPrimitive
,
operand
);
return
false
;
case
glslang
:
:
EOpAtomicCounterIncrement
:
case
glslang
:
:
EOpAtomicCounterDecrement
:
case
glslang
:
:
EOpAtomicCounter
:
{
// Handle all of the atomics in one place, in createAtomicOperation()
std
::
vector
<
spv
::
Id
>
operands
;
operands
.
push_back
(
operand
);
result
=
createAtomicOperation
(
node
->
getOp
(),
precision
,
convertGlslangToSpvType
(
node
->
getType
()),
operands
);
return
false
;
}
default
:
spv
::
MissingFunctionality
(
"glslang unary"
);
break
;
...
...
@@ -733,6 +744,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
bool
reduceComparison
=
true
;
bool
isMatrix
=
false
;
bool
noReturnValue
=
false
;
bool
atomic
=
false
;
assert
(
node
->
getOp
());
...
...
@@ -952,6 +964,17 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
// These all have 0 operands and will naturally finish up in the code below for 0 operands
break
;
case
glslang
:
:
EOpAtomicAdd
:
case
glslang
:
:
EOpAtomicMin
:
case
glslang
:
:
EOpAtomicMax
:
case
glslang
:
:
EOpAtomicAnd
:
case
glslang
:
:
EOpAtomicOr
:
case
glslang
:
:
EOpAtomicXor
:
case
glslang
:
:
EOpAtomicExchange
:
case
glslang
:
:
EOpAtomicCompSwap
:
atomic
=
true
;
break
;
default
:
break
;
}
...
...
@@ -959,7 +982,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
//
// See if it maps to a regular operation.
//
if
(
binOp
!=
glslang
::
EOpNull
)
{
glslang
::
TIntermTyped
*
left
=
node
->
getSequence
()[
0
]
->
getAsTyped
();
glslang
::
TIntermTyped
*
right
=
node
->
getSequence
()[
1
]
->
getAsTyped
();
...
...
@@ -987,6 +1009,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
return
false
;
}
//
// Create the list of operands.
//
glslang
::
TIntermSequence
&
glslangOperands
=
node
->
getSequence
();
std
::
vector
<
spv
::
Id
>
operands
;
for
(
int
arg
=
0
;
arg
<
(
int
)
glslangOperands
.
size
();
++
arg
)
{
...
...
@@ -1012,16 +1037,23 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
else
operands
.
push_back
(
builder
.
accessChainLoad
(
TranslatePrecisionDecoration
(
glslangOperands
[
arg
]
->
getAsTyped
()
->
getType
())));
}
switch
(
glslangOperands
.
size
())
{
case
0
:
result
=
createNoArgOperation
(
node
->
getOp
());
break
;
case
1
:
result
=
createUnaryOperation
(
node
->
getOp
(),
precision
,
convertGlslangToSpvType
(
node
->
getType
()),
operands
.
front
(),
node
->
getType
().
getBasicType
()
==
glslang
::
EbtFloat
||
node
->
getType
().
getBasicType
()
==
glslang
::
EbtDouble
);
break
;
default
:
result
=
createMiscOperation
(
node
->
getOp
(),
precision
,
convertGlslangToSpvType
(
node
->
getType
()),
operands
);
break
;
if
(
atomic
)
{
// Handle all atomics
result
=
createAtomicOperation
(
node
->
getOp
(),
precision
,
convertGlslangToSpvType
(
node
->
getType
()),
operands
);
}
else
{
// Pass through to generic operations.
switch
(
glslangOperands
.
size
())
{
case
0
:
result
=
createNoArgOperation
(
node
->
getOp
());
break
;
case
1
:
result
=
createUnaryOperation
(
node
->
getOp
(),
precision
,
convertGlslangToSpvType
(
node
->
getType
()),
operands
.
front
(),
node
->
getType
().
getBasicType
()
==
glslang
::
EbtFloat
||
node
->
getType
().
getBasicType
()
==
glslang
::
EbtDouble
);
break
;
default
:
result
=
createMiscOperation
(
node
->
getOp
(),
precision
,
convertGlslangToSpvType
(
node
->
getType
()),
operands
);
break
;
}
}
if
(
noReturnValue
)
...
...
@@ -1272,6 +1304,10 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
case
glslang
:
:
EbtUint
:
spvType
=
builder
.
makeUintType
(
32
);
break
;
case
glslang
:
:
EbtAtomicUint
:
spv
::
TbdFunctionality
(
"Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?"
);
spvType
=
builder
.
makeUintType
(
32
);
break
;
case
glslang
:
:
EbtSampler
:
{
const
glslang
::
TSampler
&
sampler
=
type
.
getSampler
();
...
...
@@ -2245,6 +2281,67 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector
return
builder
.
makeCompositeConstant
(
vectorTypeId
,
components
);
}
// For glslang ops that map to SPV atomic opCodes
spv
::
Id
TGlslangToSpvTraverser
::
createAtomicOperation
(
glslang
::
TOperator
op
,
spv
::
Decoration
precision
,
spv
::
Id
typeId
,
std
::
vector
<
spv
::
Id
>&
operands
)
{
spv
::
Op
opCode
=
spv
::
OpNop
;
switch
(
op
)
{
case
glslang
:
:
EOpAtomicAdd
:
opCode
=
spv
::
OpAtomicIAdd
;
break
;
case
glslang
:
:
EOpAtomicMin
:
opCode
=
spv
::
OpAtomicIMin
;
break
;
case
glslang
:
:
EOpAtomicMax
:
opCode
=
spv
::
OpAtomicIMax
;
break
;
case
glslang
:
:
EOpAtomicAnd
:
opCode
=
spv
::
OpAtomicAnd
;
break
;
case
glslang
:
:
EOpAtomicOr
:
opCode
=
spv
::
OpAtomicOr
;
break
;
case
glslang
:
:
EOpAtomicXor
:
opCode
=
spv
::
OpAtomicXor
;
break
;
case
glslang
:
:
EOpAtomicExchange
:
opCode
=
spv
::
OpAtomicExchange
;
break
;
case
glslang
:
:
EOpAtomicCompSwap
:
opCode
=
spv
::
OpAtomicCompareExchange
;
break
;
case
glslang
:
:
EOpAtomicCounterIncrement
:
opCode
=
spv
::
OpAtomicIIncrement
;
break
;
case
glslang
:
:
EOpAtomicCounterDecrement
:
opCode
=
spv
::
OpAtomicIDecrement
;
break
;
case
glslang
:
:
EOpAtomicCounter
:
opCode
=
spv
::
OpAtomicLoad
;
break
;
default
:
spv
::
MissingFunctionality
(
"missing nested atomic"
);
break
;
}
// Sort out the operands
// - mapping from glslang -> SPV
// - there are extra SPV operands with no glslang source
std
::
vector
<
spv
::
Id
>
spvAtomicOperands
;
// hold the spv operands
auto
opIt
=
operands
.
begin
();
// walk the glslang operands
spvAtomicOperands
.
push_back
(
*
(
opIt
++
));
spvAtomicOperands
.
push_back
(
spv
::
ExecutionScopeDevice
);
// TBD: what is the correct scope?
spvAtomicOperands
.
push_back
(
spv
::
MemorySemanticsMaskNone
);
// TBD: what are the correct memory semantics?
// 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.
for
(;
opIt
!=
operands
.
end
();
++
opIt
)
spvAtomicOperands
.
push_back
(
*
opIt
);
return
builder
.
createOp
(
opCode
,
typeId
,
spvAtomicOperands
);
}
spv
::
Id
TGlslangToSpvTraverser
::
createMiscOperation
(
glslang
::
TOperator
op
,
spv
::
Decoration
precision
,
spv
::
Id
typeId
,
std
::
vector
<
spv
::
Id
>&
operands
)
{
spv
::
Op
opCode
=
spv
::
OpNop
;
...
...
@@ -2298,6 +2395,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
case
glslang
:
:
EOpRefract
:
libCall
=
GLSL_STD_450
::
Refract
;
break
;
default
:
return
0
;
}
...
...
@@ -2319,7 +2417,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
id
=
builder
.
createBinOp
(
opCode
,
typeId
,
operands
[
0
],
operands
[
1
]);
break
;
case
3
:
id
=
builder
.
createT
ernary
Op
(
opCode
,
typeId
,
operands
[
0
],
operands
[
1
],
operands
[
2
]);
id
=
builder
.
createT
ri
Op
(
opCode
,
typeId
,
operands
[
0
],
operands
[
1
],
operands
[
2
]);
break
;
default
:
// These do not exist yet
...
...
SPIRV/SpvBuilder.cpp
View file @
426394d0
...
...
@@ -45,6 +45,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <unordered_set>
#include "SpvBuilder.h"
#ifndef _WIN32
...
...
@@ -989,12 +991,11 @@ Id Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3)
return
op
->
getResultId
();
}
Id
Builder
::
create
TernaryOp
(
Op
opCode
,
Id
typeId
,
Id
op1
,
Id
op2
,
Id
op3
)
Id
Builder
::
create
Op
(
Op
opCode
,
Id
typeId
,
std
::
vector
<
Id
>&
operands
)
{
Instruction
*
op
=
new
Instruction
(
getUniqueId
(),
typeId
,
opCode
);
op
->
addIdOperand
(
op1
);
op
->
addIdOperand
(
op2
);
op
->
addIdOperand
(
op3
);
for
(
auto
operand
:
operands
)
op
->
addIdOperand
(
operand
);
buildPoint
->
addInstruction
(
op
);
return
op
->
getResultId
();
...
...
@@ -2172,15 +2173,20 @@ void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector
}
}
void
MissingFunctionality
(
const
char
*
fun
)
void
TbdFunctionality
(
const
char
*
tbd
)
{
printf
(
"Missing functionality: %s
\n
"
,
fun
);
exit
(
1
);
static
std
::
unordered_set
<
const
char
*>
issued
;
if
(
issued
.
find
(
tbd
)
==
issued
.
end
())
{
printf
(
"TBD functionality: %s
\n
"
,
tbd
);
issued
.
insert
(
tbd
);
}
}
void
ValidationError
(
const
char
*
error
)
void
MissingFunctionality
(
const
char
*
fun
)
{
printf
(
"Validation Error: %s
\n
"
,
error
);
printf
(
"Missing functionality: %s
\n
"
,
fun
);
exit
(
1
);
}
Builder
::
Loop
::
Loop
(
Builder
&
builder
,
bool
testFirstArg
)
...
...
SPIRV/SpvBuilder.h
View file @
426394d0
...
...
@@ -238,7 +238,7 @@ public:
Id
createUnaryOp
(
Op
,
Id
typeId
,
Id
operand
);
Id
createBinOp
(
Op
,
Id
typeId
,
Id
operand1
,
Id
operand2
);
Id
createTriOp
(
Op
,
Id
typeId
,
Id
operand1
,
Id
operand2
,
Id
operand3
);
Id
create
TernaryOp
(
Op
,
Id
typeId
,
Id
operand1
,
Id
operand2
,
Id
operand3
);
Id
create
Op
(
Op
,
Id
typeId
,
std
::
vector
<
Id
>&
operands
);
Id
createFunctionCall
(
spv
::
Function
*
,
std
::
vector
<
spv
::
Id
>&
);
// Take an rvalue (source) and a set of channels to extract from it to
...
...
@@ -564,8 +564,11 @@ protected:
std
::
stack
<
Loop
>
loops
;
};
// end Builder class
// Use for non-fatal notes about what's not complete
void
TbdFunctionality
(
const
char
*
);
// Use for fatal missing functionality
void
MissingFunctionality
(
const
char
*
);
void
ValidationError
(
const
char
*
error
);
};
// end spv namespace
...
...
Test/baseResults/spv.atomic.comp.out
0 → 100644
View file @
426394d0
spv.atomic.comp
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
Linked compute stage:
TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?
TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?
TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?
TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?
TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?
// Module Version 99
// Generated by (magic number): 51a00bb
// Id's are bound by 75
Source ESSL 310
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint GLCompute 4
Name 4 "main"
Name 11 "func(au1;"
Name 10 "c"
Name 13 "atoms("
Name 20 "counter"
Name 21 "param"
Name 24 "val"
Name 28 "countArr"
Name 38 "origi"
Name 40 "atomi"
Name 44 "origu"
Name 46 "atomu"
Name 48 "value"
Name 72 "arrX"
Name 73 "arrY"
Name 74 "arrZ"
Decorate 20(counter) PrecisionHigh
Decorate 20(counter) Binding 0
Decorate 24(val) PrecisionHigh
Decorate 28(countArr) PrecisionHigh
Decorate 28(countArr) Binding 0
Decorate 38(origi) PrecisionHigh
Decorate 40(atomi) PrecisionHigh
Decorate 44(origu) PrecisionHigh
Decorate 46(atomu) PrecisionHigh
Decorate 48(value) PrecisionHigh
Decorate 72(arrX) PrecisionHigh
Decorate 72(arrX) NoStaticUse
Decorate 73(arrY) PrecisionHigh
Decorate 73(arrY) NoStaticUse
Decorate 74(arrZ) PrecisionHigh
Decorate 74(arrZ) NoStaticUse
2: TypeVoid
3: TypeFunction 2
7: TypeInt 32 0
8: TypePointer Function 7(int)
9: TypeFunction 7(int) 8(ptr)
19: TypePointer UniformConstant 7(int)
20(counter): 19(ptr) Variable UniformConstant
25: 7(int) Constant 4
26: TypeArray 7(int) 25
27: TypePointer UniformConstant 26
28(countArr): 27(ptr) Variable UniformConstant
29: TypeInt 32 1
30: 29(int) Constant 2
37: TypePointer Function 29(int)
39: TypePointer WorkgroupLocal 29(int)
40(atomi): 39(ptr) Variable WorkgroupLocal
42: 29(int) Constant 3
45: TypePointer WorkgroupLocal 7(int)
46(atomu): 45(ptr) Variable WorkgroupLocal
48(value): 19(ptr) Variable UniformConstant
52: 7(int) Constant 7
60: 29(int) Constant 7
66: 7(int) Constant 10
69: 7(int) Constant 1
70: TypeArray 29(int) 69
71: TypePointer PrivateGlobal 70
72(arrX): 71(ptr) Variable PrivateGlobal
73(arrY): 71(ptr) Variable PrivateGlobal
74(arrZ): 71(ptr) Variable PrivateGlobal
4(main): 2 Function None 3
5: Label
21(param): 8(ptr) Variable Function
24(val): 8(ptr) Variable Function
MemoryBarrier Device AtomicCounterMemory
22: 7(int) Load 20(counter)
Store 21(param) 22
23: 7(int) FunctionCall 11(func(au1;) 21(param)
31: 19(ptr) AccessChain 28(countArr) 30
32: 7(int) Load 31
33: 7(int) AtomicLoad 32 Device None
34: 7(int) Load 31
Store 24(val) 34
35: 7(int) Load 20(counter)
36: 7(int) AtomicIDecrement 35 Device None
Branch 6
6: Label
Return
FunctionEnd
11(func(au1;): 7(int) Function None 9
10(c): 8(ptr) FunctionParameter
12: Label
15: 7(int) Load 10(c)
16: 7(int) AtomicIIncrement 15 Device None
17: 7(int) Load 10(c)
ReturnValue 17
FunctionEnd
13(atoms(): 2 Function None 3
14: Label
38(origi): 37(ptr) Variable Function
44(origu): 8(ptr) Variable Function
41: 29(int) Load 40(atomi)
43: 29(int) AtomicIAdd 41 Device None 42
Store 38(origi) 43
47: 7(int) Load 46(atomu)
49: 7(int) Load 48(value)
50: 7(int) AtomicAnd 47 Device None 49
Store 44(origu) 50
51: 7(int) Load 46(atomu)
53: 7(int) AtomicOr 51 Device None 52
Store 44(origu) 53
54: 7(int) Load 46(atomu)
55: 7(int) AtomicXor 54 Device None 52
Store 44(origu) 55
56: 7(int) Load 46(atomu)
57: 7(int) Load 48(value)
58: 7(int) AtomicIMin 56 Device None 57
Store 44(origu) 58
59: 29(int) Load 40(atomi)
61: 29(int) AtomicIMax 59 Device None 60
Store 38(origi) 61
62: 29(int) Load 40(atomi)
63: 29(int) Load 38(origi)
64: 29(int) AtomicExchange 62 Device None 63
Store 38(origi) 64
65: 7(int) Load 46(atomu)
67: 7(int) Load 48(value)
68: 7(int) AtomicCompareExchange 65 Device None 66 67
Store 44(origu) 68
Return
FunctionEnd
Test/spv.atomic.comp
0 → 100644
View file @
426394d0
#version 310 es
layout(binding = 0) uniform atomic_uint counter;
layout(binding = 0, offset = 4) uniform atomic_uint countArr[4];
uniform uint value;
int arrX[gl_WorkGroupSize.x];
int arrY[gl_WorkGroupSize.y];
int arrZ[gl_WorkGroupSize.z];
uint func(atomic_uint c)
{
return atomicCounterIncrement(c);
}
void main()
{
memoryBarrierAtomicCounter();
func(counter);
uint val = atomicCounter(countArr[2]);
atomicCounterDecrement(counter);
}
shared int atomi;
shared uint atomu;
void atoms()
{
int origi = atomicAdd(atomi, 3);
uint origu = atomicAnd(atomu, value);
origu = atomicOr(atomu, 7u);
origu = atomicXor(atomu, 7u);
origu = atomicMin(atomu, value);
origi = atomicMax(atomi, 7);
origi = atomicExchange(atomi, origi);
origu = atomicCompSwap(atomu, 10u, value);
}
Test/test-spirv-list
View file @
426394d0
...
...
@@ -78,3 +78,4 @@ spv.varyingArray.frag
spv.varyingArrayIndirect.frag
spv.voidFunction.frag
spv.whileLoop.frag
spv.atomic.comp
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