mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
Update lightmapper and add limiter to updates
This commit is contained in:
parent
acc50ef36e
commit
995de6f71d
4 changed files with 88 additions and 36 deletions
|
@ -10,6 +10,8 @@
|
|||
#include "hw_viewpointuniforms.h"
|
||||
#include "hw_cvars.h"
|
||||
|
||||
EXTERN_CVAR(Int, lm_max_updates);
|
||||
|
||||
struct FColormap;
|
||||
class IBuffer;
|
||||
struct HWViewpointUniforms;
|
||||
|
@ -733,11 +735,11 @@ public:
|
|||
|
||||
inline void PushVisibleSurface(int surfaceIndex, LevelMeshSurface* surface)
|
||||
{
|
||||
if(surface->needsUpdate && mActiveLightmapSurfaces.Find(surfaceIndex) >= mActiveLightmapSurfaces.Size()) // yikes, how awful
|
||||
if(surface->needsUpdate && mActiveLightmapSurfaces.Size() < lm_max_updates && mActiveLightmapSurfaces.Find(surfaceIndex) >= mActiveLightmapSurfaces.Size()) // yikes, how awful
|
||||
mActiveLightmapSurfaces.Push(surfaceIndex);
|
||||
}
|
||||
|
||||
inline const auto& GetVisibleSurfaceList() const
|
||||
inline auto& GetVisibleSurfaceList()
|
||||
{
|
||||
return mActiveLightmapSurfaces;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,21 @@
|
|||
#include "filesystem.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
static int lastSurfaceCount;
|
||||
static glcycle_t lightmapRaytrace;
|
||||
static glcycle_t lightmapRaytraceLast;
|
||||
|
||||
ADD_STAT(lightmapper)
|
||||
{
|
||||
FString out;
|
||||
out.Format("last: %.3fms\ntotal: %3.fms\nLast batch surface count: %d", lightmapRaytraceLast.TimeMS(), lightmapRaytrace.TimeMS(), lastSurfaceCount);
|
||||
return out;
|
||||
}
|
||||
|
||||
CVAR(Int, lm_background_updates, 8, CVAR_NOSAVE);
|
||||
CVAR(Int, lm_max_updates, 128, CVAR_NOSAVE);
|
||||
|
||||
|
||||
VkLightmap::VkLightmap(VulkanRenderDevice* fb) : fb(fb)
|
||||
{
|
||||
useRayQuery = fb->GetDevice()->PhysicalDevice.Features.RayQuery.rayQuery;
|
||||
|
@ -31,18 +46,9 @@ VkLightmap::~VkLightmap()
|
|||
lights.Buffer->Unmap();
|
||||
}
|
||||
|
||||
static int lastSurfaceCount;
|
||||
static glcycle_t lightmapRaytrace;
|
||||
static glcycle_t lightmapRaytraceLast;
|
||||
|
||||
ADD_STAT(lightmapper)
|
||||
{
|
||||
FString out;
|
||||
out.Format("last: %.3fms\ntotal: %3.fms\nLast batch surface count: %d", lightmapRaytraceLast.TimeMS(), lightmapRaytrace.TimeMS(), lastSurfaceCount);
|
||||
return out;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include <set>
|
||||
#endif
|
||||
|
||||
void VkLightmap::Raytrace(LevelMesh* level, const TArray<int>& surfaceIndices)
|
||||
{
|
||||
|
@ -52,7 +58,6 @@ void VkLightmap::Raytrace(LevelMesh* level, const TArray<int>& surfaceIndices)
|
|||
if (newLevel)
|
||||
{
|
||||
UpdateAccelStructDescriptors();
|
||||
CreateAtlasImages();
|
||||
|
||||
lightmapRaytrace.Reset();
|
||||
lightmapRaytraceLast.Reset();
|
||||
|
@ -64,6 +69,8 @@ void VkLightmap::Raytrace(LevelMesh* level, const TArray<int>& surfaceIndices)
|
|||
lightmapRaytrace.Clock();
|
||||
lightmapRaytraceLast.ResetAndClock();
|
||||
|
||||
CreateAtlasImages(surfaceIndices);
|
||||
|
||||
#if 0
|
||||
TArray<int> allSurfaces;
|
||||
|
||||
|
@ -99,14 +106,20 @@ void VkLightmap::Raytrace(LevelMesh* level, const TArray<int>& surfaceIndices)
|
|||
|
||||
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
|
||||
{
|
||||
RenderAtlasImage(pageIndex, allSurfaces);
|
||||
if (atlasImages[pageIndex].pageMaxX && atlasImages[pageIndex].pageMaxY)
|
||||
{
|
||||
RenderAtlasImage(pageIndex, allSurfaces);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
|
||||
{
|
||||
ResolveAtlasImage(pageIndex);
|
||||
BlurAtlasImage(pageIndex);
|
||||
CopyAtlasImageResult(pageIndex, allSurfaces);
|
||||
if (atlasImages[pageIndex].pageMaxX && atlasImages[pageIndex].pageMaxY)
|
||||
{
|
||||
ResolveAtlasImage(pageIndex);
|
||||
BlurAtlasImage(pageIndex);
|
||||
CopyAtlasImageResult(pageIndex, allSurfaces);
|
||||
}
|
||||
}
|
||||
|
||||
lightmapRaytrace.Unclock();
|
||||
|
@ -246,24 +259,39 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex, const TArray<int>& surfaceIn
|
|||
fb->GetCommands()->GetTransferCommands()->endRenderPass();
|
||||
}
|
||||
|
||||
void VkLightmap::CreateAtlasImages()
|
||||
void VkLightmap::CreateAtlasImages(const TArray<int>& surfaceIndices)
|
||||
{
|
||||
for (auto& page : atlasImages)
|
||||
{
|
||||
page.pageMaxX = 0;
|
||||
page.pageMaxY = 0;
|
||||
}
|
||||
|
||||
const int spacing = 3; // Note: the spacing is here to avoid that the resolve sampler finds data from other surface tiles
|
||||
RectPacker packer(atlasImageSize, atlasImageSize, RectPacker::Spacing(spacing));
|
||||
|
||||
for (int i = 0, count = mesh->GetSurfaceCount(); i < count; i++)
|
||||
size_t pageIndex = atlasImages.size();
|
||||
|
||||
for (int i = 0, count = surfaceIndices.Size(); i < count; i++)
|
||||
{
|
||||
LevelMeshSurface* surface = mesh->GetSurface(i);
|
||||
LevelMeshSurface* surface = mesh->GetSurface(surfaceIndices[i]);
|
||||
//for (int i = 0, count = mesh->GetSurfaceCount(); i < count; i++)
|
||||
//{
|
||||
//LevelMeshSurface* surface = mesh->GetSurface(i);
|
||||
|
||||
auto result = packer.insert(surface->texWidth + 2, surface->texHeight + 2);
|
||||
surface->lightmapperAtlasX = result.pos.x + 1;
|
||||
surface->lightmapperAtlasY = result.pos.y + 1;
|
||||
surface->lightmapperAtlasPage = (int)result.pageIndex;
|
||||
}
|
||||
|
||||
for (size_t pageIndex = atlasImages.size(); pageIndex < packer.getNumPages(); pageIndex++)
|
||||
{
|
||||
atlasImages.push_back(CreateImage(atlasImageSize, atlasImageSize));
|
||||
for (;pageIndex <= result.pageIndex; pageIndex++)
|
||||
{
|
||||
atlasImages.push_back(CreateImage(atlasImageSize, atlasImageSize));
|
||||
}
|
||||
|
||||
auto& image = atlasImages[result.pageIndex];
|
||||
image.pageMaxX = std::max<uint16_t>(image.pageMaxX, uint16_t(surface->lightmapperAtlasX + surface->texWidth + spacing));
|
||||
image.pageMaxY = std::max<uint16_t>(image.pageMaxY, uint16_t(surface->lightmapperAtlasY + surface->texHeight + spacing));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,7 +325,7 @@ void VkLightmap::ResolveAtlasImage(size_t pageIndex)
|
|||
|
||||
RenderPassBegin()
|
||||
.RenderPass(resolve.renderPass.get())
|
||||
.RenderArea(0, 0, atlasImageSize, atlasImageSize)
|
||||
.RenderArea(0, 0, img.pageMaxX, img.pageMaxY)
|
||||
.Framebuffer(img.resolve.Framebuffer.get())
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
|
@ -308,8 +336,8 @@ void VkLightmap::ResolveAtlasImage(size_t pageIndex)
|
|||
|
||||
VkViewport viewport = {};
|
||||
viewport.maxDepth = 1;
|
||||
viewport.width = (float)atlasImageSize;
|
||||
viewport.height = (float)atlasImageSize;
|
||||
viewport.width = (float)img.pageMaxX;
|
||||
viewport.height = (float)img.pageMaxY;
|
||||
cmdbuffer->setViewport(0, 1, &viewport);
|
||||
|
||||
LightmapPushConstants pc;
|
||||
|
@ -348,7 +376,7 @@ void VkLightmap::BlurAtlasImage(size_t pageIndex)
|
|||
{
|
||||
RenderPassBegin()
|
||||
.RenderPass(blur.renderPass.get())
|
||||
.RenderArea(0, 0, atlasImageSize, atlasImageSize)
|
||||
.RenderArea(0, 0, img.pageMaxX, img.pageMaxY)
|
||||
.Framebuffer(img.blur.Framebuffer.get())
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
|
@ -359,8 +387,8 @@ void VkLightmap::BlurAtlasImage(size_t pageIndex)
|
|||
|
||||
VkViewport viewport = {};
|
||||
viewport.maxDepth = 1;
|
||||
viewport.width = (float)atlasImageSize;
|
||||
viewport.height = (float)atlasImageSize;
|
||||
viewport.width = (float)img.pageMaxX;
|
||||
viewport.height = (float)img.pageMaxY;
|
||||
cmdbuffer->setViewport(0, 1, &viewport);
|
||||
|
||||
LightmapPushConstants pc;
|
||||
|
@ -393,7 +421,7 @@ void VkLightmap::BlurAtlasImage(size_t pageIndex)
|
|||
{
|
||||
RenderPassBegin()
|
||||
.RenderPass(blur.renderPass.get())
|
||||
.RenderArea(0, 0, atlasImageSize, atlasImageSize)
|
||||
.RenderArea(0, 0, img.pageMaxX, img.pageMaxY)
|
||||
.Framebuffer(img.resolve.Framebuffer.get())
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
|
@ -404,8 +432,8 @@ void VkLightmap::BlurAtlasImage(size_t pageIndex)
|
|||
|
||||
VkViewport viewport = {};
|
||||
viewport.maxDepth = 1;
|
||||
viewport.width = (float)atlasImageSize;
|
||||
viewport.height = (float)atlasImageSize;
|
||||
viewport.width = (float)img.pageMaxX;
|
||||
viewport.height = (float)img.pageMaxY;
|
||||
cmdbuffer->setViewport(0, 1, &viewport);
|
||||
|
||||
LightmapPushConstants pc;
|
||||
|
|
|
@ -55,6 +55,10 @@ struct LightmapImage
|
|||
std::unique_ptr<VulkanFramebuffer> Framebuffer;
|
||||
std::unique_ptr<VulkanDescriptorSet> DescriptorSet[2];
|
||||
} blur;
|
||||
|
||||
// how much of the page is used?
|
||||
uint16_t pageMaxX = 0;
|
||||
uint16_t pageMaxY = 0;
|
||||
};
|
||||
|
||||
struct SceneVertex
|
||||
|
@ -92,7 +96,7 @@ private:
|
|||
void UpdateAccelStructDescriptors();
|
||||
|
||||
void UploadUniforms();
|
||||
void CreateAtlasImages();
|
||||
void CreateAtlasImages(const TArray<int>& surfaceIndices);
|
||||
void RenderAtlasImage(size_t pageIndex, const TArray<int>& surfaceIndices);
|
||||
void ResolveAtlasImage(size_t pageIndex);
|
||||
void BlurAtlasImage(size_t pageIndex);
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "hwrenderer/scene/hw_drawcontext.h"
|
||||
#include "hw_vrmodes.h"
|
||||
|
||||
EXTERN_CVAR(Int, lm_background_updates);
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
extern bool NoInterpolateView;
|
||||
|
||||
|
@ -198,7 +199,24 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou
|
|||
screen->NextEye(eyeCount);
|
||||
}
|
||||
|
||||
screen->UpdateLightmaps(RenderState.GetVisibleSurfaceList());
|
||||
auto& list = RenderState.GetVisibleSurfaceList();
|
||||
if (list.Size() <= lm_background_updates)
|
||||
{
|
||||
int index = 0;
|
||||
for (auto& e : level.levelMesh->Surfaces)
|
||||
{
|
||||
if (e.needsUpdate)
|
||||
{
|
||||
list.Push(index);
|
||||
|
||||
if(list.Size() >= lm_background_updates)
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
screen->UpdateLightmaps(list);
|
||||
|
||||
return mainvp.sector;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue