From 9d322660e8fcb2139e13208327e1e7c6c75ad071 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 7 Jul 2024 09:26:12 +1000 Subject: [PATCH] Dreamcast: Fix not skipping completely invisible quads --- .github/workflows/build_dreamcast.yml | 2 +- misc/dreamcast/DrawColouredQuads.S | 49 ---------- misc/dreamcast/DrawTexturedQuads.S | 46 --------- misc/dreamcast/VertexTransform.S | 129 +++++++++++++++++--------- src/Graphics_Dreamcast.c | 3 + third_party/gldc/src/gldc.h | 17 ---- third_party/gldc/src/state.c | 17 +++- 7 files changed, 103 insertions(+), 160 deletions(-) delete mode 100644 misc/dreamcast/DrawColouredQuads.S delete mode 100644 misc/dreamcast/DrawTexturedQuads.S diff --git a/.github/workflows/build_dreamcast.yml b/.github/workflows/build_dreamcast.yml index 8261dd9df..c25091323 100644 --- a/.github/workflows/build_dreamcast.yml +++ b/.github/workflows/build_dreamcast.yml @@ -23,7 +23,7 @@ jobs: run: | apt-get update apt-get -y install genisoimage - wget https://github.com/ClassiCube/rpi-compiling-stuff/raw/main/cdi4dc -O /opt/toolchains/dc/kos/utils/cdi4dc + wget https://github.com/ClassiCube/rpi-compiling-stuff/raw/main/cdi4dc -O /opt/toolchains/dc/kos/utils/cdi4dc chmod +x /opt/toolchains/dc/kos/utils/cdi4dc export PATH=/opt/toolchains/dc/kos/utils/:$PATH make dreamcast diff --git a/misc/dreamcast/DrawColouredQuads.S b/misc/dreamcast/DrawColouredQuads.S deleted file mode 100644 index 029480b16..000000000 --- a/misc/dreamcast/DrawColouredQuads.S +++ /dev/null @@ -1,49 +0,0 @@ -#include "VertexTransform.S" -.global _DrawColouredQuads -.align 4 -.type _DrawColouredQuads,%function - -_DrawColouredQuads: -! Setup - fldi0 fr1 ! U = 0 - fldi0 fr2 ! V = 0 - TransformSetup - !ViewportTransformSetup _VP_COL - -.TRANSFORM_QUAD: - LoadColouredVertex - ProcessVertex1 - - LoadColouredVertex - ProcessVertex2 - - LoadColouredVertex - ProcessVertex3 - - LoadColouredVertex - ProcessVertex4 - -! CLIPFLAGS TESTING - cmp/eq #0,r0 ! T = r0 == 0 (all points invisible) - bt/s .NO_POINTS_VISIBLE ! if T goto NO_POINTS_VISIBLE - nop - bra .SOME_POINTS_VISIBLE - nop - -.NO_POINTS_VISIBLE: - bra .LOOP_END ! jump to loop end after executing instruction in delay slot - add #-128, r5 ! r5 -= 4 * sizeof(VERTEX), move back to 1 vertex before start of quad - -.SOME_POINTS_VISIBLE: - -.LOOP_END: - dt r6 ! r6--; T = r6 == 0 - bf .TRANSFORM_QUAD ! if !T then goto TRANSFORM_QUAD - nop - - TransformEnd - -.align 4 - -!.VP_COL: -! .long _vp diff --git a/misc/dreamcast/DrawTexturedQuads.S b/misc/dreamcast/DrawTexturedQuads.S deleted file mode 100644 index 202dc686d..000000000 --- a/misc/dreamcast/DrawTexturedQuads.S +++ /dev/null @@ -1,46 +0,0 @@ -#include "VertexTransform.S" -.global _DrawTexturedQuads -.align 4 - -_DrawTexturedQuads: -! Setup - TransformSetup - !ViewportTransformSetup .VP_TEX - -.TRANSFORM_QUAD: - LoadTexturedVertex - ProcessVertex1 - - LoadTexturedVertex - ProcessVertex2 - - LoadTexturedVertex - ProcessVertex3 - - LoadTexturedVertex - ProcessVertex4 - -! CLIPFLAGS TESTING - cmp/eq #0,r0 ! T = r0 == 0 (all points invisible) - bt/s .NO_POINTS_VISIBLE ! if T goto NO_POINTS_VISIBLE - nop - bra .SOME_POINTS_VISIBLE - nop - -.NO_POINTS_VISIBLE: - bra .LOOP_END ! jump to loop end after executing instruction in delay slot - add #-128, r5 ! r5 -= 4 * sizeof(VERTEX), move back to prior quad, so that this invisible quad gets overwritten in next iteration - -.SOME_POINTS_VISIBLE: - -.LOOP_END: - dt r6 ! r6--; T = r6 == 0 - bf .TRANSFORM_QUAD ! if !T then goto TRANSFORM_QUAD - nop - - TransformEnd - -.align 4 - -!.VP_TEX: -! .long _vp diff --git a/misc/dreamcast/VertexTransform.S b/misc/dreamcast/VertexTransform.S index a0955ca52..1a36ca965 100644 --- a/misc/dreamcast/VertexTransform.S +++ b/misc/dreamcast/VertexTransform.S @@ -192,55 +192,94 @@ ! ========================================================= -! ====================== VIEWPORT TRANSFORM =============== +! ==================== TEXTURED VERTEX TRANSFORM ========== ! ========================================================= -!r2 = return addr -!r0 = temp -!r5 = dst pointer +.global _DrawTexturedQuads +.type _DrawTexturedQuads,%function +.align 4 -!fr0 = temp -!fr4 = temp -!fr5 = temp -!fr5 = temp -!fr8 = VIEWPORT_HWIDTH -!fr9 = VIEWPORT_HHEIGHT -!fr10 = VIEWPORT_X_PLUS_HWIDTH -!fr11 = VIEWPORT_Y_PLUS_HHEIGHT +_DrawTexturedQuads: +! Setup + TransformSetup -.macro ViewportTransformSetup vp_addr - mov.l \vp_addr, r0 ! EX, r0 = &vp - fmov.s @r0+,fr8 ! LS, fr8 = vp->HWIDTH - fmov.s @r0+,fr9 ! LS, fr9 = vp->HHEIGHT - fmov.s @r0+,fr10 ! LS, fr10 = vp->X_PLUS_HWIDTH - fmov.s @r0+,fr11 ! LS, fr11 = vp->Y_PLUS_HHEIGHT - nop ! MT (align to even instructions boundary) -.endm +.T_TRANSFORM_QUAD: + LoadTexturedVertex + ProcessVertex1 -.macro ViewportTransformVertex -! INVERSE W CALCULATION - add #28, r5 ! EX, r5 = &vertex->w - fmov.s @r5,fr0 ! LS, fr0 = vertex->w - fmul fr0,fr0 ! FE, fr0 = fr0 * fr0 - add #-24, r5 ! EX, r5 = &vertex->x - fsrra fr0 ! FE, fr0 = 1 / sqrt(fr0) -> 1 / vertex->w + LoadTexturedVertex + ProcessVertex2 -! TRANSFORM X - fmov.s @r5,fr4 ! LS, fr4 = vertex->x - fmov fr10,fr5 ! LS, fr5 = VIEWPORT_X_PLUS_HWIDTH - fmul fr8,fr4 ! FE, fr4 = VIEWPORT_HWIDTH * vertex->x - fmac fr0,fr4,fr5 ! FE, fr5 = fr0 * fr4 + fr5 -- (X * F * hwidth) + x_plus_hwidth - fmov.s fr5,@r5 ! LS, vertex->x = fr5 - add #4, r5 ! EX, r5 = &vertex->y + LoadTexturedVertex + ProcessVertex3 -! TRANSFORM Y - fmov.s @r5,fr4 ! LS, fr4 = vertex->y - fmov fr11,fr5 ! LS, fr5 = VIEWPORT_Y_PLUS_HHEIGHT - fmul fr9,fr4 ! FE, fr4 = VIEWPORT_HHEIGHT * vertex->y - fmac fr0,fr4,fr5 ! FE, fr5 = fr0 * fr4 + fr5 -- (Y * F * hheight) + y_plus_hheight - fmov.s fr5,@r5 ! LS, vertex->y = fr5 - add #4, r5 ! EX, r5 = &vertex->z + LoadTexturedVertex + ProcessVertex4 -! ASSIGN Z - fmov.s fr0,@r5 ! LS, vertex->z = fr0 - add #20, r5 ! EX, r5 += 20 (points to start of next vertex) -.endm +! CLIPFLAGS TESTING + and #15,r0 + cmp/eq #0,r0 ! T = r0 == 0 (all points invisible) + bt/s .T_NO_POINTS_VISIBLE ! if T goto NO_POINTS_VISIBLE + nop + bra .T_SOME_POINTS_VISIBLE + nop + +.T_NO_POINTS_VISIBLE: + bra .T_LOOP_END ! jump to loop end after executing instruction in delay slot + add #-128, r5 ! r5 -= 4 * sizeof(VERTEX), move back to prior quad, so that this invisible quad gets overwritten in next iteration + +.T_SOME_POINTS_VISIBLE: + +.T_LOOP_END: + dt r6 ! r6--; T = r6 == 0 + bf .T_TRANSFORM_QUAD ! if !T then goto T_TRANSFORM_QUAD + nop + + TransformEnd + + +! ========================================================= +! ==================== COLOURED VERTEX TRANSFORM ========== +! ========================================================= +.global _DrawColouredQuads +.type _DrawColouredQuads,%function +.align 4 + +_DrawColouredQuads: +! Setup + fldi0 fr1 ! U = 0 + fldi0 fr2 ! V = 0 + TransformSetup + +.C_TRANSFORM_QUAD: + LoadColouredVertex + ProcessVertex1 + + LoadColouredVertex + ProcessVertex2 + + LoadColouredVertex + ProcessVertex3 + + LoadColouredVertex + ProcessVertex4 + +! CLIPFLAGS TESTING + and #15,r0 + cmp/eq #0,r0 ! T = r0 == 0 (all points invisible) + bt/s .C_NO_POINTS_VISIBLE ! if T goto NO_POINTS_VISIBLE + nop + bra .C_SOME_POINTS_VISIBLE + nop + +.C_NO_POINTS_VISIBLE: + bra .C_LOOP_END ! jump to loop end after executing instruction in delay slot + add #-128, r5 ! r5 -= 4 * sizeof(VERTEX), move back to 1 vertex before start of quad + +.C_SOME_POINTS_VISIBLE: + +.C_LOOP_END: + dt r6 ! r6--; T = r6 == 0 + bf .C_TRANSFORM_QUAD ! if !T then goto TRANSFORM_QUAD + nop + + TransformEnd diff --git a/src/Graphics_Dreamcast.c b/src/Graphics_Dreamcast.c index dbf48f90e..217bd1399 100644 --- a/src/Graphics_Dreamcast.c +++ b/src/Graphics_Dreamcast.c @@ -627,7 +627,10 @@ void Gfx_ClearBuffers(GfxBuffers buffers) { void Gfx_EndFrame(void) { pvr_wait_ready(); + + pvr_scene_begin(); glKosSwapBuffers(); + pvr_scene_finish(); } void Gfx_OnWindowResize(void) { diff --git a/third_party/gldc/src/gldc.h b/third_party/gldc/src/gldc.h index c931b4fbd..35c69e071 100644 --- a/third_party/gldc/src/gldc.h +++ b/third_party/gldc/src/gldc.h @@ -123,25 +123,8 @@ GLuint _glFreeTextureMemory(void); GLuint _glUsedTextureMemory(void); GLuint _glFreeContiguousTextureMemory(void); -void _glApplyScissor(int force); - extern GLboolean STATE_DIRTY; void SceneListSubmit(Vertex* v2, int n, int type); -static inline int DimensionFlag(int w) { - switch(w) { - case 16: return 1; - case 32: return 2; - case 64: return 3; - case 128: return 4; - case 256: return 5; - case 512: return 6; - case 1024: return 7; - case 8: - default: - return 0; - } -} - #endif // PRIVATE_H diff --git a/third_party/gldc/src/state.c b/third_party/gldc/src/state.c index b9306bb8c..05f3674d9 100644 --- a/third_party/gldc/src/state.c +++ b/third_party/gldc/src/state.c @@ -41,7 +41,6 @@ void glKosInit() { } void glKosSwapBuffers() { - pvr_scene_begin(); if (OP_LIST.vector.size > 2) { pvr_list_begin(PVR_LIST_OP_POLY); SceneListSubmit((Vertex*)OP_LIST.vector.data, OP_LIST.vector.size, 0); @@ -62,7 +61,21 @@ void glKosSwapBuffers() { pvr_list_finish(); TR_LIST.vector.size = 0; } - pvr_scene_finish(); +} + +static inline int DimensionFlag(int w) { + switch(w) { + case 16: return 1; + case 32: return 2; + case 64: return 3; + case 128: return 4; + case 256: return 5; + case 512: return 6; + case 1024: return 7; + case 8: + default: + return 0; + } } void apply_poly_header(pvr_poly_hdr_t* dst, int list_type) {