SPV: Turn on atomic-storage functionality for SPIR-V.

This is used by OpenGL, but not Vulkan.
Includes:
 - atomicCounter, atomicIncrement, atomicCounterDecrement
 - atomic_uint layout-offset checking
 - AtomicStorage capability
This commit is contained in:
John Kessenich 2016-07-07 13:20:00 -06:00
parent 5e69ec683d
commit 2d0cc786f3
6 changed files with 152 additions and 203 deletions

View File

@ -1832,7 +1832,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
spvType = builder.makeUintType(64);
break;
case glslang::EbtAtomicUint:
logger->tbdFunctionality("Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?");
builder.addCapability(spv::CapabilityAtomicStorage);
spvType = builder.makeUintType(32);
break;
case glslang::EbtSampler:

View File

@ -1,203 +1,131 @@
spv.atomic.comp
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
Shader version: 310
local_size = (1, 1, 1)
0:? Sequence
0:14 Function Definition: func(au1; (global highp uint)
0:14 Function Parameters:
0:14 'c' (in highp atomic_uint)
0:16 Sequence
0:16 Branch: Return with expression
0:16 AtomicCounterIncrement (global highp uint)
0:16 'c' (in highp atomic_uint)
0:19 Function Definition: main( (global void)
0:19 Function Parameters:
0:21 Sequence
0:21 MemoryBarrierAtomicCounter (global void)
0:22 Function Call: func(au1; (global highp uint)
0:22 'counter' (layout(binding=0 offset=0 ) uniform highp atomic_uint)
0:23 Sequence
0:23 move second child to first child (temp highp uint)
0:23 'val' (temp highp uint)
0:23 AtomicCounter (global highp uint)
0:23 direct index (layout(binding=0 offset=4 ) temp highp atomic_uint)
0:23 'countArr' (layout(binding=0 offset=4 ) uniform 4-element array of highp atomic_uint)
0:23 Constant:
0:23 2 (const int)
0:24 AtomicCounterDecrement (global highp uint)
0:24 'counter' (layout(binding=0 offset=0 ) uniform highp atomic_uint)
0:36 Function Definition: atoms( (global void)
0:36 Function Parameters:
0:38 Sequence
0:38 Sequence
0:38 move second child to first child (temp highp int)
0:38 'origi' (temp highp int)
0:38 AtomicAdd (global highp int)
0:38 'atomi' (shared highp int)
0:38 Constant:
0:38 3 (const int)
0:39 Sequence
0:39 move second child to first child (temp highp uint)
0:39 'origu' (temp highp uint)
0:39 AtomicAnd (global highp uint)
0:39 'atomu' (shared highp uint)
0:39 'value' (shared highp uint)
0:40 move second child to first child (temp highp uint)
0:40 'origu' (temp highp uint)
0:40 AtomicOr (global highp uint)
0:40 'atomu' (shared highp uint)
0:40 Constant:
0:40 7 (const uint)
0:41 move second child to first child (temp highp uint)
0:41 'origu' (temp highp uint)
0:41 AtomicXor (global highp uint)
0:41 'atomu' (shared highp uint)
0:41 Constant:
0:41 7 (const uint)
0:42 move second child to first child (temp highp uint)
0:42 'origu' (temp highp uint)
0:42 AtomicMin (global highp uint)
0:42 'atomu' (shared highp uint)
0:42 'value' (shared highp uint)
0:43 move second child to first child (temp highp int)
0:43 'origi' (temp highp int)
0:43 AtomicMax (global highp int)
0:43 'atomi' (shared highp int)
0:43 Constant:
0:43 7 (const int)
0:44 move second child to first child (temp highp int)
0:44 'origi' (temp highp int)
0:44 AtomicExchange (global highp int)
0:44 'atomi' (shared highp int)
0:44 'origi' (temp highp int)
0:45 move second child to first child (temp highp uint)
0:45 'origu' (temp highp uint)
0:45 AtomicCompSwap (global highp uint)
0:45 'atomu' (shared highp uint)
0:45 Constant:
0:45 10 (const uint)
0:45 'value' (shared highp uint)
0:46 AtomicAdd (global highp int)
0:46 direct index (temp highp int)
0:46 n_frames_rendered: direct index for structure (layout(column_major std140 offset=16 ) buffer highp 4-component vector of int)
0:46 'result' (layout(binding=0 column_major std140 ) restrict buffer block{layout(column_major std140 offset=0 ) buffer highp float f, layout(column_major std140 offset=16 ) buffer highp 4-component vector of int n_frames_rendered})
0:46 Constant:
0:46 1 (const int)
0:46 Constant:
0:46 2 (const int)
0:46 Constant:
0:46 1 (const int)
0:? Linker Objects
0:? 'counter' (layout(binding=0 offset=0 ) uniform highp atomic_uint)
0:? 'countArr' (layout(binding=0 offset=4 ) uniform 4-element array of highp atomic_uint)
0:? 'value' (shared highp uint)
0:? 'arrX' (global 1-element array of highp int)
0:? 'arrY' (global 1-element array of highp int)
0:? 'arrZ' (global 1-element array of highp int)
0:? 'atomi' (shared highp int)
0:? 'atomu' (shared highp uint)
0:? 'result' (layout(binding=0 column_major std140 ) restrict buffer block{layout(column_major std140 offset=0 ) buffer highp float f, layout(column_major std140 offset=16 ) buffer highp 4-component vector of int n_frames_rendered})
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Linked compute stage:
Shader version: 310
local_size = (1, 1, 1)
0:? Sequence
0:14 Function Definition: func(au1; (global highp uint)
0:14 Function Parameters:
0:14 'c' (in highp atomic_uint)
0:16 Sequence
0:16 Branch: Return with expression
0:16 AtomicCounterIncrement (global highp uint)
0:16 'c' (in highp atomic_uint)
0:19 Function Definition: main( (global void)
0:19 Function Parameters:
0:21 Sequence
0:21 MemoryBarrierAtomicCounter (global void)
0:22 Function Call: func(au1; (global highp uint)
0:22 'counter' (layout(binding=0 offset=0 ) uniform highp atomic_uint)
0:23 Sequence
0:23 move second child to first child (temp highp uint)
0:23 'val' (temp highp uint)
0:23 AtomicCounter (global highp uint)
0:23 direct index (layout(binding=0 offset=4 ) temp highp atomic_uint)
0:23 'countArr' (layout(binding=0 offset=4 ) uniform 4-element array of highp atomic_uint)
0:23 Constant:
0:23 2 (const int)
0:24 AtomicCounterDecrement (global highp uint)
0:24 'counter' (layout(binding=0 offset=0 ) uniform highp atomic_uint)
0:36 Function Definition: atoms( (global void)
0:36 Function Parameters:
0:38 Sequence
0:38 Sequence
0:38 move second child to first child (temp highp int)
0:38 'origi' (temp highp int)
0:38 AtomicAdd (global highp int)
0:38 'atomi' (shared highp int)
0:38 Constant:
0:38 3 (const int)
0:39 Sequence
0:39 move second child to first child (temp highp uint)
0:39 'origu' (temp highp uint)
0:39 AtomicAnd (global highp uint)
0:39 'atomu' (shared highp uint)
0:39 'value' (shared highp uint)
0:40 move second child to first child (temp highp uint)
0:40 'origu' (temp highp uint)
0:40 AtomicOr (global highp uint)
0:40 'atomu' (shared highp uint)
0:40 Constant:
0:40 7 (const uint)
0:41 move second child to first child (temp highp uint)
0:41 'origu' (temp highp uint)
0:41 AtomicXor (global highp uint)
0:41 'atomu' (shared highp uint)
0:41 Constant:
0:41 7 (const uint)
0:42 move second child to first child (temp highp uint)
0:42 'origu' (temp highp uint)
0:42 AtomicMin (global highp uint)
0:42 'atomu' (shared highp uint)
0:42 'value' (shared highp uint)
0:43 move second child to first child (temp highp int)
0:43 'origi' (temp highp int)
0:43 AtomicMax (global highp int)
0:43 'atomi' (shared highp int)
0:43 Constant:
0:43 7 (const int)
0:44 move second child to first child (temp highp int)
0:44 'origi' (temp highp int)
0:44 AtomicExchange (global highp int)
0:44 'atomi' (shared highp int)
0:44 'origi' (temp highp int)
0:45 move second child to first child (temp highp uint)
0:45 'origu' (temp highp uint)
0:45 AtomicCompSwap (global highp uint)
0:45 'atomu' (shared highp uint)
0:45 Constant:
0:45 10 (const uint)
0:45 'value' (shared highp uint)
0:46 AtomicAdd (global highp int)
0:46 direct index (temp highp int)
0:46 n_frames_rendered: direct index for structure (layout(column_major std140 offset=16 ) buffer highp 4-component vector of int)
0:46 'result' (layout(binding=0 column_major std140 ) restrict buffer block{layout(column_major std140 offset=0 ) buffer highp float f, layout(column_major std140 offset=16 ) buffer highp 4-component vector of int n_frames_rendered})
0:46 Constant:
0:46 1 (const int)
0:46 Constant:
0:46 2 (const int)
0:46 Constant:
0:46 1 (const int)
0:? Linker Objects
0:? 'counter' (layout(binding=0 offset=0 ) uniform highp atomic_uint)
0:? 'countArr' (layout(binding=0 offset=4 ) uniform 4-element array of highp atomic_uint)
0:? 'value' (shared highp uint)
0:? 'arrX' (global 1-element array of highp int)
0:? 'arrY' (global 1-element array of highp int)
0:? 'arrZ' (global 1-element array of highp int)
0:? 'atomi' (shared highp int)
0:? 'atomu' (shared highp uint)
0:? 'result' (layout(binding=0 column_major std140 ) restrict buffer block{layout(column_major std140 offset=0 ) buffer highp float f, layout(column_major std140 offset=16 ) buffer highp 4-component vector of int n_frames_rendered})
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 73
Capability Shader
Capability AtomicStorage
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint GLCompute 4 "main"
ExecutionMode 4 LocalSize 1 1 1
Source GLSL 450
Name 4 "main"
Name 10 "func(au1;"
Name 9 "c"
Name 12 "atoms("
Name 20 "counter"
Name 23 "val"
Name 27 "countArr"
Name 35 "origi"
Name 37 "atomi"
Name 40 "origu"
Name 42 "atomu"
Name 43 "value"
Name 60 "dataSSB"
MemberName 60(dataSSB) 0 "f"
MemberName 60(dataSSB) 1 "n_frames_rendered"
Name 62 "result"
Name 70 "arrX"
Name 71 "arrY"
Name 72 "arrZ"
Decorate 20(counter) Binding 0
Decorate 27(countArr) Binding 0
MemberDecorate 60(dataSSB) 0 Restrict
MemberDecorate 60(dataSSB) 0 Offset 0
MemberDecorate 60(dataSSB) 1 Restrict
MemberDecorate 60(dataSSB) 1 Offset 16
Decorate 60(dataSSB) BufferBlock
Decorate 62(result) DescriptorSet 0
Decorate 62(result) Binding 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 0
7: TypePointer AtomicCounter 6(int)
8: TypeFunction 6(int) 7(ptr)
14: 6(int) Constant 1
15: 6(int) Constant 0
19: 6(int) Constant 1024
20(counter): 7(ptr) Variable AtomicCounter
22: TypePointer Function 6(int)
24: 6(int) Constant 4
25: TypeArray 6(int) 24
26: TypePointer AtomicCounter 25
27(countArr): 26(ptr) Variable AtomicCounter
28: TypeInt 32 1
29: 28(int) Constant 2
34: TypePointer Function 28(int)
36: TypePointer Workgroup 28(int)
37(atomi): 36(ptr) Variable Workgroup
38: 28(int) Constant 3
41: TypePointer Workgroup 6(int)
42(atomu): 41(ptr) Variable Workgroup
43(value): 41(ptr) Variable Workgroup
46: 6(int) Constant 7
51: 28(int) Constant 7
55: 6(int) Constant 10
58: TypeFloat 32
59: TypeVector 28(int) 4
60(dataSSB): TypeStruct 58(float) 59(ivec4)
61: TypePointer Uniform 60(dataSSB)
62(result): 61(ptr) Variable Uniform
63: 28(int) Constant 1
64: 6(int) Constant 2
65: TypePointer Uniform 28(int)
68: TypeArray 28(int) 14
69: TypePointer Private 68
70(arrX): 69(ptr) Variable Private
71(arrY): 69(ptr) Variable Private
72(arrZ): 69(ptr) Variable Private
4(main): 2 Function None 3
5: Label
23(val): 22(ptr) Variable Function
MemoryBarrier 14 19
21: 6(int) FunctionCall 10(func(au1;) 20(counter)
30: 7(ptr) AccessChain 27(countArr) 29
31: 6(int) AtomicLoad 30 14 15
Store 23(val) 31
32: 6(int) AtomicIDecrement 20(counter) 14 15
33: 6(int) AtomicIIncrement 20(counter) 14 15
Return
FunctionEnd
10(func(au1;): 6(int) Function None 8
9(c): 7(ptr) FunctionParameter
11: Label
16: 6(int) AtomicIIncrement 9(c) 14 15
ReturnValue 16
FunctionEnd
12(atoms(): 2 Function None 3
13: Label
35(origi): 34(ptr) Variable Function
40(origu): 22(ptr) Variable Function
39: 28(int) AtomicIAdd 37(atomi) 14 15 38
Store 35(origi) 39
44: 6(int) Load 43(value)
45: 6(int) AtomicAnd 42(atomu) 14 15 44
Store 40(origu) 45
47: 6(int) AtomicOr 42(atomu) 14 15 46
Store 40(origu) 47
48: 6(int) AtomicXor 42(atomu) 14 15 46
Store 40(origu) 48
49: 6(int) Load 43(value)
50: 6(int) AtomicUMin 42(atomu) 14 15 49
Store 40(origu) 50
52: 28(int) AtomicSMax 37(atomi) 14 15 51
Store 35(origi) 52
53: 28(int) Load 35(origi)
54: 28(int) AtomicExchange 37(atomi) 14 15 53
Store 35(origi) 54
56: 6(int) Load 43(value)
57: 6(int) AtomicCompareExchange 42(atomu) 14 15 15 56 55
Store 40(origu) 57
66: 65(ptr) AccessChain 62(result) 63 64
67: 28(int) AtomicIAdd 66 14 15 63
Return
FunctionEnd

View File

@ -1,4 +1,4 @@
#version 310 es
#version 450
@ -22,6 +22,7 @@ void main()
func(counter);
uint val = atomicCounter(countArr[2]);
atomicCounterDecrement(counter);
atomicCounterIncrement(counter);
}
shared int atomi;

View File

@ -1259,7 +1259,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
}
if (spvVersion.vulkan == 0) {
// gl_spirv TODO
//
// Atomic counter functions.
//

View File

@ -186,7 +186,6 @@ INSTANTIATE_TEST_CASE_P(
"whileLoop.frag",
"nonVulkan.frag",
"negativeArraySize.comp",
"spv.atomic.comp",
"precise.tesc",
"precise_struct_block.vert",
"maxClipDistances.vert",

View File

@ -41,19 +41,29 @@
namespace glslangtest {
namespace {
using CompileToSpirvTest = GlslangTest<::testing::TestWithParam<std::string>>;
using CompileVulkanToSpirvTest = GlslangTest<::testing::TestWithParam<std::string>>;
using CompileOpenGLToSpirvTest = GlslangTest<::testing::TestWithParam<std::string>>;
using VulkanSemantics = GlslangTest<::testing::TestWithParam<std::string>>;
using VulkanAstSemantics = GlslangTest<::testing::TestWithParam<std::string>>;
// Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully
// generate SPIR-V.
TEST_P(CompileToSpirvTest, FromFile)
TEST_P(CompileVulkanToSpirvTest, FromFile)
{
loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(),
Source::GLSL, Semantics::Vulkan,
Target::Spv);
}
// Compiling GLSL to SPIR-V under OpenGL semantics. Expected to successfully
// generate SPIR-V.
TEST_P(CompileOpenGLToSpirvTest, FromFile)
{
loadFileCompileAndCheck(GLSLANG_TEST_DIRECTORY, GetParam(),
Source::GLSL, Semantics::OpenGL,
Target::Spv);
}
// GLSL-level Vulkan semantics test. Expected to error out before generating
// SPIR-V.
TEST_P(VulkanSemantics, FromFile)
@ -73,7 +83,7 @@ TEST_P(VulkanAstSemantics, FromFile)
// clang-format off
INSTANTIATE_TEST_CASE_P(
Glsl, CompileToSpirvTest,
Glsl, CompileVulkanToSpirvTest,
::testing::ValuesIn(std::vector<std::string>({
// Test looping constructs.
// No tests yet for making sure break and continue from a nested loop
@ -192,6 +202,18 @@ INSTANTIATE_TEST_CASE_P(
FileNameAsCustomTestSuffix
);
// clang-format off
INSTANTIATE_TEST_CASE_P(
Glsl, CompileOpenGLToSpirvTest,
::testing::ValuesIn(std::vector<std::string>({
// Test looping constructs.
// No tests yet for making sure break and continue from a nested loop
// goes to the innermost target.
"spv.atomic.comp",
})),
FileNameAsCustomTestSuffix
);
INSTANTIATE_TEST_CASE_P(
Glsl, VulkanSemantics,
::testing::ValuesIn(std::vector<std::string>({