DS GX: Stub out GX renderer

This commit is contained in:
Vicki Pfau 2017-02-27 16:55:14 -08:00
parent 2f0ab002e2
commit e8bfc7bcca
4 changed files with 101 additions and 4 deletions
include/mgba/internal/ds
src/ds

View File

@ -10,6 +10,7 @@
CXX_GUARD_START
#include <mgba/core/interface.h>
#include <mgba/core/log.h>
#include <mgba/core/timing.h>
#include <mgba-util/circle-buffer.h>
@ -80,9 +81,36 @@ struct DSGXEntry {
};
#pragma pack(pop)
struct DSGXVertex {
// Viewport coords
int32_t x; // 16.16
int32_t y; // 16.16
int32_t z; // 16.16
uint16_t color;
// Texcoords
int16_t s; // 12.4
int16_t t; // 12.4
};
struct DSGXPolygon {
int verts;
unsigned vertIds[4];
};
struct DSGXRenderer {
void (*init)(struct DSGXRenderer* renderer);
void (*reset)(struct DSGXRenderer* renderer);
void (*deinit)(struct DSGXRenderer* renderer);
void (*setRAM)(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount);
void (*drawScanline)(struct DSGXRenderer* renderer, int y);
void (*getScanline)(struct DSGXRenderer* renderer, int y, color_t** output);
};
struct DS;
struct DSGX {
struct DS* p;
struct DSGXRenderer* renderer;
struct CircleBuffer fifo;
struct CircleBuffer pipe;
@ -92,11 +120,15 @@ struct DSGX {
uint8_t outstandingCommand[4];
bool swapBuffers;
int bufferIndex;
struct DSGXVertex* vertexBuffer[2];
struct DSGXPolygon* polygonBuffer[2];
};
void DSGXInit(struct DSGX*);
void DSGXDeinit(struct DSGX*);
void DSGXReset(struct DSGX*);
void DSGXAssociateRenderer(struct DSGX* video, struct DSGXRenderer* renderer);
uint16_t DSGXWriteRegister(struct DSGX*, uint32_t address, uint16_t value);
uint32_t DSGXWriteRegister32(struct DSGX*, uint32_t address, uint32_t value);

View File

@ -70,6 +70,7 @@ DECL_BITFIELD(DSRegisterMASTER_BRIGHT, uint16_t);
DECL_BITS(DSRegisterMASTER_BRIGHT, Y, 0, 5);
DECL_BITS(DSRegisterMASTER_BRIGHT, Mode, 14, 2);
struct DSGX;
struct DSVideoRenderer {
void (*init)(struct DSVideoRenderer* renderer);
void (*reset)(struct DSVideoRenderer* renderer);
@ -96,6 +97,7 @@ struct DSVideoRenderer {
uint16_t* vramBBGExtPal[4];
uint16_t* vramBOBJExtPal;
union DSOAM* oam;
struct DSGX* gx;
};
struct DS;

View File

@ -13,6 +13,13 @@ mLOG_DEFINE_CATEGORY(DS_GX, "DS GX");
#define DS_GX_FIFO_SIZE 256
#define DS_GX_PIPE_SIZE 4
static void DSGXDummyRendererInit(struct DSGXRenderer* renderer);
static void DSGXDummyRendererReset(struct DSGXRenderer* renderer);
static void DSGXDummyRendererDeinit(struct DSGXRenderer* renderer);
static void DSGXDummyRendererSetRAM(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount);
static void DSGXDummyRendererDrawScanline(struct DSGXRenderer* renderer, int y);
static void DSGXDummyRendererGetScanline(struct DSGXRenderer* renderer, int y, color_t** output);
static const int32_t _gxCommandCycleBase[DS_GX_CMD_MAX] = {
[DS_GX_CMD_NOP] = 0,
[DS_GX_CMD_MTX_MODE] = 2,
@ -91,6 +98,15 @@ static const int32_t _gxCommandParams[DS_GX_CMD_MAX] = {
[DS_GX_CMD_VEC_TEST] = 1,
};
static struct DSGXRenderer dummyRenderer = {
.init = DSGXDummyRendererInit,
.reset = DSGXDummyRendererReset,
.deinit = DSGXDummyRendererDeinit,
.setRAM = DSGXDummyRendererSetRAM,
.drawScanline = DSGXDummyRendererDrawScanline,
.getScanline = DSGXDummyRendererGetScanline,
};
static void _pullPipe(struct DSGX* gx) {
if (CircleBufferSize(&gx->fifo) >= sizeof(struct DSGXEntry)) {
struct DSGXEntry entry = { 0 };
@ -171,6 +187,7 @@ static void _fifoRun(struct mTiming* timing, void* context, uint32_t cyclesLate)
}
void DSGXInit(struct DSGX* gx) {
gx->renderer = &dummyRenderer;
CircleBufferInit(&gx->fifo, sizeof(struct DSGXEntry) * DS_GX_FIFO_SIZE);
CircleBufferInit(&gx->pipe, sizeof(struct DSGXEntry) * DS_GX_PIPE_SIZE);
gx->fifoEvent.name = "DS GX FIFO";
@ -180,6 +197,7 @@ void DSGXInit(struct DSGX* gx) {
}
void DSGXDeinit(struct DSGX* gx) {
DSGXAssociateRenderer(gx, &dummyRenderer);
CircleBufferDeinit(&gx->fifo);
CircleBufferDeinit(&gx->pipe);
}
@ -192,6 +210,12 @@ void DSGXReset(struct DSGX* gx) {
memset(gx->outstandingCommand, 0, sizeof(gx->outstandingCommand));
}
void DSGXAssociateRenderer(struct DSGX* gx, struct DSGXRenderer* renderer) {
gx->renderer->deinit(gx->renderer);
gx->renderer = renderer;
gx->renderer->init(gx->renderer);
}
void DSGXUpdateGXSTAT(struct DSGX* gx) {
uint32_t value = gx->p->memory.io9[DS9_REG_GXSTAT_HI >> 1] << 16;
value = DSRegGXSTATIsDoIRQ(value);
@ -379,3 +403,39 @@ void DSGXSwapBuffers(struct DSGX* gx) {
mTimingSchedule(&gx->p->ds9.timing, &gx->fifoEvent, 0);
}
}
static void DSGXDummyRendererInit(struct DSGXRenderer* renderer) {
UNUSED(renderer);
// Nothing to do
}
static void DSGXDummyRendererReset(struct DSGXRenderer* renderer) {
UNUSED(renderer);
// Nothing to do
}
static void DSGXDummyRendererDeinit(struct DSGXRenderer* renderer) {
UNUSED(renderer);
// Nothing to do
}
static void DSGXDummyRendererSetRAM(struct DSGXRenderer* renderer, struct DSGXVertex* verts, struct DSGXPolygon* polys, unsigned polyCount) {
UNUSED(renderer);
UNUSED(verts);
UNUSED(polys);
UNUSED(polyCount);
// Nothing to do
}
static void DSGXDummyRendererDrawScanline(struct DSGXRenderer* renderer, int y) {
UNUSED(renderer);
UNUSED(y);
// Nothing to do
}
static void DSGXDummyRendererGetScanline(struct DSGXRenderer* renderer, int y, color_t** output) {
UNUSED(renderer);
UNUSED(y);
*output = NULL;
// Nothing to do
}

View File

@ -7,6 +7,7 @@
#include "gba/renderers/software-private.h"
#include <mgba/internal/arm/macros.h>
#include <mgba/internal/ds/gx.h>
#include <mgba/internal/ds/io.h>
static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer);
@ -354,7 +355,7 @@ static void DSVideoSoftwareRendererInvalidateExtPal(struct DSVideoRenderer* rend
_regenerateExtPalette(softwareRenderer, obj, engB, slot);
}
static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* renderer, int y) {
static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* renderer, struct DSGX* gx, int y) {
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
int x;
@ -381,7 +382,9 @@ static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* rend
GBAVideoSoftwareRendererPostprocessSprite(softwareRenderer, priority);
}
if (TEST_LAYER_ENABLED(0)) {
if (DSRegisterDISPCNTIs3D(softwareRenderer->dispcnt)) {
if (DSRegisterDISPCNTIs3D(softwareRenderer->dispcnt) && gx) {
color_t* scanline;
gx->renderer->getScanline(gx->renderer, y, &scanline);
// TODO
} else {
GBAVideoSoftwareRendererDrawBackgroundMode0(softwareRenderer, &softwareRenderer->bg[0], y);
@ -472,7 +475,7 @@ static void _drawScanlineA(struct DSVideoSoftwareRenderer* softwareRenderer, int
}
return;
case 1:
DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engA.d, y);
DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engA.d, softwareRenderer->d.gx, y);
return;
case 2: {
uint16_t* vram = &softwareRenderer->d.vram[0x10000 * DSRegisterDISPCNTGetVRAMBlock(softwareRenderer->dispcntA)];
@ -527,7 +530,7 @@ static void _drawScanlineB(struct DSVideoSoftwareRenderer* softwareRenderer, int
}
return;
case 1:
DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engB.d, y);
DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engB.d, NULL, y);
return;
}