summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-10-16 17:11:26 -0300
committerGravatar ReinUsesLisp2018-10-17 21:30:45 -0300
commit41fb25349a82ba0657e41e4597ac9e415f6e442a (patch)
tree529a948ab657eef57b05c0cb932269374a6b5df4 /src
parentMerge pull request #1443 from DarkLordZach/lower-loader-logs-1 (diff)
downloadyuzu-41fb25349a82ba0657e41e4597ac9e415f6e442a.tar.gz
yuzu-41fb25349a82ba0657e41e4597ac9e415f6e442a.tar.xz
yuzu-41fb25349a82ba0657e41e4597ac9e415f6e442a.zip
gl_shader_decompiler: Implement PBK and BRK
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/shader_bytecode.h10
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp55
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;