glsl: Reusable typed variables. IADD32
This commit is contained in:
		| @@ -31,9 +31,33 @@ class EmitContext { | ||||
| public: | ||||
|     explicit EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_); | ||||
|  | ||||
|     // template <typename... Args> | ||||
|     // void Add(const char* format_str, IR::Inst& inst, Args&&... args) { | ||||
|     //     code += fmt::format(format_str, reg_alloc.Define(inst), std::forward<Args>(args)...); | ||||
|     //     // TODO: Remove this | ||||
|     //     code += '\n'; | ||||
|     // } | ||||
|  | ||||
|     template <typename... Args> | ||||
|     void Add(const char* format_str, IR::Inst& inst, Args&&... args) { | ||||
|         code += fmt::format(format_str, reg_alloc.Define(inst), std::forward<Args>(args)...); | ||||
|     void AddU32(const char* format_str, IR::Inst& inst, Args&&... args) { | ||||
|         code += | ||||
|             fmt::format(format_str, reg_alloc.Define(inst, Type::U32), std::forward<Args>(args)...); | ||||
|         // TODO: Remove this | ||||
|         code += '\n'; | ||||
|     } | ||||
|  | ||||
|     template <typename... Args> | ||||
|     void AddS32(const char* format_str, IR::Inst& inst, Args&&... args) { | ||||
|         code += | ||||
|             fmt::format(format_str, reg_alloc.Define(inst, Type::S32), std::forward<Args>(args)...); | ||||
|         // TODO: Remove this | ||||
|         code += '\n'; | ||||
|     } | ||||
|  | ||||
|     template <typename... Args> | ||||
|     void AddF32(const char* format_str, IR::Inst& inst, Args&&... args) { | ||||
|         code += | ||||
|             fmt::format(format_str, reg_alloc.Define(inst, Type::F32), std::forward<Args>(args)...); | ||||
|         // TODO: Remove this | ||||
|         code += '\n'; | ||||
|     } | ||||
|   | ||||
| @@ -33,7 +33,7 @@ void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR | ||||
| void EmitGetCbufU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& binding, | ||||
|                     const IR::Value& offset) { | ||||
|     const auto u32_offset{offset.U32()}; | ||||
|     ctx.Add("uint {}=floatBitsToUint(cbuf{}[{}][{}]);", *inst, binding.U32(), u32_offset / 16, | ||||
|     ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}][{}]);", *inst, binding.U32(), u32_offset / 16, | ||||
|                (u32_offset / 4) % 4); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,221 @@ | ||||
|  | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <string_view> | ||||
|  | ||||
| #include "shader_recompiler/backend/glsl/emit_context.h" | ||||
| #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | ||||
| #include "shader_recompiler/frontend/ir/value.h" | ||||
| #include "shader_recompiler/profile.h" | ||||
|  | ||||
| namespace Shader::Backend::GLSL { | ||||
| void EmitIAdd32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst* inst, | ||||
|                 [[maybe_unused]] std::string a, [[maybe_unused]] std::string b) { | ||||
|     ctx.AddU32("{}={}+{};", *inst, a, b); | ||||
| } | ||||
|  | ||||
| void EmitIAdd64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string a, | ||||
|                 [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitISub32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string a, | ||||
|                 [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitISub64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string a, | ||||
|                 [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitIMul32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string a, | ||||
|                 [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitINeg32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitINeg64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitIAbs32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitIAbs64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitShiftLeftLogical32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string base, | ||||
|                             [[maybe_unused]] std::string shift) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitShiftLeftLogical64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string base, | ||||
|                             [[maybe_unused]] std::string shift) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitShiftRightLogical32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string base, | ||||
|                              [[maybe_unused]] std::string shift) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitShiftRightLogical64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string base, | ||||
|                              [[maybe_unused]] std::string shift) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitShiftRightArithmetic32([[maybe_unused]] EmitContext& ctx, | ||||
|                                 [[maybe_unused]] std::string base, | ||||
|                                 [[maybe_unused]] std::string shift) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitShiftRightArithmetic64([[maybe_unused]] EmitContext& ctx, | ||||
|                                 [[maybe_unused]] std::string base, | ||||
|                                 [[maybe_unused]] std::string shift) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitwiseAnd32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst* inst, | ||||
|                       [[maybe_unused]] std::string a, [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitwiseOr32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst* inst, | ||||
|                      [[maybe_unused]] std::string a, [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitwiseXor32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst* inst, | ||||
|                       [[maybe_unused]] std::string a, [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitFieldInsert([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string base, | ||||
|                         [[maybe_unused]] std::string insert, [[maybe_unused]] std::string offset, | ||||
|                         std::string count) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitFieldSExtract([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst* inst, | ||||
|                           [[maybe_unused]] std::string base, [[maybe_unused]] std::string offset, | ||||
|                           std::string count) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitFieldUExtract([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst* inst, | ||||
|                           [[maybe_unused]] std::string base, [[maybe_unused]] std::string offset, | ||||
|                           std::string count) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitReverse32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitCount32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitBitwiseNot32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitFindSMsb32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitFindUMsb32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string value) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSMin32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string a, | ||||
|                 [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitUMin32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string a, | ||||
|                 [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSMax32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string a, | ||||
|                 [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitUMax32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string a, | ||||
|                 [[maybe_unused]] std::string b) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSClamp32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst* inst, | ||||
|                   [[maybe_unused]] std::string value, [[maybe_unused]] std::string min, | ||||
|                   std::string max) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitUClamp32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst* inst, | ||||
|                   [[maybe_unused]] std::string value, [[maybe_unused]] std::string min, | ||||
|                   std::string max) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSLessThan([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                    [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitULessThan([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                    [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitIEqual([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                 [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSLessThanEqual([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                         [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitULessThanEqual([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                         [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSGreaterThan([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                       [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitUGreaterThan([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                       [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitINotEqual([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                    [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSGreaterThanEqual([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                            [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitUGreaterThanEqual([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string lhs, | ||||
|                            [[maybe_unused]] std::string rhs) { | ||||
|     throw NotImplementedException("GLSL Instruction"); | ||||
| } | ||||
| } // namespace Shader::Backend::GLSL | ||||
|   | ||||
| @@ -979,179 +979,6 @@ void EmitFPIsNan64(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitIAdd32(EmitContext& ctx, IR::Inst* inst, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitIAdd64(EmitContext& ctx, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitISub32(EmitContext& ctx, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitISub64(EmitContext& ctx, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitIMul32(EmitContext& ctx, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitINeg32(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitINeg64(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitIAbs32(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitIAbs64(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitShiftLeftLogical32(EmitContext& ctx, std::string base, std::string shift) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitShiftLeftLogical64(EmitContext& ctx, std::string base, std::string shift) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitShiftRightLogical32(EmitContext& ctx, std::string base, std::string shift) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitShiftRightLogical64(EmitContext& ctx, std::string base, std::string shift) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitShiftRightArithmetic32(EmitContext& ctx, std::string base, std::string shift) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitShiftRightArithmetic64(EmitContext& ctx, std::string base, std::string shift) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitwiseAnd32(EmitContext& ctx, IR::Inst* inst, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitwiseOr32(EmitContext& ctx, IR::Inst* inst, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitwiseXor32(EmitContext& ctx, IR::Inst* inst, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitFieldInsert(EmitContext& ctx, std::string base, std::string insert, std::string offset, | ||||
|                         std::string count) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst* inst, std::string base, std::string offset, | ||||
|                           std::string count) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, std::string base, std::string offset, | ||||
|                           std::string count) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitReverse32(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitCount32(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitBitwiseNot32(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitFindSMsb32(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitFindUMsb32(EmitContext& ctx, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitSMin32(EmitContext& ctx, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitUMin32(EmitContext& ctx, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitSMax32(EmitContext& ctx, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitUMax32(EmitContext& ctx, std::string a, std::string b) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitSClamp32(EmitContext& ctx, IR::Inst* inst, std::string value, std::string min, | ||||
|                   std::string max) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitUClamp32(EmitContext& ctx, IR::Inst* inst, std::string value, std::string min, | ||||
|                   std::string max) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitSLessThan(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitULessThan(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitIEqual(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitSLessThanEqual(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitULessThanEqual(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitSGreaterThan(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitUGreaterThan(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitINotEqual(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitSGreaterThanEqual(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitUGreaterThanEqual(EmitContext& ctx, std::string lhs, std::string rhs) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitSharedAtomicIAdd32(EmitContext& ctx, std::string pointer_offset, std::string value) { | ||||
|     NotImplemented(); | ||||
| } | ||||
|   | ||||
| @@ -13,7 +13,6 @@ | ||||
| #pragma optimize("", off) | ||||
| namespace Shader::Backend::GLSL { | ||||
| namespace { | ||||
| constexpr std::string_view SWIZZLE = "xyzw"; | ||||
|  | ||||
| std::string Representation(Id id) { | ||||
|     if (id.is_condition_code != 0) { | ||||
| @@ -22,7 +21,6 @@ std::string Representation(Id id) { | ||||
|     if (id.is_spill != 0) { | ||||
|         throw NotImplementedException("Spilling"); | ||||
|     } | ||||
|     const u32 num_elements{id.num_elements_minus_one + 1}; | ||||
|     const u32 index{static_cast<u32>(id.index)}; | ||||
|     return fmt::format("R{}", index); | ||||
| } | ||||
| @@ -45,10 +43,11 @@ std::string MakeImm(const IR::Value& value) { | ||||
| } | ||||
| } // Anonymous namespace | ||||
|  | ||||
| std::string RegAlloc::Define(IR::Inst& inst, u32 num_elements, u32 alignment) { | ||||
|     const Id id{Alloc(num_elements, alignment)}; | ||||
| std::string RegAlloc::Define(IR::Inst& inst, Type type) { | ||||
|     const Id id{Alloc()}; | ||||
|     const auto type_str{GetType(type, id.index)}; | ||||
|     inst.SetDefinition<Id>(id); | ||||
|     return Representation(id); | ||||
|     return type_str + Representation(id); | ||||
| } | ||||
|  | ||||
| std::string RegAlloc::Consume(const IR::Value& value) { | ||||
| @@ -65,20 +64,37 @@ std::string RegAlloc::Consume(IR::Inst& inst) { | ||||
|     return Representation(inst.Definition<Id>()); | ||||
| } | ||||
|  | ||||
| Id RegAlloc::Alloc(u32 num_elements, [[maybe_unused]] u32 alignment) { | ||||
| std::string RegAlloc::GetType(Type type, u32 index) { | ||||
|     if (register_defined[index]) { | ||||
|         return ""; | ||||
|     } | ||||
|     register_defined[index] = true; | ||||
|     switch (type) { | ||||
|     case Type::U32: | ||||
|         return "uint "; | ||||
|     case Type::S32: | ||||
|         return "int "; | ||||
|     case Type::F32: | ||||
|         return "float "; | ||||
|     default: | ||||
|         return ""; | ||||
|     } | ||||
| } | ||||
|  | ||||
| Id RegAlloc::Alloc() { | ||||
|     if (num_used_registers < NUM_REGS) { | ||||
|         for (size_t reg = 0; reg < NUM_REGS; ++reg) { | ||||
|             if (register_use[reg]) { | ||||
|                 continue; | ||||
|             } | ||||
|         num_used_registers = std::max(num_used_registers, reg + 1); | ||||
|             register_use[reg] = true; | ||||
|         return Id{ | ||||
|             .base_element = 0, | ||||
|             .num_elements_minus_one = num_elements - 1, | ||||
|             .index = static_cast<u32>(reg), | ||||
|             .is_spill = 0, | ||||
|             .is_condition_code = 0, | ||||
|         }; | ||||
|             Id ret{}; | ||||
|             ret.index.Assign(static_cast<u32>(reg)); | ||||
|             ret.is_long.Assign(0); | ||||
|             ret.is_spill.Assign(0); | ||||
|             ret.is_condition_code.Assign(0); | ||||
|             return ret; | ||||
|         } | ||||
|     } | ||||
|     throw NotImplementedException("Register spilling"); | ||||
| } | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
|  | ||||
| #include <bitset> | ||||
|  | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
|  | ||||
| namespace Shader::IR { | ||||
| @@ -14,18 +15,36 @@ class Value; | ||||
| } // namespace Shader::IR | ||||
|  | ||||
| namespace Shader::Backend::GLSL { | ||||
| enum class Type : u32 { | ||||
|     U32, | ||||
|     S32, | ||||
|     F32, | ||||
|     U64, | ||||
|     F64, | ||||
|     Void, | ||||
| }; | ||||
|  | ||||
| struct Id { | ||||
|     u32 base_element : 2; | ||||
|     u32 num_elements_minus_one : 2; | ||||
|     u32 index : 26; | ||||
|     u32 is_spill : 1; | ||||
|     u32 is_condition_code : 1; | ||||
|     union { | ||||
|         u32 raw; | ||||
|         BitField<0, 29, u32> index; | ||||
|         BitField<29, 1, u32> is_long; | ||||
|         BitField<30, 1, u32> is_spill; | ||||
|         BitField<31, 1, u32> is_condition_code; | ||||
|     }; | ||||
|  | ||||
|     bool operator==(Id rhs) const noexcept { | ||||
|         return raw == rhs.raw; | ||||
|     } | ||||
|     bool operator!=(Id rhs) const noexcept { | ||||
|         return !operator==(rhs); | ||||
|     } | ||||
| }; | ||||
| static_assert(sizeof(Id) == sizeof(u32)); | ||||
|  | ||||
| class RegAlloc { | ||||
| public: | ||||
|     std::string Define(IR::Inst& inst, u32 num_elements = 1, u32 alignment = 1); | ||||
|     std::string Define(IR::Inst& inst, Type type = Type::Void); | ||||
|  | ||||
|     std::string Consume(const IR::Value& value); | ||||
|  | ||||
| @@ -40,13 +59,14 @@ private: | ||||
|     static constexpr size_t NUM_ELEMENTS = 4; | ||||
|  | ||||
|     std::string Consume(IR::Inst& inst); | ||||
|     std::string GetType(Type type, u32 index); | ||||
|  | ||||
|     Id Alloc(u32 num_elements, u32 alignment); | ||||
|  | ||||
|     Id Alloc(); | ||||
|     void Free(Id id); | ||||
|  | ||||
|     size_t num_used_registers{}; | ||||
|     std::bitset<NUM_REGS> register_use{}; | ||||
|     std::bitset<NUM_REGS> register_defined{}; | ||||
| }; | ||||
|  | ||||
| } // namespace Shader::Backend::GLSL | ||||
|   | ||||
		Reference in New Issue
	
	Block a user