SPV: Turn on atomic-storage functionality for SPIR-V.
authorJohn Kessenich <cepheus@frii.com>
Thu, 7 Jul 2016 19:20:00 +0000 (13:20 -0600)
committerJohn Kessenich <cepheus@frii.com>
Thu, 7 Jul 2016 23:40:35 +0000 (17:40 -0600)
This is used by OpenGL, but not Vulkan.
Includes:
 - atomicCounter, atomicIncrement, atomicCounterDecrement
 - atomic_uint layout-offset checking
 - AtomicStorage capability

SPIRV/GlslangToSpv.cpp
Test/baseResults/spv.atomic.comp.out
Test/spv.atomic.comp
glslang/MachineIndependent/Initialize.cpp
gtests/AST.FromFile.cpp
gtests/Spv.FromFile.cpp

index de87763..e949547 100755 (executable)
@@ -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:
index 14a0fe3..e4cf232 100755 (executable)
 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
index dc1fe6e..8ab846e 100644 (file)
@@ -1,4 +1,4 @@
-#version 310 es\r
+#version 450\r
 \r
 \r
 \r
@@ -22,6 +22,7 @@ void main()
     func(counter);\r
     uint val = atomicCounter(countArr[2]);\r
     atomicCounterDecrement(counter);\r
+    atomicCounterIncrement(counter);\r
 }\r
 \r
 shared int atomi;\r
index 6de3a99..2e016a8 100644 (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.
         //
index 3e5ea37..6f4abef 100644 (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",
index 04787ea..00f4a98 100644 (file)
 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>({