Dreamcast: Be a little bit more efficient in clipping by using z > 0 instead of z > -w

This commit is contained in:
UnknownShadow200 2024-06-21 23:54:24 +10:00
parent ebfa704e08
commit 73ea4968bc
3 changed files with 47 additions and 49 deletions

View File

@ -129,9 +129,9 @@
.macro ProcessVertex1 .macro ProcessVertex1
fmov.s fr7,@-r5 ! LS, dst->w = W fmov.s fr7,@-r5 ! LS, dst->w = W
fmov.s fr3,@-r5 ! LS, dst->c = C fmov.s fr3,@-r5 ! LS, dst->c = C
fneg fr7 ! LS, W = -W fldi0 fr0 ! LS, fr0 = 0.0
fmov.s fr2,@-r5 ! LS, dst->v = V fmov.s fr2,@-r5 ! LS, dst->v = V
fcmp/gt fr7,fr6 ! FE, T = Z > W (i.e. Z > -W) fcmp/gt fr0,fr6 ! FE, T = Z > 0
fmov.s fr1,@-r5 ! LS, dst->u = U fmov.s fr1,@-r5 ! LS, dst->u = U
movt r0 ! EX, CLIPFLAGS = T movt r0 ! EX, CLIPFLAGS = T
fmov.s fr6,@-r5 ! LS, dst->z = Z fmov.s fr6,@-r5 ! LS, dst->z = Z
@ -143,9 +143,9 @@
.macro ProcessVertex2 .macro ProcessVertex2
fmov.s fr7,@-r5 ! LS, dst->w = W fmov.s fr7,@-r5 ! LS, dst->w = W
fmov.s fr3,@-r5 ! LS, dst->c = C fmov.s fr3,@-r5 ! LS, dst->c = C
fneg fr7 ! LS, W = -W fldi0 fr0 ! LS, fr0 = 0.0
fmov.s fr2,@-r5 ! LS, dst->v = V fmov.s fr2,@-r5 ! LS, dst->v = V
fcmp/gt fr7,fr6 ! FE, T = Z > W (i.e. Z > -W) fcmp/gt fr0,fr6 ! FE, T = Z > 0
fmov.s fr1,@-r5 ! LS, dst->u = U fmov.s fr1,@-r5 ! LS, dst->u = U
movt r2 ! EX, tmp = T movt r2 ! EX, tmp = T
fmov.s fr6,@-r5 ! LS, dst->z = Z fmov.s fr6,@-r5 ! LS, dst->z = Z
@ -159,9 +159,9 @@
.macro ProcessVertex3 .macro ProcessVertex3
fmov.s fr7,@-r5 ! LS, dst->w = W fmov.s fr7,@-r5 ! LS, dst->w = W
fmov.s fr3,@-r5 ! LS, dst->c = C fmov.s fr3,@-r5 ! LS, dst->c = C
fneg fr7 ! LS, W = -W fldi0 fr0 ! LS, fr0 = 0.0
fmov.s fr2,@-r5 ! LS, dst->v = V fmov.s fr2,@-r5 ! LS, dst->v = V
fcmp/gt fr7,fr6 ! FE, T = Z > W (i.e. Z > -W) fcmp/gt fr0,fr6 ! FE, T = Z > 0
fmov.s fr1,@-r5 ! LS, dst->u = U fmov.s fr1,@-r5 ! LS, dst->u = U
movt r2 ! EX, tmp = T movt r2 ! EX, tmp = T
fmov.s fr6,@-r5 ! LS, dst->z = Z fmov.s fr6,@-r5 ! LS, dst->z = Z
@ -176,9 +176,9 @@
fmov.s fr7,@-r5 ! LS, dst->w = W fmov.s fr7,@-r5 ! LS, dst->w = W
or r11,r0 ! EX, CLIPFLAGS |= PVR_CMD_VERTEX_EOL or r11,r0 ! EX, CLIPFLAGS |= PVR_CMD_VERTEX_EOL
fmov.s fr3,@-r5 ! LS, dst->c = C fmov.s fr3,@-r5 ! LS, dst->c = C
fneg fr7 ! LS, W = -W fldi0 fr0 ! LS, fr0 = 0.0
fmov.s fr2,@-r5 ! LS, dst->v = V fmov.s fr2,@-r5 ! LS, dst->v = V
fcmp/gt fr7,fr6 ! FE, T = Z > W (i.e. Z > -W) fcmp/gt fr0,fr6 ! FE, T = Z > 0
fmov.s fr1,@-r5 ! LS, dst->u = U fmov.s fr1,@-r5 ! LS, dst->u = U
movt r2 ! EX, tmp = T movt r2 ! EX, tmp = T
fmov.s fr6,@-r5 ! LS, dst->z = Z fmov.s fr6,@-r5 ! LS, dst->z = Z

View File

@ -132,35 +132,34 @@ void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
*---------------------------------------------------------Matrices--------------------------------------------------------* *---------------------------------------------------------Matrices--------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float zNear, float zFar) { void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float zNear, float zFar) {
/* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glortho */ /* Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixorthooffcenterrh */
/* The simplified calculation below uses: L = 0, R = width, T = 0, B = height */ /* The simplified calculation below uses: L = 0, R = width, T = 0, B = height */
/* NOTE: This calculation is shared with Direct3D 11 backend */
*matrix = Matrix_Identity; *matrix = Matrix_Identity;
matrix->row1.x = 2.0f / width; matrix->row1.x = 2.0f / width;
matrix->row2.y = -2.0f / height; matrix->row2.y = -2.0f / height;
matrix->row3.z = -2.0f / (zFar - zNear); matrix->row3.z = 1.0f / (zNear - zFar);
matrix->row4.x = -1.0f; matrix->row4.x = -1.0f;
matrix->row4.y = 1.0f; matrix->row4.y = 1.0f;
matrix->row4.z = -(zFar + zNear) / (zFar - zNear); matrix->row4.z = zNear / (zNear - zFar);
} }
static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); }
void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) {
float zNear = 0.1f; float zNear = 0.1f;
float c = Cotangent(0.5f * fov);
/* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum */ /* Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh */
/* For a FOV based perspective matrix, left/right/top/bottom are calculated as: */ /* NOTE: This calculation is shared with Direct3D 11 backend */
/* left = -c * aspect, right = c * aspect, bottom = -c, top = c */ float c = Cotangent(0.5f * fov);
/* Calculations are simplified because of left/right and top/bottom symmetry */
*matrix = Matrix_Identity; *matrix = Matrix_Identity;
matrix->row1.x = c / aspect; matrix->row1.x = c / aspect;
matrix->row2.y = c; matrix->row2.y = c;
matrix->row3.z = -(zFar + zNear) / (zFar - zNear); matrix->row3.z = zFar / (zNear - zFar);
matrix->row3.w = -1.0f; matrix->row3.w = -1.0f;
matrix->row4.z = -(2.0f * zFar * zNear) / (zFar - zNear); matrix->row4.z = (zNear * zFar) / (zNear - zFar);
matrix->row4.w = 0.0f; matrix->row4.w = 0.0f;
} }

View File

@ -49,19 +49,18 @@ static inline void _glPushHeaderOrVertex(Vertex* v) {
sq += 8; sq += 8;
} }
static void _glClipEdge(const Vertex* const v1, const Vertex* const v2, Vertex* vout) { static void ClipEdge(const Vertex* const v1, const Vertex* const v2, Vertex* vout) {
const float d0 = v1->w + v1->z; float d0 = v1->z;
const float d1 = v2->w + v2->z; float d1 = v2->z;
const float t = (fabsf(d0) * MATH_fsrra((d1 - d0) * (d1 - d0))) + 0.000001f; float t = (fabsf(d0) * MATH_fsrra((d1 - d0) * (d1 - d0))) + 0.000001f;
const float invt = 1.0f - t; float invt = 1.0f - t;
vout->x = invt * v1->x + t * v2->x; vout->x = invt * v1->x + t * v2->x;
vout->y = invt * v1->y + t * v2->y; vout->y = invt * v1->y + t * v2->y;
vout->z = invt * v1->z + t * v2->z; vout->z = 0.0f; // clipped against near plane, where Z = 0 anyways
vout->u = invt * v1->u + t * v2->u; vout->u = invt * v1->u + t * v2->u;
vout->v = invt * v1->v + t * v2->v; vout->v = invt * v1->v + t * v2->v;
vout->w = invt * v1->w + t * v2->w; vout->w = invt * v1->w + t * v2->w;
vout->bgra[0] = invt * v1->bgra[0] + t * v2->bgra[0]; vout->bgra[0] = invt * v1->bgra[0] + t * v2->bgra[0];
@ -96,9 +95,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// .....A....B... // .....A....B...
// / | // / |
// v3--v2---v1 // v3--v2---v1
_glClipEdge(v3, v0, a); ClipEdge(v3, v0, a);
a->flags = PVR_CMD_VERTEX_EOL; a->flags = PVR_CMD_VERTEX_EOL;
_glClipEdge(v0, v1, b); ClipEdge(v0, v1, b);
b->flags = PVR_CMD_VERTEX; b->flags = PVR_CMD_VERTEX;
_glPerspectiveDivideVertex(v0); _glPerspectiveDivideVertex(v0);
@ -119,9 +118,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// ....A.....B... // ....A.....B...
// / | // / |
// v0--v3---v2 // v0--v3---v2
_glClipEdge(v0, v1, a); ClipEdge(v0, v1, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v1, v2, b); ClipEdge(v1, v2, b);
b->flags = PVR_CMD_VERTEX_EOL; b->flags = PVR_CMD_VERTEX_EOL;
_glPerspectiveDivideVertex(a); _glPerspectiveDivideVertex(a);
@ -142,9 +141,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// / | // / |
// v1--v0---v3 // v1--v0---v3
_glClipEdge(v1, v2, a); ClipEdge(v1, v2, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v2, v3, b); ClipEdge(v2, v3, b);
b->flags = PVR_CMD_VERTEX_EOL; b->flags = PVR_CMD_VERTEX_EOL;
_glPerspectiveDivideVertex(a); _glPerspectiveDivideVertex(a);
@ -164,9 +163,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// ....A.....B... // ....A.....B...
// / | // / |
// v2--v1---v0 // v2--v1---v0
_glClipEdge(v2, v3, a); ClipEdge(v2, v3, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v3, v0, b); ClipEdge(v3, v0, b);
b->flags = PVR_CMD_VERTEX; b->flags = PVR_CMD_VERTEX;
_glPerspectiveDivideVertex(b); _glPerspectiveDivideVertex(b);
@ -186,9 +185,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// ....B..........A... // ....B..........A...
// \ | // \ |
// v3-----v2 // v3-----v2
_glClipEdge(v1, v2, a); ClipEdge(v1, v2, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v3, v0, b); ClipEdge(v3, v0, b);
b->flags = PVR_CMD_VERTEX_EOL; b->flags = PVR_CMD_VERTEX_EOL;
_glPerspectiveDivideVertex(v1); _glPerspectiveDivideVertex(v1);
@ -211,9 +210,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// ....B..........A... // ....B..........A...
// \ | // \ |
// v2-----v1 // v2-----v1
_glClipEdge(v0, v1, a); ClipEdge(v0, v1, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v2, v3, b); ClipEdge(v2, v3, b);
b->flags = PVR_CMD_VERTEX; b->flags = PVR_CMD_VERTEX;
_glPerspectiveDivideVertex(a); _glPerspectiveDivideVertex(a);
@ -235,9 +234,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// ....B..........A... // ....B..........A...
// \ | // \ |
// v0-----v3 // v0-----v3
_glClipEdge(v2, v3, a); ClipEdge(v2, v3, a);
a->flags = PVR_CMD_VERTEX_EOL; a->flags = PVR_CMD_VERTEX_EOL;
_glClipEdge(v0, v1, b); ClipEdge(v0, v1, b);
b->flags = PVR_CMD_VERTEX; b->flags = PVR_CMD_VERTEX;
_glPerspectiveDivideVertex(v1); _glPerspectiveDivideVertex(v1);
@ -260,9 +259,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// ....B..........A... // ....B..........A...
// \ | // \ |
// v1-----v0 // v1-----v0
_glClipEdge(v3, v0, a); ClipEdge(v3, v0, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v1, v2, b); ClipEdge(v1, v2, b);
b->flags = PVR_CMD_VERTEX; b->flags = PVR_CMD_VERTEX;
_glPerspectiveDivideVertex(b); _glPerspectiveDivideVertex(b);
@ -286,9 +285,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// \ | // \ |
// v3 // v3
// v1,v2,v0 v2,v0,A v0,A,B // v1,v2,v0 v2,v0,A v0,A,B
_glClipEdge(v2, v3, a); ClipEdge(v2, v3, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v3, v0, b); ClipEdge(v3, v0, b);
b->flags = PVR_CMD_VERTEX_EOL; b->flags = PVR_CMD_VERTEX_EOL;
_glPerspectiveDivideVertex(v1); _glPerspectiveDivideVertex(v1);
@ -315,9 +314,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// \ | // \ |
// v2 // v2
// v0,v1,v3 v1,v3,A v3,A,B // v0,v1,v3 v1,v3,A v3,A,B
_glClipEdge(v1, v2, a); ClipEdge(v1, v2, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v2, v3, b); ClipEdge(v2, v3, b);
b->flags = PVR_CMD_VERTEX_EOL; b->flags = PVR_CMD_VERTEX_EOL;
v3->flags = PVR_CMD_VERTEX; v3->flags = PVR_CMD_VERTEX;
@ -345,9 +344,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// \ | // \ |
// v1 // v1
// v3,v0,v2 v0,v2,A v2,A,B // v3,v0,v2 v0,v2,A v2,A,B
_glClipEdge(v0, v1, a); ClipEdge(v0, v1, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v1, v2, b); ClipEdge(v1, v2, b);
b->flags = PVR_CMD_VERTEX_EOL; b->flags = PVR_CMD_VERTEX_EOL;
v3->flags = PVR_CMD_VERTEX; v3->flags = PVR_CMD_VERTEX;
@ -375,9 +374,9 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_
// \ | // \ |
// v0 // v0
// v2,v3,v1 v3,v1,A v1,A,B // v2,v3,v1 v3,v1,A v1,A,B
_glClipEdge(v3, v0, a); ClipEdge(v3, v0, a);
a->flags = PVR_CMD_VERTEX; a->flags = PVR_CMD_VERTEX;
_glClipEdge(v0, v1, b); ClipEdge(v0, v1, b);
b->flags = PVR_CMD_VERTEX_EOL; b->flags = PVR_CMD_VERTEX_EOL;
v3->flags = PVR_CMD_VERTEX; v3->flags = PVR_CMD_VERTEX;