Portal and high update count fixes

This commit is contained in:
Magnus Norddahl 2025-05-12 00:39:41 +02:00
commit 2c069349a3
9 changed files with 51 additions and 23 deletions

View file

@ -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");

View file

@ -262,6 +262,8 @@ public:
uint64_t FrameTime = 0;
uint64_t FrameTimeNS = 0;
int FrameTileUpdates = 0;
private:
uint64_t fpsLimitTime = 0;

View file

@ -85,6 +85,7 @@ void VkLightmapper::SetLevelMesh(LevelMesh* level)
void VkLightmapper::BeginFrame()
{
drawindexed.Pos = 0;
copytiles.Pos = 0;
}
void VkLightmapper::Raytrace(const TArray<LightmapTile*>& tiles)
@ -97,6 +98,7 @@ void VkLightmapper::Raytrace(const TArray<LightmapTile*>& 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<LightmapTile*>& 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++)

View file

@ -163,6 +163,7 @@ private:
const int BufferSize = 100'000;
std::unique_ptr<VulkanBuffer> Buffer;
CopyTileInfo* Tiles = nullptr;
int Pos = 0;
} copytiles;
struct

View file

@ -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<LightmapTile*>& tiles)
{
FrameTileUpdates += (int)tiles.size();
GetLightmapper()->Raytrace(tiles);
}

View file

@ -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,

View file

@ -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;

View file

@ -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);

View file

@ -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];