From 2c069349a38de754baae26603ebda4be241df5ee Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 May 2025 00:39:41 +0200 Subject: [PATCH] Portal and high update count fixes --- src/commandlets/lightmapcmd.cpp | 6 ++-- src/common/rendering/v_video.h | 2 ++ .../rendering/vulkan/vk_lightmapper.cpp | 28 ++++++++++++++++--- src/common/rendering/vulkan/vk_lightmapper.h | 1 + .../rendering/vulkan/vk_renderdevice.cpp | 3 ++ src/rendering/hwrenderer/doom_levelmesh.cpp | 8 ++++-- .../hwrenderer/scene/hw_drawinfo.cpp | 19 +++++-------- src/rendering/hwrenderer/scene/hw_drawinfo.h | 2 +- src/rendering/hwrenderer/scene/hw_walls.cpp | 5 ++++ 9 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/commandlets/lightmapcmd.cpp b/src/commandlets/lightmapcmd.cpp index 0841e9706..5f3593799 100644 --- a/src/commandlets/lightmapcmd.cpp +++ b/src/commandlets/lightmapcmd.cpp @@ -58,9 +58,9 @@ void LightmapBuildCmdlet::OnCommand(FArgs args) uint32_t atlasPixelCount = level.levelMesh->AtlasPixelCount(); auto stats = level.levelMesh->GatherTilePixelStats(); - 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("Tiles: %u (%u out of date)\n", stats.tiles.total, stats.tiles.dirty); + Printf("Tile pixel area to update: %u\n", stats.pixels.dirty); + Printf("Tile 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); Printf("Baking lightmap. Please wait...\n"); diff --git a/src/common/rendering/v_video.h b/src/common/rendering/v_video.h index d6c54a91d..9633f5aab 100644 --- a/src/common/rendering/v_video.h +++ b/src/common/rendering/v_video.h @@ -262,6 +262,8 @@ public: uint64_t FrameTime = 0; uint64_t FrameTimeNS = 0; + int FrameTileUpdates = 0; + private: uint64_t fpsLimitTime = 0; diff --git a/src/common/rendering/vulkan/vk_lightmapper.cpp b/src/common/rendering/vulkan/vk_lightmapper.cpp index f62ce09fb..e32709d2d 100644 --- a/src/common/rendering/vulkan/vk_lightmapper.cpp +++ b/src/common/rendering/vulkan/vk_lightmapper.cpp @@ -85,6 +85,7 @@ void VkLightmapper::SetLevelMesh(LevelMesh* level) void VkLightmapper::BeginFrame() { drawindexed.Pos = 0; + copytiles.Pos = 0; } void VkLightmapper::Raytrace(const TArray& tiles) @@ -97,6 +98,7 @@ void VkLightmapper::Raytrace(const TArray& tiles) fb->GetCommands()->PushGroup(fb->GetCommands()->GetTransferCommands(), "lightmap.total"); UploadUniforms(); + bool firstCall = true; while (true) { SelectTiles(tiles); @@ -108,6 +110,15 @@ void VkLightmapper::Raytrace(const TArray& tiles) if (lm_blur) Blur(); CopyResult(); + + if (drawindexed.Pos == drawindexed.BufferSize || copytiles.Pos == drawindexed.BufferSize) + { + fb->GetCommands()->PopGroup(fb->GetCommands()->GetTransferCommands()); + fb->WaitForCommands(false); + fb->GetCommands()->PushGroup(fb->GetCommands()->GetTransferCommands(), "lightmap.total"); + drawindexed.Pos = 0; + copytiles.Pos = 0; + } } fb->GetCommands()->PopGroup(fb->GetCommands()->GetTransferCommands()); @@ -159,6 +170,10 @@ void VkLightmapper::Render() fb->GetCommands()->PushGroup(cmdbuffer, "lightmap.raytrace"); + PipelineBarrier() + .AddImage(bakeImage.raytrace.Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) + .Execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + RenderPassBegin() .RenderPass(raytrace.renderPass.get()) .RenderArea(0, 0, bakeImage.maxX, bakeImage.maxY) @@ -180,6 +195,8 @@ void VkLightmapper::Render() viewport.height = (float)bakeImageSize; cmdbuffer->setViewport(0, 1, &viewport); + int startPos = drawindexed.Pos; + for (int i = 0, count = selectedTiles.Size(); i < count; i++) { auto& selectedTile = selectedTiles[i]; @@ -237,7 +254,7 @@ void VkLightmapper::Render() selectedTile.Rendered = true; } - cmdbuffer->drawIndexedIndirect(drawindexed.CommandsBuffer->buffer, 0, drawindexed.Pos, sizeof(VkDrawIndexedIndirectCommand)); + cmdbuffer->drawIndexedIndirect(drawindexed.CommandsBuffer->buffer, startPos * sizeof(VkDrawIndexedIndirectCommand), drawindexed.Pos - startPos, sizeof(VkDrawIndexedIndirectCommand)); cmdbuffer->endRenderPass(); @@ -270,7 +287,8 @@ void VkLightmapper::Resolve() PipelineBarrier() .AddImage(bakeImage.raytrace.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT) - .Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + .AddImage(bakeImage.resolve.Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) + .Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); RenderPassBegin() .RenderPass(resolve.renderPass.get()) @@ -400,8 +418,8 @@ void VkLightmapper::CopyResult() barrier0.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); // Copy into the lightmap images - int start = 0; - int pos = 0; + int start = copytiles.Pos; + int pos = copytiles.Pos; for (unsigned int i = 0, count = copylists.Size(); i < count; i++) { auto& list = copylists[i]; @@ -477,6 +495,8 @@ void VkLightmapper::CopyResult() cmdbuffer->endRenderPass(); } + copytiles.Pos = pos; + // Transition lightmap destination images back to be used for fragment shader sampling PipelineBarrier barrier1; for (unsigned int i = 0, count = copylists.Size(); i < count; i++) diff --git a/src/common/rendering/vulkan/vk_lightmapper.h b/src/common/rendering/vulkan/vk_lightmapper.h index 01fea04ef..80ea7f1ab 100644 --- a/src/common/rendering/vulkan/vk_lightmapper.h +++ b/src/common/rendering/vulkan/vk_lightmapper.h @@ -163,6 +163,7 @@ private: const int BufferSize = 100'000; std::unique_ptr Buffer; CopyTileInfo* Tiles = nullptr; + int Pos = 0; } copytiles; struct diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index 19cee6273..604537161 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -604,6 +604,8 @@ void VulkanRenderDevice::BeginFrame() } hwtexturecount = mTextureManager->GetHWTextureCount(); + FrameTileUpdates = 0; + GetRenderPassManager()->ProcessMainThreadTasks(); GetTextureManager()->ProcessMainThreadTasks(); @@ -686,6 +688,7 @@ void VulkanRenderDevice::SetLevelMesh(LevelMesh* mesh) void VulkanRenderDevice::UpdateLightmaps(const TArray& tiles) { + FrameTileUpdates += (int)tiles.size(); GetLightmapper()->Raytrace(tiles); } diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 3fee04ab7..5045dab90 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -77,15 +77,17 @@ ADD_STAT(lightmap) int indexBufferUsed = levelMesh->FreeLists.Index.GetUsedSize(); out.Format( - "Surfaces: %u (awaiting updates: %u)\n" - "Surface pixel area to update: %u\n" - "Surface pixel area: %u\nAtlas pixel area: %u\n" + "Tiles updated this frame: %d\n" + "Tiles: %u (%u out of date)\n" + "Tile pixel area to update: %u\n" + "Tile pixel area: %u\nAtlas pixel area: %u\n" "Atlas efficiency: %.4f%%\n" "Dynamic BLAS time: %2.3f ms\n" "Level mesh process time: %2.3f ms\n" "Level mesh index buffer: %d K used (%d%%)\n" "Lightmap tiles in use: %d\n" "Lightmap texture count: %d", + screen->FrameTileUpdates, stats.tiles.total, stats.tiles.dirty, stats.pixels.dirty, stats.pixels.total, diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index 373898bba..dffc11455 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -139,11 +139,13 @@ void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uni for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset(); hudsprites.Clear(); Fogballs.Clear(); - VisibleTiles.Clear(); vpIndex = 0; - static int counter = 1; - TileSeenCounter = ++counter; + if (!outer) + { + static int counter = 1; + TileSeenCounter = ++counter; + } // Fullbright information needs to be propagated from the main view. if (outer != nullptr) FullbrightFlags = outer->FullbrightFlags; @@ -717,7 +719,7 @@ void HWDrawInfo::PutWallPortal(HWWall wall, FRenderState& state) void HWDrawInfo::UpdateLightmaps() { if (outer) - return; + outer->UpdateLightmaps(); /* if (VisibleTiles.size() > (size_t)lm_max_updates) VisibleTiles.resize(lm_max_updates); @@ -737,16 +739,9 @@ void HWDrawInfo::UpdateLightmaps() */ screen->UpdateLightmaps(VisibleTiles); + VisibleTiles.Clear(); } -//----------------------------------------------------------------------------- -// -// RenderScene -// -// Draws the current draw lists for the non GLSL renderer -// -//----------------------------------------------------------------------------- - void HWDrawInfo::RenderScene(FRenderState &state) { const auto &vp = Viewpoint; diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index eef985849..f92bb3cf5 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -241,7 +241,7 @@ public: } LightmapTile* tile = &Level->levelMesh->Lightmap.Tiles[tileIndex]; - if (tile->LastSeen != TileSeenCounter) + if (tile->NeedsUpdate && tile->LastSeen != TileSeenCounter) { tile->LastSeen = TileSeenCounter; VisibleTiles.Push(tile); diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 4b1c6b296..c63dce97b 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -1146,6 +1146,11 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_ if (di->di) { + if (seg->sidedef->Index() == 55) + { + type = _type; + } + if (seg->sidedef->LightmapTiles.Size() >= 4 && type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM) { lightmaptile = seg->sidedef->LightmapTiles[type - RENDERWALL_TOP];