From 4743678478f7f8aadd12e7cea0365036fd52513e Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Fri, 9 May 2025 21:47:55 +0200 Subject: [PATCH] Improvements around STALL --- src/gu/guInternal.h | 18 ++++++++++++------ src/gu/pspgu.h | 8 +++++++- src/gu/sceGuCallList.c | 12 +++++++++--- src/gu/sceGuDrawArray.c | 3 ++- src/gu/sceGuDrawArrayN.c | 4 ++-- src/gu/sceGuFinishId.c | 31 +++++++++++++++++++++---------- src/gu/sceGuInit.c | 2 +- src/gu/sceGuSignal.c | 6 +++--- src/gu/sceGuStart.c | 7 ++++++- 9 files changed, 63 insertions(+), 28 deletions(-) diff --git a/src/gu/guInternal.h b/src/gu/guInternal.h index 12841a68..0b214dd9 100644 --- a/src/gu/guInternal.h +++ b/src/gu/guInternal.h @@ -645,12 +645,18 @@ static inline void sendCommandf(GECommand cmd, float argument) sendCommandi(cmd, t.i >> 8); } -static inline void sendCommandiStall(GECommand cmd, int argument) -{ - sendCommandi(cmd, argument); - - if (!gu_object_stack_depth && !gu_curr_context) - sceGeListUpdateStallAddr(ge_list_executed[0], gu_list->current); +static inline int _sceGuUpdateStallAddr(void) { + if (gu_curr_context == GU_DIRECT) { + // Just if there are no objects in the stack (no guBeginObject) + if (!gu_object_stack_depth) { + int res; + res = sceGeListUpdateStallAddr(ge_list_executed[0], gu_list->current); + if (res < 0) { + return res; + } + } + } + return 0; } #endif diff --git a/src/gu/pspgu.h b/src/gu/pspgu.h index c7e1d0d3..bd185dfc 100644 --- a/src/gu/pspgu.h +++ b/src/gu/pspgu.h @@ -477,6 +477,11 @@ void* sceGuSetCallback(int signal, void (*callback)(int)); /** * Trigger signal to call code from the command stream + * + * Available signals are: + * - GU_SIGNAL_WAIT - Wait for callback to finish + * - GU_SIGNAL_NOWAIT - Do not wait for callback to finish + * - GU_SIGNAL_PAUSE - Pause execution until callback is finished * * Available behaviors are: * - GU_BEHAVIOR_SUSPEND - Stops display list execution until callback function finished @@ -566,8 +571,9 @@ int sceGuFinishId(unsigned int id); * Call previously generated display-list * * @param list - Display list to call + * @return 0 for success, < 0 for failure **/ -void sceGuCallList(const void* list); +int sceGuCallList(const void* list); /** * Set wether to use stack-based calls or signals to handle execution of called lists. diff --git a/src/gu/sceGuCallList.c b/src/gu/sceGuCallList.c index d59043ad..20a4bb0c 100644 --- a/src/gu/sceGuCallList.c +++ b/src/gu/sceGuCallList.c @@ -8,19 +8,25 @@ #include "guInternal.h" -void sceGuCallList(const void *list) +int sceGuCallList(const void *list) { + int res; unsigned int list_addr = (unsigned int)list; if (gu_call_mode == GU_CALL_SIGNAL) { sendCommandi(SIGNAL, (list_addr >> 16) | 0x110000); sendCommandi(END, list_addr & 0xffff); - sendCommandiStall(NOP, 0); } else { sendCommandi(BASE, (list_addr >> 8) & 0xf0000); - sendCommandiStall(CALL, list_addr); + sendCommandi(CALL, list_addr); } + + res = _sceGuUpdateStallAddr(); + if (res < 0) { + return res; + } + return 0; } diff --git a/src/gu/sceGuDrawArray.c b/src/gu/sceGuDrawArray.c index c98143c9..2dcdb872 100644 --- a/src/gu/sceGuDrawArray.c +++ b/src/gu/sceGuDrawArray.c @@ -25,5 +25,6 @@ void sceGuDrawArray(int prim, int vtype, int count, const void *indices, const v sendCommandi(VADDR, ((unsigned int)vertices)); } - sendCommandiStall(PRIM, (prim << 16) | count); + sendCommandi(PRIM, (prim << 16) | count); + _sceGuUpdateStallAddr(); } diff --git a/src/gu/sceGuDrawArrayN.c b/src/gu/sceGuDrawArrayN.c index 7bf743f5..dd5ecc45 100644 --- a/src/gu/sceGuDrawArrayN.c +++ b/src/gu/sceGuDrawArrayN.c @@ -30,7 +30,7 @@ void sceGuDrawArrayN(int primitive_type, int vertex_type, int vcount, int primco int i; for (i = 0; i < primcount; i++) sendCommandi(PRIM, (primitive_type << 16) | vcount); - - sendCommandiStall(PRIM, (primitive_type << 16) | vcount); } + + _sceGuUpdateStallAddr(); } diff --git a/src/gu/sceGuFinishId.c b/src/gu/sceGuFinishId.c index a228b734..ad5e638f 100644 --- a/src/gu/sceGuFinishId.c +++ b/src/gu/sceGuFinishId.c @@ -7,39 +7,50 @@ */ #include "guInternal.h" +#include +#include int sceGuFinishId(unsigned int id) { + int ret; + int intr; + switch (gu_curr_context) { case GU_DIRECT: - case GU_SEND: - { sendCommandi(FINISH, id & 0xffff); - sendCommandiStall(END, 0); - } - break; - + sendCommandi(END, 0); + ret = _sceGuUpdateStallAddr(); + if (ret < 0) + { + return ret; + } + break; + case GU_SEND: + sendCommandi(FINISH, id & 0xffff); + sendCommandi(END, 0); + break; case GU_CALL: - { if (gu_call_mode == GU_CALL_SIGNAL) { sendCommandi(SIGNAL, 0x120000); sendCommandi(END, 0); - sendCommandiStall(NOP, 0); } else { sendCommandi(RET, 0); } - } - break; + break; + default: + return SCE_DISPLAY_ERROR_ARGUMENT; } unsigned int size = ((unsigned int)gu_list->current) - ((unsigned int)gu_list->start); // go to parent list + intr = sceKernelCpuSuspendIntr(); gu_curr_context = gu_list->parent_context; gu_list = &gu_contexts[gu_curr_context].list; + sceKernelCpuResumeIntr(intr); return size; } \ No newline at end of file diff --git a/src/gu/sceGuInit.c b/src/gu/sceGuInit.c index 048de45a..8a51ae80 100644 --- a/src/gu/sceGuInit.c +++ b/src/gu/sceGuInit.c @@ -283,7 +283,7 @@ int sceGuInit(void) gu_settings.ge_callback_id = res; // initialize graphics hardware - res = sceGeListEnQueue((void *)((unsigned int)ge_init_list & 0x1fffffff), 0, gu_settings.ge_callback_id, 0); + res = sceGeListEnQueue((void *)((unsigned int)ge_init_list & 0x1fffffff), NULL, gu_settings.ge_callback_id, NULL); if (res < 0) { sceKernelDeleteEventFlag(gu_settings.kernel_event_flag); diff --git a/src/gu/sceGuSignal.c b/src/gu/sceGuSignal.c index c1779c16..df691cc0 100644 --- a/src/gu/sceGuSignal.c +++ b/src/gu/sceGuSignal.c @@ -13,11 +13,11 @@ void sceGuSignal(int signal, int argument) sendCommandi(SIGNAL, ((signal & 0xff) << 16) | (argument & 0xffff)); sendCommandi(END, 0); - if (GU_SIGNAL_PAUSE == 3) + if (signal == GU_SIGNAL_PAUSE) { sendCommandi(FINISH, 0); sendCommandi(END, 0); } - sendCommandiStall(NOP, 0); -} + _sceGuUpdateStallAddr(); +} \ No newline at end of file diff --git a/src/gu/sceGuStart.c b/src/gu/sceGuStart.c index ef14da39..96791e9a 100644 --- a/src/gu/sceGuStart.c +++ b/src/gu/sceGuStart.c @@ -10,12 +10,16 @@ #include #include +#include void sceGuStart(int ctype, void *list) { + int intr; GuContext *context = &gu_contexts[ctype]; unsigned int *local_list = (unsigned int *)(((unsigned int)list) | 0x40000000); + intr = sceKernelCpuSuspendIntr(); + // setup display list context->list.start = local_list; @@ -26,10 +30,11 @@ void sceGuStart(int ctype, void *list) // store current context gu_curr_context = ctype; + sceKernelCpuResumeIntr(intr); if (ctype == GU_DIRECT) { - ge_list_executed[0] = sceGeListEnQueue(local_list, local_list, gu_settings.ge_callback_id, 0); + ge_list_executed[0] = sceGeListEnQueue(local_list, local_list, gu_settings.ge_callback_id, NULL); gu_settings.signal_offset = 0; }