diff --git a/src/ThreadPool.cpp b/src/ThreadPool.cpp index 7a3f3e4..cd1fe4e 100644 --- a/src/ThreadPool.cpp +++ b/src/ThreadPool.cpp @@ -16,25 +16,23 @@ ThreadPool::~ThreadPool() std::unique_lock l(queueLock); queueCV.notify_all(); } - for(auto& worker : workers) + for (auto& worker : workers) { worker.join(); } } -void ThreadPool::addJob(std::function&& job) +void ThreadPool::runBatch(Batch&& batch) { - std::unique_lock l(queueLock); - taskQueue.push_back(job); - queueCV.notify_one(); -} - -void ThreadPool::waitIdle() -{ - while(true) { std::unique_lock l(queueLock); - if(taskQueue.empty()) + taskQueue.push_back(batch); + queueCV.notify_one(); + } + while (true) + { + std::unique_lock l(queueLock); + if (taskQueue.empty()) return; completedCV.wait(l); } @@ -42,24 +40,27 @@ void ThreadPool::waitIdle() void ThreadPool::work() { - while(running) + while (running) { std::function job; { std::unique_lock l(queueLock); - if(taskQueue.empty()) + if (taskQueue.front().jobs.empty()) { queueCV.wait(l); continue; } - job = taskQueue.front(); - taskQueue.pop_front(); + job = taskQueue.front().jobs.front(); + taskQueue.front().jobs.pop_front(); } job(); { std::unique_lock l(queueLock); - completedCV.notify_one(); + if (taskQueue.front().jobs.empty()) + { + taskQueue.pop_front(); + completedCV.notify_one(); + } } } } - diff --git a/src/ThreadPool.h b/src/ThreadPool.h index 1aaea19..dba5b67 100644 --- a/src/ThreadPool.h +++ b/src/ThreadPool.h @@ -4,19 +4,23 @@ #include #include +struct Batch +{ + std::list> jobs; +}; + class ThreadPool { public: ThreadPool(uint32_t numWorkers = std::thread::hardware_concurrency()); ~ThreadPool(); - void addJob(std::function&& job); - void waitIdle(); + void runBatch(Batch&& batch); private: std::atomic_bool running = true; void work(); std::mutex queueLock; std::condition_variable queueCV; std::condition_variable completedCV; - std::list> taskQueue; + std::list taskQueue; std::vector workers; }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 5a219d4..88dfbe4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,18 +1,24 @@ #include "scene/BVH.h" +#include "scene/Scene.h" #include "util/ModelLoader.h" #include "window/Window.h" int main() { Scene scene; - Window window; + Window window(1920, 1080); + scene.render( + Camera{ + .position = glm::vec3(10, 0, 0), + .direction = glm::vec3(-1, 0, 0), + }, + RenderParameter{ + .width = 1920, + .height = 1080, + .numSamples = 10000, + }); while (true) { - // IMGUI.... - if (Imgui.Button()) - { - scene.render(); - } window.update(scene.getImage()); } return 0; diff --git a/src/scene/Scene.cpp b/src/scene/Scene.cpp index 355dbd1..64a58d2 100644 --- a/src/scene/Scene.cpp +++ b/src/scene/Scene.cpp @@ -1,34 +1,40 @@ #include "Scene.h" -Scene::Scene(glm::vec3 cameraPos, glm::vec3 cameraDirection) : cameraPos(cameraPos), cameraDirection(cameraDirection) {} +Scene::Scene() {} Scene::~Scene() {} -void Scene::render(int width, int height, int numSamples) +void Scene::render(Camera cam, RenderParameter params) { + pendingCancel = true; + worker.join(); + pendingCancel = false; worker = std::thread( [&]() { image.clear(); accumulator.clear(); - image.resize(width * height * 3); - for (int samp = 0; samp < numSamples; ++samp) + image.resize(params.width * params.height * 3); + accumulator.resize(params.width * params.height * 3); + for (int samp = 0; samp < params.numSamples; ++samp) { - std::function job = [&]() + if (pendingCancel) + return; + Batch batch; + for (int w = 0; w < params.width; ++w) { - std::vector localAccumulator(width * height * 3); - for (int w = 0; w < width; ++w) + for (int h = 0; h < params.height; ++h) { - for (int h = 0; h < height; ++h) - { - if (cancel) - return; - bvh.traceRay(); - } + batch.jobs.push_back( + [&]() + { + Ray r = Ray(); + bvh.traceRay(r); + }); } - // lock image - // add result to image - }; + } + threadPool.runBatch(std::move(batch)); + std::memcpy(image.data(), accumulator.data(), accumulator.size()); } }); } diff --git a/src/scene/Scene.h b/src/scene/Scene.h index 9b517ec..24dde72 100644 --- a/src/scene/Scene.h +++ b/src/scene/Scene.h @@ -2,26 +2,26 @@ #include "BVH.h" #include "window/Window.h" #include "util/Camera.h" +#include "ThreadPool.h" + +struct RenderParameter +{ + int width; + int height; + int numSamples; +}; -/// -/// Ray1 -/// Ray2 -/// Ray3 -/// Ray4 -/// Ray5 -/// GammaResolve -/// Ray1 -/// Ray2 -/// Ray3 -/// class Scene { public: Scene(); ~Scene(); - void render(Camera cam, int width, int height, int numSamples); + void render(Camera cam, RenderParameter params); constexpr const std::vector& getImage() const { return image; } private: + std::atomic_bool pendingCancel = false; + ThreadPool threadPool; + std::thread worker; // the thing being displayed std::vector image; // radiance accumulator