diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 7e5ebfe24..391c92d47 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -729,8 +729,7 @@ private: {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"}, {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="}, {PredCondition::LessThanWithNan, "<"}, {PredCondition::NotEqualWithNan, "!="}, - {PredCondition::GreaterThanWithNan, ">"}, - }; + {PredCondition::GreaterThanWithNan, ">"}, {PredCondition::GreaterEqualWithNan, ">="}}; const auto& comparison{PredicateComparisonStrings.find(condition)}; ASSERT_MSG(comparison != PredicateComparisonStrings.end(), @@ -739,7 +738,8 @@ private: std::string predicate{'(' + op_a + ") " + comparison->second + " (" + op_b + ')'}; if (condition == PredCondition::LessThanWithNan || condition == PredCondition::NotEqualWithNan || - condition == PredCondition::GreaterThanWithNan) { + condition == PredCondition::GreaterThanWithNan || + condition == PredCondition::GreaterEqualWithNan) { predicate += " || isnan(" + op_a + ") || isnan(" + op_b + ')'; } @@ -1363,6 +1363,15 @@ private: "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); break; } + case OpCode::Id::POPC_C: + case OpCode::Id::POPC_R: + case OpCode::Id::POPC_IMM: { + if (instr.popc.invert) { + op_b = "~(" + op_b + ')'; + } + regs.SetRegisterToInteger(instr.gpr0, true, 0, "bitCount(" + op_b + ')', 1, 1); + break; + } case OpCode::Id::SEL_C: case OpCode::Id::SEL_R: case OpCode::Id::SEL_IMM: { @@ -2100,7 +2109,39 @@ private: } case OpCode::Id::IPA: { const auto& attribute = instr.attribute.fmt28; - regs.SetRegisterToInputAttibute(instr.gpr0, attribute.element, attribute.index); + const auto& reg = instr.gpr0; + switch (instr.ipa.mode) { + case Tegra::Shader::IpaMode::Pass: + if (stage == Maxwell3D::Regs::ShaderStage::Fragment && + attribute.index == Attribute::Index::Position) { + switch (attribute.element) { + case 0: + shader.AddLine(regs.GetRegisterAsFloat(reg) + " = gl_FragCoord.x;"); + break; + case 1: + shader.AddLine(regs.GetRegisterAsFloat(reg) + " = gl_FragCoord.y;"); + break; + case 2: + shader.AddLine(regs.GetRegisterAsFloat(reg) + " = gl_FragCoord.z;"); + break; + case 3: + shader.AddLine(regs.GetRegisterAsFloat(reg) + " = 1.0;"); + break; + } + } else { + regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); + } + break; + case Tegra::Shader::IpaMode::None: + regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); + break; + default: + LOG_CRITICAL(HW_GPU, "Unhandled IPA mode: {}", + static_cast<u32>(instr.ipa.mode.Value())); + UNREACHABLE(); + regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index); + } + break; } case OpCode::Id::SSY: { |