mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-16 06:00:33 +01:00
rt: extract bit array
This commit is contained in:
parent
9f6fa0a8cb
commit
c53f22d028
38
ref_vk/bitarray.c
Normal file
38
ref_vk/bitarray.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include "bitarray.h"
|
||||||
|
|
||||||
|
#include "vk_core.h"
|
||||||
|
|
||||||
|
bit_array_t bitArrayCreate(uint32_t size) {
|
||||||
|
size = (size + 31) / 32;
|
||||||
|
bit_array_t ret = {
|
||||||
|
.size = size,
|
||||||
|
.bits = Mem_Malloc(vk_core.pool, size * sizeof(uint32_t))
|
||||||
|
};
|
||||||
|
bitArrayClear(&ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitArrayDestroy(bit_array_t *ba) {
|
||||||
|
if (ba->bits)
|
||||||
|
Mem_Free(ba->bits);
|
||||||
|
ba->bits = NULL;
|
||||||
|
ba->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitArrayClear(bit_array_t *ba) {
|
||||||
|
memset(ba->bits, 0, ba->size * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean bitArrayCheckOrSet(bit_array_t *ba, uint32_t index) {
|
||||||
|
const uint32_t offset = index / 32;
|
||||||
|
ASSERT(offset < ba->size);
|
||||||
|
|
||||||
|
uint32_t* bits = ba->bits + offset;
|
||||||
|
|
||||||
|
const uint32_t bit = 1u << (index % 32);
|
||||||
|
if ((*bits) & bit)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
(*bits) |= bit;
|
||||||
|
return true;
|
||||||
|
}
|
15
ref_vk/bitarray.h
Normal file
15
ref_vk/bitarray.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <xash3d_types.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t *bits;
|
||||||
|
} bit_array_t;
|
||||||
|
|
||||||
|
bit_array_t bitArrayCreate(uint32_t size);
|
||||||
|
void bitArrayDestroy(bit_array_t *ba);
|
||||||
|
void bitArrayClear(bit_array_t *ba);
|
||||||
|
|
||||||
|
// Returns true if wasn't set
|
||||||
|
qboolean bitArrayCheckOrSet(bit_array_t *ba, uint32_t index);
|
@ -6,6 +6,7 @@
|
|||||||
#include "vk_cvar.h"
|
#include "vk_cvar.h"
|
||||||
#include "vk_common.h"
|
#include "vk_common.h"
|
||||||
#include "shaders/ray_interop.h"
|
#include "shaders/ray_interop.h"
|
||||||
|
#include "bitarray.h"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
|
|
||||||
#include "mod_local.h"
|
#include "mod_local.h"
|
||||||
@ -69,6 +70,8 @@ static struct {
|
|||||||
int polygon_vertices;
|
int polygon_vertices;
|
||||||
} num_static;
|
} num_static;
|
||||||
|
|
||||||
|
bit_array_t visited_cells;
|
||||||
|
|
||||||
} g_lights_;
|
} g_lights_;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
@ -108,14 +111,12 @@ qboolean VK_LightsInit( void ) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clusterBitMapShutdown( void );
|
|
||||||
|
|
||||||
void VK_LightsShutdown( void ) {
|
void VK_LightsShutdown( void ) {
|
||||||
VK_BufferDestroy(&g_lights_.staging);
|
VK_BufferDestroy(&g_lights_.staging);
|
||||||
VK_BufferDestroy(&g_lights_.buffer);
|
VK_BufferDestroy(&g_lights_.buffer);
|
||||||
|
|
||||||
gEngine.Cmd_RemoveCommand("vk_lights_dump");
|
gEngine.Cmd_RemoveCommand("vk_lights_dump");
|
||||||
clusterBitMapShutdown();
|
bitArrayDestroy(&g_lights_.visited_cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -389,41 +390,6 @@ vk_light_leaf_set_t *getMapLeafsAffectedByMapSurface( const msurface_t *surf ) {
|
|||||||
return smeta->potentially_visible_leafs;
|
return smeta->potentially_visible_leafs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
#define CLUSTERS_BIT_MAP_SIZE_UINT ((g_lights.map.grid_cells + 31) / 32)
|
|
||||||
uint32_t *clusters_bit_map;
|
|
||||||
} g_lights_tmp;
|
|
||||||
|
|
||||||
static void clusterBitMapClear( void ) {
|
|
||||||
memset(g_lights_tmp.clusters_bit_map, 0, CLUSTERS_BIT_MAP_SIZE_UINT * sizeof(uint32_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if wasn't set
|
|
||||||
static qboolean clusterBitMapCheckOrSet( int cell_index ) {
|
|
||||||
uint32_t *const bits = g_lights_tmp.clusters_bit_map + (cell_index / 32);
|
|
||||||
const uint32_t bit = 1u << (cell_index % 32);
|
|
||||||
|
|
||||||
if ((*bits) & bit)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
(*bits) |= bit;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clusterBitMapInit( void ) {
|
|
||||||
ASSERT(!g_lights_tmp.clusters_bit_map);
|
|
||||||
|
|
||||||
g_lights_tmp.clusters_bit_map = Mem_Malloc(vk_core.pool, CLUSTERS_BIT_MAP_SIZE_UINT * sizeof(uint32_t));
|
|
||||||
clusterBitMapClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clusterBitMapShutdown( void ) {
|
|
||||||
if (g_lights_tmp.clusters_bit_map)
|
|
||||||
Mem_Free(g_lights_tmp.clusters_bit_map);
|
|
||||||
g_lights_tmp.clusters_bit_map = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RT_LightCellIndex( const int light_cell[3] ) {
|
int RT_LightCellIndex( const int light_cell[3] ) {
|
||||||
if (light_cell[0] < 0 || light_cell[1] < 0 || light_cell[2] < 0
|
if (light_cell[0] < 0 || light_cell[1] < 0 || light_cell[2] < 0
|
||||||
|| (light_cell[0] >= g_lights.map.grid_size[0])
|
|| (light_cell[0] >= g_lights.map.grid_size[0])
|
||||||
@ -548,8 +514,8 @@ void RT_LightsNewMapBegin( const struct model_s *map ) {
|
|||||||
g_lights.map.grid_cells
|
g_lights.map.grid_cells
|
||||||
);
|
);
|
||||||
|
|
||||||
clusterBitMapShutdown();
|
bitArrayDestroy(&g_lights_.visited_cells);
|
||||||
clusterBitMapInit();
|
g_lights_.visited_cells = bitArrayCreate(g_lights.map.grid_cells);
|
||||||
|
|
||||||
prepareSurfacesLeafVisibilityCache( map );
|
prepareSurfacesLeafVisibilityCache( map );
|
||||||
|
|
||||||
@ -688,7 +654,7 @@ static void addLightIndexToLeaf( const mleaf_t *leaf, int index ) {
|
|||||||
if (cell_index < 0)
|
if (cell_index < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (clusterBitMapCheckOrSet( cell_index )) {
|
if (bitArrayCheckOrSet(&g_lights_.visited_cells, cell_index)) {
|
||||||
if (!addLightToCell(cell_index, index)) {
|
if (!addLightToCell(cell_index, index)) {
|
||||||
ERROR_THROTTLED(10, "Cluster %d,%d,%d(%d) ran out of light slots",
|
ERROR_THROTTLED(10, "Cluster %d,%d,%d(%d) ran out of light slots",
|
||||||
cell[0], cell[1], cell[2], cell_index);
|
cell[0], cell[1], cell[2], cell_index);
|
||||||
@ -700,10 +666,10 @@ static void addLightIndexToLeaf( const mleaf_t *leaf, int index ) {
|
|||||||
static void addPointLightToAllClusters( int index ) {
|
static void addPointLightToAllClusters( int index ) {
|
||||||
const model_t* const world = gEngine.pfnGetModelByIndex( 1 );
|
const model_t* const world = gEngine.pfnGetModelByIndex( 1 );
|
||||||
|
|
||||||
// TODO there's certainly a better way to do this: just enumerate
|
// FIXME there's certainly a better way to do this: just enumerate
|
||||||
// all clusters, not all leafs
|
// all clusters, not all leafs
|
||||||
|
|
||||||
clusterBitMapClear();
|
bitArrayClear(&g_lights_.visited_cells);
|
||||||
for (int i = 1; i <= world->numleafs; ++i) {
|
for (int i = 1; i <= world->numleafs; ++i) {
|
||||||
const mleaf_t *const leaf = world->leafs + i;
|
const mleaf_t *const leaf = world->leafs + i;
|
||||||
addLightIndexToLeaf( leaf, index );
|
addLightIndexToLeaf( leaf, index );
|
||||||
@ -726,7 +692,7 @@ static void addPointLightToClusters( int index ) {
|
|||||||
leafAccumAddPotentiallyVisibleFromLeaf( world, leaf, false);
|
leafAccumAddPotentiallyVisibleFromLeaf( world, leaf, false);
|
||||||
leafAccumFinalize();
|
leafAccumFinalize();
|
||||||
|
|
||||||
clusterBitMapClear();
|
bitArrayClear(&g_lights_.visited_cells);
|
||||||
for (int i = 0; i < leafs->num; ++i) {
|
for (int i = 0; i < leafs->num; ++i) {
|
||||||
const mleaf_t *const leaf = world->leafs + leafs->leafs[i];
|
const mleaf_t *const leaf = world->leafs + leafs->leafs[i];
|
||||||
addLightIndexToLeaf( leaf, index );
|
addLightIndexToLeaf( leaf, index );
|
||||||
@ -1001,7 +967,6 @@ qboolean RT_GetEmissiveForTexture( vec3_t out, int texture_id ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void addPolygonLightIndexToLeaf(const mleaf_t* leaf, int poly_index) {
|
static void addPolygonLightIndexToLeaf(const mleaf_t* leaf, int poly_index) {
|
||||||
const int min_x = floorf(leaf->minmaxs[0] / LIGHT_GRID_CELL_SIZE);
|
const int min_x = floorf(leaf->minmaxs[0] / LIGHT_GRID_CELL_SIZE);
|
||||||
const int min_y = floorf(leaf->minmaxs[1] / LIGHT_GRID_CELL_SIZE);
|
const int min_y = floorf(leaf->minmaxs[1] / LIGHT_GRID_CELL_SIZE);
|
||||||
@ -1038,7 +1003,7 @@ static void addPolygonLightIndexToLeaf(const mleaf_t* leaf, int poly_index) {
|
|||||||
if (cell_index < 0)
|
if (cell_index < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (clusterBitMapCheckOrSet( cell_index )) {
|
if (bitArrayCheckOrSet(&g_lights_.visited_cells, cell_index)) {
|
||||||
const float minmaxs[6] = {
|
const float minmaxs[6] = {
|
||||||
x * LIGHT_GRID_CELL_SIZE,
|
x * LIGHT_GRID_CELL_SIZE,
|
||||||
y * LIGHT_GRID_CELL_SIZE,
|
y * LIGHT_GRID_CELL_SIZE,
|
||||||
@ -1062,10 +1027,10 @@ static void addPolygonLightIndexToLeaf(const mleaf_t* leaf, int poly_index) {
|
|||||||
static void addPolygonLightToAllClusters( int poly_index ) {
|
static void addPolygonLightToAllClusters( int poly_index ) {
|
||||||
const model_t* const world = gEngine.pfnGetModelByIndex( 1 );
|
const model_t* const world = gEngine.pfnGetModelByIndex( 1 );
|
||||||
|
|
||||||
// TODO there's certainly a better way to do this: just enumerate
|
// FIXME there's certainly a better way to do this: just enumerate
|
||||||
// all clusters, not all leafs
|
// all clusters, not all leafs
|
||||||
|
|
||||||
clusterBitMapClear();
|
bitArrayClear(&g_lights_.visited_cells);
|
||||||
for (int i = 1; i <= world->numleafs; ++i) {
|
for (int i = 1; i <= world->numleafs; ++i) {
|
||||||
const mleaf_t *const leaf = world->leafs + i;
|
const mleaf_t *const leaf = world->leafs + i;
|
||||||
addPolygonLightIndexToLeaf( leaf, poly_index );
|
addPolygonLightIndexToLeaf( leaf, poly_index );
|
||||||
@ -1079,7 +1044,7 @@ static void addPolygonLeafSetToClusters(const vk_light_leaf_set_t *leafs, int po
|
|||||||
if (!leafs)
|
if (!leafs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clusterBitMapClear();
|
bitArrayClear(&g_lights_.visited_cells);
|
||||||
|
|
||||||
// Iterate through each visible/potentially affected leaf to get a range of grid cells
|
// Iterate through each visible/potentially affected leaf to get a range of grid cells
|
||||||
for (int i = 0; i < leafs->num; ++i) {
|
for (int i = 0; i < leafs->num; ++i) {
|
||||||
|
Loading…
Reference in New Issue
Block a user