revert geometry flush timing to an older form. can't remember what this was supposed to fix. it was supposed to be more accurate, but it turns out to be way more complicated than I thought. the form i am checking in now should be an effective approximation. This will fix some games whose 3d was entirely broken (and even crashing the emulator). But I am more interested in what regressions it will cause, which may involve broken dual screen 3d modes or other bugs with things flickering in and out of existence. these I will track in detail while I try to understand the problem.

This commit is contained in:
zeromus 2009-05-13 21:44:47 +00:00
parent 9fbac3e7bc
commit 7bea1697c3
1 changed files with 36 additions and 11 deletions

View File

@ -42,6 +42,24 @@
#include "readwrite.h" #include "readwrite.h"
#include "FIFO.h" #include "FIFO.h"
/*
thoughts on flush timing:
I think a flush is supposed to queue up and wait to happen during vblank sometime.
But, we have some games that continue to do work after a flush but before a vblank.
Since our timing is bad anyway, and we're not sure when the flush is really supposed to happen,
then this leaves us in a bad situation.
What makes it worse is that if flush is supposed to be deferred, then we have to queue these
errant geometry commands. That would require a better gxfifo we have now, and some mechanism to block
while the geometry engine is stalled (which doesnt exist).
Since these errant games are nevertheless using flush command to represent the end of a frame, we deem this
a good time to execute an actual flush.
I think we originally didnt do this because we found some game that it glitched, but that may have been
resolved since then by deferring actual rendering to the next vcount=0 (giving textures enough time to upload).
But since we're not sure how we'll eventually want this, I am leaving it sort of reconfigurable, doing all the work
in this function: */
static void gfx3d_doFlush();
using std::max; using std::max;
using std::min; using std::min;
@ -1378,6 +1396,8 @@ void gfx3d_glFlush(u32 v)
flushPending = TRUE; flushPending = TRUE;
gfx3d.sortmode = BIT0(v); gfx3d.sortmode = BIT0(v);
gfx3d.wbuffer = BIT1(v); gfx3d.wbuffer = BIT1(v);
//see discussion at top of file
gfx3d_doFlush();
} }
static int _CDECL_ gfx3d_ysort_compare_old_qsort(const void * elem1, const void * elem2) static int _CDECL_ gfx3d_ysort_compare_old_qsort(const void * elem1, const void * elem2)
@ -1417,17 +1437,8 @@ static bool gfx3d_ysort_compare(int num1, int num2)
return false; //equal should always return false "strict weak ordering" return false; //equal should always return false "strict weak ordering"
} }
static void gfx3d_doFlush()
void gfx3d_VBlankSignal()
{ {
//the 3d buffers are swapped when a vblank begins.
//so, if we have a redraw pending, now is a safe time to do it
if(!flushPending)
{
gfx3d_FlushFIFO();
return;
}
gfx3d.frameCtr++; gfx3d.frameCtr++;
gfx3d_FlushFIFO(); gfx3d_FlushFIFO();
@ -1493,6 +1504,20 @@ void gfx3d_VBlankSignal()
drawPending = TRUE; drawPending = TRUE;
} }
void gfx3d_VBlankSignal()
{
//the 3d buffers are swapped when a vblank begins.
//so, if we have a redraw pending, now is a safe time to do it
if(!flushPending)
{
gfx3d_FlushFIFO();
return;
}
//see discussion at top of file
//gfx3d_doFlush();
}
void gfx3d_VBlankEndSignal(bool skipFrame) void gfx3d_VBlankEndSignal(bool skipFrame)
{ {
//if we are skipping 3d frames then the 3d rendering will get held up here. //if we are skipping 3d frames then the 3d rendering will get held up here.