mirror of
https://github.com/yuzu-mirror/yuzu
synced 2024-12-11 10:42:30 +00:00
Implemented Internal Flags
This commit is contained in:
parent
e4bb759c4b
commit
567a5524b9
1 changed files with 35 additions and 13 deletions
|
@ -235,6 +235,14 @@ private:
|
||||||
const std::string& suffix;
|
const std::string& suffix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class InternalFlag : u64 {
|
||||||
|
ZeroFlag = 0,
|
||||||
|
CarryFlag = 1,
|
||||||
|
OverflowFlag = 2,
|
||||||
|
NaNFlag = 3,
|
||||||
|
Amount
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to manage shader registers that are emulated with GLSL. This class keeps track of the state
|
* Used to manage shader registers that are emulated with GLSL. This class keeps track of the state
|
||||||
* of all registers (e.g. whether they are currently being used as Floats or Integers), and
|
* of all registers (e.g. whether they are currently being used as Floats or Integers), and
|
||||||
|
@ -328,13 +336,19 @@ public:
|
||||||
void SetRegisterToInteger(const Register& reg, bool is_signed, u64 elem,
|
void SetRegisterToInteger(const Register& reg, bool is_signed, u64 elem,
|
||||||
const std::string& value, u64 dest_num_components,
|
const std::string& value, u64 dest_num_components,
|
||||||
u64 value_num_components, bool is_saturated = false,
|
u64 value_num_components, bool is_saturated = false,
|
||||||
u64 dest_elem = 0, Register::Size size = Register::Size::Word) {
|
u64 dest_elem = 0, Register::Size size = Register::Size::Word,
|
||||||
|
bool sets_cc = false) {
|
||||||
ASSERT_MSG(!is_saturated, "Unimplemented");
|
ASSERT_MSG(!is_saturated, "Unimplemented");
|
||||||
|
|
||||||
const std::string func{is_signed ? "intBitsToFloat" : "uintBitsToFloat"};
|
const std::string func{is_signed ? "intBitsToFloat" : "uintBitsToFloat"};
|
||||||
|
|
||||||
SetRegister(reg, elem, func + '(' + ConvertIntegerSize(value, size) + ')',
|
SetRegister(reg, elem, func + '(' + ConvertIntegerSize(value, size) + ')',
|
||||||
dest_num_components, value_num_components, dest_elem);
|
dest_num_components, value_num_components, dest_elem);
|
||||||
|
|
||||||
|
if (sets_cc) {
|
||||||
|
const std::string zero_condition = "( " + ConvertIntegerSize(value, size) + " == 0 )";
|
||||||
|
SetInternalFlag(InternalFlag::ZeroFlag, zero_condition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -352,12 +366,23 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetControlCode(const Tegra::Shader::ControlCode cc) const {
|
std::string GetControlCode(const Tegra::Shader::ControlCode cc) const {
|
||||||
const u32 code = static_cast<u32>(cc);
|
switch (cc) {
|
||||||
return "controlCode_" + std::to_string(code) + suffix;
|
case Tegra::Shader::ControlCode::NEU:
|
||||||
|
return "!(" + GetInternalFlag(InternalFlag::ZeroFlag) + ')';
|
||||||
|
default:
|
||||||
|
LOG_CRITICAL(HW_GPU, "Unimplemented Control Code {}", static_cast<u32>(cc));
|
||||||
|
UNREACHABLE();
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetControlCode(const Tegra::Shader::ControlCode cc, const std::string& value) const {
|
std::string GetInternalFlag(const InternalFlag ii) const {
|
||||||
shader.AddLine(GetControlCode(cc) + " = " + value + ';');
|
const u32 code = static_cast<u32>(ii);
|
||||||
|
return "internalFlag_" + std::to_string(code) + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetInternalFlag(const InternalFlag ii, const std::string& value) const {
|
||||||
|
shader.AddLine(GetInternalFlag(ii) + " = " + value + ';');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -423,9 +448,9 @@ public:
|
||||||
}
|
}
|
||||||
declarations.AddNewLine();
|
declarations.AddNewLine();
|
||||||
|
|
||||||
for (u32 cc = 0; cc < 32; cc++) {
|
for (u32 ii = 0; ii < static_cast<u64>(InternalFlag::Amount); ii++) {
|
||||||
const Tegra::Shader::ControlCode code = static_cast<Tegra::Shader::ControlCode>(cc);
|
const InternalFlag code = static_cast<InternalFlag>(ii);
|
||||||
declarations.AddLine("bool " + GetControlCode(code) + " = false;");
|
declarations.AddLine("bool " + GetInternalFlag(code) + " = false;");
|
||||||
}
|
}
|
||||||
declarations.AddNewLine();
|
declarations.AddNewLine();
|
||||||
|
|
||||||
|
@ -1655,11 +1680,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1,
|
regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1,
|
||||||
1, instr.alu.saturate_d, 0, instr.conversion.dest_size);
|
1, instr.alu.saturate_d, 0, instr.conversion.dest_size,
|
||||||
if (instr.generates_cc.Value() != 0) {
|
instr.generates_cc.Value() != 0);
|
||||||
const std::string neucondition = "( " + op_a + " != 0 )";
|
|
||||||
regs.SetControlCode(Tegra::Shader::ControlCode::NEU, neucondition);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpCode::Id::I2F_R:
|
case OpCode::Id::I2F_R:
|
||||||
|
|
Loading…
Reference in a new issue