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();
primitiveLayout->reset();
@@ -132,6 +132,7 @@ void BasePass::beginFrame()
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
co_return;
}
MainJob BasePass::render()
@@ -161,8 +162,9 @@ MainJob BasePass::render()
graphics->endRenderPass();
}
void BasePass::endFrame()
MainJob BasePass::endFrame()
{
co_return;
}
void BasePass::publishOutputs()
+2 -2
View File
@@ -37,9 +37,9 @@ class BasePass : public RenderPass<BasePassData>
public:
BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
virtual ~BasePass();
virtual void beginFrame() override;
virtual MainJob beginFrame() override;
virtual MainJob render() override;
virtual void endFrame() override;
virtual MainJob endFrame() override;
virtual void publishOutputs() override;
virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
@@ -93,7 +93,7 @@ DepthPrepass::~DepthPrepass()
{
}
void DepthPrepass::beginFrame()
MainJob DepthPrepass::beginFrame()
{
processor->clearCommands();
primitiveLayout->reset();
@@ -111,6 +111,7 @@ void DepthPrepass::beginFrame()
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
co_return;
}
MainJob DepthPrepass::render()
@@ -130,8 +131,9 @@ MainJob DepthPrepass::render()
graphics->endRenderPass();
}
void DepthPrepass::endFrame()
MainJob DepthPrepass::endFrame()
{
co_return;
}
void DepthPrepass::publishOutputs()
@@ -36,9 +36,9 @@ class DepthPrepass : public RenderPass<DepthPrepassData>
public:
DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
~DepthPrepass();
virtual void beginFrame() override;
virtual MainJob beginFrame() override;
virtual MainJob render() override;
virtual void endFrame() override;
virtual MainJob endFrame() override;
virtual void publishOutputs() override;
virtual void createRenderPass() override;
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 viewportHeight = viewport->getSizeY();
@@ -75,6 +75,7 @@ void LightCullingPass::beginFrame()
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer);
lightEnvDescriptorSet->writeChanges();
co_return;
}
MainJob LightCullingPass::render()
@@ -104,8 +105,9 @@ MainJob LightCullingPass::render()
co_return;
}
void LightCullingPass::endFrame()
MainJob LightCullingPass::endFrame()
{
co_return;
}
void LightCullingPass::publishOutputs()
@@ -18,9 +18,9 @@ class LightCullingPass : public RenderPass<LightCullingPassData>
public:
LightCullingPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera);
virtual ~LightCullingPass();
virtual void beginFrame() override;
virtual MainJob beginFrame() override;
virtual MainJob render() override;
virtual void endFrame() override;
virtual MainJob endFrame() override;
virtual void publishOutputs() override;
virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
+2 -2
View File
@@ -22,9 +22,9 @@ public:
void updateViewFrame(RenderPassDataType viewFrame) {
passData = std::move(viewFrame);
}
virtual void beginFrame() = 0;
virtual MainJob beginFrame() = 0;
virtual MainJob render() = 0;
virtual void endFrame() = 0;
virtual MainJob endFrame() = 0;
virtual void publishOutputs() = 0;
virtual void createRenderPass() = 0;
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()
@@ -31,8 +32,9 @@ MainJob UIPass::render()
co_return;
}
void UIPass::endFrame()
MainJob UIPass::endFrame()
{
co_return;
}
void UIPass::publishOutputs()
+2 -2
View File
@@ -16,9 +16,9 @@ class UIPass : public RenderPass<UIPassData>
public:
UIPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, Gfx::PRenderTargetAttachment renderTarget);
virtual ~UIPass();
virtual void beginFrame() override;
virtual MainJob beginFrame() override;
virtual MainJob render() override;
virtual void endFrame() override;
virtual MainJob endFrame() override;
virtual void publishOutputs() override;
virtual void createRenderPass() override;
private:
@@ -236,7 +236,7 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &l
{
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
@@ -280,6 +280,10 @@ void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorS
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())
{
// Currently in use, skip
@@ -308,6 +312,10 @@ void DescriptorAllocator::reset()
{
for(uint32 i = 0; i < cachedHandles.size(); ++i)
{
if(cachedHandles[i] == nullptr)
{
return;
}
cachedHandles[i]->free();
}
}
@@ -142,7 +142,7 @@ public:
private:
PGraphics graphics;
DescriptorLayout &layout;
const static int maxSets = 512;
const static int maxSets = 64;
StaticArray<PDescriptorSet, maxSets> cachedHandles;
VkDescriptorPool poolHandle;
};
+1
View File
@@ -3,6 +3,7 @@
using namespace Seele;
Event::Event()
: flag(new std::atomic_bool())
{}
+37 -19
View File
@@ -3,6 +3,7 @@
#include <coroutine>
#include "MinimalEngine.h"
#include "Containers/List.h"
#include "Concepts.h"
namespace Seele
{
@@ -10,12 +11,14 @@ extern class ThreadPool& getGlobalThreadPool();
template<bool MainJob>
struct JobBase;
struct Event;
static std::atomic_uint64_t globalCounter;
template<bool MainJob>
struct JobPromiseBase
{
JobBase<MainJob> get_return_object() noexcept;
inline auto initial_suspend() const noexcept;
inline auto initial_suspend() noexcept;
inline auto final_suspend() const noexcept;
void return_void() noexcept {}
@@ -23,7 +26,9 @@ struct JobPromiseBase
std::cerr << "Unhandled exception" << std::endl;
exit(1);
};
std::coroutine_handle<> continuation;
std::coroutine_handle<> continuation = std::noop_coroutine();
uint64 id;
Event finishedEvent;
};
struct Event
@@ -57,9 +62,7 @@ private:
friend class ThreadPool;
};
static std::atomic_uint64_t globalCounter;
template<bool MainJob>
template<bool MainJob = false>
struct JobBase
{
public:
@@ -67,16 +70,18 @@ public:
explicit JobBase()
: id(-1)
{}
explicit JobBase(std::coroutine_handle<promise_type> handle)
{
}
explicit JobBase(std::coroutine_handle<promise_type> handle, uint64 id, Event finishedEvent)
: handle(handle)
, id(globalCounter++)
, event(std::format("Job {}", id))
, event(std::move(finishedEvent))
, id(id)
{
}
JobBase(const JobBase & rhs) = delete;
JobBase(JobBase&& rhs)
: handle(std::move(rhs.handle))
, event(rhs.event)
, id(std::move(rhs.id))
{
rhs.id = -1;
@@ -86,6 +91,7 @@ public:
{
if(handle && handle.done())
{
std::cout << "Destroy job " << handle.address() << std::endl;
handle.destroy();
}
}
@@ -95,6 +101,7 @@ public:
if(this != &rhs)
{
handle = std::move(rhs.handle);
event = std::move(rhs.event);
id = std::move(rhs.id);
rhs.id = -1;
rhs.handle = nullptr;
@@ -105,9 +112,15 @@ public:
{
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;
return continuation;
}
bool done()
{
@@ -125,12 +138,13 @@ public:
{
return event;
}
static JobBase all() = delete;
template<typename... Awaitable>
static JobBase all(Awaitable... jobs)
{
co_await jobs;
(co_await jobs, ...);
}
template<typename Iterable>
template<iterable Iterable>
static JobBase all(Iterable&& collection)
{
for(auto&& it : collection)
@@ -138,7 +152,7 @@ public:
co_await it;
}
}
template<typename JobFunc, typename IterableParams>
template<std::invocable JobFunc, iterable IterableParams>
static JobBase launchJobs(JobFunc&& func, IterableParams params)
{
List<JobBase> jobs;
@@ -194,23 +208,27 @@ private:
template<bool MainJob>
inline JobBase<MainJob> JobPromiseBase<MainJob>::get_return_object() noexcept {
return JobBase<MainJob>();
inline JobBase<MainJob> JobPromiseBase<MainJob>::get_return_object() noexcept
{
id = globalCounter++;
return JobBase<MainJob>(std::coroutine_handle<JobPromiseBase<MainJob>>::from_promise(*this), id, finishedEvent);
}
template<bool MainJob>
inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept
inline auto JobPromiseBase<MainJob>::initial_suspend() noexcept
{
struct JobAwaitable
{
constexpr bool await_ready() { return false; }
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() {}
uint64 id;
Event& event;
};
return JobAwaitable{};
return JobAwaitable{id, finishedEvent};
}
template<bool MainJob>
inline auto JobPromiseBase<MainJob>::final_suspend() const noexcept
@@ -230,7 +248,7 @@ inline auto JobPromiseBase<MainJob>::final_suspend() const noexcept
template<bool MainJob>
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
+8 -6
View File
@@ -40,12 +40,14 @@ void InspectorView::prepareRender()
MainJob InspectorView::render()
{
uiPass.beginFrame();
uiPass.render();
uiPass.endFrame();
renderFinishedEvent.raise();
co_return;
return uiPass.beginFrame()
.then(uiPass.render())
.then(uiPass.endFrame())
.then([=]() -> MainJob
{
renderFinishedEvent.raise();
co_return;
});
}
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier)
+14 -14
View File
@@ -84,20 +84,20 @@ void SceneView::prepareRender()
MainJob SceneView::render()
{
depthPrepass.beginFrame();
lightCullingPass.beginFrame();
basePass.beginFrame();
depthPrepass.render();
lightCullingPass.render();
basePass.render();
depthPrepass.endFrame();
lightCullingPass.endFrame();
basePass.endFrame();
renderFinishedEvent.raise();
co_return;
return depthPrepass.beginFrame()
.then(lightCullingPass.beginFrame())
.then(basePass.beginFrame())
.then(depthPrepass.render())
.then(lightCullingPass.render())
.then(basePass.render())
.then(depthPrepass.endFrame())
.then(lightCullingPass.endFrame())
.then(basePass.endFrame())
.then([=]() -> MainJob
{
renderFinishedEvent.raise();
co_return;
});
}
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier)
+4 -1
View File
@@ -5,7 +5,10 @@
using namespace Seele;
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);
}