1
0
Fork 0
forked from suyu/suyu

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.

This commit is contained in:
Rodolfo Bogado 2018-11-07 00:27:12 -03:00
parent e9610ec0dd
commit 4a6eff3b7b
4 changed files with 61 additions and 37 deletions

View file

@ -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_source_a = Regs::Blend::Factor::One;
regs.independent_blend[blend_index].factor_dest_a = Regs::Blend::Factor::Zero; 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) { void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {

View file

@ -345,6 +345,14 @@ public:
Invert = 6, Invert = 6,
IncrWrap = 7, IncrWrap = 7,
DecrWrap = 8, DecrWrap = 8,
KeepOGL = 0x1E00,
ZeroOGL = 0,
ReplaceOGL = 0x1E01,
IncrOGL = 0x1E02,
DecrOGL = 0x1E03,
InvertOGL = 0x150A,
IncrWrapOGL = 0x8507,
DecrWrapOGL = 0x8508,
}; };
enum class MemoryLayout : u32 { enum class MemoryLayout : u32 {

View file

@ -996,9 +996,6 @@ void RasterizerOpenGL::SyncStencilTestState() {
return; 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_func = MaxwellToGL::ComparisonOp(regs.stencil_front_func_func);
state.stencil.front.test_ref = regs.stencil_front_func_ref; state.stencil.front.test_ref = regs.stencil_front_func_ref;
state.stencil.front.test_mask = regs.stencil_front_func_mask; 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_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_zfail);
state.stencil.front.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_front_op_zpass); state.stencil.front.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_front_op_zpass);
state.stencil.front.write_mask = regs.stencil_front_mask; 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_func = MaxwellToGL::ComparisonOp(regs.stencil_back_func_func);
state.stencil.back.test_ref = regs.stencil_back_func_ref; state.stencil.back.test_ref = regs.stencil_back_func_ref;
state.stencil.back.test_mask = regs.stencil_back_func_mask; 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_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_zfail);
state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass); state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass);
state.stencil.back.write_mask = regs.stencil_back_mask; 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() { void RasterizerOpenGL::SyncColorMask() {

View file

@ -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)); static_cast<u32>(filter_mode));
UNREACHABLE(); return GL_LINEAR;
return {};
} }
inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) { 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: case Tegra::Texture::WrapMode::MirrorOnceClampToEdge:
return GL_MIRROR_CLAMP_TO_EDGE; return GL_MIRROR_CLAMP_TO_EDGE;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode)); LOG_ERROR(Render_OpenGL, "Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode));
UNREACHABLE(); return GL_REPEAT;
return {};
} }
inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) { inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
@ -207,10 +205,9 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
case Tegra::Texture::DepthCompareFunc::Always: case Tegra::Texture::DepthCompareFunc::Always:
return GL_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)); static_cast<u32>(func));
UNREACHABLE(); return GL_GREATER;
return {};
} }
inline GLenum BlendEquation(Maxwell::Blend::Equation equation) { inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
@ -226,9 +223,8 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
case Maxwell::Blend::Equation::Max: case Maxwell::Blend::Equation::Max:
return GL_MAX; return GL_MAX;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation)); LOG_ERROR(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation));
UNREACHABLE(); return GL_FUNC_ADD;
return {};
} }
inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
@ -291,9 +287,8 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: case Maxwell::Blend::Factor::OneMinusConstantAlphaGL:
return GL_ONE_MINUS_CONSTANT_ALPHA; return GL_ONE_MINUS_CONSTANT_ALPHA;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor)); LOG_ERROR(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor));
UNREACHABLE(); return GL_ZERO;
return {};
} }
inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) { inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
@ -312,9 +307,8 @@ inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
case Tegra::Texture::SwizzleSource::OneFloat: case Tegra::Texture::SwizzleSource::OneFloat:
return GL_ONE; return GL_ONE;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source)); LOG_ERROR(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source));
UNREACHABLE(); return GL_ZERO;
return {};
} }
inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) { inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
@ -344,33 +338,39 @@ inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
case Maxwell::ComparisonOp::AlwaysOld: case Maxwell::ComparisonOp::AlwaysOld:
return GL_ALWAYS; return GL_ALWAYS;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison)); LOG_ERROR(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison));
UNREACHABLE(); return GL_ALWAYS;
return {};
} }
inline GLenum StencilOp(Maxwell::StencilOp stencil) { inline GLenum StencilOp(Maxwell::StencilOp stencil) {
switch (stencil) { switch (stencil) {
case Maxwell::StencilOp::Keep: case Maxwell::StencilOp::Keep:
case Maxwell::StencilOp::KeepOGL:
return GL_KEEP; return GL_KEEP;
case Maxwell::StencilOp::Zero: case Maxwell::StencilOp::Zero:
case Maxwell::StencilOp::ZeroOGL:
return GL_ZERO; return GL_ZERO;
case Maxwell::StencilOp::Replace: case Maxwell::StencilOp::Replace:
case Maxwell::StencilOp::ReplaceOGL:
return GL_REPLACE; return GL_REPLACE;
case Maxwell::StencilOp::Incr: case Maxwell::StencilOp::Incr:
case Maxwell::StencilOp::IncrOGL:
return GL_INCR; return GL_INCR;
case Maxwell::StencilOp::Decr: case Maxwell::StencilOp::Decr:
case Maxwell::StencilOp::DecrOGL:
return GL_DECR; return GL_DECR;
case Maxwell::StencilOp::Invert: case Maxwell::StencilOp::Invert:
case Maxwell::StencilOp::InvertOGL:
return GL_INVERT; return GL_INVERT;
case Maxwell::StencilOp::IncrWrap: case Maxwell::StencilOp::IncrWrap:
case Maxwell::StencilOp::IncrWrapOGL:
return GL_INCR_WRAP; return GL_INCR_WRAP;
case Maxwell::StencilOp::DecrWrap: case Maxwell::StencilOp::DecrWrap:
case Maxwell::StencilOp::DecrWrapOGL:
return GL_DECR_WRAP; return GL_DECR_WRAP;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil)); LOG_ERROR(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil));
UNREACHABLE(); return GL_KEEP;
return {};
} }
inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) { 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: case Maxwell::Cull::FrontFace::CounterClockWise:
return GL_CCW; return GL_CCW;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face)); LOG_ERROR(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face));
UNREACHABLE(); return GL_CCW;
return {};
} }
inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) { 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: case Maxwell::Cull::CullFace::FrontAndBack:
return GL_FRONT_AND_BACK; return GL_FRONT_AND_BACK;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face)); LOG_ERROR(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face));
UNREACHABLE(); return GL_BACK;
return {};
} }
inline GLenum LogicOp(Maxwell::LogicOperation operation) { inline GLenum LogicOp(Maxwell::LogicOperation operation) {
@ -434,9 +432,8 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) {
case Maxwell::LogicOperation::Set: case Maxwell::LogicOperation::Set:
return GL_SET; return GL_SET;
} }
LOG_CRITICAL(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation)); LOG_ERROR(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation));
UNREACHABLE(); return GL_COPY;
return {};
} }
} // namespace MaxwellToGL } // namespace MaxwellToGL