- added a non-multithreaded option for the renderer and fixed a few places where the wrong sector was used

The render_sector is only relevant for flats, but never for walls or sprites!
This commit is contained in:
Christoph Oelckers 2018-10-31 16:53:00 +01:00
parent 91df3f8c73
commit 2dec7bb1e5
2 changed files with 104 additions and 38 deletions

View file

@ -41,6 +41,7 @@
#include "hwrenderer/utility/hw_clock.h" #include "hwrenderer/utility/hw_clock.h"
#include "hwrenderer/data/flatvertices.h" #include "hwrenderer/data/flatvertices.h"
CVAR(Bool, gl_multithread, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
thread_local bool isWorkerThread; thread_local bool isWorkerThread;
ctpl::thread_pool renderPool(1); ctpl::thread_pool renderPool(1);
@ -127,8 +128,22 @@ void HWDrawInfo::WorkerThread()
GLWall wall; GLWall wall;
SetupWall.Clock(); SetupWall.Clock();
wall.sub = job->sub; wall.sub = job->sub;
front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false);
back = job->seg->PartnerSeg ? hw_FakeFlat(job->seg->PartnerSeg->Subsector->render_sector, &fakeback, in_area, true) : nullptr; front = hw_FakeFlat(job->sub->sector, &fakefront, in_area, false);
auto seg = job->seg;
if (seg->backsector)
{
if (front->sectornum == seg->backsector->sectornum || (seg->sidedef->Flags & WALLF_POLYOBJ))
{
back = front;
}
else
{
back = hw_FakeFlat(seg->backsector, &fakeback, in_area, true);
}
}
else back = nullptr;
wall.Process(this, job->seg, front, back); wall.Process(this, job->seg, front, back);
rendered_lines++; rendered_lines++;
SetupWall.Unclock(); SetupWall.Unclock();
@ -147,32 +162,20 @@ void HWDrawInfo::WorkerThread()
case RenderJob::SpriteJob: case RenderJob::SpriteJob:
SetupSprite.Clock(); SetupSprite.Clock();
front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false); front = hw_FakeFlat(job->sub->sector, &fakefront, in_area, false);
RenderThings(job->sub, front); RenderThings(job->sub, front);
SetupSprite.Unclock(); SetupSprite.Unclock();
break; break;
case RenderJob::ParticleJob: case RenderJob::ParticleJob:
{
SetupSprite.Clock(); SetupSprite.Clock();
front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false); front = hw_FakeFlat(job->sub->sector, &fakefront, in_area, false);
for (int i = ParticlesInSubsec[job->sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext) RenderParticles(job->sub, front);
{
if (mClipPortal)
{
int clipres = mClipPortal->ClipPoint(Particles[i].Pos);
if (clipres == PClip_InFront) continue;
}
GLSprite sprite;
sprite.ProcessParticle(this, &Particles[i], front);
}
SetupSprite.Unclock(); SetupSprite.Unclock();
break; break;
} }
} }
} }
}
@ -307,9 +310,21 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
if (!ispoly) seg->linedef->validcount=validcount; if (!ispoly) seg->linedef->validcount=validcount;
if (gl_render_walls) if (gl_render_walls)
{
if (multithread)
{ {
jobQueue.AddJob(RenderJob::WallJob, seg->Subsector, seg); jobQueue.AddJob(RenderJob::WallJob, seg->Subsector, seg);
} }
else
{
GLWall wall;
SetupWall.Clock();
wall.sub = seg->Subsector;
wall.Process(this, seg, currentsector, backsector);
rendered_lines++;
SetupWall.Unclock();
}
}
} }
} }
@ -527,6 +542,23 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
} }
} }
void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front)
{
SetupSprite.Clock();
for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext)
{
if (mClipPortal)
{
int clipres = mClipPortal->ClipPoint(Particles[i].Pos);
if (clipres == PClip_InFront) continue;
}
GLSprite sprite;
sprite.ProcessParticle(this, &Particles[i], front);
}
SetupSprite.Unclock();
}
//========================================================================== //==========================================================================
// //
@ -582,19 +614,23 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
if (sector->validcount != validcount) if (sector->validcount != validcount)
{ {
if (sector->Index() == 62)
{
int a = 0;
}
screen->mVertexData->CheckUpdate(sector); screen->mVertexData->CheckUpdate(sector);
} }
// [RH] Add particles // [RH] Add particles
//int shade = LIGHT2SHADE((floorlightlevel + ceilinglightlevel)/2 + r_actualextralight);
if (gl_render_things && ParticlesInSubsec[sub->Index()] != NO_PARTICLE) if (gl_render_things && ParticlesInSubsec[sub->Index()] != NO_PARTICLE)
{
if (multithread)
{ {
jobQueue.AddJob(RenderJob::ParticleJob, sub, nullptr); jobQueue.AddJob(RenderJob::ParticleJob, sub, nullptr);
} }
else
{
SetupSprite.Clock();
RenderParticles(sub, fakesector);
SetupSprite.Unclock();
}
}
AddLines(sub, fakesector); AddLines(sub, fakesector);
@ -608,10 +644,19 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
sector->validcount = validcount; sector->validcount = validcount;
sector->MoreFlags |= SECMF_DRAWN; sector->MoreFlags |= SECMF_DRAWN;
if (gl_render_things) if (gl_render_things && sector->touching_renderthings)
{
if (multithread)
{ {
jobQueue.AddJob(RenderJob::SpriteJob, sub, nullptr); jobQueue.AddJob(RenderJob::SpriteJob, sub, nullptr);
} }
else
{
SetupSprite.Clock();
RenderThings(sub, fakesector);
SetupSprite.Unclock();
}
}
} }
if (gl_render_flats) if (gl_render_flats)
@ -638,8 +683,18 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
{ {
srf |= SSRF_PROCESSED; srf |= SSRF_PROCESSED;
if (multithread)
{
jobQueue.AddJob(RenderJob::FlatJob, sub); jobQueue.AddJob(RenderJob::FlatJob, sub);
} }
else
{
GLFlat flat;
SetupFlat.Clock();
flat.ProcessSector(this, fakesector);
SetupFlat.Unclock();
}
}
// mark subsector as processed - but mark for rendering only if it has an actual area. // mark subsector as processed - but mark for rendering only if it has an actual area.
ss_renderflags[sub->Index()] = ss_renderflags[sub->Index()] =
(sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED; (sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED;
@ -717,21 +772,29 @@ void HWDrawInfo::RenderBSP(void *node)
validcount++; // used for processing sidedefs only once by the renderer. validcount++; // used for processing sidedefs only once by the renderer.
multithread = gl_multithread;
if (multithread)
{
auto future = renderPool.push([&](int id) { auto future = renderPool.push([&](int id) {
WorkerThread(); WorkerThread();
}); });
RenderBSPNode(node); RenderBSPNode(node);
// Process all the sprites on the current portal's back side which touch the portal.
if (mCurrentPortal != nullptr) mCurrentPortal->RenderAttached(this);
jobQueue.AddJob(RenderJob::TerminateJob, nullptr, nullptr); jobQueue.AddJob(RenderJob::TerminateJob, nullptr, nullptr);
Bsp.Unclock(); Bsp.Unclock();
MTWait.Clock(); MTWait.Clock();
future.wait(); future.wait();
jobQueue.ReleaseAll(); jobQueue.ReleaseAll();
MTWait.Unclock(); MTWait.Unclock();
}
else
{
RenderBSPNode(node);
Bsp.Unclock();
}
// Process all the sprites on the current portal's back side which touch the portal.
if (mCurrentPortal != nullptr) mCurrentPortal->RenderAttached(this);
PreparePlayerSprites(Viewpoint.sector, in_area); PreparePlayerSprites(Viewpoint.sector, in_area);
} }

View file

@ -178,6 +178,7 @@ struct HWDrawInfo
BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections.
area_t in_area; area_t in_area;
fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster. fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster.
bool multithread;
std::function<void(HWDrawInfo *, int)> DrawScene = nullptr; std::function<void(HWDrawInfo *, int)> DrawScene = nullptr;
@ -195,6 +196,7 @@ private:
void WorkerThread(); void WorkerThread();
void UnclipSubsector(subsector_t *sub); void UnclipSubsector(subsector_t *sub);
void AddLine(seg_t *seg, bool portalclip); void AddLine(seg_t *seg, bool portalclip);
void PolySubsector(subsector_t * sub); void PolySubsector(subsector_t * sub);
void RenderPolyBSPNode(void *node); void RenderPolyBSPNode(void *node);
@ -203,6 +205,7 @@ private:
void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line); void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line);
public: public:
void RenderThings(subsector_t * sub, sector_t * sector); void RenderThings(subsector_t * sub, sector_t * sector);
void RenderParticles(subsector_t *sub, sector_t *front);
void DoSubsector(subsector_t * sub); void DoSubsector(subsector_t * sub);
int SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &lightdata, const secplane_t *plane); int SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &lightdata, const secplane_t *plane);
int CreateOtherPlaneVertices(subsector_t *sub, const secplane_t *plane); int CreateOtherPlaneVertices(subsector_t *sub, const secplane_t *plane);