summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp44
1 files changed, 31 insertions, 13 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index c29cabb84..96a4ca6fe 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -728,10 +728,10 @@ private:
const std::string& op_a, const std::string& op_b) const {
using Tegra::Shader::PredCondition;
static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = {
- {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="},
- {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"},
- {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="},
- {PredCondition::NotEqualWithNan, "!="},
+ {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="},
+ {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"},
+ {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="},
+ {PredCondition::LessThanWithNan, "<"}, {PredCondition::NotEqualWithNan, "!="},
};
const auto& comparison{PredicateComparisonStrings.find(condition)};
@@ -739,7 +739,8 @@ private:
"Unknown predicate comparison operation");
std::string predicate{'(' + op_a + ") " + comparison->second + " (" + op_b + ')'};
- if (condition == PredCondition::NotEqualWithNan) {
+ if (condition == PredCondition::LessThanWithNan ||
+ condition == PredCondition::NotEqualWithNan) {
predicate += " || isnan(" + op_a + ") || isnan(" + op_b + ')';
}
@@ -1639,16 +1640,32 @@ private:
shader.AddLine("color.a = " + regs.GetRegisterAsFloat(3) + ';');
}
- shader.AddLine("return true;");
- 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;
+ switch (instr.flow.cond) {
+ case Tegra::Shader::FlowCondition::Always:
+ shader.AddLine("return true;");
+ 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;
+
+ case Tegra::Shader::FlowCondition::Fcsm_Tr:
+ // TODO(bunnei): What is this used for? If we assume this conditon is not
+ // satisifed, dual vertex shaders in Farming Simulator make more sense
+ LOG_CRITICAL(HW_GPU, "Skipping unknown FlowCondition::Fcsm_Tr");
+ break;
+
+ default:
+ LOG_CRITICAL(HW_GPU, "Unhandled flow condition: {}",
+ static_cast<u32>(instr.flow.cond.Value()));
+ UNREACHABLE();
}
break;
}
case OpCode::Id::KIL: {
+ ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
shader.AddLine("discard;");
break;
}
@@ -1669,8 +1686,9 @@ private:
// can ignore this when generating GLSL code.
break;
}
- case OpCode::Id::DEPBAR:
- case OpCode::Id::SYNC: {
+ case OpCode::Id::SYNC:
+ ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
+ case OpCode::Id::DEPBAR: {
// TODO(Subv): Find out if we actually have to care about these instructions or if
// the GLSL compiler takes care of that for us.
LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed");