summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-12-20 17:41:27 -0300
committerGravatar ReinUsesLisp2019-12-20 17:55:42 -0300
commitcf27b59493501787320764889a0375711c3f68e1 (patch)
tree023528e2ffbae8c335dc24f836ccef5e98f261b1 /src
parentMerge pull request #3234 from ReinUsesLisp/i2f-u8-selector (diff)
downloadyuzu-cf27b59493501787320764889a0375711c3f68e1.tar.gz
yuzu-cf27b59493501787320764889a0375711c3f68e1.tar.xz
yuzu-cf27b59493501787320764889a0375711c3f68e1.zip
shader/r2p: Refactor P2R to support P2R
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h4
-rw-r--r--src/video_core/shader/decode/register_set_predicate.cpp46
2 files changed, 33 insertions, 17 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index dfb12cd2d..269ed6127 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -1051,7 +1051,7 @@ union Instruction {
1051 BitField<40, 1, R2pMode> mode; 1051 BitField<40, 1, R2pMode> mode;
1052 BitField<41, 2, u64> byte; 1052 BitField<41, 2, u64> byte;
1053 BitField<20, 7, u64> immediate_mask; 1053 BitField<20, 7, u64> immediate_mask;
1054 } r2p; 1054 } p2r_r2p;
1055 1055
1056 union { 1056 union {
1057 BitField<39, 3, u64> pred39; 1057 BitField<39, 3, u64> pred39;
@@ -1801,6 +1801,7 @@ public:
1801 PSET, 1801 PSET,
1802 CSETP, 1802 CSETP,
1803 R2P_IMM, 1803 R2P_IMM,
1804 P2R_IMM,
1804 XMAD_IMM, 1805 XMAD_IMM,
1805 XMAD_CR, 1806 XMAD_CR,
1806 XMAD_RC, 1807 XMAD_RC,
@@ -2106,6 +2107,7 @@ private:
2106 INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), 2107 INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
2107 INST("010100001010----", Id::CSETP, Type::PredicateSetPredicate, "CSETP"), 2108 INST("010100001010----", Id::CSETP, Type::PredicateSetPredicate, "CSETP"),
2108 INST("0011100-11110---", Id::R2P_IMM, Type::RegisterSetPredicate, "R2P_IMM"), 2109 INST("0011100-11110---", Id::R2P_IMM, Type::RegisterSetPredicate, "R2P_IMM"),
2110 INST("0011100-11101---", Id::P2R_IMM, Type::RegisterSetPredicate, "P2R_IMM"),
2109 INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), 2111 INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"),
2110 INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), 2112 INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"),
2111 INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"), 2113 INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"),
diff --git a/src/video_core/shader/decode/register_set_predicate.cpp b/src/video_core/shader/decode/register_set_predicate.cpp
index e6c9d287e..ff8245020 100644
--- a/src/video_core/shader/decode/register_set_predicate.cpp
+++ b/src/video_core/shader/decode/register_set_predicate.cpp
@@ -13,37 +13,51 @@ namespace VideoCommon::Shader {
13using Tegra::Shader::Instruction; 13using Tegra::Shader::Instruction;
14using Tegra::Shader::OpCode; 14using Tegra::Shader::OpCode;
15 15
16namespace {
17constexpr u64 NUM_PROGRAMMABLE_PREDICATES = 7;
18}
19
16u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) { 20u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) {
17 const Instruction instr = {program_code[pc]}; 21 const Instruction instr = {program_code[pc]};
18 const auto opcode = OpCode::Decode(instr); 22 const auto opcode = OpCode::Decode(instr);
19 23
20 UNIMPLEMENTED_IF(instr.r2p.mode != Tegra::Shader::R2pMode::Pr); 24 UNIMPLEMENTED_IF(instr.p2r_r2p.mode != Tegra::Shader::R2pMode::Pr);
21 25
22 const Node apply_mask = [&]() { 26 const Node apply_mask = [&] {
23 switch (opcode->get().GetId()) { 27 switch (opcode->get().GetId()) {
24 case OpCode::Id::R2P_IMM: 28 case OpCode::Id::R2P_IMM:
25 return Immediate(static_cast<u32>(instr.r2p.immediate_mask)); 29 case OpCode::Id::P2R_IMM:
30 return Immediate(static_cast<u32>(instr.p2r_r2p.immediate_mask));
26 default: 31 default:
27 UNREACHABLE(); 32 UNREACHABLE();
28 return Immediate(static_cast<u32>(instr.r2p.immediate_mask)); 33 return Immediate(0);
29 } 34 }
30 }(); 35 }();
31 const Node mask = GetRegister(instr.gpr8);
32 const auto offset = static_cast<u32>(instr.r2p.byte) * 8;
33 36
34 constexpr u32 programmable_preds = 7; 37 switch (opcode->get().GetId()) {
35 for (u64 pred = 0; pred < programmable_preds; ++pred) { 38 case OpCode::Id::R2P_IMM: {
36 const auto shift = static_cast<u32>(pred); 39 const Node mask = GetRegister(instr.gpr8);
40 const auto offset = static_cast<u32>(instr.p2r_r2p.byte) * 8;
41
42 for (u64 pred = 0; pred < NUM_PROGRAMMABLE_PREDICATES; ++pred) {
43 const auto shift = static_cast<u32>(pred);
37 44
38 const Node apply_compare = BitfieldExtract(apply_mask, shift, 1); 45 const Node apply_compare = BitfieldExtract(apply_mask, shift, 1);
39 const Node condition = 46 const Node condition =
40 Operation(OperationCode::LogicalUNotEqual, apply_compare, Immediate(0)); 47 Operation(OperationCode::LogicalUNotEqual, apply_compare, Immediate(0));
41 48
42 const Node value_compare = BitfieldExtract(mask, offset + shift, 1); 49 const Node value_compare = BitfieldExtract(mask, offset + shift, 1);
43 const Node value = Operation(OperationCode::LogicalUNotEqual, value_compare, Immediate(0)); 50 const Node value =
51 Operation(OperationCode::LogicalUNotEqual, value_compare, Immediate(0));
44 52
45 const Node code = Operation(OperationCode::LogicalAssign, GetPredicate(pred), value); 53 const Node code = Operation(OperationCode::LogicalAssign, GetPredicate(pred), value);
46 bb.push_back(Conditional(condition, {code})); 54 bb.push_back(Conditional(condition, {code}));
55 }
56 break;
57 }
58 default:
59 UNIMPLEMENTED_MSG("Unhandled P2R/R2R instruction: {}", opcode->get().GetName());
60 break;
47 } 61 }
48 62
49 return pc; 63 return pc;