quakeforge/tools/qfvis/include/vis.h
Bill Currie ff4cd84891 [qfvis] Use simd vector code
While whether it's any faster is debatable (it's slightly slower, but
many more portals are being tested due to different rounding in the base
vis stage), it's certainly easier to read.
2021-03-28 19:55:47 +09:00

214 lines
6.4 KiB
C

/*
vis.h
PVS/PHS generation tool
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2002 Colin Thompson
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __vis_h
#define __vis_h
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if defined (HAVE_PTHREAD_H) && defined (HAVE_PTHREAD)
#define USE_PTHREADS
#endif
#ifdef USE_PTHREADS
#include <pthread.h>
extern pthread_rwlock_t *global_lock;
extern pthread_rwlock_t *portal_locks;
#define WRLOCK(l) \
do { \
if (options.threads > 1) \
pthread_rwlock_wrlock (l); \
} while (0)
#define RDLOCK(l) \
do { \
if (options.threads > 1) \
pthread_rwlock_rdlock (l); \
} while (0)
#define UNLOCK(l) \
do { \
if (options.threads > 1) \
pthread_rwlock_unlock (l); \
} while (0)
#define WRLOCK_PORTAL(p) WRLOCK (&portal_locks[p - portals])
#define RDLOCK_PORTAL(p) RDLOCK (&portal_locks[p - portals])
#define UNLOCK_PORTAL(p) UNLOCK (&portal_locks[p - portals])
#else
#define LOCK(l)
#define UNLOCK(l)
#define WRLOCK_PORTAL(p)
#define RDLOCK_PORTAL(p)
#define UNLOCK_PORTAL(p)
#endif
#include "QF/cmem.h"
#include "QF/set.h"
#include "QF/simd/vec4f.h"
#define MAX_PORTALS 32768
#define PORTALFILE "PRT1"
#define PORTALFILE_AM "PRT1-AM"
#define PORTALFILE2 "PRT2"
#define ON_EPSILON 0.1
#define MAX_POINTS_ON_WINDING 64
#define MAX_PORTALS_ON_CLUSTER 128
typedef struct winding_s {
struct winding_s *next;
qboolean original; // don't free, it's part of the portal
unsigned numpoints;
int id;
int thread;
vec4f_t points[MAX_PORTALS_ON_CLUSTER]; // variable sized
} winding_t;
typedef enum {
stat_none,
stat_selected,
stat_working,
stat_done
} vstatus_t;
typedef struct {
vec4f_t plane; // normal pointing into neighbor
vspheref_t sphere; // bounding sphere
int cluster; // neighbor
winding_t *winding;
vstatus_t status;
set_t *visbits;
set_t *mightsee;
int nummightsee;
int numcansee;
} portal_t;
typedef struct seperating_plane_s {
vec4f_t plane; // from portal is on positive side
struct seperating_plane_s *next;
} sep_t;
typedef struct passage_s {
struct passage_s *next;
int from, to; // cluster numbers
sep_t *planes;
} passage_t;
typedef struct cluster_s {
int numportals;
int visofs;
passage_t *passages;
portal_t *portals[MAX_PORTALS_ON_CLUSTER];
} cluster_t;
typedef struct pstack_s {
struct pstack_s *next; ///< linked list of active stack objects
cluster_t *cluster; ///< the cluster being sub-vised
winding_t *source_winding; ///< clipped source portal winding
portal_t *pass_portal; ///< the portal exiting from the cluster
vec4f_t pass_plane; ///< plane of the pass portal
winding_t *pass_winding; ///< clipped pass portal winding
set_t *mightsee;
sep_t *separators[2];
} 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 sep_alloc; ///< how many separators were allocated
unsigned sep_free; ///< how many separators were freed
unsigned sep_highwater; ///< most separators in flight
unsigned sep_maxbulk; ///< most separators freed at once
unsigned winding_alloc; ///< how many windings were allocated
unsigned winding_free; ///< how many windings were freed
unsigned winding_highwater; ///< most windings in flight
unsigned stack_alloc; ///< how many stack blocks were allocated
unsigned stack_free; ///< how many stack blocks were freed
} visstat_t;
typedef struct threaddata_s {
visstat_t stats; ///< per-thread statistics merged on completion
set_t *clustervis; ///< clusters base portal can see
portal_t *base; ///< portal for which this thread is being run
pstack_t pstack_head;
sep_t *sep_freelist; ///< per-thread list of free separators
winding_t *winding_freelist; ///< per-thread list of free windings
memsuper_t *memsuper; ///< per-thread memory pool
set_pool_t set_pool;
int id;
int winding_id;
} threaddata_t;
typedef struct {
set_t *portalsee;
unsigned spherecull; ///< number of portals culled by sphere tests
unsigned windingcull; ///< number of portals culled by winding tests
int clustersee;
int id;
} basethread_t;
extern unsigned numportals;
extern unsigned portalclusters;
extern unsigned numrealleafs;
extern int bitbytes;
extern int bitbytes_l;
extern int bitlongs;
extern struct bsp_s *bsp;
extern portal_t *portals;
extern cluster_t *clusters;
extern int *leafcluster;
extern byte *uncompressed;
void FreeWinding (threaddata_t *thread, winding_t *w);
winding_t *NewWinding (threaddata_t *thread, int points);
winding_t *ClipWinding (threaddata_t *thread, winding_t *in, vec4f_t split,
qboolean keepon);
winding_t *CopyWinding (threaddata_t *thread, const winding_t *w);
void ClusterFlow (int clusternum);
void PortalBase (basethread_t *thread, portal_t *portal);
void PortalFlow (threaddata_t *data, portal_t *portal);
void CalcAmbientSounds (void);
#endif// __vis_h