Web: Add basic atomics for SSBOs.
authorJohn Kessenich <cepheus@frii.com>
Fri, 18 Oct 2019 07:03:11 +0000 (01:03 -0600)
committerJohn Kessenich <cepheus@frii.com>
Wed, 23 Oct 2019 06:25:39 +0000 (00:25 -0600)
SPIRV/GlslangToSpv.cpp
Test/baseResults/web.comp.out
Test/web.comp
glslang/MachineIndependent/Initialize.cpp

index c6dcef5..f1ca015 100644 (file)
@@ -2572,11 +2572,6 @@ 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;
 
-#ifndef GLSLANG_WEB
-    case glslang::EOpAtomicStore:
-        noReturnValue = true;
-        // fallthrough
-    case glslang::EOpAtomicLoad:
     case glslang::EOpAtomicAdd:
     case glslang::EOpAtomicMin:
     case glslang::EOpAtomicMax:
@@ -2588,6 +2583,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         atomic = true;
         break;
 
+#ifndef GLSLANG_WEB
+    case glslang::EOpAtomicStore:
+        noReturnValue = true;
+        // fallthrough
+    case glslang::EOpAtomicLoad:
+        atomic = true;
+        break;
+
     case glslang::EOpAtomicCounterAdd:
     case glslang::EOpAtomicCounterSubtract:
     case glslang::EOpAtomicCounterMin:
@@ -2670,6 +2673,19 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
             if (arg == 1)
                 lvalue = true;
             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:
+            if (arg == 0)
+                lvalue = true;
+            break;
+
 #ifndef GLSLANG_WEB
         case glslang::EOpFrexp:
             if (arg == 1)
@@ -2688,14 +2704,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
                     invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType());
             }
             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:
         case glslang::EOpAtomicLoad:
         case glslang::EOpAtomicStore:
         case glslang::EOpAtomicCounterAdd:
@@ -2821,12 +2829,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 
         builder.createNoResultOp(spv::OpCooperativeMatrixStoreNV, idImmOps);
         result = 0;
-    } else if (atomic) {
-        // Handle all atomics
-        result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags);
     } else
 #endif
-    {
+    if (atomic) {
+        // Handle all atomics
+        result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags);
+    } else {
         // Pass through to generic operations.
         switch (glslangOperands.size()) {
         case 0:
index 711c720..79a3072 100644 (file)
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.0
 ; Generator: Khronos Glslang Reference Front End; 7
-; Bound: 91
+; Bound: 108
 ; Schema: 0
                OpCapability Shader
           %1 = OpExtInstImport "GLSL.std.450"
@@ -92,6 +92,7 @@
 %_ptr_Input_uint = OpTypePointer Input %uint
 %gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input
 %_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
+      %int_5 = OpConstant %int 5
  %int_197645 = OpConstant %int 197645
        %main = OpFunction %void None %3
           %5 = OpLabel
          %87 = OpIAdd %v3uint %79 %86
          %89 = OpAccessChain %_ptr_Uniform_v3uint %bInst %int_1
                OpStore %89 %87
+         %90 = OpAccessChain %_ptr_Uniform_int %bInst %int_0
+         %91 = OpAtomicIAdd %int %90 %uint_1 %uint_0 %int_2
+         %92 = OpAccessChain %_ptr_Uniform_int %bInst %int_0
+         %93 = OpAtomicSMin %int %92 %uint_1 %uint_0 %int_2
+         %94 = OpAccessChain %_ptr_Uniform_int %bInst %int_0
+         %95 = OpAtomicSMax %int %94 %uint_1 %uint_0 %int_2
+         %96 = OpAccessChain %_ptr_Uniform_int %bInst %int_0
+         %97 = OpAtomicAnd %int %96 %uint_1 %uint_0 %int_2
+         %98 = OpAccessChain %_ptr_Uniform_int %bInst %int_0
+         %99 = OpAtomicOr %int %98 %uint_1 %uint_0 %int_2
+        %100 = OpAccessChain %_ptr_Uniform_int %bInst %int_0
+        %101 = OpAtomicXor %int %100 %uint_1 %uint_0 %int_2
+        %102 = OpAccessChain %_ptr_Uniform_int %bInst %int_0
+        %103 = OpAtomicExchange %int %102 %uint_1 %uint_0 %int_2
+        %104 = OpAccessChain %_ptr_Uniform_int %bInst %int_0
+        %106 = OpAtomicCompareExchange %int %104 %uint_1 %uint_0 %uint_0 %int_2 %int_5
                OpReturn
                OpFunctionEnd
index 24ef43c..07847b4 100644 (file)
@@ -38,4 +38,13 @@ void main()
     s[3] = vec4(0, arrX[0], arrY[0], arrZ[0]);
     bInst.count = gl_NumWorkGroups + gl_WorkGroupSize + gl_WorkGroupID + gl_LocalInvocationID +
                   gl_GlobalInvocationID * gl_LocalInvocationIndex;
+
+    atomicAdd(bInst.size, 2);
+    atomicMin(bInst.size, 2);
+    atomicMax(bInst.size, 2);
+    atomicAnd(bInst.size, 2);
+    atomicOr(bInst.size, 2);
+    atomicXor(bInst.size, 2);
+    atomicExchange(bInst.size, 2);
+    atomicCompSwap(bInst.size, 5, 2);
 }
index 18590af..7f20ee8 100644 (file)
@@ -147,16 +147,16 @@ EProfile EDesktopProfile = static_cast<EProfile>(ENoProfile | ECoreProfile | ECo
 // Declare pointers to put into the table for versioning.
 #ifdef GLSLANG_WEB
     const Versioning* Es300Desktop130 = nullptr;
-#else
-    const Versioning Es300Desktop130Version[] = { { EEsProfile,      0, 300, 0, nullptr },
-                                                  { EDesktopProfile, 0, 130, 0, nullptr },
-                                                  { EBadProfile } };
-    const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
 
     const Versioning Es310Desktop430Version[] = { { EEsProfile,      0, 310, 0, nullptr },
                                                   { EDesktopProfile, 0, 430, 0, nullptr },
                                                   { EBadProfile } };
     const Versioning* Es310Desktop430 = &Es310Desktop430Version[0];
+#else
+    const Versioning Es300Desktop130Version[] = { { EEsProfile,      0, 300, 0, nullptr },
+                                                  { EDesktopProfile, 0, 130, 0, nullptr },
+                                                  { EBadProfile } };
+    const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
 
     const Versioning Es310Desktop450Version[] = { { EEsProfile,      0, 310, 0, nullptr },
                                                   { EDesktopProfile, 0, 450, 0, nullptr },
@@ -256,7 +256,6 @@ const BuiltInFunction BaseFunctions[] = {
     { EOpGreaterThanEqual, "greaterThanEqual", 2,   TypeU,     ClassBNS,     Es300Desktop130 },
     { EOpVectorEqual,      "equal",            2,   TypeU,     ClassBNS,     Es300Desktop130 },
     { EOpVectorNotEqual,   "notEqual",         2,   TypeU,     ClassBNS,     Es300Desktop130 },
-#ifndef GLSLANG_WEB
     { EOpAtomicAdd,        "atomicAdd",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop430 },
     { EOpAtomicMin,        "atomicMin",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop430 },
     { EOpAtomicMax,        "atomicMax",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop430 },
@@ -265,6 +264,7 @@ const BuiltInFunction BaseFunctions[] = {
     { EOpAtomicXor,        "atomicXor",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop430 },
     { EOpAtomicExchange,   "atomicExchange",   2,   TypeIU,    ClassV1FIOCV, Es310Desktop430 },
     { EOpAtomicCompSwap,   "atomicCompSwap",   3,   TypeIU,    ClassV1FIOCV, Es310Desktop430 },
+#ifndef GLSLANG_WEB
     { EOpMix,              "mix",              3,   TypeB,     ClassRegular, Es310Desktop450 },
     { EOpMix,              "mix",              3,   TypeIU,    ClassLB,      Es310Desktop450 },
 #endif
@@ -331,8 +331,10 @@ void AddTabledBuiltin(TString& decls, const BuiltInFunction& function)
                 if (arg == function.numArguments - 1 && (function.classes & ClassLO))
                     decls.append("out ");
                 if (arg == 0) {
+#ifndef GLSLANG_WEB
                     if (function.classes & ClassCV)
                         decls.append("coherent volatile ");
+#endif
                     if (function.classes & ClassFIO)
                         decls.append("inout ");
                     if (function.classes & ClassFO)