initial work on GPU
This commit is contained in:
@@ -414,7 +414,7 @@ int main(int argc, char **argv) {
|
|||||||
double wattage = 0;
|
double wattage = 0;
|
||||||
|
|
||||||
nn_Component *screen = ncl_createScreen(u, NULL, &nn_defaultScreens[3]);
|
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
|
// draw test
|
||||||
@@ -444,6 +444,7 @@ restart:;
|
|||||||
nn_mountComponent(c, ocelotCard, -1);
|
nn_mountComponent(c, ocelotCard, -1);
|
||||||
nn_mountComponent(c, eepromCard, 0);
|
nn_mountComponent(c, eepromCard, 0);
|
||||||
nn_mountComponent(c, managedfs, 1);
|
nn_mountComponent(c, managedfs, 1);
|
||||||
|
nn_mountComponent(c, gpuCard, 2);
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
if(WindowShouldClose()) break;
|
if(WindowShouldClose()) break;
|
||||||
@@ -578,6 +579,7 @@ cleanup:;
|
|||||||
nn_dropComponent(eepromCard);
|
nn_dropComponent(eepromCard);
|
||||||
nn_dropComponent(managedfs);
|
nn_dropComponent(managedfs);
|
||||||
nn_dropComponent(screen);
|
nn_dropComponent(screen);
|
||||||
|
nn_dropComponent(gpuCard);
|
||||||
// rip the universe
|
// rip the universe
|
||||||
nn_destroyUniverse(u);
|
nn_destroyUniverse(u);
|
||||||
UnloadFont(font);
|
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;
|
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 {
|
typedef struct ncl_FSState {
|
||||||
nn_Context *ctx;
|
nn_Context *ctx;
|
||||||
nn_Lock *lock;
|
nn_Lock *lock;
|
||||||
@@ -590,6 +614,11 @@ static nn_Exit ncl_fsHandler(nn_FSRequest *req) {
|
|||||||
}
|
}
|
||||||
state->fds[fd] = file;
|
state->fds[fd] = file;
|
||||||
req->fd = fd;
|
req->fd = fd;
|
||||||
|
if(mode[0] == 'w') {
|
||||||
|
// file cleared
|
||||||
|
state->spaceUsed = 0;
|
||||||
|
state->realSpaceUsed = 0;
|
||||||
|
}
|
||||||
nn_unlock(ctx, state->lock);
|
nn_unlock(ctx, state->lock);
|
||||||
return NN_OK;
|
return NN_OK;
|
||||||
}
|
}
|
||||||
@@ -1008,7 +1037,88 @@ fail:;
|
|||||||
return NULL;
|
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) {
|
void ncl_lockScreen(ncl_ScreenState *state) {
|
||||||
nn_lock(state->ctx, state->lock);
|
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) {
|
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);
|
nn_ComponentEntry *c = nn_getInternalComponent(computer, address);
|
||||||
if(c == NULL) return false;
|
if(c == NULL) return false;
|
||||||
c->budgetUsed += (NN_COMPONENT_CALLBUDGET * amount) / perTick;
|
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);
|
nn_setComponentHandler(c, nn_screenHandler);
|
||||||
return c;
|
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.
|
// 1 GPU tier for every screen.
|
||||||
extern const nn_GPU nn_defaultGPUs[4];
|
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.
|
// Colors and palettes.
|
||||||
// Do note that the
|
// Do note that the
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user