mirror of https://github.com/mgba-emu/mgba.git
DS GX: Process vertex list
This commit is contained in:
parent
1bc3170755
commit
778eb8bc3b
|
@ -83,10 +83,17 @@ struct DSGXEntry {
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct DSGXVertex {
|
struct DSGXVertex {
|
||||||
|
// World coords
|
||||||
|
int16_t x; // 4.12
|
||||||
|
int16_t y; // 4.12
|
||||||
|
int16_t z; // 4.12
|
||||||
|
|
||||||
// Viewport coords
|
// Viewport coords
|
||||||
int32_t x; // 16.16
|
int32_t vx; // 16.16
|
||||||
int32_t y; // 16.16
|
int32_t vy; // 16.16
|
||||||
int32_t z; // 16.16
|
int32_t vz; // 16.16
|
||||||
|
int32_t vw; // 16.16
|
||||||
|
|
||||||
uint16_t color;
|
uint16_t color;
|
||||||
// Texcoords
|
// Texcoords
|
||||||
int16_t s; // 12.4
|
int16_t s; // 12.4
|
||||||
|
@ -94,6 +101,7 @@ struct DSGXVertex {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DSGXPolygon {
|
struct DSGXPolygon {
|
||||||
|
uint32_t polyParams;
|
||||||
int verts;
|
int verts;
|
||||||
unsigned vertIds[4];
|
unsigned vertIds[4];
|
||||||
};
|
};
|
||||||
|
@ -125,6 +133,8 @@ struct DSGX {
|
||||||
|
|
||||||
bool swapBuffers;
|
bool swapBuffers;
|
||||||
int bufferIndex;
|
int bufferIndex;
|
||||||
|
int vertexIndex;
|
||||||
|
int polygonIndex;
|
||||||
struct DSGXVertex* vertexBuffer[2];
|
struct DSGXVertex* vertexBuffer[2];
|
||||||
struct DSGXPolygon* polygonBuffer[2];
|
struct DSGXPolygon* polygonBuffer[2];
|
||||||
|
|
||||||
|
@ -139,6 +149,12 @@ struct DSGX {
|
||||||
struct DSGXMatrix texMatrix;
|
struct DSGXMatrix texMatrix;
|
||||||
struct DSGXMatrix posMatrix;
|
struct DSGXMatrix posMatrix;
|
||||||
struct DSGXMatrix vecMatrix;
|
struct DSGXMatrix vecMatrix;
|
||||||
|
|
||||||
|
struct DSGXMatrix vertexMatrix;
|
||||||
|
|
||||||
|
int vertexMode;
|
||||||
|
struct DSGXVertex currentVertex;
|
||||||
|
struct DSGXPolygon currentPoly;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DSGXInit(struct DSGX*);
|
void DSGXInit(struct DSGX*);
|
||||||
|
|
180
src/ds/gx.c
180
src/ds/gx.c
|
@ -12,6 +12,8 @@ mLOG_DEFINE_CATEGORY(DS_GX, "DS GX");
|
||||||
|
|
||||||
#define DS_GX_FIFO_SIZE 256
|
#define DS_GX_FIFO_SIZE 256
|
||||||
#define DS_GX_PIPE_SIZE 4
|
#define DS_GX_PIPE_SIZE 4
|
||||||
|
#define DS_GX_POLYGON_BUFFER_SIZE 2048
|
||||||
|
#define DS_GX_VERTEX_BUFFER_SIZE 6144
|
||||||
|
|
||||||
static void DSGXDummyRendererInit(struct DSGXRenderer* renderer);
|
static void DSGXDummyRendererInit(struct DSGXRenderer* renderer);
|
||||||
static void DSGXDummyRendererReset(struct DSGXRenderer* renderer);
|
static void DSGXDummyRendererReset(struct DSGXRenderer* renderer);
|
||||||
|
@ -136,6 +138,87 @@ 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 int32_t _dotViewport(struct DSGXVertex* vertex, int32_t* col) {
|
||||||
|
int64_t a;
|
||||||
|
int64_t b;
|
||||||
|
int64_t sum;
|
||||||
|
a = col[0];
|
||||||
|
b = vertex->x;
|
||||||
|
sum = a * b;
|
||||||
|
a = col[4];
|
||||||
|
b = vertex->y;
|
||||||
|
sum += a * b;
|
||||||
|
a = col[8];
|
||||||
|
b = vertex->z;
|
||||||
|
sum += a * b;
|
||||||
|
a = col[12];
|
||||||
|
b = MTX_ONE;
|
||||||
|
sum += a * b;
|
||||||
|
return sum >> 8LL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _emitVertex(struct DSGX* gx, uint16_t x, uint16_t y, uint16_t z) {
|
||||||
|
if (gx->vertexMode < 0 || gx->vertexIndex == DS_GX_VERTEX_BUFFER_SIZE || gx->polygonIndex == DS_GX_POLYGON_BUFFER_SIZE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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]);
|
||||||
|
|
||||||
|
struct DSGXVertex* vbuf = gx->vertexBuffer[gx->bufferIndex];
|
||||||
|
vbuf[gx->vertexIndex] = gx->currentVertex;
|
||||||
|
|
||||||
|
gx->currentPoly.vertIds[gx->currentPoly.verts] = gx->vertexIndex;
|
||||||
|
|
||||||
|
++gx->vertexIndex;
|
||||||
|
++gx->currentPoly.verts;
|
||||||
|
int totalVertices;
|
||||||
|
switch (gx->vertexMode) {
|
||||||
|
case 0:
|
||||||
|
case 2:
|
||||||
|
totalVertices = 3;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
totalVertices = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (gx->currentPoly.verts == totalVertices) {
|
||||||
|
struct DSGXPolygon* pbuf = gx->polygonBuffer[gx->bufferIndex];
|
||||||
|
pbuf[gx->polygonIndex] = gx->currentPoly;
|
||||||
|
|
||||||
|
switch (gx->vertexMode) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
gx->currentPoly.verts = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
gx->currentPoly.vertIds[0] = gx->currentPoly.vertIds[1];
|
||||||
|
gx->currentPoly.vertIds[1] = gx->currentPoly.vertIds[2];
|
||||||
|
gx->currentPoly.verts = 2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
gx->currentPoly.vertIds[0] = gx->currentPoly.vertIds[2];
|
||||||
|
gx->currentPoly.vertIds[1] = gx->currentPoly.vertIds[3];
|
||||||
|
// Ensure quads don't cross over
|
||||||
|
pbuf[gx->polygonIndex].vertIds[2] = gx->currentPoly.vertIds[3];
|
||||||
|
pbuf[gx->polygonIndex].vertIds[3] = gx->currentPoly.vertIds[2];
|
||||||
|
gx->currentPoly.verts = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++gx->polygonIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
||||||
struct DSGX* gx = context;
|
struct DSGX* gx = context;
|
||||||
uint32_t cycles;
|
uint32_t cycles;
|
||||||
|
@ -211,6 +294,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
mLOG(DS_GX, STUB, "Unimplemented GX MTX_PUSH mode");
|
mLOG(DS_GX, STUB, "Unimplemented GX MTX_PUSH mode");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_updateVertexMatrix(gx);
|
||||||
break;
|
break;
|
||||||
case DS_GX_CMD_MTX_POP: {
|
case DS_GX_CMD_MTX_POP: {
|
||||||
int8_t offset = entry.params[0];
|
int8_t offset = entry.params[0];
|
||||||
|
@ -234,6 +318,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
mLOG(DS_GX, STUB, "Unimplemented GX MTX_POP mode");
|
mLOG(DS_GX, STUB, "Unimplemented GX MTX_POP mode");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_updateVertexMatrix(gx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_MTX_IDENTITY:
|
case DS_GX_CMD_MTX_IDENTITY:
|
||||||
|
@ -251,6 +336,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
DSGXMtxIdentity(&gx->texMatrix);
|
DSGXMtxIdentity(&gx->texMatrix);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_updateVertexMatrix(gx);
|
||||||
break;
|
break;
|
||||||
case DS_GX_CMD_MTX_LOAD_4x4: {
|
case DS_GX_CMD_MTX_LOAD_4x4: {
|
||||||
struct DSGXMatrix m;
|
struct DSGXMatrix m;
|
||||||
|
@ -275,6 +361,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix));
|
memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_updateVertexMatrix(gx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_MTX_LOAD_4x3: {
|
case DS_GX_CMD_MTX_LOAD_4x3: {
|
||||||
|
@ -304,6 +391,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix));
|
memcpy(&gx->texMatrix, &m, sizeof(gx->texMatrix));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_updateVertexMatrix(gx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_MTX_MULT_4x4: {
|
case DS_GX_CMD_MTX_MULT_4x4: {
|
||||||
|
@ -329,6 +417,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
DSGXMtxMultiply(&gx->texMatrix, &m);
|
DSGXMtxMultiply(&gx->texMatrix, &m);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_updateVertexMatrix(gx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_MTX_MULT_4x3: {
|
case DS_GX_CMD_MTX_MULT_4x3: {
|
||||||
|
@ -358,6 +447,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
DSGXMtxMultiply(&gx->texMatrix, &m);
|
DSGXMtxMultiply(&gx->texMatrix, &m);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_updateVertexMatrix(gx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_MTX_MULT_3x3: {
|
case DS_GX_CMD_MTX_MULT_3x3: {
|
||||||
|
@ -390,6 +480,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
memcpy(&gx->texMatrix, &m, sizeof(gx->projMatrix));
|
memcpy(&gx->texMatrix, &m, sizeof(gx->projMatrix));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_updateVertexMatrix(gx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DS_GX_CMD_MTX_TRANS: {
|
case DS_GX_CMD_MTX_TRANS: {
|
||||||
|
@ -452,6 +543,74 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DS_GX_CMD_COLOR:
|
||||||
|
gx->currentVertex.color = entry.params[0];
|
||||||
|
gx->currentVertex.color |= entry.params[1] << 8;
|
||||||
|
break;
|
||||||
|
case DS_GX_CMD_TEXCOORD:
|
||||||
|
gx->currentVertex.s = entry.params[0];
|
||||||
|
gx->currentVertex.s |= entry.params[1] << 8;
|
||||||
|
gx->currentVertex.t = entry.params[2];
|
||||||
|
gx->currentVertex.t |= entry.params[3] << 8;
|
||||||
|
break;
|
||||||
|
case DS_GX_CMD_VTX_16: {
|
||||||
|
int16_t x = gx->activeEntries[0].params[0];
|
||||||
|
x |= gx->activeEntries[0].params[1] << 8;
|
||||||
|
int16_t y = gx->activeEntries[0].params[2];
|
||||||
|
y |= gx->activeEntries[0].params[3] << 8;
|
||||||
|
int16_t z = gx->activeEntries[1].params[0];
|
||||||
|
z |= gx->activeEntries[1].params[1] << 8;
|
||||||
|
_emitVertex(gx, x, y, z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DS_GX_CMD_VTX_10: {
|
||||||
|
int32_t xyz = gx->activeEntries[0].params[0];
|
||||||
|
xyz |= gx->activeEntries[0].params[1] << 8;
|
||||||
|
xyz |= gx->activeEntries[0].params[2] << 16;
|
||||||
|
xyz |= gx->activeEntries[0].params[3] << 24;
|
||||||
|
int16_t x = (xyz << 6) & 0xFFC0;
|
||||||
|
int16_t y = (xyz >> 4) & 0xFFC0;
|
||||||
|
int16_t z = (xyz >> 14) & 0xFFC0;
|
||||||
|
_emitVertex(gx, x, y, z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DS_GX_CMD_VTX_XY: {
|
||||||
|
int16_t x = gx->activeEntries[0].params[0];
|
||||||
|
x |= gx->activeEntries[0].params[1] << 8;
|
||||||
|
int16_t y = gx->activeEntries[0].params[2];
|
||||||
|
y |= gx->activeEntries[0].params[3] << 8;
|
||||||
|
_emitVertex(gx, x, y, gx->currentVertex.z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DS_GX_CMD_VTX_XZ: {
|
||||||
|
int16_t x = gx->activeEntries[0].params[0];
|
||||||
|
x |= gx->activeEntries[0].params[1] << 8;
|
||||||
|
int16_t z = gx->activeEntries[0].params[2];
|
||||||
|
z |= gx->activeEntries[0].params[3] << 8;
|
||||||
|
_emitVertex(gx, x, gx->currentVertex.y, z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DS_GX_CMD_VTX_YZ: {
|
||||||
|
int16_t y = gx->activeEntries[0].params[0];
|
||||||
|
y |= gx->activeEntries[0].params[1] << 8;
|
||||||
|
int16_t z = gx->activeEntries[0].params[2];
|
||||||
|
z |= gx->activeEntries[0].params[3] << 8;
|
||||||
|
_emitVertex(gx, gx->currentVertex.x, y, z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DS_GX_CMD_POLYGON_ATTR:
|
||||||
|
gx->currentPoly.polyParams = entry.params[0];
|
||||||
|
gx->currentPoly.polyParams |= entry.params[1] << 8;
|
||||||
|
gx->currentPoly.polyParams |= entry.params[2] << 16;
|
||||||
|
gx->currentPoly.polyParams |= entry.params[3] << 24;
|
||||||
|
break;
|
||||||
|
case DS_GX_CMD_BEGIN_VTXS:
|
||||||
|
gx->vertexMode = entry.params[0] & 3;
|
||||||
|
gx->currentPoly.verts = 0;
|
||||||
|
break;
|
||||||
|
case DS_GX_CMD_END_VTXS:
|
||||||
|
gx->vertexMode = -1;
|
||||||
|
break;
|
||||||
case DS_GX_CMD_SWAP_BUFFERS:
|
case DS_GX_CMD_SWAP_BUFFERS:
|
||||||
gx->swapBuffers = true;
|
gx->swapBuffers = true;
|
||||||
break;
|
break;
|
||||||
|
@ -481,6 +640,10 @@ void DSGXInit(struct DSGX* gx) {
|
||||||
gx->renderer = &dummyRenderer;
|
gx->renderer = &dummyRenderer;
|
||||||
CircleBufferInit(&gx->fifo, sizeof(struct DSGXEntry) * DS_GX_FIFO_SIZE);
|
CircleBufferInit(&gx->fifo, sizeof(struct DSGXEntry) * DS_GX_FIFO_SIZE);
|
||||||
CircleBufferInit(&gx->pipe, sizeof(struct DSGXEntry) * DS_GX_PIPE_SIZE);
|
CircleBufferInit(&gx->pipe, sizeof(struct DSGXEntry) * DS_GX_PIPE_SIZE);
|
||||||
|
gx->vertexBuffer[0] = malloc(sizeof(struct DSGXVertex) * DS_GX_VERTEX_BUFFER_SIZE);
|
||||||
|
gx->vertexBuffer[1] = malloc(sizeof(struct DSGXVertex) * DS_GX_VERTEX_BUFFER_SIZE);
|
||||||
|
gx->polygonBuffer[0] = malloc(sizeof(struct DSGXPolygon) * DS_GX_POLYGON_BUFFER_SIZE);
|
||||||
|
gx->polygonBuffer[1] = malloc(sizeof(struct DSGXPolygon) * DS_GX_POLYGON_BUFFER_SIZE);
|
||||||
gx->fifoEvent.name = "DS GX FIFO";
|
gx->fifoEvent.name = "DS GX FIFO";
|
||||||
gx->fifoEvent.priority = 0xC;
|
gx->fifoEvent.priority = 0xC;
|
||||||
gx->fifoEvent.context = gx;
|
gx->fifoEvent.context = gx;
|
||||||
|
@ -491,6 +654,10 @@ void DSGXDeinit(struct DSGX* gx) {
|
||||||
DSGXAssociateRenderer(gx, &dummyRenderer);
|
DSGXAssociateRenderer(gx, &dummyRenderer);
|
||||||
CircleBufferDeinit(&gx->fifo);
|
CircleBufferDeinit(&gx->fifo);
|
||||||
CircleBufferDeinit(&gx->pipe);
|
CircleBufferDeinit(&gx->pipe);
|
||||||
|
free(gx->vertexBuffer[0]);
|
||||||
|
free(gx->vertexBuffer[1]);
|
||||||
|
free(gx->polygonBuffer[0]);
|
||||||
|
free(gx->polygonBuffer[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSGXReset(struct DSGX* gx) {
|
void DSGXReset(struct DSGX* gx) {
|
||||||
|
@ -501,6 +668,7 @@ void DSGXReset(struct DSGX* gx) {
|
||||||
DSGXMtxIdentity(&gx->posMatrix);
|
DSGXMtxIdentity(&gx->posMatrix);
|
||||||
DSGXMtxIdentity(&gx->vecMatrix);
|
DSGXMtxIdentity(&gx->vecMatrix);
|
||||||
|
|
||||||
|
DSGXMtxIdentity(&gx->vertexMatrix);
|
||||||
DSGXMtxIdentity(&gx->projMatrixStack);
|
DSGXMtxIdentity(&gx->projMatrixStack);
|
||||||
DSGXMtxIdentity(&gx->texMatrixStack);
|
DSGXMtxIdentity(&gx->texMatrixStack);
|
||||||
int i;
|
int i;
|
||||||
|
@ -510,12 +678,16 @@ void DSGXReset(struct DSGX* gx) {
|
||||||
}
|
}
|
||||||
gx->swapBuffers = false;
|
gx->swapBuffers = false;
|
||||||
gx->bufferIndex = 0;
|
gx->bufferIndex = 0;
|
||||||
|
gx->vertexIndex = 0;
|
||||||
|
gx->polygonIndex = 0;
|
||||||
gx->mtxMode = 0;
|
gx->mtxMode = 0;
|
||||||
gx->pvMatrixPointer = 0;
|
gx->pvMatrixPointer = 0;
|
||||||
|
gx->vertexMode = -1;
|
||||||
|
|
||||||
memset(gx->outstandingParams, 0, sizeof(gx->outstandingParams));
|
memset(gx->outstandingParams, 0, sizeof(gx->outstandingParams));
|
||||||
memset(gx->outstandingCommand, 0, sizeof(gx->outstandingCommand));
|
memset(gx->outstandingCommand, 0, sizeof(gx->outstandingCommand));
|
||||||
gx->activeParams = 0;
|
gx->activeParams = 0;
|
||||||
|
memset(&gx->currentVertex, 0, sizeof(gx->currentVertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSGXAssociateRenderer(struct DSGX* gx, struct DSGXRenderer* renderer) {
|
void DSGXAssociateRenderer(struct DSGX* gx, struct DSGXRenderer* renderer) {
|
||||||
|
@ -702,10 +874,14 @@ uint32_t DSGXWriteRegister32(struct DSGX* gx, uint32_t address, uint32_t value)
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSGXSwapBuffers(struct DSGX* gx) {
|
void DSGXSwapBuffers(struct DSGX* gx) {
|
||||||
mLOG(DS_GX, STUB, "Unimplemented GX swap buffers");
|
|
||||||
gx->swapBuffers = false;
|
gx->swapBuffers = false;
|
||||||
|
|
||||||
// TODO
|
gx->renderer->setRAM(gx->renderer, gx->vertexBuffer[gx->bufferIndex], gx->polygonBuffer[gx->bufferIndex], gx->polygonIndex);
|
||||||
|
|
||||||
|
gx->bufferIndex ^= 1;
|
||||||
|
gx->vertexIndex = 0;
|
||||||
|
gx->polygonIndex = 0;
|
||||||
|
|
||||||
DSGXUpdateGXSTAT(gx);
|
DSGXUpdateGXSTAT(gx);
|
||||||
if (CircleBufferSize(&gx->fifo)) {
|
if (CircleBufferSize(&gx->fifo)) {
|
||||||
mTimingSchedule(&gx->p->ds9.timing, &gx->fifoEvent, 0);
|
mTimingSchedule(&gx->p->ds9.timing, &gx->fifoEvent, 0);
|
||||||
|
|
Loading…
Reference in New Issue