diff options
| author | 2019-06-02 18:52:07 -0300 | |
|---|---|---|
| committer | 2019-06-07 02:18:27 -0300 | |
| commit | fe8e6618f2907a9262d69232ef0e2d5d58cbc6e0 (patch) | |
| tree | 308d278996e18558ab049daa01b4873b08b799e8 /src/video_core/shader/decode | |
| parent | Merge pull request #2558 from ReinUsesLisp/shader-nodes (diff) | |
| download | yuzu-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.cpp | 18 |
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: { |