Changed visible plane list to use the shared frame memory allocator instead of using its own internal free list

This commit is contained in:
Magnus Norddahl 2017-01-19 01:47:58 +01:00
parent 111b5c5469
commit a92771431b
6 changed files with 49 additions and 124 deletions

View file

@ -43,6 +43,18 @@ CVAR(Bool, tilt, false, 0);
namespace swrenderer namespace swrenderer
{ {
visplane_t::visplane_t()
{
picnum.SetNull();
height.set(0.0, 0.0, 1.0, 0.0);
bottom = RenderMemory::AllocMemory<uint16_t>(viewwidth);
top = RenderMemory::AllocMemory<uint16_t>(viewwidth);
fillshort(bottom, viewwidth, 0);
fillshort(top, viewwidth, 0x7fff);
}
void visplane_t::AddLights(FLightNode *node) void visplane_t::AddLights(FLightNode *node)
{ {
if (!r_dynlights) if (!r_dynlights)

View file

@ -15,6 +15,8 @@
#include <stddef.h> #include <stddef.h>
#include "r_defs.h" #include "r_defs.h"
#include "r_state.h"
#include "swrenderer/r_memory.h"
class ADynamicLight; class ADynamicLight;
struct FLightNode; struct FLightNode;
@ -31,40 +33,42 @@ namespace swrenderer
struct visplane_t struct visplane_t
{ {
visplane_t *next; // Next visplane in hash chain -- killough visplane_t();
FDynamicColormap *colormap; // [RH] Support multiple colormaps void AddLights(FLightNode *node);
FSectorPortal *portal; // [RH] Support sky boxes void Render(fixed_t alpha, bool additive, bool masked);
visplane_light *lights;
visplane_t *next = nullptr; // Next visplane in hash chain -- killough
FDynamicColormap *colormap = nullptr; // [RH] Support multiple colormaps
FSectorPortal *portal = nullptr; // [RH] Support sky boxes
visplane_light *lights = nullptr;
FTransform xform; FTransform xform;
secplane_t height; secplane_t height;
FTextureID picnum; FTextureID picnum;
int lightlevel; int lightlevel = 0;
int left, right; int left = viewwidth;
int sky; int right = 0;
int sky = 0;
// [RH] This set of variables copies information from the time when the // [RH] This set of variables copies information from the time when the
// visplane is created. They are only used by stacks so that you can // visplane is created. They are only used by stacks so that you can
// have stacked sectors inside a skybox. If the visplane is not for a // have stacked sectors inside a skybox. If the visplane is not for a
// stack, then they are unused. // stack, then they are unused.
int extralight; int extralight = 0;
double visibility; double visibility = 0.0;
DVector3 viewpos; DVector3 viewpos = { 0.0, 0.0, 0.0 };
DAngle viewangle; DAngle viewangle = { 0.0 };
fixed_t Alpha; fixed_t Alpha = 0;
bool Additive; bool Additive = false;
// kg3D - keep track of mirror and skybox owner // kg3D - keep track of mirror and skybox owner
int CurrentSkybox; int CurrentSkybox = 0;
int CurrentPortalUniq; // mirror counter, counts all of them int CurrentPortalUniq = 0; // mirror counter, counts all of them
int MirrorFlags; // this is not related to CurrentMirror int MirrorFlags = 0; // this is not related to CurrentMirror
unsigned short *bottom; // [RH] bottom and top arrays are dynamically uint16_t *bottom = nullptr;
unsigned short pad; // allocated immediately after the uint16_t *top = nullptr;
unsigned short top[]; // visplane.
void AddLights(FLightNode *node);
void Render(fixed_t alpha, bool additive, bool masked);
}; };
} }

View file

@ -54,87 +54,22 @@ namespace swrenderer
{ {
for (auto &plane : visplanes) for (auto &plane : visplanes)
plane = nullptr; plane = nullptr;
freehead = &freetail;
}
void VisiblePlaneList::Deinit()
{
// do not use R_ClearPlanes because at this point the screen pointer is no longer valid.
for (int i = 0; i <= MAXVISPLANES; i++) // new code -- killough
{
for (*freehead = visplanes[i], visplanes[i] = nullptr; *freehead; )
{
freehead = &(*freehead)->next;
}
}
for (visplane_t *pl = freetail; pl != nullptr; )
{
visplane_t *next = pl->next;
free(pl);
pl = next;
}
} }
visplane_t *VisiblePlaneList::Add(unsigned hash) visplane_t *VisiblePlaneList::Add(unsigned hash)
{ {
visplane_t *check = freetail; visplane_t *newplane = RenderMemory::NewObject<visplane_t>();
newplane->next = visplanes[hash];
if (check == nullptr) visplanes[hash] = newplane;
{ return newplane;
check = (visplane_t *)M_Malloc(sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH * 2));
memset(check, 0, sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH * 2));
check->bottom = check->top + MAXWIDTH + 2;
}
else if (nullptr == (freetail = freetail->next))
{
freehead = &freetail;
}
check->lights = nullptr;
check->next = visplanes[hash];
visplanes[hash] = check;
return check;
}
void VisiblePlaneList::Init()
{
int i;
visplane_t *pl;
// Free all visplanes and let them be re-allocated as needed.
pl = freetail;
while (pl)
{
visplane_t *next = pl->next;
M_Free(pl);
pl = next;
}
freetail = nullptr;
freehead = &freetail;
for (i = 0; i < MAXVISPLANES; i++)
{
pl = visplanes[i];
visplanes[i] = nullptr;
while (pl)
{
visplane_t *next = pl->next;
M_Free(pl);
pl = next;
}
}
} }
void VisiblePlaneList::Clear(bool fullclear) void VisiblePlaneList::Clear(bool fullclear)
{ {
int i;
// Don't clear fake planes if not doing a full clear. // Don't clear fake planes if not doing a full clear.
if (!fullclear) if (!fullclear)
{ {
for (i = 0; i <= MAXVISPLANES - 1; i++) // new code -- killough for (int i = 0; i <= MAXVISPLANES - 1; i++)
{ {
for (visplane_t **probe = &visplanes[i]; *probe != nullptr; ) for (visplane_t **probe = &visplanes[i]; *probe != nullptr; )
{ {
@ -143,25 +78,18 @@ namespace swrenderer
probe = &(*probe)->next; probe = &(*probe)->next;
} }
else else
{ // not fake: move to freelist { // not fake: move from list
visplane_t *vis = *probe; visplane_t *vis = *probe;
*freehead = vis;
*probe = vis->next; *probe = vis->next;
vis->next = nullptr; vis->next = nullptr;
freehead = &vis->next;
} }
} }
} }
} }
else else
{ {
for (i = 0; i <= MAXVISPLANES; i++) // new code -- killough for (int i = 0; i <= MAXVISPLANES; i++)
{ visplanes[i] = nullptr;
for (*freehead = visplanes[i], visplanes[i] = nullptr; *freehead; )
{
freehead = &(*freehead)->next;
}
}
} }
} }
@ -282,8 +210,6 @@ namespace swrenderer
check->colormap = basecolormap; // [RH] Save colormap check->colormap = basecolormap; // [RH] Save colormap
check->sky = sky; check->sky = sky;
check->portal = portal; check->portal = portal;
check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98
check->right = 0;
check->extralight = renderportal->stacked_extralight; check->extralight = renderportal->stacked_extralight;
check->visibility = renderportal->stacked_visibility; check->visibility = renderportal->stacked_visibility;
check->viewpos = renderportal->stacked_viewpos; check->viewpos = renderportal->stacked_viewpos;
@ -294,8 +220,6 @@ namespace swrenderer
check->MirrorFlags = renderportal->MirrorFlags; check->MirrorFlags = renderportal->MirrorFlags;
check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox; check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox;
fillshort(check->top, viewwidth, 0x7fff);
return check; return check;
} }
@ -330,8 +254,8 @@ namespace swrenderer
intrh = stop; intrh = stop;
} }
for (x = intrl; x < intrh && pl->top[x] == 0x7fff; x++) x = intrl;
; while (x < intrh && pl->top[x] == 0x7fff) x++;
if (x >= intrh) if (x >= intrh)
{ {
@ -374,7 +298,6 @@ namespace swrenderer
pl = new_pl; pl = new_pl;
pl->left = start; pl->left = start;
pl->right = stop; pl->right = stop;
fillshort(pl->top, viewwidth, 0x7fff);
} }
return pl; return pl;
} }

View file

@ -27,8 +27,6 @@ namespace swrenderer
public: public:
static VisiblePlaneList *Instance(); static VisiblePlaneList *Instance();
void Init();
void Deinit();
void Clear(bool fullclear); void Clear(bool fullclear);
visplane_t *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap); visplane_t *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap);
@ -39,8 +37,6 @@ namespace swrenderer
enum { MAXVISPLANES = 128 }; // must be a power of 2 enum { MAXVISPLANES = 128 }; // must be a power of 2
visplane_t *visplanes[MAXVISPLANES + 1]; visplane_t *visplanes[MAXVISPLANES + 1];
visplane_t *freetail = nullptr;
visplane_t **freehead = nullptr;
private: private:
VisiblePlaneList(); VisiblePlaneList();

View file

@ -123,8 +123,6 @@ namespace swrenderer
if (pl->right < pl->left || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES || pl->portal == nullptr) if (pl->right < pl->left || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES || pl->portal == nullptr)
{ {
pl->Render(OPAQUE, false, false); pl->Render(OPAQUE, false, false);
*planes->freehead = pl;
planes->freehead = &pl->next;
continue; continue;
} }
@ -164,8 +162,6 @@ namespace swrenderer
default: default:
pl->Render(OPAQUE, false, false); pl->Render(OPAQUE, false, false);
*planes->freehead = pl;
planes->freehead = &pl->next;
numskyboxes--; numskyboxes--;
continue; continue;
} }
@ -262,8 +258,6 @@ namespace swrenderer
{ {
pl->Render(pl->Alpha, pl->Additive, true); pl->Render(pl->Alpha, pl->Additive, true);
} }
*planes->freehead = pl;
planes->freehead = &pl->next;
} }
firstdrawseg = drawsegs; firstdrawseg = drawsegs;
ds_p = drawsegs + savedds_p; ds_p = drawsegs + savedds_p;
@ -283,8 +277,7 @@ namespace swrenderer
if (Clip3DFloors::Instance()->fakeActive) return; if (Clip3DFloors::Instance()->fakeActive) return;
for (*planes->freehead = planes->visplanes[VisiblePlaneList::MAXVISPLANES], planes->visplanes[VisiblePlaneList::MAXVISPLANES] = nullptr; *planes->freehead; ) planes->visplanes[VisiblePlaneList::MAXVISPLANES] = nullptr;
planes->freehead = &(*planes->freehead)->next;
} }
void RenderPortal::RenderLinePortals() void RenderPortal::RenderLinePortals()

View file

@ -246,8 +246,6 @@ namespace swrenderer
void RenderScene::ScreenResized() void RenderScene::ScreenResized()
{ {
VisiblePlaneList::Instance()->Init();
RenderTarget = screen; RenderTarget = screen;
int width = SCREENWIDTH; int width = SCREENWIDTH;
int height = SCREENHEIGHT; int height = SCREENHEIGHT;
@ -271,7 +269,6 @@ namespace swrenderer
void RenderScene::Deinit() void RenderScene::Deinit()
{ {
RenderTranslucentPass::Deinit(); RenderTranslucentPass::Deinit();
VisiblePlaneList::Instance()->Deinit();
Clip3DFloors::Instance()->Cleanup(); Clip3DFloors::Instance()->Cleanup();
R_FreeDrawSegs(); R_FreeDrawSegs();
} }