1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-09 14:47:02 +02:00

#407 OT processing optimizations (next/prev vertex index pre-fill)

This commit is contained in:
XProger
2022-07-02 05:19:52 +03:00
parent ea021e0a36
commit 32a5459110
3 changed files with 131 additions and 195 deletions

View File

@@ -11,7 +11,7 @@
.align 4
.global _rasterize_asm
_rasterize_asm:
mov tile, r7
mov tile, r7 // set 4th arg for proc
mov flags, type
shll2 type
shlr16 type
@@ -19,7 +19,7 @@ _rasterize_asm:
cmp/eq #FACE_TYPE_F, type // cmp/eq #imm is 8-bit
bf/s .getProc
mov L, R
mov L, R // [delay slot]
extu.b flags, R
.getProc: // proc = table[type]
@@ -29,13 +29,14 @@ _rasterize_asm:
// pixel = fb + y * 320 = fb + y * 256 + y * 64
mov.w @(VERTEX_Y, L), y
// FRAME_WIDTH = 320 = 256 + 64
mov.l var_fb, pixel
shll8 y
add y, pixel // pixel += y * 256
shar y
shar y
jmp @proc
add y, pixel // pixel += y * 64
add y, pixel // [delay slot] pixel += y * 64
.align 2
var_fb:

View File

@@ -84,9 +84,14 @@ void updateInput()
if (mask & SEGA_CTRL_MODE) keys |= IK_SELECT;
}
void* osLoadLevel(const char* name)
const void* osLoadScreen(LevelID id)
{
return (void*)LEVEL1_PKD;
return TITLE_SCR;
}
const void* osLoadLevel(LevelID id)
{
return (void*)LEVEL1_PKD; // TODO
}
uint16 pageIndex = 0;
@@ -190,7 +195,7 @@ int main()
MARS_SYS_COMM4 = 0;
gameInit(gLevelInfo[gLevelID].name);
gameInit();
int32 lastFrame = (gFrameIndex >> 1) - 1;
int32 fpsCounter = 0;

View File

@@ -116,8 +116,8 @@ X_INLINE Face* faceAdd(int32 depth)
extern "C" {
X_NOINLINE void drawPoly(uint32 flags, VertexLink* v, const ColorIndex* tile);
X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v, const ColorIndex* tile);
X_NOINLINE void drawQuad(uint32 flags, VertexLink* v, const ColorIndex* tile);
X_INLINE void drawTriangle(uint32 flags, VertexLink* v, const ColorIndex* tile);
X_INLINE void drawQuad(uint32 flags, VertexLink* v, const ColorIndex* tile);
}
extern "C" {
@@ -598,6 +598,26 @@ int32 sphereIsVisible_c(int32 sx, int32 sy, int32 sz, int32 r)
void flush_ot(int32 bit)
{
VertexLink v[4 + 3];
VertexLink* q = v;
VertexLink* t = v + 4;
// quad
q[0].prev = 3;
q[0].next = 1;
q[1].prev = -1;
q[1].next = 1;
q[2].prev = -1;
q[2].next = 1;
q[3].prev = -1;
q[3].next = -3;
// triangle
t[0].prev = 2;
t[0].next = 1;
t[1].prev = -1;
t[1].next = 1;
t[2].prev = -1;
t[2].next = -2;
int32 index = 0;
const ColorIndex* tile = NULL;
@@ -617,37 +637,37 @@ void flush_ot(int32 bit)
uint32 flags = face->flags;
VertexLink v[16];
uint32 type = (flags >> FACE_TYPE_SHIFT) & FACE_TYPE_MASK;
if (type <= FACE_TYPE_GTA)
{
VertexLink* ptr = (flags & FACE_TRIANGLE) ? t : q;
if (type > FACE_TYPE_F)
{
const Texture &tex = level.textures[flags & FACE_TEXTURE];
tile = (ColorIndex*)tex.tile;
v[0].t.t = 0xFF00FF00 & (tex.uv01);
v[1].t.t = 0xFF00FF00 & (tex.uv01 << 8);
v[2].t.t = 0xFF00FF00 & (tex.uv23);
v[3].t.t = 0xFF00FF00 & (tex.uv23 << 8);
ptr[0].t.t = 0xFF00FF00 & (tex.uv01);
ptr[1].t.t = 0xFF00FF00 & (tex.uv01 << 8);
ptr[2].t.t = 0xFF00FF00 & (tex.uv23);
ptr[3].t.t = 0xFF00FF00 & (tex.uv23 << 8);
}
v[0].v = gVertices[face->indices[0]];
v[1].v = gVertices[face->indices[1]];
v[2].v = gVertices[face->indices[2]];
ptr[0].v = gVertices[face->indices[0]];
ptr[1].v = gVertices[face->indices[1]];
ptr[2].v = gVertices[face->indices[2]];
if (!(flags & FACE_TRIANGLE)) {
v[3].v = gVertices[face->indices[3]];
ptr[3].v = gVertices[face->indices[3]];
}
if (flags & FACE_CLIPPED) {
drawPoly(flags, v, tile);
drawPoly(flags, ptr, tile);
} else {
if (flags & FACE_TRIANGLE) {
drawTriangle(flags, v, tile);
drawTriangle(flags, ptr, tile);
} else {
drawQuad(flags, v, tile);
drawQuad(flags, ptr, tile);
}
}
}
@@ -734,7 +754,42 @@ void flush_c()
#endif
}
VertexLink* clipPoly(VertexLink* poly, VertexLink* tmp, int32 &pCount)
void renderInit()
{
gVerticesBase = gVertices;
gFacesBase = gFaces;
}
void renderFree()
{
}
void renderLevelInit()
{
}
void renderLevelFree()
{
}
extern "C" X_INLINE void drawTriangle(uint32 flags, VertexLink* v, const ColorIndex* tile)
{
VertexLink* top = v;
if (top->v.y > v[1].v.y) top = v + 1;
if (top->v.y > v[2].v.y) top = v + 2;
rasterize(flags, top, tile);
}
extern "C" X_INLINE void drawQuad(uint32 flags, VertexLink* v, const ColorIndex* tile)
{
VertexLink* top = v;
if (top->v.y > v[1].v.y) top = v + 1;
if (top->v.y > v[2].v.y) top = v + 2;
if (top->v.y > v[3].v.y) top = v + 3;
rasterize(flags, top, tile);
}
extern "C" X_NOINLINE void drawPoly(uint32 flags, VertexLink* v, const ColorIndex* tile)
{
#define LERP_SHIFT 6
#define LERP(a,b,t) (b + ((a - b) * t >> LERP_SHIFT))
@@ -746,12 +801,13 @@ VertexLink* clipPoly(VertexLink* poly, VertexLink* tmp, int32 &pCount)
int32 tb = (a->v.X - b->v.X);\
ASSERT(tb != 0);\
int32 t = ta / tb;\
VertexLink* v = output + count++;\
v->v.X = edge;\
v->v.Y = LERP2(a->v.Y, b->v.Y, ta, tb);\
v->v.g = LERP(a->v.g, b->v.g, t);\
v->t.uv.u = LERP(a->t.uv.u, b->t.uv.u, t);\
v->t.uv.v = LERP(a->t.uv.v, b->t.uv.v, t);\
ASSERT(count < 8);\
VertexLink* p = output + count++;\
p->v.X = edge;\
p->v.Y = LERP2(a->v.Y, b->v.Y, ta, tb);\
p->v.g = LERP(a->v.g, b->v.g, t);\
p->t.uv.u = LERP(a->t.uv.u, b->t.uv.u, t);\
p->t.uv.v = LERP(a->t.uv.v, b->t.uv.v, t);\
}
#define CLIP_XY(X, Y, X0, X1, input, output) {\
@@ -771,184 +827,58 @@ VertexLink* clipPoly(VertexLink* poly, VertexLink* tmp, int32 &pCount)
} else if (b->v.X > X1) {\
CLIP_AXIS(X, Y, X1, output);\
} else {\
ASSERT(count < 8);\
output[count++] = *b;\
}\
}\
if (count < 3) return NULL;\
if (count < 3) return;\
}
VertexLink tmp[8];
VertexLink out[8];
int32 pCount = (flags & FACE_TRIANGLE) ? 3 : 4;
int32 count = 0;
VertexLink *in = poly;
VertexLink *out = tmp;
// clip x
CLIP_XY(x, y, 0, FRAME_WIDTH, in, out);
CLIP_XY(x, y, 0, FRAME_WIDTH, v, tmp);
pCount = count;
count = 0;
// clip y
CLIP_XY(y, x, 0, FRAME_HEIGHT, out, in);
pCount = count;
CLIP_XY(y, x, 0, FRAME_HEIGHT, tmp, out);
return in;
}
VertexLink* first = out;
VertexLink* last = out + count - 1;
void renderInit()
{
gVerticesBase = gVertices;
gFacesBase = gFaces;
}
bool skip = (first->v.y == last->v.y);
void renderFree()
{
}
VertexLink* top = (first->v.y < last->v.y) ? first : last;
first->prev = count - 1;
first->next = 1;
last->prev = -1;
last->next = 1 - count;
void renderLevelInit()
{
}
void renderLevelFree()
{
}
extern "C" X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v, const ColorIndex* tile)
{
VertexLink* v0 = v + 0;
VertexLink* v1 = v + 1;
VertexLink* v2 = v + 2;
v0->next = v1 - v0;
v1->next = v2 - v1;
v2->next = v0 - v2;
v0->prev = v2 - v0;
v1->prev = v0 - v1;
v2->prev = v1 - v2;
VertexLink* top;
if (v0->v.y < v1->v.y) {
if (v0->v.y < v2->v.y) {
top = v0;
} else {
top = v2;
}
} else {
if (v1->v.y < v2->v.y) {
top = v1;
} else {
top = v2;
}
}
rasterize(flags, top, tile);
}
extern "C" X_NOINLINE void drawQuad(uint32 flags, VertexLink* v, const ColorIndex* tile)
{
VertexLink* v0 = v + 0;
VertexLink* v1 = v + 1;
VertexLink* v2 = v + 2;
VertexLink* v3 = v + 3;
v0->next = v1 - v0;
v1->next = v2 - v1;
v2->next = v3 - v2;
v3->next = v0 - v3;
v0->prev = v3 - v0;
v1->prev = v0 - v1;
v2->prev = v1 - v2;
v3->prev = v2 - v3;
VertexLink* top;
if (v0->v.y < v1->v.y) {
if (v0->v.y < v2->v.y) {
top = (v0->v.y < v3->v.y) ? v0 : v3;
} else {
top = (v2->v.y < v3->v.y) ? v2 : v3;
}
} else {
if (v1->v.y < v2->v.y) {
top = (v1->v.y < v3->v.y) ? v1 : v3;
} else {
top = (v2->v.y < v3->v.y) ? v2 : v3;
}
}
rasterize(flags, top, tile);
}
extern "C" X_NOINLINE void drawPoly(uint32 flags, VertexLink* v, const ColorIndex* tile)
{
VertexLink tmp[16];
int32 count = (flags & FACE_TRIANGLE) ? 3 : 4;
v = clipPoly(v, tmp, count);
if (!v) return;
if (count <= 4)
for (int32 i = 1; i < count - 1; i++)
{
if (count == 3) {
if (v[0].v.y == v[1].v.y &&
v[0].v.y == v[2].v.y)
return;
drawTriangle(flags, v, tile);
} else {
if (v[0].v.y == v[1].v.y &&
v[0].v.y == v[2].v.y &&
v[0].v.y == v[3].v.y)
return;
drawQuad(flags, v, tile);
}
return;
}
VertexLink* top = v;
top->next = (v + 1) - top;
top->prev = (v + count - 1) - top;
bool skip = true;
for (int32 i = 1; i < count; i++)
{
int8 next = i + 1;
int8 prev = i - 1;
if (next >= count) {
next -= count;
}
if (prev < 0) {
prev += count;
}
next -= i;
prev -= i;
VertexLink *p = v + i;
p->next = next;
p->prev = prev;
VertexLink* p = out + i;
if (p->v.y != top->v.y)
{
if (p->v.y < top->v.y) {
if (p->v.y < top->v.y)
{
top = p;
}
skip = false;
}
p->prev = -1;
p->next = 1;
}
if (skip) {
return; // zero height poly
}
if (skip)
return;
rasterize(flags, top, tile);
}