Make LevelMeshUpdater responsible for updating the tiles (playsim tells the mesh updater, the level mesh tells the tiles)
This commit is contained in:
parent
bfb37a89c3
commit
6cf3cdb871
11 changed files with 45 additions and 117 deletions
|
|
@ -58,8 +58,8 @@ void LightmapBuildCmdlet::OnCommand(FArgs args)
|
|||
uint32_t atlasPixelCount = level.levelMesh->AtlasPixelCount();
|
||||
auto stats = level.levelMesh->GatherTilePixelStats();
|
||||
|
||||
Printf("Surfaces: %u (awaiting updates: %u static, %u dynamic)\n", stats.tiles.total, stats.tiles.dirty, stats.tiles.dirtyDynamic);
|
||||
Printf("Surface pixel area to update: %u static, %u dynamic\n", stats.pixels.dirty, stats.pixels.dirtyDynamic);
|
||||
Printf("Surfaces: %u (awaiting updates: %u)\n", stats.tiles.total, stats.tiles.dirty);
|
||||
Printf("Surface pixel area to update: %u\n", stats.pixels.dirty);
|
||||
Printf("Surface pixel area: %u\nAtlas pixel area: %u\n", stats.pixels.total, atlasPixelCount);
|
||||
Printf("Atlas efficiency: %.4f%%\n", float(stats.pixels.total) / float(atlasPixelCount) * 100.0f);
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ void LightmapBuildCmdlet::OnCommand(FArgs args)
|
|||
tiles.Clear();
|
||||
for (auto& e : level.levelMesh->Lightmap.Tiles)
|
||||
{
|
||||
if (e.NeedsUpdate && e.AlwaysUpdate == 0)
|
||||
if (e.NeedsUpdate)
|
||||
{
|
||||
tiles.Push(&e);
|
||||
if (tiles.Size() == 1001)
|
||||
|
|
|
|||
|
|
@ -142,12 +142,6 @@ LevelMeshTileStats LevelMesh::GatherTilePixelStats()
|
|||
stats.tiles.dirty++;
|
||||
stats.pixels.dirty += area;
|
||||
}
|
||||
|
||||
if (tile.AlwaysUpdate)
|
||||
{
|
||||
stats.tiles.dirtyDynamic++;
|
||||
stats.pixels.dirtyDynamic += area;
|
||||
}
|
||||
}
|
||||
stats.tiles.total += Lightmap.Tiles.Size();
|
||||
return stats;
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ struct LevelMeshTileStats
|
|||
{
|
||||
struct Stats
|
||||
{
|
||||
uint32_t total = 0, dirty = 0, dirtyDynamic = 0;
|
||||
uint32_t total = 0, dirty = 0;
|
||||
};
|
||||
|
||||
Stats tiles, pixels;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,6 @@ struct LightmapTileBinding
|
|||
}
|
||||
};
|
||||
|
||||
enum TileUpdatePolicy
|
||||
{
|
||||
MapChanges,
|
||||
AlwaysUltraQuality,
|
||||
Always,
|
||||
MapChangesUltraQuality
|
||||
};
|
||||
|
||||
struct LightmapTile
|
||||
{
|
||||
// Surface location in lightmap texture
|
||||
|
|
@ -68,7 +60,8 @@ struct LightmapTile
|
|||
// True if the tile needs to be rendered into the lightmap texture before it can be used
|
||||
bool NeedsUpdate = true;
|
||||
|
||||
uint8_t AlwaysUpdate = 0;
|
||||
// Used to track if tile has already been added to the VisibleTiles list for this scene
|
||||
int LastSeen = 0;
|
||||
|
||||
FVector2 ToUV(const FVector3& vert) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -94,22 +94,23 @@ void VkLightmapper::Raytrace(const TArray<LightmapTile*>& tiles)
|
|||
lightmapRaytraceLast.active = true;
|
||||
|
||||
lightmapRaytraceLast.ResetAndClock();
|
||||
fb->GetCommands()->PushGroup(fb->GetCommands()->GetTransferCommands(), "lightmap.total");
|
||||
UploadUniforms();
|
||||
|
||||
SelectTiles(tiles);
|
||||
if (selectedTiles.Size() > 0)
|
||||
while (true)
|
||||
{
|
||||
fb->GetCommands()->PushGroup(fb->GetCommands()->GetTransferCommands(), "lightmap.total");
|
||||
SelectTiles(tiles);
|
||||
if (selectedTiles.Size() == 0)
|
||||
break;
|
||||
|
||||
UploadUniforms();
|
||||
Render();
|
||||
Resolve();
|
||||
if (lm_blur)
|
||||
Blur();
|
||||
CopyResult();
|
||||
|
||||
fb->GetCommands()->PopGroup(fb->GetCommands()->GetTransferCommands());
|
||||
}
|
||||
|
||||
fb->GetCommands()->PopGroup(fb->GetCommands()->GetTransferCommands());
|
||||
lightmapRaytraceLast.Unclock();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,21 +74,6 @@ static FCRandom randLight;
|
|||
extern TArray<FLightDefaults *> StateLights;
|
||||
|
||||
|
||||
static void MarkTilesForUpdate(FLevelLocals * Level, const TArrayView<int> &tiles)
|
||||
{
|
||||
for(int i : tiles)
|
||||
{
|
||||
if(i >= 0)
|
||||
{
|
||||
auto &tile = Level->levelMesh->Lightmap.Tiles[i];
|
||||
if(tile.AlwaysUpdate == 0 && !tile.NeedsUpdate)
|
||||
{
|
||||
tile.AlwaysUpdate = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void MarkTilesForUpdate(FLevelLocals * Level, FLightNode * touching_sides, FLightNode * touching_sector)
|
||||
{
|
||||
if(Level->levelMesh)
|
||||
|
|
@ -96,20 +81,12 @@ static void MarkTilesForUpdate(FLevelLocals * Level, FLightNode * touching_sides
|
|||
while(touching_sides)
|
||||
{
|
||||
LevelMeshUpdater->SideLightListChanged(touching_sides->targLine);
|
||||
MarkTilesForUpdate(Level, touching_sides->targLine->LightmapTiles);
|
||||
|
||||
touching_sides = touching_sides->nextTarget;
|
||||
}
|
||||
|
||||
while(touching_sector)
|
||||
{
|
||||
LevelMeshUpdater->SectorLightListChanged(touching_sector->targSection->sector);
|
||||
for(subsector_t * ss : touching_sector->targSection->subsectors)
|
||||
{
|
||||
MarkTilesForUpdate(Level, ss->LightmapTiles[0]);
|
||||
MarkTilesForUpdate(Level, ss->LightmapTiles[1]);
|
||||
}
|
||||
|
||||
touching_sector = touching_sector->nextTarget;
|
||||
}
|
||||
}
|
||||
|
|
@ -675,11 +652,7 @@ void FDynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
|
||||
if(markTiles)
|
||||
{
|
||||
for(subsector_t * ss : section->subsectors)
|
||||
{
|
||||
MarkTilesForUpdate(Level, ss->LightmapTiles[0]);
|
||||
MarkTilesForUpdate(Level, ss->LightmapTiles[1]);
|
||||
}
|
||||
LevelMeshUpdater->SectorLightListChanged(section->sector);
|
||||
}
|
||||
|
||||
auto processSide = [&](side_t *sidedef, const vertex_t *v1, const vertex_t *v2)
|
||||
|
|
@ -694,7 +667,7 @@ void FDynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
touching_sides = AddLightNode(&sidedef->lighthead, sidedef, this, touching_sides);
|
||||
if(markTiles)
|
||||
{
|
||||
MarkTilesForUpdate(Level, sidedef->LightmapTiles);
|
||||
LevelMeshUpdater->SideLightListChanged(sidedef);
|
||||
}
|
||||
}
|
||||
else if (linedef->sidedef[0] == sidedef && linedef->sidedef[1] == nullptr)
|
||||
|
|
@ -836,8 +809,7 @@ void FDynamicLight::LinkLight()
|
|||
{
|
||||
if (node->lightsource == nullptr)
|
||||
{
|
||||
MarkTilesForUpdate(Level, node->targLine->LightmapTiles);
|
||||
|
||||
LevelMeshUpdater->SideLightListChanged(node->targLine);
|
||||
node = DeleteLightNode(node);
|
||||
}
|
||||
else
|
||||
|
|
@ -849,12 +821,7 @@ void FDynamicLight::LinkLight()
|
|||
{
|
||||
if (node->lightsource == nullptr)
|
||||
{
|
||||
for(subsector_t * ss : node->targSection->subsectors)
|
||||
{
|
||||
MarkTilesForUpdate(Level, ss->LightmapTiles[0]);
|
||||
MarkTilesForUpdate(Level, ss->LightmapTiles[1]);
|
||||
}
|
||||
|
||||
LevelMeshUpdater->SectorLightListChanged(node->targSection->sector);
|
||||
node = DeleteLightNode(node);
|
||||
}
|
||||
else
|
||||
|
|
@ -901,17 +868,13 @@ void FDynamicLight::UnlinkLight ()
|
|||
{
|
||||
while (touching_sides)
|
||||
{
|
||||
MarkTilesForUpdate(Level, touching_sides->targLine->LightmapTiles);
|
||||
LevelMeshUpdater->SideLightListChanged(touching_sides->targLine);
|
||||
touching_sides = DeleteLightNode(touching_sides);
|
||||
}
|
||||
|
||||
while (touching_sector)
|
||||
{
|
||||
for(subsector_t * ss : touching_sector->targSection->subsectors)
|
||||
{
|
||||
MarkTilesForUpdate(Level, ss->LightmapTiles[0]);
|
||||
MarkTilesForUpdate(Level, ss->LightmapTiles[1]);
|
||||
}
|
||||
LevelMeshUpdater->SectorLightListChanged(touching_sector->targSection->sector);
|
||||
touching_sector = DeleteLightNode(touching_sector);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,8 +77,8 @@ ADD_STAT(lightmap)
|
|||
int indexBufferUsed = levelMesh->FreeLists.Index.GetUsedSize();
|
||||
|
||||
out.Format(
|
||||
"Surfaces: %u (awaiting updates: %u static, %u dynamic)\n"
|
||||
"Surface pixel area to update: %u static, %u dynamic\n"
|
||||
"Surfaces: %u (awaiting updates: %u)\n"
|
||||
"Surface pixel area to update: %u\n"
|
||||
"Surface pixel area: %u\nAtlas pixel area: %u\n"
|
||||
"Atlas efficiency: %.4f%%\n"
|
||||
"Dynamic BLAS time: %2.3f ms\n"
|
||||
|
|
@ -86,8 +86,8 @@ ADD_STAT(lightmap)
|
|||
"Level mesh index buffer: %d K used (%d%%)\n"
|
||||
"Lightmap tiles in use: %d\n"
|
||||
"Lightmap texture count: %d",
|
||||
stats.tiles.total, stats.tiles.dirty, stats.tiles.dirtyDynamic,
|
||||
stats.pixels.dirty, stats.pixels.dirtyDynamic,
|
||||
stats.tiles.total, stats.tiles.dirty,
|
||||
stats.pixels.dirty,
|
||||
stats.pixels.total,
|
||||
atlasPixelCount,
|
||||
float(stats.pixels.total) / float(atlasPixelCount) * 100.0f,
|
||||
|
|
@ -159,7 +159,6 @@ void DoomLevelMesh::PrintSurfaceInfo(const LevelMeshSurface* surface)
|
|||
Printf(" Pixels: %dx%d (area: %d)\n", tile->AtlasLocation.Width, tile->AtlasLocation.Height, tile->AtlasLocation.Area());
|
||||
Printf(" Sample dimension: %d\n", tile->SampleDimension);
|
||||
Printf(" Needs update?: %d\n", tile->NeedsUpdate);
|
||||
Printf(" Always update?: %d\n", tile->AlwaysUpdate);
|
||||
}
|
||||
Printf(" Sector group: %d\n", surface->SectorGroup);
|
||||
Printf(" Texture: '%s'\n", gameTexture ? gameTexture->GetName().GetChars() : "<nullptr>");
|
||||
|
|
@ -1239,7 +1238,6 @@ int DoomLevelMesh::AddSurfaceToTile(const DoomSurfaceInfo& info, const LevelMesh
|
|||
tile.Bounds.max.X = std::max(tile.Bounds.max.X, surf.Bounds.max.X);
|
||||
tile.Bounds.max.Y = std::max(tile.Bounds.max.Y, surf.Bounds.max.Y);
|
||||
tile.Bounds.max.Z = std::max(tile.Bounds.max.Z, surf.Bounds.max.Z);
|
||||
tile.AlwaysUpdate = max<uint8_t>(tile.AlwaysUpdate, alwaysUpdate);
|
||||
tile.UseCount++;
|
||||
|
||||
return index;
|
||||
|
|
@ -1251,7 +1249,6 @@ int DoomLevelMesh::AddSurfaceToTile(const DoomSurfaceInfo& info, const LevelMesh
|
|||
tile.Bounds = surf.Bounds;
|
||||
tile.Plane = surf.Plane;
|
||||
tile.SampleDimension = GetSampleDimension(sampleDimension);
|
||||
tile.AlwaysUpdate = alwaysUpdate;
|
||||
tile.UseCount = 1;
|
||||
|
||||
int index = AllocTile(tile);
|
||||
|
|
|
|||
|
|
@ -140,9 +140,11 @@ void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uni
|
|||
hudsprites.Clear();
|
||||
Fogballs.Clear();
|
||||
VisibleTiles.Clear();
|
||||
visibleDyn = 0;
|
||||
vpIndex = 0;
|
||||
|
||||
static int counter = 1;
|
||||
TileSeenCounter = ++counter;
|
||||
|
||||
// Fullbright information needs to be propagated from the main view.
|
||||
if (outer != nullptr) FullbrightFlags = outer->FullbrightFlags;
|
||||
else FullbrightFlags = 0;
|
||||
|
|
@ -714,34 +716,26 @@ void HWDrawInfo::PutWallPortal(HWWall wall, FRenderState& state)
|
|||
|
||||
void HWDrawInfo::UpdateLightmaps()
|
||||
{
|
||||
if (!outer && VisibleTiles.Size() < unsigned(lm_background_updates))
|
||||
{
|
||||
int unbaked = 0;
|
||||
int dynamic = 0;
|
||||
if (outer)
|
||||
return;
|
||||
/*
|
||||
if (VisibleTiles.size() > (size_t)lm_max_updates)
|
||||
VisibleTiles.resize(lm_max_updates);
|
||||
|
||||
if (VisibleTiles.size() < (size_t)lm_background_updates)
|
||||
{
|
||||
for (auto& e : level.levelMesh->Lightmap.Tiles)
|
||||
{
|
||||
if (e.NeedsUpdate)
|
||||
if (e.NeedsUpdate && e.LastSeen != TileSeenCounter)
|
||||
{
|
||||
if(e.AlwaysUpdate == 0) unbaked++;
|
||||
if(e.AlwaysUpdate != 0) dynamic++;
|
||||
|
||||
VisibleTiles.Push(&e);
|
||||
|
||||
if((!dynamic && (VisibleTiles.Size() >= unsigned(lm_background_updates))) || unbaked >= unsigned(lm_background_updates)) break;
|
||||
if (VisibleTiles.size() >= (size_t)lm_background_updates)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(unbaked && dynamic)
|
||||
{
|
||||
std::sort(VisibleTiles.begin(), VisibleTiles.end(), [](LightmapTile *a, LightmapTile *b){return (!!a->AlwaysUpdate) < (!!b->AlwaysUpdate);});
|
||||
}
|
||||
|
||||
if(VisibleTiles.Size() > unsigned(lm_background_updates))
|
||||
{
|
||||
VisibleTiles.Resize(lm_background_updates);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
screen->UpdateLightmaps(VisibleTiles);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ struct HWDrawInfo
|
|||
TArray<HUDSprite> hudsprites; // These may just be stored by value.
|
||||
TArray<Fogball> Fogballs;
|
||||
TArray<LightmapTile*> VisibleTiles;
|
||||
unsigned visibleDyn;
|
||||
int TileSeenCounter = 0;
|
||||
uint64_t LastFrameTime = 0;
|
||||
|
||||
TArray<MissingTextureInfo> MissingUpperTextures;
|
||||
|
|
@ -241,24 +241,9 @@ public:
|
|||
}
|
||||
|
||||
LightmapTile* tile = &Level->levelMesh->Lightmap.Tiles[tileIndex];
|
||||
if (lm_always_update || tile->AlwaysUpdate == 2 || (tile->AlwaysUpdate == 1 && lm_dynamic))
|
||||
{
|
||||
tile->NeedsUpdate = true;
|
||||
visibleDyn++;
|
||||
}
|
||||
else if(tile->AlwaysUpdate == 3 && lm_dynamic)
|
||||
{
|
||||
tile->AlwaysUpdate = 0;
|
||||
tile->NeedsUpdate = true;
|
||||
visibleDyn++;
|
||||
}
|
||||
else if ((VisibleTiles.Size() - visibleDyn) >= unsigned(lm_max_updates))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (tile->NeedsUpdate)
|
||||
if (tile->LastSeen != TileSeenCounter)
|
||||
{
|
||||
tile->LastSeen = TileSeenCounter;
|
||||
VisibleTiles.Push(tile);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -553,7 +553,8 @@ void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t *
|
|||
unsigned int count = sector->e->XFloor.ffloors.Size() + 1;
|
||||
for (unsigned int j = 0; j < count; j++)
|
||||
{
|
||||
if (int tile = sector->subsectors[i]->LightmapTiles[plane].Size() > j ? sector->subsectors[i]->LightmapTiles[plane][j] : -1)
|
||||
int tile = sector->subsectors[i]->LightmapTiles[plane].Size() > j ? sector->subsectors[i]->LightmapTiles[plane][j] : -1;
|
||||
if (tile >= 0)
|
||||
{
|
||||
di->di->PushVisibleTile(tile);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1149,7 +1149,7 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_
|
|||
if (seg->sidedef->LightmapTiles.Size() >= 4 && type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM)
|
||||
{
|
||||
lightmaptile = seg->sidedef->LightmapTiles[type - RENDERWALL_TOP];
|
||||
if (lightmaptile && di->di)
|
||||
if (lightmaptile >= 0 && di->di)
|
||||
{
|
||||
di->di->PushVisibleTile(lightmaptile);
|
||||
}
|
||||
|
|
@ -1582,7 +1582,7 @@ void HWWall::BuildFFBlock(HWWallDispatcher *di, FRenderState& state, seg_t * seg
|
|||
else
|
||||
lightmaptile = seg->linedef->sidedef[0]->LightmapTiles.Size() > 4 + roverIndex ? seg->linedef->sidedef[0]->LightmapTiles[4 + roverIndex] : -1;
|
||||
|
||||
if (lightmaptile > 0)
|
||||
if (lightmaptile >= 0)
|
||||
{
|
||||
di->di->PushVisibleTile(lightmaptile);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue