diff options
| author | 2018-10-16 17:11:26 -0300 | |
|---|---|---|
| committer | 2018-10-17 21:30:45 -0300 | |
| commit | 41fb25349a82ba0657e41e4597ac9e415f6e442a (patch) | |
| tree | 529a948ab657eef57b05c0cb932269374a6b5df4 /src | |
| parent | Merge pull request #1443 from DarkLordZach/lower-loader-logs-1 (diff) | |
| download | yuzu-41fb25349a82ba0657e41e4597ac9e415f6e442a.tar.gz yuzu-41fb25349a82ba0657e41e4597ac9e415f6e442a.tar.xz yuzu-41fb25349a82ba0657e41e4597ac9e415f6e442a.zip | |
gl_shader_decompiler: Implement PBK and BRK
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 55 |
2 files changed, 43 insertions, 22 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index f356f9a03..8c8d65769 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1095,11 +1095,13 @@ public: | |||
| 1095 | KIL, | 1095 | KIL, |
| 1096 | SSY, | 1096 | SSY, |
| 1097 | SYNC, | 1097 | SYNC, |
| 1098 | BRK, | ||
| 1098 | DEPBAR, | 1099 | DEPBAR, |
| 1099 | BFE_C, | 1100 | BFE_C, |
| 1100 | BFE_R, | 1101 | BFE_R, |
| 1101 | BFE_IMM, | 1102 | BFE_IMM, |
| 1102 | BRA, | 1103 | BRA, |
| 1104 | PBK, | ||
| 1103 | LD_A, | 1105 | LD_A, |
| 1104 | LD_C, | 1106 | LD_C, |
| 1105 | ST_A, | 1107 | ST_A, |
| @@ -1239,7 +1241,7 @@ public: | |||
| 1239 | /// conditionally executed). | 1241 | /// conditionally executed). |
| 1240 | static bool IsPredicatedInstruction(Id opcode) { | 1242 | static bool IsPredicatedInstruction(Id opcode) { |
| 1241 | // TODO(Subv): Add the rest of unpredicated instructions. | 1243 | // TODO(Subv): Add the rest of unpredicated instructions. |
| 1242 | return opcode != Id::SSY; | 1244 | return opcode != Id::SSY && opcode != Id::PBK; |
| 1243 | } | 1245 | } |
| 1244 | 1246 | ||
| 1245 | class Matcher { | 1247 | class Matcher { |
| @@ -1335,9 +1337,11 @@ private: | |||
| 1335 | #define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) | 1337 | #define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) |
| 1336 | INST("111000110011----", Id::KIL, Type::Flow, "KIL"), | 1338 | INST("111000110011----", Id::KIL, Type::Flow, "KIL"), |
| 1337 | INST("111000101001----", Id::SSY, Type::Flow, "SSY"), | 1339 | INST("111000101001----", Id::SSY, Type::Flow, "SSY"), |
| 1340 | INST("111000101010----", Id::PBK, Type::Flow, "PBK"), | ||
| 1338 | INST("111000100100----", Id::BRA, Type::Flow, "BRA"), | 1341 | INST("111000100100----", Id::BRA, Type::Flow, "BRA"), |
| 1342 | INST("1111000011111---", Id::SYNC, Type::Flow, "SYNC"), | ||
| 1343 | INST("111000110100---", Id::BRK, Type::Flow, "BRK"), | ||
| 1339 | INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"), | 1344 | INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"), |
| 1340 | INST("1111000011111---", Id::SYNC, Type::Synch, "SYNC"), | ||
| 1341 | INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), | 1345 | INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), |
| 1342 | INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), | 1346 | INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), |
| 1343 | INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"), | 1347 | INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"), |
| @@ -1463,4 +1467,4 @@ private: | |||
| 1463 | } | 1467 | } |
| 1464 | }; | 1468 | }; |
| 1465 | 1469 | ||
| 1466 | } // namespace Tegra::Shader | 1470 | } // namespace Tegra::Shader \ No newline at end of file |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index ca063d90d..db52841f3 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -165,10 +165,11 @@ private: | |||
| 165 | const ExitMethod jmp = Scan(target, end, labels); | 165 | const ExitMethod jmp = Scan(target, end, labels); |
| 166 | return exit_method = ParallelExit(no_jmp, jmp); | 166 | return exit_method = ParallelExit(no_jmp, jmp); |
| 167 | } | 167 | } |
| 168 | case OpCode::Id::SSY: { | 168 | case OpCode::Id::SSY: |
| 169 | // The SSY instruction uses a similar encoding as the BRA instruction. | 169 | case OpCode::Id::PBK: { |
| 170 | // The SSY and PBK use a similar encoding as the BRA instruction. | ||
| 170 | ASSERT_MSG(instr.bra.constant_buffer == 0, | 171 | ASSERT_MSG(instr.bra.constant_buffer == 0, |
| 171 | "Constant buffer SSY is not supported"); | 172 | "Constant buffer branching is not supported"); |
| 172 | const u32 target = offset + instr.bra.GetBranchTarget(); | 173 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 173 | labels.insert(target); | 174 | labels.insert(target); |
| 174 | // Continue scanning for an exit method. | 175 | // Continue scanning for an exit method. |
| @@ -1153,27 +1154,27 @@ private: | |||
| 1153 | } | 1154 | } |
| 1154 | 1155 | ||
| 1155 | /* | 1156 | /* |
| 1156 | * Emits code to push the input target address to the SSY address stack, incrementing the stack | 1157 | * Emits code to push the input target address to the flow address stack, incrementing the stack |
| 1157 | * top. | 1158 | * top. |
| 1158 | */ | 1159 | */ |
| 1159 | void EmitPushToSSYStack(u32 target) { | 1160 | void EmitPushToFlowStack(u32 target) { |
| 1160 | shader.AddLine('{'); | 1161 | shader.AddLine('{'); |
| 1161 | ++shader.scope; | 1162 | ++shader.scope; |
| 1162 | shader.AddLine("ssy_stack[ssy_stack_top] = " + std::to_string(target) + "u;"); | 1163 | shader.AddLine("flow_stack[flow_stack_top] = " + std::to_string(target) + "u;"); |
| 1163 | shader.AddLine("ssy_stack_top++;"); | 1164 | shader.AddLine("flow_stack_top++;"); |
| 1164 | --shader.scope; | 1165 | --shader.scope; |
| 1165 | shader.AddLine('}'); | 1166 | shader.AddLine('}'); |
| 1166 | } | 1167 | } |
| 1167 | 1168 | ||
| 1168 | /* | 1169 | /* |
| 1169 | * Emits code to pop an address from the SSY address stack, setting the jump address to the | 1170 | * Emits code to pop an address from the flow address stack, setting the jump address to the |
| 1170 | * popped address and decrementing the stack top. | 1171 | * popped address and decrementing the stack top. |
| 1171 | */ | 1172 | */ |
| 1172 | void EmitPopFromSSYStack() { | 1173 | void EmitPopFromFlowStack() { |
| 1173 | shader.AddLine('{'); | 1174 | shader.AddLine('{'); |
| 1174 | ++shader.scope; | 1175 | ++shader.scope; |
| 1175 | shader.AddLine("ssy_stack_top--;"); | 1176 | shader.AddLine("flow_stack_top--;"); |
| 1176 | shader.AddLine("jmp_to = ssy_stack[ssy_stack_top];"); | 1177 | shader.AddLine("jmp_to = flow_stack[flow_stack_top];"); |
| 1177 | shader.AddLine("break;"); | 1178 | shader.AddLine("break;"); |
| 1178 | --shader.scope; | 1179 | --shader.scope; |
| 1179 | shader.AddLine('}'); | 1180 | shader.AddLine('}'); |
| @@ -2933,16 +2934,32 @@ private: | |||
| 2933 | // The SSY opcode tells the GPU where to re-converge divergent execution paths, it | 2934 | // The SSY opcode tells the GPU where to re-converge divergent execution paths, it |
| 2934 | // sets the target of the jump that the SYNC instruction will make. The SSY opcode | 2935 | // sets the target of the jump that the SYNC instruction will make. The SSY opcode |
| 2935 | // has a similar structure to the BRA opcode. | 2936 | // has a similar structure to the BRA opcode. |
| 2936 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); | 2937 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer flow is not supported"); |
| 2937 | 2938 | ||
| 2938 | const u32 target = offset + instr.bra.GetBranchTarget(); | 2939 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 2939 | EmitPushToSSYStack(target); | 2940 | EmitPushToFlowStack(target); |
| 2941 | break; | ||
| 2942 | } | ||
| 2943 | case OpCode::Id::PBK: { | ||
| 2944 | // PBK pushes to a stack the address where BRK will jump to. This shares stack with | ||
| 2945 | // SSY but using SYNC on a PBK address will kill the shader execution. We don't | ||
| 2946 | // emulate this because it's very unlikely a driver will emit such invalid shader. | ||
| 2947 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer PBK is not supported"); | ||
| 2948 | |||
| 2949 | const u32 target = offset + instr.bra.GetBranchTarget(); | ||
| 2950 | EmitPushToFlowStack(target); | ||
| 2940 | break; | 2951 | break; |
| 2941 | } | 2952 | } |
| 2942 | case OpCode::Id::SYNC: { | 2953 | case OpCode::Id::SYNC: { |
| 2943 | // The SYNC opcode jumps to the address previously set by the SSY opcode | 2954 | // The SYNC opcode jumps to the address previously set by the SSY opcode |
| 2944 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | 2955 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); |
| 2945 | EmitPopFromSSYStack(); | 2956 | EmitPopFromFlowStack(); |
| 2957 | break; | ||
| 2958 | } | ||
| 2959 | case OpCode::Id::BRK: { | ||
| 2960 | // The BRK opcode jumps to the address previously set by the PBK opcode | ||
| 2961 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | ||
| 2962 | EmitPopFromFlowStack(); | ||
| 2946 | break; | 2963 | break; |
| 2947 | } | 2964 | } |
| 2948 | case OpCode::Id::DEPBAR: { | 2965 | case OpCode::Id::DEPBAR: { |
| @@ -3096,11 +3113,11 @@ private: | |||
| 3096 | labels.insert(subroutine.begin); | 3113 | labels.insert(subroutine.begin); |
| 3097 | shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); | 3114 | shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); |
| 3098 | 3115 | ||
| 3099 | // TODO(Subv): Figure out the actual depth of the SSY stack, for now it seems | 3116 | // TODO(Subv): Figure out the actual depth of the flow stack, for now it seems |
| 3100 | // unlikely that shaders will use 20 nested SSYs. | 3117 | // unlikely that shaders will use 20 nested SSYs and PBKs. |
| 3101 | constexpr u32 SSY_STACK_SIZE = 20; | 3118 | constexpr u32 FLOW_STACK_SIZE = 20; |
| 3102 | shader.AddLine("uint ssy_stack[" + std::to_string(SSY_STACK_SIZE) + "];"); | 3119 | shader.AddLine("uint flow_stack[" + std::to_string(FLOW_STACK_SIZE) + "];"); |
| 3103 | shader.AddLine("uint ssy_stack_top = 0u;"); | 3120 | shader.AddLine("uint flow_stack_top = 0u;"); |
| 3104 | 3121 | ||
| 3105 | shader.AddLine("while (true) {"); | 3122 | shader.AddLine("while (true) {"); |
| 3106 | ++shader.scope; | 3123 | ++shader.scope; |