diff --git a/src/commandlets/lightmapcmd.cpp b/src/commandlets/lightmapcmd.cpp index adb84b1c2..0841e9706 100644 --- a/src/commandlets/lightmapcmd.cpp +++ b/src/commandlets/lightmapcmd.cpp @@ -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) diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp index 38fad93f9..d91423e36 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp @@ -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; diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index 19b7d6d87..98b354241 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -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; diff --git a/src/common/rendering/hwrenderer/data/hw_lightmaptile.h b/src/common/rendering/hwrenderer/data/hw_lightmaptile.h index 765215035..86574faf9 100644 --- a/src/common/rendering/hwrenderer/data/hw_lightmaptile.h +++ b/src/common/rendering/hwrenderer/data/hw_lightmaptile.h @@ -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 { diff --git a/src/common/rendering/vulkan/vk_lightmapper.cpp b/src/common/rendering/vulkan/vk_lightmapper.cpp index f14a5d647..f62ce09fb 100644 --- a/src/common/rendering/vulkan/vk_lightmapper.cpp +++ b/src/common/rendering/vulkan/vk_lightmapper.cpp @@ -94,22 +94,23 @@ void VkLightmapper::Raytrace(const TArray& 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(); } } diff --git a/src/playsim/a_dynlight.cpp b/src/playsim/a_dynlight.cpp index f3ba3854d..a586d4578 100644 --- a/src/playsim/a_dynlight.cpp +++ b/src/playsim/a_dynlight.cpp @@ -74,21 +74,6 @@ static FCRandom randLight; extern TArray StateLights; -static void MarkTilesForUpdate(FLevelLocals * Level, const TArrayView &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); } } diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index bb7ba3f7e..42946c346 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -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() : ""); @@ -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(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); diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index d53bdd3aa..373898bba 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -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); } diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index 57b1f2c69..eef985849 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -158,7 +158,7 @@ struct HWDrawInfo TArray hudsprites; // These may just be stored by value. TArray Fogballs; TArray VisibleTiles; - unsigned visibleDyn; + int TileSeenCounter = 0; uint64_t LastFrameTime = 0; TArray 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); } } diff --git a/src/rendering/hwrenderer/scene/hw_flats.cpp b/src/rendering/hwrenderer/scene/hw_flats.cpp index e40eea761..7bd658032 100644 --- a/src/rendering/hwrenderer/scene/hw_flats.cpp +++ b/src/rendering/hwrenderer/scene/hw_flats.cpp @@ -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); } diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index d474fe111..4b1c6b296 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -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); }