~33% speed improvement on vis by using already-allocated memory for the vis stack

This commit is contained in:
Jonathan 2022-06-17 13:53:35 -04:00
parent 46aaa81ffd
commit c3bb07acaa
3 changed files with 20 additions and 10 deletions

View File

@ -150,14 +150,15 @@ struct pstack_t
leaf_t *leaf;
portal_t *portal; // portal exiting
std::shared_ptr<winding_t> source, pass;
std::shared_ptr<winding_t> windings[STACK_WINDINGS]; // Fixed size windings
winding_t windings[STACK_WINDINGS]; // Fixed size windings
bool windings_used[STACK_WINDINGS]; // whether the winding is used currently
qplane3d portalplane;
leafbits_t *mightsee; // bit string
qplane3d separators[2][MAX_SEPARATORS]; /* Separator cache */
int numseparators[2];
};
std::shared_ptr<winding_t> &AllocStackWinding(pstack_t *stack);
std::shared_ptr<winding_t> AllocStackWinding(pstack_t *stack);
void FreeStackWinding(std::shared_ptr<winding_t> &w, pstack_t *stack);
std::shared_ptr<winding_t> ClipStackWinding(std::shared_ptr<winding_t> &in, pstack_t *stack, qplane3d *split);

View File

@ -179,7 +179,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs
stack.numseparators[1] = 0;
for (i = 0; i < STACK_WINDINGS; i++)
stack.windings[i].reset();
stack.windings_used[i] = false;
leafbits_t local(portalleafs);
stack.mightsee = &local;

View File

@ -63,6 +63,10 @@ void vis_settings::initialize(int argc, const char **argv)
settings::vis_settings options;
fs::path portalfile, statefile, statetmpfile;
struct noop_delete {
void operator()(winding_t *p) const { }
};
/*
==================
@ -71,11 +75,14 @@ fs::path portalfile, statefile, statetmpfile;
Return a pointer to a free fixed winding on the stack
==================
*/
std::shared_ptr<winding_t> &AllocStackWinding(pstack_t *stack)
std::shared_ptr<winding_t> AllocStackWinding(pstack_t *stack)
{
for (auto &winding : stack->windings) {
if (!winding) {
return (winding = std::make_shared<winding_t>());
for (size_t i = 0; i < STACK_WINDINGS; i++) {
if (!stack->windings_used[i]) {
stack->windings_used[i] = true;
return std::shared_ptr<winding_t>(&stack->windings[i], [stack, i]([[maybe_unused]] winding_t *) {
stack->windings_used[i] = false;
});
}
}
@ -89,14 +96,16 @@ std::shared_ptr<winding_t> &AllocStackWinding(pstack_t *stack)
As long as the winding passed in is local to the stack, free it. Otherwise,
do nothing (the winding either belongs to a portal or another stack
structure further up the call chain).
FIXME: is there some way we can refactor this out entirely? the deleter
for stack windings is safe
==================
*/
void FreeStackWinding(std::shared_ptr<winding_t> &w, pstack_t *stack)
{
for (auto &winding : stack->windings) {
if (winding == w) {
for (size_t i = 0; i < STACK_WINDINGS; i++) {
if (stack->windings_used[i] && &stack->windings[i] == w.get()) {
w.reset();
winding.reset();
return;
}
}