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

View file

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

View file

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