mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-16 17:21:10 +00:00
Move the visible surface list to HWDrawInfo
This commit is contained in:
parent
39312e898f
commit
a6ff0a65d0
9 changed files with 58 additions and 75 deletions
|
@ -53,8 +53,8 @@ struct LevelMeshSurface
|
|||
int texWidth = 0;
|
||||
int texHeight = 0;
|
||||
|
||||
// True if the surface needs to be rendered into the lightmap texture before it can be used
|
||||
bool needsUpdate = true;
|
||||
bool alreadyInVisibleList = false;
|
||||
|
||||
//
|
||||
// Required for internal lightmapper:
|
||||
|
|
|
@ -262,17 +262,12 @@ protected:
|
|||
|
||||
EPassType mPassType = NORMAL_PASS;
|
||||
|
||||
std::atomic<unsigned> mActiveLightmapSurfaceBufferIndex;
|
||||
TArray<LevelMeshSurface*> mActiveLightmapSurfacesBuffer;
|
||||
public:
|
||||
|
||||
uint64_t firstFrame = 0;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mActiveLightmapSurfaceBufferIndex = { 0 };
|
||||
mActiveLightmapSurfacesBuffer.Resize(lm_max_updates);
|
||||
|
||||
mTextureEnabled = true;
|
||||
mBrightmapEnabled = mGradientEnabled = mFogEnabled = mGlowEnabled = false;
|
||||
mFogColor = 0xffffffff;
|
||||
|
@ -739,35 +734,6 @@ public:
|
|||
return SetViewpoint(matrices);
|
||||
}
|
||||
|
||||
inline void PushVisibleSurface(LevelMeshSurface* surface)
|
||||
{
|
||||
if (surface->needsUpdate && !surface->portalIndex && !surface->bSky) // TODO atomic?
|
||||
{
|
||||
auto index = mActiveLightmapSurfaceBufferIndex.fetch_add(1);
|
||||
if (index < mActiveLightmapSurfacesBuffer.Size())
|
||||
{
|
||||
mActiveLightmapSurfacesBuffer[index] = surface;
|
||||
surface->needsUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline auto& GetVisibleSurfaceList()
|
||||
{
|
||||
return mActiveLightmapSurfacesBuffer;
|
||||
}
|
||||
|
||||
inline unsigned GetVisibleSurfaceListCount() const
|
||||
{
|
||||
return mActiveLightmapSurfaceBufferIndex;
|
||||
}
|
||||
|
||||
inline void ClearVisibleSurfaceList()
|
||||
{
|
||||
mActiveLightmapSurfacesBuffer.Resize(lm_max_updates);
|
||||
mActiveLightmapSurfaceBufferIndex = 0;
|
||||
}
|
||||
|
||||
// API-dependent render interface
|
||||
|
||||
// Worker threads
|
||||
|
|
|
@ -100,8 +100,8 @@ void VkLightmap::SelectSurfaces(const TArray<LevelMeshSurface*>& surfaces)
|
|||
{
|
||||
LevelMeshSurface* surface = surfaces[i];
|
||||
|
||||
// All surfaces needs to be updated until we rendered them.
|
||||
surface->needsUpdate = true;
|
||||
if (!surface->needsUpdate)
|
||||
continue;
|
||||
|
||||
// Only grab surfaces until our bake texture is full
|
||||
auto result = packer.insert(surface->texWidth + 2, surface->texHeight + 2);
|
||||
|
@ -115,6 +115,8 @@ void VkLightmap::SelectSurfaces(const TArray<LevelMeshSurface*>& surfaces)
|
|||
|
||||
bakeImage.maxX = std::max<uint16_t>(bakeImage.maxX, uint16_t(selected.X + surface->texWidth + spacing));
|
||||
bakeImage.maxY = std::max<uint16_t>(bakeImage.maxY, uint16_t(selected.Y + surface->texHeight + spacing));
|
||||
|
||||
surface->needsUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -227,7 +229,14 @@ void VkLightmap::RenderBakeImage()
|
|||
}
|
||||
|
||||
if (buffersFull)
|
||||
{
|
||||
while (i < count)
|
||||
{
|
||||
selectedSurfaces[i].Surface->needsUpdate = true;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
selectedSurface.Rendered = true;
|
||||
}
|
||||
|
@ -423,9 +432,6 @@ void VkLightmap::CopyBakeImageResult()
|
|||
regions.push_back(region);
|
||||
seenPages.insert(surface->atlasPageIndex);
|
||||
|
||||
// We rendered this surface. Does not need an update anymore.
|
||||
surface->needsUpdate = false;
|
||||
|
||||
pixels += surface->Area();
|
||||
lastSurfaceCount++;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ ADD_STAT(lightmap)
|
|||
auto stats = levelMesh->GatherSurfacePixelStats();
|
||||
|
||||
out.Format("Surfaces: %u (sky: %u, awaiting updates: %u)\nSurface pixel area to update: %u\nSurface pixel area: %u\nAtlas pixel area: %u\nAtlas efficiency: %.4f%%",
|
||||
stats.surfaces.total, stats.surfaces.sky, stats.surfaces.dirty,
|
||||
stats.surfaces.total, stats.surfaces.sky, std::max(stats.surfaces.dirty - stats.surfaces.sky, (uint32_t)0),
|
||||
stats.pixels.dirty,
|
||||
stats.pixels.total,
|
||||
atlasPixelCount,
|
||||
|
|
|
@ -52,7 +52,6 @@ CVAR(Bool, gl_multithread, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|||
|
||||
EXTERN_CVAR(Float, r_actorspriteshadowdist)
|
||||
EXTERN_CVAR(Bool, gl_meshcache)
|
||||
EXTERN_CVAR(Int, lm_background_updates);
|
||||
|
||||
thread_local bool isWorkerThread;
|
||||
ctpl::thread_pool renderPool(1);
|
||||
|
@ -857,35 +856,8 @@ void HWDrawInfo::RenderBSPNode (void *node, FRenderState& state)
|
|||
DoSubsector ((subsector_t *)((uint8_t *)node - 1), state);
|
||||
}
|
||||
|
||||
void UpdateLightmaps(DFrameBuffer* screen, FRenderState& RenderState)
|
||||
{
|
||||
// Lightmapping stuff
|
||||
auto& list = RenderState.GetVisibleSurfaceList();
|
||||
auto size = RenderState.GetVisibleSurfaceListCount();
|
||||
|
||||
list.Resize(min(list.Size(), unsigned(size)));
|
||||
|
||||
if (size < unsigned(lm_background_updates))
|
||||
{
|
||||
for (auto& e : level.levelMesh->Surfaces)
|
||||
{
|
||||
if (e.needsUpdate && !e.bSky && !e.portalIndex)
|
||||
{
|
||||
list.Push(&e);
|
||||
|
||||
if (list.Size() >= unsigned(lm_background_updates))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
screen->UpdateLightmaps(list);
|
||||
}
|
||||
|
||||
void HWDrawInfo::RenderBSP(void *node, bool drawpsprites, FRenderState& state)
|
||||
{
|
||||
state.ClearVisibleSurfaceList();
|
||||
|
||||
Bsp.Clock();
|
||||
|
||||
// Give the DrawInfo the viewpoint in fixed point because that's what the nodes are.
|
||||
|
@ -920,6 +892,4 @@ void HWDrawInfo::RenderBSP(void *node, bool drawpsprites, FRenderState& state)
|
|||
|
||||
if (drawpsprites)
|
||||
PreparePlayerSprites(Viewpoint.sector, in_area, state);
|
||||
|
||||
UpdateLightmaps(screen, state);
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include "g_levellocals.h"
|
||||
|
||||
EXTERN_CVAR(Float, r_visibility)
|
||||
EXTERN_CVAR(Int, lm_background_updates);
|
||||
|
||||
CVAR(Bool, gl_bandedswlight, false, CVAR_ARCHIVE)
|
||||
CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, gl_no_skyclear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
@ -122,6 +124,7 @@ void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uni
|
|||
for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset();
|
||||
hudsprites.Clear();
|
||||
Coronas.Clear();
|
||||
VisibleSurfaces.Clear();
|
||||
vpIndex = 0;
|
||||
|
||||
// Fullbright information needs to be propagated from the main view.
|
||||
|
@ -410,6 +413,25 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
|
|||
|
||||
}
|
||||
|
||||
void HWDrawInfo::UpdateLightmaps()
|
||||
{
|
||||
if (VisibleSurfaces.Size() < unsigned(lm_background_updates))
|
||||
{
|
||||
for (auto& e : level.levelMesh->Surfaces)
|
||||
{
|
||||
if (e.needsUpdate && !e.bSky && !e.portalIndex)
|
||||
{
|
||||
VisibleSurfaces.Push(&e);
|
||||
|
||||
if (VisibleSurfaces.Size() >= unsigned(lm_background_updates))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
screen->UpdateLightmaps(VisibleSurfaces);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// RenderScene
|
||||
|
@ -423,6 +445,8 @@ void HWDrawInfo::RenderScene(FRenderState &state)
|
|||
const auto &vp = Viewpoint;
|
||||
RenderAll.Clock();
|
||||
|
||||
UpdateLightmaps();
|
||||
|
||||
state.SetLightMode((int)lightmode);
|
||||
|
||||
state.SetDepthMask(true);
|
||||
|
|
|
@ -148,6 +148,7 @@ struct HWDrawInfo
|
|||
TArray<HWDecal *> Decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
|
||||
TArray<HUDSprite> hudsprites; // These may just be stored by value.
|
||||
TArray<ACorona*> Coronas;
|
||||
TArray<LevelMeshSurface*> VisibleSurfaces;
|
||||
uint64_t LastFrameTime = 0;
|
||||
|
||||
TArray<MissingTextureInfo> MissingUpperTextures;
|
||||
|
@ -198,6 +199,20 @@ struct HWDrawInfo
|
|||
VPUniforms.mClipHeight = 0;
|
||||
}
|
||||
|
||||
void PushVisibleSurface(LevelMeshSurface* surface)
|
||||
{
|
||||
if (outer)
|
||||
{
|
||||
outer->PushVisibleSurface(surface);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!surface->portalIndex && !surface->bSky)
|
||||
{
|
||||
VisibleSurfaces.Push(surface);
|
||||
}
|
||||
}
|
||||
|
||||
HWPortal * FindPortal(const void * src);
|
||||
void RenderBSPNode(void *node, FRenderState& state);
|
||||
void RenderBSP(void *node, bool drawpsprites, FRenderState& state);
|
||||
|
@ -335,6 +350,8 @@ private:
|
|||
void AddPolyobjs(subsector_t* sub, FRenderState& state);
|
||||
void AddLines(subsector_t* sub, sector_t* sector, FRenderState& state);
|
||||
void AddSpecialPortalLines(subsector_t* sub, sector_t* sector, linebase_t* line, FRenderState& state);
|
||||
|
||||
void UpdateLightmaps();
|
||||
};
|
||||
|
||||
void CleanSWDrawer();
|
||||
|
|
|
@ -512,7 +512,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
|
|||
{
|
||||
if (auto lightmap = sector->subsectors[i]->lightmap[plane][0])
|
||||
{
|
||||
state.PushVisibleSurface(lightmap);
|
||||
di->PushVisibleSurface(lightmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -523,7 +523,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
|
|||
{
|
||||
if (surface)
|
||||
{
|
||||
state.PushVisibleSurface(surface);
|
||||
di->PushVisibleSurface(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -538,7 +538,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
|
|||
{
|
||||
if (surface)
|
||||
{
|
||||
state.PushVisibleSurface(surface);
|
||||
di->PushVisibleSurface(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1267,7 +1267,7 @@ void HWWall::DoTexture(HWDrawInfo *di, FRenderState& state, int _type,seg_t * se
|
|||
lightmap = seg->sidedef->lightmap[type - RENDERWALL_TOP];
|
||||
if (lightmap)
|
||||
{
|
||||
state.PushVisibleSurface(lightmap);
|
||||
di->PushVisibleSurface(lightmap);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue