diff options
| author | 2018-12-24 00:51:52 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:53 -0300 | |
| commit | b11e0b94c7ce0d965a6149c98c48cda967ec3c04 (patch) | |
| tree | 98fcb050f6d94ae33d1a26a020834d5c1bdf6b33 /src | |
| parent | shader_decode: Rework HSETP2 (diff) | |
| download | yuzu-b11e0b94c7ce0d965a6149c98c48cda967ec3c04.tar.gz yuzu-b11e0b94c7ce0d965a6149c98c48cda967ec3c04.tar.xz yuzu-b11e0b94c7ce0d965a6149c98c48cda967ec3c04.zip | |
shader_decode: Implement HSET2
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/half_set.cpp | 44 | ||||
| -rw-r--r-- | src/video_core/shader/glsl_decompiler.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 1 |
3 files changed, 50 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/half_set.cpp b/src/video_core/shader/decode/half_set.cpp index af363d5d2..b4ac06144 100644 --- a/src/video_core/shader/decode/half_set.cpp +++ b/src/video_core/shader/decode/half_set.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | ||
| 6 | |||
| 5 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 6 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 7 | #include "video_core/engines/shader_bytecode.h" | 9 | #include "video_core/engines/shader_bytecode.h" |
| @@ -16,7 +18,47 @@ u32 ShaderIR::DecodeHalfSet(BasicBlock& bb, u32 pc) { | |||
| 16 | const Instruction instr = {program_code[pc]}; | 18 | const Instruction instr = {program_code[pc]}; |
| 17 | const auto opcode = OpCode::Decode(instr); | 19 | const auto opcode = OpCode::Decode(instr); |
| 18 | 20 | ||
| 19 | UNIMPLEMENTED(); | 21 | UNIMPLEMENTED_IF(instr.hset2.ftz != 0); |
| 22 | |||
| 23 | // instr.hset2.type_a | ||
| 24 | // instr.hset2.type_b | ||
| 25 | Node op_a = GetRegister(instr.gpr8); | ||
| 26 | Node op_b = [&]() { | ||
| 27 | switch (opcode->get().GetId()) { | ||
| 28 | case OpCode::Id::HSET2_R: | ||
| 29 | return GetRegister(instr.gpr20); | ||
| 30 | default: | ||
| 31 | UNREACHABLE(); | ||
| 32 | return Immediate(0); | ||
| 33 | } | ||
| 34 | }(); | ||
| 35 | |||
| 36 | op_a = GetOperandAbsNegHalf(op_a, instr.hset2.abs_a, instr.hset2.negate_a); | ||
| 37 | op_b = GetOperandAbsNegHalf(op_b, instr.hset2.abs_b, instr.hset2.negate_b); | ||
| 38 | |||
| 39 | const Node second_pred = GetPredicate(instr.hset2.pred39, instr.hset2.neg_pred); | ||
| 40 | |||
| 41 | MetaHalfArithmetic meta{false, {instr.hset2.type_a, instr.hset2.type_b}}; | ||
| 42 | const Node comparison_pair = GetPredicateComparisonHalf(instr.hset2.cond, meta, op_a, op_b); | ||
| 43 | |||
| 44 | const OperationCode combiner = GetPredicateCombiner(instr.hset2.op); | ||
| 45 | |||
| 46 | // HSET2 operates on each half float in the pack. | ||
| 47 | std::array<Node, 2> values; | ||
| 48 | for (u32 i = 0; i < 2; ++i) { | ||
| 49 | const u32 raw_value = instr.hset2.bf ? 0x3c00 : 0xffff; | ||
| 50 | const Node true_value = Immediate(raw_value << (i * 16)); | ||
| 51 | const Node false_value = Immediate(0); | ||
| 52 | |||
| 53 | const Node comparison = | ||
| 54 | Operation(OperationCode::LogicalPick2, comparison_pair, Immediate(i)); | ||
| 55 | const Node predicate = Operation(combiner, comparison, second_pred); | ||
| 56 | |||
| 57 | values[i] = Operation(OperationCode::Select, NO_PRECISE, predicate, true_value, false_value); | ||
| 58 | } | ||
| 59 | |||
| 60 | const Node value = Operation(OperationCode::UBitwiseOr, NO_PRECISE, values[0], values[1]); | ||
| 61 | SetRegister(bb, instr.gpr0, value); | ||
| 20 | 62 | ||
| 21 | return pc; | 63 | return pc; |
| 22 | } | 64 | } |
diff --git a/src/video_core/shader/glsl_decompiler.cpp b/src/video_core/shader/glsl_decompiler.cpp index 8a2cc3c31..2e9323df7 100644 --- a/src/video_core/shader/glsl_decompiler.cpp +++ b/src/video_core/shader/glsl_decompiler.cpp | |||
| @@ -1012,6 +1012,11 @@ private: | |||
| 1012 | return GenerateUnary(operation, "!", Type::Bool, Type::Bool, false); | 1012 | return GenerateUnary(operation, "!", Type::Bool, Type::Bool, false); |
| 1013 | } | 1013 | } |
| 1014 | 1014 | ||
| 1015 | std::string LogicalPick2(Operation operation) { | ||
| 1016 | const std::string pair = VisitOperand(operation, 0, Type::Bool2); | ||
| 1017 | return pair + '[' + VisitOperand(operation, 1, Type::Uint) + ']'; | ||
| 1018 | } | ||
| 1019 | |||
| 1015 | std::string LogicalAll2(Operation operation) { | 1020 | std::string LogicalAll2(Operation operation) { |
| 1016 | return GenerateUnary(operation, "all", Type::Bool, Type::Bool2); | 1021 | return GenerateUnary(operation, "all", Type::Bool, Type::Bool2); |
| 1017 | } | 1022 | } |
| @@ -1306,6 +1311,7 @@ private: | |||
| 1306 | &LogicalOr, | 1311 | &LogicalOr, |
| 1307 | &LogicalXor, | 1312 | &LogicalXor, |
| 1308 | &LogicalNegate, | 1313 | &LogicalNegate, |
| 1314 | &LogicalPick2, | ||
| 1309 | &LogicalAll2, | 1315 | &LogicalAll2, |
| 1310 | &LogicalAny2, | 1316 | &LogicalAny2, |
| 1311 | 1317 | ||
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 5ef0a7779..69ff18058 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -122,6 +122,7 @@ enum class OperationCode { | |||
| 122 | LogicalOr, /// (bool a, bool b) -> bool | 122 | LogicalOr, /// (bool a, bool b) -> bool |
| 123 | LogicalXor, /// (bool a, bool b) -> bool | 123 | LogicalXor, /// (bool a, bool b) -> bool |
| 124 | LogicalNegate, /// (bool a) -> bool | 124 | LogicalNegate, /// (bool a) -> bool |
| 125 | LogicalPick2, /// (bool2 pair, uint index) -> bool | ||
| 125 | LogicalAll2, /// (bool2 a) -> bool | 126 | LogicalAll2, /// (bool2 a) -> bool |
| 126 | LogicalAny2, /// (bool2 a) -> bool | 127 | LogicalAny2, /// (bool2 a) -> bool |
| 127 | 128 | ||