summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-08-28 21:09:33 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-08-28 21:09:33 +0200
commite3534700d79aedd696f36430ea2a632506f2b1e3 (patch)
tree92593bd4554714e738387fb05a8d1dd883066bbf /src/video_core/shader
parentshader_ir/conversion: Implement F2I F16 Ra.H1 (diff)
downloadyuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.tar
yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.tar.gz
yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.tar.bz2
yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.tar.lz
yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.tar.xz
yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.tar.zst
yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.zip
Diffstat (limited to 'src/video_core/shader')
-rw-r--r--src/video_core/shader/decode/conversion.cpp34
1 files changed, 16 insertions, 18 deletions
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index cf328aff8..32facd6ba 100644
--- a/src/video_core/shader/decode/conversion.cpp
+++ b/src/video_core/shader/decode/conversion.cpp
@@ -14,6 +14,12 @@ using Tegra::Shader::Instruction;
using Tegra::Shader::OpCode;
using Tegra::Shader::Register;
+namespace {
+constexpr OperationCode GetFloatSelector(u64 selector) {
+ return selector == 0 ? OperationCode::FCastHalf0 : OperationCode::FCastHalf1;
+}
+} // Anonymous namespace
+
u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
const Instruction instr = {program_code[pc]};
const auto opcode = OpCode::Decode(instr);
@@ -22,7 +28,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
case OpCode::Id::I2I_R:
case OpCode::Id::I2I_C:
case OpCode::Id::I2I_IMM: {
- UNIMPLEMENTED_IF(instr.conversion.selector.Value());
+ UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);
UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word);
UNIMPLEMENTED_IF(instr.alu.saturate_d);
@@ -57,7 +63,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
case OpCode::Id::I2F_R:
case OpCode::Id::I2F_C:
case OpCode::Id::I2F_IMM: {
- UNIMPLEMENTED_IF(instr.conversion.selector.Value());
+ UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);
UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
UNIMPLEMENTED_IF_MSG(instr.generates_cc,
"Condition codes generation in I2F is not implemented");
@@ -93,7 +99,6 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
case OpCode::Id::F2F_R:
case OpCode::Id::F2F_C:
case OpCode::Id::F2F_IMM: {
- UNIMPLEMENTED_IF(instr.conversion.selector.Value());
UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long);
UNIMPLEMENTED_IF_MSG(instr.generates_cc,
@@ -114,8 +119,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
}();
if (instr.conversion.src_size == Register::Size::Short) {
- // TODO: figure where extract is sey in the encoding
- value = Operation(OperationCode::FCastHalf0, PRECISE, value);
+ value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE,
+ std::move(value));
+ } else {
+ ASSERT(instr.conversion.float_src.selector == 0);
}
value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);
@@ -170,19 +177,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
}();
if (instr.conversion.src_size == Register::Size::Short) {
- const OperationCode cast = [instr] {
- switch (instr.conversion.selector) {
- case 0:
- return OperationCode::FCastHalf0;
- case 1:
- return OperationCode::FCastHalf1;
- default:
- UNREACHABLE_MSG("Invalid selector={}",
- static_cast<u32>(instr.conversion.selector));
- return OperationCode::FCastHalf0;
- }
- }();
- value = Operation(cast, NO_PRECISE, std::move(value));
+ value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE,
+ std::move(value));
+ } else {
+ ASSERT(instr.conversion.float_src.selector == 0);
}
value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);