glsl: textures wip
This commit is contained in:
		| @@ -8,9 +8,21 @@ | |||||||
| #include "shader_recompiler/profile.h" | #include "shader_recompiler/profile.h" | ||||||
|  |  | ||||||
| namespace Shader::Backend::GLSL { | namespace Shader::Backend::GLSL { | ||||||
|  | namespace { | ||||||
|  | std::string_view InterpDecorator(Interpolation interp) { | ||||||
|  |     switch (interp) { | ||||||
|  |     case Interpolation::Smooth: | ||||||
|  |         return ""; | ||||||
|  |     case Interpolation::Flat: | ||||||
|  |         return "flat"; | ||||||
|  |     case Interpolation::NoPerspective: | ||||||
|  |         return "noperspective"; | ||||||
|  |     } | ||||||
|  |     throw InvalidArgument("Invalid interpolation {}", interp); | ||||||
|  | } | ||||||
|  | } // namespace | ||||||
|  |  | ||||||
| EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindings, | EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_) | ||||||
|                          const Profile& profile_) |  | ||||||
|     : info{program.info}, profile{profile_} { |     : info{program.info}, profile{profile_} { | ||||||
|     std::string header = "#version 450\n"; |     std::string header = "#version 450\n"; | ||||||
|     SetupExtensions(header); |     SetupExtensions(header); | ||||||
| @@ -49,7 +61,8 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin | |||||||
|     for (size_t index = 0; index < info.input_generics.size(); ++index) { |     for (size_t index = 0; index < info.input_generics.size(); ++index) { | ||||||
|         const auto& generic{info.input_generics[index]}; |         const auto& generic{info.input_generics[index]}; | ||||||
|         if (generic.used) { |         if (generic.used) { | ||||||
|             Add("layout(location={})in vec4 in_attr{};", index, index); |             Add("layout(location={}) {} in vec4 in_attr{};", index, | ||||||
|  |                 InterpDecorator(generic.interpolation), index); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { |     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 | |||||||
|     DefineConstantBuffers(); |     DefineConstantBuffers(); | ||||||
|     DefineStorageBuffers(); |     DefineStorageBuffers(); | ||||||
|     DefineHelperFunctions(); |     DefineHelperFunctions(); | ||||||
|  |     SetupImages(bindings); | ||||||
|     Add("void main(){{"); |     Add("void main(){{"); | ||||||
|  |  | ||||||
|     if (stage == Stage::VertexA || stage == Stage::VertexB) { |     if (stage == Stage::VertexA || stage == Stage::VertexB) { | ||||||
| @@ -102,7 +116,7 @@ void EmitContext::DefineConstantBuffers() { | |||||||
|     } |     } | ||||||
|     u32 binding{}; |     u32 binding{}; | ||||||
|     for (const auto& desc : info.constant_buffer_descriptors) { |     for (const auto& desc : info.constant_buffer_descriptors) { | ||||||
|         Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, binding, |         Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, desc.index, | ||||||
|             desc.index, 4 * 1024); |             desc.index, 4 * 1024); | ||||||
|         ++binding; |         ++binding; | ||||||
|     } |     } | ||||||
| @@ -164,4 +178,36 @@ void EmitContext::DefineHelperFunctions() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void EmitContext::SetupImages(Bindings& bindings) { | ||||||
|  |     image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); | ||||||
|  |     for (const auto& desc : info.image_buffer_descriptors) { | ||||||
|  |         throw NotImplementedException("image_buffer_descriptors"); | ||||||
|  |         image_buffer_bindings.push_back(bindings.image); | ||||||
|  |         bindings.image += desc.count; | ||||||
|  |     } | ||||||
|  |     image_bindings.reserve(info.image_descriptors.size()); | ||||||
|  |     for (const auto& desc : info.image_descriptors) { | ||||||
|  |         throw NotImplementedException("image_bindings"); | ||||||
|  |  | ||||||
|  |         image_bindings.push_back(bindings.image); | ||||||
|  |         bindings.image += desc.count; | ||||||
|  |     } | ||||||
|  |     texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); | ||||||
|  |     for (const auto& desc : info.texture_buffer_descriptors) { | ||||||
|  |         throw NotImplementedException("TextureType::Buffer"); | ||||||
|  |  | ||||||
|  |         texture_buffer_bindings.push_back(bindings.texture); | ||||||
|  |         bindings.texture += desc.count; | ||||||
|  |     } | ||||||
|  |     texture_bindings.reserve(info.texture_descriptors.size()); | ||||||
|  |     for (const auto& desc : info.texture_descriptors) { | ||||||
|  |         texture_bindings.push_back(bindings.texture); | ||||||
|  |         const auto indices{bindings.texture + desc.count}; | ||||||
|  |         for (u32 index = bindings.texture; index < indices; ++index) { | ||||||
|  |             Add("layout(binding={}) uniform sampler2D tex{};", bindings.texture, index); | ||||||
|  |         } | ||||||
|  |         bindings.texture += desc.count; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| } // namespace Shader::Backend::GLSL | } // namespace Shader::Backend::GLSL | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ | |||||||
|  |  | ||||||
| #include <string> | #include <string> | ||||||
| #include <utility> | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  |  | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
|  |  | ||||||
| #include "shader_recompiler/backend/glsl/reg_alloc.h" | #include "shader_recompiler/backend/glsl/reg_alloc.h" | ||||||
| @@ -109,11 +111,17 @@ public: | |||||||
|     std::string_view stage_name = "invalid"; |     std::string_view stage_name = "invalid"; | ||||||
|     std::string_view attrib_name = "invalid"; |     std::string_view attrib_name = "invalid"; | ||||||
|  |  | ||||||
|  |     std::vector<u32> texture_buffer_bindings; | ||||||
|  |     std::vector<u32> image_buffer_bindings; | ||||||
|  |     std::vector<u32> texture_bindings; | ||||||
|  |     std::vector<u32> image_bindings; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     void SetupExtensions(std::string& header); |     void SetupExtensions(std::string& header); | ||||||
|     void DefineConstantBuffers(); |     void DefineConstantBuffers(); | ||||||
|     void DefineStorageBuffers(); |     void DefineStorageBuffers(); | ||||||
|     void DefineHelperFunctions(); |     void DefineHelperFunctions(); | ||||||
|  |     void SetupImages(Bindings& bindings); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace Shader::Backend::GLSL | } // namespace Shader::Backend::GLSL | ||||||
|   | |||||||
| @@ -113,7 +113,7 @@ void PrecolorInst(IR::Inst& phi) { | |||||||
|         if (arg.IsImmediate()) { |         if (arg.IsImmediate()) { | ||||||
|             ir.PhiMove(phi, arg); |             ir.PhiMove(phi, arg); | ||||||
|         } else { |         } else { | ||||||
|             ir.PhiMove(phi, IR::Value{&RegAlloc::AliasInst(*arg.Inst())}); |             ir.PhiMove(phi, IR::Value{&*arg.InstRecursive()}); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     for (size_t i = 0; i < num_args; ++i) { |     for (size_t i = 0; i < num_args; ++i) { | ||||||
| @@ -157,7 +157,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { | |||||||
|             break; |             break; | ||||||
|         case IR::AbstractSyntaxNode::Type::Return: |         case IR::AbstractSyntaxNode::Type::Return: | ||||||
|         case IR::AbstractSyntaxNode::Type::Unreachable: |         case IR::AbstractSyntaxNode::Type::Unreachable: | ||||||
|             ctx.Add("return;\n}}"); |             ctx.Add("return;"); | ||||||
|             break; |             break; | ||||||
|         case IR::AbstractSyntaxNode::Type::Loop: |         case IR::AbstractSyntaxNode::Type::Loop: | ||||||
|         case IR::AbstractSyntaxNode::Type::Repeat: |         case IR::AbstractSyntaxNode::Type::Repeat: | ||||||
| @@ -175,6 +175,8 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo&, IR::Program& pr | |||||||
|     EmitContext ctx{program, bindings, profile}; |     EmitContext ctx{program, bindings, profile}; | ||||||
|     Precolor(program); |     Precolor(program); | ||||||
|     EmitCode(ctx, program); |     EmitCode(ctx, program); | ||||||
|  |     ctx.code += "}"; | ||||||
|  |     fmt::print("\n{}\n", ctx.code); | ||||||
|     return ctx.code; |     return ctx.code; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ static void Alias(IR::Inst& inst, const IR::Value& value) { | |||||||
|     if (value.IsImmediate()) { |     if (value.IsImmediate()) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     IR::Inst& value_inst{RegAlloc::AliasInst(*value.Inst())}; |     IR::Inst& value_inst{*value.InstRecursive()}; | ||||||
|     value_inst.DestructiveAddUsage(inst.UseCount()); |     value_inst.DestructiveAddUsage(inst.UseCount()); | ||||||
|     value_inst.DestructiveRemoveUsage(); |     value_inst.DestructiveRemoveUsage(); | ||||||
|     inst.SetDefinition(value_inst.Definition<Id>()); |     inst.SetDefinition(value_inst.Definition<Id>()); | ||||||
|   | |||||||
| @@ -6,17 +6,39 @@ | |||||||
|  |  | ||||||
| #include "shader_recompiler/backend/glsl/emit_context.h" | #include "shader_recompiler/backend/glsl/emit_context.h" | ||||||
| #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | ||||||
|  | #include "shader_recompiler/frontend/ir/modifiers.h" | ||||||
| #include "shader_recompiler/frontend/ir/value.h" | #include "shader_recompiler/frontend/ir/value.h" | ||||||
| #include "shader_recompiler/profile.h" | #include "shader_recompiler/profile.h" | ||||||
|  |  | ||||||
| namespace Shader::Backend::GLSL { | namespace Shader::Backend::GLSL { | ||||||
|  | namespace { | ||||||
|  | std::string Texture(EmitContext& ctx, IR::TextureInstInfo info, | ||||||
|  |                     [[maybe_unused]] const IR::Value& index) { | ||||||
|  |     if (info.type == TextureType::Buffer) { | ||||||
|  |         throw NotImplementedException("TextureType::Buffer"); | ||||||
|  |     } else { | ||||||
|  |         return fmt::format("tex{}", ctx.texture_bindings.at(info.descriptor_index)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | } // namespace | ||||||
|  |  | ||||||
| void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
|                                 [[maybe_unused]] const IR::Value& index, |                                 [[maybe_unused]] const IR::Value& index, | ||||||
|                                 [[maybe_unused]] std::string_view coords, |                                 [[maybe_unused]] std::string_view coords, | ||||||
|                                 [[maybe_unused]] std::string_view bias_lc, |                                 [[maybe_unused]] std::string_view bias_lc, | ||||||
|                                 [[maybe_unused]] const IR::Value& offset) { |                                 [[maybe_unused]] const IR::Value& offset) { | ||||||
|     throw NotImplementedException("GLSL Instruction"); |     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||||
|  |     if (info.has_bias) { | ||||||
|  |         throw NotImplementedException("Bias texture samples"); | ||||||
|  |     } | ||||||
|  |     if (info.has_lod_clamp) { | ||||||
|  |         throw NotImplementedException("Lod clamp samples"); | ||||||
|  |     } | ||||||
|  |     if (!offset.IsEmpty()) { | ||||||
|  |         throw NotImplementedException("Offset"); | ||||||
|  |     } | ||||||
|  |     const auto texture{Texture(ctx, info, index)}; | ||||||
|  |     ctx.AddF32x4("{}=texture({},{});", inst, texture, coords); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
|   | |||||||
| @@ -89,11 +89,11 @@ void EmitIsHelperInvocation(EmitContext& ctx); | |||||||
| void EmitYDirection(EmitContext& ctx); | void EmitYDirection(EmitContext& ctx); | ||||||
| void EmitLoadLocal(EmitContext& ctx, std::string_view word_offset); | void EmitLoadLocal(EmitContext& ctx, std::string_view word_offset); | ||||||
| void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_view value); | void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_view value); | ||||||
| void EmitUndefU1(EmitContext& ctx); | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst); | ||||||
| void EmitUndefU8(EmitContext& ctx); | void EmitUndefU8(EmitContext& ctx, IR::Inst& inst); | ||||||
| void EmitUndefU16(EmitContext& ctx); | void EmitUndefU16(EmitContext& ctx, IR::Inst& inst); | ||||||
| void EmitUndefU32(EmitContext& ctx); | void EmitUndefU32(EmitContext& ctx, IR::Inst& inst); | ||||||
| void EmitUndefU64(EmitContext& ctx); | void EmitUndefU64(EmitContext& ctx, IR::Inst& inst); | ||||||
| void EmitLoadGlobalU8(EmitContext& ctx); | void EmitLoadGlobalU8(EmitContext& ctx); | ||||||
| void EmitLoadGlobalS8(EmitContext& ctx); | void EmitLoadGlobalS8(EmitContext& ctx); | ||||||
| void EmitLoadGlobalU16(EmitContext& ctx); | void EmitLoadGlobalU16(EmitContext& ctx); | ||||||
|   | |||||||
| @@ -39,17 +39,26 @@ void EmitReference(EmitContext&) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | ||||||
|     IR::Inst& phi{RegAlloc::AliasInst(*phi_value.Inst())}; |     IR::Inst& phi{*phi_value.InstRecursive()}; | ||||||
|  |     const auto phi_type{phi.Arg(0).Type()}; | ||||||
|     if (!phi.Definition<Id>().is_valid) { |     if (!phi.Definition<Id>().is_valid) { | ||||||
|         // The phi node wasn't forward defined |         // The phi node wasn't forward defined | ||||||
|         ctx.Add("{};", ctx.reg_alloc.Define(phi, phi.Arg(0).Type())); |         ctx.Add("{};", ctx.reg_alloc.Define(phi, phi_type)); | ||||||
|     } |     } | ||||||
|     const auto phi_reg{ctx.reg_alloc.Consume(IR::Value{&phi})}; |     const auto phi_reg{ctx.reg_alloc.Consume(IR::Value{&phi})}; | ||||||
|     const auto val_reg{ctx.reg_alloc.Consume(value)}; |     const auto val_reg{ctx.reg_alloc.Consume(value)}; | ||||||
|     if (phi_reg == val_reg) { |     if (phi_reg == val_reg) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     ctx.Add("{}={};", phi_reg, val_reg); |     if (phi_type == value.Type()) { | ||||||
|  |         ctx.Add("{}={}; // PHI MOVE", phi_reg, val_reg); | ||||||
|  |     } else if (phi_type == IR::Type::U32 && value.Type() == IR::Type::F32) { | ||||||
|  |         ctx.Add("{}=floatBitsToUint({}); // CAST PHI MOVE", phi_reg, val_reg); | ||||||
|  |     } else { | ||||||
|  |         throw NotImplementedException("{} to {} move", phi_type, value.Type()); | ||||||
|  |         const auto cast{ctx.reg_alloc.GetGlslType(phi_type)}; | ||||||
|  |         ctx.Add("{}={}({}); // CAST PHI MOVE", phi_reg, cast, val_reg); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBranch(EmitContext& ctx, std::string_view label) { | void EmitBranch(EmitContext& ctx, std::string_view label) { | ||||||
| @@ -235,23 +244,23 @@ void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_ | |||||||
|     NotImplemented(); |     NotImplemented(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitUndefU1(EmitContext& ctx) { | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     NotImplemented(); |     NotImplemented(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitUndefU8(EmitContext& ctx) { | void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     NotImplemented(); |     NotImplemented(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitUndefU16(EmitContext& ctx) { | void EmitUndefU16(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     NotImplemented(); |     NotImplemented(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitUndefU32(EmitContext& ctx) { | void EmitUndefU32(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     NotImplemented(); |     ctx.AddU32("{}=0u;", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitUndefU64(EmitContext& ctx) { | void EmitUndefU64(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     NotImplemented(); |     NotImplemented(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -71,26 +71,17 @@ std::string RegAlloc::Define(IR::Inst& inst) { | |||||||
|  |  | ||||||
| std::string RegAlloc::Define(IR::Inst& inst, Type type) { | std::string RegAlloc::Define(IR::Inst& inst, Type type) { | ||||||
|     const Id id{Alloc()}; |     const Id id{Alloc()}; | ||||||
|     const auto type_str{GetType(type, id.index)}; |     std::string type_str = ""; | ||||||
|  |     if (!register_defined[id.index]) { | ||||||
|  |         register_defined[id.index] = true; | ||||||
|  |         type_str = GetGlslType(type); | ||||||
|  |     } | ||||||
|     inst.SetDefinition<Id>(id); |     inst.SetDefinition<Id>(id); | ||||||
|     return type_str + Representation(id); |     return type_str + Representation(id); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string RegAlloc::Define(IR::Inst& inst, IR::Type type) { | std::string RegAlloc::Define(IR::Inst& inst, IR::Type type) { | ||||||
|     switch (type) { |     return Define(inst, RegType(type)); | ||||||
|     case IR::Type::U1: |  | ||||||
|         return Define(inst, Type::U1); |  | ||||||
|     case IR::Type::U32: |  | ||||||
|         return Define(inst, Type::U32); |  | ||||||
|     case IR::Type::F32: |  | ||||||
|         return Define(inst, Type::F32); |  | ||||||
|     case IR::Type::U64: |  | ||||||
|         return Define(inst, Type::U64); |  | ||||||
|     case IR::Type::F64: |  | ||||||
|         return Define(inst, Type::F64); |  | ||||||
|     default: |  | ||||||
|         throw NotImplementedException("IR type {}", type); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string RegAlloc::Consume(const IR::Value& value) { | std::string RegAlloc::Consume(const IR::Value& value) { | ||||||
| @@ -107,11 +98,24 @@ std::string RegAlloc::Consume(IR::Inst& inst) { | |||||||
|     return Representation(inst.Definition<Id>()); |     return Representation(inst.Definition<Id>()); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string RegAlloc::GetType(Type type, u32 index) { | Type RegAlloc::RegType(IR::Type type) { | ||||||
|     if (register_defined[index]) { |     switch (type) { | ||||||
|         return ""; |     case IR::Type::U1: | ||||||
|  |         return Type::U1; | ||||||
|  |     case IR::Type::U32: | ||||||
|  |         return Type::U32; | ||||||
|  |     case IR::Type::F32: | ||||||
|  |         return Type::F32; | ||||||
|  |     case IR::Type::U64: | ||||||
|  |         return Type::U64; | ||||||
|  |     case IR::Type::F64: | ||||||
|  |         return Type::F64; | ||||||
|  |     default: | ||||||
|  |         throw NotImplementedException("IR type {}", type); | ||||||
|     } |     } | ||||||
|     register_defined[index] = true; | } | ||||||
|  |  | ||||||
|  | std::string RegAlloc::GetGlslType(Type type) { | ||||||
|     switch (type) { |     switch (type) { | ||||||
|     case Type::U1: |     case Type::U1: | ||||||
|         return "bool "; |         return "bool "; | ||||||
| @@ -144,6 +148,10 @@ std::string RegAlloc::GetType(Type type, u32 index) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::string RegAlloc::GetGlslType(IR::Type type) { | ||||||
|  |     return GetGlslType(RegType(type)); | ||||||
|  | } | ||||||
|  |  | ||||||
| Id RegAlloc::Alloc() { | Id RegAlloc::Alloc() { | ||||||
|     if (num_used_registers < NUM_REGS) { |     if (num_used_registers < NUM_REGS) { | ||||||
|         for (size_t reg = 0; reg < NUM_REGS; ++reg) { |         for (size_t reg = 0; reg < NUM_REGS; ++reg) { | ||||||
| @@ -170,30 +178,4 @@ void RegAlloc::Free(Id id) { | |||||||
|     register_use[id.index] = false; |     register_use[id.index] = false; | ||||||
| } | } | ||||||
|  |  | ||||||
| /*static*/ bool RegAlloc::IsAliased(const IR::Inst& inst) { |  | ||||||
|     switch (inst.GetOpcode()) { |  | ||||||
|     case IR::Opcode::Identity: |  | ||||||
|     case IR::Opcode::BitCastU16F16: |  | ||||||
|     case IR::Opcode::BitCastU32F32: |  | ||||||
|     case IR::Opcode::BitCastU64F64: |  | ||||||
|     case IR::Opcode::BitCastF16U16: |  | ||||||
|     case IR::Opcode::BitCastF32U32: |  | ||||||
|     case IR::Opcode::BitCastF64U64: |  | ||||||
|         return true; |  | ||||||
|     default: |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /*static*/ IR::Inst& RegAlloc::AliasInst(IR::Inst& inst) { |  | ||||||
|     IR::Inst* it{&inst}; |  | ||||||
|     while (IsAliased(*it)) { |  | ||||||
|         const IR::Value arg{it->Arg(0)}; |  | ||||||
|         if (arg.IsImmediate()) { |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|         it = arg.InstRecursive(); |  | ||||||
|     } |  | ||||||
|     return *it; |  | ||||||
| } |  | ||||||
| } // namespace Shader::Backend::GLSL | } // namespace Shader::Backend::GLSL | ||||||
|   | |||||||
| @@ -59,20 +59,15 @@ public: | |||||||
|     std::string Define(IR::Inst& inst, IR::Type type); |     std::string Define(IR::Inst& inst, IR::Type type); | ||||||
|  |  | ||||||
|     std::string Consume(const IR::Value& value); |     std::string Consume(const IR::Value& value); | ||||||
|  |     std::string GetGlslType(Type type); | ||||||
|     /// Returns true if the instruction is expected to be aliased to another |     std::string GetGlslType(IR::Type type); | ||||||
|     static bool IsAliased(const IR::Inst& inst); |  | ||||||
|  |  | ||||||
|     /// Returns the underlying value out of an alias sequence |  | ||||||
|     static IR::Inst& AliasInst(IR::Inst& inst); |  | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     static constexpr size_t NUM_REGS = 4096; |     static constexpr size_t NUM_REGS = 4096; | ||||||
|     static constexpr size_t NUM_ELEMENTS = 4; |     static constexpr size_t NUM_ELEMENTS = 4; | ||||||
|  |  | ||||||
|     std::string Consume(IR::Inst& inst); |     std::string Consume(IR::Inst& inst); | ||||||
|     std::string GetType(Type type, u32 index); |     Type RegType(IR::Type type); | ||||||
|  |  | ||||||
|     Id Alloc(); |     Id Alloc(); | ||||||
|     void Free(Id id); |     void Free(Id id); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user