mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- store the wall render nodes as pointers, not as objects.
This is mainly for future-proofing because storing these as objects in an array not only has a negative impact when using multithreading due to longer blocking time for the threads but also makes it hard to cache this data for reuse.
This commit is contained in:
parent
e15baa21cb
commit
e8eb8dd596
5 changed files with 59 additions and 47 deletions
|
@ -559,7 +559,8 @@ bool FDrawInfo::PutWallCompat(GLWall *wall, int passflag)
|
||||||
bool masked = passflag == 2 && wall->gltexture->isMasked();
|
bool masked = passflag == 2 && wall->gltexture->isMasked();
|
||||||
|
|
||||||
int list = list_indices[masked][foggy];
|
int list = list_indices[masked][foggy];
|
||||||
dldrawlists[list].AddWall(wall);
|
auto newwall = dldrawlists[list].NewWall();
|
||||||
|
*newwall = *wall;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
#include "memarena.h"
|
||||||
|
|
||||||
#include "gl/system/gl_cvars.h"
|
#include "gl/system/gl_cvars.h"
|
||||||
#include "gl/data/gl_vertexbuffer.h"
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
|
@ -50,6 +51,13 @@
|
||||||
FDrawInfo * gl_drawinfo;
|
FDrawInfo * gl_drawinfo;
|
||||||
FDrawInfoList di_list;
|
FDrawInfoList di_list;
|
||||||
|
|
||||||
|
static FMemArena RenderDataAllocator(1024*1024); // Use large blocks to reduce allocation time.
|
||||||
|
|
||||||
|
void ResetAllocator()
|
||||||
|
{
|
||||||
|
RenderDataAllocator.FreeAll();
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -244,7 +252,7 @@ SortNode * GLDrawList::FindSortWall(SortNode * head)
|
||||||
GLDrawItem * it = &drawitems[node->itemindex];
|
GLDrawItem * it = &drawitems[node->itemindex];
|
||||||
if (it->rendertype == GLDIT_WALL)
|
if (it->rendertype == GLDIT_WALL)
|
||||||
{
|
{
|
||||||
float d = walls[it->index].ViewDistance;
|
float d = walls[it->index]->ViewDistance;
|
||||||
if (d > farthest) farthest = d;
|
if (d > farthest) farthest = d;
|
||||||
if (d < nearest) nearest = d;
|
if (d < nearest) nearest = d;
|
||||||
}
|
}
|
||||||
|
@ -258,7 +266,7 @@ SortNode * GLDrawList::FindSortWall(SortNode * head)
|
||||||
GLDrawItem * it = &drawitems[node->itemindex];
|
GLDrawItem * it = &drawitems[node->itemindex];
|
||||||
if (it->rendertype == GLDIT_WALL)
|
if (it->rendertype == GLDIT_WALL)
|
||||||
{
|
{
|
||||||
float di = fabsf(walls[it->index].ViewDistance - farthest);
|
float di = fabsf(walls[it->index]->ViewDistance - farthest);
|
||||||
if (!best || di < bestdist)
|
if (!best || di < bestdist)
|
||||||
{
|
{
|
||||||
best = node;
|
best = node;
|
||||||
|
@ -297,7 +305,7 @@ void GLDrawList::SortPlaneIntoPlane(SortNode * head,SortNode * sort)
|
||||||
void GLDrawList::SortWallIntoPlane(SortNode * head, SortNode * sort)
|
void GLDrawList::SortWallIntoPlane(SortNode * head, SortNode * sort)
|
||||||
{
|
{
|
||||||
GLFlat * fh = &flats[drawitems[head->itemindex].index];
|
GLFlat * fh = &flats[drawitems[head->itemindex].index];
|
||||||
GLWall * ws=&walls[drawitems[sort->itemindex].index];
|
GLWall * ws = walls[drawitems[sort->itemindex].index];
|
||||||
|
|
||||||
bool ceiling = fh->z > r_viewpoint.Pos.Z;
|
bool ceiling = fh->z > r_viewpoint.Pos.Z;
|
||||||
|
|
||||||
|
@ -305,18 +313,13 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort)
|
||||||
{
|
{
|
||||||
// We have to split this wall!
|
// We have to split this wall!
|
||||||
|
|
||||||
// WARNING: NEVER EVER push a member of an array onto the array itself.
|
GLWall *w = NewWall();
|
||||||
// Bad things will happen if the memory must be reallocated!
|
*w = *ws;
|
||||||
GLWall w = *ws;
|
|
||||||
AddWall(&w);
|
|
||||||
|
|
||||||
// Splitting is done in the shader with clip planes, if available
|
// Splitting is done in the shader with clip planes, if available
|
||||||
if (gl.flags & RFL_NO_CLIP_PLANES)
|
if (gl.flags & RFL_NO_CLIP_PLANES)
|
||||||
{
|
{
|
||||||
GLWall * ws1;
|
|
||||||
ws->vertcount = 0; // invalidate current vertices.
|
ws->vertcount = 0; // invalidate current vertices.
|
||||||
ws1=&walls[walls.Size()-1];
|
|
||||||
ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated!
|
|
||||||
float newtexv = ws->tcs[GLWall::UPLFT].v + ((ws->tcs[GLWall::LOLFT].v - ws->tcs[GLWall::UPLFT].v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]);
|
float newtexv = ws->tcs[GLWall::UPLFT].v + ((ws->tcs[GLWall::LOLFT].v - ws->tcs[GLWall::UPLFT].v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]);
|
||||||
|
|
||||||
// I make the very big assumption here that translucent walls in sloped sectors
|
// I make the very big assumption here that translucent walls in sloped sectors
|
||||||
|
@ -324,13 +327,13 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort)
|
||||||
// code would become extremely more complicated.
|
// code would become extremely more complicated.
|
||||||
if (!ceiling)
|
if (!ceiling)
|
||||||
{
|
{
|
||||||
ws->ztop[1] = ws1->zbottom[1] = ws->ztop[0] = ws1->zbottom[0] = fh->z;
|
ws->ztop[1] = w->zbottom[1] = ws->ztop[0] = w->zbottom[0] = fh->z;
|
||||||
ws->tcs[GLWall::UPRGT].v = ws1->tcs[GLWall::LORGT].v = ws->tcs[GLWall::UPLFT].v = ws1->tcs[GLWall::LOLFT].v = newtexv;
|
ws->tcs[GLWall::UPRGT].v = w->tcs[GLWall::LORGT].v = ws->tcs[GLWall::UPLFT].v = w->tcs[GLWall::LOLFT].v = newtexv;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ws1->ztop[1] = ws->zbottom[1] = ws1->ztop[0] = ws->zbottom[0] = fh->z;
|
w->ztop[1] = ws->zbottom[1] = w->ztop[0] = ws->zbottom[0] = fh->z;
|
||||||
ws1->tcs[GLWall::UPLFT].v = ws->tcs[GLWall::LOLFT].v = ws1->tcs[GLWall::UPRGT].v = ws->tcs[GLWall::LORGT].v=newtexv;
|
w->tcs[GLWall::UPLFT].v = ws->tcs[GLWall::LOLFT].v = w->tcs[GLWall::UPRGT].v = ws->tcs[GLWall::LORGT].v = newtexv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,9 +424,8 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort)
|
||||||
|
|
||||||
void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
|
void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
|
||||||
{
|
{
|
||||||
GLWall * wh=&walls[drawitems[head->itemindex].index];
|
GLWall * wh= walls[drawitems[head->itemindex].index];
|
||||||
GLWall * ws=&walls[drawitems[sort->itemindex].index];
|
GLWall * ws= walls[drawitems[sort->itemindex].index];
|
||||||
GLWall * ws1;
|
|
||||||
float v1=wh->PointOnSide(ws->glseg.x1,ws->glseg.y1);
|
float v1=wh->PointOnSide(ws->glseg.x1,ws->glseg.y1);
|
||||||
float v2=wh->PointOnSide(ws->glseg.x2,ws->glseg.y2);
|
float v2=wh->PointOnSide(ws->glseg.x2,ws->glseg.y2);
|
||||||
|
|
||||||
|
@ -461,21 +463,18 @@ void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
|
||||||
float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0]));
|
float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0]));
|
||||||
|
|
||||||
ws->vertcount = 0; // invalidate current vertices.
|
ws->vertcount = 0; // invalidate current vertices.
|
||||||
GLWall w=*ws;
|
GLWall *w= NewWall();
|
||||||
AddWall(&w);
|
|
||||||
ws1=&walls[walls.Size()-1];
|
|
||||||
ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated!
|
|
||||||
|
|
||||||
ws1->glseg.x1=ws->glseg.x2=ix;
|
w->glseg.x1=ws->glseg.x2=ix;
|
||||||
ws1->glseg.y1=ws->glseg.y2=iy;
|
w->glseg.y1=ws->glseg.y2=iy;
|
||||||
ws1->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft);
|
w->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft);
|
||||||
ws1->ztop[0]=ws->ztop[1]=izt;
|
w->ztop[0]=ws->ztop[1]=izt;
|
||||||
ws1->zbottom[0]=ws->zbottom[1]=izb;
|
w->zbottom[0]=ws->zbottom[1]=izb;
|
||||||
ws1->tcs[GLWall::LOLFT].u = ws1->tcs[GLWall::UPLFT].u = ws->tcs[GLWall::LORGT].u = ws->tcs[GLWall::UPRGT].u = iu;
|
w->tcs[GLWall::LOLFT].u = w->tcs[GLWall::UPLFT].u = ws->tcs[GLWall::LORGT].u = ws->tcs[GLWall::UPRGT].u = iu;
|
||||||
if (gl.buffermethod == BM_DEFERRED)
|
if (gl.buffermethod == BM_DEFERRED)
|
||||||
{
|
{
|
||||||
ws->MakeVertices(false);
|
ws->MakeVertices(false);
|
||||||
ws1->MakeVertices(false);
|
w->MakeVertices(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SortNode * sort2=SortNodes.GetNew();
|
SortNode * sort2=SortNodes.GetNew();
|
||||||
|
@ -507,7 +506,7 @@ EXTERN_CVAR(Bool, gl_billboard_particles)
|
||||||
|
|
||||||
void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
|
void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
|
||||||
{
|
{
|
||||||
GLWall * wh=&walls[drawitems[head->itemindex].index];
|
GLWall *wh= walls[drawitems[head->itemindex].index];
|
||||||
GLSprite * ss=&sprites[drawitems[sort->itemindex].index];
|
GLSprite * ss=&sprites[drawitems[sort->itemindex].index];
|
||||||
GLSprite * ss1;
|
GLSprite * ss1;
|
||||||
|
|
||||||
|
@ -731,7 +730,7 @@ void GLDrawList::DoDraw(int pass, int i, bool trans)
|
||||||
|
|
||||||
case GLDIT_WALL:
|
case GLDIT_WALL:
|
||||||
{
|
{
|
||||||
GLWall * w=&walls[drawitems[i].index];
|
GLWall * w= walls[drawitems[i].index];
|
||||||
RenderWall.Clock();
|
RenderWall.Clock();
|
||||||
w->Draw(pass);
|
w->Draw(pass);
|
||||||
RenderWall.Unclock();
|
RenderWall.Unclock();
|
||||||
|
@ -863,7 +862,7 @@ void GLDrawList::DrawWalls(int pass)
|
||||||
RenderWall.Clock();
|
RenderWall.Clock();
|
||||||
for(unsigned i=0;i<drawitems.Size();i++)
|
for(unsigned i=0;i<drawitems.Size();i++)
|
||||||
{
|
{
|
||||||
walls[drawitems[i].index].Draw(pass);
|
walls[drawitems[i].index]->Draw(pass);
|
||||||
}
|
}
|
||||||
RenderWall.Unclock();
|
RenderWall.Unclock();
|
||||||
}
|
}
|
||||||
|
@ -892,7 +891,7 @@ void GLDrawList::DrawDecals()
|
||||||
{
|
{
|
||||||
for(unsigned i=0;i<drawitems.Size();i++)
|
for(unsigned i=0;i<drawitems.Size();i++)
|
||||||
{
|
{
|
||||||
walls[drawitems[i].index].DoDrawDecals();
|
walls[drawitems[i].index]->DoDrawDecals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,8 +907,8 @@ void GLDrawList::SortWalls()
|
||||||
{
|
{
|
||||||
std::sort(drawitems.begin(), drawitems.end(), [=](const GLDrawItem &a, const GLDrawItem &b) -> bool
|
std::sort(drawitems.begin(), drawitems.end(), [=](const GLDrawItem &a, const GLDrawItem &b) -> bool
|
||||||
{
|
{
|
||||||
GLWall * w1 = &walls[a.index];
|
GLWall * w1 = walls[a.index];
|
||||||
GLWall * w2 = &walls[b.index];
|
GLWall * w2 = walls[b.index];
|
||||||
|
|
||||||
if (w1->gltexture != w2->gltexture) return w1->gltexture < w2->gltexture;
|
if (w1->gltexture != w2->gltexture) return w1->gltexture < w2->gltexture;
|
||||||
return (w1->flags & 3) < (w2->flags & 3);
|
return (w1->flags & 3) < (w2->flags & 3);
|
||||||
|
@ -936,9 +935,12 @@ void GLDrawList::SortFlats()
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void GLDrawList::AddWall(GLWall * wall)
|
|
||||||
|
GLWall *GLDrawList::NewWall()
|
||||||
{
|
{
|
||||||
drawitems.Push(GLDrawItem(GLDIT_WALL,walls.Push(*wall)));
|
auto wall = (GLWall*)RenderDataAllocator.Alloc(sizeof(GLWall));
|
||||||
|
drawitems.Push(GLDrawItem(GLDIT_WALL, walls.Push(wall)));
|
||||||
|
return wall;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1059,6 +1061,8 @@ void FDrawInfo::EndDrawInfo()
|
||||||
}
|
}
|
||||||
gl_drawinfo=di->next;
|
gl_drawinfo=di->next;
|
||||||
di_list.Release(di);
|
di_list.Release(di);
|
||||||
|
if (gl_drawinfo == nullptr)
|
||||||
|
ResetAllocator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ struct SortNode
|
||||||
struct GLDrawList
|
struct GLDrawList
|
||||||
{
|
{
|
||||||
//private:
|
//private:
|
||||||
TArray<GLWall> walls;
|
TArray<GLWall*> walls;
|
||||||
TArray<GLFlat> flats;
|
TArray<GLFlat> flats;
|
||||||
TArray<GLSprite> sprites;
|
TArray<GLSprite> sprites;
|
||||||
TArray<GLDrawItem> drawitems;
|
TArray<GLDrawItem> drawitems;
|
||||||
|
@ -131,7 +131,8 @@ public:
|
||||||
return drawitems.Size();
|
return drawitems.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddWall(GLWall * wall);
|
GLWall *NewWall();
|
||||||
|
//void AddWall(GLWall * wall);
|
||||||
void AddFlat(GLFlat * flat);
|
void AddFlat(GLFlat * flat);
|
||||||
void AddSprite(GLSprite * sprite);
|
void AddSprite(GLSprite * sprite);
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
|
@ -55,7 +55,8 @@ void FDrawInfo::AddWall(GLWall *wall)
|
||||||
{
|
{
|
||||||
wall->ViewDistance = (r_viewpoint.Pos - (wall->seg->linedef->v1->fPos() + wall->seg->linedef->Delta() / 2)).XY().LengthSquared();
|
wall->ViewDistance = (r_viewpoint.Pos - (wall->seg->linedef->v1->fPos() + wall->seg->linedef->Delta() / 2)).XY().LengthSquared();
|
||||||
if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(true);
|
if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(true);
|
||||||
drawlists[GLDL_TRANSLUCENT].AddWall(wall);
|
auto newwall = drawlists[GLDL_TRANSLUCENT].NewWall();
|
||||||
|
*newwall = *wall;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -77,8 +78,8 @@ void FDrawInfo::AddWall(GLWall *wall)
|
||||||
list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS;
|
list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS;
|
||||||
}
|
}
|
||||||
if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(false);
|
if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(false);
|
||||||
drawlists[list].AddWall(wall);
|
auto newwall = drawlists[list].NewWall();
|
||||||
|
*newwall = *wall;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +173,8 @@ void GLWall::PutPortal(int ptype)
|
||||||
{
|
{
|
||||||
// draw a reflective layer over the mirror
|
// draw a reflective layer over the mirror
|
||||||
type=RENDERWALL_MIRRORSURFACE;
|
type=RENDERWALL_MIRRORSURFACE;
|
||||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].AddWall(this);
|
auto newwall = gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].NewWall();
|
||||||
|
*newwall = *this;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -560,6 +560,10 @@ public:
|
||||||
{
|
{
|
||||||
return Array[index];
|
return Array[index];
|
||||||
}
|
}
|
||||||
|
T &At(size_t index) const
|
||||||
|
{
|
||||||
|
return Array[index];
|
||||||
|
}
|
||||||
unsigned int Size() const
|
unsigned int Size() const
|
||||||
{
|
{
|
||||||
return Count;
|
return Count;
|
||||||
|
|
Loading…
Reference in a new issue