summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-06-02 18:52:07 -0300
committerGravatar ReinUsesLisp2019-06-07 02:18:27 -0300
commitfe8e6618f2907a9262d69232ef0e2d5d58cbc6e0 (patch)
tree308d278996e18558ab049daa01b4873b08b799e8 /src/video_core/shader/decode
parentMerge pull request #2558 from ReinUsesLisp/shader-nodes (diff)
downloadyuzu-fe8e6618f2907a9262d69232ef0e2d5d58cbc6e0.tar.gz
yuzu-fe8e6618f2907a9262d69232ef0e2d5d58cbc6e0.tar.xz
yuzu-fe8e6618f2907a9262d69232ef0e2d5d58cbc6e0.zip
shader: Split SSY and PBK stack
Hardware testing revealed that SSY and PBK push to a different stack, allowing code like this: SSY label1; PBK label2; SYNC; label1: PBK; label2: EXIT;
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/other.cpp18
1 files changed, 8 insertions, 10 deletions
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index 6fc07f213..d46a8ab82 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -109,22 +109,20 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
109 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, 109 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
110 "Constant buffer flow is not supported"); 110 "Constant buffer flow is not supported");
111 111
112 // The SSY opcode tells the GPU where to re-converge divergent execution paths, it sets the 112 // The SSY opcode tells the GPU where to re-converge divergent execution paths with SYNC.
113 // target of the jump that the SYNC instruction will make. The SSY opcode has a similar
114 // structure to the BRA opcode.
115 const u32 target = pc + instr.bra.GetBranchTarget(); 113 const u32 target = pc + instr.bra.GetBranchTarget();
116 bb.push_back(Operation(OperationCode::PushFlowStack, Immediate(target))); 114 bb.push_back(
115 Operation(OperationCode::PushFlowStack, MetaStackClass::Ssy, Immediate(target)));
117 break; 116 break;
118 } 117 }
119 case OpCode::Id::PBK: { 118 case OpCode::Id::PBK: {
120 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, 119 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
121 "Constant buffer PBK is not supported"); 120 "Constant buffer PBK is not supported");
122 121
123 // PBK pushes to a stack the address where BRK will jump to. This shares stack with SSY but 122 // PBK pushes to a stack the address where BRK will jump to.
124 // using SYNC on a PBK address will kill the shader execution. We don't emulate this because
125 // it's very unlikely a driver will emit such invalid shader.
126 const u32 target = pc + instr.bra.GetBranchTarget(); 123 const u32 target = pc + instr.bra.GetBranchTarget();
127 bb.push_back(Operation(OperationCode::PushFlowStack, Immediate(target))); 124 bb.push_back(
125 Operation(OperationCode::PushFlowStack, MetaStackClass::Pbk, Immediate(target)));
128 break; 126 break;
129 } 127 }
130 case OpCode::Id::SYNC: { 128 case OpCode::Id::SYNC: {
@@ -133,7 +131,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
133 static_cast<u32>(cc)); 131 static_cast<u32>(cc));
134 132
135 // The SYNC opcode jumps to the address previously set by the SSY opcode 133 // The SYNC opcode jumps to the address previously set by the SSY opcode
136 bb.push_back(Operation(OperationCode::PopFlowStack)); 134 bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Ssy));
137 break; 135 break;
138 } 136 }
139 case OpCode::Id::BRK: { 137 case OpCode::Id::BRK: {
@@ -142,7 +140,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
142 static_cast<u32>(cc)); 140 static_cast<u32>(cc));
143 141
144 // The BRK opcode jumps to the address previously set by the PBK opcode 142 // The BRK opcode jumps to the address previously set by the PBK opcode
145 bb.push_back(Operation(OperationCode::PopFlowStack)); 143 bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Pbk));
146 break; 144 break;
147 } 145 }
148 case OpCode::Id::IPA: { 146 case OpCode::Id::IPA: {