[qfvis] Produce more details base-vis stats

And nicely, things add up (after fixing 32-bit overflows :P)
This commit is contained in:
Bill Currie 2021-07-30 23:07:12 +09:00
parent ca8dcf3fa9
commit 523ab007d6
3 changed files with 69 additions and 25 deletions

View file

@ -143,19 +143,19 @@ typedef struct pstack_s {
} pstack_t;
typedef struct {
int portaltest; ///< number of portals tested via separators
int portalpass; ///< number of portals through which vis passes
int portalcheck; ///< number of portal checks
int targettested; ///< number of times target portal tested
int targettrimmed; ///< number of times target portal trimmed
int targetclipped; ///< number of times target portal clipped away
int sourcetested; ///< number of times source portal tested
int sourcetrimmed; ///< number of times source portal trimmed
int sourceclipped; ///< number of times source portal clipped away
int chains; ///< number of visits to clusters
int mighttest; ///< amount mightsee is used for masked tests
int vistest; ///< amount visbits is used for masked tests
int mightseeupdate; ///< amount of updates to waiting portals
unsigned long portaltest; ///< number of portals tested via separators
unsigned long portalpass; ///< number of portals through which vis passes
unsigned long portalcheck; ///< number of portal checks
unsigned long targettested; ///< number of times target portal tested
unsigned long targettrimmed;///< number of times target portal trimmed
unsigned long targetclipped;///< number of times target portal clipped away
unsigned long sourcetested; ///< number of times source portal tested
unsigned long sourcetrimmed;///< number of times source portal trimmed
unsigned long sourceclipped;///< number of times source portal clipped away
unsigned long chains; ///< number of visits to clusters
unsigned long mighttest; ///< amount mightsee is used for masked tests
unsigned long vistest; ///< amount visbits is used for masked tests
unsigned long mightseeupdate;///< amount of updates to waiting portals
unsigned sep_alloc; ///< how many separators were allocated
unsigned sep_free; ///< how many separators were freed
unsigned sep_highwater; ///< most separators in flight
@ -182,10 +182,16 @@ typedef struct threaddata_s {
typedef struct {
set_t *portalsee;
unsigned clustercull; ///< number of portals culled by cluster sphere
unsigned spherecull; ///< number of portals culled by sphere tests
unsigned windingcull; ///< number of portals culled by winding tests
int clustersee;
unsigned long selfcull; ///< number of protals culled by self
unsigned long clustercull; ///< number of portals culled by cluster sphere
unsigned long clustertest; ///< number of portals tested by cluster
unsigned long spheretest; ///< number of portal sphere tests done
unsigned long spherecull; ///< number of portals culled by sphere tests
unsigned long spherepass; ///< number of portals passed by sphere tests
unsigned long windingtest; ///< number of portal pairs tested by winding
unsigned long windingcull; ///< number of portals culled by winding tests
unsigned long windingpass; ///< number of portals passed by winding tests
unsigned long clustersee;
int id;
} basethread_t;

View file

@ -136,6 +136,7 @@ PortalBase (basethread_t *thread, portal_t *portal)
int side = test_sphere (&cluster->sphere, portal->plane);
if (side < 0) {
thread->clustertest += cluster->numportals;
// The cluster is entirely behind the portal's plane, thus every
// portal in the cluster is also behind the portal's plane and
// cannot be seen at all.
@ -145,14 +146,17 @@ PortalBase (basethread_t *thread, portal_t *portal)
// every portal in the cluster is also in front of the portal's
// plane and may be seen. However, as portals are one-way (ie,
// can see out the portal along its plane normal, but not into
// the portal against its plane normal), for a cluster's portal
// to be considered visible, the current portal must be behind
// the cluster's portal, or straddle its plane.
// the portal against its plane normal), the current portal
// must be behind the cluster's portal, or straddle its plane,
// for a cluster's portal to be considered visible.
thread->clustertest += cluster->numportals;
for (int i = 0; i < cluster->numportals; i++) {
tp = cluster->portals + i;
if (tp == portal) {
thread->selfcull++;
continue;
}
thread->spheretest++;
portal_side = test_sphere (&portal->sphere, tp->plane);
if (portal_side > 0) {
// The portal definitely is entirely in front of the test
@ -163,14 +167,17 @@ PortalBase (basethread_t *thread, portal_t *portal)
// The portal's sphere is behind the test portal's plane,
// so the portal itself is entirely behind the plane
// thus the test portal is potentially visible.
thread->spherepass++;
set_add (thread->portalsee, tp - portals);
} else {
// The portal's sphere straddle's the test portal's
// plane, so need to do a more refined check.
thread->windingtest++;
if (test_winding_back (portal->winding, tp->plane)) {
// The portal is at least partially behind the test
// portal's plane, so the test portal is potentially
// visible.
thread->windingpass++;
set_add (thread->portalsee, tp - portals);
} else {
thread->windingcull++;
@ -178,13 +185,16 @@ PortalBase (basethread_t *thread, portal_t *portal)
}
}
} else {
thread->clustertest += cluster->numportals;
// The cluster's sphere straddle's the portal's plane, thus each
// portal in the cluster must be tested individually.
for (int i = 0; i < cluster->numportals; i++) {
tp = cluster->portals + i;
if (tp == portal) {
thread->selfcull++;
continue;
}
thread->spheretest++;
// If the target portal is behind the portals's plane, then
// it can't possibly be seen by the portal.
//
@ -208,7 +218,13 @@ PortalBase (basethread_t *thread, portal_t *portal)
thread->spherecull++;
continue; // entirely in front
}
if (tp_side > 0 && portal_side < 0) {
thread->spherepass++;
set_add (thread->portalsee, tp - portals);
continue;
}
thread->windingtest++;
if (tp_side == 0) {
// The test portal's sphere touches the portal's plane,
// so do a more refined check.
@ -226,6 +242,7 @@ PortalBase (basethread_t *thread, portal_t *portal)
}
}
thread->windingpass++;
set_add (thread->portalsee, tp - portals);
}
}

View file

@ -76,9 +76,15 @@ options_t options;
static threaddata_t main_thread;
static visstat_t global_stats;
unsigned long base_mightsee;
unsigned long base_selfcull;
unsigned long base_clustercull;
unsigned long base_clustertest;
unsigned long base_spherecull;
unsigned long base_spheretest;
unsigned long base_spherepass;
unsigned long base_windingcull;
unsigned long base_windingtest;
unsigned long base_windingpass;
static unsigned portal_count;
unsigned numportals;
@ -636,9 +642,15 @@ BaseVisThread (void *_thread)
} while (1);
WRLOCK (stats_lock);
base_selfcull += data.selfcull;
base_clustercull += data.clustercull;
base_clustertest += data.clustertest;
base_spherecull += data.spherecull;
base_spheretest += data.spheretest;
base_spherepass += data.spherepass;
base_windingcull += data.windingcull;
base_windingtest += data.windingtest;
base_windingpass += data.windingpass;
base_mightsee += num_mightsee;
UNLOCK (stats_lock);
@ -898,10 +910,19 @@ BasePortalVis (void)
end = Sys_DoubleTime ();
if (options.verbosity >= 1) {
unsigned long n = numportals;
printf ("base_mightsee: %lu %gs\n", base_mightsee, end - start);
printf ("\n");
printf (" total tests: %lu\n", n * n * 4);
printf ("cluster test: %lu\n", base_clustertest);
printf ("cluster cull: %lu\n", base_clustercull);
printf (" self cull: %lu\n", base_selfcull);
printf (" sphere test: %lu\n", base_spheretest);
printf (" sphere cull: %lu\n", base_spherecull);
printf (" sphere pass: %lu\n", base_spherepass);
printf ("winding test: %lu\n", base_windingtest);
printf ("winding cull: %lu\n", base_windingcull);
printf ("winding pass: %lu\n", base_windingpass);
}
}
@ -935,16 +956,16 @@ CalcPortalVis (void)
RunThreads (LeafThread, print_progress);
if (options.verbosity >= 1) {
printf ("portalcheck: %i portaltest: %i portalpass: %i\n",
printf ("portalcheck: %ld portaltest: %ld portalpass: %ld\n",
global_stats.portalcheck, global_stats.portaltest,
global_stats.portalpass);
printf ("target trimmed: %d clipped: %d tested: %d\n",
printf ("target trimmed: %ld clipped: %ld tested: %ld\n",
global_stats.targettrimmed, global_stats.targetclipped,
global_stats.targettested);
printf ("source trimmed: %d clipped: %d tested: %d\n",
printf ("source trimmed: %ld clipped: %ld tested: %ld\n",
global_stats.sourcetrimmed, global_stats.sourceclipped,
global_stats.sourcetested);
printf ("vistest: %i mighttest: %i mightseeupdate: %i\n",
printf ("vistest: %ld mighttest: %ld mightseeupdate: %ld\n",
global_stats.vistest, global_stats.mighttest,
global_stats.mightseeupdate);
if (options.verbosity >= 2) {
@ -1420,7 +1441,7 @@ generate_pvs (void)
CalcVis ();
if (options.verbosity >= 1)
printf ("chains: %i%s\n", global_stats.chains,
printf ("chains: %ld%s\n", global_stats.chains,
options.threads > 1 ? " (not reliable)" :"");
BSP_AddVisibility (bsp, (byte *) visdata->str, visdata->size);