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_cache.h2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp49
2 files changed, 46 insertions, 5 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index 44156dcab..658f9e994 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -30,7 +30,7 @@ public:
/// Gets the size of the shader in guest memory, required for cache management
size_t GetSizeInBytes() const {
- return sizeof(GLShader::ProgramCode);
+ return GLShader::MAX_PROGRAM_CODE_LENGTH * sizeof(u64);
}
/// Gets the shader entries for the shader
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: {