yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

Merge pull request #518 from Subv/incomplete_shaders

GPU: Implemented predicated exit instructions in the shader programs.
This commit is contained in:
bunnei 2018-06-04 22:43:46 -04:00 committed by GitHub
commit 8c99dd055c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 5 deletions

View File

@ -115,7 +115,16 @@ private:
if (const auto opcode = OpCode::Decode(instr)) { if (const auto opcode = OpCode::Decode(instr)) {
switch (opcode->GetId()) { switch (opcode->GetId()) {
case OpCode::Id::EXIT: { case OpCode::Id::EXIT: {
return exit_method = ExitMethod::AlwaysEnd; // The EXIT instruction can be predicated, which means that the shader can
// conditionally end on this instruction. We have to consider the case where the
// condition is not met and check the exit method of that other basic block.
using Tegra::Shader::Pred;
if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) {
return exit_method = ExitMethod::AlwaysEnd;
} else {
ExitMethod not_met = Scan(offset + 1, end, labels);
return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met);
}
} }
case OpCode::Id::BRA: { case OpCode::Id::BRA: {
u32 target = offset + instr.bra.GetBranchTarget(); u32 target = offset + instr.bra.GetBranchTarget();
@ -1213,9 +1222,6 @@ private:
default: { default: {
switch (opcode->GetId()) { switch (opcode->GetId()) {
case OpCode::Id::EXIT: { case OpCode::Id::EXIT: {
ASSERT_MSG(instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex),
"Predicated exits not implemented");
// Final color output is currently hardcoded to GPR0-3 for fragment shaders // Final color output is currently hardcoded to GPR0-3 for fragment shaders
if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { if (stage == Maxwell3D::Regs::ShaderStage::Fragment) {
shader.AddLine("color.r = " + regs.GetRegisterAsFloat(0) + ';'); shader.AddLine("color.r = " + regs.GetRegisterAsFloat(0) + ';');
@ -1225,7 +1231,12 @@ private:
} }
shader.AddLine("return true;"); shader.AddLine("return true;");
offset = PROGRAM_END - 1; if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) {
// If this is an unconditional exit then just end processing here, otherwise we
// have to account for the possibility of the condition not being met, so
// continue processing the next instruction.
offset = PROGRAM_END - 1;
}
break; break;
} }
case OpCode::Id::KIL: { case OpCode::Id::KIL: {