diff options
| author | 2021-05-25 01:52:02 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:36 -0400 | |
| commit | 9cc1b8a873196dac5a97368df125816b5b195777 (patch) | |
| tree | 18e640848aa6e01707bc58479e3c776df0200440 /src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp | |
| parent | glsl: Revert ssbo aliasing. Storage Atomics impl (diff) | |
| download | yuzu-9cc1b8a873196dac5a97368df125816b5b195777.tar.gz yuzu-9cc1b8a873196dac5a97368df125816b5b195777.tar.xz yuzu-9cc1b8a873196dac5a97368df125816b5b195777.zip | |
glsl: F16x2 storage atomics
Diffstat (limited to 'src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp | 85 |
1 files changed, 34 insertions, 51 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp index 0b29c213b..b6b326762 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp | |||
| @@ -12,8 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Shader::Backend::GLSL { | 13 | namespace Shader::Backend::GLSL { |
| 14 | namespace { | 14 | namespace { |
| 15 | static constexpr std::string_view cas_loop{R"( | 15 | static constexpr std::string_view cas_loop{R"(uint {}; |
| 16 | uint {}; | ||
| 17 | for (;;){{ | 16 | for (;;){{ |
| 18 | uint old_value={}; | 17 | uint old_value={}; |
| 19 | {}=atomicCompSwap({},old_value,{}({},{})); | 18 | {}=atomicCompSwap({},old_value,{}({},{})); |
| @@ -49,6 +48,14 @@ void CasFunctionF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding | |||
| 49 | const auto ret{ctx.reg_alloc.Define(inst)}; | 48 | const auto ret{ctx.reg_alloc.Define(inst)}; |
| 50 | CasFunction(ctx, ret, ssbo, u32_value, function); | 49 | CasFunction(ctx, ret, ssbo, u32_value, function); |
| 51 | } | 50 | } |
| 51 | |||
| 52 | void CasFunctionF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | ||
| 53 | const IR::Value& offset, std::string_view value, std::string_view function) { | ||
| 54 | const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())}; | ||
| 55 | const std::string u32_value{fmt::format("packFloat2x16({})", value)}; | ||
| 56 | const auto ret{ctx.reg_alloc.Define(inst)}; | ||
| 57 | CasFunction(ctx, ret, ssbo, u32_value, function); | ||
| 58 | } | ||
| 52 | } // namespace | 59 | } // namespace |
| 53 | 60 | ||
| 54 | void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 61 | void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -122,11 +129,8 @@ void EmitStorageAtomicSMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& | |||
| 122 | // LOG_WARNING(..., "Op falling to non-atomic"); | 129 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 123 | ctx.AddS64("{}=int64_t(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 130 | ctx.AddS64("{}=int64_t(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), |
| 124 | binding.U32(), offset.U32() + 1); | 131 | binding.U32(), offset.U32() + 1); |
| 125 | ctx.Add(R"( | 132 | ctx.Add("for(int i=0;i<2;++i){{ " |
| 126 | for(int i=0;i<2;++i){{ | 133 | "ssbo{}[{}+i]=uint(min(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}", |
| 127 | ssbo{}[{}+i]=uint(min(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i])); | ||
| 128 | }} | ||
| 129 | )", | ||
| 130 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); | 134 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); |
| 131 | } | 135 | } |
| 132 | 136 | ||
| @@ -135,12 +139,9 @@ void EmitStorageAtomicUMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& | |||
| 135 | // LOG_WARNING(..., "Op falling to non-atomic"); | 139 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 136 | ctx.AddU64("{}=uint64_t(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 140 | ctx.AddU64("{}=uint64_t(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), |
| 137 | binding.U32(), offset.U32() + 1); | 141 | binding.U32(), offset.U32() + 1); |
| 138 | ctx.Add(R"( | 142 | ctx.Add( |
| 139 | for(int i=0;i<2;++i){{ | 143 | "for(int i=0;i<2;++i){{ ssbo{}[{}+i]=min(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}", |
| 140 | ssbo{}[{}+i]=min(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]); | 144 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); |
| 141 | }} | ||
| 142 | )", | ||
| 143 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); | ||
| 144 | } | 145 | } |
| 145 | 146 | ||
| 146 | void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 147 | void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -148,11 +149,8 @@ void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& | |||
| 148 | // LOG_WARNING(..., "Op falling to non-atomic"); | 149 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 149 | ctx.AddS64("{}=int64_t(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 150 | ctx.AddS64("{}=int64_t(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), |
| 150 | binding.U32(), offset.U32() + 1); | 151 | binding.U32(), offset.U32() + 1); |
| 151 | ctx.Add(R"( | 152 | ctx.Add("for(int i=0;i<2;++i){{ " |
| 152 | for(int i=0;i<2;++i){{ | 153 | "ssbo{}[{}+i]=uint(max(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}", |
| 153 | ssbo{}[{}+i]=uint(max(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i])); | ||
| 154 | }} | ||
| 155 | )", | ||
| 156 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); | 154 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); |
| 157 | } | 155 | } |
| 158 | 156 | ||
| @@ -161,12 +159,9 @@ void EmitStorageAtomicUMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& | |||
| 161 | // LOG_WARNING(..., "Op falling to non-atomic"); | 159 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 162 | ctx.AddU64("{}=uint64_t(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 160 | ctx.AddU64("{}=uint64_t(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), |
| 163 | binding.U32(), offset.U32() + 1); | 161 | binding.U32(), offset.U32() + 1); |
| 164 | ctx.Add(R"( | 162 | ctx.Add( |
| 165 | for(int i=0;i<2;++i){{ | 163 | "for(int i=0;i<2;++i){{ssbo{}[{}+i]=max(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}", |
| 166 | ssbo{}[{}+i]=max(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]); | 164 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); |
| 167 | }} | ||
| 168 | )", | ||
| 169 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); | ||
| 170 | } | 165 | } |
| 171 | 166 | ||
| 172 | void EmitStorageAtomicAnd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 167 | void EmitStorageAtomicAnd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -202,45 +197,33 @@ void EmitStorageAtomicAddF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& | |||
| 202 | CasFunctionF32(ctx, inst, binding, offset, value, "CasFloatAdd"); | 197 | CasFunctionF32(ctx, inst, binding, offset, value, "CasFloatAdd"); |
| 203 | } | 198 | } |
| 204 | 199 | ||
| 205 | void EmitStorageAtomicAddF16x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 200 | void EmitStorageAtomicAddF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 206 | [[maybe_unused]] const IR::Value& binding, | 201 | const IR::Value& offset, std::string_view value) { |
| 207 | [[maybe_unused]] const IR::Value& offset, | 202 | CasFunctionF16x2(ctx, inst, binding, offset, value, "CasFloatAdd16x2"); |
| 208 | [[maybe_unused]] std::string_view value) { | ||
| 209 | throw NotImplementedException("GLSL Instrucion"); | ||
| 210 | } | 203 | } |
| 211 | 204 | ||
| 212 | void EmitStorageAtomicAddF32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 205 | void EmitStorageAtomicAddF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 213 | [[maybe_unused]] const IR::Value& binding, | 206 | const IR::Value& offset, std::string_view value) { |
| 214 | [[maybe_unused]] const IR::Value& offset, | ||
| 215 | [[maybe_unused]] std::string_view value) { | ||
| 216 | CasFunctionF32x2(ctx, inst, binding, offset, value, "CasFloatAdd32x2"); | 207 | CasFunctionF32x2(ctx, inst, binding, offset, value, "CasFloatAdd32x2"); |
| 217 | } | 208 | } |
| 218 | 209 | ||
| 219 | void EmitStorageAtomicMinF16x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 210 | void EmitStorageAtomicMinF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 220 | [[maybe_unused]] const IR::Value& binding, | 211 | const IR::Value& offset, std::string_view value) { |
| 221 | [[maybe_unused]] const IR::Value& offset, | 212 | CasFunctionF16x2(ctx, inst, binding, offset, value, "CasFloatMin16x2"); |
| 222 | [[maybe_unused]] std::string_view value) { | ||
| 223 | throw NotImplementedException("GLSL Instrucion"); | ||
| 224 | } | 213 | } |
| 225 | 214 | ||
| 226 | void EmitStorageAtomicMinF32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 215 | void EmitStorageAtomicMinF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 227 | [[maybe_unused]] const IR::Value& binding, | 216 | const IR::Value& offset, std::string_view value) { |
| 228 | [[maybe_unused]] const IR::Value& offset, | ||
| 229 | [[maybe_unused]] std::string_view value) { | ||
| 230 | CasFunctionF32x2(ctx, inst, binding, offset, value, "CasFloatMin32x2"); | 217 | CasFunctionF32x2(ctx, inst, binding, offset, value, "CasFloatMin32x2"); |
| 231 | } | 218 | } |
| 232 | 219 | ||
| 233 | void EmitStorageAtomicMaxF16x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 220 | void EmitStorageAtomicMaxF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 234 | [[maybe_unused]] const IR::Value& binding, | 221 | const IR::Value& offset, std::string_view value) { |
| 235 | [[maybe_unused]] const IR::Value& offset, | 222 | CasFunctionF16x2(ctx, inst, binding, offset, value, "CasFloatMax16x2"); |
| 236 | [[maybe_unused]] std::string_view value) { | ||
| 237 | throw NotImplementedException("GLSL Instrucion"); | ||
| 238 | } | 223 | } |
| 239 | 224 | ||
| 240 | void EmitStorageAtomicMaxF32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 225 | void EmitStorageAtomicMaxF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 241 | [[maybe_unused]] const IR::Value& binding, | 226 | const IR::Value& offset, std::string_view value) { |
| 242 | [[maybe_unused]] const IR::Value& offset, | ||
| 243 | [[maybe_unused]] std::string_view value) { | ||
| 244 | CasFunctionF32x2(ctx, inst, binding, offset, value, "CasFloatMax32x2"); | 227 | CasFunctionF32x2(ctx, inst, binding, offset, value, "CasFloatMax32x2"); |
| 245 | } | 228 | } |
| 246 | 229 | ||