summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-25 21:56:11 -0300
committerGravatar ReinUsesLisp2020-04-25 22:55:26 -0300
commit255197e64363f9286ed145cafdeb129c85c16621 (patch)
tree976cb93129b86277b8136f21f3c7c2492bb8694d /src/video_core
parentdecode/register_set_predicate: Implement CC (diff)
downloadyuzu-255197e64363f9286ed145cafdeb129c85c16621.tar.gz
yuzu-255197e64363f9286ed145cafdeb129c85c16621.tar.xz
yuzu-255197e64363f9286ed145cafdeb129c85c16621.zip
shader/arithmetic_integer: Implement CC for IADD
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp10
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp11
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp22
-rw-r--r--src/video_core/shader/node.h2
4 files changed, 42 insertions, 3 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 0cd3ad7e1..3803a6f3a 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1870,6 +1870,14 @@ private:
1870 return GenerateBinaryInfix(operation, ">=", Type::Bool, type, type); 1870 return GenerateBinaryInfix(operation, ">=", Type::Bool, type, type);
1871 } 1871 }
1872 1872
1873 Expression LogicalAddCarry(Operation operation) {
1874 const std::string carry = code.GenerateTemporary();
1875 code.AddLine("uint {};", carry);
1876 code.AddLine("uaddCarry({}, {}, {});", VisitOperand(operation, 0).AsUint(),
1877 VisitOperand(operation, 1).AsUint(), carry);
1878 return {fmt::format("({} != 0)", carry), Type::Bool};
1879 }
1880
1873 Expression LogicalFIsNan(Operation operation) { 1881 Expression LogicalFIsNan(Operation operation) {
1874 return GenerateUnary(operation, "isnan", Type::Bool, Type::Float); 1882 return GenerateUnary(operation, "isnan", Type::Bool, Type::Float);
1875 } 1883 }
@@ -2441,6 +2449,8 @@ private:
2441 &GLSLDecompiler::LogicalNotEqual<Type::Uint>, 2449 &GLSLDecompiler::LogicalNotEqual<Type::Uint>,
2442 &GLSLDecompiler::LogicalGreaterEqual<Type::Uint>, 2450 &GLSLDecompiler::LogicalGreaterEqual<Type::Uint>,
2443 2451
2452 &GLSLDecompiler::LogicalAddCarry,
2453
2444 &GLSLDecompiler::Logical2HLessThan<false>, 2454 &GLSLDecompiler::Logical2HLessThan<false>,
2445 &GLSLDecompiler::Logical2HEqual<false>, 2455 &GLSLDecompiler::Logical2HEqual<false>,
2446 &GLSLDecompiler::Logical2HLessEqual<false>, 2456 &GLSLDecompiler::Logical2HLessEqual<false>,
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index aaa138f52..20b6ca0ad 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -1584,6 +1584,15 @@ private:
1584 return {OpCompositeConstruct(t_half, low, high), Type::HalfFloat}; 1584 return {OpCompositeConstruct(t_half, low, high), Type::HalfFloat};
1585 } 1585 }
1586 1586
1587 Expression LogicalAddCarry(Operation operation) {
1588 const Id op_a = AsUint(Visit(operation[0]));
1589 const Id op_b = AsUint(Visit(operation[1]));
1590
1591 const Id result = OpIAddCarry(TypeStruct({t_uint, t_uint}), op_a, op_b);
1592 const Id carry = OpCompositeExtract(t_uint, result, 1);
1593 return {OpINotEqual(t_bool, carry, Constant(t_uint, 0)), Type::Bool};
1594 }
1595
1587 Expression LogicalAssign(Operation operation) { 1596 Expression LogicalAssign(Operation operation) {
1588 const Node& dest = operation[0]; 1597 const Node& dest = operation[0];
1589 const Node& src = operation[1]; 1598 const Node& src = operation[1];
@@ -2518,6 +2527,8 @@ private:
2518 &SPIRVDecompiler::Binary<&Module::OpINotEqual, Type::Bool, Type::Uint>, 2527 &SPIRVDecompiler::Binary<&Module::OpINotEqual, Type::Bool, Type::Uint>,
2519 &SPIRVDecompiler::Binary<&Module::OpUGreaterThanEqual, Type::Bool, Type::Uint>, 2528 &SPIRVDecompiler::Binary<&Module::OpUGreaterThanEqual, Type::Bool, Type::Uint>,
2520 2529
2530 &SPIRVDecompiler::LogicalAddCarry,
2531
2521 &SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool2, Type::HalfFloat>, 2532 &SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool2, Type::HalfFloat>,
2522 &SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool2, Type::HalfFloat>, 2533 &SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool2, Type::HalfFloat>,
2523 &SPIRVDecompiler::Binary<&Module::OpFOrdLessThanEqual, Type::Bool2, Type::HalfFloat>, 2534 &SPIRVDecompiler::Binary<&Module::OpFOrdLessThanEqual, Type::Bool2, Type::HalfFloat>,
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index 9af8c606d..99b4b6342 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -40,10 +40,26 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
40 op_a = GetOperandAbsNegInteger(op_a, false, instr.alu_integer.negate_a, true); 40 op_a = GetOperandAbsNegInteger(op_a, false, instr.alu_integer.negate_a, true);
41 op_b = GetOperandAbsNegInteger(op_b, false, instr.alu_integer.negate_b, true); 41 op_b = GetOperandAbsNegInteger(op_b, false, instr.alu_integer.negate_b, true);
42 42
43 const Node value = Operation(OperationCode::IAdd, PRECISE, op_a, op_b); 43 Node value = Operation(OperationCode::IAdd, op_a, op_b);
44 44
45 SetInternalFlagsFromInteger(bb, value, instr.generates_cc); 45 if (instr.generates_cc) {
46 SetRegister(bb, instr.gpr0, value); 46 const Node i0 = Immediate(0);
47
48 Node zero = Operation(OperationCode::LogicalIEqual, value, i0);
49 Node sign = Operation(OperationCode::LogicalILessThan, value, i0);
50 Node carry = Operation(OperationCode::LogicalAddCarry, op_a, op_b);
51
52 Node pos_a = Operation(OperationCode::LogicalIGreaterThan, op_a, i0);
53 Node pos_b = Operation(OperationCode::LogicalIGreaterThan, op_b, i0);
54 Node pos = Operation(OperationCode::LogicalAnd, std::move(pos_a), std::move(pos_b));
55 Node overflow = Operation(OperationCode::LogicalAnd, pos, sign);
56
57 SetInternalFlag(bb, InternalFlag::Zero, std::move(zero));
58 SetInternalFlag(bb, InternalFlag::Sign, std::move(sign));
59 SetInternalFlag(bb, InternalFlag::Carry, std::move(carry));
60 SetInternalFlag(bb, InternalFlag::Overflow, std::move(overflow));
61 }
62 SetRegister(bb, instr.gpr0, std::move(value));
47 break; 63 break;
48 } 64 }
49 case OpCode::Id::IADD3_C: 65 case OpCode::Id::IADD3_C:
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 3eee961f5..3f5a7bc7a 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -132,6 +132,8 @@ enum class OperationCode {
132 LogicalUNotEqual, /// (uint a, uint b) -> bool 132 LogicalUNotEqual, /// (uint a, uint b) -> bool
133 LogicalUGreaterEqual, /// (uint a, uint b) -> bool 133 LogicalUGreaterEqual, /// (uint a, uint b) -> bool
134 134
135 LogicalAddCarry, /// (uint a, uint b) -> bool
136
135 Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 137 Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
136 Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 138 Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
137 Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 139 Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2