mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 04:01:31 +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();
|
||||
|
||||
int list = list_indices[masked][foggy];
|
||||
dldrawlists[list].AddWall(wall);
|
||||
auto newwall = dldrawlists[list].NewWall();
|
||||
*newwall = *wall;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "r_state.h"
|
||||
#include "doomstat.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "memarena.h"
|
||||
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
@ -50,6 +51,13 @@
|
|||
FDrawInfo * gl_drawinfo;
|
||||
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];
|
||||
if (it->rendertype == GLDIT_WALL)
|
||||
{
|
||||
float d = walls[it->index].ViewDistance;
|
||||
float d = walls[it->index]->ViewDistance;
|
||||
if (d > farthest) farthest = d;
|
||||
if (d < nearest) nearest = d;
|
||||
}
|
||||
|
@ -258,7 +266,7 @@ SortNode * GLDrawList::FindSortWall(SortNode * head)
|
|||
GLDrawItem * it = &drawitems[node->itemindex];
|
||||
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)
|
||||
{
|
||||
best = node;
|
||||
|
@ -294,10 +302,10 @@ 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];
|
||||
GLWall * ws=&walls[drawitems[sort->itemindex].index];
|
||||
GLFlat * fh = &flats[drawitems[head->itemindex].index];
|
||||
GLWall * ws = walls[drawitems[sort->itemindex].index];
|
||||
|
||||
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!
|
||||
|
||||
// WARNING: NEVER EVER push a member of an array onto the array itself.
|
||||
// Bad things will happen if the memory must be reallocated!
|
||||
GLWall w = *ws;
|
||||
AddWall(&w);
|
||||
|
||||
GLWall *w = NewWall();
|
||||
*w = *ws;
|
||||
|
||||
// Splitting is done in the shader with clip planes, if available
|
||||
if (gl.flags & RFL_NO_CLIP_PLANES)
|
||||
{
|
||||
GLWall * ws1;
|
||||
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]);
|
||||
|
||||
// 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.
|
||||
if (!ceiling)
|
||||
{
|
||||
ws->ztop[1] = ws1->zbottom[1] = ws->ztop[0] = ws1->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->ztop[1] = w->zbottom[1] = ws->ztop[0] = w->zbottom[0] = fh->z;
|
||||
ws->tcs[GLWall::UPRGT].v = w->tcs[GLWall::LORGT].v = ws->tcs[GLWall::UPLFT].v = w->tcs[GLWall::LOLFT].v = newtexv;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws1->ztop[1] = ws->zbottom[1] = ws1->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->ztop[1] = ws->zbottom[1] = w->ztop[0] = ws->zbottom[0] = fh->z;
|
||||
w->tcs[GLWall::UPLFT].v = ws->tcs[GLWall::LOLFT].v = w->tcs[GLWall::UPRGT].v = ws->tcs[GLWall::LORGT].v = newtexv;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,7 +344,7 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort)
|
|||
head->AddToLeft(sort);
|
||||
head->AddToRight(sort2);
|
||||
}
|
||||
else if ((ws->zbottom[0]<fh->z && !ceiling) || (ws->ztop[0]>fh->z && ceiling)) // completely on the left side
|
||||
else if ((ws->zbottom[0] < fh->z && !ceiling) || (ws->ztop[0] > fh->z && ceiling)) // completely on the left side
|
||||
{
|
||||
head->AddToLeft(sort);
|
||||
}
|
||||
|
@ -421,9 +424,8 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort)
|
|||
|
||||
void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
|
||||
{
|
||||
GLWall * wh=&walls[drawitems[head->itemindex].index];
|
||||
GLWall * ws=&walls[drawitems[sort->itemindex].index];
|
||||
GLWall * ws1;
|
||||
GLWall * wh= walls[drawitems[head->itemindex].index];
|
||||
GLWall * ws= walls[drawitems[sort->itemindex].index];
|
||||
float v1=wh->PointOnSide(ws->glseg.x1,ws->glseg.y1);
|
||||
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]));
|
||||
|
||||
ws->vertcount = 0; // invalidate current vertices.
|
||||
GLWall w=*ws;
|
||||
AddWall(&w);
|
||||
ws1=&walls[walls.Size()-1];
|
||||
ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated!
|
||||
GLWall *w= NewWall();
|
||||
|
||||
ws1->glseg.x1=ws->glseg.x2=ix;
|
||||
ws1->glseg.y1=ws->glseg.y2=iy;
|
||||
ws1->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft);
|
||||
ws1->ztop[0]=ws->ztop[1]=izt;
|
||||
ws1->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->glseg.x1=ws->glseg.x2=ix;
|
||||
w->glseg.y1=ws->glseg.y2=iy;
|
||||
w->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft);
|
||||
w->ztop[0]=ws->ztop[1]=izt;
|
||||
w->zbottom[0]=ws->zbottom[1]=izb;
|
||||
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)
|
||||
{
|
||||
ws->MakeVertices(false);
|
||||
ws1->MakeVertices(false);
|
||||
w->MakeVertices(false);
|
||||
}
|
||||
|
||||
SortNode * sort2=SortNodes.GetNew();
|
||||
|
@ -507,7 +506,7 @@ EXTERN_CVAR(Bool, gl_billboard_particles)
|
|||
|
||||
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 * ss1;
|
||||
|
||||
|
@ -731,7 +730,7 @@ void GLDrawList::DoDraw(int pass, int i, bool trans)
|
|||
|
||||
case GLDIT_WALL:
|
||||
{
|
||||
GLWall * w=&walls[drawitems[i].index];
|
||||
GLWall * w= walls[drawitems[i].index];
|
||||
RenderWall.Clock();
|
||||
w->Draw(pass);
|
||||
RenderWall.Unclock();
|
||||
|
@ -863,7 +862,7 @@ void GLDrawList::DrawWalls(int pass)
|
|||
RenderWall.Clock();
|
||||
for(unsigned i=0;i<drawitems.Size();i++)
|
||||
{
|
||||
walls[drawitems[i].index].Draw(pass);
|
||||
walls[drawitems[i].index]->Draw(pass);
|
||||
}
|
||||
RenderWall.Unclock();
|
||||
}
|
||||
|
@ -892,7 +891,7 @@ void GLDrawList::DrawDecals()
|
|||
{
|
||||
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
|
||||
{
|
||||
GLWall * w1 = &walls[a.index];
|
||||
GLWall * w2 = &walls[b.index];
|
||||
GLWall * w1 = walls[a.index];
|
||||
GLWall * w2 = walls[b.index];
|
||||
|
||||
if (w1->gltexture != w2->gltexture) return w1->gltexture < w2->gltexture;
|
||||
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;
|
||||
di_list.Release(di);
|
||||
if (gl_drawinfo == nullptr)
|
||||
ResetAllocator();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ struct SortNode
|
|||
struct GLDrawList
|
||||
{
|
||||
//private:
|
||||
TArray<GLWall> walls;
|
||||
TArray<GLWall*> walls;
|
||||
TArray<GLFlat> flats;
|
||||
TArray<GLSprite> sprites;
|
||||
TArray<GLDrawItem> drawitems;
|
||||
|
@ -131,7 +131,8 @@ public:
|
|||
return drawitems.Size();
|
||||
}
|
||||
|
||||
void AddWall(GLWall * wall);
|
||||
GLWall *NewWall();
|
||||
//void AddWall(GLWall * wall);
|
||||
void AddFlat(GLFlat * flat);
|
||||
void AddSprite(GLSprite * sprite);
|
||||
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();
|
||||
if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(true);
|
||||
drawlists[GLDL_TRANSLUCENT].AddWall(wall);
|
||||
auto newwall = drawlists[GLDL_TRANSLUCENT].NewWall();
|
||||
*newwall = *wall;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -77,8 +78,8 @@ void FDrawInfo::AddWall(GLWall *wall)
|
|||
list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS;
|
||||
}
|
||||
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
|
||||
type=RENDERWALL_MIRRORSURFACE;
|
||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].AddWall(this);
|
||||
auto newwall = gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].NewWall();
|
||||
*newwall = *this;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -560,6 +560,10 @@ public:
|
|||
{
|
||||
return Array[index];
|
||||
}
|
||||
T &At(size_t index) const
|
||||
{
|
||||
return Array[index];
|
||||
}
|
||||
unsigned int Size() const
|
||||
{
|
||||
return Count;
|
||||
|
|
Loading…
Reference in a new issue