initial work on GPU
This commit is contained in:
@@ -414,7 +414,7 @@ int main(int argc, char **argv) {
|
||||
double wattage = 0;
|
||||
|
||||
nn_Component *screen = ncl_createScreen(u, NULL, &nn_defaultScreens[3]);
|
||||
//nn_Component *gpu = ncl_createGPU(u, NULL, &nn_defaultGPUs[3]);
|
||||
nn_Component *gpuCard = ncl_createGPU(u, NULL, &nn_defaultGPUs[3]);
|
||||
|
||||
{
|
||||
// draw test
|
||||
@@ -444,6 +444,7 @@ restart:;
|
||||
nn_mountComponent(c, ocelotCard, -1);
|
||||
nn_mountComponent(c, eepromCard, 0);
|
||||
nn_mountComponent(c, managedfs, 1);
|
||||
nn_mountComponent(c, gpuCard, 2);
|
||||
|
||||
while(true) {
|
||||
if(WindowShouldClose()) break;
|
||||
@@ -578,6 +579,7 @@ cleanup:;
|
||||
nn_dropComponent(eepromCard);
|
||||
nn_dropComponent(managedfs);
|
||||
nn_dropComponent(screen);
|
||||
nn_dropComponent(gpuCard);
|
||||
// rip the universe
|
||||
nn_destroyUniverse(u);
|
||||
UnloadFont(font);
|
||||
|
||||
112
src/ncomplib.c
112
src/ncomplib.c
@@ -438,6 +438,30 @@ static ncl_VRAMBuf *ncl_allocVRAM(nn_Context *ctx, int width, int height) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
static ncl_ScreenPixel *ncl_vramPtr(ncl_VRAMBuf *buf, int x, int y) {
|
||||
x--;
|
||||
y--;
|
||||
if(x < 0 || y < 0 || x >= buf->width || y >= buf->height) return NULL;
|
||||
return &buf->pixels[x + y * buf->width];
|
||||
}
|
||||
|
||||
static ncl_ScreenPixel ncl_vramGet(ncl_VRAMBuf *buf, int x, int y) {
|
||||
ncl_ScreenPixel *ptr = ncl_vramPtr(buf, x, y);
|
||||
if(ptr != NULL) return *ptr;
|
||||
return (ncl_ScreenPixel) {
|
||||
.codepoint = ' ',
|
||||
.storedFg = 0xFFFFFF,
|
||||
.storedBg = 0x000000,
|
||||
.realFg = 0xFFFFFF,
|
||||
.realBg = 0x000000,
|
||||
};
|
||||
}
|
||||
|
||||
static void ncl_vramSet(ncl_VRAMBuf *buf, int x, int y, ncl_ScreenPixel pixel) {
|
||||
ncl_ScreenPixel *ptr = ncl_vramPtr(buf, x, y);
|
||||
if(ptr != NULL) *ptr = pixel;
|
||||
}
|
||||
|
||||
typedef struct ncl_FSState {
|
||||
nn_Context *ctx;
|
||||
nn_Lock *lock;
|
||||
@@ -590,6 +614,11 @@ static nn_Exit ncl_fsHandler(nn_FSRequest *req) {
|
||||
}
|
||||
state->fds[fd] = file;
|
||||
req->fd = fd;
|
||||
if(mode[0] == 'w') {
|
||||
// file cleared
|
||||
state->spaceUsed = 0;
|
||||
state->realSpaceUsed = 0;
|
||||
}
|
||||
nn_unlock(ctx, state->lock);
|
||||
return NN_OK;
|
||||
}
|
||||
@@ -1008,7 +1037,88 @@ fail:;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nn_Component *ncl_createGPU(nn_Universe *universe, const char *address, const nn_GPU *gpu);
|
||||
static ncl_ScreenState *ncl_getBoundScreen(ncl_GPUState *gpu, nn_Computer *C) {
|
||||
if(gpu->screenAddress == NULL) return NULL;
|
||||
nn_Component *c = nn_getComponent(C, gpu->screenAddress);
|
||||
if(c == NULL) return NULL;
|
||||
return nn_getComponentState(c);
|
||||
}
|
||||
|
||||
static void ncl_getGPULimits(ncl_GPUState *gpu, nn_Computer *C, int *maxWidth, int *maxHeight, char *maxDepth) {
|
||||
int w = gpu->conf.maxWidth, h = gpu->conf.maxHeight;
|
||||
char d = gpu->conf.maxDepth;
|
||||
|
||||
ncl_ScreenState *screen = ncl_getBoundScreen(gpu, C);
|
||||
|
||||
if(screen != NULL) {
|
||||
if(w > screen->conf.maxWidth) w = screen->conf.maxWidth;
|
||||
if(h > screen->conf.maxHeight) h = screen->conf.maxHeight;
|
||||
if(d > screen->conf.maxDepth) d = screen->conf.maxDepth;
|
||||
}
|
||||
|
||||
*maxWidth = w;
|
||||
*maxHeight = h;
|
||||
*maxDepth = d;
|
||||
}
|
||||
|
||||
static nn_Exit ncl_gpuHandler(nn_GPURequest *req) {
|
||||
nn_Context *ctx = req->ctx;
|
||||
nn_Computer *C = req->computer;
|
||||
ncl_GPUState *state = req->state;
|
||||
const nn_GPU *gpu = req->gpu;
|
||||
if(req->action == NN_GPU_DROP) {
|
||||
for(size_t i = 0; i < NCL_MAX_VRAMBUF; i++) {
|
||||
if(state->vram[i] != NULL) ncl_freeVRAM(ctx, state->vram[i]);
|
||||
}
|
||||
if(state->screenAddress != NULL) nn_strfree(ctx, state->screenAddress);
|
||||
nn_free(ctx, state, sizeof(*state));
|
||||
return NN_OK;
|
||||
}
|
||||
if(C != NULL) nn_setError(C, "ncl-gpu: not implemented yet");
|
||||
return NN_EBADCALL;
|
||||
}
|
||||
|
||||
nn_Component *ncl_createGPU(nn_Universe *universe, const char *address, const nn_GPU *gpu) {
|
||||
nn_Context *ctx = nn_getUniverseContext(universe);
|
||||
nn_Lock *lock = NULL;
|
||||
ncl_GPUState *state = NULL;
|
||||
nn_Component *c = NULL;
|
||||
|
||||
lock = nn_createLock(ctx);
|
||||
if(lock == NULL) goto fail;
|
||||
|
||||
state = nn_alloc(ctx, sizeof(*state));
|
||||
if(state == NULL) goto fail;
|
||||
|
||||
state->ctx = ctx;
|
||||
state->lock = lock;
|
||||
state->conf = *gpu;
|
||||
state->vramFree = gpu->totalVRAM;
|
||||
state->screenAddress = NULL;
|
||||
state->currentFg = 0xFFFFFF;
|
||||
state->currentBg = 0x000000;
|
||||
state->activeBuffer = 0;
|
||||
state->isFgPalette = false;
|
||||
state->isBgPalette = false;
|
||||
for(size_t i = 0; i < NCL_MAX_VRAMBUF; i++) {
|
||||
state->vram[i] = NULL;
|
||||
}
|
||||
|
||||
c = nn_createGPU(universe, address, gpu, state, ncl_gpuHandler);
|
||||
if(c == NULL) goto fail;
|
||||
|
||||
if(nn_setComponentTypeID(c, NCL_GPU)) goto fail;
|
||||
|
||||
return c;
|
||||
fail:
|
||||
if(c != NULL) {
|
||||
nn_dropComponent(c);
|
||||
return NULL;
|
||||
}
|
||||
if(lock != NULL) nn_destroyLock(ctx, lock);
|
||||
nn_free(ctx, state, sizeof(*state));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ncl_lockScreen(ncl_ScreenState *state) {
|
||||
nn_lock(state->ctx, state->lock);
|
||||
|
||||
@@ -1821,6 +1821,8 @@ bool nn_costComponent(nn_Computer *computer, const char *address, double perTick
|
||||
}
|
||||
|
||||
bool nn_costComponentN(nn_Computer *computer, const char *address, double amount, double perTick) {
|
||||
// this means 0 per tick means free
|
||||
if(perTick == 0) return false;
|
||||
nn_ComponentEntry *c = nn_getInternalComponent(computer, address);
|
||||
if(c == NULL) return false;
|
||||
c->budgetUsed += (NN_COMPONENT_CALLBUDGET * amount) / perTick;
|
||||
@@ -3825,3 +3827,51 @@ nn_Component *nn_createScreen(nn_Universe *universe, const char *address, const
|
||||
nn_setComponentHandler(c, nn_screenHandler);
|
||||
return c;
|
||||
}
|
||||
|
||||
typedef struct nn_GPUState {
|
||||
nn_Context *ctx;
|
||||
nn_GPU gpu;
|
||||
nn_GPUHandler *handler;
|
||||
} nn_GPUState;
|
||||
|
||||
static nn_Exit nn_gpuHandler(nn_ComponentRequest *req) {
|
||||
if(req->action == NN_COMP_CHECKMETHOD) return NN_OK;
|
||||
if(req->action == NN_COMP_SIGNAL) return NN_OK;
|
||||
nn_Context *ctx = req->ctx;
|
||||
nn_GPUState *state = req->classState;
|
||||
nn_Computer *C = req->computer;
|
||||
nn_GPURequest greq;
|
||||
greq.ctx = ctx;
|
||||
greq.state = req->state;
|
||||
greq.computer = C;
|
||||
greq.gpu = &state->gpu;
|
||||
|
||||
if(req->action == NN_COMP_DROP) {
|
||||
greq.action = NN_GPU_DROP;
|
||||
state->handler(&greq);
|
||||
nn_free(ctx, state, sizeof(*state));
|
||||
return NN_OK;
|
||||
}
|
||||
|
||||
nn_setError(C, "gpu: not yet implemented");
|
||||
return NN_EBADCALL;
|
||||
}
|
||||
|
||||
nn_Component *nn_createGPU(nn_Universe *universe, const char *address, const nn_GPU *gpu, void *state, nn_GPUHandler *handler) {
|
||||
nn_Component *c = nn_createComponent(universe, address, "gpu");
|
||||
if(c == NULL) return NULL;
|
||||
// TODO: methods
|
||||
nn_Context *ctx = &universe->ctx;
|
||||
nn_GPUState *gpustate = nn_alloc(ctx, sizeof(*gpustate));
|
||||
if(gpustate == NULL) {
|
||||
nn_dropComponent(c);
|
||||
return NULL;
|
||||
}
|
||||
gpustate->ctx = ctx;
|
||||
gpustate->gpu = *gpu;
|
||||
gpustate->handler = handler;
|
||||
nn_setComponentState(c, state);
|
||||
nn_setComponentClassState(c, gpustate);
|
||||
nn_setComponentHandler(c, nn_gpuHandler);
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -1220,6 +1220,22 @@ typedef struct nn_GPU {
|
||||
// 1 GPU tier for every screen.
|
||||
extern const nn_GPU nn_defaultGPUs[4];
|
||||
|
||||
typedef enum nn_GPUAction {
|
||||
NN_GPU_DROP,
|
||||
} nn_GPUAction;
|
||||
|
||||
typedef struct nn_GPURequest {
|
||||
nn_Context *ctx;
|
||||
nn_Computer *computer;
|
||||
void *state;
|
||||
const nn_GPU *gpu;
|
||||
nn_GPUAction action;
|
||||
} nn_GPURequest;
|
||||
|
||||
typedef nn_Exit (nn_GPUHandler)(nn_GPURequest *req);
|
||||
|
||||
nn_Component *nn_createGPU(nn_Universe *universe, const char *address, const nn_GPU *gpu, void *state, nn_GPUHandler *handler);
|
||||
|
||||
// Colors and palettes.
|
||||
// Do note that the
|
||||
|
||||
|
||||
Reference in New Issue
Block a user