diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
4 files changed, 130 insertions, 114 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 02d88b7ad..b9594de40 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -182,10 +182,10 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) { | |||
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | void EmitContext::DefineHelperFunctions() { | 184 | void EmitContext::DefineHelperFunctions() { |
| 185 | if (info.uses_global_increment) { | 185 | if (info.uses_global_increment || info.uses_shared_increment) { |
| 186 | header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; | 186 | header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; |
| 187 | } | 187 | } |
| 188 | if (info.uses_global_decrement) { | 188 | if (info.uses_global_decrement || info.uses_shared_decrement) { |
| 189 | header += | 189 | header += |
| 190 | "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; | 190 | "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; |
| 191 | } | 191 | } |
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 | ||
| 12 | namespace Shader::Backend::GLSL { | 12 | namespace Shader::Backend::GLSL { |
| 13 | namespace { | 13 | namespace { |
| 14 | static constexpr std::string_view cas_loop{R"(uint {}; | 14 | static constexpr std::string_view cas_loop{R"({}; |
| 15 | for (;;){{ | 15 | for (;;){{ |
| 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 | ||
| 21 | void CasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 21 | void 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 | |||
| 28 | void 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 | ||
| 28 | void CasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 35 | void 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 | ||
| 45 | void 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 | |||
| 50 | void 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 | |||
| 56 | void 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 | |||
| 61 | void 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 | |||
| 67 | void 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 | |||
| 72 | void 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 | |||
| 77 | void 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 | |||
| 82 | void 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 | |||
| 87 | void 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 | |||
| 92 | void 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 | |||
| 97 | void 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 | |||
| 102 | void 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 | |||
| 40 | void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 112 | void 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& | |||
| 45 | void EmitStorageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 117 | void 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 | ||
| 51 | void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 123 | void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -56,7 +128,7 @@ void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& | |||
| 56 | void EmitStorageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 128 | void 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 | ||
| 62 | void EmitStorageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 134 | void 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 | ||
| 67 | void EmitStorageAtomicInc32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 139 | void 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 | ||
| 72 | void EmitStorageAtomicDec32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 144 | void 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 | ||
| 77 | void EmitStorageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 149 | void EmitStorageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -97,7 +169,7 @@ void EmitStorageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Val | |||
| 97 | void EmitStorageAtomicIAdd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 169 | void 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& | |||
| 106 | void EmitStorageAtomicSMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 178 | void 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& | |||
| 116 | void EmitStorageAtomicUMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 188 | void 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& | |||
| 126 | void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 198 | void 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& | |||
| 136 | void EmitStorageAtomicUMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 208 | void 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 | ||
| 146 | void EmitStorageAtomicAnd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 218 | void 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 | ||
| 153 | void EmitStorageAtomicOr64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 226 | void 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 | ||
| 160 | void EmitStorageAtomicXor64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 234 | void 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 | ||
| 167 | void EmitStorageAtomicExchange64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 242 | void 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 | ||
| 174 | void EmitStorageAtomicAddF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 250 | void 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 | ||
| 179 | void EmitStorageAtomicAddF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 255 | void 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 | ||
| 184 | void EmitStorageAtomicAddF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 260 | void 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 | ||
| 189 | void EmitStorageAtomicMinF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 265 | void 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 | ||
| 194 | void EmitStorageAtomicMinF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 270 | void 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 | ||
| 199 | void EmitStorageAtomicMaxF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 275 | void 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 | ||
| 204 | void EmitStorageAtomicMaxF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 280 | void 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 | ||
| 209 | void EmitGlobalAtomicIAdd32(EmitContext&) { | 285 | void EmitGlobalAtomicIAdd32(EmitContext&) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index 1e7247358..703db80ee 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h | |||
| @@ -421,29 +421,29 @@ void EmitSGreaterThanEqual(EmitContext& ctx, IR::Inst& inst, std::string_view lh | |||
| 421 | std::string_view rhs); | 421 | std::string_view rhs); |
| 422 | void EmitUGreaterThanEqual(EmitContext& ctx, IR::Inst& inst, std::string_view lhs, | 422 | void EmitUGreaterThanEqual(EmitContext& ctx, IR::Inst& inst, std::string_view lhs, |
| 423 | std::string_view rhs); | 423 | std::string_view rhs); |
| 424 | void EmitSharedAtomicIAdd32(EmitContext& ctx, std::string_view pointer_offset, | 424 | void EmitSharedAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 425 | std::string_view value); | 425 | std::string_view value); |
| 426 | void EmitSharedAtomicSMin32(EmitContext& ctx, std::string_view pointer_offset, | 426 | void EmitSharedAtomicSMin32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 427 | std::string_view value); | 427 | std::string_view value); |
| 428 | void EmitSharedAtomicUMin32(EmitContext& ctx, std::string_view pointer_offset, | 428 | void EmitSharedAtomicUMin32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 429 | std::string_view value); | 429 | std::string_view value); |
| 430 | void EmitSharedAtomicSMax32(EmitContext& ctx, std::string_view pointer_offset, | 430 | void EmitSharedAtomicSMax32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 431 | std::string_view value); | 431 | std::string_view value); |
| 432 | void EmitSharedAtomicUMax32(EmitContext& ctx, std::string_view pointer_offset, | 432 | void EmitSharedAtomicUMax32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 433 | std::string_view value); | 433 | std::string_view value); |
| 434 | void EmitSharedAtomicInc32(EmitContext& ctx, std::string_view pointer_offset, | 434 | void EmitSharedAtomicInc32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 435 | std::string_view value); | 435 | std::string_view value); |
| 436 | void EmitSharedAtomicDec32(EmitContext& ctx, std::string_view pointer_offset, | 436 | void EmitSharedAtomicDec32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 437 | std::string_view value); | 437 | std::string_view value); |
| 438 | void EmitSharedAtomicAnd32(EmitContext& ctx, std::string_view pointer_offset, | 438 | void EmitSharedAtomicAnd32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 439 | std::string_view value); | 439 | std::string_view value); |
| 440 | void EmitSharedAtomicOr32(EmitContext& ctx, std::string_view pointer_offset, | 440 | void EmitSharedAtomicOr32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 441 | std::string_view value); | 441 | std::string_view value); |
| 442 | void EmitSharedAtomicXor32(EmitContext& ctx, std::string_view pointer_offset, | 442 | void EmitSharedAtomicXor32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 443 | std::string_view value); | 443 | std::string_view value); |
| 444 | void EmitSharedAtomicExchange32(EmitContext& ctx, std::string_view pointer_offset, | 444 | void EmitSharedAtomicExchange32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 445 | std::string_view value); | 445 | std::string_view value); |
| 446 | void EmitSharedAtomicExchange64(EmitContext& ctx, std::string_view pointer_offset, | 446 | void EmitSharedAtomicExchange64(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 447 | std::string_view value); | 447 | std::string_view value); |
| 448 | void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 448 | void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 449 | const IR::Value& offset, std::string_view value); | 449 | const IR::Value& offset, std::string_view value); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp index 088c86f30..22ea9c9b1 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp | |||
| @@ -324,66 +324,6 @@ void EmitGetInBoundsFromOp(EmitContext& ctx) { | |||
| 324 | NotImplemented(); | 324 | NotImplemented(); |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | void EmitSharedAtomicIAdd32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 328 | std::string_view value) { | ||
| 329 | NotImplemented(); | ||
| 330 | } | ||
| 331 | |||
| 332 | void EmitSharedAtomicSMin32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 333 | std::string_view value) { | ||
| 334 | NotImplemented(); | ||
| 335 | } | ||
| 336 | |||
| 337 | void EmitSharedAtomicUMin32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 338 | std::string_view value) { | ||
| 339 | NotImplemented(); | ||
| 340 | } | ||
| 341 | |||
| 342 | void EmitSharedAtomicSMax32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 343 | std::string_view value) { | ||
| 344 | NotImplemented(); | ||
| 345 | } | ||
| 346 | |||
| 347 | void EmitSharedAtomicUMax32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 348 | std::string_view value) { | ||
| 349 | NotImplemented(); | ||
| 350 | } | ||
| 351 | |||
| 352 | void EmitSharedAtomicInc32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 353 | std::string_view value) { | ||
| 354 | NotImplemented(); | ||
| 355 | } | ||
| 356 | |||
| 357 | void EmitSharedAtomicDec32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 358 | std::string_view value) { | ||
| 359 | NotImplemented(); | ||
| 360 | } | ||
| 361 | |||
| 362 | void EmitSharedAtomicAnd32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 363 | std::string_view value) { | ||
| 364 | NotImplemented(); | ||
| 365 | } | ||
| 366 | |||
| 367 | void EmitSharedAtomicOr32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 368 | std::string_view value) { | ||
| 369 | NotImplemented(); | ||
| 370 | } | ||
| 371 | |||
| 372 | void EmitSharedAtomicXor32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 373 | std::string_view value) { | ||
| 374 | NotImplemented(); | ||
| 375 | } | ||
| 376 | |||
| 377 | void EmitSharedAtomicExchange32(EmitContext& ctx, std::string_view pointer_offset, | ||
| 378 | std::string_view value) { | ||
| 379 | NotImplemented(); | ||
| 380 | } | ||
| 381 | |||
| 382 | void EmitSharedAtomicExchange64(EmitContext& ctx, std::string_view pointer_offset, | ||
| 383 | std::string_view value) { | ||
| 384 | NotImplemented(); | ||
| 385 | } | ||
| 386 | |||
| 387 | void EmitBindlessImageAtomicIAdd32(EmitContext&) { | 327 | void EmitBindlessImageAtomicIAdd32(EmitContext&) { |
| 388 | NotImplemented(); | 328 | NotImplemented(); |
| 389 | } | 329 | } |