gsdx-ogl: Optimise overlap detection algorithm

Vectorise coordinate min/max sorting, and use the ordered runion
instead.
This commit is contained in:
Jonathan Li 2016-01-13 21:43:57 +00:00
parent 14dffa762b
commit 37deeb0d52
1 changed files with 10 additions and 33 deletions

View File

@ -497,41 +497,18 @@ GSRendererOGL::PRIM_OVERLAP GSRendererOGL::PrimitiveOverlap()
// In order to speed up comparison a bounding-box is accumulated. It removes a // In order to speed up comparison a bounding-box is accumulated. It removes a
// loop so code is much faster (check game virtua fighter). Besides it allow to check // loop so code is much faster (check game virtua fighter). Besides it allow to check
// properly the Y order. // properly the Y order.
GSVector4i all;
//FIXME better vector operation // .x = min(v[i].XYZ.X, v[i+1].XYZ.X)
if (v[i+1].XYZ.Y < v[i+0].XYZ.Y) { // .y = min(v[i].XYZ.Y, v[i+1].XYZ.Y)
all.y = v[i+1].XYZ.Y; // .z = max(v[i].XYZ.X, v[i+1].XYZ.X)
all.w = v[i+0].XYZ.Y; // .w = max(v[i].XYZ.Y, v[i+1].XYZ.Y)
} else { GSVector4i all = GSVector4i(v[i].m[1]).upl16(GSVector4i(v[i+1].m[1])).upl16().xzyw();
all.y = v[i+0].XYZ.Y; all = all.xyxy().blend(all.zwzw(), all > all.zwxy());
all.w = v[i+1].XYZ.Y;
}
if (v[i+1].XYZ.X < v[i+0].XYZ.X) {
all.x = v[i+1].XYZ.X;
all.z = v[i+0].XYZ.X;
} else {
all.x = v[i+0].XYZ.X;
all.z = v[i+1].XYZ.X;
}
size_t j = i + 2; size_t j = i + 2;
while (j < count) { while (j < count) {
GSVector4i sprite; GSVector4i sprite = GSVector4i(v[j].m[1]).upl16(GSVector4i(v[j+1].m[1])).upl16().xzyw();
//FIXME better vector operation sprite = sprite.xyxy().blend(sprite.zwzw(), sprite > sprite.zwxy());
if (v[j+1].XYZ.Y < v[j+0].XYZ.Y) {
sprite.y = v[j+1].XYZ.Y;
sprite.w = v[j+0].XYZ.Y;
} else {
sprite.y = v[j+0].XYZ.Y;
sprite.w = v[j+1].XYZ.Y;
}
if (v[j+1].XYZ.X < v[j+0].XYZ.X) {
sprite.x = v[j+1].XYZ.X;
sprite.z = v[j+0].XYZ.X;
} else {
sprite.x = v[j+0].XYZ.X;
sprite.z = v[j+1].XYZ.X;
}
// Be sure to get vertex in good order, otherwise .r* function doesn't // Be sure to get vertex in good order, otherwise .r* function doesn't
// work as expected. // work as expected.
@ -541,7 +518,7 @@ GSRendererOGL::PRIM_OVERLAP GSRendererOGL::PrimitiveOverlap()
ASSERT(all.y <= all.w); ASSERT(all.y <= all.w);
if (all.rintersect(sprite).rempty()) { if (all.rintersect(sprite).rempty()) {
all = all.runion(sprite); all = all.runion_ordered(sprite);
} else { } else {
overlap = PRIM_OVERLAP_YES; overlap = PRIM_OVERLAP_YES;
break; break;