diff options
| author | 2020-04-25 19:05:34 -0300 | |
|---|---|---|
| committer | 2020-04-25 22:54:42 -0300 | |
| commit | ffc5ec6fa816b1bf56044b9d8cf5f1935abe77ee (patch) | |
| tree | e74ab4b6acb3e7dac52557b7760c51f95186ec64 /src | |
| parent | decode/register_set_predicate: Use move for shared pointers (diff) | |
| download | yuzu-ffc5ec6fa816b1bf56044b9d8cf5f1935abe77ee.tar.gz yuzu-ffc5ec6fa816b1bf56044b9d8cf5f1935abe77ee.tar.xz yuzu-ffc5ec6fa816b1bf56044b9d8cf5f1935abe77ee.zip | |
decode/register_set_predicate: Implement CC
P2R CC takes the state of condition codes and puts them into a register.
We already have this implemented for PR (predicates). This commit
implements CC over that.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/register_set_predicate.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/src/video_core/shader/decode/register_set_predicate.cpp b/src/video_core/shader/decode/register_set_predicate.cpp index a6733255d..6116c31aa 100644 --- a/src/video_core/shader/decode/register_set_predicate.cpp +++ b/src/video_core/shader/decode/register_set_predicate.cpp | |||
| @@ -17,15 +17,14 @@ using Tegra::Shader::Instruction; | |||
| 17 | using Tegra::Shader::OpCode; | 17 | using Tegra::Shader::OpCode; |
| 18 | 18 | ||
| 19 | namespace { | 19 | namespace { |
| 20 | constexpr u64 NUM_PROGRAMMABLE_PREDICATES = 7; | 20 | constexpr u64 NUM_CONDITION_CODES = 4; |
| 21 | } | 21 | constexpr u64 NUM_PREDICATES = 7; |
| 22 | } // namespace | ||
| 22 | 23 | ||
| 23 | u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) { | 24 | u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) { |
| 24 | const Instruction instr = {program_code[pc]}; | 25 | const Instruction instr = {program_code[pc]}; |
| 25 | const auto opcode = OpCode::Decode(instr); | 26 | const auto opcode = OpCode::Decode(instr); |
| 26 | 27 | ||
| 27 | UNIMPLEMENTED_IF(instr.p2r_r2p.mode != Tegra::Shader::R2pMode::Pr); | ||
| 28 | |||
| 29 | Node apply_mask = [this, opcode, instr] { | 28 | Node apply_mask = [this, opcode, instr] { |
| 30 | switch (opcode->get().GetId()) { | 29 | switch (opcode->get().GetId()) { |
| 31 | case OpCode::Id::R2P_IMM: | 30 | case OpCode::Id::R2P_IMM: |
| @@ -39,12 +38,18 @@ u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) { | |||
| 39 | 38 | ||
| 40 | const u32 offset = static_cast<u32>(instr.p2r_r2p.byte) * 8; | 39 | const u32 offset = static_cast<u32>(instr.p2r_r2p.byte) * 8; |
| 41 | 40 | ||
| 41 | const bool cc = instr.p2r_r2p.mode == Tegra::Shader::R2pMode::Cc; | ||
| 42 | const u64 num_entries = cc ? NUM_CONDITION_CODES : NUM_PREDICATES; | ||
| 43 | const auto get_entry = [this, cc](u64 entry) { | ||
| 44 | return cc ? GetInternalFlag(static_cast<InternalFlag>(entry)) : GetPredicate(entry); | ||
| 45 | }; | ||
| 46 | |||
| 42 | switch (opcode->get().GetId()) { | 47 | switch (opcode->get().GetId()) { |
| 43 | case OpCode::Id::R2P_IMM: { | 48 | case OpCode::Id::R2P_IMM: { |
| 44 | Node mask = GetRegister(instr.gpr8); | 49 | Node mask = GetRegister(instr.gpr8); |
| 45 | 50 | ||
| 46 | for (u64 pred = 0; pred < NUM_PROGRAMMABLE_PREDICATES; ++pred) { | 51 | for (u64 entry = 0; entry < num_entries; ++entry) { |
| 47 | const u32 shift = static_cast<u32>(pred); | 52 | const u32 shift = static_cast<u32>(entry); |
| 48 | 53 | ||
| 49 | Node apply = BitfieldExtract(apply_mask, shift, 1); | 54 | Node apply = BitfieldExtract(apply_mask, shift, 1); |
| 50 | Node condition = Operation(OperationCode::LogicalUNotEqual, apply, Immediate(0)); | 55 | Node condition = Operation(OperationCode::LogicalUNotEqual, apply, Immediate(0)); |
| @@ -52,15 +57,15 @@ u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) { | |||
| 52 | Node compare = BitfieldExtract(mask, offset + shift, 1); | 57 | Node compare = BitfieldExtract(mask, offset + shift, 1); |
| 53 | Node value = Operation(OperationCode::LogicalUNotEqual, move(compare), Immediate(0)); | 58 | Node value = Operation(OperationCode::LogicalUNotEqual, move(compare), Immediate(0)); |
| 54 | 59 | ||
| 55 | Node code = Operation(OperationCode::LogicalAssign, GetPredicate(pred), move(value)); | 60 | Node code = Operation(OperationCode::LogicalAssign, get_entry(entry), move(value)); |
| 56 | bb.push_back(Conditional(condition, {move(code)})); | 61 | bb.push_back(Conditional(condition, {move(code)})); |
| 57 | } | 62 | } |
| 58 | break; | 63 | break; |
| 59 | } | 64 | } |
| 60 | case OpCode::Id::P2R_IMM: { | 65 | case OpCode::Id::P2R_IMM: { |
| 61 | Node value = Immediate(0); | 66 | Node value = Immediate(0); |
| 62 | for (u64 pred = 0; pred < NUM_PROGRAMMABLE_PREDICATES; ++pred) { | 67 | for (u64 entry = 0; entry < num_entries; ++entry) { |
| 63 | Node bit = Operation(OperationCode::Select, GetPredicate(pred), Immediate(1U << pred), | 68 | Node bit = Operation(OperationCode::Select, get_entry(entry), Immediate(1U << entry), |
| 64 | Immediate(0)); | 69 | Immediate(0)); |
| 65 | value = Operation(OperationCode::UBitwiseOr, move(value), move(bit)); | 70 | value = Operation(OperationCode::UBitwiseOr, move(value), move(bit)); |
| 66 | } | 71 | } |