glsl: Reusable typed variables. IADD32
This commit is contained in:
parent
faf4cd72c5
commit
e221baccdd
|
@ -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,8 +33,8 @@ 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,
|
||||
(u32_offset / 4) % 4);
|
||||
ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}][{}]);", *inst, binding.U32(), u32_offset / 16,
|
||||
(u32_offset / 4) % 4);
|
||||
}
|
||||
|
||||
void EmitGetCbufF32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding,
|
||||
|
|
|
@ -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) {
|
||||
for (size_t reg = 0; reg < NUM_REGS; ++reg) {
|
||||
if (register_use[reg]) {
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
register_use[reg] = true;
|
||||
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;
|
||||
}
|
||||
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,
|
||||
};
|
||||
}
|
||||
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