Fixed issue with latency patch not always starting with the correct behavior
This commit is contained in:
parent
1651298a2c
commit
31d2424774
|
@ -2,7 +2,12 @@
|
|||
#include "sys_cfb.h"
|
||||
#include "buffers.h"
|
||||
#include "fault.h"
|
||||
#include "audiomgr.h"
|
||||
#include "z64speed_meter.h"
|
||||
#include "z64vimode.h"
|
||||
#include "z64viscvg.h"
|
||||
#include "z64vismono.h"
|
||||
#include "z64viszbuf.h"
|
||||
|
||||
void recomp_set_current_frame_poll_id();
|
||||
void PadMgr_HandleRetrace(void);
|
||||
|
@ -34,6 +39,7 @@ void PadMgr_GetInput2(Input* inputs, s32 gameRequest) {
|
|||
extern CfbInfo sGraphCfbInfos[3];
|
||||
u32 recomp_time_us();
|
||||
void recomp_measure_latency();
|
||||
void* osViGetCurrentFramebuffer_recomp();
|
||||
|
||||
OSMesgQueue *rdp_queue_ptr = NULL;
|
||||
|
||||
|
@ -51,13 +57,10 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx, GameState* gameState) {
|
|||
static IrqMgrClient irq_client = {0};
|
||||
static OSMesgQueue vi_queue = {0};
|
||||
static OSMesg vi_buf[8] = {0};
|
||||
static OSMesgQueue rdp_queue = {0};
|
||||
static OSMesg rdp_mesg = NULL;
|
||||
static bool created = false;
|
||||
if (!created) {
|
||||
created = true;
|
||||
osCreateMesgQueue(&vi_queue, vi_buf, ARRAY_COUNT(vi_buf));
|
||||
osCreateMesgQueue(&rdp_queue, &rdp_mesg, 1);
|
||||
extern IrqMgr gIrqMgr;
|
||||
IrqMgr_AddClient(&gIrqMgr, &irq_client, &vi_queue);
|
||||
}
|
||||
|
@ -65,9 +68,7 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx, GameState* gameState) {
|
|||
// @recomp Disable the wait here so that it can be moved after task submission for minimizing latency.
|
||||
// retry:
|
||||
// osSetTimer(&timer, OS_USEC_TO_CYCLES(3 * 1000 * 1000), 0, &gfxCtx->queue, (OSMesg)666);
|
||||
u32 count_before = recomp_time_us();
|
||||
osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_BLOCK);
|
||||
u32 count_after = recomp_time_us();
|
||||
// osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_BLOCK);
|
||||
// osStopTimer(&timer);
|
||||
|
||||
// if (msg == (OSMesg)666) {
|
||||
|
@ -143,66 +144,51 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx, GameState* gameState) {
|
|||
osRecvMesg(&gfxCtx->queue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
// @recomp Set up the dedicated RDP complete message queue pointer for the scheduler.
|
||||
rdp_queue_ptr = &rdp_queue;
|
||||
|
||||
gfxCtx->schedMsgQ = &gSchedContext.cmdQ;
|
||||
recomp_measure_latency();
|
||||
osSendMesg(&gSchedContext.cmdQ, scTask, OS_MESG_BLOCK);
|
||||
Sched_SendEntryMsg(&gSchedContext);
|
||||
|
||||
// @recomp Wait for the RDP complete message to mitigate waiting between creating the next task and submitting it.
|
||||
osRecvMesg(&rdp_queue, NULL, OS_MESG_BLOCK);
|
||||
rdp_queue_ptr = NULL;
|
||||
// @recomp Immediately wait on the task to complete to minimize latency for the next one.
|
||||
osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_BLOCK);
|
||||
|
||||
// @recomp Manually wait the required number of VI periods after submitting the task
|
||||
// so that the next frame doesn't need to wait before submitting its task.
|
||||
u32 vi_count_before = recomp_time_us();
|
||||
for (int i = 0; i < cfb->updateRate; i++) {
|
||||
// @recomp Wait on the VI framebuffer to change if this task has a framebuffer swap.
|
||||
if (scTask->flags & OS_SC_SWAPBUFFER) {
|
||||
while (osViGetCurrentFramebuffer_recomp() != cfb->fb1) {
|
||||
osRecvMesg(&vi_queue, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
// Wait one extra VI afterwards.
|
||||
osRecvMesg(&vi_queue, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
// @recomp Flush any excess VI messages that came in.
|
||||
|
||||
// @recomp Flush any extra messages from the VI queue.
|
||||
while (osRecvMesg(&vi_queue, NULL, OS_MESG_NOBLOCK) == 0) {
|
||||
;
|
||||
}
|
||||
u32 vi_count_after = recomp_time_us();
|
||||
|
||||
// recomp_printf("recv wait added %d us\nVI wait: %d us\n", count_after - count_before, vi_count_after - vi_count_before);
|
||||
}
|
||||
|
||||
extern OSTime sRDPStartTime;
|
||||
extern SpeedMeter sGameSpeedMeter;
|
||||
extern VisCvg sGameVisCvg;
|
||||
extern VisZbuf sGameVisZbuf;
|
||||
extern VisMono sGameVisMono;
|
||||
extern ViMode sGameViMode;
|
||||
|
||||
// @recomp Patched to send a message to the dedicated RDP complete message queue.
|
||||
void Sched_HandleRDPDone(SchedContext* sched) {
|
||||
OSScTask* curRDP;
|
||||
OSScTask* nextRSP = NULL;
|
||||
OSScTask* nextRDP = NULL;
|
||||
s32 state;
|
||||
void GameState_Destroy(GameState* gameState) {
|
||||
AudioMgr_StopAllSfxExceptSystem();
|
||||
Audio_Update();
|
||||
|
||||
if (sched->curRDPTask == NULL) {
|
||||
osSyncPrintf("__scHandleRDP:sc->curRDPTask == NULL\n");
|
||||
return;
|
||||
// @recomp The wait for the gfx task was moved to directly after submission, so it's not needed here.
|
||||
// osRecvMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK);
|
||||
|
||||
if (gameState->destroy != NULL) {
|
||||
gameState->destroy(gameState);
|
||||
}
|
||||
|
||||
// Log run time
|
||||
gRDPTimeAcc = osGetTime() - sRDPStartTime;
|
||||
|
||||
// Mark task done
|
||||
curRDP = sched->curRDPTask;
|
||||
sched->curRDPTask = NULL;
|
||||
curRDP->state &= ~OS_SC_DP;
|
||||
|
||||
// @recomp Send a message to the dedicated RDP complete message queue if it's currently set up.
|
||||
if (rdp_queue_ptr) {
|
||||
osSendMesg(rdp_queue_ptr, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
Sched_NotifyDone(sched, curRDP);
|
||||
|
||||
// Schedule and run next task
|
||||
state = ((sched->curRSPTask == NULL) << 1) | (sched->curRDPTask == NULL);
|
||||
if (Sched_Schedule(sched, &nextRSP, &nextRDP, state) != state) {
|
||||
Sched_RunTask(sched, nextRSP, nextRDP);
|
||||
}
|
||||
Rumble_Destroy();
|
||||
SpeedMeter_Destroy(&sGameSpeedMeter);
|
||||
VisCvg_Destroy(&sGameVisCvg);
|
||||
VisZbuf_Destroy(&sGameVisZbuf);
|
||||
VisMono_Destroy(&sGameVisMono);
|
||||
ViMode_Destroy(&sGameViMode);
|
||||
THA_Destroy(&gameState->tha);
|
||||
GameAlloc_Cleanup(&gameState->alloc);
|
||||
}
|
||||
|
|
|
@ -25,3 +25,4 @@ osCreateMesgQueue_recomp = 0x8F000048;
|
|||
recomp_set_current_frame_poll_id = 0x8F00004C;
|
||||
recomp_time_us = 0x8F000050;
|
||||
recomp_measure_latency = 0x8F000054;
|
||||
osViGetCurrentFramebuffer_recomp = 0x8F000058;
|
||||
|
|
|
@ -320,6 +320,7 @@ void gfx_thread_func(uint8_t* rdram, std::atomic_flag* thread_ready, ultramodern
|
|||
// is finished as well, so sending this early shouldn't be an issue in most cases.
|
||||
// If this causes issues then the logic can be replaced with responding to yield requests.
|
||||
sp_complete();
|
||||
ultramodern::measure_input_latency();
|
||||
|
||||
auto rt64_start = std::chrono::system_clock::now();
|
||||
RT64SendDL(rdram, &task_action->task);
|
||||
|
|
Loading…
Reference in New Issue