From b9f6961931b4b676996f2e87bc8524a8bc487611 Mon Sep 17 00:00:00 2001 From: MaikelChan Date: Sun, 4 Aug 2024 05:28:10 +0200 Subject: [PATCH] Depth compare improvements based on GlideN64. --- port/fast3d/gfx_opengl.cpp | 53 ++++++++++++++++++++++----------- port/fast3d/gfx_pc.cpp | 25 +++++++--------- port/fast3d/gfx_rendering_api.h | 3 +- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index f486628a5..0a0107755 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -699,12 +699,42 @@ static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt)); } -static void gfx_opengl_set_depth_test_and_mask(bool depth_test, bool z_upd) { - if (depth_test || z_upd) { +static void gfx_opengl_set_depth_mode(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode) { + if (depth_test) { glEnable(GL_DEPTH_TEST); - glDepthMask(z_upd ? GL_TRUE : GL_FALSE); - glDepthFunc(depth_test ? GL_LEQUAL : GL_ALWAYS); - current_depth_mask = z_upd; + glDepthMask(depth_update ? GL_TRUE : GL_FALSE); + current_depth_mask = depth_update; + + if (depth_compare) { + switch (zmode) { + case ZMODE_INTER: + glDepthFunc(GL_LEQUAL); + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); + break; + + case ZMODE_OPA: + case ZMODE_XLU: + if (depth_source_prim) { + glDepthFunc(GL_LEQUAL); + } else { + glDepthFunc(GL_LESS); + } + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); + break; + + case ZMODE_DEC: + glDepthFunc(GL_LEQUAL); + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-2, -2); + break; + } + } else { + glDepthFunc(GL_ALWAYS); + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); + } } else { glDisable(GL_DEPTH_TEST); } @@ -714,16 +744,6 @@ static void gfx_opengl_set_depth_range(float znear, float zfar) { glDepthRange(znear, zfar); } -static void gfx_opengl_set_zmode_decal(bool zmode_decal) { - if (zmode_decal) { - glPolygonOffset(-2, -2); - glEnable(GL_POLYGON_OFFSET_FILL); - } else { - glPolygonOffset(0, 0); - glDisable(GL_POLYGON_OFFSET_FILL); - } -} - static void gfx_opengl_set_viewport(int x, int y, int width, int height) { glViewport(x, y, width, height); } @@ -1156,9 +1176,8 @@ struct GfxRenderingAPI gfx_opengl_api = { gfx_opengl_select_texture, gfx_opengl_upload_texture, gfx_opengl_set_sampler_parameters, - gfx_opengl_set_depth_test_and_mask, + gfx_opengl_set_depth_mode, gfx_opengl_set_depth_range, - gfx_opengl_set_zmode_decal, gfx_opengl_set_viewport, gfx_opengl_set_scissor, gfx_opengl_set_use_alpha, diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 7938fdd77..6e7f6257e 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -197,9 +197,8 @@ static struct RDP { } rdp; static struct RenderingState { - uint8_t depth_test_and_mask; // 1: depth test, 2: depth mask + uint8_t depth_mode; float depth_zfar; - bool decal_mode; bool alpha_blend; bool modulate; struct XYWidthHeight viewport, scissor; @@ -1240,25 +1239,23 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo } } - bool depth_test = (rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER; - bool depth_mask = (rdp.other_mode_l & Z_UPD) == Z_UPD; - uint8_t depth_test_and_mask = (depth_test ? 1 : 0) | (depth_mask ? 2 : 0); - if (depth_test_and_mask != rendering_state.depth_test_and_mask) { - gfx_flush(); - gfx_rapi->set_depth_test_and_mask(depth_test, depth_mask); - rendering_state.depth_test_and_mask = depth_test_and_mask; - } if (rsp.depth_zfar != rendering_state.depth_zfar) { gfx_flush(); gfx_rapi->set_depth_range(0.0f, rsp.depth_zfar); rendering_state.depth_zfar = rsp.depth_zfar; } - bool zmode_decal = (rdp.other_mode_l & ZMODE_DEC) == ZMODE_DEC; - if (zmode_decal != rendering_state.decal_mode) { + bool depth_test = (rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER; + bool depth_update = (rdp.other_mode_l & Z_UPD) == Z_UPD; + bool depth_compare = (rdp.other_mode_l & Z_CMP) == Z_CMP; + bool depth_source_prim = (rdp.other_mode_l & G_ZS_PRIM) == G_ZS_PRIM /* && gDP.primDepth.z == 1.0f */; + uint16_t zmode = rdp.other_mode_l & ZMODE_DEC; + uint8_t depth_mode = (depth_test ? 1 : 0) | (depth_update ? 2 : 0) | (depth_compare ? 4 : 0) | (depth_source_prim ? 8 : 0) | (zmode >> 6); + + if (depth_mode != rendering_state.depth_mode) { gfx_flush(); - gfx_rapi->set_zmode_decal(zmode_decal); - rendering_state.decal_mode = zmode_decal; + gfx_rapi->set_depth_mode(depth_test, depth_update, depth_compare, depth_source_prim, zmode); + rendering_state.depth_mode = depth_mode; } if (rdp.viewport_or_scissor_changed) { diff --git a/port/fast3d/gfx_rendering_api.h b/port/fast3d/gfx_rendering_api.h index b31aa4ba7..fcc287665 100644 --- a/port/fast3d/gfx_rendering_api.h +++ b/port/fast3d/gfx_rendering_api.h @@ -27,9 +27,8 @@ struct GfxRenderingAPI { void (*select_texture)(int tile, uint32_t texture_id); void (*upload_texture)(const uint8_t* rgba32_buf, uint32_t width, uint32_t height); void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt); - void (*set_depth_test_and_mask)(bool depth_test, bool z_upd); + void (*set_depth_mode)(bool depth_test, bool depth_update, bool depth_compare, bool depth_source_prim, uint16_t zmode); void (*set_depth_range)(float znear, float zfar); - void (*set_zmode_decal)(bool zmode_decal); void (*set_viewport)(int x, int y, int width, int height); void (*set_scissor)(int x, int y, int width, int height); void (*set_use_alpha)(bool use_alpha, bool modulate);