use alloca instead of thread-local static

This commit is contained in:
Jonathan 2022-08-13 20:30:51 -04:00
parent da5b40ce73
commit 40b04b9518
1 changed files with 40 additions and 23 deletions

View File

@ -114,13 +114,15 @@ BrushVolume
================== ==================
*/ */
template<typename T> template<typename T>
static vec_t BrushVolume(const T &brush) static vec_t BrushVolume(T begin, T end)
{ {
// grab the first valid point as the corner // grab the first valid point as the corner
bool found = false; bool found = false;
qvec3d corner; qvec3d corner;
for (auto &face : brush.sides) { for (auto it = begin; it != end; it++) {
auto &face = *it;
if (face.w.size() > 0) { if (face.w.size() > 0) {
corner = face.w[0]; corner = face.w[0];
found = true; found = true;
@ -133,13 +135,16 @@ static vec_t BrushVolume(const T &brush)
// make tetrahedrons to all other faces // make tetrahedrons to all other faces
vec_t volume = 0; vec_t volume = 0;
for (auto &side : brush.sides) { for (auto it = begin; it != end; it++) {
if (!side.w.size()) { auto &face = *it;
if (!face.w.size()) {
continue; continue;
} }
auto &plane = side.get_plane();
auto &plane = face.get_plane();
vec_t d = -(qv::dot(corner, plane.get_normal()) - plane.get_dist()); vec_t d = -(qv::dot(corner, plane.get_normal()) - plane.get_dist());
vec_t area = side.w.area(); vec_t area = face.w.area();
volume += d * area; volume += d * area;
} }
@ -545,7 +550,7 @@ static twosided<bspbrush_t::ptr> SplitBrush(bspbrush_t::ptr brush, size_t planen
} }
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
vec_t v1 = BrushVolume(*result[i]); vec_t v1 = BrushVolume(result[i]->sides.begin(), result[i]->sides.end());
if (v1 < qbsp_options.microvolume.value()) { if (v1 < qbsp_options.microvolume.value()) {
result[i] = nullptr; result[i] = nullptr;
if (stats) { if (stats) {
@ -579,16 +584,26 @@ struct stack_side_t
struct stack_brush_t struct stack_brush_t
{ {
std::vector<stack_side_t> sides;
aabb3d bounds; aabb3d bounds;
size_t num_sides;
// stack allocated
stack_side_t *sides;
~stack_brush_t()
{
for (size_t i = 0; i < num_sides; i++) {
sides[i].~stack_side_t();
}
}
inline bool update_bounds() inline bool update_bounds()
{ {
this->bounds = {}; this->bounds = {};
for (const auto &face : sides) { for (size_t i = 0; i < num_sides; i++) {
if (face.w) { if (sides[i].w) {
this->bounds.unionWith_in_place(face.w.bounds()); this->bounds.unionWith_in_place(sides[i].w.bounds());
} }
} }
@ -660,11 +675,11 @@ static bool CheckSplitBrush(const bspbrush_t::ptr &brush, size_t planenum)
// split it for real // split it for real
// start with 2 empty brushes // start with 2 empty brushes
thread_local static twosided<stack_brush_t> temporary_brushes; twosided<stack_brush_t> temporary_brushes;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
temporary_brushes[i].sides.clear(); temporary_brushes[i].sides = (stack_side_t *) alloca(sizeof(stack_side_t) * (brush->sides.size() + 1));
temporary_brushes[i].sides.reserve(brush->sides.size() + 1); temporary_brushes[i].num_sides = 0;
} }
// split all the current windings // split all the current windings
@ -678,7 +693,8 @@ static bool CheckSplitBrush(const bspbrush_t::ptr &brush, size_t planenum)
} }
// add the clipped face to result[j] // add the clipped face to result[j]
stack_side_t &faceCopy = temporary_brushes[j].sides.emplace_back(); stack_side_t &faceCopy = temporary_brushes[j].sides[temporary_brushes[j].num_sides++];
new(&faceCopy) stack_side_t;
faceCopy.planenum = face.planenum; faceCopy.planenum = face.planenum;
faceCopy.w = std::move(*cw[j]); faceCopy.w = std::move(*cw[j]);
} }
@ -687,17 +703,17 @@ static bool CheckSplitBrush(const bspbrush_t::ptr &brush, size_t planenum)
// see if we have valid polygons on both sides // see if we have valid polygons on both sides
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (temporary_brushes[i].sides.size() < 3) { if (temporary_brushes[i].num_sides < 3) {
return false; return false;
} }
if (!temporary_brushes[i].update_bounds()) { if (!temporary_brushes[i].update_bounds()) {
return false; return false;
} else { }
for (int j = 0; j < 3; j++) {
if (temporary_brushes[i].bounds.mins()[j] < -qbsp_options.worldextent.value() || temporary_brushes[i].bounds.maxs()[j] > qbsp_options.worldextent.value()) { for (int j = 0; j < 3; j++) {
return false; if (temporary_brushes[i].bounds.mins()[j] < -qbsp_options.worldextent.value() || temporary_brushes[i].bounds.maxs()[j] > qbsp_options.worldextent.value()) {
} return false;
} }
} }
} }
@ -706,7 +722,8 @@ static bool CheckSplitBrush(const bspbrush_t::ptr &brush, size_t planenum)
// FIXME: check if we can remove this/if BrushVolume below // FIXME: check if we can remove this/if BrushVolume below
// will have the same result either way // will have the same result either way
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
stack_side_t &cs = temporary_brushes[i].sides.emplace_back(); stack_side_t &cs = temporary_brushes[i].sides[temporary_brushes[i].num_sides++];
new(&cs) stack_side_t;
const bool brushOnFront = (i == 0); const bool brushOnFront = (i == 0);
@ -720,7 +737,7 @@ static bool CheckSplitBrush(const bspbrush_t::ptr &brush, size_t planenum)
} }
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
vec_t v1 = BrushVolume(temporary_brushes[i]); vec_t v1 = BrushVolume(temporary_brushes[i].sides, temporary_brushes[i].sides + temporary_brushes[i].num_sides);
if (v1 < qbsp_options.microvolume.value()) { if (v1 < qbsp_options.microvolume.value()) {
return false; return false;
} }