summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp156
1 files changed, 116 insertions, 40 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
index ad2120670..16791be84 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
@@ -11,32 +11,104 @@
11 11
12namespace Shader::Backend::GLSL { 12namespace Shader::Backend::GLSL {
13namespace { 13namespace {
14static constexpr std::string_view cas_loop{R"(uint {}; 14static constexpr std::string_view cas_loop{R"({};
15for (;;){{ 15for (;;){{
16 uint old_value={}; 16 uint old_value={};
17 {}=atomicCompSwap({},old_value,{}({},{})); 17 {}=atomicCompSwap({},old_value,{}({},{}));
18 if ({}==old_value){{break;}} 18 if ({}==old_value){{break;}}
19}})"}; 19}})"};
20 20
21void CasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 21void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset,
22 const IR::Value& offset, std::string_view value, std::string_view function) { 22 std::string_view value, std::string_view function) {
23 const auto ret{ctx.reg_alloc.Define(inst)}; 23 const auto ret{ctx.reg_alloc.Define(inst, Type::U32)};
24 const std::string smem{fmt::format("smem[{}/4]", offset)};
25 ctx.Add(cas_loop.data(), ret, smem, ret, smem, function, smem, value, ret);
26}
27
28void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
29 const IR::Value& offset, std::string_view value, std::string_view function) {
30 const auto ret{ctx.reg_alloc.Define(inst, Type::U32)};
24 const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())}; 31 const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())};
25 ctx.Add(cas_loop.data(), ret, ssbo, ret, ssbo, function, ssbo, value, ret); 32 ctx.Add(cas_loop.data(), ret, ssbo, ret, ssbo, function, ssbo, value, ret);
26} 33}
27 34
28void CasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 35void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
29 const IR::Value& offset, std::string_view value, std::string_view function) { 36 const IR::Value& offset, std::string_view value,
37 std::string_view function) {
30 const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())}; 38 const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())};
31 const std::string u32_value{fmt::format("floatBitsToUint({})", value)}; 39 const auto ret{ctx.reg_alloc.Define(inst, Type::U32)};
32 const auto ret{ctx.reg_alloc.Define(inst)}; 40 ctx.Add(cas_loop.data(), ret, ssbo, ret, ssbo, function, ssbo, value, ret);
33 const auto ret_32{ret + "_u32"}; 41 ctx.AddF32("{}=uintBitsToFloat({});", inst, ret);
34 ctx.Add(cas_loop.data(), ret_32, ssbo, ret_32, ssbo, function, ssbo, value, ret_32);
35 ctx.Add("float {}=uintBitsToFloat({});", ret, ret_32);
36} 42}
37
38} // namespace 43} // namespace
39 44
45void EmitSharedAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
46 std::string_view value) {
47 ctx.AddU32("{}=atomicAdd(smem[{}/4],{});", inst, pointer_offset, value);
48}
49
50void EmitSharedAtomicSMin32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
51 std::string_view value) {
52 const std::string u32_value{fmt::format("uint({})", value)};
53 SharedCasFunction(ctx, inst, pointer_offset, u32_value, "CasMinS32");
54}
55
56void EmitSharedAtomicUMin32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
57 std::string_view value) {
58 ctx.AddU32("{}=atomicMin(smem[{}/4],{});", inst, pointer_offset, value);
59}
60
61void EmitSharedAtomicSMax32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
62 std::string_view value) {
63 const std::string u32_value{fmt::format("uint({})", value)};
64 SharedCasFunction(ctx, inst, pointer_offset, u32_value, "CasMaxS32");
65}
66
67void EmitSharedAtomicUMax32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
68 std::string_view value) {
69 ctx.AddU32("{}=atomicMax(smem[{}/4],{});", inst, pointer_offset, value);
70}
71
72void EmitSharedAtomicInc32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
73 std::string_view value) {
74 SharedCasFunction(ctx, inst, pointer_offset, value, "CasIncrement");
75}
76
77void EmitSharedAtomicDec32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
78 std::string_view value) {
79 SharedCasFunction(ctx, inst, pointer_offset, value, "CasDecrement");
80}
81
82void EmitSharedAtomicAnd32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
83 std::string_view value) {
84 ctx.AddU32("{}=atomicAnd(smem[{}/4],{});", inst, pointer_offset, value);
85}
86
87void EmitSharedAtomicOr32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
88 std::string_view value) {
89 ctx.AddU32("{}=atomicOr(smem[{}/4],{});", inst, pointer_offset, value);
90}
91
92void EmitSharedAtomicXor32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
93 std::string_view value) {
94 ctx.AddU32("{}=atomicXor(smem[{}/4],{});", inst, pointer_offset, value);
95}
96
97void EmitSharedAtomicExchange32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
98 std::string_view value) {
99 ctx.AddU32("{}=atomicExchange(smem[{}/4],{});", inst, pointer_offset, value);
100}
101
102void EmitSharedAtomicExchange64(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset,
103 std::string_view value) {
104 // LOG_WARNING("Int64 Atomics not supported, fallback to non-atomic");
105 const auto ret{ctx.reg_alloc.Define(inst, Type::U64)};
106 ctx.Add("{}=packUint2x32(uvec2(smem[{}/4],smem[({}+4)/4]));", ret, pointer_offset,
107 pointer_offset);
108 ctx.Add("smem[{}/4]=unpackUint2x32({}).x;smem[({}+4)/4]=unpackUint2x32({}).y;", pointer_offset,
109 value, pointer_offset, value);
110}
111
40void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 112void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
41 const IR::Value& offset, std::string_view value) { 113 const IR::Value& offset, std::string_view value) {
42 ctx.AddU32("{}=atomicAdd(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value); 114 ctx.AddU32("{}=atomicAdd(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value);
@@ -45,7 +117,7 @@ void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value&
45void EmitStorageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 117void EmitStorageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
46 const IR::Value& offset, std::string_view value) { 118 const IR::Value& offset, std::string_view value) {
47 const std::string u32_value{fmt::format("uint({})", value)}; 119 const std::string u32_value{fmt::format("uint({})", value)};
48 CasFunction(ctx, inst, binding, offset, u32_value, "CasMinS32"); 120 SsboCasFunction(ctx, inst, binding, offset, u32_value, "CasMinS32");
49} 121}
50 122
51void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 123void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
@@ -56,7 +128,7 @@ void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value&
56void EmitStorageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 128void EmitStorageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
57 const IR::Value& offset, std::string_view value) { 129 const IR::Value& offset, std::string_view value) {
58 const std::string u32_value{fmt::format("uint({})", value)}; 130 const std::string u32_value{fmt::format("uint({})", value)};
59 CasFunction(ctx, inst, binding, offset, u32_value, "CasMaxS32"); 131 SsboCasFunction(ctx, inst, binding, offset, u32_value, "CasMaxS32");
60} 132}
61 133
62void EmitStorageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 134void EmitStorageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
@@ -66,12 +138,12 @@ void EmitStorageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value&
66 138
67void EmitStorageAtomicInc32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 139void EmitStorageAtomicInc32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
68 const IR::Value& offset, std::string_view value) { 140 const IR::Value& offset, std::string_view value) {
69 CasFunction(ctx, inst, binding, offset, value, "CasIncrement"); 141 SsboCasFunction(ctx, inst, binding, offset, value, "CasIncrement");
70} 142}
71 143
72void EmitStorageAtomicDec32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 144void EmitStorageAtomicDec32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
73 const IR::Value& offset, std::string_view value) { 145 const IR::Value& offset, std::string_view value) {
74 CasFunction(ctx, inst, binding, offset, value, "CasDecrement"); 146 SsboCasFunction(ctx, inst, binding, offset, value, "CasDecrement");
75} 147}
76 148
77void EmitStorageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 149void EmitStorageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
@@ -97,7 +169,7 @@ void EmitStorageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Val
97void EmitStorageAtomicIAdd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 169void EmitStorageAtomicIAdd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
98 const IR::Value& offset, std::string_view value) { 170 const IR::Value& offset, std::string_view value) {
99 // LOG_WARNING(..., "Op falling to non-atomic"); 171 // LOG_WARNING(..., "Op falling to non-atomic");
100 ctx.AddU64("{}=uint64_t(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), 172 ctx.AddU64("{}=packUint2x32(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(),
101 binding.U32(), offset.U32() + 1); 173 binding.U32(), offset.U32() + 1);
102 ctx.Add("ssbo{}[{}]+=unpackUint2x32({}).x;ssbo{}[{}]+=unpackUint2x32({}).y;", binding.U32(), 174 ctx.Add("ssbo{}[{}]+=unpackUint2x32({}).x;ssbo{}[{}]+=unpackUint2x32({}).y;", binding.U32(),
103 offset.U32(), value, binding.U32(), offset.U32() + 1, value); 175 offset.U32(), value, binding.U32(), offset.U32() + 1, value);
@@ -106,7 +178,7 @@ void EmitStorageAtomicIAdd64(EmitContext& ctx, IR::Inst& inst, const IR::Value&
106void EmitStorageAtomicSMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 178void EmitStorageAtomicSMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
107 const IR::Value& offset, std::string_view value) { 179 const IR::Value& offset, std::string_view value) {
108 // LOG_WARNING(..., "Op falling to non-atomic"); 180 // LOG_WARNING(..., "Op falling to non-atomic");
109 ctx.AddS64("{}=int64_t(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), 181 ctx.AddS64("{}=packInt2x32(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(),
110 binding.U32(), offset.U32() + 1); 182 binding.U32(), offset.U32() + 1);
111 ctx.Add("for(int i=0;i<2;++i){{ " 183 ctx.Add("for(int i=0;i<2;++i){{ "
112 "ssbo{}[{}+i]=uint(min(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}", 184 "ssbo{}[{}+i]=uint(min(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}",
@@ -116,7 +188,7 @@ void EmitStorageAtomicSMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value&
116void EmitStorageAtomicUMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 188void EmitStorageAtomicUMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
117 const IR::Value& offset, std::string_view value) { 189 const IR::Value& offset, std::string_view value) {
118 // LOG_WARNING(..., "Op falling to non-atomic"); 190 // LOG_WARNING(..., "Op falling to non-atomic");
119 ctx.AddU64("{}=uint64_t(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), 191 ctx.AddU64("{}=packUint2x32(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(),
120 binding.U32(), offset.U32() + 1); 192 binding.U32(), offset.U32() + 1);
121 ctx.Add( 193 ctx.Add(
122 "for(int i=0;i<2;++i){{ ssbo{}[{}+i]=min(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}", 194 "for(int i=0;i<2;++i){{ ssbo{}[{}+i]=min(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}",
@@ -126,7 +198,7 @@ void EmitStorageAtomicUMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value&
126void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 198void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
127 const IR::Value& offset, std::string_view value) { 199 const IR::Value& offset, std::string_view value) {
128 // LOG_WARNING(..., "Op falling to non-atomic"); 200 // LOG_WARNING(..., "Op falling to non-atomic");
129 ctx.AddS64("{}=int64_t(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), 201 ctx.AddS64("{}=packInt2x32(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(),
130 binding.U32(), offset.U32() + 1); 202 binding.U32(), offset.U32() + 1);
131 ctx.Add("for(int i=0;i<2;++i){{ " 203 ctx.Add("for(int i=0;i<2;++i){{ "
132 "ssbo{}[{}+i]=uint(max(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}", 204 "ssbo{}[{}+i]=uint(max(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}",
@@ -136,7 +208,7 @@ void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value&
136void EmitStorageAtomicUMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 208void EmitStorageAtomicUMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
137 const IR::Value& offset, std::string_view value) { 209 const IR::Value& offset, std::string_view value) {
138 // LOG_WARNING(..., "Op falling to non-atomic"); 210 // LOG_WARNING(..., "Op falling to non-atomic");
139 ctx.AddU64("{}=uint64_t(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), 211 ctx.AddU64("{}=packUint2x32(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(),
140 binding.U32(), offset.U32() + 1); 212 binding.U32(), offset.U32() + 1);
141 ctx.Add( 213 ctx.Add(
142 "for(int i=0;i<2;++i){{ssbo{}[{}+i]=max(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}", 214 "for(int i=0;i<2;++i){{ssbo{}[{}+i]=max(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}",
@@ -145,65 +217,69 @@ void EmitStorageAtomicUMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value&
145 217
146void EmitStorageAtomicAnd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 218void EmitStorageAtomicAnd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
147 const IR::Value& offset, std::string_view value) { 219 const IR::Value& offset, std::string_view value) {
148 ctx.AddU64("{}=uint64_t(uvec2(atomicAnd(ssbo{}[{}],unpackUint2x32({}).x),atomicAnd(ssbo{}[{}]," 220 ctx.AddU64(
149 "unpackUint2x32({}).y)));", 221 "{}=packUint2x32(uvec2(atomicAnd(ssbo{}[{}],unpackUint2x32({}).x),atomicAnd(ssbo{}[{}],"
150 inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value); 222 "unpackUint2x32({}).y)));",
223 inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value);
151} 224}
152 225
153void EmitStorageAtomicOr64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 226void EmitStorageAtomicOr64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
154 const IR::Value& offset, std::string_view value) { 227 const IR::Value& offset, std::string_view value) {
155 ctx.AddU64("{}=uint64_t(uvec2(atomicOr(ssbo{}[{}],unpackUint2x32({}).x),atomicOr(ssbo{}[{}]," 228 ctx.AddU64(
156 "unpackUint2x32({}).y)));", 229 "{}=packUint2x32(uvec2(atomicOr(ssbo{}[{}],unpackUint2x32({}).x),atomicOr(ssbo{}[{}],"
157 inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value); 230 "unpackUint2x32({}).y)));",
231 inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value);
158} 232}
159 233
160void EmitStorageAtomicXor64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 234void EmitStorageAtomicXor64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
161 const IR::Value& offset, std::string_view value) { 235 const IR::Value& offset, std::string_view value) {
162 ctx.AddU64("{}=uint64_t(uvec2(atomicXor(ssbo{}[{}],unpackUint2x32({}).x),atomicXor(ssbo{}[{}]," 236 ctx.AddU64(
163 "unpackUint2x32({}).y)));", 237 "{}=packUint2x32(uvec2(atomicXor(ssbo{}[{}],unpackUint2x32({}).x),atomicXor(ssbo{}[{}],"
164 inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value); 238 "unpackUint2x32({}).y)));",
239 inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value);
165} 240}
166 241
167void EmitStorageAtomicExchange64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 242void EmitStorageAtomicExchange64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
168 const IR::Value& offset, std::string_view value) { 243 const IR::Value& offset, std::string_view value) {
169 ctx.AddU64("{}=uint64_t(uvec2(atomicExchange(ssbo{}[{}],unpackUint2x32({}).x),atomicExchange(" 244 ctx.AddU64(
170 "ssbo{}[{}],unpackUint2x32({}).y)));", 245 "{}=packUint2x32(uvec2(atomicExchange(ssbo{}[{}],unpackUint2x32({}).x),atomicExchange("
171 inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value); 246 "ssbo{}[{}],unpackUint2x32({}).y)));",
247 inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value);
172} 248}
173 249
174void EmitStorageAtomicAddF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 250void EmitStorageAtomicAddF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
175 const IR::Value& offset, std::string_view value) { 251 const IR::Value& offset, std::string_view value) {
176 CasFunctionF32(ctx, inst, binding, offset, value, "CasFloatAdd"); 252 SsboCasFunctionF32(ctx, inst, binding, offset, value, "CasFloatAdd");
177} 253}
178 254
179void EmitStorageAtomicAddF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 255void EmitStorageAtomicAddF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
180 const IR::Value& offset, std::string_view value) { 256 const IR::Value& offset, std::string_view value) {
181 CasFunction(ctx, inst, binding, offset, value, "CasFloatAdd16x2"); 257 SsboCasFunction(ctx, inst, binding, offset, value, "CasFloatAdd16x2");
182} 258}
183 259
184void EmitStorageAtomicAddF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 260void EmitStorageAtomicAddF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
185 const IR::Value& offset, std::string_view value) { 261 const IR::Value& offset, std::string_view value) {
186 CasFunction(ctx, inst, binding, offset, value, "CasFloatAdd32x2"); 262 SsboCasFunction(ctx, inst, binding, offset, value, "CasFloatAdd32x2");
187} 263}
188 264
189void EmitStorageAtomicMinF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 265void EmitStorageAtomicMinF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
190 const IR::Value& offset, std::string_view value) { 266 const IR::Value& offset, std::string_view value) {
191 CasFunction(ctx, inst, binding, offset, value, "CasFloatMin16x2"); 267 SsboCasFunction(ctx, inst, binding, offset, value, "CasFloatMin16x2");
192} 268}
193 269
194void EmitStorageAtomicMinF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 270void EmitStorageAtomicMinF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
195 const IR::Value& offset, std::string_view value) { 271 const IR::Value& offset, std::string_view value) {
196 CasFunction(ctx, inst, binding, offset, value, "CasFloatMin32x2"); 272 SsboCasFunction(ctx, inst, binding, offset, value, "CasFloatMin32x2");
197} 273}
198 274
199void EmitStorageAtomicMaxF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 275void EmitStorageAtomicMaxF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
200 const IR::Value& offset, std::string_view value) { 276 const IR::Value& offset, std::string_view value) {
201 CasFunction(ctx, inst, binding, offset, value, "CasFloatMax16x2"); 277 SsboCasFunction(ctx, inst, binding, offset, value, "CasFloatMax16x2");
202} 278}
203 279
204void EmitStorageAtomicMaxF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 280void EmitStorageAtomicMaxF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
205 const IR::Value& offset, std::string_view value) { 281 const IR::Value& offset, std::string_view value) {
206 CasFunction(ctx, inst, binding, offset, value, "CasFloatMax32x2"); 282 SsboCasFunction(ctx, inst, binding, offset, value, "CasFloatMax32x2");
207} 283}
208 284
209void EmitGlobalAtomicIAdd32(EmitContext&) { 285void EmitGlobalAtomicIAdd32(EmitContext&) {