- cache the results of hw_FakeFlat for the remainder of the current scene instead of storing this in local variables.

An exception is made for the sprite drawer which needs to call this in the worker thread on some occasions for as-yet unprocessed sectors.
This case may not alter the cache to avoid having to add thread synchronization to it.

The main reason for this change is that pointers to such manipulated sectors can now be considered static in the renderer.
Due to them being short lived local buffers it was not possible to carry them along with the render data for information retrieval.

# Conflicts:
#	src/gl/renderer/gl_renderer.cpp
#	src/hwrenderer/scene/hw_bsp.cpp
#	src/hwrenderer/scene/hw_drawinfo.h
#	src/hwrenderer/scene/hw_drawlist.cpp
#	src/hwrenderer/scene/hw_fakeflat.cpp
#	src/hwrenderer/scene/hw_renderhacks.cpp

# Conflicts:
#	src/gl/renderer/gl_renderer.cpp
#	src/gl/renderer/gl_renderer.h
#	src/gl/scene/gl_bsp.cpp
#	src/gl/scene/gl_drawinfo.cpp
#	src/gl/scene/gl_fakeflat.cpp
#	src/gl/scene/gl_renderhacks.cpp
#	src/gl/scene/gl_scene.cpp
#	src/hwrenderer/scene/hw_drawinfo.h
#	src/hwrenderer/scene/hw_drawlist.cpp
#	src/hwrenderer/scene/hw_fakeflat.h
#	src/hwrenderer/scene/hw_sprites.cpp
#	src/hwrenderer/scene/hw_weapon.cpp
This commit is contained in:
Christoph Oelckers 2018-11-10 20:06:10 +01:00 committed by drfrag666
parent 7f5bf11f12
commit 103f3f4cf9
8 changed files with 69 additions and 36 deletions

View file

@ -217,7 +217,8 @@ enum area_t
// Global functions. Make them members of GLRenderer later?
bool gl_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsector);
sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back);
void gl_ClearFakeFlat();
sector_t * gl_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *localcopy = nullptr);
struct TexFilter_s
{

View file

@ -87,7 +87,6 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
#endif
sector_t * backsector = NULL;
sector_t bs;
if (portalclip)
{
@ -149,7 +148,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
// clipping checks are only needed when the backsector is not the same as the front sector
if (in_area == area_default) in_area = CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector);
backsector = gl_FakeFlat(seg->backsector, &bs, in_area, true);
backsector = gl_FakeFlat(seg->backsector, in_area, true);
if (gl_CheckClip(seg->sidedef, currentsector, backsector))
{
@ -410,7 +409,6 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
unsigned int i;
sector_t * sector;
sector_t * fakesector;
sector_t fake;
#ifdef _DEBUG
if (sub->sector->sectornum==931)
@ -435,7 +433,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
}
if (clipper.IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet.
fakesector=gl_FakeFlat(sector, &fake, in_area, false);
fakesector=gl_FakeFlat(sector, in_area, false);
if (GLRenderer->mClipPortal)
{
@ -502,7 +500,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
sector = sub->render_sector;
// the planes of this subsector are faked to belong to another sector
// This means we need the heightsec parts and light info of the render sector, not the actual one.
fakesector = gl_FakeFlat(sector, &fake, in_area, false);
fakesector = gl_FakeFlat(sector, in_area, false);
}
uint8_t &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum];

View file

@ -42,6 +42,7 @@
#include "gl/scene/gl_scenedrawer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
@ -1212,9 +1213,8 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
void FDrawInfo::FloodUpperGap(seg_t * seg)
{
wallseg ws;
sector_t ffake, bfake;
sector_t * fakefsector = gl_FakeFlat(seg->frontsector, &ffake, mDrawer->in_area, true);
sector_t * fakebsector = gl_FakeFlat(seg->backsector, &bfake, mDrawer->in_area, false);
sector_t * fakefsector = gl_FakeFlat(seg->frontsector, mDrawer->in_area, false);
sector_t * fakebsector = gl_FakeFlat(seg->backsector, mDrawer->in_area, true);
vertex_t * v1, * v2;
@ -1264,9 +1264,8 @@ void FDrawInfo::FloodUpperGap(seg_t * seg)
void FDrawInfo::FloodLowerGap(seg_t * seg)
{
wallseg ws;
sector_t ffake, bfake;
sector_t * fakefsector = gl_FakeFlat(seg->frontsector, &ffake, mDrawer->in_area, true);
sector_t * fakebsector = gl_FakeFlat(seg->backsector, &bfake, mDrawer->in_area, false);
sector_t * fakefsector = gl_FakeFlat(seg->frontsector, mDrawer->in_area, false);
sector_t * fakebsector = gl_FakeFlat(seg->backsector, mDrawer->in_area, true);
vertex_t * v1, * v2;

View file

@ -34,6 +34,7 @@
#include "gl/scene/gl_scenedrawer.h"
#include "gl/data/gl_data.h"
static sector_t **fakesectorbuffer;
//==========================================================================
//
@ -181,6 +182,24 @@ area_t GLSceneDrawer::CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *fronts
return area_default;
}
//==========================================================================
//
//
//
//==========================================================================
static FMemArena FakeSectorAllocator(20 * sizeof(sector_t));
static sector_t *allocateSector(sector_t *sec)
{
if (fakesectorbuffer == nullptr)
{
fakesectorbuffer = (sector_t**)FakeSectorAllocator.Alloc(level.sectors.Size() * sizeof(sector_t*));
memset(fakesectorbuffer, 0, level.sectors.Size() * sizeof(sector_t*));
}
auto sectornum = sec->sectornum;
fakesectorbuffer[sectornum] = (sector_t*)FakeSectorAllocator.Alloc(sizeof(sector_t));
return fakesectorbuffer[sectornum];
}
//==========================================================================
//
@ -188,7 +207,8 @@ area_t GLSceneDrawer::CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *fronts
// by hardware rendering
//
//==========================================================================
sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back)
sector_t * gl_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *localcopy)
{
if (!sec->GetHeightSec() || sec->heightsec==sec)
{
@ -196,6 +216,8 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
// visual glitches because upper amd lower textures overlap.
if (back && (sec->MoreFlags & SECMF_OVERLAPPING))
{
if (fakesectorbuffer && fakesectorbuffer[sec->sectornum]) return fakesectorbuffer[sec->sectornum];
auto dest = localcopy? localcopy : allocateSector(sec);
*dest = *sec;
dest->ceilingplane = sec->floorplane;
dest->ceilingplane.FlipVert();
@ -214,6 +236,11 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
}
#endif
if (fakesectorbuffer && fakesectorbuffer[sec->sectornum])
{
return fakesectorbuffer[sec->sectornum];
}
if (in_area==area_above)
{
if (sec->heightsec->MoreFlags&SECMF_FAKEFLOORONLY /*|| sec->GetTexture(sector_t::ceiling)==skyflatnum*/) in_area=area_normal;
@ -222,11 +249,8 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
int diffTex = (sec->heightsec->MoreFlags & SECMF_CLIPFAKEPLANES);
sector_t * s = sec->heightsec;
#if 0
*dest=*sec; // This will invoke the copy operator which isn't really needed here. Memcpy is faster.
#else
memcpy(dest, sec, sizeof(sector_t));
#endif
auto dest = localcopy ? localcopy : allocateSector(sec);
*dest = *sec;
// Replace floor and ceiling height with control sector's heights.
if (diffTex)
@ -308,7 +332,7 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
dest->lightlevel = s->lightlevel;
}
if (!back)
//if (!back)
{
dest->SetTexture(sector_t::floor, diffTex ? sec->GetTexture(sector_t::floor) : s->GetTexture(sector_t::floor), false);
dest->planes[sector_t::floor].xform = s->planes[sector_t::floor].xform;
@ -361,7 +385,7 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
dest->lightlevel = s->lightlevel;
}
if (!back)
//if (!back)
{
dest->SetTexture(sector_t::ceiling, diffTex ? sec->GetTexture(sector_t::ceiling) : s->GetTexture(sector_t::ceiling), false);
dest->SetTexture(sector_t::floor, s->GetTexture(sector_t::ceiling), false);
@ -387,3 +411,9 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
}
void gl_ClearFakeFlat()
{
FakeSectorAllocator.FreeAll();
fakesectorbuffer = nullptr;
}

View file

@ -51,7 +51,6 @@ static int totalupper, totallower;
static int lowershcount, uppershcount;
static glcycle_t totalms, showtotalms;
static glcycle_t totalssms;
static sector_t fakesec;
void FDrawInfo::ClearBuffers()
{
@ -281,7 +280,7 @@ bool FDrawInfo::DoOneSectorUpper(subsector_t * subsec, float Planez)
// Note: if this is a real line between sectors
// we can be sure that render_sector is the real sector!
sector_t * sec = gl_FakeFlat(seg->backsector, &fakesec, mDrawer->in_area, true);
sector_t * sec = gl_FakeFlat(seg->backsector, mDrawer->in_area, true);
// Don't bother with slopes
if (sec->ceilingplane.isSlope()) return false;
@ -339,7 +338,7 @@ bool FDrawInfo::DoOneSectorLower(subsector_t * subsec, float Planez)
// Note: if this is a real line between sectors
// we can be sure that render_sector is the real sector!
sector_t * sec = gl_FakeFlat(seg->backsector, &fakesec, mDrawer->in_area, true);
sector_t * sec = gl_FakeFlat(seg->backsector, mDrawer->in_area, true);
// Don't bother with slopes
if (sec->floorplane.isSlope()) return false;
@ -398,7 +397,7 @@ bool FDrawInfo::DoFakeBridge(subsector_t * subsec, float Planez)
// Note: if this is a real line between sectors
// we can be sure that render_sector is the real sector!
sector_t * sec = gl_FakeFlat(seg->backsector, &fakesec, mDrawer->in_area, true);
sector_t * sec = gl_FakeFlat(seg->backsector, mDrawer->in_area, true);
// Don't bother with slopes
if (sec->floorplane.isSlope()) return false;
@ -451,7 +450,7 @@ bool FDrawInfo::DoFakeCeilingBridge(subsector_t * subsec, float Planez)
// Note: if this is a real line between sectors
// we can be sure that render_sector is the real sector!
sector_t * sec = gl_FakeFlat(seg->backsector, &fakesec, mDrawer->in_area, true);
sector_t * sec = gl_FakeFlat(seg->backsector, mDrawer->in_area, true);
// Don't bother with slopes
if (sec->ceilingplane.isSlope()) return false;
@ -483,7 +482,6 @@ bool FDrawInfo::DoFakeCeilingBridge(subsector_t * subsec, float Planez)
//==========================================================================
void FDrawInfo::HandleMissingTextures()
{
sector_t fake;
totalms.Clock();
totalupper = MissingUpperTextures.Size();
totallower = MissingLowerTextures.Size();
@ -540,7 +538,7 @@ void FDrawInfo::HandleMissingTextures()
{
// It isn't a hole. Now check whether it might be a fake bridge
sector_t * fakesector = gl_FakeFlat(MissingUpperTextures[i].seg->frontsector, &fake, mDrawer->in_area, false);
sector_t * fakesector = gl_FakeFlat(MissingUpperTextures[i].seg->frontsector, mDrawer->in_area, false);
float planez = (float)fakesector->GetPlaneTexZ(sector_t::ceiling);
backsub->validcount = validcount;
@ -611,7 +609,7 @@ void FDrawInfo::HandleMissingTextures()
{
// It isn't a hole. Now check whether it might be a fake bridge
sector_t * fakesector = gl_FakeFlat(MissingLowerTextures[i].seg->frontsector, &fake, mDrawer->in_area, false);
sector_t * fakesector = gl_FakeFlat(MissingLowerTextures[i].seg->frontsector, mDrawer->in_area, false);
float planez = (float)fakesector->GetPlaneTexZ(sector_t::floor);
backsub->validcount = validcount;
@ -1043,7 +1041,7 @@ void FDrawInfo::CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor)
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
// Must be the exact same visplane
sector_t * me = gl_FakeFlat(sub->render_sector, &fakesec, mDrawer->in_area, false);
sector_t * me = gl_FakeFlat(sub->render_sector, mDrawer->in_area, false);
if (me->GetTexture(sector_t::ceiling) != anchor->GetTexture(sector_t::ceiling) ||
me->ceilingplane != anchor->ceilingplane ||
me->GetCeilingLight() != anchor->GetCeilingLight() ||
@ -1087,7 +1085,7 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor)
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
// Must be the exact same visplane
sector_t * me = gl_FakeFlat(sub->render_sector, &fakesec, mDrawer->in_area, false);
sector_t * me = gl_FakeFlat(sub->render_sector, mDrawer->in_area, false);
if (me->GetTexture(sector_t::floor) != anchor->GetTexture(sector_t::floor) ||
me->floorplane != anchor->floorplane ||
me->GetFloorLight() != anchor->GetFloorLight() ||
@ -1127,7 +1125,7 @@ void FDrawInfo::ProcessSectorStacks()
validcount++;
for (i=0;i<CeilingStacks.Size (); i++)
{
sector_t *sec = gl_FakeFlat(CeilingStacks[i], &fake, mDrawer->in_area, false);
sector_t *sec = gl_FakeFlat(CeilingStacks[i], mDrawer->in_area, false);
FPortal *portal = sec->GetGLPortal(sector_t::ceiling);
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
{
@ -1171,7 +1169,7 @@ void FDrawInfo::ProcessSectorStacks()
validcount++;
for (i=0;i<FloorStacks.Size (); i++)
{
sector_t *sec = gl_FakeFlat(FloorStacks[i], &fake, mDrawer->in_area, false);
sector_t *sec = gl_FakeFlat(FloorStacks[i], mDrawer->in_area, false);
FPortal *portal = sec->GetGLPortal(sector_t::floor);
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
{

View file

@ -62,6 +62,7 @@
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/shaders/gl_shader.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/stereo3d/scoped_view_shifter.h"
@ -905,6 +906,8 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
void FGLRenderer::RenderView (player_t* player)
{
gl_ClearFakeFlat();
checkBenchActive();
gl_RenderState.SetVertexBuffer(mVBO);
@ -964,6 +967,7 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
{
GL_IRECT bounds;
gl_ClearFakeFlat();
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
bounds.left=0;
bounds.top=0;
@ -1125,6 +1129,7 @@ extern TexFilter_s TexFilter[];
void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
// This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene.
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
int width = gltex->TextureWidth();

View file

@ -785,7 +785,9 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
if (sector->sectornum != thing->Sector->sectornum && !thruportal)
{
rendersector = gl_FakeFlat(thing->Sector, &rs, mDrawer->in_area, false);
// This cannot create a copy in the fake sector cache because it'd interfere with the main thread, so provide a local buffer for the copy.
// Adding synchronization for this one case would cost more than it might save if the result here could be cached.
rendersector = gl_FakeFlat(thing->Sector, mDrawer->in_area, false, &rs);
}
else
{
@ -1325,7 +1327,7 @@ void GLSceneDrawer::RenderActorsInPortal(FGLLinePortal *glport)
th->Prev += newpos - savedpos;
GLSprite spr(this);
spr.Process(th, gl_FakeFlat(th->Sector, &fakesector, in_area, false), 2);
spr.Process(th, gl_FakeFlat(th->Sector, in_area, false, &fakesector), 2);
th->Angles.Yaw = savedangle;
th->SetXYZ(savedpos);
th->Prev -= newpos - savedpos;

View file

@ -228,7 +228,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
unsigned int i;
int lightlevel=0;
FColormap cm;
sector_t * fakesec, fs;
sector_t * fakesec;
AActor * playermo=players[consoleplayer].camera;
player_t * player=playermo->player;
@ -277,7 +277,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
}
else
{
fakesec = gl_FakeFlat(viewsector, &fs, in_area, false);
fakesec = gl_FakeFlat(viewsector, in_area, false);
// calculate light level for weapon sprites
lightlevel = gl_ClampLight(fakesec->lightlevel);