OpenGL: Respect depth-read allow register

This commit is contained in:
Jannik Vogel 2016-04-01 01:48:36 +02:00
parent dad051f55f
commit 8fa5995077
2 changed files with 53 additions and 4 deletions

View file

@ -314,6 +314,11 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
SyncBlendFuncs(); SyncBlendFuncs();
break; break;
// Stencil and depth read mask
case PICA_REG_INDEX(framebuffer.allow_stencil_read):
SyncDepthTest();
break;
// Logic op // Logic op
case PICA_REG_INDEX(output_merger.logic_op): case PICA_REG_INDEX(output_merger.logic_op):
SyncLogicOp(); SyncLogicOp();
@ -1032,10 +1037,30 @@ void RasterizerOpenGL::SyncStencilTest() {
void RasterizerOpenGL::SyncDepthTest() { void RasterizerOpenGL::SyncDepthTest() {
const auto& regs = Pica::g_state.regs; const auto& regs = Pica::g_state.regs;
state.depth.test_enabled = regs.output_merger.depth_test_enable == 1 ||
regs.output_merger.depth_write_enable == 1; // Enable depth test so depth writes can still occur
state.depth.test_func = regs.output_merger.depth_test_enable == 1 ? state.depth.test_enabled = GL_TRUE;
PicaToGL::CompareFunc(regs.output_merger.depth_test_func) : GL_ALWAYS;
if (!regs.output_merger.depth_test_enable) {
state.depth.test_func = GL_ALWAYS;
} else {
if (!regs.framebuffer.allow_depth_read) {
// If reads are not allowed we have to patch the depth test accordingly
state.depth.test_func = PicaToGL::CompareXToZeroFunc(regs.output_merger.depth_test_func);
// Check if the result is known at this point, if not it depends on the framebuffer really being zero
if (state.depth.test_func != GL_NEVER && state.depth.test_func != GL_ALWAYS) {
LOG_CRITICAL(Render_OpenGL, "Can't emulate disabled read on depth yet");
UNIMPLEMENTED();
}
} else {
state.depth.test_func = PicaToGL::CompareFunc(regs.output_merger.depth_test_func);
}
}
} }
void RasterizerOpenGL::SyncCombinerColor() { void RasterizerOpenGL::SyncCombinerColor() {

View file

@ -155,6 +155,30 @@ inline GLenum CompareFunc(Pica::Regs::CompareFunc func) {
return compare_func_table[(unsigned)func]; return compare_func_table[(unsigned)func];
} }
/// Pretend we compare 'x FUNC 0' (unsigned)
inline GLenum CompareXToZeroFunc(Pica::Regs::CompareFunc func) {
static const GLenum compare_func_table[] = {
GL_NEVER, // CompareFunc::Never
GL_ALWAYS, // CompareFunc::Always
GL_EQUAL, // CompareFunc::Equal
GL_NOTEQUAL, // CompareFunc::NotEqual
GL_NEVER, // CompareFunc::LessThan
GL_LEQUAL, // CompareFunc::LessThanOrEqual
GL_GREATER, // CompareFunc::GreaterThan
GL_ALWAYS, // CompareFunc::GreaterThanOrEqual
};
// Range check table for input
if (static_cast<size_t>(func) >= ARRAY_SIZE(compare_func_table)) {
LOG_CRITICAL(Render_OpenGL, "Unknown compare function %d", func);
UNREACHABLE();
return GL_ALWAYS;
}
return compare_func_table[(unsigned)func];
}
inline GLenum StencilOp(Pica::Regs::StencilAction action) { inline GLenum StencilOp(Pica::Regs::StencilAction action) {
static const GLenum stencil_op_table[] = { static const GLenum stencil_op_table[] = {
GL_KEEP, // StencilAction::Keep GL_KEEP, // StencilAction::Keep