glsl: Reusable typed variables. IADD32
This commit is contained in:
		| @@ -31,9 +31,33 @@ class EmitContext { | |||||||
| public: | public: | ||||||
|     explicit EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_); |     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> |     template <typename... Args> | ||||||
|     void Add(const char* format_str, IR::Inst& inst, Args&&... args) { |     void AddU32(const char* format_str, IR::Inst& inst, Args&&... args) { | ||||||
|         code += fmt::format(format_str, reg_alloc.Define(inst), std::forward<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 |         // TODO: Remove this | ||||||
|         code += '\n'; |         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, | void EmitGetCbufU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& binding, | ||||||
|                     const IR::Value& offset) { |                     const IR::Value& offset) { | ||||||
|     const auto u32_offset{offset.U32()}; |     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); |                (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(); |     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) { | void EmitSharedAtomicIAdd32(EmitContext& ctx, std::string pointer_offset, std::string value) { | ||||||
|     NotImplemented(); |     NotImplemented(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -13,7 +13,6 @@ | |||||||
| #pragma optimize("", off) | #pragma optimize("", off) | ||||||
| namespace Shader::Backend::GLSL { | namespace Shader::Backend::GLSL { | ||||||
| namespace { | namespace { | ||||||
| constexpr std::string_view SWIZZLE = "xyzw"; |  | ||||||
|  |  | ||||||
| std::string Representation(Id id) { | std::string Representation(Id id) { | ||||||
|     if (id.is_condition_code != 0) { |     if (id.is_condition_code != 0) { | ||||||
| @@ -22,7 +21,6 @@ std::string Representation(Id id) { | |||||||
|     if (id.is_spill != 0) { |     if (id.is_spill != 0) { | ||||||
|         throw NotImplementedException("Spilling"); |         throw NotImplementedException("Spilling"); | ||||||
|     } |     } | ||||||
|     const u32 num_elements{id.num_elements_minus_one + 1}; |  | ||||||
|     const u32 index{static_cast<u32>(id.index)}; |     const u32 index{static_cast<u32>(id.index)}; | ||||||
|     return fmt::format("R{}", index); |     return fmt::format("R{}", index); | ||||||
| } | } | ||||||
| @@ -45,10 +43,11 @@ std::string MakeImm(const IR::Value& value) { | |||||||
| } | } | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| std::string RegAlloc::Define(IR::Inst& inst, u32 num_elements, u32 alignment) { | std::string RegAlloc::Define(IR::Inst& inst, Type type) { | ||||||
|     const Id id{Alloc(num_elements, alignment)}; |     const Id id{Alloc()}; | ||||||
|  |     const auto type_str{GetType(type, id.index)}; | ||||||
|     inst.SetDefinition<Id>(id); |     inst.SetDefinition<Id>(id); | ||||||
|     return Representation(id); |     return type_str + Representation(id); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string RegAlloc::Consume(const IR::Value& value) { | std::string RegAlloc::Consume(const IR::Value& value) { | ||||||
| @@ -65,20 +64,37 @@ std::string RegAlloc::Consume(IR::Inst& inst) { | |||||||
|     return Representation(inst.Definition<Id>()); |     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) { |         for (size_t reg = 0; reg < NUM_REGS; ++reg) { | ||||||
|             if (register_use[reg]) { |             if (register_use[reg]) { | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|         num_used_registers = std::max(num_used_registers, reg + 1); |  | ||||||
|             register_use[reg] = true; |             register_use[reg] = true; | ||||||
|         return Id{ |             Id ret{}; | ||||||
|             .base_element = 0, |             ret.index.Assign(static_cast<u32>(reg)); | ||||||
|             .num_elements_minus_one = num_elements - 1, |             ret.is_long.Assign(0); | ||||||
|             .index = static_cast<u32>(reg), |             ret.is_spill.Assign(0); | ||||||
|             .is_spill = 0, |             ret.is_condition_code.Assign(0); | ||||||
|             .is_condition_code = 0, |             return ret; | ||||||
|         }; |         } | ||||||
|     } |     } | ||||||
|     throw NotImplementedException("Register spilling"); |     throw NotImplementedException("Register spilling"); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
|  |  | ||||||
| #include <bitset> | #include <bitset> | ||||||
|  |  | ||||||
|  | #include "common/bit_field.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
|  |  | ||||||
| namespace Shader::IR { | namespace Shader::IR { | ||||||
| @@ -14,18 +15,36 @@ class Value; | |||||||
| } // namespace Shader::IR | } // namespace Shader::IR | ||||||
|  |  | ||||||
| namespace Shader::Backend::GLSL { | namespace Shader::Backend::GLSL { | ||||||
|  | enum class Type : u32 { | ||||||
|  |     U32, | ||||||
|  |     S32, | ||||||
|  |     F32, | ||||||
|  |     U64, | ||||||
|  |     F64, | ||||||
|  |     Void, | ||||||
|  | }; | ||||||
|  |  | ||||||
| struct Id { | struct Id { | ||||||
|     u32 base_element : 2; |     union { | ||||||
|     u32 num_elements_minus_one : 2; |         u32 raw; | ||||||
|     u32 index : 26; |         BitField<0, 29, u32> index; | ||||||
|     u32 is_spill : 1; |         BitField<29, 1, u32> is_long; | ||||||
|     u32 is_condition_code : 1; |         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 { | class RegAlloc { | ||||||
| public: | 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); |     std::string Consume(const IR::Value& value); | ||||||
|  |  | ||||||
| @@ -40,13 +59,14 @@ private: | |||||||
|     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); | ||||||
|  |  | ||||||
|     Id Alloc(u32 num_elements, u32 alignment); |     Id Alloc(); | ||||||
|  |  | ||||||
|     void Free(Id id); |     void Free(Id id); | ||||||
|  |  | ||||||
|     size_t num_used_registers{}; |     size_t num_used_registers{}; | ||||||
|     std::bitset<NUM_REGS> register_use{}; |     std::bitset<NUM_REGS> register_use{}; | ||||||
|  |     std::bitset<NUM_REGS> register_defined{}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace Shader::Backend::GLSL | } // namespace Shader::Backend::GLSL | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user