yuzu-emu
/
yuzu
Archived
1
0
Fork 0

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