summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-25 19:05:34 -0300
committerGravatar ReinUsesLisp2020-04-25 22:54:42 -0300
commitffc5ec6fa816b1bf56044b9d8cf5f1935abe77ee (patch)
treee74ab4b6acb3e7dac52557b7760c51f95186ec64 /src
parentdecode/register_set_predicate: Use move for shared pointers (diff)
downloadyuzu-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.cpp23
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;
17using Tegra::Shader::OpCode; 17using Tegra::Shader::OpCode;
18 18
19namespace { 19namespace {
20constexpr u64 NUM_PROGRAMMABLE_PREDICATES = 7; 20constexpr u64 NUM_CONDITION_CODES = 4;
21} 21constexpr u64 NUM_PREDICATES = 7;
22} // namespace
22 23
23u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) { 24u32 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 }