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.y = -sdy;
sundir.z = -sdz; 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++) for (unsigned int propIndex = 0; propIndex < thing->props.Size(); propIndex++)
{ {
@ -71,7 +71,7 @@ void FLevel::SetupLights()
if (!stricmp(key.key, "lm_suncolor")) if (!stricmp(key.key, "lm_suncolor"))
{ {
lightcolor = atoi(key.value); 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")) 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) // add surface lights (temporarily disabled)
for (unsigned int i = 0; i < Sides.Size(); i++) 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> #include <dlfcn.h>
#endif #endif
RENDERDOC_API_1_4_2* rdoc_api; static 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);
}
GPURaytracer::GPURaytracer() GPURaytracer::GPURaytracer()
{ {
@ -103,47 +58,57 @@ void GPURaytracer::Raytrace(LevelMesh* level)
mesh = level; mesh = level;
printf("Building Vulkan acceleration structures\n"); printf(" Building Vulkan acceleration structures\n");
CreateVulkanObjects(); CreateVulkanObjects();
printf("Ray tracing in progress...\n"); try
CreateAtlasImages();
BeginCommands();
UploadUniforms();
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{ {
RenderAtlasImage(pageIndex); printf(" Ray tracing in progress\n");
} printf(" [");
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++) CreateAtlasImages();
{
ResolveAtlasImage(pageIndex);
}
#ifdef WIN32 #ifdef WIN32
LARGE_INTEGER s; LARGE_INTEGER s;
QueryPerformanceCounter(&s); QueryPerformanceCounter(&s);
#endif #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 #ifdef WIN32
LARGE_INTEGER e, f; LARGE_INTEGER e, f;
QueryPerformanceCounter(&e); QueryPerformanceCounter(&e);
QueryPerformanceFrequency(&f); QueryPerformanceFrequency(&f);
printf("GPU ray tracing time was %.3f seconds.\n", double(e.QuadPart - s.QuadPart) / double(f.QuadPart)); printf("]\n");
printf(" GPU ray tracing time was %.3f seconds.\n", double(e.QuadPart - s.QuadPart) / double(f.QuadPart));
#endif #endif
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++) for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{ {
DownloadAtlasImage(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); if (rdoc_api) rdoc_api->EndFrameCapture(nullptr, nullptr);
} }
@ -182,14 +147,11 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
cmdbuffer->setViewport(0, 1, &viewport); cmdbuffer->setViewport(0, 1, &viewport);
// Paint all surfaces part of the smoothing group into the surface // 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 minUV = ToUV(surface->bounds.min, targetSurface);
vec2 maxUV = ToUV(surface->bounds.max, 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 continue; // Bounding box not visible
int firstLight = sceneLightPos; int firstLight = sceneLightPos;
@ -198,6 +160,8 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
int vertexCount = (int)surface->verts.size(); int vertexCount = (int)surface->verts.size();
if (sceneLightPos + lightCount > SceneLightBufferSize || sceneVertexPos + vertexCount > SceneVertexBufferSize) if (sceneLightPos + lightCount > SceneLightBufferSize || sceneVertexPos + vertexCount > SceneVertexBufferSize)
{ {
printf(".");
// Flush scene buffers // Flush scene buffers
FinishCommands(); FinishCommands();
sceneLightPos = 0; sceneLightPos = 0;
@ -207,6 +171,8 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
BeginCommands(); BeginCommands();
beginPass(); beginPass();
printf(".");
if (sceneLightPos + lightCount > SceneLightBufferSize) if (sceneLightPos + lightCount > SceneLightBufferSize)
{ {
throw std::runtime_error("SceneLightBuffer is too small!"); 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 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)); 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: %s\n", props.deviceName);
printf("Vulkan device type: %s\n", deviceType.c_str()); 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 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 BeginCommands();
void FinishCommands(); void FinishCommands();
void LoadRenderDoc();
void PrintVulkanInfo(); void PrintVulkanInfo();
std::vector<SurfaceInfo> CreateSurfaceInfo(); std::vector<SurfaceInfo> CreateSurfaceInfo();

View file

@ -46,19 +46,17 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
textureWidth = textureSize; textureWidth = textureSize;
textureHeight = textureSize; textureHeight = textureSize;
printf("\n------------- Building side surfaces -------------\n");
for (unsigned int i = 0; i < doomMap.Sides.Size(); i++) for (unsigned int i = 0; i < doomMap.Sides.Size(); i++)
{ {
CreateSideSurfaces(doomMap, &doomMap.Sides[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); 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 // Update sector group of the surfacesaa
for (auto& surface : surfaces) 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()); 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++) 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()); BuildSurfaceParams(surfaces[i].get());
} }
printf("Finding smoothing groups...\n\n"); printf(" Finding smoothing groups...\n");
BuildSmoothingGroups(doomMap); 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()); 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) for (auto& surface : surfaces)
lightStats[surface->LightList.size()]++; lightStats[surface->LightList.size()]++;
for (auto& it : lightStats) 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"); printf("\n");
*/ */
} }
void LevelMesh::BuildSmoothingGroups(FLevel& doomMap) void LevelMesh::BuildSmoothingGroups(FLevel& doomMap)
{ {
size_t lastPercentage = 0;
for (size_t i = 0; i < surfaces.size(); i++) 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? // Is this surface in the same plane as an existing smoothing group?
int smoothingGroupIndex = -1; int smoothingGroupIndex = -1;
@ -172,10 +175,11 @@ void LevelMesh::BuildSmoothingGroups(FLevel& doomMap)
smoothingGroups.push_back(group); smoothingGroups.push_back(group);
} }
smoothingGroups[smoothingGroupIndex].surfaces.push_back(surface);
surface->smoothingGroupIndex = smoothingGroupIndex; 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) 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) 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]); 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. // 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 // Rotation
// TODO :( // 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->transformation = mat4::translate(translation);
portal->sourceSectorGroup = srcLine.GetSectorGroup(); portal->sourceSectorGroup = srcLine.GetSectorGroup();
@ -662,7 +666,7 @@ int LevelMesh::CreatePlanePortal(FLevel& doomMap, const IntLineDef& srcLine, con
vec3 translation = originDst - originSrc; 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->transformation = mat4::translate(translation);
portal->sourceSectorGroup = srcLine.GetSectorGroup(); portal->sourceSectorGroup = srcLine.GetSectorGroup();
@ -1116,11 +1120,9 @@ void LevelMesh::CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSe
void LevelMesh::CreateSubsectorSurfaces(FLevel &doomMap) void LevelMesh::CreateSubsectorSurfaces(FLevel &doomMap)
{ {
printf("\n------------- Building subsector surfaces -------------\n");
for (int i = 0; i < doomMap.NumGLSubsectors; i++) 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]; 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) 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) 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! ;) // This is so ugly! I had nothing to do with it! ;)
std::string mtlfilename = filename; std::string mtlfilename = filename;
@ -1460,5 +1462,5 @@ void LevelMesh::Export(std::string filename)
#endif #endif
} }
printf("Export complete\n"); printf(" Export complete\n");
} }

View file

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