diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_context.cpp | 9 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp | 106 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp | 63 |
3 files changed, 101 insertions, 77 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index da29290a2..788679f40 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -121,7 +121,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | void EmitContext::SetupExtensions(std::string&) { | 123 | void EmitContext::SetupExtensions(std::string&) { |
| 124 | header += "#extension GL_ARB_separate_shader_objects : enable\n"; | ||
| 125 | // TODO: track this usage | 124 | // TODO: track this usage |
| 126 | header += "#extension GL_ARB_sparse_texture2 : enable\n"; | 125 | header += "#extension GL_ARB_sparse_texture2 : enable\n"; |
| 127 | header += "#extension GL_EXT_texture_shadow_lod : enable\n"; | 126 | header += "#extension GL_EXT_texture_shadow_lod : enable\n"; |
| @@ -171,11 +170,13 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) { | |||
| 171 | if (info.storage_buffers_descriptors.empty()) { | 170 | if (info.storage_buffers_descriptors.empty()) { |
| 172 | return; | 171 | return; |
| 173 | } | 172 | } |
| 173 | u32 index{}; | ||
| 174 | for (const auto& desc : info.storage_buffers_descriptors) { | 174 | for (const auto& desc : info.storage_buffers_descriptors) { |
| 175 | header += | 175 | header += fmt::format("layout(std430,binding={}) buffer {}_ssbo_{}{{uint {}_ssbo{}[];}};", |
| 176 | fmt::format("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", | 176 | bindings.storage_buffer, stage_name, bindings.storage_buffer, |
| 177 | bindings.storage_buffer, bindings.storage_buffer, bindings.storage_buffer); | 177 | stage_name, index); |
| 178 | bindings.storage_buffer += desc.count; | 178 | bindings.storage_buffer += desc.count; |
| 179 | index += desc.count; | ||
| 179 | } | 180 | } |
| 180 | } | 181 | } |
| 181 | 182 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp index db4c60002..d3301054c 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp | |||
| @@ -27,14 +27,16 @@ void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset | |||
| 27 | void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 27 | void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 28 | const IR::Value& offset, std::string_view value, std::string_view function) { | 28 | const IR::Value& offset, std::string_view value, std::string_view function) { |
| 29 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | 29 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; |
| 30 | const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())}; | 30 | const std::string ssbo{ |
| 31 | fmt::format("{}_ssbo{}[{}]", ctx.stage_name, binding.U32(), offset.U32())}; | ||
| 31 | ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); | 32 | ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); |
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 35 | void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 35 | const IR::Value& offset, std::string_view value, | 36 | const IR::Value& offset, std::string_view value, |
| 36 | std::string_view function) { | 37 | std::string_view function) { |
| 37 | const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())}; | 38 | const std::string ssbo{ |
| 39 | fmt::format("{}_ssbo{}[{}]", ctx.stage_name, binding.U32(), offset.U32())}; | ||
| 38 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | 40 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; |
| 39 | ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); | 41 | ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); |
| 40 | ctx.AddF32("{}=uintBitsToFloat({});", inst, ret); | 42 | ctx.AddF32("{}=uintBitsToFloat({});", inst, ret); |
| @@ -109,7 +111,8 @@ void EmitSharedAtomicExchange64(EmitContext& ctx, IR::Inst& inst, std::string_vi | |||
| 109 | 111 | ||
| 110 | void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 112 | void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 111 | const IR::Value& offset, std::string_view value) { | 113 | const IR::Value& offset, std::string_view value) { |
| 112 | ctx.AddU32("{}=atomicAdd(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value); | 114 | ctx.AddU32("{}=atomicAdd({}_ssbo{}[{}],{});", inst, ctx.stage_name, binding.U32(), offset.U32(), |
| 115 | value); | ||
| 113 | } | 116 | } |
| 114 | 117 | ||
| 115 | void EmitStorageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 118 | void EmitStorageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -120,7 +123,8 @@ void EmitStorageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& | |||
| 120 | 123 | ||
| 121 | void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 124 | void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 122 | const IR::Value& offset, std::string_view value) { | 125 | const IR::Value& offset, std::string_view value) { |
| 123 | ctx.AddU32("{}=atomicMin(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value); | 126 | ctx.AddU32("{}=atomicMin({}_ssbo{}[{}],{});", inst, ctx.stage_name, binding.U32(), offset.U32(), |
| 127 | value); | ||
| 124 | } | 128 | } |
| 125 | 129 | ||
| 126 | void EmitStorageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 130 | void EmitStorageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -131,7 +135,8 @@ void EmitStorageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& | |||
| 131 | 135 | ||
| 132 | void EmitStorageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 136 | void EmitStorageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 133 | const IR::Value& offset, std::string_view value) { | 137 | const IR::Value& offset, std::string_view value) { |
| 134 | ctx.AddU32("{}=atomicMax(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value); | 138 | ctx.AddU32("{}=atomicMax({}_ssbo{}[{}],{});", inst, ctx.stage_name, binding.U32(), offset.U32(), |
| 139 | value); | ||
| 135 | } | 140 | } |
| 136 | 141 | ||
| 137 | void EmitStorageAtomicInc32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 142 | void EmitStorageAtomicInc32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -146,103 +151,116 @@ void EmitStorageAtomicDec32(EmitContext& ctx, IR::Inst& inst, const IR::Value& b | |||
| 146 | 151 | ||
| 147 | void EmitStorageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 152 | void EmitStorageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 148 | const IR::Value& offset, std::string_view value) { | 153 | const IR::Value& offset, std::string_view value) { |
| 149 | ctx.AddU32("{}=atomicAnd(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value); | 154 | ctx.AddU32("{}=atomicAnd({}_ssbo{}[{}],{});", inst, ctx.stage_name, binding.U32(), offset.U32(), |
| 155 | value); | ||
| 150 | } | 156 | } |
| 151 | 157 | ||
| 152 | void EmitStorageAtomicOr32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 158 | void EmitStorageAtomicOr32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 153 | const IR::Value& offset, std::string_view value) { | 159 | const IR::Value& offset, std::string_view value) { |
| 154 | ctx.AddU32("{}=atomicOr(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value); | 160 | ctx.AddU32("{}=atomicOr({}_ssbo{}[{}],{});", inst, ctx.stage_name, binding.U32(), offset.U32(), |
| 161 | value); | ||
| 155 | } | 162 | } |
| 156 | 163 | ||
| 157 | void EmitStorageAtomicXor32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 164 | void EmitStorageAtomicXor32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 158 | const IR::Value& offset, std::string_view value) { | 165 | const IR::Value& offset, std::string_view value) { |
| 159 | ctx.AddU32("{}=atomicXor(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value); | 166 | ctx.AddU32("{}=atomicXor({}_ssbo{}[{}],{});", inst, ctx.stage_name, binding.U32(), offset.U32(), |
| 167 | value); | ||
| 160 | } | 168 | } |
| 161 | 169 | ||
| 162 | void EmitStorageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 170 | void EmitStorageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 163 | const IR::Value& offset, std::string_view value) { | 171 | const IR::Value& offset, std::string_view value) { |
| 164 | ctx.AddU32("{}=atomicExchange(ssbo{}[{}],{});", inst, binding.U32(), offset.U32(), value); | 172 | ctx.AddU32("{}=atomicExchange({}_ssbo{}[{}],{});", inst, ctx.stage_name, binding.U32(), |
| 173 | offset.U32(), value); | ||
| 165 | } | 174 | } |
| 166 | 175 | ||
| 167 | void EmitStorageAtomicIAdd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 176 | void EmitStorageAtomicIAdd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 168 | const IR::Value& offset, std::string_view value) { | 177 | const IR::Value& offset, std::string_view value) { |
| 169 | // LOG_WARNING(..., "Op falling to non-atomic"); | 178 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 170 | ctx.AddU64("{}=packUint2x32(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 179 | ctx.AddU64("{}=packUint2x32(uvec2({}_ssbo{}[{}],{}_ssbo{}[{}]));", inst, ctx.stage_name, |
| 171 | binding.U32(), offset.U32() + 1); | 180 | binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), offset.U32() + 1); |
| 172 | ctx.Add("ssbo{}[{}]+=unpackUint2x32({}).x;ssbo{}[{}]+=unpackUint2x32({}).y;", binding.U32(), | 181 | ctx.Add("{}_ssbo{}[{}]+=unpackUint2x32({}).x;{}_ssbo{}[{}]+=unpackUint2x32({}).y;", |
| 173 | offset.U32(), value, binding.U32(), offset.U32() + 1, value); | 182 | ctx.stage_name, binding.U32(), offset.U32(), value, ctx.stage_name, binding.U32(), |
| 183 | offset.U32() + 1, value); | ||
| 174 | } | 184 | } |
| 175 | 185 | ||
| 176 | void EmitStorageAtomicSMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 186 | void EmitStorageAtomicSMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 177 | const IR::Value& offset, std::string_view value) { | 187 | const IR::Value& offset, std::string_view value) { |
| 178 | // LOG_WARNING(..., "Op falling to non-atomic"); | 188 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 179 | ctx.AddS64("{}=packInt2x32(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 189 | ctx.AddS64("{}=packInt2x32(ivec2({}_ssbo{}[{}],{}_ssbo{}[{}]));", inst, ctx.stage_name, |
| 180 | binding.U32(), offset.U32() + 1); | 190 | binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), offset.U32() + 1); |
| 181 | ctx.Add("for(int i=0;i<2;++i){{ " | 191 | ctx.Add("for(int i=0;i<2;++i){{ " |
| 182 | "ssbo{}[{}+i]=uint(min(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}", | 192 | "{}_ssbo{}[{}+i]=uint(min(int({}_ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}", |
| 183 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); | 193 | ctx.stage_name, binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), |
| 194 | offset.U32(), value); | ||
| 184 | } | 195 | } |
| 185 | 196 | ||
| 186 | void EmitStorageAtomicUMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 197 | void EmitStorageAtomicUMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 187 | const IR::Value& offset, std::string_view value) { | 198 | const IR::Value& offset, std::string_view value) { |
| 188 | // LOG_WARNING(..., "Op falling to non-atomic"); | 199 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 189 | ctx.AddU64("{}=packUint2x32(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 200 | ctx.AddU64("{}=packUint2x32(uvec2({}_ssbo{}[{}],{}_ssbo{}[{}]));", inst, ctx.stage_name, |
| 190 | binding.U32(), offset.U32() + 1); | 201 | binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), offset.U32() + 1); |
| 191 | ctx.Add( | 202 | ctx.Add("for(int i=0;i<2;++i){{ " |
| 192 | "for(int i=0;i<2;++i){{ ssbo{}[{}+i]=min(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}", | 203 | "{}_ssbo{}[{}+i]=min({}_ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}", |
| 193 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); | 204 | ctx.stage_name, binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), |
| 205 | offset.U32(), value); | ||
| 194 | } | 206 | } |
| 195 | 207 | ||
| 196 | void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 208 | void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 197 | const IR::Value& offset, std::string_view value) { | 209 | const IR::Value& offset, std::string_view value) { |
| 198 | // LOG_WARNING(..., "Op falling to non-atomic"); | 210 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 199 | ctx.AddS64("{}=packInt2x32(ivec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 211 | ctx.AddS64("{}=packInt2x32(ivec2({}_ssbo{}[{}],{}_ssbo{}[{}]));", inst, ctx.stage_name, |
| 200 | binding.U32(), offset.U32() + 1); | 212 | binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), offset.U32() + 1); |
| 201 | ctx.Add("for(int i=0;i<2;++i){{ " | 213 | ctx.Add("for(int i=0;i<2;++i){{ " |
| 202 | "ssbo{}[{}+i]=uint(max(int(ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}", | 214 | "{}_ssbo{}[{}+i]=uint(max(int({}_ssbo{}[{}+i]),unpackInt2x32(int64_t({}))[i]));}}", |
| 203 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); | 215 | ctx.stage_name, binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), |
| 216 | offset.U32(), value); | ||
| 204 | } | 217 | } |
| 205 | 218 | ||
| 206 | void EmitStorageAtomicUMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 219 | void EmitStorageAtomicUMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 207 | const IR::Value& offset, std::string_view value) { | 220 | const IR::Value& offset, std::string_view value) { |
| 208 | // LOG_WARNING(..., "Op falling to non-atomic"); | 221 | // LOG_WARNING(..., "Op falling to non-atomic"); |
| 209 | ctx.AddU64("{}=packUint2x32(uvec2(ssbo{}[{}],ssbo{}[{}]));", inst, binding.U32(), offset.U32(), | 222 | ctx.AddU64("{}=packUint2x32(uvec2({}_ssbo{}[{}],{}_ssbo{}[{}]));", inst, ctx.stage_name, |
| 210 | binding.U32(), offset.U32() + 1); | 223 | binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), offset.U32() + 1); |
| 211 | ctx.Add( | 224 | ctx.Add("for(int " |
| 212 | "for(int i=0;i<2;++i){{ssbo{}[{}+i]=max(ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}", | 225 | "i=0;i<2;++i){{{}_ssbo{}[{}+i]=max({}_ssbo{}[{}+i],unpackUint2x32(uint64_t({}))[i]);}}", |
| 213 | binding.U32(), offset.U32(), binding.U32(), offset.U32(), value); | 226 | ctx.stage_name, binding.U32(), offset.U32(), ctx.stage_name, binding.U32(), |
| 227 | offset.U32(), value); | ||
| 214 | } | 228 | } |
| 215 | 229 | ||
| 216 | void EmitStorageAtomicAnd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 230 | void EmitStorageAtomicAnd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 217 | const IR::Value& offset, std::string_view value) { | 231 | const IR::Value& offset, std::string_view value) { |
| 218 | ctx.AddU64( | 232 | ctx.AddU64("{}=packUint2x32(uvec2(atomicAnd({}_ssbo{}[{}],unpackUint2x32({}).x),atomicAnd({}_" |
| 219 | "{}=packUint2x32(uvec2(atomicAnd(ssbo{}[{}],unpackUint2x32({}).x),atomicAnd(ssbo{}[{}]," | 233 | "ssbo{}[{}]," |
| 220 | "unpackUint2x32({}).y)));", | 234 | "unpackUint2x32({}).y)));", |
| 221 | inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value); | 235 | inst, ctx.stage_name, binding.U32(), offset.U32(), value, ctx.stage_name, |
| 236 | binding.U32(), offset.U32() + 1, value); | ||
| 222 | } | 237 | } |
| 223 | 238 | ||
| 224 | void EmitStorageAtomicOr64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 239 | void EmitStorageAtomicOr64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 225 | const IR::Value& offset, std::string_view value) { | 240 | const IR::Value& offset, std::string_view value) { |
| 226 | ctx.AddU64( | 241 | ctx.AddU64( |
| 227 | "{}=packUint2x32(uvec2(atomicOr(ssbo{}[{}],unpackUint2x32({}).x),atomicOr(ssbo{}[{}]," | 242 | "{}=packUint2x32(uvec2(atomicOr({}_ssbo{}[{}],unpackUint2x32({}).x),atomicOr({}_ssbo{}[{}]," |
| 228 | "unpackUint2x32({}).y)));", | 243 | "unpackUint2x32({}).y)));", |
| 229 | inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value); | 244 | inst, ctx.stage_name, binding.U32(), offset.U32(), value, ctx.stage_name, binding.U32(), |
| 245 | offset.U32() + 1, value); | ||
| 230 | } | 246 | } |
| 231 | 247 | ||
| 232 | void EmitStorageAtomicXor64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 248 | void EmitStorageAtomicXor64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 233 | const IR::Value& offset, std::string_view value) { | 249 | const IR::Value& offset, std::string_view value) { |
| 234 | ctx.AddU64( | 250 | ctx.AddU64("{}=packUint2x32(uvec2(atomicXor({}_ssbo{}[{}],unpackUint2x32({}).x),atomicXor({}_" |
| 235 | "{}=packUint2x32(uvec2(atomicXor(ssbo{}[{}],unpackUint2x32({}).x),atomicXor(ssbo{}[{}]," | 251 | "ssbo{}[{}]," |
| 236 | "unpackUint2x32({}).y)));", | 252 | "unpackUint2x32({}).y)));", |
| 237 | inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value); | 253 | inst, ctx.stage_name, binding.U32(), offset.U32(), value, ctx.stage_name, |
| 254 | binding.U32(), offset.U32() + 1, value); | ||
| 238 | } | 255 | } |
| 239 | 256 | ||
| 240 | void EmitStorageAtomicExchange64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 257 | void EmitStorageAtomicExchange64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 241 | const IR::Value& offset, std::string_view value) { | 258 | const IR::Value& offset, std::string_view value) { |
| 242 | ctx.AddU64( | 259 | ctx.AddU64( |
| 243 | "{}=packUint2x32(uvec2(atomicExchange(ssbo{}[{}],unpackUint2x32({}).x),atomicExchange(" | 260 | "{}=packUint2x32(uvec2(atomicExchange({}_ssbo{}[{}],unpackUint2x32({}).x),atomicExchange(" |
| 244 | "ssbo{}[{}],unpackUint2x32({}).y)));", | 261 | "{}_ssbo{}[{}],unpackUint2x32({}).y)));", |
| 245 | inst, binding.U32(), offset.U32(), value, binding.U32(), offset.U32() + 1, value); | 262 | inst, ctx.stage_name, binding.U32(), offset.U32(), value, ctx.stage_name, binding.U32(), |
| 263 | offset.U32() + 1, value); | ||
| 246 | } | 264 | } |
| 247 | 265 | ||
| 248 | void EmitStorageAtomicAddF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 266 | void EmitStorageAtomicAddF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp index 8ce186733..78fbb9d6e 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp | |||
| @@ -13,53 +13,54 @@ void EmitLoadStorageU8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | |||
| 13 | [[maybe_unused]] const IR::Value& binding, | 13 | [[maybe_unused]] const IR::Value& binding, |
| 14 | [[maybe_unused]] const IR::Value& offset) { | 14 | [[maybe_unused]] const IR::Value& offset) { |
| 15 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 15 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 16 | ctx.AddU32("{}=bitfieldExtract(ssbo{}[{}/4],int({}%4)*8,8);", inst, binding.U32(), offset_var, | 16 | ctx.AddU32("{}=bitfieldExtract({}_ssbo{}[{}/4],int({}%4)*8,8);", inst, ctx.stage_name, |
| 17 | offset_var); | 17 | binding.U32(), offset_var, offset_var); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | void EmitLoadStorageS8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 20 | void EmitLoadStorageS8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, |
| 21 | [[maybe_unused]] const IR::Value& binding, | 21 | [[maybe_unused]] const IR::Value& binding, |
| 22 | [[maybe_unused]] const IR::Value& offset) { | 22 | [[maybe_unused]] const IR::Value& offset) { |
| 23 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 23 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 24 | ctx.AddS32("{}=bitfieldExtract(int(ssbo{}[{}/4]),int({}%4)*8,8);", inst, binding.U32(), | 24 | ctx.AddS32("{}=bitfieldExtract(int({}_ssbo{}[{}/4]),int({}%4)*8,8);", inst, ctx.stage_name, |
| 25 | offset_var, offset_var); | 25 | binding.U32(), offset_var, offset_var); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | void EmitLoadStorageU16([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 28 | void EmitLoadStorageU16([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, |
| 29 | [[maybe_unused]] const IR::Value& binding, | 29 | [[maybe_unused]] const IR::Value& binding, |
| 30 | [[maybe_unused]] const IR::Value& offset) { | 30 | [[maybe_unused]] const IR::Value& offset) { |
| 31 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 31 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 32 | ctx.AddU32("{}=bitfieldExtract(ssbo{}[{}/4],int(({}/2)%2)*16,16);", inst, binding.U32(), | 32 | ctx.AddU32("{}=bitfieldExtract({}_ssbo{}[{}/4],int(({}/2)%2)*16,16);", inst, ctx.stage_name, |
| 33 | offset_var, offset_var); | 33 | binding.U32(), offset_var, offset_var); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void EmitLoadStorageS16([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 36 | void EmitLoadStorageS16([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, |
| 37 | [[maybe_unused]] const IR::Value& binding, | 37 | [[maybe_unused]] const IR::Value& binding, |
| 38 | [[maybe_unused]] const IR::Value& offset) { | 38 | [[maybe_unused]] const IR::Value& offset) { |
| 39 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 39 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 40 | ctx.AddS32("{}=bitfieldExtract(int(ssbo{}[{}/4]),int(({}/2)%2)*16,16);", inst, binding.U32(), | 40 | ctx.AddS32("{}=bitfieldExtract(int({}_ssbo{}[{}/4]),int(({}/2)%2)*16,16);", inst, |
| 41 | offset_var, offset_var); | 41 | ctx.stage_name, binding.U32(), offset_var, offset_var); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 44 | void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 45 | const IR::Value& offset) { | 45 | const IR::Value& offset) { |
| 46 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 46 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 47 | ctx.AddU32("{}=ssbo{}[{}/4];", inst, binding.U32(), offset_var); | 47 | ctx.AddU32("{}={}_ssbo{}[{}/4];", inst, ctx.stage_name, binding.U32(), offset_var); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 50 | void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 51 | const IR::Value& offset) { | 51 | const IR::Value& offset) { |
| 52 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 52 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 53 | ctx.AddU32x2("{}=uvec2(ssbo{}[{}/4],ssbo{}[({}+4)/4]);", inst, binding.U32(), offset_var, | 53 | ctx.AddU32x2("{}=uvec2({}_ssbo{}[{}/4],{}_ssbo{}[({}+4)/4]);", inst, ctx.stage_name, |
| 54 | binding.U32(), offset_var); | 54 | binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | void EmitLoadStorage128(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 57 | void EmitLoadStorage128(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 58 | const IR::Value& offset) { | 58 | const IR::Value& offset) { |
| 59 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 59 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 60 | ctx.AddU32x4("{}=uvec4(ssbo{}[{}/4],ssbo{}[({}+4)/4],ssbo{}[({}+8)/4],ssbo{}[({}+12)/4]);", | 60 | ctx.AddU32x4( |
| 61 | inst, binding.U32(), offset_var, binding.U32(), offset_var, binding.U32(), | 61 | "{}=uvec4({}_ssbo{}[{}/4],{}_ssbo{}[({}+4)/4],{}_ssbo{}[({}+8)/4],{}_ssbo{}[({}+12)/4]);", |
| 62 | offset_var, binding.U32(), offset_var); | 62 | inst, ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, |
| 63 | ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var); | ||
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx, | 66 | void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx, |
| @@ -67,8 +68,9 @@ void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx, | |||
| 67 | [[maybe_unused]] const IR::Value& offset, | 68 | [[maybe_unused]] const IR::Value& offset, |
| 68 | [[maybe_unused]] std::string_view value) { | 69 | [[maybe_unused]] std::string_view value) { |
| 69 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 70 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 70 | ctx.Add("ssbo{}[{}/4]=bitfieldInsert(ssbo{}[{}/4],{},int({}%4)*8,8);", binding.U32(), | 71 | ctx.Add("{}_ssbo{}[{}/4]=bitfieldInsert({}_ssbo{}[{}/4],{},int({}%4)*8,8);", ctx.stage_name, |
| 71 | offset_var, binding.U32(), offset_var, value, offset_var); | 72 | binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, value, |
| 73 | offset_var); | ||
| 72 | } | 74 | } |
| 73 | 75 | ||
| 74 | void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, | 76 | void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, |
| @@ -76,8 +78,9 @@ void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, | |||
| 76 | [[maybe_unused]] const IR::Value& offset, | 78 | [[maybe_unused]] const IR::Value& offset, |
| 77 | [[maybe_unused]] std::string_view value) { | 79 | [[maybe_unused]] std::string_view value) { |
| 78 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 80 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 79 | ctx.Add("ssbo{}[{}/4]=bitfieldInsert(ssbo{}[{}/4],{},int({}%4)*8,8);", binding.U32(), | 81 | ctx.Add("{}_ssbo{}[{}/4]=bitfieldInsert({}_ssbo{}[{}/4],{},int({}%4)*8,8);", ctx.stage_name, |
| 80 | offset_var, binding.U32(), offset_var, value, offset_var); | 82 | binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, value, |
| 83 | offset_var); | ||
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, | 86 | void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, |
| @@ -85,8 +88,9 @@ void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, | |||
| 85 | [[maybe_unused]] const IR::Value& offset, | 88 | [[maybe_unused]] const IR::Value& offset, |
| 86 | [[maybe_unused]] std::string_view value) { | 89 | [[maybe_unused]] std::string_view value) { |
| 87 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 90 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 88 | ctx.Add("ssbo{}[{}/4]=bitfieldInsert(ssbo{}[{}/4],{},int(({}/2)%2)*16,16);", binding.U32(), | 91 | ctx.Add("{}_ssbo{}[{}/4]=bitfieldInsert({}_ssbo{}[{}/4],{},int(({}/2)%2)*16,16);", |
| 89 | offset_var, binding.U32(), offset_var, value, offset_var); | 92 | ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, |
| 93 | value, offset_var); | ||
| 90 | } | 94 | } |
| 91 | 95 | ||
| 92 | void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, | 96 | void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, |
| @@ -94,21 +98,22 @@ void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, | |||
| 94 | [[maybe_unused]] const IR::Value& offset, | 98 | [[maybe_unused]] const IR::Value& offset, |
| 95 | [[maybe_unused]] std::string_view value) { | 99 | [[maybe_unused]] std::string_view value) { |
| 96 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 100 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 97 | ctx.Add("ssbo{}[{}/4]=bitfieldInsert(ssbo{}[{}/4],{},int(({}/2)%2)*16,16);", binding.U32(), | 101 | ctx.Add("{}_ssbo{}[{}/4]=bitfieldInsert({}_ssbo{}[{}/4],{},int(({}/2)%2)*16,16);", |
| 98 | offset_var, binding.U32(), offset_var, value, offset_var); | 102 | ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, |
| 103 | value, offset_var); | ||
| 99 | } | 104 | } |
| 100 | 105 | ||
| 101 | void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | 106 | void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 102 | std::string_view value) { | 107 | std::string_view value) { |
| 103 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 108 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 104 | ctx.Add("ssbo{}[{}/4]={};", binding.U32(), offset_var, value); | 109 | ctx.Add("{}_ssbo{}[{}/4]={};", ctx.stage_name, binding.U32(), offset_var, value); |
| 105 | } | 110 | } |
| 106 | 111 | ||
| 107 | void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | 112 | void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 108 | std::string_view value) { | 113 | std::string_view value) { |
| 109 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 114 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 110 | ctx.Add("ssbo{}[{}/4]={}.x;", binding.U32(), offset_var, value); | 115 | ctx.Add("{}_ssbo{}[{}/4]={}.x;", ctx.stage_name, binding.U32(), offset_var, value); |
| 111 | ctx.Add("ssbo{}[({}+4)/4]={}.y;", binding.U32(), offset_var, value); | 116 | ctx.Add("{}_ssbo{}[({}+4)/4]={}.y;", ctx.stage_name, binding.U32(), offset_var, value); |
| 112 | } | 117 | } |
| 113 | 118 | ||
| 114 | void EmitWriteStorage128([[maybe_unused]] EmitContext& ctx, | 119 | void EmitWriteStorage128([[maybe_unused]] EmitContext& ctx, |
| @@ -116,9 +121,9 @@ void EmitWriteStorage128([[maybe_unused]] EmitContext& ctx, | |||
| 116 | [[maybe_unused]] const IR::Value& offset, | 121 | [[maybe_unused]] const IR::Value& offset, |
| 117 | [[maybe_unused]] std::string_view value) { | 122 | [[maybe_unused]] std::string_view value) { |
| 118 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 123 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 119 | ctx.Add("ssbo{}[{}/4]={}.x;", binding.U32(), offset_var, value); | 124 | ctx.Add("{}_ssbo{}[{}/4]={}.x;", ctx.stage_name, binding.U32(), offset_var, value); |
| 120 | ctx.Add("ssbo{}[({}+4)/4]={}.y;", binding.U32(), offset_var, value); | 125 | ctx.Add("{}_ssbo{}[({}+4)/4]={}.y;", ctx.stage_name, binding.U32(), offset_var, value); |
| 121 | ctx.Add("ssbo{}[({}+8)/4]={}.z;", binding.U32(), offset_var, value); | 126 | ctx.Add("{}_ssbo{}[({}+8)/4]={}.z;", ctx.stage_name, binding.U32(), offset_var, value); |
| 122 | ctx.Add("ssbo{}[({}+12)/4]={}.w;", binding.U32(), offset_var, value); | 127 | ctx.Add("{}_ssbo{}[({}+12)/4]={}.w;", ctx.stage_name, binding.U32(), offset_var, value); |
| 123 | } | 128 | } |
| 124 | } // namespace Shader::Backend::GLSL | 129 | } // namespace Shader::Backend::GLSL |