diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
9 files changed, 139 insertions, 75 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 8e5983909..de19e0fba 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -8,9 +8,21 @@ | |||
| 8 | #include "shader_recompiler/profile.h" | 8 | #include "shader_recompiler/profile.h" |
| 9 | 9 | ||
| 10 | namespace Shader::Backend::GLSL { | 10 | namespace Shader::Backend::GLSL { |
| 11 | namespace { | ||
| 12 | std::string_view InterpDecorator(Interpolation interp) { | ||
| 13 | switch (interp) { | ||
| 14 | case Interpolation::Smooth: | ||
| 15 | return ""; | ||
| 16 | case Interpolation::Flat: | ||
| 17 | return "flat"; | ||
| 18 | case Interpolation::NoPerspective: | ||
| 19 | return "noperspective"; | ||
| 20 | } | ||
| 21 | throw InvalidArgument("Invalid interpolation {}", interp); | ||
| 22 | } | ||
| 23 | } // namespace | ||
| 11 | 24 | ||
| 12 | EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindings, | 25 | EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_) |
| 13 | const Profile& profile_) | ||
| 14 | : info{program.info}, profile{profile_} { | 26 | : info{program.info}, profile{profile_} { |
| 15 | std::string header = "#version 450\n"; | 27 | std::string header = "#version 450\n"; |
| 16 | SetupExtensions(header); | 28 | SetupExtensions(header); |
| @@ -49,7 +61,8 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin | |||
| 49 | for (size_t index = 0; index < info.input_generics.size(); ++index) { | 61 | for (size_t index = 0; index < info.input_generics.size(); ++index) { |
| 50 | const auto& generic{info.input_generics[index]}; | 62 | const auto& generic{info.input_generics[index]}; |
| 51 | if (generic.used) { | 63 | if (generic.used) { |
| 52 | Add("layout(location={})in vec4 in_attr{};", index, index); | 64 | Add("layout(location={}) {} in vec4 in_attr{};", index, |
| 65 | InterpDecorator(generic.interpolation), index); | ||
| 53 | } | 66 | } |
| 54 | } | 67 | } |
| 55 | for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { | 68 | for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { |
| @@ -66,6 +79,7 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin | |||
| 66 | DefineConstantBuffers(); | 79 | DefineConstantBuffers(); |
| 67 | DefineStorageBuffers(); | 80 | DefineStorageBuffers(); |
| 68 | DefineHelperFunctions(); | 81 | DefineHelperFunctions(); |
| 82 | SetupImages(bindings); | ||
| 69 | Add("void main(){{"); | 83 | Add("void main(){{"); |
| 70 | 84 | ||
| 71 | if (stage == Stage::VertexA || stage == Stage::VertexB) { | 85 | if (stage == Stage::VertexA || stage == Stage::VertexB) { |
| @@ -102,7 +116,7 @@ void EmitContext::DefineConstantBuffers() { | |||
| 102 | } | 116 | } |
| 103 | u32 binding{}; | 117 | u32 binding{}; |
| 104 | for (const auto& desc : info.constant_buffer_descriptors) { | 118 | for (const auto& desc : info.constant_buffer_descriptors) { |
| 105 | Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, binding, | 119 | Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, desc.index, |
| 106 | desc.index, 4 * 1024); | 120 | desc.index, 4 * 1024); |
| 107 | ++binding; | 121 | ++binding; |
| 108 | } | 122 | } |
| @@ -164,4 +178,36 @@ void EmitContext::DefineHelperFunctions() { | |||
| 164 | } | 178 | } |
| 165 | } | 179 | } |
| 166 | 180 | ||
| 181 | void EmitContext::SetupImages(Bindings& bindings) { | ||
| 182 | image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); | ||
| 183 | for (const auto& desc : info.image_buffer_descriptors) { | ||
| 184 | throw NotImplementedException("image_buffer_descriptors"); | ||
| 185 | image_buffer_bindings.push_back(bindings.image); | ||
| 186 | bindings.image += desc.count; | ||
| 187 | } | ||
| 188 | image_bindings.reserve(info.image_descriptors.size()); | ||
| 189 | for (const auto& desc : info.image_descriptors) { | ||
| 190 | throw NotImplementedException("image_bindings"); | ||
| 191 | |||
| 192 | image_bindings.push_back(bindings.image); | ||
| 193 | bindings.image += desc.count; | ||
| 194 | } | ||
| 195 | texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); | ||
| 196 | for (const auto& desc : info.texture_buffer_descriptors) { | ||
| 197 | throw NotImplementedException("TextureType::Buffer"); | ||
| 198 | |||
| 199 | texture_buffer_bindings.push_back(bindings.texture); | ||
| 200 | bindings.texture += desc.count; | ||
| 201 | } | ||
| 202 | texture_bindings.reserve(info.texture_descriptors.size()); | ||
| 203 | for (const auto& desc : info.texture_descriptors) { | ||
| 204 | texture_bindings.push_back(bindings.texture); | ||
| 205 | const auto indices{bindings.texture + desc.count}; | ||
| 206 | for (u32 index = bindings.texture; index < indices; ++index) { | ||
| 207 | Add("layout(binding={}) uniform sampler2D tex{};", bindings.texture, index); | ||
| 208 | } | ||
| 209 | bindings.texture += desc.count; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 167 | } // namespace Shader::Backend::GLSL | 213 | } // namespace Shader::Backend::GLSL |
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h index 087eaff6a..1cd051b24 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.h +++ b/src/shader_recompiler/backend/glsl/emit_context.h | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <utility> | 8 | #include <utility> |
| 9 | #include <vector> | ||
| 10 | |||
| 9 | #include <fmt/format.h> | 11 | #include <fmt/format.h> |
| 10 | 12 | ||
| 11 | #include "shader_recompiler/backend/glsl/reg_alloc.h" | 13 | #include "shader_recompiler/backend/glsl/reg_alloc.h" |
| @@ -109,11 +111,17 @@ public: | |||
| 109 | std::string_view stage_name = "invalid"; | 111 | std::string_view stage_name = "invalid"; |
| 110 | std::string_view attrib_name = "invalid"; | 112 | std::string_view attrib_name = "invalid"; |
| 111 | 113 | ||
| 114 | std::vector<u32> texture_buffer_bindings; | ||
| 115 | std::vector<u32> image_buffer_bindings; | ||
| 116 | std::vector<u32> texture_bindings; | ||
| 117 | std::vector<u32> image_bindings; | ||
| 118 | |||
| 112 | private: | 119 | private: |
| 113 | void SetupExtensions(std::string& header); | 120 | void SetupExtensions(std::string& header); |
| 114 | void DefineConstantBuffers(); | 121 | void DefineConstantBuffers(); |
| 115 | void DefineStorageBuffers(); | 122 | void DefineStorageBuffers(); |
| 116 | void DefineHelperFunctions(); | 123 | void DefineHelperFunctions(); |
| 124 | void SetupImages(Bindings& bindings); | ||
| 117 | }; | 125 | }; |
| 118 | 126 | ||
| 119 | } // namespace Shader::Backend::GLSL | 127 | } // namespace Shader::Backend::GLSL |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp index a8e53cf66..35dbe19ec 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp | |||
| @@ -113,7 +113,7 @@ void PrecolorInst(IR::Inst& phi) { | |||
| 113 | if (arg.IsImmediate()) { | 113 | if (arg.IsImmediate()) { |
| 114 | ir.PhiMove(phi, arg); | 114 | ir.PhiMove(phi, arg); |
| 115 | } else { | 115 | } else { |
| 116 | ir.PhiMove(phi, IR::Value{&RegAlloc::AliasInst(*arg.Inst())}); | 116 | ir.PhiMove(phi, IR::Value{&*arg.InstRecursive()}); |
| 117 | } | 117 | } |
| 118 | } | 118 | } |
| 119 | for (size_t i = 0; i < num_args; ++i) { | 119 | for (size_t i = 0; i < num_args; ++i) { |
| @@ -157,7 +157,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { | |||
| 157 | break; | 157 | break; |
| 158 | case IR::AbstractSyntaxNode::Type::Return: | 158 | case IR::AbstractSyntaxNode::Type::Return: |
| 159 | case IR::AbstractSyntaxNode::Type::Unreachable: | 159 | case IR::AbstractSyntaxNode::Type::Unreachable: |
| 160 | ctx.Add("return;\n}}"); | 160 | ctx.Add("return;"); |
| 161 | break; | 161 | break; |
| 162 | case IR::AbstractSyntaxNode::Type::Loop: | 162 | case IR::AbstractSyntaxNode::Type::Loop: |
| 163 | case IR::AbstractSyntaxNode::Type::Repeat: | 163 | case IR::AbstractSyntaxNode::Type::Repeat: |
| @@ -175,6 +175,8 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo&, IR::Program& pr | |||
| 175 | EmitContext ctx{program, bindings, profile}; | 175 | EmitContext ctx{program, bindings, profile}; |
| 176 | Precolor(program); | 176 | Precolor(program); |
| 177 | EmitCode(ctx, program); | 177 | EmitCode(ctx, program); |
| 178 | ctx.code += "}"; | ||
| 179 | fmt::print("\n{}\n", ctx.code); | ||
| 178 | return ctx.code; | 180 | return ctx.code; |
| 179 | } | 181 | } |
| 180 | 182 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp index 742f394d4..8512147e2 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp | |||
| @@ -15,7 +15,7 @@ static void Alias(IR::Inst& inst, const IR::Value& value) { | |||
| 15 | if (value.IsImmediate()) { | 15 | if (value.IsImmediate()) { |
| 16 | return; | 16 | return; |
| 17 | } | 17 | } |
| 18 | IR::Inst& value_inst{RegAlloc::AliasInst(*value.Inst())}; | 18 | IR::Inst& value_inst{*value.InstRecursive()}; |
| 19 | value_inst.DestructiveAddUsage(inst.UseCount()); | 19 | value_inst.DestructiveAddUsage(inst.UseCount()); |
| 20 | value_inst.DestructiveRemoveUsage(); | 20 | value_inst.DestructiveRemoveUsage(); |
| 21 | inst.SetDefinition(value_inst.Definition<Id>()); | 21 | inst.SetDefinition(value_inst.Definition<Id>()); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 109938e0e..cc5afc048 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -6,17 +6,39 @@ | |||
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | 7 | #include "shader_recompiler/backend/glsl/emit_context.h" |
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | #include "shader_recompiler/profile.h" | 11 | #include "shader_recompiler/profile.h" |
| 11 | 12 | ||
| 12 | namespace Shader::Backend::GLSL { | 13 | namespace Shader::Backend::GLSL { |
| 14 | namespace { | ||
| 15 | std::string Texture(EmitContext& ctx, IR::TextureInstInfo info, | ||
| 16 | [[maybe_unused]] const IR::Value& index) { | ||
| 17 | if (info.type == TextureType::Buffer) { | ||
| 18 | throw NotImplementedException("TextureType::Buffer"); | ||
| 19 | } else { | ||
| 20 | return fmt::format("tex{}", ctx.texture_bindings.at(info.descriptor_index)); | ||
| 21 | } | ||
| 22 | } | ||
| 23 | } // namespace | ||
| 13 | 24 | ||
| 14 | void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 25 | void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 15 | [[maybe_unused]] const IR::Value& index, | 26 | [[maybe_unused]] const IR::Value& index, |
| 16 | [[maybe_unused]] std::string_view coords, | 27 | [[maybe_unused]] std::string_view coords, |
| 17 | [[maybe_unused]] std::string_view bias_lc, | 28 | [[maybe_unused]] std::string_view bias_lc, |
| 18 | [[maybe_unused]] const IR::Value& offset) { | 29 | [[maybe_unused]] const IR::Value& offset) { |
| 19 | throw NotImplementedException("GLSL Instruction"); | 30 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 31 | if (info.has_bias) { | ||
| 32 | throw NotImplementedException("Bias texture samples"); | ||
| 33 | } | ||
| 34 | if (info.has_lod_clamp) { | ||
| 35 | throw NotImplementedException("Lod clamp samples"); | ||
| 36 | } | ||
| 37 | if (!offset.IsEmpty()) { | ||
| 38 | throw NotImplementedException("Offset"); | ||
| 39 | } | ||
| 40 | const auto texture{Texture(ctx, info, index)}; | ||
| 41 | ctx.AddF32x4("{}=texture({},{});", inst, texture, coords); | ||
| 20 | } | 42 | } |
| 21 | 43 | ||
| 22 | void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 44 | void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index 49ab108bb..c9b53bae2 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h | |||
| @@ -89,11 +89,11 @@ void EmitIsHelperInvocation(EmitContext& ctx); | |||
| 89 | void EmitYDirection(EmitContext& ctx); | 89 | void EmitYDirection(EmitContext& ctx); |
| 90 | void EmitLoadLocal(EmitContext& ctx, std::string_view word_offset); | 90 | void EmitLoadLocal(EmitContext& ctx, std::string_view word_offset); |
| 91 | void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_view value); | 91 | void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_view value); |
| 92 | void EmitUndefU1(EmitContext& ctx); | 92 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst); |
| 93 | void EmitUndefU8(EmitContext& ctx); | 93 | void EmitUndefU8(EmitContext& ctx, IR::Inst& inst); |
| 94 | void EmitUndefU16(EmitContext& ctx); | 94 | void EmitUndefU16(EmitContext& ctx, IR::Inst& inst); |
| 95 | void EmitUndefU32(EmitContext& ctx); | 95 | void EmitUndefU32(EmitContext& ctx, IR::Inst& inst); |
| 96 | void EmitUndefU64(EmitContext& ctx); | 96 | void EmitUndefU64(EmitContext& ctx, IR::Inst& inst); |
| 97 | void EmitLoadGlobalU8(EmitContext& ctx); | 97 | void EmitLoadGlobalU8(EmitContext& ctx); |
| 98 | void EmitLoadGlobalS8(EmitContext& ctx); | 98 | void EmitLoadGlobalS8(EmitContext& ctx); |
| 99 | void EmitLoadGlobalU16(EmitContext& ctx); | 99 | void EmitLoadGlobalU16(EmitContext& ctx); |
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 14a2edd74..42b1e8764 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp | |||
| @@ -39,17 +39,26 @@ void EmitReference(EmitContext&) { | |||
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | 41 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { |
| 42 | IR::Inst& phi{RegAlloc::AliasInst(*phi_value.Inst())}; | 42 | IR::Inst& phi{*phi_value.InstRecursive()}; |
| 43 | const auto phi_type{phi.Arg(0).Type()}; | ||
| 43 | if (!phi.Definition<Id>().is_valid) { | 44 | if (!phi.Definition<Id>().is_valid) { |
| 44 | // The phi node wasn't forward defined | 45 | // The phi node wasn't forward defined |
| 45 | ctx.Add("{};", ctx.reg_alloc.Define(phi, phi.Arg(0).Type())); | 46 | ctx.Add("{};", ctx.reg_alloc.Define(phi, phi_type)); |
| 46 | } | 47 | } |
| 47 | const auto phi_reg{ctx.reg_alloc.Consume(IR::Value{&phi})}; | 48 | const auto phi_reg{ctx.reg_alloc.Consume(IR::Value{&phi})}; |
| 48 | const auto val_reg{ctx.reg_alloc.Consume(value)}; | 49 | const auto val_reg{ctx.reg_alloc.Consume(value)}; |
| 49 | if (phi_reg == val_reg) { | 50 | if (phi_reg == val_reg) { |
| 50 | return; | 51 | return; |
| 51 | } | 52 | } |
| 52 | ctx.Add("{}={};", phi_reg, val_reg); | 53 | if (phi_type == value.Type()) { |
| 54 | ctx.Add("{}={}; // PHI MOVE", phi_reg, val_reg); | ||
| 55 | } else if (phi_type == IR::Type::U32 && value.Type() == IR::Type::F32) { | ||
| 56 | ctx.Add("{}=floatBitsToUint({}); // CAST PHI MOVE", phi_reg, val_reg); | ||
| 57 | } else { | ||
| 58 | throw NotImplementedException("{} to {} move", phi_type, value.Type()); | ||
| 59 | const auto cast{ctx.reg_alloc.GetGlslType(phi_type)}; | ||
| 60 | ctx.Add("{}={}({}); // CAST PHI MOVE", phi_reg, cast, val_reg); | ||
| 61 | } | ||
| 53 | } | 62 | } |
| 54 | 63 | ||
| 55 | void EmitBranch(EmitContext& ctx, std::string_view label) { | 64 | void EmitBranch(EmitContext& ctx, std::string_view label) { |
| @@ -235,23 +244,23 @@ void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_ | |||
| 235 | NotImplemented(); | 244 | NotImplemented(); |
| 236 | } | 245 | } |
| 237 | 246 | ||
| 238 | void EmitUndefU1(EmitContext& ctx) { | 247 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { |
| 239 | NotImplemented(); | 248 | NotImplemented(); |
| 240 | } | 249 | } |
| 241 | 250 | ||
| 242 | void EmitUndefU8(EmitContext& ctx) { | 251 | void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) { |
| 243 | NotImplemented(); | 252 | NotImplemented(); |
| 244 | } | 253 | } |
| 245 | 254 | ||
| 246 | void EmitUndefU16(EmitContext& ctx) { | 255 | void EmitUndefU16(EmitContext& ctx, IR::Inst& inst) { |
| 247 | NotImplemented(); | 256 | NotImplemented(); |
| 248 | } | 257 | } |
| 249 | 258 | ||
| 250 | void EmitUndefU32(EmitContext& ctx) { | 259 | void EmitUndefU32(EmitContext& ctx, IR::Inst& inst) { |
| 251 | NotImplemented(); | 260 | ctx.AddU32("{}=0u;", inst); |
| 252 | } | 261 | } |
| 253 | 262 | ||
| 254 | void EmitUndefU64(EmitContext& ctx) { | 263 | void EmitUndefU64(EmitContext& ctx, IR::Inst& inst) { |
| 255 | NotImplemented(); | 264 | NotImplemented(); |
| 256 | } | 265 | } |
| 257 | 266 | ||
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.cpp b/src/shader_recompiler/backend/glsl/reg_alloc.cpp index a080d5341..06f1965b5 100644 --- a/src/shader_recompiler/backend/glsl/reg_alloc.cpp +++ b/src/shader_recompiler/backend/glsl/reg_alloc.cpp | |||
| @@ -71,26 +71,17 @@ std::string RegAlloc::Define(IR::Inst& inst) { | |||
| 71 | 71 | ||
| 72 | std::string RegAlloc::Define(IR::Inst& inst, Type type) { | 72 | std::string RegAlloc::Define(IR::Inst& inst, Type type) { |
| 73 | const Id id{Alloc()}; | 73 | const Id id{Alloc()}; |
| 74 | const auto type_str{GetType(type, id.index)}; | 74 | std::string type_str = ""; |
| 75 | if (!register_defined[id.index]) { | ||
| 76 | register_defined[id.index] = true; | ||
| 77 | type_str = GetGlslType(type); | ||
| 78 | } | ||
| 75 | inst.SetDefinition<Id>(id); | 79 | inst.SetDefinition<Id>(id); |
| 76 | return type_str + Representation(id); | 80 | return type_str + Representation(id); |
| 77 | } | 81 | } |
| 78 | 82 | ||
| 79 | std::string RegAlloc::Define(IR::Inst& inst, IR::Type type) { | 83 | std::string RegAlloc::Define(IR::Inst& inst, IR::Type type) { |
| 80 | switch (type) { | 84 | return Define(inst, RegType(type)); |
| 81 | case IR::Type::U1: | ||
| 82 | return Define(inst, Type::U1); | ||
| 83 | case IR::Type::U32: | ||
| 84 | return Define(inst, Type::U32); | ||
| 85 | case IR::Type::F32: | ||
| 86 | return Define(inst, Type::F32); | ||
| 87 | case IR::Type::U64: | ||
| 88 | return Define(inst, Type::U64); | ||
| 89 | case IR::Type::F64: | ||
| 90 | return Define(inst, Type::F64); | ||
| 91 | default: | ||
| 92 | throw NotImplementedException("IR type {}", type); | ||
| 93 | } | ||
| 94 | } | 85 | } |
| 95 | 86 | ||
| 96 | std::string RegAlloc::Consume(const IR::Value& value) { | 87 | std::string RegAlloc::Consume(const IR::Value& value) { |
| @@ -107,11 +98,24 @@ std::string RegAlloc::Consume(IR::Inst& inst) { | |||
| 107 | return Representation(inst.Definition<Id>()); | 98 | return Representation(inst.Definition<Id>()); |
| 108 | } | 99 | } |
| 109 | 100 | ||
| 110 | std::string RegAlloc::GetType(Type type, u32 index) { | 101 | Type RegAlloc::RegType(IR::Type type) { |
| 111 | if (register_defined[index]) { | 102 | switch (type) { |
| 112 | return ""; | 103 | case IR::Type::U1: |
| 104 | return Type::U1; | ||
| 105 | case IR::Type::U32: | ||
| 106 | return Type::U32; | ||
| 107 | case IR::Type::F32: | ||
| 108 | return Type::F32; | ||
| 109 | case IR::Type::U64: | ||
| 110 | return Type::U64; | ||
| 111 | case IR::Type::F64: | ||
| 112 | return Type::F64; | ||
| 113 | default: | ||
| 114 | throw NotImplementedException("IR type {}", type); | ||
| 113 | } | 115 | } |
| 114 | register_defined[index] = true; | 116 | } |
| 117 | |||
| 118 | std::string RegAlloc::GetGlslType(Type type) { | ||
| 115 | switch (type) { | 119 | switch (type) { |
| 116 | case Type::U1: | 120 | case Type::U1: |
| 117 | return "bool "; | 121 | return "bool "; |
| @@ -144,6 +148,10 @@ std::string RegAlloc::GetType(Type type, u32 index) { | |||
| 144 | } | 148 | } |
| 145 | } | 149 | } |
| 146 | 150 | ||
| 151 | std::string RegAlloc::GetGlslType(IR::Type type) { | ||
| 152 | return GetGlslType(RegType(type)); | ||
| 153 | } | ||
| 154 | |||
| 147 | Id RegAlloc::Alloc() { | 155 | Id RegAlloc::Alloc() { |
| 148 | if (num_used_registers < NUM_REGS) { | 156 | if (num_used_registers < NUM_REGS) { |
| 149 | for (size_t reg = 0; reg < NUM_REGS; ++reg) { | 157 | for (size_t reg = 0; reg < NUM_REGS; ++reg) { |
| @@ -170,30 +178,4 @@ void RegAlloc::Free(Id id) { | |||
| 170 | register_use[id.index] = false; | 178 | register_use[id.index] = false; |
| 171 | } | 179 | } |
| 172 | 180 | ||
| 173 | /*static*/ bool RegAlloc::IsAliased(const IR::Inst& inst) { | ||
| 174 | switch (inst.GetOpcode()) { | ||
| 175 | case IR::Opcode::Identity: | ||
| 176 | case IR::Opcode::BitCastU16F16: | ||
| 177 | case IR::Opcode::BitCastU32F32: | ||
| 178 | case IR::Opcode::BitCastU64F64: | ||
| 179 | case IR::Opcode::BitCastF16U16: | ||
| 180 | case IR::Opcode::BitCastF32U32: | ||
| 181 | case IR::Opcode::BitCastF64U64: | ||
| 182 | return true; | ||
| 183 | default: | ||
| 184 | return false; | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | /*static*/ IR::Inst& RegAlloc::AliasInst(IR::Inst& inst) { | ||
| 189 | IR::Inst* it{&inst}; | ||
| 190 | while (IsAliased(*it)) { | ||
| 191 | const IR::Value arg{it->Arg(0)}; | ||
| 192 | if (arg.IsImmediate()) { | ||
| 193 | break; | ||
| 194 | } | ||
| 195 | it = arg.InstRecursive(); | ||
| 196 | } | ||
| 197 | return *it; | ||
| 198 | } | ||
| 199 | } // namespace Shader::Backend::GLSL | 181 | } // namespace Shader::Backend::GLSL |
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.h b/src/shader_recompiler/backend/glsl/reg_alloc.h index df067d3ad..419d0bde0 100644 --- a/src/shader_recompiler/backend/glsl/reg_alloc.h +++ b/src/shader_recompiler/backend/glsl/reg_alloc.h | |||
| @@ -59,20 +59,15 @@ public: | |||
| 59 | std::string Define(IR::Inst& inst, IR::Type type); | 59 | std::string Define(IR::Inst& inst, IR::Type type); |
| 60 | 60 | ||
| 61 | std::string Consume(const IR::Value& value); | 61 | std::string Consume(const IR::Value& value); |
| 62 | 62 | std::string GetGlslType(Type type); | |
| 63 | /// Returns true if the instruction is expected to be aliased to another | 63 | std::string GetGlslType(IR::Type type); |
| 64 | static bool IsAliased(const IR::Inst& inst); | ||
| 65 | |||
| 66 | /// Returns the underlying value out of an alias sequence | ||
| 67 | static IR::Inst& AliasInst(IR::Inst& inst); | ||
| 68 | 64 | ||
| 69 | private: | 65 | private: |
| 70 | static constexpr size_t NUM_REGS = 4096; | 66 | static constexpr size_t NUM_REGS = 4096; |
| 71 | static constexpr size_t NUM_ELEMENTS = 4; | 67 | static constexpr size_t NUM_ELEMENTS = 4; |
| 72 | 68 | ||
| 73 | std::string Consume(IR::Inst& inst); | 69 | std::string Consume(IR::Inst& inst); |
| 74 | std::string GetType(Type type, u32 index); | 70 | Type RegType(IR::Type type); |
| 75 | |||
| 76 | Id Alloc(); | 71 | Id Alloc(); |
| 77 | void Free(Id id); | 72 | void Free(Id id); |
| 78 | 73 | ||