DS GX: Update matrix transforms

This commit is contained in:
Vicki Pfau 2017-02-28 13:05:25 -08:00
parent 0d5a15380b
commit 9ad56b1b79
4 changed files with 69 additions and 52 deletions

View File

@ -153,7 +153,14 @@ struct DSGX {
struct DSGXMatrix posMatrix;
struct DSGXMatrix vecMatrix;
struct DSGXMatrix vertexMatrix;
struct DSGXMatrix clipMatrix;
int viewportX1;
int viewportY1;
int viewportX2;
int viewportY2;
int viewportWidth;
int viewportHeight;
int vertexMode;
struct DSGXVertex currentVertex;

View File

@ -17,7 +17,7 @@ struct DSGXMatrix {
};
void DSGXMtxIdentity(struct DSGXMatrix*);
void DSGXMtxMultiply(struct DSGXMatrix*, const struct DSGXMatrix*);
void DSGXMtxMultiply(struct DSGXMatrix*, const struct DSGXMatrix*, const struct DSGXMatrix*);
void DSGXMtxScale(struct DSGXMatrix*, const int32_t* m);
void DSGXMtxTranslate(struct DSGXMatrix*, const int32_t* m);

View File

@ -136,9 +136,8 @@ static void _pullPipe(struct DSGX* gx) {
}
}
static void _updateVertexMatrix(struct DSGX* gx) {
memcpy(&gx->vertexMatrix, &gx->projMatrix, sizeof(gx->vertexMatrix));
DSGXMtxMultiply(&gx->vertexMatrix, &gx->posMatrix);
static void _updateClipMatrix(struct DSGX* gx) {
DSGXMtxMultiply(&gx->clipMatrix, &gx->projMatrix, &gx->posMatrix);
}
static int32_t _dotViewport(struct DSGXVertex* vertex, int32_t* col) {
@ -167,10 +166,13 @@ static void _emitVertex(struct DSGX* gx, uint16_t x, uint16_t y, uint16_t z) {
gx->currentVertex.x = x;
gx->currentVertex.y = y;
gx->currentVertex.z = z;
gx->currentVertex.vx = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[0]);
gx->currentVertex.vy = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[1]);
gx->currentVertex.vz = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[2]);
gx->currentVertex.vw = _dotViewport(&gx->currentVertex, &gx->vertexMatrix.m[3]);
gx->currentVertex.vx = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[0]);
gx->currentVertex.vy = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[1]);
gx->currentVertex.vz = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[2]);
gx->currentVertex.vw = _dotViewport(&gx->currentVertex, &gx->clipMatrix.m[3]);
gx->currentVertex.vx = (gx->currentVertex.vx + gx->currentVertex.vw) * gx->viewportWidth / (gx->currentVertex.vw * 2) + gx->viewportX1;
gx->currentVertex.vy = (gx->currentVertex.vy + gx->currentVertex.vw) * gx->viewportHeight / (gx->currentVertex.vw * 2) + gx->viewportY1;
struct DSGXVertex* vbuf = gx->vertexBuffer[gx->bufferIndex];
vbuf[gx->vertexIndex] = gx->currentVertex;
@ -240,7 +242,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
if (first) {
first = false;
} else if (cycles > cyclesLate) {
} else if (!gx->activeParams && cycles > cyclesLate) {
break;
}
CircleBufferRead8(&gx->pipe, (int8_t*) &entry.command);
@ -292,7 +294,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
mLOG(DS_GX, STUB, "Unimplemented GX MTX_PUSH mode");
break;
}
_updateVertexMatrix(gx);
_updateClipMatrix(gx);
break;
case DS_GX_CMD_MTX_POP: {
int8_t offset = entry.params[0];
@ -316,7 +318,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
mLOG(DS_GX, STUB, "Unimplemented GX MTX_POP mode");
break;
}
_updateVertexMatrix(gx);
_updateClipMatrix(gx);
break;
}
case DS_GX_CMD_MTX_IDENTITY:
@ -334,7 +336,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
DSGXMtxIdentity(&gx->texMatrix);
break;
}
_updateVertexMatrix(gx);
_updateClipMatrix(gx);
break;
case DS_GX_CMD_MTX_LOAD_4x4: {
struct DSGXMatrix m;
@ -359,7 +361,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix));
break;
}
_updateVertexMatrix(gx);
_updateClipMatrix(gx);
break;
}
case DS_GX_CMD_MTX_LOAD_4x3: {
@ -389,7 +391,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix));
break;
}
_updateVertexMatrix(gx);
_updateClipMatrix(gx);
break;
}
case DS_GX_CMD_MTX_MULT_4x4: {
@ -403,19 +405,19 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
}
switch (gx->mtxMode) {
case 0:
DSGXMtxMultiply(&gx->projMatrix, &m);
DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix);
break;
case 2:
DSGXMtxMultiply(&gx->vecMatrix, &m);
DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
// Fall through
case 1:
DSGXMtxMultiply(&gx->posMatrix, &m);
DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
break;
case 3:
DSGXMtxMultiply(&gx->texMatrix, &m);
DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix);
break;
}
_updateVertexMatrix(gx);
_updateClipMatrix(gx);
break;
}
case DS_GX_CMD_MTX_MULT_4x3: {
@ -433,19 +435,19 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
m.m[15] = MTX_ONE;
switch (gx->mtxMode) {
case 0:
DSGXMtxMultiply(&gx->projMatrix, &m);
DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix);
break;
case 2:
DSGXMtxMultiply(&gx->vecMatrix, &m);
DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
// Fall through
case 1:
DSGXMtxMultiply(&gx->posMatrix, &m);
DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
break;
case 3:
DSGXMtxMultiply(&gx->texMatrix, &m);
DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix);
break;
}
_updateVertexMatrix(gx);
_updateClipMatrix(gx);
break;
}
case DS_GX_CMD_MTX_MULT_3x3: {
@ -466,19 +468,19 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
m.m[15] = MTX_ONE;
switch (gx->mtxMode) {
case 0:
memcpy(&gx->projMatrix, &m, sizeof(gx->projMatrix));
DSGXMtxMultiply(&gx->projMatrix, &m, &gx->projMatrix);
break;
case 2:
memcpy(&gx->vecMatrix, &m, sizeof(gx->vecMatrix));
DSGXMtxMultiply(&gx->vecMatrix, &m, &gx->vecMatrix);
// Fall through
case 1:
memcpy(&gx->posMatrix, &m, sizeof(gx->posMatrix));
DSGXMtxMultiply(&gx->posMatrix, &m, &gx->posMatrix);
break;
case 3:
memcpy(&gx->texMatrix, &m, sizeof(gx->projMatrix));
DSGXMtxMultiply(&gx->texMatrix, &m, &gx->texMatrix);
break;
}
_updateVertexMatrix(gx);
_updateClipMatrix(gx);
break;
}
case DS_GX_CMD_MTX_TRANS: {
@ -666,7 +668,7 @@ void DSGXReset(struct DSGX* gx) {
DSGXMtxIdentity(&gx->posMatrix);
DSGXMtxIdentity(&gx->vecMatrix);
DSGXMtxIdentity(&gx->vertexMatrix);
DSGXMtxIdentity(&gx->clipMatrix);
DSGXMtxIdentity(&gx->projMatrixStack);
DSGXMtxIdentity(&gx->texMatrixStack);
int i;
@ -682,6 +684,13 @@ void DSGXReset(struct DSGX* gx) {
gx->pvMatrixPointer = 0;
gx->vertexMode = -1;
gx->viewportX1 = 0;
gx->viewportY1 = 0;
gx->viewportX2 = DS_VIDEO_HORIZONTAL_PIXELS - 1;
gx->viewportY2 = DS_VIDEO_VERTICAL_PIXELS - 1;
gx->viewportWidth = gx->viewportX2 - gx->viewportX1;
gx->viewportHeight = gx->viewportY2 - gx->viewportY1;
memset(gx->outstandingParams, 0, sizeof(gx->outstandingParams));
memset(gx->outstandingCommand, 0, sizeof(gx->outstandingCommand));
gx->activeParams = 0;

View File

@ -32,25 +32,26 @@ void DSGXMtxIdentity(struct DSGXMatrix* mtx) {
mtx->m[15] = MTX_ONE;
}
void DSGXMtxMultiply(struct DSGXMatrix* mtx, const struct DSGXMatrix* m) {
struct DSGXMatrix out;
out.m[0] = _dot(&mtx->m[0], &m->m[0]);
out.m[1] = _dot(&mtx->m[1], &m->m[0]);
out.m[2] = _dot(&mtx->m[2], &m->m[0]);
out.m[3] = _dot(&mtx->m[3], &m->m[0]);
out.m[4] = _dot(&mtx->m[0], &m->m[4]);
out.m[5] = _dot(&mtx->m[1], &m->m[4]);
out.m[6] = _dot(&mtx->m[2], &m->m[4]);
out.m[7] = _dot(&mtx->m[3], &m->m[4]);
out.m[8] = _dot(&mtx->m[0], &m->m[8]);
out.m[9] = _dot(&mtx->m[1], &m->m[8]);
out.m[10] = _dot(&mtx->m[2], &m->m[8]);
out.m[11] = _dot(&mtx->m[3], &m->m[8]);
out.m[12] = _dot(&mtx->m[0], &m->m[12]);
out.m[13] = _dot(&mtx->m[1], &m->m[12]);
out.m[14] = _dot(&mtx->m[2], &m->m[12]);
out.m[15] = _dot(&mtx->m[3], &m->m[12]);
*mtx = out;
void DSGXMtxMultiply(struct DSGXMatrix* out, const struct DSGXMatrix* a, const struct DSGXMatrix* b) {
struct DSGXMatrix o;
// XXX: This is transposed because DS matrices are transposed
o.m[0] = _dot(&a->m[0], &b->m[0]);
o.m[1] = _dot(&a->m[1], &b->m[0]);
o.m[2] = _dot(&a->m[2], &b->m[0]);
o.m[3] = _dot(&a->m[3], &b->m[0]);
o.m[4] = _dot(&a->m[0], &b->m[4]);
o.m[5] = _dot(&a->m[1], &b->m[4]);
o.m[6] = _dot(&a->m[2], &b->m[4]);
o.m[7] = _dot(&a->m[3], &b->m[4]);
o.m[8] = _dot(&a->m[0], &b->m[8]);
o.m[9] = _dot(&a->m[1], &b->m[8]);
o.m[10] = _dot(&a->m[2], &b->m[8]);
o.m[11] = _dot(&a->m[3], &b->m[8]);
o.m[12] = _dot(&a->m[0], &b->m[12]);
o.m[13] = _dot(&a->m[1], &b->m[12]);
o.m[14] = _dot(&a->m[2], &b->m[12]);
o.m[15] = _dot(&a->m[3], &b->m[12]);
*out = o;
}
void DSGXMtxScale(struct DSGXMatrix* mtx, const int32_t* m) {
@ -62,7 +63,7 @@ void DSGXMtxScale(struct DSGXMatrix* mtx, const int32_t* m) {
0, 0, 0, MTX_ONE
}
};
DSGXMtxMultiply(mtx, &s);
DSGXMtxMultiply(mtx, &s, mtx);
}
void DSGXMtxTranslate(struct DSGXMatrix* mtx, const int32_t* m) {
@ -74,5 +75,5 @@ void DSGXMtxTranslate(struct DSGXMatrix* mtx, const int32_t* m) {
m[0], m[1], m[2], MTX_ONE
}
};
DSGXMtxMultiply(mtx, &t);
DSGXMtxMultiply(mtx, &t, mtx);
}