summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodolfo Bogado <rodolfoosvaldobogado@gmail.com>2018-11-07 00:27:12 -0300
committerRodolfo Bogado <rodolfoosvaldobogado@gmail.com>2018-11-11 16:31:00 -0300
commit4a6eff3b7b0cf8578ac8e23fe47dae52c7fb350a (patch)
tree6c562c3140257de2d510ab67aff43f02af11c7a0
parente9610ec0dd3d47ae7dc2b14932faef0318d36125 (diff)
Try to fix problems with stencil test in some games, relax translation to opengl enums to avoid crashing and only generate logs of the errors.
-rw-r--r--src/video_core/engines/maxwell_3d.cpp13
-rw-r--r--src/video_core/engines/maxwell_3d.h8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp14
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h63
4 files changed, 61 insertions, 37 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 5ae836aca..d1777b25b 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -53,6 +53,19 @@ void Maxwell3D::InitializeRegisterDefaults() {
regs.independent_blend[blend_index].factor_source_a = Regs::Blend::Factor::One;
regs.independent_blend[blend_index].factor_dest_a = Regs::Blend::Factor::Zero;
}
+ regs.stencil_front_op_fail = Regs::StencilOp::Keep;
+ regs.stencil_front_op_zfail = Regs::StencilOp::Keep;
+ regs.stencil_front_op_zpass = Regs::StencilOp::Keep;
+ regs.stencil_front_func_func = Regs::ComparisonOp::Always;
+ regs.stencil_front_func_mask = 0xFFFFFFFF;
+ regs.stencil_front_mask = 0xFFFFFFFF;
+ regs.stencil_two_side_enable = 1;
+ regs.stencil_back_op_fail = Regs::StencilOp::Keep;
+ regs.stencil_back_op_zfail = Regs::StencilOp::Keep;
+ regs.stencil_back_op_zpass = Regs::StencilOp::Keep;
+ regs.stencil_back_func_func = Regs::ComparisonOp::Always;
+ regs.stencil_back_func_mask = 0xFFFFFFFF;
+ regs.stencil_back_mask = 0xFFFFFFFF;
}
void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 557795d0f..91ca57883 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -345,6 +345,14 @@ public:
Invert = 6,
IncrWrap = 7,
DecrWrap = 8,
+ KeepOGL = 0x1E00,
+ ZeroOGL = 0,
+ ReplaceOGL = 0x1E01,
+ IncrOGL = 0x1E02,
+ DecrOGL = 0x1E03,
+ InvertOGL = 0x150A,
+ IncrWrapOGL = 0x8507,
+ DecrWrapOGL = 0x8508,
};
enum class MemoryLayout : u32 {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 40f474e07..8dd7bd514 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -996,9 +996,6 @@ void RasterizerOpenGL::SyncStencilTestState() {
return;
}
- // TODO(bunnei): Verify behavior when this is not set
- ASSERT(regs.stencil_two_side_enable);
-
state.stencil.front.test_func = MaxwellToGL::ComparisonOp(regs.stencil_front_func_func);
state.stencil.front.test_ref = regs.stencil_front_func_ref;
state.stencil.front.test_mask = regs.stencil_front_func_mask;
@@ -1006,7 +1003,7 @@ void RasterizerOpenGL::SyncStencilTestState() {
state.stencil.front.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_zfail);
state.stencil.front.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_front_op_zpass);
state.stencil.front.write_mask = regs.stencil_front_mask;
-
+ if (regs.stencil_two_side_enable) {
state.stencil.back.test_func = MaxwellToGL::ComparisonOp(regs.stencil_back_func_func);
state.stencil.back.test_ref = regs.stencil_back_func_ref;
state.stencil.back.test_mask = regs.stencil_back_func_mask;
@@ -1014,6 +1011,15 @@ void RasterizerOpenGL::SyncStencilTestState() {
state.stencil.back.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_zfail);
state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass);
state.stencil.back.write_mask = regs.stencil_back_mask;
+ } else {
+ state.stencil.back.test_func = GL_ALWAYS;
+ state.stencil.back.test_ref = 0;
+ state.stencil.back.test_mask = 0xFFFFFFFF;
+ state.stencil.back.write_mask = 0xFFFFFFFF;
+ state.stencil.back.action_stencil_fail = GL_KEEP;
+ state.stencil.back.action_depth_fail = GL_KEEP;
+ state.stencil.back.action_depth_pass = GL_KEEP;
+ }
}
void RasterizerOpenGL::SyncColorMask() {
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 87d511c38..32dc158e4 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -159,10 +159,9 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode,
}
}
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented texture filter mode={}",
+ LOG_ERROR(Render_OpenGL, "Unimplemented texture filter mode={}",
static_cast<u32>(filter_mode));
- UNREACHABLE();
- return {};
+ return GL_LINEAR;
}
inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) {
@@ -183,9 +182,8 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) {
case Tegra::Texture::WrapMode::MirrorOnceClampToEdge:
return GL_MIRROR_CLAMP_TO_EDGE;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode));
+ return GL_REPEAT;
}
inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
@@ -207,10 +205,9 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
case Tegra::Texture::DepthCompareFunc::Always:
return GL_ALWAYS;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented texture depth compare function ={}",
+ LOG_ERROR(Render_OpenGL, "Unimplemented texture depth compare function ={}",
static_cast<u32>(func));
- UNREACHABLE();
- return {};
+ return GL_GREATER;
}
inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
@@ -226,9 +223,8 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
case Maxwell::Blend::Equation::Max:
return GL_MAX;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation));
+ return GL_FUNC_ADD;
}
inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
@@ -291,9 +287,8 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
case Maxwell::Blend::Factor::OneMinusConstantAlphaGL:
return GL_ONE_MINUS_CONSTANT_ALPHA;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor));
+ return GL_ZERO;
}
inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
@@ -312,9 +307,8 @@ inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
case Tegra::Texture::SwizzleSource::OneFloat:
return GL_ONE;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source));
+ return GL_ZERO;
}
inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
@@ -344,33 +338,39 @@ inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
case Maxwell::ComparisonOp::AlwaysOld:
return GL_ALWAYS;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison));
+ return GL_ALWAYS;
}
inline GLenum StencilOp(Maxwell::StencilOp stencil) {
switch (stencil) {
case Maxwell::StencilOp::Keep:
+ case Maxwell::StencilOp::KeepOGL:
return GL_KEEP;
case Maxwell::StencilOp::Zero:
+ case Maxwell::StencilOp::ZeroOGL:
return GL_ZERO;
case Maxwell::StencilOp::Replace:
+ case Maxwell::StencilOp::ReplaceOGL:
return GL_REPLACE;
case Maxwell::StencilOp::Incr:
+ case Maxwell::StencilOp::IncrOGL:
return GL_INCR;
case Maxwell::StencilOp::Decr:
+ case Maxwell::StencilOp::DecrOGL:
return GL_DECR;
case Maxwell::StencilOp::Invert:
+ case Maxwell::StencilOp::InvertOGL:
return GL_INVERT;
case Maxwell::StencilOp::IncrWrap:
+ case Maxwell::StencilOp::IncrWrapOGL:
return GL_INCR_WRAP;
case Maxwell::StencilOp::DecrWrap:
+ case Maxwell::StencilOp::DecrWrapOGL:
return GL_DECR_WRAP;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil));
+ return GL_KEEP;
}
inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) {
@@ -380,9 +380,8 @@ inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) {
case Maxwell::Cull::FrontFace::CounterClockWise:
return GL_CCW;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face));
+ return GL_CCW;
}
inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) {
@@ -394,9 +393,8 @@ inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) {
case Maxwell::Cull::CullFace::FrontAndBack:
return GL_FRONT_AND_BACK;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face));
+ return GL_BACK;
}
inline GLenum LogicOp(Maxwell::LogicOperation operation) {
@@ -434,9 +432,8 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) {
case Maxwell::LogicOperation::Set:
return GL_SET;
}
- LOG_CRITICAL(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation));
- UNREACHABLE();
- return {};
+ LOG_ERROR(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation));
+ return GL_COPY;
}
} // namespace MaxwellToGL