GFX3D: Revert the polygon sorting code back to its original state, which should result in a minor performance improvement for high polygon-count scenes.

- After years of testing, no one has reported running into the assert in gfx3d_ysort_compare() so I think we should be safe in reverting std::stable_sort() back to std::sort().
- For the sorting function, use gfx3d_ysort_compare_orig() since this function compiles down to fewer instructions than gfx3d_ysort_compare_kalven() does, resulting in better sorting performance.
- Of note, I'm pretty sure that SF commit r5132 is what fixed the original bug (see SF#1461 for more details) by getting rid of the NaN comparisons that were tripping up std::sort(). In the future, we should research why we're dividing by 0 in the first place, since r5132 is clearly a hack of a fix.
This commit is contained in:
rogerman 2018-12-05 14:37:33 -08:00
parent d80a84b762
commit 35e834ff2c
1 changed files with 11 additions and 36 deletions

View File

@ -2274,49 +2274,29 @@ void gfx3d_glFlush(u32 v)
GFX_DELAY(1);
}
static inline bool gfx3d_ysort_compare_orig(int num1, int num2)
static bool gfx3d_ysort_compare(int num1, int num2)
{
const POLY &poly1 = polylist->list[num1];
const POLY &poly2 = polylist->list[num2];
if (poly1.maxy != poly2.maxy)
return poly1.maxy < poly2.maxy;
if (poly1.miny != poly2.miny)
return poly1.miny < poly2.miny;
return num1 < num2;
}
static inline bool gfx3d_ysort_compare_kalven(int num1, int num2)
{
const POLY &poly1 = polylist->list[num1];
const POLY &poly2 = polylist->list[num2];
//this may be verified by checking the game create menus in harvest moon island of happiness
//also the buttons in the knights in the nightmare frontend depend on this and the perspective division
if (poly1.maxy < poly2.maxy) return true;
if (poly1.maxy > poly2.maxy) return false;
if (poly1.miny < poly2.miny) return true;
if (poly1.miny > poly2.miny) return false;
if (poly1.maxy != poly2.maxy)
return (poly1.maxy < poly2.maxy);
if (poly1.miny != poly2.miny)
return (poly1.miny < poly2.miny);
//notably, the main shop interface in harvest moon will not have a correct RTN button
//i think this is due to a math error rounding its position to one pixel too high and it popping behind
//the bar that it sits on.
//everything else in all the other menus that I could find looks right..
//make sure we respect the game's ordering in cases of complete ties
//this makes it a stable sort.
//this must be a stable sort or else advance wars DOR will flicker in the main map mode
return (num1 < num2);
}
static bool gfx3d_ysort_compare(int num1, int num2)
{
bool original = gfx3d_ysort_compare_orig(num1,num2);
bool kalven = gfx3d_ysort_compare_kalven(num1,num2);
assert(original == kalven);
return original;
}
static void gfx3d_doFlush()
{
gfx3d.render3DFrameCount++;
@ -2392,22 +2372,17 @@ static void gfx3d_doFlush()
if (poly.isTranslucent())
gfx3d.indexlist.list[ctr++] = i;
}
//NOTE: the use of the stable_sort below must be here as a workaround for some compilers on osx and linux.
//we're hazy on the exact behaviour of the resulting bug, all thats known is the list gets mangled somehow.
//it should not in principle be relevant since the predicate results in no ties.
//perhaps the compiler is buggy. perhaps the predicate is wrong.
//now we have to sort the opaque polys by y-value.
//(test case: harvest moon island of happiness character cretor UI)
//(test case: harvest moon island of happiness character creator UI)
//should this be done after clipping??
std::stable_sort(gfx3d.indexlist.list, gfx3d.indexlist.list + polylist->opaqueCount, gfx3d_ysort_compare);
std::sort(gfx3d.indexlist.list, gfx3d.indexlist.list + polylist->opaqueCount, gfx3d_ysort_compare);
if (!gfx3d.state.sortmode)
{
//if we are autosorting translucent polys, we need to do this also
//TODO - this is unverified behavior. need a test case
std::stable_sort(gfx3d.indexlist.list + polylist->opaqueCount, gfx3d.indexlist.list + polycount, gfx3d_ysort_compare);
std::sort(gfx3d.indexlist.list + polylist->opaqueCount, gfx3d.indexlist.list + polycount, gfx3d_ysort_compare);
}
//switch to the new lists