summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-04-20 09:16:55 -0500
committerGravatar Subv2018-04-20 21:09:33 -0500
commitc3a8ea76f180fbaf2d58d0454e7adc2bb1f30009 (patch)
tree5b23e8812808e3b3f87a874b0d4e5a418675ea85 /src
parentShaderGen: Implemented the fsetp instruction. (diff)
downloadyuzu-c3a8ea76f180fbaf2d58d0454e7adc2bb1f30009.tar.gz
yuzu-c3a8ea76f180fbaf2d58d0454e7adc2bb1f30009.tar.xz
yuzu-c3a8ea76f180fbaf2d58d0454e7adc2bb1f30009.zip
ShaderGen: Implemented predicated instruction execution.
Each predicated instruction will be wrapped in an `if (predicate) { instruction_body; }` in the GLSL, where `predicate` is one of the predicate boolean variables previously set by fsetp.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h6
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp35
2 files changed, 40 insertions, 1 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index fb639a417..e6c2fd367 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -331,7 +331,11 @@ union Instruction {
331 OpCode opcode; 331 OpCode opcode;
332 BitField<0, 8, Register> gpr0; 332 BitField<0, 8, Register> gpr0;
333 BitField<8, 8, Register> gpr8; 333 BitField<8, 8, Register> gpr8;
334 BitField<16, 4, Pred> pred; 334 union {
335 BitField<16, 4, Pred> full_pred;
336 BitField<16, 3, u64> pred_index;
337 } pred;
338 BitField<19, 1, u64> negate_pred;
335 BitField<20, 8, Register> gpr20; 339 BitField<20, 8, Register> gpr20;
336 BitField<20, 7, SubOp> sub_op; 340 BitField<20, 7, SubOp> sub_op;
337 BitField<28, 8, Register> gpr28; 341 BitField<28, 8, Register> gpr28;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 2e0203a68..7aaee9464 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -294,6 +294,25 @@ private:
294 } 294 }
295 295
296 /* 296 /*
297 * Returns the condition to use in the 'if' for a predicated instruction.
298 * @param instr Instruction to generate the if condition for.
299 * @returns string containing the predicate condition.
300 */
301 std::string GetPredicateCondition(Instruction instr) const {
302 using Tegra::Shader::Pred;
303 ASSERT(instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex));
304
305 std::string variable =
306 'p' + std::to_string(static_cast<u64>(instr.pred.pred_index.Value()));
307
308 if (instr.negate_pred) {
309 return "!(" + variable + ')';
310 }
311
312 return variable;
313 }
314
315 /*
297 * Returns whether the instruction at the specified offset is a 'sched' instruction. 316 * Returns whether the instruction at the specified offset is a 'sched' instruction.
298 * Sched instructions always appear before a sequence of 3 instructions. 317 * Sched instructions always appear before a sequence of 3 instructions.
299 */ 318 */
@@ -320,6 +339,16 @@ private:
320 339
321 shader.AddLine("// " + std::to_string(offset) + ": " + OpCode::GetInfo(instr.opcode).name); 340 shader.AddLine("// " + std::to_string(offset) + ": " + OpCode::GetInfo(instr.opcode).name);
322 341
342 using Tegra::Shader::Pred;
343 ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute,
344 "NeverExecute predicate not implemented");
345
346 if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
347 shader.AddLine("if (" + GetPredicateCondition(instr) + ')');
348 shader.AddLine('{');
349 ++shader.scope;
350 }
351
323 switch (OpCode::GetInfo(instr.opcode).type) { 352 switch (OpCode::GetInfo(instr.opcode).type) {
324 case OpCode::Type::Arithmetic: { 353 case OpCode::Type::Arithmetic: {
325 std::string dest = GetRegister(instr.gpr0); 354 std::string dest = GetRegister(instr.gpr0);
@@ -559,6 +588,12 @@ private:
559 } 588 }
560 } 589 }
561 590
591 // Close the predicate condition scope.
592 if (instr.pred != Pred::UnusedIndex) {
593 --shader.scope;
594 shader.AddLine('}');
595 }
596
562 return offset + 1; 597 return offset + 1;
563 } 598 }
564 599