diff options
Diffstat (limited to 'src/shader_recompiler/backend')
34 files changed, 141 insertions, 82 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp index 4cff70fe4..8603c6be2 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" |
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | 7 | #include "shader_recompiler/frontend/ir/modifiers.h" |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp index 356640471..e4b6b6f31 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" |
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | 7 | #include "shader_recompiler/frontend/ir/modifiers.h" |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp index f0fd94a28..44b363b50 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" |
| 9 | #include "shader_recompiler/frontend/ir/program.h" | 7 | #include "shader_recompiler/frontend/ir/program.h" |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp index 86287ee3f..affe35be7 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp | |||
| @@ -2,11 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" |
| 9 | #include "shader_recompiler/frontend/ir/program.h" | ||
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | 8 | ||
| 12 | #ifdef _MSC_VER | 9 | #ifdef _MSC_VER |
diff --git a/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp index 0401953f7..af88b7dfa 100644 --- a/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp +++ b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/bindings.h" | 5 | #include "shader_recompiler/backend/bindings.h" |
| 8 | #include "shader_recompiler/backend/glasm/emit_glasm.h" | 6 | #include "shader_recompiler/backend/glasm/emit_glasm.h" |
| 9 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | 7 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" |
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp index 201e428c1..4e98d3ea0 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp +++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp | |||
| @@ -2,11 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string> | ||
| 6 | |||
| 7 | #include <fmt/format.h> | 5 | #include <fmt/format.h> |
| 8 | 6 | ||
| 9 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 10 | #include "shader_recompiler/backend/glasm/reg_alloc.h" | 7 | #include "shader_recompiler/backend/glasm/reg_alloc.h" |
| 11 | #include "shader_recompiler/exception.h" | 8 | #include "shader_recompiler/exception.h" |
| 12 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_barriers.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_barriers.cpp index 8a9faa394..0f204495c 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_barriers.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_barriers.cpp | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" |
| 7 | #include "shader_recompiler/frontend/ir/value.h" | ||
| 8 | 7 | ||
| 9 | namespace Shader::Backend::GLSL { | 8 | namespace Shader::Backend::GLSL { |
| 10 | void EmitBarrier(EmitContext& ctx) { | 9 | void EmitBarrier(EmitContext& ctx) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index 0c1fbc7b1..282668b36 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp | |||
| @@ -35,6 +35,15 @@ std::string_view OutputVertexIndex(EmitContext& ctx) { | |||
| 35 | return ctx.stage == Stage::TessellationControl ? "[gl_InvocationID]" : ""; | 35 | return ctx.stage == Stage::TessellationControl ? "[gl_InvocationID]" : ""; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | std::string ChooseCbuf(EmitContext& ctx, const IR::Value& binding, std::string_view index) { | ||
| 39 | if (binding.IsImmediate()) { | ||
| 40 | return fmt::format("{}_cbuf{}[{}]", ctx.stage_name, binding.U32(), index); | ||
| 41 | } else { | ||
| 42 | const auto binding_var{ctx.var_alloc.Consume(binding)}; | ||
| 43 | return fmt::format("GetCbufIndirect({},{})", binding_var, index); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 38 | void GetCbuf(EmitContext& ctx, std::string_view ret, const IR::Value& binding, | 47 | void GetCbuf(EmitContext& ctx, std::string_view ret, const IR::Value& binding, |
| 39 | const IR::Value& offset, u32 num_bits, std::string_view cast = {}, | 48 | const IR::Value& offset, u32 num_bits, std::string_view cast = {}, |
| 40 | std::string_view bit_offset = {}) { | 49 | std::string_view bit_offset = {}) { |
| @@ -55,8 +64,8 @@ void GetCbuf(EmitContext& ctx, std::string_view ret, const IR::Value& binding, | |||
| 55 | const auto swizzle{is_immediate ? fmt::format(".{}", OffsetSwizzle(offset.U32())) | 64 | const auto swizzle{is_immediate ? fmt::format(".{}", OffsetSwizzle(offset.U32())) |
| 56 | : fmt::format("[({}>>2)%4]", offset_var)}; | 65 | : fmt::format("[({}>>2)%4]", offset_var)}; |
| 57 | 66 | ||
| 58 | const auto cbuf{fmt::format("{}_cbuf{}", ctx.stage_name, binding.U32())}; | 67 | const auto cbuf{ChooseCbuf(ctx, binding, index)}; |
| 59 | const auto cbuf_cast{fmt::format("{}({}[{}]{{}})", cast, cbuf, index)}; | 68 | const auto cbuf_cast{fmt::format("{}({}{{}})", cast, cbuf)}; |
| 60 | const auto extraction{num_bits == 32 ? cbuf_cast | 69 | const auto extraction{num_bits == 32 ? cbuf_cast |
| 61 | : fmt::format("bitfieldExtract({},int({}),{})", cbuf_cast, | 70 | : fmt::format("bitfieldExtract({},int({}),{})", cbuf_cast, |
| 62 | bit_offset, num_bits)}; | 71 | bit_offset, num_bits)}; |
| @@ -140,9 +149,9 @@ void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | |||
| 140 | 149 | ||
| 141 | void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 150 | void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 142 | const IR::Value& offset) { | 151 | const IR::Value& offset) { |
| 143 | const auto cbuf{fmt::format("{}_cbuf{}", ctx.stage_name, binding.U32())}; | ||
| 144 | const auto cast{ctx.profile.has_gl_cbuf_ftou_bug ? "" : "ftou"}; | 152 | const auto cast{ctx.profile.has_gl_cbuf_ftou_bug ? "" : "ftou"}; |
| 145 | if (offset.IsImmediate()) { | 153 | if (offset.IsImmediate()) { |
| 154 | const auto cbuf{fmt::format("{}_cbuf{}", ctx.stage_name, binding.U32())}; | ||
| 146 | static constexpr u32 cbuf_size{0x10000}; | 155 | static constexpr u32 cbuf_size{0x10000}; |
| 147 | const u32 u32_offset{offset.U32()}; | 156 | const u32 u32_offset{offset.U32()}; |
| 148 | const s32 signed_offset{static_cast<s32>(offset.U32())}; | 157 | const s32 signed_offset{static_cast<s32>(offset.U32())}; |
| @@ -162,17 +171,17 @@ void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding | |||
| 162 | return; | 171 | return; |
| 163 | } | 172 | } |
| 164 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 173 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 174 | const auto cbuf{ChooseCbuf(ctx, binding, fmt::format("{}>>4", offset_var))}; | ||
| 165 | if (!ctx.profile.has_gl_component_indexing_bug) { | 175 | if (!ctx.profile.has_gl_component_indexing_bug) { |
| 166 | ctx.AddU32x2("{}=uvec2({}({}[{}>>4][({}>>2)%4]),{}({}[({}+4)>>4][(({}+4)>>2)%4]));", inst, | 176 | ctx.AddU32x2("{}=uvec2({}({}[({}>>2)%4]),{}({}[(({}+4)>>2)%4]));", inst, cast, cbuf, |
| 167 | cast, cbuf, offset_var, offset_var, cast, cbuf, offset_var, offset_var); | 177 | offset_var, cast, cbuf, offset_var); |
| 168 | return; | 178 | return; |
| 169 | } | 179 | } |
| 170 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x2)}; | 180 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x2)}; |
| 171 | const auto cbuf_offset{fmt::format("{}>>2", offset_var)}; | 181 | const auto cbuf_offset{fmt::format("{}>>2", offset_var)}; |
| 172 | for (u32 swizzle = 0; swizzle < 4; ++swizzle) { | 182 | for (u32 swizzle = 0; swizzle < 4; ++swizzle) { |
| 173 | ctx.Add("if(({}&3)=={}){}=uvec2({}({}[{}>>4].{}),{}({}[({}+4)>>4].{}));", cbuf_offset, | 183 | ctx.Add("if(({}&3)=={}){}=uvec2({}({}.{}),{}({}.{}));", cbuf_offset, swizzle, ret, cast, |
| 174 | swizzle, ret, cast, cbuf, offset_var, "xyzw"[swizzle], cast, cbuf, offset_var, | 184 | cbuf, "xyzw"[swizzle], cast, cbuf, "xyzw"[(swizzle + 1) % 4]); |
| 175 | "xyzw"[(swizzle + 1) % 4]); | ||
| 176 | } | 185 | } |
| 177 | } | 186 | } |
| 178 | 187 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp index c86465e8b..6f61560f1 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" |
| 9 | #include "shader_recompiler/exception.h" | 7 | #include "shader_recompiler/exception.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp index b0d85be99..64322cdbf 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" |
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_logical.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_logical.cpp index 742fec9cf..162a8c461 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_logical.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_logical.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" |
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp index 74ae345e5..f8aa4ecd6 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" |
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp index fcf620b79..8b94ea90a 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" |
| 9 | #include "shader_recompiler/frontend/ir/program.h" | 7 | #include "shader_recompiler/frontend/ir/program.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp index cace1db85..9367524e8 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" |
| 9 | 7 | ||
diff --git a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp index e816a93ec..17266f40d 100644 --- a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp | |||
| @@ -359,6 +359,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 359 | header += "layout(location=0) uniform vec4 scaling;"; | 359 | header += "layout(location=0) uniform vec4 scaling;"; |
| 360 | } | 360 | } |
| 361 | DefineConstantBuffers(bindings); | 361 | DefineConstantBuffers(bindings); |
| 362 | DefineConstantBufferIndirect(); | ||
| 362 | DefineStorageBuffers(bindings); | 363 | DefineStorageBuffers(bindings); |
| 363 | SetupImages(bindings); | 364 | SetupImages(bindings); |
| 364 | SetupTextures(bindings); | 365 | SetupTextures(bindings); |
| @@ -436,6 +437,24 @@ void EmitContext::DefineConstantBuffers(Bindings& bindings) { | |||
| 436 | } | 437 | } |
| 437 | } | 438 | } |
| 438 | 439 | ||
| 440 | void EmitContext::DefineConstantBufferIndirect() { | ||
| 441 | if (!info.uses_cbuf_indirect) { | ||
| 442 | return; | ||
| 443 | } | ||
| 444 | |||
| 445 | header += profile.has_gl_cbuf_ftou_bug ? "uvec4 " : "vec4 "; | ||
| 446 | header += "GetCbufIndirect(uint binding, uint offset){" | ||
| 447 | "switch(binding){" | ||
| 448 | "default:"; | ||
| 449 | |||
| 450 | for (const auto& desc : info.constant_buffer_descriptors) { | ||
| 451 | header += | ||
| 452 | fmt::format("case {}:return {}_cbuf{}[offset];", desc.index, stage_name, desc.index); | ||
| 453 | } | ||
| 454 | |||
| 455 | header += "}}"; | ||
| 456 | } | ||
| 457 | |||
| 439 | void EmitContext::DefineStorageBuffers(Bindings& bindings) { | 458 | void EmitContext::DefineStorageBuffers(Bindings& bindings) { |
| 440 | if (info.storage_buffers_descriptors.empty()) { | 459 | if (info.storage_buffers_descriptors.empty()) { |
| 441 | return; | 460 | return; |
diff --git a/src/shader_recompiler/backend/glsl/glsl_emit_context.h b/src/shader_recompiler/backend/glsl/glsl_emit_context.h index d9b639d29..2b13db6e6 100644 --- a/src/shader_recompiler/backend/glsl/glsl_emit_context.h +++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.h | |||
| @@ -162,6 +162,7 @@ public: | |||
| 162 | private: | 162 | private: |
| 163 | void SetupExtensions(); | 163 | void SetupExtensions(); |
| 164 | void DefineConstantBuffers(Bindings& bindings); | 164 | void DefineConstantBuffers(Bindings& bindings); |
| 165 | void DefineConstantBufferIndirect(); | ||
| 165 | void DefineStorageBuffers(Bindings& bindings); | 166 | void DefineStorageBuffers(Bindings& bindings); |
| 166 | void DefineGenericOutput(size_t index, u32 invocations); | 167 | void DefineGenericOutput(size_t index, u32 invocations); |
| 167 | void DefineHelperFunctions(); | 168 | void DefineHelperFunctions(); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index b412957c7..2b360e073 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -22,7 +22,7 @@ constexpr u32 NUM_TEXTURE_AND_IMAGE_SCALING_WORDS = | |||
| 22 | struct RescalingLayout { | 22 | struct RescalingLayout { |
| 23 | alignas(16) std::array<u32, NUM_TEXTURE_SCALING_WORDS> rescaling_textures; | 23 | alignas(16) std::array<u32, NUM_TEXTURE_SCALING_WORDS> rescaling_textures; |
| 24 | alignas(16) std::array<u32, NUM_IMAGE_SCALING_WORDS> rescaling_images; | 24 | alignas(16) std::array<u32, NUM_IMAGE_SCALING_WORDS> rescaling_images; |
| 25 | alignas(16) u32 down_factor; | 25 | u32 down_factor; |
| 26 | }; | 26 | }; |
| 27 | constexpr u32 RESCALING_LAYOUT_WORDS_OFFSET = offsetof(RescalingLayout, rescaling_textures); | 27 | constexpr u32 RESCALING_LAYOUT_WORDS_OFFSET = offsetof(RescalingLayout, rescaling_textures); |
| 28 | constexpr u32 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET = offsetof(RescalingLayout, down_factor); | 28 | constexpr u32 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET = offsetof(RescalingLayout, down_factor); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp index d3cbb14a9..cb47d253c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <bit> | ||
| 6 | |||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 7 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 8 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 9 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp index 9ce95a41b..6ecaa3937 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp | |||
| @@ -2,10 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | #include "shader_recompiler/frontend/ir/modifiers.h" | ||
| 9 | 7 | ||
| 10 | namespace Shader::Backend::SPIRV { | 8 | namespace Shader::Backend::SPIRV { |
| 11 | namespace { | 9 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp index 02d1e63f7..831c6f158 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp index 5c3e1ee2b..812c3668d 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp | |||
| @@ -2,10 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | #include "shader_recompiler/frontend/ir/modifiers.h" | ||
| 9 | 7 | ||
| 10 | namespace Shader::Backend::SPIRV { | 8 | namespace Shader::Backend::SPIRV { |
| 11 | 9 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 8ea730c80..aa7082978 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -2,10 +2,10 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <bit> | ||
| 5 | #include <tuple> | 6 | #include <tuple> |
| 6 | #include <utility> | 7 | #include <utility> |
| 7 | 8 | ||
| 8 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 9 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 9 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 10 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 10 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 11 | 11 | ||
| @@ -123,34 +123,36 @@ std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | |||
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr, u32 element_size, | 125 | Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr, u32 element_size, |
| 126 | const IR::Value& binding, const IR::Value& offset) { | 126 | const IR::Value& binding, const IR::Value& offset, const Id indirect_func) { |
| 127 | Id buffer_offset; | ||
| 128 | const Id uniform_type{ctx.uniform_types.*member_ptr}; | ||
| 129 | if (offset.IsImmediate()) { | ||
| 130 | // Hardware been proved to read the aligned offset (e.g. LDC.U32 at 6 will read offset 4) | ||
| 131 | const Id imm_offset{ctx.Const(offset.U32() / element_size)}; | ||
| 132 | buffer_offset = imm_offset; | ||
| 133 | } else if (element_size > 1) { | ||
| 134 | const u32 log2_element_size{static_cast<u32>(std::countr_zero(element_size))}; | ||
| 135 | const Id shift{ctx.Const(log2_element_size)}; | ||
| 136 | buffer_offset = ctx.OpShiftRightArithmetic(ctx.U32[1], ctx.Def(offset), shift); | ||
| 137 | } else { | ||
| 138 | buffer_offset = ctx.Def(offset); | ||
| 139 | } | ||
| 127 | if (!binding.IsImmediate()) { | 140 | if (!binding.IsImmediate()) { |
| 128 | throw NotImplementedException("Constant buffer indexing"); | 141 | return ctx.OpFunctionCall(result_type, indirect_func, ctx.Def(binding), buffer_offset); |
| 129 | } | 142 | } |
| 130 | const Id cbuf{ctx.cbufs[binding.U32()].*member_ptr}; | 143 | const Id cbuf{ctx.cbufs[binding.U32()].*member_ptr}; |
| 131 | const Id uniform_type{ctx.uniform_types.*member_ptr}; | 144 | const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, buffer_offset)}; |
| 132 | if (!offset.IsImmediate()) { | ||
| 133 | Id index{ctx.Def(offset)}; | ||
| 134 | if (element_size > 1) { | ||
| 135 | const u32 log2_element_size{static_cast<u32>(std::countr_zero(element_size))}; | ||
| 136 | const Id shift{ctx.Const(log2_element_size)}; | ||
| 137 | index = ctx.OpShiftRightArithmetic(ctx.U32[1], ctx.Def(offset), shift); | ||
| 138 | } | ||
| 139 | const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, index)}; | ||
| 140 | return ctx.OpLoad(result_type, access_chain); | ||
| 141 | } | ||
| 142 | // Hardware been proved to read the aligned offset (e.g. LDC.U32 at 6 will read offset 4) | ||
| 143 | const Id imm_offset{ctx.Const(offset.U32() / element_size)}; | ||
| 144 | const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, imm_offset)}; | ||
| 145 | return ctx.OpLoad(result_type, access_chain); | 145 | return ctx.OpLoad(result_type, access_chain); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | Id GetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 148 | Id GetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 149 | return GetCbuf(ctx, ctx.U32[1], &UniformDefinitions::U32, sizeof(u32), binding, offset); | 149 | return GetCbuf(ctx, ctx.U32[1], &UniformDefinitions::U32, sizeof(u32), binding, offset, |
| 150 | ctx.load_const_func_u32); | ||
| 150 | } | 151 | } |
| 151 | 152 | ||
| 152 | Id GetCbufU32x4(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 153 | Id GetCbufU32x4(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 153 | return GetCbuf(ctx, ctx.U32[4], &UniformDefinitions::U32x4, sizeof(u32[4]), binding, offset); | 154 | return GetCbuf(ctx, ctx.U32[4], &UniformDefinitions::U32x4, sizeof(u32[4]), binding, offset, |
| 155 | ctx.load_const_func_u32x4); | ||
| 154 | } | 156 | } |
| 155 | 157 | ||
| 156 | Id GetCbufElement(EmitContext& ctx, Id vector, const IR::Value& offset, u32 index_offset) { | 158 | Id GetCbufElement(EmitContext& ctx, Id vector, const IR::Value& offset, u32 index_offset) { |
| @@ -201,7 +203,8 @@ void EmitGetIndirectBranchVariable(EmitContext&) { | |||
| 201 | 203 | ||
| 202 | Id EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 204 | Id EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 203 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8) { | 205 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8) { |
| 204 | const Id load{GetCbuf(ctx, ctx.U8, &UniformDefinitions::U8, sizeof(u8), binding, offset)}; | 206 | const Id load{GetCbuf(ctx, ctx.U8, &UniformDefinitions::U8, sizeof(u8), binding, offset, |
| 207 | ctx.load_const_func_u8)}; | ||
| 205 | return ctx.OpUConvert(ctx.U32[1], load); | 208 | return ctx.OpUConvert(ctx.U32[1], load); |
| 206 | } | 209 | } |
| 207 | Id element{}; | 210 | Id element{}; |
| @@ -217,7 +220,8 @@ Id EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& of | |||
| 217 | 220 | ||
| 218 | Id EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 221 | Id EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 219 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8) { | 222 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8) { |
| 220 | const Id load{GetCbuf(ctx, ctx.S8, &UniformDefinitions::S8, sizeof(s8), binding, offset)}; | 223 | const Id load{GetCbuf(ctx, ctx.S8, &UniformDefinitions::S8, sizeof(s8), binding, offset, |
| 224 | ctx.load_const_func_u8)}; | ||
| 221 | return ctx.OpSConvert(ctx.U32[1], load); | 225 | return ctx.OpSConvert(ctx.U32[1], load); |
| 222 | } | 226 | } |
| 223 | Id element{}; | 227 | Id element{}; |
| @@ -233,8 +237,8 @@ Id EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& of | |||
| 233 | 237 | ||
| 234 | Id EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 238 | Id EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 235 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16) { | 239 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16) { |
| 236 | const Id load{ | 240 | const Id load{GetCbuf(ctx, ctx.U16, &UniformDefinitions::U16, sizeof(u16), binding, offset, |
| 237 | GetCbuf(ctx, ctx.U16, &UniformDefinitions::U16, sizeof(u16), binding, offset)}; | 241 | ctx.load_const_func_u16)}; |
| 238 | return ctx.OpUConvert(ctx.U32[1], load); | 242 | return ctx.OpUConvert(ctx.U32[1], load); |
| 239 | } | 243 | } |
| 240 | Id element{}; | 244 | Id element{}; |
| @@ -250,8 +254,8 @@ Id EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& o | |||
| 250 | 254 | ||
| 251 | Id EmitGetCbufS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 255 | Id EmitGetCbufS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 252 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16) { | 256 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16) { |
| 253 | const Id load{ | 257 | const Id load{GetCbuf(ctx, ctx.S16, &UniformDefinitions::S16, sizeof(s16), binding, offset, |
| 254 | GetCbuf(ctx, ctx.S16, &UniformDefinitions::S16, sizeof(s16), binding, offset)}; | 258 | ctx.load_const_func_u16)}; |
| 255 | return ctx.OpSConvert(ctx.U32[1], load); | 259 | return ctx.OpSConvert(ctx.U32[1], load); |
| 256 | } | 260 | } |
| 257 | Id element{}; | 261 | Id element{}; |
| @@ -276,7 +280,8 @@ Id EmitGetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& o | |||
| 276 | 280 | ||
| 277 | Id EmitGetCbufF32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 281 | Id EmitGetCbufF32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 278 | if (ctx.profile.support_descriptor_aliasing) { | 282 | if (ctx.profile.support_descriptor_aliasing) { |
| 279 | return GetCbuf(ctx, ctx.F32[1], &UniformDefinitions::F32, sizeof(f32), binding, offset); | 283 | return GetCbuf(ctx, ctx.F32[1], &UniformDefinitions::F32, sizeof(f32), binding, offset, |
| 284 | ctx.load_const_func_f32); | ||
| 280 | } else { | 285 | } else { |
| 281 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; | 286 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; |
| 282 | return ctx.OpBitcast(ctx.F32[1], GetCbufElement(ctx, vector, offset, 0u)); | 287 | return ctx.OpBitcast(ctx.F32[1], GetCbufElement(ctx, vector, offset, 0u)); |
| @@ -285,8 +290,8 @@ Id EmitGetCbufF32(EmitContext& ctx, const IR::Value& binding, const IR::Value& o | |||
| 285 | 290 | ||
| 286 | Id EmitGetCbufU32x2(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 291 | Id EmitGetCbufU32x2(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 287 | if (ctx.profile.support_descriptor_aliasing) { | 292 | if (ctx.profile.support_descriptor_aliasing) { |
| 288 | return GetCbuf(ctx, ctx.U32[2], &UniformDefinitions::U32x2, sizeof(u32[2]), binding, | 293 | return GetCbuf(ctx, ctx.U32[2], &UniformDefinitions::U32x2, sizeof(u32[2]), binding, offset, |
| 289 | offset); | 294 | ctx.load_const_func_u32x2); |
| 290 | } else { | 295 | } else { |
| 291 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; | 296 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; |
| 292 | return ctx.OpCompositeConstruct(ctx.U32[2], GetCbufElement(ctx, vector, offset, 0u), | 297 | return ctx.OpCompositeConstruct(ctx.U32[2], GetCbufElement(ctx, vector, offset, 0u), |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp index 1eca3aa85..d1afd47b8 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index 832de2452..137a0e257 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp index 0cdc46495..9f65fa269 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | #include "shader_recompiler/frontend/ir/modifiers.h" | 7 | #include "shader_recompiler/frontend/ir/modifiers.h" |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp index a96190bc6..727ac2027 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | #include "shader_recompiler/frontend/ir/modifiers.h" | 7 | #include "shader_recompiler/frontend/ir/modifiers.h" |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp index 44521f539..45a384e46 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp index 47745f7ee..74b6efe01 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp index 48caf1ffc..ce55cd31c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp index 330c9052c..b57c66828 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp index b5766fc52..00c6e86e2 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp index 7034228bf..905c735ad 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | ||
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | 6 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" |
| 8 | 7 | ||
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index cd90c084a..9c83cd2e4 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <bit> | ||
| 7 | #include <climits> | 8 | #include <climits> |
| 8 | #include <string_view> | ||
| 9 | 9 | ||
| 10 | #include <boost/container/static_vector.hpp> | 10 | #include <boost/container/static_vector.hpp> |
| 11 | 11 | ||
| @@ -464,6 +464,7 @@ EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_inf | |||
| 464 | DefineSharedMemory(program); | 464 | DefineSharedMemory(program); |
| 465 | DefineSharedMemoryFunctions(program); | 465 | DefineSharedMemoryFunctions(program); |
| 466 | DefineConstantBuffers(program.info, uniform_binding); | 466 | DefineConstantBuffers(program.info, uniform_binding); |
| 467 | DefineConstantBufferIndirectFunctions(program.info); | ||
| 467 | DefineStorageBuffers(program.info, storage_binding); | 468 | DefineStorageBuffers(program.info, storage_binding); |
| 468 | DefineTextureBuffers(program.info, texture_binding); | 469 | DefineTextureBuffers(program.info, texture_binding); |
| 469 | DefineImageBuffers(program.info, image_binding); | 470 | DefineImageBuffers(program.info, image_binding); |
| @@ -993,7 +994,7 @@ void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) { | |||
| 993 | } | 994 | } |
| 994 | return; | 995 | return; |
| 995 | } | 996 | } |
| 996 | IR::Type types{info.used_constant_buffer_types}; | 997 | IR::Type types{info.used_constant_buffer_types | info.used_indirect_cbuf_types}; |
| 997 | if (True(types & IR::Type::U8)) { | 998 | if (True(types & IR::Type::U8)) { |
| 998 | if (profile.support_int8) { | 999 | if (profile.support_int8) { |
| 999 | DefineConstBuffers(*this, info, &UniformDefinitions::U8, binding, U8, 'u', sizeof(u8)); | 1000 | DefineConstBuffers(*this, info, &UniformDefinitions::U8, binding, U8, 'u', sizeof(u8)); |
| @@ -1027,6 +1028,63 @@ void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) { | |||
| 1027 | binding += static_cast<u32>(info.constant_buffer_descriptors.size()); | 1028 | binding += static_cast<u32>(info.constant_buffer_descriptors.size()); |
| 1028 | } | 1029 | } |
| 1029 | 1030 | ||
| 1031 | void EmitContext::DefineConstantBufferIndirectFunctions(const Info& info) { | ||
| 1032 | if (!info.uses_cbuf_indirect) { | ||
| 1033 | return; | ||
| 1034 | } | ||
| 1035 | const auto make_accessor{[&](Id buffer_type, Id UniformDefinitions::*member_ptr) { | ||
| 1036 | const Id func_type{TypeFunction(buffer_type, U32[1], U32[1])}; | ||
| 1037 | const Id func{OpFunction(buffer_type, spv::FunctionControlMask::MaskNone, func_type)}; | ||
| 1038 | const Id binding{OpFunctionParameter(U32[1])}; | ||
| 1039 | const Id offset{OpFunctionParameter(U32[1])}; | ||
| 1040 | |||
| 1041 | AddLabel(); | ||
| 1042 | |||
| 1043 | const Id merge_label{OpLabel()}; | ||
| 1044 | const Id uniform_type{uniform_types.*member_ptr}; | ||
| 1045 | |||
| 1046 | std::array<Id, Info::MAX_INDIRECT_CBUFS> buf_labels; | ||
| 1047 | std::array<Sirit::Literal, Info::MAX_INDIRECT_CBUFS> buf_literals; | ||
| 1048 | for (u32 i = 0; i < Info::MAX_INDIRECT_CBUFS; i++) { | ||
| 1049 | buf_labels[i] = OpLabel(); | ||
| 1050 | buf_literals[i] = Sirit::Literal{i}; | ||
| 1051 | } | ||
| 1052 | OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone); | ||
| 1053 | OpSwitch(binding, buf_labels[0], buf_literals, buf_labels); | ||
| 1054 | for (u32 i = 0; i < Info::MAX_INDIRECT_CBUFS; i++) { | ||
| 1055 | AddLabel(buf_labels[i]); | ||
| 1056 | const Id cbuf{cbufs[i].*member_ptr}; | ||
| 1057 | const Id access_chain{OpAccessChain(uniform_type, cbuf, u32_zero_value, offset)}; | ||
| 1058 | const Id result{OpLoad(buffer_type, access_chain)}; | ||
| 1059 | OpReturnValue(result); | ||
| 1060 | } | ||
| 1061 | AddLabel(merge_label); | ||
| 1062 | OpUnreachable(); | ||
| 1063 | OpFunctionEnd(); | ||
| 1064 | return func; | ||
| 1065 | }}; | ||
| 1066 | IR::Type types{info.used_indirect_cbuf_types}; | ||
| 1067 | bool supports_aliasing = profile.support_descriptor_aliasing; | ||
| 1068 | if (supports_aliasing && True(types & IR::Type::U8)) { | ||
| 1069 | load_const_func_u8 = make_accessor(U8, &UniformDefinitions::U8); | ||
| 1070 | } | ||
| 1071 | if (supports_aliasing && True(types & IR::Type::U16)) { | ||
| 1072 | load_const_func_u16 = make_accessor(U16, &UniformDefinitions::U16); | ||
| 1073 | } | ||
| 1074 | if (supports_aliasing && True(types & IR::Type::F32)) { | ||
| 1075 | load_const_func_f32 = make_accessor(F32[1], &UniformDefinitions::F32); | ||
| 1076 | } | ||
| 1077 | if (supports_aliasing && True(types & IR::Type::U32)) { | ||
| 1078 | load_const_func_u32 = make_accessor(U32[1], &UniformDefinitions::U32); | ||
| 1079 | } | ||
| 1080 | if (supports_aliasing && True(types & IR::Type::U32x2)) { | ||
| 1081 | load_const_func_u32x2 = make_accessor(U32[2], &UniformDefinitions::U32x2); | ||
| 1082 | } | ||
| 1083 | if (!supports_aliasing || True(types & IR::Type::U32x4)) { | ||
| 1084 | load_const_func_u32x4 = make_accessor(U32[4], &UniformDefinitions::U32x4); | ||
| 1085 | } | ||
| 1086 | } | ||
| 1087 | |||
| 1030 | void EmitContext::DefineStorageBuffers(const Info& info, u32& binding) { | 1088 | void EmitContext::DefineStorageBuffers(const Info& info, u32& binding) { |
| 1031 | if (info.storage_buffers_descriptors.empty()) { | 1089 | if (info.storage_buffers_descriptors.empty()) { |
| 1032 | return; | 1090 | return; |
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index f87138f7e..b9115a405 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <string_view> | ||
| 9 | 8 | ||
| 10 | #include <sirit/sirit.h> | 9 | #include <sirit/sirit.h> |
| 11 | 10 | ||
| @@ -294,6 +293,13 @@ public: | |||
| 294 | 293 | ||
| 295 | std::vector<Id> interfaces; | 294 | std::vector<Id> interfaces; |
| 296 | 295 | ||
| 296 | Id load_const_func_u8{}; | ||
| 297 | Id load_const_func_u16{}; | ||
| 298 | Id load_const_func_u32{}; | ||
| 299 | Id load_const_func_f32{}; | ||
| 300 | Id load_const_func_u32x2{}; | ||
| 301 | Id load_const_func_u32x4{}; | ||
| 302 | |||
| 297 | private: | 303 | private: |
| 298 | void DefineCommonTypes(const Info& info); | 304 | void DefineCommonTypes(const Info& info); |
| 299 | void DefineCommonConstants(); | 305 | void DefineCommonConstants(); |
| @@ -302,6 +308,7 @@ private: | |||
| 302 | void DefineSharedMemory(const IR::Program& program); | 308 | void DefineSharedMemory(const IR::Program& program); |
| 303 | void DefineSharedMemoryFunctions(const IR::Program& program); | 309 | void DefineSharedMemoryFunctions(const IR::Program& program); |
| 304 | void DefineConstantBuffers(const Info& info, u32& binding); | 310 | void DefineConstantBuffers(const Info& info, u32& binding); |
| 311 | void DefineConstantBufferIndirectFunctions(const Info& info); | ||
| 305 | void DefineStorageBuffers(const Info& info, u32& binding); | 312 | void DefineStorageBuffers(const Info& info, u32& binding); |
| 306 | void DefineTextureBuffers(const Info& info, u32& binding); | 313 | void DefineTextureBuffers(const Info& info, u32& binding); |
| 307 | void DefineImageBuffers(const Info& info, u32& binding); | 314 | void DefineImageBuffers(const Info& info, u32& binding); |