diff options
| author | 2020-04-25 21:56:11 -0300 | |
|---|---|---|
| committer | 2020-04-25 22:55:26 -0300 | |
| commit | 255197e64363f9286ed145cafdeb129c85c16621 (patch) | |
| tree | 976cb93129b86277b8136f21f3c7c2492bb8694d /src/video_core | |
| parent | decode/register_set_predicate: Implement CC (diff) | |
| download | yuzu-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.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 2 |
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 |