Add progress dots for CPU tracer and streamline how they look

This commit is contained in:
Magnus Norddahl 2021-11-16 00:57:06 +01:00
parent 4cb0f59f66
commit 95232aedf4
3 changed files with 115 additions and 42 deletions

View file

@ -10,6 +10,8 @@
#include <vector>
#include <algorithm>
#include <thread>
#include <condition_variable>
#include <atomic>
extern bool VKDebug;
extern int NumThreads;
@ -491,19 +493,43 @@ void CPURaytracer::RunJob(int count, std::function<void(int)> callback)
numThreads = std::min(numThreads, count);
std::condition_variable condvar;
std::mutex m;
int threadsleft = 0;
{
std::unique_lock<std::mutex> lock(m);
threadsleft = numThreads;
}
std::vector<std::thread> threads;
for (int threadIndex = 0; threadIndex < numThreads; threadIndex++)
{
threads.push_back(std::thread([=]() {
threads.push_back(std::thread([&]() {
for (int i = threadIndex; i < count; i += numThreads)
{
callback(i);
}
std::unique_lock<std::mutex> lock(m);
threadsleft--;
lock.unlock();
condvar.notify_all();
}));
}
{
std::unique_lock<std::mutex> lock(m);
while (threadsleft != 0)
{
condvar.wait_for(lock, std::chrono::milliseconds(500), [&]() { return threadsleft == 0; });
printf(".");
}
printf("\n");
}
for (int i = 0; i < numThreads; i++)
threads[i].join();
}

View file

@ -11,6 +11,8 @@
#include <vector>
#include <algorithm>
#include <limits>
#include <condition_variable>
#include <mutex>
#include "glsl_rgen_bounce.h"
#include "glsl_rgen_light.h"
#include "glsl_rchit_bounce.h"
@ -86,58 +88,60 @@ void GPURaytracer::Raytrace(LevelMesh* level)
printf("Ray tracing with %d bounce(s)\n", mesh->map->LightBounce);
size_t maxTasks = (size_t)rayTraceImageSize * rayTraceImageSize;
for (size_t startTask = 0; startTask < tasks.size(); startTask += maxTasks)
{
size_t numTasks = std::min(tasks.size() - startTask, maxTasks);
UploadTasks(tasks.data() + startTask, numTasks);
BeginTracing();
Uniforms uniforms = {};
uniforms.SampleDistance = (float)mesh->samples;
uniforms.LightCount = mesh->map->ThingLights.Size();
uniforms.SunDir = mesh->map->GetSunDirection();
uniforms.SunColor = mesh->map->GetSunColor();
uniforms.SunIntensity = 1.0f;
uniforms.PassType = 0;
uniforms.SampleIndex = 0;
uniforms.SampleCount = bounceSampleCount;
RunTrace(uniforms, rgenBounceRegion);
uniforms.SampleCount = coverageSampleCount;
RunTrace(uniforms, rgenLightRegion);
for (uint32_t i = 0; i < (uint32_t)bounceSampleCount; i++)
RunWithProgressDots([&]() {
size_t maxTasks = (size_t)rayTraceImageSize * rayTraceImageSize;
for (size_t startTask = 0; startTask < tasks.size(); startTask += maxTasks)
{
uniforms.PassType = 1;
uniforms.SampleIndex = i;
size_t numTasks = std::min(tasks.size() - startTask, maxTasks);
UploadTasks(tasks.data() + startTask, numTasks);
BeginTracing();
Uniforms uniforms = {};
uniforms.SampleDistance = (float)mesh->samples;
uniforms.LightCount = mesh->map->ThingLights.Size();
uniforms.SunDir = mesh->map->GetSunDirection();
uniforms.SunColor = mesh->map->GetSunColor();
uniforms.SunIntensity = 1.0f;
uniforms.PassType = 0;
uniforms.SampleIndex = 0;
uniforms.SampleCount = bounceSampleCount;
uniforms.HemisphereVec = HemisphereVectors[uniforms.SampleIndex];
RunTrace(uniforms, rgenBounceRegion);
for (int bounce = 0; bounce < mesh->map->LightBounce; bounce++)
{
uniforms.SampleCount = coverageSampleCount;
RunTrace(uniforms, rgenLightRegion);
uniforms.SampleCount = coverageSampleCount;
RunTrace(uniforms, rgenLightRegion);
uniforms.PassType = 2;
uniforms.SampleIndex = (i + bounce) % uniforms.SampleCount;
for (uint32_t i = 0; i < (uint32_t)bounceSampleCount; i++)
{
uniforms.PassType = 1;
uniforms.SampleIndex = i;
uniforms.SampleCount = bounceSampleCount;
uniforms.HemisphereVec = HemisphereVectors[uniforms.SampleIndex];
RunTrace(uniforms, rgenBounceRegion);
}
}
EndTracing();
DownloadTasks(tasks.data() + startTask, numTasks);
}
for (int bounce = 0; bounce < mesh->map->LightBounce; bounce++)
{
uniforms.SampleCount = coverageSampleCount;
RunTrace(uniforms, rgenLightRegion);
uniforms.PassType = 2;
uniforms.SampleIndex = (i + bounce) % uniforms.SampleCount;
uniforms.SampleCount = bounceSampleCount;
uniforms.HemisphereVec = HemisphereVectors[uniforms.SampleIndex];
RunTrace(uniforms, rgenBounceRegion);
}
}
EndTracing();
DownloadTasks(tasks.data() + startTask, numTasks);
}
});
if (device->renderdoc)
device->renderdoc->EndFrameCapture(0, 0);
printf("\nRaytrace complete\n");
printf("Raytrace complete\n");
}
void GPURaytracer::CreateVulkanObjects()
@ -264,7 +268,6 @@ void GPURaytracer::EndTracing()
cmdbuffer->end();
SubmitCommands();
printf(".");
cmdbuffer = cmdpool->createBuffer();
cmdbuffer->begin();
@ -929,3 +932,46 @@ float GPURaytracer::RadicalInverse_VdC(uint32_t bits)
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10f; // / 0x100000000
}
void GPURaytracer::RunWithProgressDots(std::function<void()> callback)
{
std::exception_ptr e;
std::condition_variable condvar;
std::mutex m;
bool stop;
{
std::unique_lock<std::mutex> lock(m);
stop = false;
}
std::thread t([&]() {
try
{
callback();
}
catch (...)
{
e = std::current_exception();
}
std::unique_lock<std::mutex> lock(m);
stop = true;
lock.unlock();
condvar.notify_all();
});
{
std::unique_lock<std::mutex> lock(m);
while (!stop)
{
condvar.wait_for(lock, std::chrono::milliseconds(500), [&]() { return stop; });
printf(".");
}
printf("\n");
}
t.join();
if (e)
std::rethrow_exception(e);
}

View file

@ -81,6 +81,8 @@ private:
static float RadicalInverse_VdC(uint32_t bits);
static vec2 Hammersley(uint32_t i, uint32_t N);
static void RunWithProgressDots(std::function<void()> callback);
const int coverageSampleCount = 256;
const int bounceSampleCount = 2048;
int rayTraceImageSize = 1024;
@ -139,5 +141,4 @@ private:
std::unique_ptr<VulkanCommandPool> cmdpool;
std::unique_ptr<VulkanCommandBuffer> cmdbuffer;
};