Slightly improve performance

This commit is contained in:
Magnus Norddahl 2023-04-14 16:55:56 +02:00
parent 74b81bc65a
commit 0655ffd7f5
5 changed files with 120 additions and 105 deletions

View file

@ -62,7 +62,7 @@ void FLevel::SetupLights()
sundir.y = -sdy;
sundir.z = -sdz;
printf("Sun vector: %f, %f, %f\n", sundir.x, sundir.y, sundir.z);
printf(" Sun vector: %f, %f, %f\n", sundir.x, sundir.y, sundir.z);
for (unsigned int propIndex = 0; propIndex < thing->props.Size(); propIndex++)
{
@ -71,7 +71,7 @@ void FLevel::SetupLights()
if (!stricmp(key.key, "lm_suncolor"))
{
lightcolor = atoi(key.value);
printf("Sun color: %d (%X)\n", lightcolor, lightcolor);
printf(" Sun color: %d (%X)\n", lightcolor, lightcolor);
}
else if (!stricmp(key.key, "lm_sampledistance"))
{
@ -291,7 +291,7 @@ void FLevel::CreateLights()
}
}
printf("Thing lights: %i\n", (int)ThingLights.Size());
printf(" Thing lights: %i\n", (int)ThingLights.Size());
// add surface lights (temporarily disabled)
for (unsigned int i = 0; i < Sides.Size(); i++)
@ -412,5 +412,5 @@ void FLevel::CreateLights()
*/
}
//printf("Surface lights: %i\n", (int)SurfaceLights.Size());
//printf(" Surface lights: %i\n", (int)SurfaceLights.Size());
}

View file

@ -28,52 +28,7 @@ extern bool NoRtx;
#include <dlfcn.h>
#endif
RENDERDOC_API_1_4_2* rdoc_api;
void LoadRenderDoc()
{
#ifdef _WIN32
if (auto mod = GetModuleHandleA("renderdoc.dll"))
{
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_4_2, (void**)&rdoc_api);
assert(ret == 1);
if (ret != 1)
{
printf("RENDERDOC_GetAPI returned %d\n", ret);
}
}
#else
if (void* mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD))
{
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_4_2, (void**)&rdoc_api);
assert(ret == 1);
if (ret != 1)
{
printf("RENDERDOC_GetAPI returned %d\n", ret);
}
}
#endif
if (rdoc_api)
{
printf("RenderDoc enabled\n");
}
}
void VulkanPrintLog(const char* typestr, const std::string& msg)
{
printf("[%s] %s\n", typestr, msg.c_str());
printf("%s\n", CaptureStackTraceText(2).c_str());
}
void VulkanError(const char* text)
{
throw std::runtime_error(text);
}
static RENDERDOC_API_1_4_2* rdoc_api;
GPURaytracer::GPURaytracer()
{
@ -103,47 +58,57 @@ void GPURaytracer::Raytrace(LevelMesh* level)
mesh = level;
printf("Building Vulkan acceleration structures\n");
printf(" Building Vulkan acceleration structures\n");
CreateVulkanObjects();
printf("Ray tracing in progress...\n");
CreateAtlasImages();
BeginCommands();
UploadUniforms();
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
try
{
RenderAtlasImage(pageIndex);
}
printf(" Ray tracing in progress\n");
printf(" [");
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
ResolveAtlasImage(pageIndex);
}
CreateAtlasImages();
#ifdef WIN32
LARGE_INTEGER s;
QueryPerformanceCounter(&s);
LARGE_INTEGER s;
QueryPerformanceCounter(&s);
#endif
FinishCommands();
BeginCommands();
UploadUniforms();
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
RenderAtlasImage(pageIndex);
}
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
ResolveAtlasImage(pageIndex);
}
FinishCommands();
#ifdef WIN32
LARGE_INTEGER e, f;
QueryPerformanceCounter(&e);
QueryPerformanceFrequency(&f);
printf("GPU ray tracing time was %.3f seconds.\n", double(e.QuadPart - s.QuadPart) / double(f.QuadPart));
LARGE_INTEGER e, f;
QueryPerformanceCounter(&e);
QueryPerformanceFrequency(&f);
printf("]\n");
printf(" GPU ray tracing time was %.3f seconds.\n", double(e.QuadPart - s.QuadPart) / double(f.QuadPart));
#endif
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
DownloadAtlasImage(pageIndex);
}
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
DownloadAtlasImage(pageIndex);
}
printf("Ray trace complete\n");
printf(" Ray trace complete\n");
}
catch (...)
{
printf("]\n");
throw;
}
if (rdoc_api) rdoc_api->EndFrameCapture(nullptr, nullptr);
}
@ -182,14 +147,11 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
cmdbuffer->setViewport(0, 1, &viewport);
// Paint all surfaces part of the smoothing group into the surface
for (const auto& surface : mesh->surfaces)
for (Surface* surface : mesh->smoothingGroups[targetSurface->smoothingGroupIndex].surfaces)
{
if (surface->smoothingGroupIndex != targetSurface->smoothingGroupIndex)
continue;
vec2 minUV = ToUV(surface->bounds.min, targetSurface);
vec2 maxUV = ToUV(surface->bounds.max, targetSurface);
if (surface.get() != targetSurface && (maxUV.x < 0.0f || maxUV.y < 0.0f || minUV.x > 1.0f || minUV.y > 1.0f))
if (surface != targetSurface && (maxUV.x < 0.0f || maxUV.y < 0.0f || minUV.x > 1.0f || minUV.y > 1.0f))
continue; // Bounding box not visible
int firstLight = sceneLightPos;
@ -198,6 +160,8 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
int vertexCount = (int)surface->verts.size();
if (sceneLightPos + lightCount > SceneLightBufferSize || sceneVertexPos + vertexCount > SceneVertexBufferSize)
{
printf(".");
// Flush scene buffers
FinishCommands();
sceneLightPos = 0;
@ -207,6 +171,8 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
BeginCommands();
beginPass();
printf(".");
if (sceneLightPos + lightCount > SceneLightBufferSize)
{
throw std::runtime_error("SceneLightBuffer is too small!");
@ -1075,9 +1041,54 @@ void GPURaytracer::PrintVulkanInfo()
std::string apiVersion = std::to_string(VK_VERSION_MAJOR(props.apiVersion)) + "." + std::to_string(VK_VERSION_MINOR(props.apiVersion)) + "." + std::to_string(VK_VERSION_PATCH(props.apiVersion));
std::string driverVersion = std::to_string(VK_VERSION_MAJOR(props.driverVersion)) + "." + std::to_string(VK_VERSION_MINOR(props.driverVersion)) + "." + std::to_string(VK_VERSION_PATCH(props.driverVersion));
printf("Vulkan device: %s\n", props.deviceName);
printf("Vulkan device type: %s\n", deviceType.c_str());
printf("Vulkan version: %s (api) %s (driver)\n", apiVersion.c_str(), driverVersion.c_str());
printf(" Vulkan device: %s\n", props.deviceName);
printf(" Vulkan device type: %s\n", deviceType.c_str());
printf(" Vulkan version: %s (api) %s (driver)\n", apiVersion.c_str(), driverVersion.c_str());
}
void GPURaytracer::LoadRenderDoc()
{
#ifdef _WIN32
if (auto mod = GetModuleHandleA("renderdoc.dll"))
{
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_4_2, (void**)&rdoc_api);
assert(ret == 1);
if (ret != 1)
{
printf(" RENDERDOC_GetAPI returned %d\n", ret);
}
}
#else
if (void* mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD))
{
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_4_2, (void**)&rdoc_api);
assert(ret == 1);
if (ret != 1)
{
printf(" RENDERDOC_GetAPI returned %d\n", ret);
}
}
#endif
if (rdoc_api)
{
printf(" RenderDoc enabled\n");
}
}
void VulkanPrintLog(const char* typestr, const std::string& msg)
{
printf(" [%s] %s\n", typestr, msg.c_str());
printf(" %s\n", CaptureStackTraceText(2).c_str());
}
void VulkanError(const char* text)
{
throw std::runtime_error(text);
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -139,6 +139,7 @@ private:
void BeginCommands();
void FinishCommands();
void LoadRenderDoc();
void PrintVulkanInfo();
std::vector<SurfaceInfo> CreateSurfaceInfo();

View file

@ -46,19 +46,17 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
textureWidth = textureSize;
textureHeight = textureSize;
printf("\n------------- Building side surfaces -------------\n");
for (unsigned int i = 0; i < doomMap.Sides.Size(); i++)
{
CreateSideSurfaces(doomMap, &doomMap.Sides[i]);
printf("Sides: %i / %i\r", i + 1, doomMap.Sides.Size());
printf(" Sides: %i / %i\r", i + 1, doomMap.Sides.Size());
}
printf("\nSide surfaces: %i\n", (int)surfaces.size());
printf("\n Side surfaces: %i\n", (int)surfaces.size());
CreateSubsectorSurfaces(doomMap);
printf("Surfaces total: %i\n\n", (int)surfaces.size());
printf(" Surfaces total: %i\n", (int)surfaces.size());
// Update sector group of the surfacesaa
for (auto& surface : surfaces)
@ -67,7 +65,7 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
doomMap.GetSectorFromSubSector(&doomMap.GLSubsectors[surface->typeIndex])->group : (doomMap.Sides[surface->typeIndex].GetSectorGroup());
}
printf("Building level mesh...\n\n");
printf(" Building level mesh...\n");
for (size_t i = 0; i < surfaces.size(); i++)
{
@ -118,9 +116,9 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
BuildSurfaceParams(surfaces[i].get());
}
printf("Finding smoothing groups...\n\n");
printf(" Finding smoothing groups...\n");
BuildSmoothingGroups(doomMap);
printf("Building collision data...\n\n");
printf(" Building collision data...\n");
Collision = std::make_unique<TriangleMeshShape>(MeshVertices.Data(), MeshVertices.Size(), MeshElements.Data(), MeshElements.Size());
@ -130,15 +128,20 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
for (auto& surface : surfaces)
lightStats[surface->LightList.size()]++;
for (auto& it : lightStats)
printf("%d lights: %d surfaces\n", it.first, it.second);
printf(" %d lights: %d surfaces\n", it.first, it.second);
printf("\n");
*/
}
void LevelMesh::BuildSmoothingGroups(FLevel& doomMap)
{
size_t lastPercentage = 0;
for (size_t i = 0; i < surfaces.size(); i++)
{
size_t percentage = i * 100 / surfaces.size();
if (lastPercentage != percentage)
printf(" Surfaces: %i%%\r", (int)percentage);
// Is this surface in the same plane as an existing smoothing group?
int smoothingGroupIndex = -1;
@ -172,10 +175,11 @@ void LevelMesh::BuildSmoothingGroups(FLevel& doomMap)
smoothingGroups.push_back(group);
}
smoothingGroups[smoothingGroupIndex].surfaces.push_back(surface);
surface->smoothingGroupIndex = smoothingGroupIndex;
}
printf("Created %d smoothing groups for %d surfaces\n\n", (int)smoothingGroups.size(), (int)surfaces.size());
printf(" Created %d smoothing groups for %d surfaces\n", (int)smoothingGroups.size(), (int)surfaces.size());
}
void LevelMesh::PropagateLight(FLevel& doomMap, ThingLight *light)
@ -241,11 +245,11 @@ void LevelMesh::BuildLightLists(FLevel& doomMap)
{
for (unsigned i = 0; i < map->ThingLights.Size(); ++i)
{
printf("Building light lists: %u / %u\r", i, map->ThingLights.Size());
printf(" Building light lists: %u / %u\r", i, map->ThingLights.Size());
PropagateLight(doomMap, &map->ThingLights[i]);
}
printf("Building light lists: %u / %u\n", map->ThingLights.Size(), map->ThingLights.Size());
printf(" Building light lists: %u / %u\n", map->ThingLights.Size(), map->ThingLights.Size());
}
// Determines a lightmap block in which to map to the lightmap texture.
@ -567,7 +571,7 @@ int LevelMesh::CreateLinePortal(FLevel& doomMap, const IntLineDef& srcLine, cons
// Rotation
// TODO :(
// printf("Portal translation: %.3f %.3f %.3f\n", translation.x, translation.y, translation.z);
// printf(" Portal translation: %.3f %.3f %.3f\n", translation.x, translation.y, translation.z);
portal->transformation = mat4::translate(translation);
portal->sourceSectorGroup = srcLine.GetSectorGroup();
@ -662,7 +666,7 @@ int LevelMesh::CreatePlanePortal(FLevel& doomMap, const IntLineDef& srcLine, con
vec3 translation = originDst - originSrc;
// printf("Portal translation: %.3f %.3f %.3f\n", translation.x, translation.y, translation.z);
// printf(" Portal translation: %.3f %.3f %.3f\n", translation.x, translation.y, translation.z);
portal->transformation = mat4::translate(translation);
portal->sourceSectorGroup = srcLine.GetSectorGroup();
@ -1116,11 +1120,9 @@ void LevelMesh::CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSe
void LevelMesh::CreateSubsectorSurfaces(FLevel &doomMap)
{
printf("\n------------- Building subsector surfaces -------------\n");
for (int i = 0; i < doomMap.NumGLSubsectors; i++)
{
printf("Subsectors: %i / %i\r", i + 1, doomMap.NumGLSubsectors);
printf(" Subsectors: %i / %i\r", i + 1, doomMap.NumGLSubsectors);
MapSubsectorEx *sub = &doomMap.GLSubsectors[i];
@ -1143,7 +1145,7 @@ void LevelMesh::CreateSubsectorSurfaces(FLevel &doomMap)
}
}
printf("\nLeaf surfaces: %i\n", (int)surfaces.size() - doomMap.NumGLSubsectors);
printf("\n Leaf surfaces: %i\n", (int)surfaces.size() - doomMap.NumGLSubsectors);
}
bool LevelMesh::IsDegenerate(const vec3 &v0, const vec3 &v1, const vec3 &v2)
@ -1277,7 +1279,7 @@ void LevelMesh::AddLightmapLump(FWadWriter& wadFile)
void LevelMesh::Export(std::string filename)
{
printf("Exporting mesh \"%s\"\n", filename.c_str());
printf(" Exporting mesh \"%s\"\n", filename.c_str());
// This is so ugly! I had nothing to do with it! ;)
std::string mtlfilename = filename;
@ -1460,5 +1462,5 @@ void LevelMesh::Export(std::string filename)
#endif
}
printf("Export complete\n");
printf(" Export complete\n");
}

View file

@ -122,6 +122,7 @@ struct SmoothingGroup
{
Plane plane = Plane(0, 0, 1, 0);
int sectorGroup = 0;
std::vector<Surface*> surfaces;
};
class LevelMesh