From 414e72299edc4cce5de042e887a8675c068a104c Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Sun, 12 Jul 2015 02:30:01 +0200 Subject: [PATCH 1/2] Proper clear masks and region --- hw/xbox/nv2a.c | 61 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 6176a8a5cd..5c5721a56d 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -4314,15 +4314,44 @@ static void pgraph_method(NV2AState *d, case NV097_CLEAR_SURFACE: NV2A_DPRINTF("---------PRE CLEAR ------\n"); GLbitfield gl_mask = 0; - if (parameter & NV097_CLEAR_SURFACE_Z) { - gl_mask |= GL_DEPTH_BUFFER_BIT; - } - if (parameter & NV097_CLEAR_SURFACE_STENCIL) { - gl_mask |= GL_STENCIL_BUFFER_BIT; - } - if (parameter & (NV097_CLEAR_SURFACE_COLOR)) { - gl_mask |= GL_COLOR_BUFFER_BIT; + bool write_color = (parameter & NV097_CLEAR_SURFACE_COLOR); + bool write_zeta = + (parameter & (NV097_CLEAR_SURFACE_Z | NV097_CLEAR_SURFACE_STENCIL)); + + if (write_zeta) { + uint32_t clear_zstencil = d->pgraph.regs[NV_PGRAPH_ZSTENCILCLEARVALUE]; + GLint gl_clear_stencil; + GLdouble gl_clear_depth; + switch(pg->surface_shape.zeta_format) { + case NV097_SET_SURFACE_FORMAT_ZETA_Z16: + //FIXME: Remove bit for stencil clear? + gl_clear_depth = (clear_zstencil & 0xFFFF) / (double)0xFFFF; + break; + case NV097_SET_SURFACE_FORMAT_ZETA_Z24S8: + gl_clear_stencil = clear_zstencil & 0xFF; + gl_clear_depth = (clear_zstencil >> 8) / (double)0xFFFFFF; + break; + default: + assert(0); + } + if (parameter & NV097_CLEAR_SURFACE_Z) { + gl_mask |= GL_DEPTH_BUFFER_BIT; + glDepthMask(GL_TRUE); + glClearDepth(gl_clear_depth); + } + if (parameter & NV097_CLEAR_SURFACE_STENCIL) { + gl_mask |= GL_STENCIL_BUFFER_BIT; + glStencilMask(0xff); + glClearStencil(gl_clear_stencil); + } + } + if (write_color) { + gl_mask |= GL_COLOR_BUFFER_BIT; + glColorMask((parameter & NV097_CLEAR_SURFACE_R)?GL_TRUE:GL_FALSE, + (parameter & NV097_CLEAR_SURFACE_G)?GL_TRUE:GL_FALSE, + (parameter & NV097_CLEAR_SURFACE_B)?GL_TRUE:GL_FALSE, + (parameter & NV097_CLEAR_SURFACE_A)?GL_TRUE:GL_FALSE); uint32_t clear_color = d->pgraph.regs[NV_PGRAPH_COLORCLEARVALUE]; glClearColor( ((clear_color >> 16) & 0xFF) / 255.0f, /* red */ ((clear_color >> 8) & 0xFF) / 255.0f, /* green */ @@ -4330,15 +4359,8 @@ static void pgraph_method(NV2AState *d, ((clear_color >> 24) & 0xFF) / 255.0f);/* alpha */ } - bool write_color = (parameter & NV097_CLEAR_SURFACE_COLOR); - bool write_zeta = - (parameter & (NV097_CLEAR_SURFACE_Z | NV097_CLEAR_SURFACE_STENCIL)); pgraph_update_surface(d, true, write_color, write_zeta); - glColorMask(true, true, true, true); - glDepthMask(true); - glStencilMask(0xff); - glEnable(GL_SCISSOR_TEST); unsigned int xmin = GET_MASK(pg->regs[NV_PGRAPH_CLEARRECTX], @@ -4349,8 +4371,8 @@ static void pgraph_method(NV2AState *d, NV_PGRAPH_CLEARRECTY_YMIN); unsigned int ymax = GET_MASK(pg->regs[NV_PGRAPH_CLEARRECTY], NV_PGRAPH_CLEARRECTY_YMAX); - glScissor(xmin, pg->surface_shape.clip_height-ymax, - xmax-xmin, ymax-ymin); + glScissor(xmin, /*pg->surface_shape.clip_height-ymax*/ymin, + xmax-xmin+1, ymax-ymin+1); NV2A_DPRINTF("------------------CLEAR 0x%x %d,%d - %d,%d %x---------------\n", parameter, xmin, ymin, xmax, ymax, d->pgraph.regs[NV_PGRAPH_COLORCLEARVALUE]); @@ -4359,6 +4381,11 @@ static void pgraph_method(NV2AState *d, glDisable(GL_SCISSOR_TEST); + //FIXME: Masks are bad now + glDepthMask(GL_TRUE); + glStencilMask(0xff); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + pgraph_set_surface_dirty(pg, write_color, write_zeta); break; From a753f3d06c2466e962e261e4ecef5dd0ec3ff972 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Mon, 13 Jul 2015 17:53:18 +0200 Subject: [PATCH 2/2] Cleanup clear code --- hw/xbox/nv2a.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 5c5721a56d..6aca344506 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -4320,12 +4320,13 @@ static void pgraph_method(NV2AState *d, (parameter & (NV097_CLEAR_SURFACE_Z | NV097_CLEAR_SURFACE_STENCIL)); if (write_zeta) { - uint32_t clear_zstencil = d->pgraph.regs[NV_PGRAPH_ZSTENCILCLEARVALUE]; + uint32_t clear_zstencil = + d->pgraph.regs[NV_PGRAPH_ZSTENCILCLEARVALUE]; GLint gl_clear_stencil; GLdouble gl_clear_depth; switch(pg->surface_shape.zeta_format) { case NV097_SET_SURFACE_FORMAT_ZETA_Z16: - //FIXME: Remove bit for stencil clear? + /* FIXME: Remove bit for stencil clear? */ gl_clear_depth = (clear_zstencil & 0xFFFF) / (double)0xFFFF; break; case NV097_SET_SURFACE_FORMAT_ZETA_Z24S8: @@ -4348,10 +4349,14 @@ static void pgraph_method(NV2AState *d, } if (write_color) { gl_mask |= GL_COLOR_BUFFER_BIT; - glColorMask((parameter & NV097_CLEAR_SURFACE_R)?GL_TRUE:GL_FALSE, - (parameter & NV097_CLEAR_SURFACE_G)?GL_TRUE:GL_FALSE, - (parameter & NV097_CLEAR_SURFACE_B)?GL_TRUE:GL_FALSE, - (parameter & NV097_CLEAR_SURFACE_A)?GL_TRUE:GL_FALSE); + glColorMask((parameter & NV097_CLEAR_SURFACE_R) + ? GL_TRUE : GL_FALSE, + (parameter & NV097_CLEAR_SURFACE_G) + ? GL_TRUE : GL_FALSE, + (parameter & NV097_CLEAR_SURFACE_B) + ? GL_TRUE : GL_FALSE, + (parameter & NV097_CLEAR_SURFACE_A) + ? GL_TRUE : GL_FALSE); uint32_t clear_color = d->pgraph.regs[NV_PGRAPH_COLORCLEARVALUE]; glClearColor( ((clear_color >> 16) & 0xFF) / 255.0f, /* red */ ((clear_color >> 8) & 0xFF) / 255.0f, /* green */ @@ -4371,8 +4376,9 @@ static void pgraph_method(NV2AState *d, NV_PGRAPH_CLEARRECTY_YMIN); unsigned int ymax = GET_MASK(pg->regs[NV_PGRAPH_CLEARRECTY], NV_PGRAPH_CLEARRECTY_YMAX); - glScissor(xmin, /*pg->surface_shape.clip_height-ymax*/ymin, - xmax-xmin+1, ymax-ymin+1); + + /* FIXME: Maybe "pg->surface_shape.clip_height-ymax" instead of ymin? */ + glScissor(xmin, ymin, xmax-xmin+1, ymax-ymin+1); NV2A_DPRINTF("------------------CLEAR 0x%x %d,%d - %d,%d %x---------------\n", parameter, xmin, ymin, xmax, ymax, d->pgraph.regs[NV_PGRAPH_COLORCLEARVALUE]); @@ -4381,11 +4387,6 @@ static void pgraph_method(NV2AState *d, glDisable(GL_SCISSOR_TEST); - //FIXME: Masks are bad now - glDepthMask(GL_TRUE); - glStencilMask(0xff); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - pgraph_set_surface_dirty(pg, write_color, write_zeta); break;