Refactoring jobs

This commit is contained in:
Dynamitos
2021-12-09 12:38:02 +01:00
parent 9e3a2446ce
commit f4ce5f9585
17 changed files with 113 additions and 60 deletions
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include <concepts>
namespace Seele
{
template<typename A>
concept iterable = requires(A&& a)
{
a.begin(); a.end();
};
template<class F, class... Args>
concept invocable = std::invocable<F, Args...>;
}
+4 -2
View File
@@ -112,7 +112,7 @@ BasePass::~BasePass()
{ {
} }
void BasePass::beginFrame() MainJob BasePass::beginFrame()
{ {
processor->clearCommands(); processor->clearCommands();
primitiveLayout->reset(); primitiveLayout->reset();
@@ -132,6 +132,7 @@ void BasePass::beginFrame()
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet(); descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
co_return;
} }
MainJob BasePass::render() MainJob BasePass::render()
@@ -161,8 +162,9 @@ MainJob BasePass::render()
graphics->endRenderPass(); graphics->endRenderPass();
} }
void BasePass::endFrame() MainJob BasePass::endFrame()
{ {
co_return;
} }
void BasePass::publishOutputs() void BasePass::publishOutputs()
+2 -2
View File
@@ -37,9 +37,9 @@ class BasePass : public RenderPass<BasePassData>
public: public:
BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source); BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
virtual ~BasePass(); virtual ~BasePass();
virtual void beginFrame() override; virtual MainJob beginFrame() override;
virtual MainJob render() override; virtual MainJob render() override;
virtual void endFrame() override; virtual MainJob endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines); static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
@@ -93,7 +93,7 @@ DepthPrepass::~DepthPrepass()
{ {
} }
void DepthPrepass::beginFrame() MainJob DepthPrepass::beginFrame()
{ {
processor->clearCommands(); processor->clearCommands();
primitiveLayout->reset(); primitiveLayout->reset();
@@ -111,6 +111,7 @@ void DepthPrepass::beginFrame()
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet(); descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
co_return;
} }
MainJob DepthPrepass::render() MainJob DepthPrepass::render()
@@ -130,8 +131,9 @@ MainJob DepthPrepass::render()
graphics->endRenderPass(); graphics->endRenderPass();
} }
void DepthPrepass::endFrame() MainJob DepthPrepass::endFrame()
{ {
co_return;
} }
void DepthPrepass::publishOutputs() void DepthPrepass::publishOutputs()
@@ -36,9 +36,9 @@ class DepthPrepass : public RenderPass<DepthPrepassData>
public: public:
DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source); DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
~DepthPrepass(); ~DepthPrepass();
virtual void beginFrame() override; virtual MainJob beginFrame() override;
virtual MainJob render() override; virtual MainJob render() override;
virtual void endFrame() override; virtual MainJob endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines); static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
@@ -18,7 +18,7 @@ LightCullingPass::~LightCullingPass()
} }
void LightCullingPass::beginFrame() MainJob LightCullingPass::beginFrame()
{ {
uint32_t viewportWidth = viewport->getSizeX(); uint32_t viewportWidth = viewport->getSizeX();
uint32_t viewportHeight = viewport->getSizeY(); uint32_t viewportHeight = viewport->getSizeY();
@@ -75,6 +75,7 @@ void LightCullingPass::beginFrame()
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer); lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer); lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer);
lightEnvDescriptorSet->writeChanges(); lightEnvDescriptorSet->writeChanges();
co_return;
} }
MainJob LightCullingPass::render() MainJob LightCullingPass::render()
@@ -104,8 +105,9 @@ MainJob LightCullingPass::render()
co_return; co_return;
} }
void LightCullingPass::endFrame() MainJob LightCullingPass::endFrame()
{ {
co_return;
} }
void LightCullingPass::publishOutputs() void LightCullingPass::publishOutputs()
@@ -18,9 +18,9 @@ class LightCullingPass : public RenderPass<LightCullingPassData>
public: public:
LightCullingPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera); LightCullingPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera);
virtual ~LightCullingPass(); virtual ~LightCullingPass();
virtual void beginFrame() override; virtual MainJob beginFrame() override;
virtual MainJob render() override; virtual MainJob render() override;
virtual void endFrame() override; virtual MainJob endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines); static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
+2 -2
View File
@@ -22,9 +22,9 @@ public:
void updateViewFrame(RenderPassDataType viewFrame) { void updateViewFrame(RenderPassDataType viewFrame) {
passData = std::move(viewFrame); passData = std::move(viewFrame);
} }
virtual void beginFrame() = 0; virtual MainJob beginFrame() = 0;
virtual MainJob render() = 0; virtual MainJob render() = 0;
virtual void endFrame() = 0; virtual MainJob endFrame() = 0;
virtual void publishOutputs() = 0; virtual void publishOutputs() = 0;
virtual void createRenderPass() = 0; virtual void createRenderPass() = 0;
void setResources(PRenderGraphResources resources) { this->resources = resources; } void setResources(PRenderGraphResources resources) { this->resources = resources; }
+4 -2
View File
@@ -15,8 +15,9 @@ UIPass::~UIPass()
} }
void UIPass::beginFrame() MainJob UIPass::beginFrame()
{ {
co_return;
} }
MainJob UIPass::render() MainJob UIPass::render()
@@ -31,8 +32,9 @@ MainJob UIPass::render()
co_return; co_return;
} }
void UIPass::endFrame() MainJob UIPass::endFrame()
{ {
co_return;
} }
void UIPass::publishOutputs() void UIPass::publishOutputs()
+2 -2
View File
@@ -16,9 +16,9 @@ class UIPass : public RenderPass<UIPassData>
public: public:
UIPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, Gfx::PRenderTargetAttachment renderTarget); UIPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, Gfx::PRenderTargetAttachment renderTarget);
virtual ~UIPass(); virtual ~UIPass();
virtual void beginFrame() override; virtual MainJob beginFrame() override;
virtual MainJob render() override; virtual MainJob render() override;
virtual void endFrame() override; virtual MainJob endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
private: private:
@@ -236,7 +236,7 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &l
{ {
for(uint32 i = 0; i < cachedHandles.size(); ++i) for(uint32 i = 0; i < cachedHandles.size(); ++i)
{ {
cachedHandles[i] = new DescriptorSet(graphics, this); cachedHandles[i] = nullptr;
} }
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM
@@ -280,6 +280,10 @@ void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorS
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
{ {
if(cachedHandles[setIndex] == nullptr)
{
cachedHandles[setIndex] = new DescriptorSet(graphics, this);
}
if(cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) if(cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse())
{ {
// Currently in use, skip // Currently in use, skip
@@ -308,6 +312,10 @@ void DescriptorAllocator::reset()
{ {
for(uint32 i = 0; i < cachedHandles.size(); ++i) for(uint32 i = 0; i < cachedHandles.size(); ++i)
{ {
if(cachedHandles[i] == nullptr)
{
return;
}
cachedHandles[i]->free(); cachedHandles[i]->free();
} }
} }
@@ -142,7 +142,7 @@ public:
private: private:
PGraphics graphics; PGraphics graphics;
DescriptorLayout &layout; DescriptorLayout &layout;
const static int maxSets = 512; const static int maxSets = 64;
StaticArray<PDescriptorSet, maxSets> cachedHandles; StaticArray<PDescriptorSet, maxSets> cachedHandles;
VkDescriptorPool poolHandle; VkDescriptorPool poolHandle;
}; };
+1
View File
@@ -3,6 +3,7 @@
using namespace Seele; using namespace Seele;
Event::Event() Event::Event()
: flag(new std::atomic_bool()) : flag(new std::atomic_bool())
{} {}
+37 -19
View File
@@ -3,6 +3,7 @@
#include <coroutine> #include <coroutine>
#include "MinimalEngine.h" #include "MinimalEngine.h"
#include "Containers/List.h" #include "Containers/List.h"
#include "Concepts.h"
namespace Seele namespace Seele
{ {
@@ -10,12 +11,14 @@ extern class ThreadPool& getGlobalThreadPool();
template<bool MainJob> template<bool MainJob>
struct JobBase; struct JobBase;
struct Event;
static std::atomic_uint64_t globalCounter;
template<bool MainJob> template<bool MainJob>
struct JobPromiseBase struct JobPromiseBase
{ {
JobBase<MainJob> get_return_object() noexcept; JobBase<MainJob> get_return_object() noexcept;
inline auto initial_suspend() const noexcept; inline auto initial_suspend() noexcept;
inline auto final_suspend() const noexcept; inline auto final_suspend() const noexcept;
void return_void() noexcept {} void return_void() noexcept {}
@@ -23,7 +26,9 @@ struct JobPromiseBase
std::cerr << "Unhandled exception" << std::endl; std::cerr << "Unhandled exception" << std::endl;
exit(1); exit(1);
}; };
std::coroutine_handle<> continuation; std::coroutine_handle<> continuation = std::noop_coroutine();
uint64 id;
Event finishedEvent;
}; };
struct Event struct Event
@@ -57,9 +62,7 @@ private:
friend class ThreadPool; friend class ThreadPool;
}; };
template<bool MainJob = false>
static std::atomic_uint64_t globalCounter;
template<bool MainJob>
struct JobBase struct JobBase
{ {
public: public:
@@ -67,16 +70,18 @@ public:
explicit JobBase() explicit JobBase()
: id(-1) : id(-1)
{} {
explicit JobBase(std::coroutine_handle<promise_type> handle) }
explicit JobBase(std::coroutine_handle<promise_type> handle, uint64 id, Event finishedEvent)
: handle(handle) : handle(handle)
, id(globalCounter++) , event(std::move(finishedEvent))
, event(std::format("Job {}", id)) , id(id)
{ {
} }
JobBase(const JobBase & rhs) = delete; JobBase(const JobBase & rhs) = delete;
JobBase(JobBase&& rhs) JobBase(JobBase&& rhs)
: handle(std::move(rhs.handle)) : handle(std::move(rhs.handle))
, event(rhs.event)
, id(std::move(rhs.id)) , id(std::move(rhs.id))
{ {
rhs.id = -1; rhs.id = -1;
@@ -86,6 +91,7 @@ public:
{ {
if(handle && handle.done()) if(handle && handle.done())
{ {
std::cout << "Destroy job " << handle.address() << std::endl;
handle.destroy(); handle.destroy();
} }
} }
@@ -95,6 +101,7 @@ public:
if(this != &rhs) if(this != &rhs)
{ {
handle = std::move(rhs.handle); handle = std::move(rhs.handle);
event = std::move(rhs.event);
id = std::move(rhs.id); id = std::move(rhs.id);
rhs.id = -1; rhs.id = -1;
rhs.handle = nullptr; rhs.handle = nullptr;
@@ -105,9 +112,15 @@ public:
{ {
handle.resume(); handle.resume();
} }
void then(JobBase continuation) template<std::invocable Callable>
inline JobBase then(Callable callable)
{
return then(callable());
}
JobBase then(JobBase continuation)
{ {
handle.promise().continuation = continuation.handle; handle.promise().continuation = continuation.handle;
return continuation;
} }
bool done() bool done()
{ {
@@ -125,12 +138,13 @@ public:
{ {
return event; return event;
} }
static JobBase all() = delete;
template<typename... Awaitable> template<typename... Awaitable>
static JobBase all(Awaitable... jobs) static JobBase all(Awaitable... jobs)
{ {
co_await jobs; (co_await jobs, ...);
} }
template<typename Iterable> template<iterable Iterable>
static JobBase all(Iterable&& collection) static JobBase all(Iterable&& collection)
{ {
for(auto&& it : collection) for(auto&& it : collection)
@@ -138,7 +152,7 @@ public:
co_await it; co_await it;
} }
} }
template<typename JobFunc, typename IterableParams> template<std::invocable JobFunc, iterable IterableParams>
static JobBase launchJobs(JobFunc&& func, IterableParams params) static JobBase launchJobs(JobFunc&& func, IterableParams params)
{ {
List<JobBase> jobs; List<JobBase> jobs;
@@ -194,23 +208,27 @@ private:
template<bool MainJob> template<bool MainJob>
inline JobBase<MainJob> JobPromiseBase<MainJob>::get_return_object() noexcept { inline JobBase<MainJob> JobPromiseBase<MainJob>::get_return_object() noexcept
return JobBase<MainJob>(); {
id = globalCounter++;
return JobBase<MainJob>(std::coroutine_handle<JobPromiseBase<MainJob>>::from_promise(*this), id, finishedEvent);
} }
template<bool MainJob> template<bool MainJob>
inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept inline auto JobPromiseBase<MainJob>::initial_suspend() noexcept
{ {
struct JobAwaitable struct JobAwaitable
{ {
constexpr bool await_ready() { return false; } constexpr bool await_ready() { return false; }
constexpr void await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h) constexpr void await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
{ {
getGlobalThreadPool().addJob(std::move(JobBase<MainJob>(h))); getGlobalThreadPool().addJob(std::move(JobBase<MainJob>(h, id, event)));
} }
constexpr void await_resume() {} constexpr void await_resume() {}
uint64 id;
Event& event;
}; };
return JobAwaitable{}; return JobAwaitable{id, finishedEvent};
} }
template<bool MainJob> template<bool MainJob>
inline auto JobPromiseBase<MainJob>::final_suspend() const noexcept inline auto JobPromiseBase<MainJob>::final_suspend() const noexcept
@@ -230,7 +248,7 @@ inline auto JobPromiseBase<MainJob>::final_suspend() const noexcept
template<bool MainJob> template<bool MainJob>
inline constexpr void Event::await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h) inline constexpr void Event::await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
{ {
getGlobalThreadPool().enqueueWaiting(*this, std::move(JobBase<MainJob>(h))); getGlobalThreadPool().enqueueWaiting(*this, std::move(JobBase<MainJob>(h, h.promise().id, *this)));
} }
} // namespace Seele } // namespace Seele
+6 -4
View File
@@ -40,12 +40,14 @@ void InspectorView::prepareRender()
MainJob InspectorView::render() MainJob InspectorView::render()
{ {
uiPass.beginFrame(); return uiPass.beginFrame()
uiPass.render(); .then(uiPass.render())
uiPass.endFrame(); .then(uiPass.endFrame())
.then([=]() -> MainJob
{
renderFinishedEvent.raise(); renderFinishedEvent.raise();
co_return; co_return;
});
} }
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier) void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier)
+12 -12
View File
@@ -84,20 +84,20 @@ void SceneView::prepareRender()
MainJob SceneView::render() MainJob SceneView::render()
{ {
depthPrepass.beginFrame(); return depthPrepass.beginFrame()
lightCullingPass.beginFrame(); .then(lightCullingPass.beginFrame())
basePass.beginFrame(); .then(basePass.beginFrame())
.then(depthPrepass.render())
depthPrepass.render(); .then(lightCullingPass.render())
lightCullingPass.render(); .then(basePass.render())
basePass.render(); .then(depthPrepass.endFrame())
.then(lightCullingPass.endFrame())
depthPrepass.endFrame(); .then(basePass.endFrame())
lightCullingPass.endFrame(); .then([=]() -> MainJob
basePass.endFrame(); {
renderFinishedEvent.raise(); renderFinishedEvent.raise();
co_return; co_return;
});
} }
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier) void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier)
+4 -1
View File
@@ -5,7 +5,10 @@
using namespace Seele; using namespace Seele;
View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &viewportInfo, std::string name) View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &viewportInfo, std::string name)
: graphics(graphics), owner(window), name(name) : graphics(graphics)
, owner(window)
, name(name)
, renderFinishedEvent(name + "RenderFinished")
{ {
viewport = graphics->createViewport(owner->getGfxHandle(), viewportInfo); viewport = graphics->createViewport(owner->getGfxHandle(), viewportInfo);
} }