Async render passes
This commit is contained in:
Vendored
+1
-3
@@ -30,15 +30,13 @@
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"configurationProvider": "ms-vscode.cmake-tools",
|
||||
"cppStandard": "c++20",
|
||||
"browse": {
|
||||
"path": [
|
||||
"external/**"
|
||||
]
|
||||
},
|
||||
"compilerPath": "/usr/bin/g++"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
||||
Vendored
-1
@@ -15,7 +15,6 @@
|
||||
"console": "internalConsole",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable break on all exceptions",
|
||||
|
||||
@@ -208,9 +208,10 @@ public:
|
||||
deallocateNode(tmp->prev);
|
||||
}
|
||||
deallocateNode(tail);
|
||||
markIteratorDirty();
|
||||
tail = nullptr;
|
||||
root = nullptr;
|
||||
markIteratorDirty();
|
||||
_size = 0;
|
||||
}
|
||||
//Insert at the end
|
||||
iterator add(const T &value)
|
||||
@@ -291,7 +292,7 @@ public:
|
||||
{
|
||||
value_type temp = std::move(root->data);
|
||||
popFront();
|
||||
return std::move(temp);
|
||||
return temp;
|
||||
}
|
||||
iterator remove(iterator pos)
|
||||
{
|
||||
|
||||
@@ -20,13 +20,13 @@ BasePassMeshProcessor::~BasePassMeshProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
void BasePassMeshProcessor::addMeshBatch(
|
||||
Job BasePassMeshProcessor::processMeshBatch(
|
||||
const MeshBatch& batch,
|
||||
// const PPrimitiveComponent primitiveComponent,
|
||||
const Gfx::PRenderPass renderPass,
|
||||
const Gfx::PRenderPass& renderPass,
|
||||
Gfx::PPipelineLayout pipelineLayout,
|
||||
Gfx::PDescriptorLayout primitiveLayout,
|
||||
Array<Gfx::PDescriptorSet>& descriptorSets,
|
||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||
int32 /*staticMeshId*/)
|
||||
{
|
||||
PMaterialAsset material = batch.material;
|
||||
@@ -34,11 +34,12 @@ void BasePassMeshProcessor::addMeshBatch(
|
||||
|
||||
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);
|
||||
|
||||
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
|
||||
renderCommand->setViewport(target);
|
||||
|
||||
pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout());
|
||||
pipelineLayout->create();
|
||||
Gfx::PDescriptorSet materialSet = material->createDescriptorSet();
|
||||
@@ -63,6 +64,7 @@ void BasePassMeshProcessor::addMeshBatch(
|
||||
false);
|
||||
}
|
||||
renderCommands.add(renderCommand);
|
||||
co_return;
|
||||
}
|
||||
|
||||
Array<Gfx::PRenderCommand> BasePassMeshProcessor::getRenderCommands()
|
||||
@@ -120,7 +122,7 @@ BasePass::~BasePass()
|
||||
{
|
||||
}
|
||||
|
||||
void BasePass::beginFrame()
|
||||
Job BasePass::beginFrame()
|
||||
{
|
||||
processor->clearCommands();
|
||||
primitiveLayout->reset();
|
||||
@@ -140,9 +142,10 @@ void BasePass::beginFrame()
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
||||
co_return;
|
||||
}
|
||||
|
||||
void BasePass::render()
|
||||
Job BasePass::render()
|
||||
{
|
||||
oLightIndexList->pipelineBarrier(
|
||||
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]->writeChanges();
|
||||
graphics->beginRenderPass(renderPass);
|
||||
List<Job> jobs;
|
||||
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->endRenderPass();
|
||||
co_return;
|
||||
}
|
||||
|
||||
void BasePass::endFrame()
|
||||
Job BasePass::endFrame()
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
void BasePass::publishOutputs()
|
||||
|
||||
@@ -11,13 +11,13 @@ public:
|
||||
BasePassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass);
|
||||
virtual ~BasePassMeshProcessor();
|
||||
|
||||
virtual void addMeshBatch(
|
||||
virtual Job processMeshBatch(
|
||||
const MeshBatch& batch,
|
||||
// const PPrimitiveComponent primitiveComponent,
|
||||
const Gfx::PRenderPass renderPass,
|
||||
const Gfx::PRenderPass& renderPass,
|
||||
Gfx::PPipelineLayout pipelineLayout,
|
||||
Gfx::PDescriptorLayout primitiveLayout,
|
||||
Array<Gfx::PDescriptorSet>& descriptorSets,
|
||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||
int32 staticMeshId = -1) override;
|
||||
Array<Gfx::PRenderCommand> getRenderCommands();
|
||||
void clearCommands();
|
||||
@@ -40,9 +40,9 @@ class BasePass : public RenderPass<BasePassData>
|
||||
public:
|
||||
BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
|
||||
virtual ~BasePass();
|
||||
virtual void beginFrame() override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Job beginFrame() override;
|
||||
virtual Job render() override;
|
||||
virtual Job endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
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 PPrimitiveComponent primitiveComponent,
|
||||
const Gfx::PRenderPass renderPass,
|
||||
const Gfx::PRenderPass& renderPass,
|
||||
Gfx::PPipelineLayout pipelineLayout,
|
||||
Gfx::PDescriptorLayout primitiveLayout,
|
||||
Array<Gfx::PDescriptorSet>& descriptorSets,
|
||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||
int32 /*staticMeshId*/)
|
||||
{
|
||||
PMaterialAsset material = batch.material;
|
||||
@@ -61,6 +61,7 @@ void DepthPrepassMeshProcessor::addMeshBatch(
|
||||
true);
|
||||
}
|
||||
renderCommands.add(renderCommand);
|
||||
co_return;
|
||||
}
|
||||
|
||||
Array<Gfx::PRenderCommand> DepthPrepassMeshProcessor::getRenderCommands()
|
||||
@@ -104,7 +105,7 @@ DepthPrepass::~DepthPrepass()
|
||||
{
|
||||
}
|
||||
|
||||
void DepthPrepass::beginFrame()
|
||||
Job DepthPrepass::beginFrame()
|
||||
{
|
||||
processor->clearCommands();
|
||||
primitiveLayout->reset();
|
||||
@@ -122,26 +123,33 @@ void DepthPrepass::beginFrame()
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
||||
co_return;
|
||||
}
|
||||
|
||||
void DepthPrepass::render()
|
||||
Job DepthPrepass::render()
|
||||
{
|
||||
|
||||
depthAttachment->getTexture()->pipelineBarrier(
|
||||
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);
|
||||
depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
graphics->beginRenderPass(renderPass);
|
||||
List<Job> jobs;
|
||||
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->endRenderPass();
|
||||
co_return;
|
||||
}
|
||||
|
||||
void DepthPrepass::endFrame()
|
||||
Job DepthPrepass::endFrame()
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
void DepthPrepass::publishOutputs()
|
||||
|
||||
@@ -11,12 +11,12 @@ public:
|
||||
DepthPrepassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics);
|
||||
virtual ~DepthPrepassMeshProcessor();
|
||||
|
||||
virtual void addMeshBatch(
|
||||
virtual Job processMeshBatch(
|
||||
const MeshBatch& batch,
|
||||
const Gfx::PRenderPass renderPass,
|
||||
const Gfx::PRenderPass& renderPass,
|
||||
Gfx::PPipelineLayout pipelineLayout,
|
||||
Gfx::PDescriptorLayout primitiveLayout,
|
||||
Array<Gfx::PDescriptorSet>& descriptorSets,
|
||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||
int32 staticMeshId = -1) override;
|
||||
|
||||
Array<Gfx::PRenderCommand> getRenderCommands();
|
||||
@@ -39,9 +39,9 @@ class DepthPrepass : public RenderPass<DepthPrepassData>
|
||||
public:
|
||||
DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
|
||||
~DepthPrepass();
|
||||
virtual void beginFrame() override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Job beginFrame() override;
|
||||
virtual Job render() override;
|
||||
virtual Job 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()
|
||||
Job LightCullingPass::beginFrame()
|
||||
{
|
||||
uint32_t viewportWidth = viewport->getSizeX();
|
||||
uint32_t viewportHeight = viewport->getSizeY();
|
||||
@@ -75,9 +75,10 @@ void LightCullingPass::beginFrame()
|
||||
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer);
|
||||
lightEnvDescriptorSet->writeChanges();
|
||||
co_return;
|
||||
}
|
||||
|
||||
void LightCullingPass::render()
|
||||
Job LightCullingPass::render()
|
||||
{
|
||||
oLightIndexList->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
@@ -101,11 +102,12 @@ void LightCullingPass::render()
|
||||
graphics->executeCommands(commands);
|
||||
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
depthAttachment->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
co_return;
|
||||
}
|
||||
|
||||
void LightCullingPass::endFrame()
|
||||
Job 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 void render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Job beginFrame() override;
|
||||
virtual Job render() override;
|
||||
virtual Job endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Scene/Scene.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/MeshBatch.h"
|
||||
#include "ThreadPool.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -14,13 +15,13 @@ public:
|
||||
protected:
|
||||
PScene scene;
|
||||
Gfx::PGraphics graphics;
|
||||
virtual void addMeshBatch(
|
||||
const MeshBatch& meshBatch,
|
||||
virtual Job processMeshBatch(
|
||||
const MeshBatch& batch,
|
||||
// const PPrimitiveComponent primitiveComponent,
|
||||
const Gfx::PRenderPass renderPass,
|
||||
const Gfx::PRenderPass& renderPass,
|
||||
Gfx::PPipelineLayout pipelineLayout,
|
||||
Gfx::PDescriptorLayout primitiveLayout,
|
||||
Array<Gfx::PDescriptorSet>& descriptorSets,
|
||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||
int32 staticMeshId = -1) = 0;
|
||||
void buildMeshDrawCommand(
|
||||
const MeshBatch& meshBatch,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "MinimalEngine.h"
|
||||
#include "Math/Math.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "ThreadPool.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -21,9 +22,9 @@ public:
|
||||
void updateViewFrame(RenderPassDataType viewFrame) {
|
||||
passData = std::move(viewFrame);
|
||||
}
|
||||
virtual void beginFrame() = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
virtual Job beginFrame() = 0;
|
||||
virtual Job render() = 0;
|
||||
virtual Job endFrame() = 0;
|
||||
virtual void publishOutputs() = 0;
|
||||
virtual void createRenderPass() = 0;
|
||||
void setResources(PRenderGraphResources resources) { this->resources = resources; }
|
||||
|
||||
@@ -15,12 +15,12 @@ UIPass::~UIPass()
|
||||
|
||||
}
|
||||
|
||||
void UIPass::beginFrame()
|
||||
Job UIPass::beginFrame()
|
||||
{
|
||||
|
||||
co_return;
|
||||
}
|
||||
|
||||
void UIPass::render()
|
||||
Job UIPass::render()
|
||||
{
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand");
|
||||
@@ -29,11 +29,12 @@ void UIPass::render()
|
||||
command->draw(4, 1, 0, 0);
|
||||
graphics->executeCommands(Array<Gfx::PRenderCommand>({command}));
|
||||
graphics->endRenderPass();
|
||||
co_return;
|
||||
}
|
||||
|
||||
void UIPass::endFrame()
|
||||
Job UIPass::endFrame()
|
||||
{
|
||||
|
||||
co_return;
|
||||
}
|
||||
|
||||
void UIPass::publishOutputs()
|
||||
|
||||
@@ -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 void render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Job beginFrame() override;
|
||||
virtual Job render() override;
|
||||
virtual Job endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
@@ -12,7 +12,7 @@ Actor::~Actor()
|
||||
{
|
||||
|
||||
}
|
||||
void Actor::tick(float deltaTime)
|
||||
void Actor::tick(float)
|
||||
{
|
||||
}
|
||||
void Actor::notifySceneAttach(PScene scene)
|
||||
|
||||
@@ -33,7 +33,7 @@ Scene::~Scene()
|
||||
{
|
||||
}
|
||||
|
||||
void Scene::tick(double deltaTime)
|
||||
void Scene::tick(double)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+26
-17
@@ -14,7 +14,7 @@ Event::Event(const std::string& name)
|
||||
void Event::raise()
|
||||
{
|
||||
flag->store(1);
|
||||
getGlobalThreadPool().notify(this);
|
||||
getGlobalThreadPool().notify(*this);
|
||||
}
|
||||
void Event::reset()
|
||||
{
|
||||
@@ -47,51 +47,56 @@ ThreadPool::~ThreadPool()
|
||||
void ThreadPool::addJob(Job&& job)
|
||||
{
|
||||
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));
|
||||
jobQueueCV.notify_one();
|
||||
}
|
||||
void ThreadPool::addJob(MainJob&& job)
|
||||
{
|
||||
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));
|
||||
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);
|
||||
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);
|
||||
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 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;
|
||||
Job job = std::move(waitingJobs[*event].retrieve());
|
||||
//assert(job.id != -1ull);
|
||||
//std::cout << "Waking up job " << job.id << std::endl;
|
||||
jobQueue.add(std::move(job));
|
||||
jobQueueCV.notify_one();
|
||||
}
|
||||
jobs.clear();
|
||||
}
|
||||
{
|
||||
std::unique_lock lock(mainJobLock);
|
||||
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;
|
||||
mainJobs.add(std::move(waitingMainJobs[*event].retrieve()));
|
||||
//assert(job.id != -1ull);
|
||||
//std::cout << "Waking up main job " << job.id << std::endl;
|
||||
mainJobs.add(std::move(job));
|
||||
mainJobCV.notify_one();
|
||||
}
|
||||
jobs.clear();
|
||||
}
|
||||
}
|
||||
void ThreadPool::tryMainJob()
|
||||
@@ -134,8 +139,12 @@ void ThreadPool::threadLoop(const bool mainThread)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
std::cout << "Starting job " << job.id << std::endl;
|
||||
//std::cout << "Starting job " << job.id << std::endl;
|
||||
job.resume();
|
||||
if(job.done())
|
||||
{
|
||||
job.signal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+61
-68
@@ -25,69 +25,6 @@ struct JobPromiseBase
|
||||
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
|
||||
{
|
||||
@@ -119,16 +56,72 @@ private:
|
||||
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
|
||||
{
|
||||
public:
|
||||
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency());
|
||||
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency() + 1);
|
||||
virtual ~ThreadPool();
|
||||
void addJob(Job&& job);
|
||||
void addJob(MainJob&& job);
|
||||
void enqueueWaiting(Event* event, Job&& job);
|
||||
void enqueueWaiting(Event* event, MainJob&& job);
|
||||
void notify(Event* event);
|
||||
void enqueueWaiting(Event& event, Job job);
|
||||
void enqueueWaiting(Event& event, MainJob job);
|
||||
void notify(Event& event);
|
||||
private:
|
||||
std::atomic_bool running;
|
||||
std::thread* mainThread;
|
||||
@@ -176,7 +169,7 @@ inline auto JobPromiseBase<MainJob>::initial_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)));
|
||||
}
|
||||
|
||||
} // namespace Seele
|
||||
|
||||
@@ -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**)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
virtual void commitUpdate() override;
|
||||
|
||||
virtual void prepareRender() override;
|
||||
virtual void render() override;
|
||||
virtual Job render() override;
|
||||
void selectActor();
|
||||
protected:
|
||||
UIPass uiPass;
|
||||
|
||||
@@ -83,19 +83,21 @@ void SceneView::prepareRender()
|
||||
basePass.updateViewFrame(basePassData);
|
||||
}
|
||||
|
||||
void SceneView::render()
|
||||
Job SceneView::render()
|
||||
{
|
||||
depthPrepass.beginFrame();
|
||||
lightCullingPass.beginFrame();
|
||||
basePass.beginFrame();
|
||||
co_await depthPrepass.beginFrame();
|
||||
co_await lightCullingPass.beginFrame();
|
||||
co_await basePass.beginFrame();
|
||||
|
||||
depthPrepass.render();
|
||||
lightCullingPass.render();
|
||||
basePass.render();
|
||||
co_await depthPrepass.render();
|
||||
co_await lightCullingPass.render();
|
||||
co_await basePass.render();
|
||||
|
||||
depthPrepass.endFrame();
|
||||
lightCullingPass.endFrame();
|
||||
basePass.endFrame();
|
||||
co_await depthPrepass.endFrame();
|
||||
co_await lightCullingPass.endFrame();
|
||||
co_await basePass.endFrame();
|
||||
|
||||
renderFinishedEvent.raise();
|
||||
}
|
||||
|
||||
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier)
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
virtual void commitUpdate() override;
|
||||
|
||||
virtual void prepareRender() override;
|
||||
virtual void render() override;
|
||||
virtual Job render() override;
|
||||
|
||||
PScene getScene() const { return scene; }
|
||||
private:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Graphics/RenderPass/RenderGraph.h"
|
||||
#include "ThreadPool.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -20,15 +21,17 @@ public:
|
||||
// These are called from the render thread
|
||||
// prepare render is also locked, so reading from shared memory is also safe
|
||||
virtual void prepareRender() {}
|
||||
virtual void render() {}
|
||||
virtual Job render() { co_return; }
|
||||
void applyArea(URect area);
|
||||
void setFocused();
|
||||
Event renderFinished() { return renderFinishedEvent; }
|
||||
|
||||
protected:
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::PViewport viewport;
|
||||
PWindow owner;
|
||||
std::string name;
|
||||
Event renderFinishedEvent;
|
||||
|
||||
virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) = 0;
|
||||
virtual void mouseMoveCallback(double xPos, double yPos) = 0;
|
||||
|
||||
@@ -37,6 +37,10 @@ MainJob Window::render()
|
||||
}
|
||||
windowView->view->render();
|
||||
}
|
||||
for(auto& windowView : views)
|
||||
{
|
||||
co_await windowView->view->renderFinished();
|
||||
}
|
||||
gfxHandle->endFrame();
|
||||
//Enqueue a new render main job
|
||||
render();
|
||||
|
||||
Reference in New Issue
Block a user