void rmEndFrame(void) { gsKit_set_finish(gsGlobal); rmFlush(); // Wait for draw ops to finish gsKit_finish(); if(!gsGlobal->FirstFrame) { SleepThread(); if(gsGlobal->DoubleBuffering == GS_SETTING_ON) { GS_SET_DISPFB2( gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192, gsGlobal->Width / 64, gsGlobal->PSM, 0, 0 ); gsGlobal->ActiveBuffer ^= 1; gsGlobal->PrimContext ^= 1; } } gsKit_setactive(gsGlobal); }
void gsKit_queue_exec_real(GSGLOBAL *gsGlobal, GSQUEUE *Queue) { if(Queue->tag_size == 0) return; // This superstrange oldQueue crap is because Persistent drawbuffers need to be "backed up" // or else they will balloon in size due to appending the finish token. // So we back up the current *state* (NOT DATA) of them here and restore it afterward. GSQUEUE oldQueue = gsKit_set_finish(gsGlobal); *(u64 *)Queue->dma_tag = DMA_TAG(Queue->tag_size, 0, DMA_END, 0, 0, 0); if(Queue->last_type != GIF_AD) { *(u64 *)Queue->last_tag = ((u64)Queue->same_obj | *(u64 *)Queue->last_tag); } if(!gsGlobal->FirstFrame) gsKit_finish(); GS_SETREG_CSR_FINISH(1); dmaKit_wait_fast(); dmaKit_send_chain_ucab(DMA_CHANNEL_GIF, Queue->pool[Queue->dbuf]); if(Queue->mode != GS_PERSISTENT) { Queue->dbuf ^= 1; Queue->dma_tag = Queue->pool[Queue->dbuf]; Queue->pool_cur = Queue->dma_tag + 16; Queue->last_type = GIF_RESERVED; Queue->last_tag = Queue->pool_cur; Queue->tag_size = 0; } else { *Queue = oldQueue; dmaKit_wait_fast(); } }