Web: Add basic atomics for SSBOs.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index c6dcef5..f1ca015 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2572,11 +2572,6 @@
// 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 @@
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 @@
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 @@
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 @@
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:
diff --git a/Test/baseResults/web.comp.out b/Test/baseResults/web.comp.out
index 711c720..79a3072 100644
--- a/Test/baseResults/web.comp.out
+++ b/Test/baseResults/web.comp.out
@@ -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
@@ -136,5 +137,21 @@
%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
diff --git a/Test/web.comp b/Test/web.comp
index 24ef43c..07847b4 100644
--- a/Test/web.comp
+++ b/Test/web.comp
@@ -38,4 +38,13 @@
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);
}
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 18590af..7f20ee8 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -147,16 +147,16 @@
// 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 @@
{ 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 @@
{ 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 @@
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)