Async render passes

This commit is contained in:
2021-11-24 12:10:23 +01:00
parent 94be513538
commit 5fafdda770
23 changed files with 199 additions and 162 deletions
+1 -3
View File
@@ -30,15 +30,13 @@
"UNICODE", "UNICODE",
"_UNICODE" "_UNICODE"
], ],
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.cmake-tools", "configurationProvider": "ms-vscode.cmake-tools",
"cppStandard": "c++20", "cppStandard": "c++20",
"browse": { "browse": {
"path": [ "path": [
"external/**" "external/**"
] ]
}, }
"compilerPath": "/usr/bin/g++"
} }
], ],
"version": 4 "version": 4
-1
View File
@@ -15,7 +15,6 @@
"console": "internalConsole", "console": "internalConsole",
"environment": [], "environment": [],
"externalConsole": false, "externalConsole": false,
"MIMode": "gdb",
"setupCommands": [ "setupCommands": [
{ {
"description": "Enable break on all exceptions", "description": "Enable break on all exceptions",
+3 -2
View File
@@ -208,9 +208,10 @@ public:
deallocateNode(tmp->prev); deallocateNode(tmp->prev);
} }
deallocateNode(tail); deallocateNode(tail);
markIteratorDirty();
tail = nullptr; tail = nullptr;
root = nullptr; root = nullptr;
markIteratorDirty();
_size = 0;
} }
//Insert at the end //Insert at the end
iterator add(const T &value) iterator add(const T &value)
@@ -291,7 +292,7 @@ public:
{ {
value_type temp = std::move(root->data); value_type temp = std::move(root->data);
popFront(); popFront();
return std::move(temp); return temp;
} }
iterator remove(iterator pos) iterator remove(iterator pos)
{ {
+18 -8
View File
@@ -20,13 +20,13 @@ BasePassMeshProcessor::~BasePassMeshProcessor()
{ {
} }
void BasePassMeshProcessor::addMeshBatch( Job BasePassMeshProcessor::processMeshBatch(
const MeshBatch& batch, const MeshBatch& batch,
// const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass& renderPass,
Gfx::PPipelineLayout pipelineLayout, Gfx::PPipelineLayout pipelineLayout,
Gfx::PDescriptorLayout primitiveLayout, Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet>& descriptorSets, Array<Gfx::PDescriptorSet> descriptorSets,
int32 /*staticMeshId*/) int32 /*staticMeshId*/)
{ {
PMaterialAsset material = batch.material; PMaterialAsset material = batch.material;
@@ -34,11 +34,12 @@ void BasePassMeshProcessor::addMeshBatch(
const PVertexShaderInput vertexInput = batch.vertexInput; const PVertexShaderInput vertexInput = batch.vertexInput;
const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType()); const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType());
assert(collection != nullptr); assert(collection != nullptr);
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand(); Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
renderCommand->setViewport(target); renderCommand->setViewport(target);
pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout()); pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout());
pipelineLayout->create(); pipelineLayout->create();
Gfx::PDescriptorSet materialSet = material->createDescriptorSet(); Gfx::PDescriptorSet materialSet = material->createDescriptorSet();
@@ -63,6 +64,7 @@ void BasePassMeshProcessor::addMeshBatch(
false); false);
} }
renderCommands.add(renderCommand); renderCommands.add(renderCommand);
co_return;
} }
Array<Gfx::PRenderCommand> BasePassMeshProcessor::getRenderCommands() Array<Gfx::PRenderCommand> BasePassMeshProcessor::getRenderCommands()
@@ -120,7 +122,7 @@ BasePass::~BasePass()
{ {
} }
void BasePass::beginFrame() Job BasePass::beginFrame()
{ {
processor->clearCommands(); processor->clearCommands();
primitiveLayout->reset(); primitiveLayout->reset();
@@ -140,9 +142,10 @@ 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;
} }
void BasePass::render() Job BasePass::render()
{ {
oLightIndexList->pipelineBarrier( oLightIndexList->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
@@ -159,16 +162,23 @@ void BasePass::render()
descriptorSets[INDEX_LIGHT_ENV]->updateTexture(5, oLightGrid); descriptorSets[INDEX_LIGHT_ENV]->updateTexture(5, oLightGrid);
descriptorSets[INDEX_LIGHT_ENV]->writeChanges(); descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
List<Job> jobs;
for (auto &&meshBatch : passData.staticDrawList) for (auto &&meshBatch : passData.staticDrawList)
{ {
processor->addMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets); jobs.add(processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets));
}
for(auto& job : jobs)
{
co_await job;
} }
graphics->executeCommands(processor->getRenderCommands()); graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass(); graphics->endRenderPass();
co_return;
} }
void BasePass::endFrame() Job BasePass::endFrame()
{ {
co_return;
} }
void BasePass::publishOutputs() void BasePass::publishOutputs()
+6 -6
View File
@@ -11,13 +11,13 @@ public:
BasePassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass); BasePassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass);
virtual ~BasePassMeshProcessor(); virtual ~BasePassMeshProcessor();
virtual void addMeshBatch( virtual Job processMeshBatch(
const MeshBatch& batch, const MeshBatch& batch,
// const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass& renderPass,
Gfx::PPipelineLayout pipelineLayout, Gfx::PPipelineLayout pipelineLayout,
Gfx::PDescriptorLayout primitiveLayout, Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet>& descriptorSets, Array<Gfx::PDescriptorSet> descriptorSets,
int32 staticMeshId = -1) override; int32 staticMeshId = -1) override;
Array<Gfx::PRenderCommand> getRenderCommands(); Array<Gfx::PRenderCommand> getRenderCommands();
void clearCommands(); void clearCommands();
@@ -40,9 +40,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 Job beginFrame() override;
virtual void render() override; virtual Job render() override;
virtual void endFrame() override; virtual Job 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,13 +18,13 @@ DepthPrepassMeshProcessor::~DepthPrepassMeshProcessor()
{ {
} }
void DepthPrepassMeshProcessor::addMeshBatch( Job DepthPrepassMeshProcessor::processMeshBatch(
const MeshBatch& batch, const MeshBatch& batch,
// const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass& renderPass,
Gfx::PPipelineLayout pipelineLayout, Gfx::PPipelineLayout pipelineLayout,
Gfx::PDescriptorLayout primitiveLayout, Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet>& descriptorSets, Array<Gfx::PDescriptorSet> descriptorSets,
int32 /*staticMeshId*/) int32 /*staticMeshId*/)
{ {
PMaterialAsset material = batch.material; PMaterialAsset material = batch.material;
@@ -61,6 +61,7 @@ void DepthPrepassMeshProcessor::addMeshBatch(
true); true);
} }
renderCommands.add(renderCommand); renderCommands.add(renderCommand);
co_return;
} }
Array<Gfx::PRenderCommand> DepthPrepassMeshProcessor::getRenderCommands() Array<Gfx::PRenderCommand> DepthPrepassMeshProcessor::getRenderCommands()
@@ -104,7 +105,7 @@ DepthPrepass::~DepthPrepass()
{ {
} }
void DepthPrepass::beginFrame() Job DepthPrepass::beginFrame()
{ {
processor->clearCommands(); processor->clearCommands();
primitiveLayout->reset(); primitiveLayout->reset();
@@ -122,26 +123,33 @@ 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;
} }
void DepthPrepass::render() Job DepthPrepass::render()
{ {
depthAttachment->getTexture()->pipelineBarrier( depthAttachment->getTexture()->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS); depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS);
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
List<Job> jobs;
for (auto &&meshBatch : passData.staticDrawList) for (auto &&meshBatch : passData.staticDrawList)
{ {
processor->addMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets); jobs.add(processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets));
}
for(auto& job : jobs)
{
co_await job;
} }
graphics->executeCommands(processor->getRenderCommands()); graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass(); graphics->endRenderPass();
co_return;
} }
void DepthPrepass::endFrame() Job DepthPrepass::endFrame()
{ {
co_return;
} }
void DepthPrepass::publishOutputs() void DepthPrepass::publishOutputs()
@@ -11,12 +11,12 @@ public:
DepthPrepassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics); DepthPrepassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics);
virtual ~DepthPrepassMeshProcessor(); virtual ~DepthPrepassMeshProcessor();
virtual void addMeshBatch( virtual Job processMeshBatch(
const MeshBatch& batch, const MeshBatch& batch,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass& renderPass,
Gfx::PPipelineLayout pipelineLayout, Gfx::PPipelineLayout pipelineLayout,
Gfx::PDescriptorLayout primitiveLayout, Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet>& descriptorSets, Array<Gfx::PDescriptorSet> descriptorSets,
int32 staticMeshId = -1) override; int32 staticMeshId = -1) override;
Array<Gfx::PRenderCommand> getRenderCommands(); Array<Gfx::PRenderCommand> getRenderCommands();
@@ -39,9 +39,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 Job beginFrame() override;
virtual void render() override; virtual Job render() override;
virtual void endFrame() override; virtual Job 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() Job LightCullingPass::beginFrame()
{ {
uint32_t viewportWidth = viewport->getSizeX(); uint32_t viewportWidth = viewport->getSizeX();
uint32_t viewportHeight = viewport->getSizeY(); uint32_t viewportHeight = viewport->getSizeY();
@@ -75,9 +75,10 @@ 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;
} }
void LightCullingPass::render() Job LightCullingPass::render()
{ {
oLightIndexList->pipelineBarrier( oLightIndexList->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
@@ -101,11 +102,12 @@ void LightCullingPass::render()
graphics->executeCommands(commands); graphics->executeCommands(commands);
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
depthAttachment->transferOwnership(Gfx::QueueType::GRAPHICS); depthAttachment->transferOwnership(Gfx::QueueType::GRAPHICS);
co_return;
} }
void LightCullingPass::endFrame() Job 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 Job beginFrame() override;
virtual void render() override; virtual Job render() override;
virtual void endFrame() override; virtual Job 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);
@@ -3,6 +3,7 @@
#include "Scene/Scene.h" #include "Scene/Scene.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/GraphicsResources.h"
#include "Graphics/MeshBatch.h" #include "Graphics/MeshBatch.h"
#include "ThreadPool.h"
namespace Seele namespace Seele
{ {
@@ -14,13 +15,13 @@ public:
protected: protected:
PScene scene; PScene scene;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
virtual void addMeshBatch( virtual Job processMeshBatch(
const MeshBatch& meshBatch, const MeshBatch& batch,
// const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass& renderPass,
Gfx::PPipelineLayout pipelineLayout, Gfx::PPipelineLayout pipelineLayout,
Gfx::PDescriptorLayout primitiveLayout, Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet>& descriptorSets, Array<Gfx::PDescriptorSet> descriptorSets,
int32 staticMeshId = -1) = 0; int32 staticMeshId = -1) = 0;
void buildMeshDrawCommand( void buildMeshDrawCommand(
const MeshBatch& meshBatch, const MeshBatch& meshBatch,
+4 -3
View File
@@ -2,6 +2,7 @@
#include "MinimalEngine.h" #include "MinimalEngine.h"
#include "Math/Math.h" #include "Math/Math.h"
#include "RenderGraph.h" #include "RenderGraph.h"
#include "ThreadPool.h"
namespace Seele namespace Seele
{ {
@@ -21,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 Job beginFrame() = 0;
virtual void render() = 0; virtual Job render() = 0;
virtual void endFrame() = 0; virtual Job 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; }
+6 -5
View File
@@ -15,12 +15,12 @@ UIPass::~UIPass()
} }
void UIPass::beginFrame() Job UIPass::beginFrame()
{ {
co_return;
} }
void UIPass::render() Job UIPass::render()
{ {
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand"); Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand");
@@ -29,11 +29,12 @@ void UIPass::render()
command->draw(4, 1, 0, 0); command->draw(4, 1, 0, 0);
graphics->executeCommands(Array<Gfx::PRenderCommand>({command})); graphics->executeCommands(Array<Gfx::PRenderCommand>({command}));
graphics->endRenderPass(); graphics->endRenderPass();
co_return;
} }
void UIPass::endFrame() Job UIPass::endFrame()
{ {
co_return;
} }
void UIPass::publishOutputs() void UIPass::publishOutputs()
+3 -3
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 Job beginFrame() override;
virtual void render() override; virtual Job render() override;
virtual void endFrame() override; virtual Job endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
private: private:
+1 -1
View File
@@ -12,7 +12,7 @@ Actor::~Actor()
{ {
} }
void Actor::tick(float deltaTime) void Actor::tick(float)
{ {
} }
void Actor::notifySceneAttach(PScene scene) void Actor::notifySceneAttach(PScene scene)
+1 -1
View File
@@ -33,7 +33,7 @@ Scene::~Scene()
{ {
} }
void Scene::tick(double deltaTime) void Scene::tick(double)
{ {
} }
+26 -17
View File
@@ -14,7 +14,7 @@ Event::Event(const std::string& name)
void Event::raise() void Event::raise()
{ {
flag->store(1); flag->store(1);
getGlobalThreadPool().notify(this); getGlobalThreadPool().notify(*this);
} }
void Event::reset() void Event::reset()
{ {
@@ -47,51 +47,56 @@ ThreadPool::~ThreadPool()
void ThreadPool::addJob(Job&& job) void ThreadPool::addJob(Job&& job)
{ {
std::unique_lock lock(jobQueueLock); std::unique_lock lock(jobQueueLock);
std::cout << "Adding job " << job.id << std::endl; //std::cout << "Adding job " << job.id << std::endl;
jobQueue.add(std::move(job)); jobQueue.add(std::move(job));
jobQueueCV.notify_one(); jobQueueCV.notify_one();
} }
void ThreadPool::addJob(MainJob&& job) void ThreadPool::addJob(MainJob&& job)
{ {
std::unique_lock lock(mainJobLock); std::unique_lock lock(mainJobLock);
std::cout << "Adding main job " << job.id << std::endl; //std::cout << "Adding main job " << job.id << std::endl;
mainJobs.add(std::move(job)); mainJobs.add(std::move(job));
mainJobCV.notify_one(); mainJobCV.notify_one();
} }
void ThreadPool::enqueueWaiting(Event* event, Job&& job) void ThreadPool::enqueueWaiting(Event& event, Job job)
{ {
std::cout << job.id << " waiting for event " << event->name << std::endl; //std::cout << job.id << " waiting for event " << event.name << std::endl;
std::unique_lock lock(waitingLock); std::unique_lock lock(waitingLock);
waitingJobs[*event].add(std::move(job)); waitingJobs[event].add(std::move(job));
} }
void ThreadPool::enqueueWaiting(Event* event, MainJob&& job) void ThreadPool::enqueueWaiting(Event& event, MainJob job)
{ {
std::cout << job.id << " main waiting for event " << event->name << std::endl; //std::cout << job.id << " main waiting for event " << event.name << std::endl;
std::unique_lock lock(waitingMainLock); std::unique_lock lock(waitingMainLock);
waitingMainJobs[*event].add(std::move(job)); waitingMainJobs[event].add(std::move(job));
} }
void ThreadPool::notify(Event* event) void ThreadPool::notify(Event& event)
{ {
{ {
std::unique_lock lock(jobQueueLock); std::unique_lock lock(jobQueueLock);
std::unique_lock lock2(waitingLock); std::unique_lock lock2(waitingLock);
while(!waitingJobs[*event].empty()) List<Job>& jobs = waitingJobs[event];
for(auto& job : jobs)
{ {
std::cout << "Waking up job " << waitingJobs[*event].front().id << std::endl; //assert(job.id != -1ull);
Job job = std::move(waitingJobs[*event].retrieve()); //std::cout << "Waking up job " << job.id << std::endl;
jobQueue.add(std::move(job)); jobQueue.add(std::move(job));
jobQueueCV.notify_one(); jobQueueCV.notify_one();
} }
jobs.clear();
} }
{ {
std::unique_lock lock(mainJobLock); std::unique_lock lock(mainJobLock);
std::unique_lock lock2(waitingMainLock); std::unique_lock lock2(waitingMainLock);
while(!waitingMainJobs[*event].empty()) List<MainJob>& jobs = waitingMainJobs[event];
for(auto& job : jobs)
{ {
std::cout << "Waking up main job " << waitingMainJobs[*event].front().id << std::endl; //assert(job.id != -1ull);
mainJobs.add(std::move(waitingMainJobs[*event].retrieve())); //std::cout << "Waking up main job " << job.id << std::endl;
mainJobs.add(std::move(job));
mainJobCV.notify_one(); mainJobCV.notify_one();
} }
jobs.clear();
} }
} }
void ThreadPool::tryMainJob() void ThreadPool::tryMainJob()
@@ -134,8 +139,12 @@ void ThreadPool::threadLoop(const bool mainThread)
continue; continue;
} }
} }
std::cout << "Starting job " << job.id << std::endl; //std::cout << "Starting job " << job.id << std::endl;
job.resume(); job.resume();
if(job.done())
{
job.signal();
}
} }
} }
+61 -68
View File
@@ -25,69 +25,6 @@ struct JobPromiseBase
exit(1); exit(1);
}; };
}; };
static std::atomic_uint64_t globalCounter;
template<bool MainJob>
struct JobBase
{
public:
using promise_type = JobPromiseBase<MainJob>;
explicit JobBase()
: id(-1)
{}
explicit JobBase(std::coroutine_handle<promise_type> handle)
: handle(handle)
, id(globalCounter++)
{
std::cout << "Creating job " << id << std::endl;
/*if constexpr(MainJob)
{
std::cout << "Creating mainjob " << handle.address() << std::endl;
}
else
{
std::cout << "Creating job " << handle.address() << std::endl;
}*/
}
JobBase(const JobBase & rhs) = delete;
JobBase(JobBase&& rhs)
: handle(std::move(rhs.handle))
, id(std::move(rhs.id))
{
rhs.id = -1;
rhs.handle = nullptr;
}
~JobBase()
{
if(handle)
{
std::cout << "Destroying job " << id << std::endl;
handle.destroy();
}
}
JobBase& operator=(const JobBase& rhs) = delete;
JobBase& operator=(JobBase&& rhs)
{
if(this != &rhs)
{
handle = std::move(rhs.handle);
id = std::move(rhs.id);
rhs.id = -1;
rhs.handle = nullptr;
}
return *this;
}
void resume()
{
handle.resume();
}
std::coroutine_handle<promise_type> handle;
uint64 id;
private:
};
using MainJob = JobBase<true>;
using Job = JobBase<false>;
struct Event struct Event
{ {
@@ -119,16 +56,72 @@ private:
friend class ThreadPool; friend class ThreadPool;
}; };
static std::atomic_uint64_t globalCounter;
template<bool MainJob>
struct JobBase
{
public:
using promise_type = JobPromiseBase<MainJob>;
explicit JobBase()
: id(-1)
{}
explicit JobBase(std::coroutine_handle<promise_type> handle)
: handle(handle)
, id(globalCounter++)
{
//std::cout << "Creating job " << id << std::endl;
}
JobBase(const JobBase & rhs) = delete;
JobBase(JobBase&& rhs)
: handle(std::move(rhs.handle))
, id(std::move(rhs.id))
{
rhs.id = -1;
rhs.handle = nullptr;
}
~JobBase()
{
if(handle && handle.done())
{
//std::cout << "Destroying job " << id << std::endl;
handle.destroy();
}
}
JobBase& operator=(const JobBase& rhs) = delete;
JobBase& operator=(JobBase&& rhs)
{
if(this != &rhs)
{
handle = std::move(rhs.handle);
id = std::move(rhs.id);
rhs.id = -1;
rhs.handle = nullptr;
}
return *this;
}
void resume()
{
handle.resume();
}
private:
std::coroutine_handle<promise_type> handle;
uint64 id;
};
using MainJob = JobBase<true>;
using Job = JobBase<false>;
class ThreadPool class ThreadPool
{ {
public: public:
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency()); ThreadPool(uint32 threadCount = std::thread::hardware_concurrency() + 1);
virtual ~ThreadPool(); virtual ~ThreadPool();
void addJob(Job&& job); void addJob(Job&& job);
void addJob(MainJob&& job); void addJob(MainJob&& job);
void enqueueWaiting(Event* event, Job&& job); void enqueueWaiting(Event& event, Job job);
void enqueueWaiting(Event* event, MainJob&& job); void enqueueWaiting(Event& event, MainJob job);
void notify(Event* event); void notify(Event& event);
private: private:
std::atomic_bool running; std::atomic_bool running;
std::thread* mainThread; std::thread* mainThread;
@@ -176,7 +169,7 @@ inline auto JobPromiseBase<MainJob>::initial_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)));
} }
} // namespace Seele } // namespace Seele
+11 -6
View File
@@ -34,31 +34,36 @@ void InspectorView::prepareRender()
} }
void InspectorView::render() Job InspectorView::render()
{ {
co_await uiPass.beginFrame();
co_await uiPass.render();
co_await uiPass.endFrame();
renderFinishedEvent.raise();
} }
void InspectorView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier)
{ {
} }
void InspectorView::mouseMoveCallback(double xPos, double yPos) void InspectorView::mouseMoveCallback(double, double)
{ {
} }
void InspectorView::mouseButtonCallback(MouseButton button, InputAction action, KeyModifier modifier) void InspectorView::mouseButtonCallback(MouseButton, InputAction, KeyModifier)
{ {
} }
void InspectorView::scrollCallback(double xOffset, double yOffset) void InspectorView::scrollCallback(double, double)
{ {
} }
void InspectorView::fileCallback(int count, const char** paths) void InspectorView::fileCallback(int, const char**)
{ {
} }
+1 -1
View File
@@ -18,7 +18,7 @@ public:
virtual void commitUpdate() override; virtual void commitUpdate() override;
virtual void prepareRender() override; virtual void prepareRender() override;
virtual void render() override; virtual Job render() override;
void selectActor(); void selectActor();
protected: protected:
UIPass uiPass; UIPass uiPass;
+12 -10
View File
@@ -83,19 +83,21 @@ void SceneView::prepareRender()
basePass.updateViewFrame(basePassData); basePass.updateViewFrame(basePassData);
} }
void SceneView::render() Job SceneView::render()
{ {
depthPrepass.beginFrame(); co_await depthPrepass.beginFrame();
lightCullingPass.beginFrame(); co_await lightCullingPass.beginFrame();
basePass.beginFrame(); co_await basePass.beginFrame();
depthPrepass.render(); co_await depthPrepass.render();
lightCullingPass.render(); co_await lightCullingPass.render();
basePass.render(); co_await basePass.render();
depthPrepass.endFrame(); co_await depthPrepass.endFrame();
lightCullingPass.endFrame(); co_await lightCullingPass.endFrame();
basePass.endFrame(); co_await basePass.endFrame();
renderFinishedEvent.raise();
} }
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier) void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier)
+1 -1
View File
@@ -18,7 +18,7 @@ public:
virtual void commitUpdate() override; virtual void commitUpdate() override;
virtual void prepareRender() override; virtual void prepareRender() override;
virtual void render() override; virtual Job render() override;
PScene getScene() const { return scene; } PScene getScene() const { return scene; }
private: private:
+4 -1
View File
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "Graphics/RenderPass/RenderGraph.h" #include "Graphics/RenderPass/RenderGraph.h"
#include "ThreadPool.h"
namespace Seele namespace Seele
{ {
@@ -20,15 +21,17 @@ public:
// These are called from the render thread // These are called from the render thread
// prepare render is also locked, so reading from shared memory is also safe // prepare render is also locked, so reading from shared memory is also safe
virtual void prepareRender() {} virtual void prepareRender() {}
virtual void render() {} virtual Job render() { co_return; }
void applyArea(URect area); void applyArea(URect area);
void setFocused(); void setFocused();
Event renderFinished() { return renderFinishedEvent; }
protected: protected:
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
Gfx::PViewport viewport; Gfx::PViewport viewport;
PWindow owner; PWindow owner;
std::string name; std::string name;
Event renderFinishedEvent;
virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) = 0; virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) = 0;
virtual void mouseMoveCallback(double xPos, double yPos) = 0; virtual void mouseMoveCallback(double xPos, double yPos) = 0;
+4
View File
@@ -37,6 +37,10 @@ MainJob Window::render()
} }
windowView->view->render(); windowView->view->render();
} }
for(auto& windowView : views)
{
co_await windowView->view->renderFinished();
}
gfxHandle->endFrame(); gfxHandle->endFrame();
//Enqueue a new render main job //Enqueue a new render main job
render(); render();