mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 14:20:59 +00:00
Use a sorted queue for portals.
qsort is used to sort the queue by nummightsee. At ~4ms for 20k portals, I think it's affordable. Using a queue rather than scanning the portal list each time loses the dynamic sorting when mightsee gets updated, but it seemed to shave off 4s anyway (~207s to ~203s (maybe, yay random times)). Another step towards threaded base-vis.
This commit is contained in:
parent
7e40981dcd
commit
32b6d15931
1 changed files with 24 additions and 26 deletions
|
@ -86,6 +86,8 @@ int bitbytes; // (portalleafs + 63)>>3
|
||||||
int bitlongs;
|
int bitlongs;
|
||||||
int bitbytes_l; // (numrealleafs + 63)>>3
|
int bitbytes_l; // (numrealleafs + 63)>>3
|
||||||
|
|
||||||
|
portal_t **portal_queue;
|
||||||
|
|
||||||
portal_t *portals;
|
portal_t *portals;
|
||||||
cluster_t *clusters;
|
cluster_t *clusters;
|
||||||
dstring_t *visdata;
|
dstring_t *visdata;
|
||||||
|
@ -285,40 +287,17 @@ ClipWinding (winding_t *in, const plane_t *split, qboolean keepon)
|
||||||
return neww;
|
return neww;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
GetNextPortal
|
|
||||||
|
|
||||||
Returns the next portal for a thread to work on
|
|
||||||
Returns the portals from the least complex, so the later ones can reuse
|
|
||||||
the earlier information.
|
|
||||||
*/
|
|
||||||
static portal_t *
|
static portal_t *
|
||||||
GetNextPortal (void)
|
GetNextPortal (void)
|
||||||
{
|
{
|
||||||
int min, j;
|
portal_t *p = 0;
|
||||||
portal_t *p, *tp;
|
|
||||||
|
|
||||||
WRLOCK (global_lock);
|
WRLOCK (global_lock);
|
||||||
|
if (portal_count < 2 * numportals) {
|
||||||
min = 99999;
|
p = portal_queue[portal_count++];
|
||||||
p = NULL;
|
|
||||||
|
|
||||||
for (j = 0, tp = portals; j < numportals * 2; j++, tp++) {
|
|
||||||
if (tp->nummightsee < min && tp->status == stat_none) {
|
|
||||||
min = tp->nummightsee;
|
|
||||||
p = tp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
WRLOCK_PORTAL (p);
|
|
||||||
portal_count++;
|
|
||||||
p->status = stat_selected;
|
p->status = stat_selected;
|
||||||
UNLOCK_PORTAL (p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK (global_lock);
|
UNLOCK (global_lock);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,10 +575,21 @@ ClusterFlow (int clusternum)
|
||||||
dstring_append (visdata, (char *) compressed, i);
|
dstring_append (visdata, (char *) compressed, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
portalcmp (const void *_a, const void *_b)
|
||||||
|
{
|
||||||
|
portal_t *a = *(portal_t **) _a;
|
||||||
|
portal_t *b = *(portal_t **) _b;
|
||||||
|
return a->nummightsee - b->nummightsee;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CalcPortalVis (void)
|
CalcPortalVis (void)
|
||||||
{
|
{
|
||||||
long i;
|
long i;
|
||||||
|
double start, end;
|
||||||
|
|
||||||
|
portal_count = 0;
|
||||||
|
|
||||||
// fastvis just uses mightsee for a very loose bound
|
// fastvis just uses mightsee for a very loose bound
|
||||||
if (options.minimal) {
|
if (options.minimal) {
|
||||||
|
@ -609,6 +599,10 @@ CalcPortalVis (void)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
start = Sys_DoubleTime ();
|
||||||
|
qsort (portal_queue, numportals * 2, sizeof (portal_t *), portalcmp);
|
||||||
|
end = Sys_DoubleTime ();
|
||||||
|
printf ("qsort: %gs\n", end - start);
|
||||||
RunThreads (LeafThread);
|
RunThreads (LeafThread);
|
||||||
|
|
||||||
if (options.verbosity > 0) {
|
if (options.verbosity > 0) {
|
||||||
|
@ -895,6 +889,10 @@ LoadPortals (char *name)
|
||||||
// each file portal is split into two memory portals, one for each
|
// each file portal is split into two memory portals, one for each
|
||||||
// direction
|
// direction
|
||||||
portals = calloc (2 * numportals, sizeof (portal_t));
|
portals = calloc (2 * numportals, sizeof (portal_t));
|
||||||
|
portal_queue = malloc (2 * numportals * sizeof (portal_t *));
|
||||||
|
for (i = 0; i < 2 * numportals; i++) {
|
||||||
|
portal_queue[i] = &portals[i];
|
||||||
|
}
|
||||||
#ifdef USE_PTHREADS
|
#ifdef USE_PTHREADS
|
||||||
portal_locks = calloc (2 * numportals, sizeof (pthread_rwlock_t));
|
portal_locks = calloc (2 * numportals, sizeof (pthread_rwlock_t));
|
||||||
for (i = 0; i < 2 * numportals; i++) {
|
for (i = 0; i < 2 * numportals; i++) {
|
||||||
|
|
Loading…
Reference in a new issue