More threadpool bs

This commit is contained in:
Dynamitos
2021-12-02 13:00:03 +01:00
parent 5fafdda770
commit 9e3a2446ce
37 changed files with 488 additions and 541 deletions
+7 -4
View File
@@ -3,7 +3,8 @@
{ {
"name": "Win32", "name": "Win32",
"includePath": [ "includePath": [
"${workspaceFolder}/src/**" "${workspaceFolder}/src/**",
"${workspaceFolder}/external/**"
], ],
"defines": [ "defines": [
"_DEBUG", "_DEBUG",
@@ -15,7 +16,7 @@
"cppStandard": "c++20", "cppStandard": "c++20",
"browse": { "browse": {
"path": [ "path": [
"external/**" "${workspaceFolder}/src/**"
] ]
}, },
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe" "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe"
@@ -23,7 +24,9 @@
{ {
"name": "Linux", "name": "Linux",
"includePath": [ "includePath": [
"${workspaceFolder}/src/**" "${workspaceFolder}/src/**",
"${workspaceFolder}/external/**"
], ],
"defines": [ "defines": [
"_DEBUG", "_DEBUG",
@@ -34,7 +37,7 @@
"cppStandard": "c++20", "cppStandard": "c++20",
"browse": { "browse": {
"path": [ "path": [
"external/**" "${workspaceFolder}/src/**"
] ]
} }
} }
+1
View File
@@ -21,6 +21,7 @@ set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath) set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
set(Boost_NO_WARN_NEW_VERSIONS 1)
if (USE_SUPERBUILD) if (USE_SUPERBUILD)
project (SUPERBUILD NONE) project (SUPERBUILD NONE)
-15
View File
@@ -35,24 +35,9 @@ public:
{ {
std::unique_lock lck(lock); std::unique_lock lck(lock);
this->status = status; this->status = status;
if(status == Status::Ready)
{
readyCV.notify_all();
}
} }
protected: protected:
inline void waitReady()
{
std::unique_lock lck(lock);
if(status != Status::Ready)
{
std::cout << "Asset " << name.generic_string() << " not ready yet, waiting" << std::endl;
readyCV.wait(lck);
std::cout << "Asset " << name.generic_string() << " now ready, continuing" << std::endl;
}
}
std::mutex lock; std::mutex lock;
std::condition_variable readyCV;
std::ifstream& getReadStream(); std::ifstream& getReadStream();
std::ofstream& getWriteStream(); std::ofstream& getWriteStream();
private: private:
+1 -1
View File
@@ -43,6 +43,6 @@ void MeshAsset::addMesh(PMesh mesh)
const Array<PMesh> MeshAsset::getMeshes() const Array<PMesh> MeshAsset::getMeshes()
{ {
waitReady(); std::unique_lock lck(lock);
return meshes; return meshes;
} }
+5 -5
View File
@@ -223,11 +223,7 @@ namespace Seele
} }
~Array() ~Array()
{ {
if (_data) clear();
{
deallocateArray(_data, allocated);
_data = nullptr;
}
} }
constexpr bool operator==(const Array &other) constexpr bool operator==(const Array &other)
@@ -347,6 +343,10 @@ namespace Seele
} }
constexpr void clear() constexpr void clear()
{ {
if(_data == nullptr)
{
return;
}
for(size_type i = 0; i < arraySize; ++i) for(size_type i = 0; i < arraySize; ++i)
{ {
_data[i].~T(); _data[i].~T();
+24 -34
View File
@@ -234,7 +234,7 @@ public:
, _size(other._size) , _size(other._size)
, comp(other.comp) , comp(other.comp)
{ {
markIteratorDirty(); markIteratorsDirty();
} }
Map(Map&& other) Map(Map&& other)
: nodeContainer(other.nodeContainer) : nodeContainer(other.nodeContainer)
@@ -242,7 +242,7 @@ public:
, _size(std::move(other._size)) , _size(std::move(other._size))
, comp(std::move(other.comp)) , comp(std::move(other.comp))
{ {
markIteratorDirty(); markIteratorsDirty();
} }
~Map() ~Map()
{ {
@@ -255,7 +255,7 @@ public:
root = other.root; root = other.root;
_size = other._size; _size = other._size;
comp = other.comp; comp = other.comp;
markIteratorDirty(); markIteratorsDirty();
} }
return *this; return *this;
} }
@@ -267,34 +267,34 @@ public:
root = std::move(other.root); root = std::move(other.root);
_size = std::move(other._size); _size = std::move(other._size);
comp = std::move(other.comp); comp = std::move(other.comp);
markIteratorDirty(); markIteratorsDirty();
} }
return *this; return *this;
} }
inline mapped_type& operator[](const key_type& key) inline mapped_type& operator[](const key_type& key)
{ {
root = splay(root, key); root = splay(root, key);
markIteratorDirty(); if (!isValid(root)
if (root >= nodeContainer.size()
|| comp(getNode(root)->pair.key, key) || comp(getNode(root)->pair.key, key)
|| comp(key, getNode(root)->pair.key)) || comp(key, getNode(root)->pair.key))
{ {
root = insert(root, key); root = insert(root, key);
_size++; _size++;
} }
markIteratorsDirty();
return getNode(root)->pair.value; return getNode(root)->pair.value;
} }
inline mapped_type& operator[](key_type&& key) inline mapped_type& operator[](key_type&& key)
{ {
root = splay(root, std::move(key)); root = splay(root, std::move(key));
markIteratorDirty(); if (!isValid(root)
if (root >= nodeContainer.size()
|| comp(getNode(root)->pair.key, key) || comp(getNode(root)->pair.key, key)
|| comp(key, getNode(root)->pair.key)) || comp(key, getNode(root)->pair.key))
{ {
root = insert(root, std::move(key)); root = insert(root, std::move(key));
_size++; _size++;
} }
markIteratorsDirty();
return getNode(root)->pair.value; return getNode(root)->pair.value;
} }
iterator find(const key_type& key) iterator find(const key_type& key)
@@ -338,7 +338,7 @@ public:
nodeContainer.clear(); nodeContainer.clear();
root = -1; root = -1;
_size = 0; _size = 0;
markIteratorDirty(); markIteratorsDirty();
} }
bool exists(key_type&& key) bool exists(key_type&& key)
{ {
@@ -423,7 +423,7 @@ private:
{ {
return index < nodeContainer.size(); return index < nodeContainer.size();
} }
void markIteratorDirty() void markIteratorsDirty()
{ {
iteratorsDirty = true; iteratorsDirty = true;
} }
@@ -435,41 +435,31 @@ private:
} }
inline Iterator calcBeginIterator() const inline Iterator calcBeginIterator() const
{ {
if (!isValid(root)) size_t beginIndex = root;
Array<size_t> beginTraversal;
while (isValid(beginIndex))
{ {
return Iterator(-1, &nodeContainer); beginTraversal.add(beginIndex);
beginIndex = getNode(beginIndex)->leftChild;
} }
else if(!beginTraversal.empty())
{ {
size_t beginIndex = root;
Array<size_t> beginTraversal;
while (isValid(beginIndex))
{
beginTraversal.add(beginIndex);
beginIndex = getNode(beginIndex)->leftChild;
}
beginIndex = beginTraversal.back(); beginIndex = beginTraversal.back();
beginTraversal.pop(); beginTraversal.pop();
return Iterator(beginIndex, &nodeContainer, std::move(beginTraversal));
} }
return Iterator(beginIndex, &nodeContainer, std::move(beginTraversal));
} }
inline Iterator calcEndIterator() const inline Iterator calcEndIterator() const
{ {
if (!isValid(root)) size_t endIndex = root;
Array<size_t> endTraversal;
while (isValid(endIndex))
{ {
return Iterator(-1, &nodeContainer); endTraversal.add(endIndex);
} endIndex = getNode(endIndex)->rightChild;
else
{
size_t endIndex = root;
Array<size_t> endTraversal;
while (isValid(endIndex))
{
endTraversal.add(endIndex);
endIndex = getNode(endIndex)->rightChild;
}
return Iterator(-1, &nodeContainer, std::move(endTraversal));
} }
return Iterator(endIndex, &nodeContainer, std::move(endTraversal));
} }
Array<Node, NodeAlloc> nodeContainer; Array<Node, NodeAlloc> nodeContainer;
size_t root; size_t root;
+4 -20
View File
@@ -67,16 +67,6 @@ Job BasePassMeshProcessor::processMeshBatch(
co_return; co_return;
} }
Array<Gfx::PRenderCommand> BasePassMeshProcessor::getRenderCommands()
{
return renderCommands;
}
void BasePassMeshProcessor::clearCommands()
{
renderCommands.clear();
}
BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source) BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
: RenderPass(graphics, viewport) : RenderPass(graphics, viewport)
, processor(new BasePassMeshProcessor(viewport, graphics, false)) , processor(new BasePassMeshProcessor(viewport, graphics, false))
@@ -122,7 +112,7 @@ BasePass::~BasePass()
{ {
} }
Job BasePass::beginFrame() void BasePass::beginFrame()
{ {
processor->clearCommands(); processor->clearCommands();
primitiveLayout->reset(); primitiveLayout->reset();
@@ -142,10 +132,9 @@ Job 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;
} }
Job BasePass::render() MainJob 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,
@@ -167,18 +156,13 @@ Job BasePass::render()
{ {
jobs.add(processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets)); jobs.add(processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets));
} }
for(auto& job : jobs) co_await Job::all(jobs);
{
co_await job;
}
graphics->executeCommands(processor->getRenderCommands()); graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass(); graphics->endRenderPass();
co_return;
} }
Job BasePass::endFrame() void BasePass::endFrame()
{ {
co_return;
} }
void BasePass::publishOutputs() void BasePass::publishOutputs()
+3 -6
View File
@@ -19,10 +19,7 @@ public:
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();
void clearCommands();
private: private:
Array<Gfx::PRenderCommand> renderCommands;
//Array<Gfx::PDescriptorSet> cachedPrimitiveSets; //Array<Gfx::PDescriptorSet> cachedPrimitiveSets;
Gfx::PViewport target; Gfx::PViewport target;
uint8 translucentBasePass; uint8 translucentBasePass;
@@ -40,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 Job beginFrame() override; virtual void beginFrame() override;
virtual Job render() override; virtual MainJob render() override;
virtual Job endFrame() override; virtual void 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);
@@ -64,18 +64,6 @@ Job DepthPrepassMeshProcessor::processMeshBatch(
co_return; co_return;
} }
Array<Gfx::PRenderCommand> DepthPrepassMeshProcessor::getRenderCommands()
{
return renderCommands;
}
void DepthPrepassMeshProcessor::clearCommands()
{
renderCommands.clear();
//cachedPrimitiveSets.clear();
//cachedPrimitiveIndex = 0;
}
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source) DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
: RenderPass(graphics, viewport) : RenderPass(graphics, viewport)
, processor(new DepthPrepassMeshProcessor(viewport, graphics)) , processor(new DepthPrepassMeshProcessor(viewport, graphics))
@@ -105,7 +93,7 @@ DepthPrepass::~DepthPrepass()
{ {
} }
Job DepthPrepass::beginFrame() void DepthPrepass::beginFrame()
{ {
processor->clearCommands(); processor->clearCommands();
primitiveLayout->reset(); primitiveLayout->reset();
@@ -123,10 +111,9 @@ Job 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;
} }
Job DepthPrepass::render() MainJob 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,
@@ -138,18 +125,13 @@ Job DepthPrepass::render()
{ {
jobs.add(processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets)); jobs.add(processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets));
} }
for(auto& job : jobs) co_await Job::all(jobs);
{
co_await job;
}
graphics->executeCommands(processor->getRenderCommands()); graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass(); graphics->endRenderPass();
co_return;
} }
Job DepthPrepass::endFrame() void DepthPrepass::endFrame()
{ {
co_return;
} }
void DepthPrepass::publishOutputs() void DepthPrepass::publishOutputs()
@@ -19,10 +19,7 @@ public:
Array<Gfx::PDescriptorSet> descriptorSets, Array<Gfx::PDescriptorSet> descriptorSets,
int32 staticMeshId = -1) override; int32 staticMeshId = -1) override;
Array<Gfx::PRenderCommand> getRenderCommands();
void clearCommands();
private: private:
Array<Gfx::PRenderCommand> renderCommands;
//Array<Gfx::PDescriptorSet> cachedPrimitiveSets; //Array<Gfx::PDescriptorSet> cachedPrimitiveSets;
Gfx::PViewport target; Gfx::PViewport target;
//uint32 cachedPrimitiveIndex; //uint32 cachedPrimitiveIndex;
@@ -39,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 Job beginFrame() override; virtual void beginFrame() override;
virtual Job render() override; virtual MainJob render() override;
virtual Job endFrame() override; virtual void 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,10 +18,10 @@ LightCullingPass::~LightCullingPass()
} }
Job LightCullingPass::beginFrame() void LightCullingPass::beginFrame()
{ {
uint32_t viewportWidth = viewport->getSizeX(); uint32_t viewportWidth = viewport->getSizeX();
uint32_t viewportHeight = viewport->getSizeY(); uint32_t viewportHeight = viewport->getSizeY();
BulkResourceData uniformUpdate; BulkResourceData uniformUpdate;
viewParams.viewMatrix = source->getViewMatrix(); viewParams.viewMatrix = source->getViewMatrix();
@@ -33,190 +33,188 @@ Job LightCullingPass::beginFrame()
uniformUpdate.data = (uint8*)&viewParams; uniformUpdate.data = (uint8*)&viewParams;
viewParamsBuffer->updateContents(uniformUpdate); viewParamsBuffer->updateContents(uniformUpdate);
const LightEnv& lightEnv = passData.lightEnv; const LightEnv& lightEnv = passData.lightEnv;
uniformUpdate.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS; uniformUpdate.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
uniformUpdate.data = (uint8*)&lightEnv.directionalLights; uniformUpdate.data = (uint8*)&lightEnv.directionalLights;
directLightBuffer->updateContents(uniformUpdate); directLightBuffer->updateContents(uniformUpdate);
uniformUpdate.size = sizeof(PointLight) * MAX_POINT_LIGHTS; uniformUpdate.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
uniformUpdate.data = (uint8*)&lightEnv.pointLights; uniformUpdate.data = (uint8*)&lightEnv.pointLights;
pointLightBuffer->updateContents(uniformUpdate); pointLightBuffer->updateContents(uniformUpdate);
uniformUpdate.size = sizeof(uint32); uniformUpdate.size = sizeof(uint32);
uniformUpdate.data = (uint8*)&lightEnv.numDirectionalLights; uniformUpdate.data = (uint8*)&lightEnv.numDirectionalLights;
numDirLightBuffer->updateContents(uniformUpdate); numDirLightBuffer->updateContents(uniformUpdate);
uniformUpdate.data = (uint8*)&lightEnv.numPointLights; uniformUpdate.data = (uint8*)&lightEnv.numPointLights;
numPointLightBuffer->updateContents(uniformUpdate); numPointLightBuffer->updateContents(uniformUpdate);
BulkResourceData counterReset; BulkResourceData counterReset;
uint32 reset = 0; uint32 reset = 0;
counterReset.data = (uint8*)&reset; counterReset.data = (uint8*)&reset;
counterReset.size = sizeof(uint32); counterReset.size = sizeof(uint32);
oLightIndexCounter->updateContents(counterReset); oLightIndexCounter->updateContents(counterReset);
tLightIndexCounter->updateContents(counterReset); tLightIndexCounter->updateContents(counterReset);
cullingDescriptorLayout->reset(); cullingDescriptorLayout->reset();
lightEnvDescriptorLayout->reset(); lightEnvDescriptorLayout->reset();
cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet(); cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet();
lightEnvDescriptorSet = lightEnvDescriptorLayout->allocateDescriptorSet(); lightEnvDescriptorSet = lightEnvDescriptorLayout->allocateDescriptorSet();
cullingDescriptorSet->updateBuffer(0, viewParamsBuffer); cullingDescriptorSet->updateBuffer(0, viewParamsBuffer);
cullingDescriptorSet->updateBuffer(1, dispatchParamsBuffer); cullingDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
cullingDescriptorSet->updateBuffer(3, frustumBuffer); cullingDescriptorSet->updateBuffer(3, frustumBuffer);
cullingDescriptorSet->updateBuffer(4, oLightIndexCounter); cullingDescriptorSet->updateBuffer(4, oLightIndexCounter);
cullingDescriptorSet->updateBuffer(5, tLightIndexCounter); cullingDescriptorSet->updateBuffer(5, tLightIndexCounter);
cullingDescriptorSet->updateBuffer(6, oLightIndexList); cullingDescriptorSet->updateBuffer(6, oLightIndexList);
cullingDescriptorSet->updateBuffer(7, tLightIndexList); cullingDescriptorSet->updateBuffer(7, tLightIndexList);
cullingDescriptorSet->updateTexture(8, oLightGrid); cullingDescriptorSet->updateTexture(8, oLightGrid);
cullingDescriptorSet->updateTexture(9, tLightGrid); cullingDescriptorSet->updateTexture(9, tLightGrid);
lightEnvDescriptorSet->updateBuffer(0, directLightBuffer); lightEnvDescriptorSet->updateBuffer(0, directLightBuffer);
lightEnvDescriptorSet->updateBuffer(1, numDirLightBuffer); lightEnvDescriptorSet->updateBuffer(1, numDirLightBuffer);
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer); lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer); lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer);
lightEnvDescriptorSet->writeChanges(); lightEnvDescriptorSet->writeChanges();
co_return;
} }
Job LightCullingPass::render() MainJob 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,
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);
oLightGrid->pipelineBarrier( oLightGrid->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,
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);
depthAttachment->pipelineBarrier( depthAttachment->pipelineBarrier(
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
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);
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL); depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE); depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE);
cullingDescriptorSet->updateTexture(2, depthAttachment); cullingDescriptorSet->updateTexture(2, depthAttachment);
cullingDescriptorSet->writeChanges(); cullingDescriptorSet->writeChanges();
Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand"); Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
computeCommand->bindPipeline(cullingPipeline); computeCommand->bindPipeline(cullingPipeline);
Array<Gfx::PDescriptorSet> descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet}; Array<Gfx::PDescriptorSet> descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet};
computeCommand->bindDescriptor(descriptorSets); computeCommand->bindDescriptor(descriptorSets);
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z); computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
Array<Gfx::PComputeCommand> commands = {computeCommand}; Array<Gfx::PComputeCommand> commands = {computeCommand};
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; co_return;
} }
Job LightCullingPass::endFrame() void LightCullingPass::endFrame()
{ {
co_return;
} }
void LightCullingPass::publishOutputs() void LightCullingPass::publishOutputs()
{ {
setupFrustums(); setupFrustums();
uint32_t viewportWidth = viewport->getSizeX(); uint32_t viewportWidth = viewport->getSizeX();
uint32_t viewportHeight = viewport->getSizeY(); uint32_t viewportHeight = viewport->getSizeY();
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1)); glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
dispatchParams.numThreadGroups = numThreadGroups; dispatchParams.numThreadGroups = numThreadGroups;
dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1); dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1);
BulkResourceData resourceData; BulkResourceData resourceData;
StructuredBufferCreateInfo structInfo; StructuredBufferCreateInfo structInfo;
uint32 counterReset = 0; uint32 counterReset = 0;
resourceData.size = sizeof(uint32); resourceData.size = sizeof(uint32);
resourceData.data = (uint8*)&counterReset; resourceData.data = (uint8*)&counterReset;
resourceData.owner = Gfx::QueueType::COMPUTE; resourceData.owner = Gfx::QueueType::COMPUTE;
structInfo.bDynamic = true; structInfo.bDynamic = true;
structInfo.resourceData = resourceData; structInfo.resourceData = resourceData;
oLightIndexCounter = graphics->createStructuredBuffer(structInfo); oLightIndexCounter = graphics->createStructuredBuffer(structInfo);
tLightIndexCounter = graphics->createStructuredBuffer(structInfo); tLightIndexCounter = graphics->createStructuredBuffer(structInfo);
resourceData.data = nullptr; resourceData.data = nullptr;
resourceData.size = sizeof(uint32_t) resourceData.size = sizeof(uint32_t)
* dispatchParams.numThreadGroups.x * dispatchParams.numThreadGroups.x
* dispatchParams.numThreadGroups.y * dispatchParams.numThreadGroups.y
* dispatchParams.numThreadGroups.z * 200; * dispatchParams.numThreadGroups.z * 200;
structInfo.resourceData = resourceData; structInfo.resourceData = resourceData;
structInfo.bDynamic = false; structInfo.bDynamic = false;
oLightIndexList = graphics->createStructuredBuffer(structInfo); oLightIndexList = graphics->createStructuredBuffer(structInfo);
tLightIndexList = graphics->createStructuredBuffer(structInfo); tLightIndexList = graphics->createStructuredBuffer(structInfo);
resources->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList); resources->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
resources->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList); resources->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS; resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
structInfo.resourceData = resourceData; structInfo.resourceData = resourceData;
structInfo.bDynamic = true; structInfo.bDynamic = true;
directLightBuffer = graphics->createStructuredBuffer(structInfo); directLightBuffer = graphics->createStructuredBuffer(structInfo);
resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS; resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
structInfo.resourceData = resourceData; structInfo.resourceData = resourceData;
pointLightBuffer = graphics->createStructuredBuffer(structInfo); pointLightBuffer = graphics->createStructuredBuffer(structInfo);
UniformBufferCreateInfo uniformInfo; UniformBufferCreateInfo uniformInfo;
resourceData.size = sizeof(uint32); resourceData.size = sizeof(uint32);
uniformInfo.resourceData = resourceData; uniformInfo.resourceData = resourceData;
uniformInfo.bDynamic = true; uniformInfo.bDynamic = true;
numDirLightBuffer = graphics->createUniformBuffer(uniformInfo); numDirLightBuffer = graphics->createUniformBuffer(uniformInfo);
uniformInfo.resourceData = resourceData; uniformInfo.resourceData = resourceData;
uniformInfo.bDynamic = true; uniformInfo.bDynamic = true;
numPointLightBuffer = graphics->createUniformBuffer(uniformInfo); numPointLightBuffer = graphics->createUniformBuffer(uniformInfo);
resources->registerBufferOutput("DIRECTIONAL_LIGHTS", directLightBuffer); resources->registerBufferOutput("DIRECTIONAL_LIGHTS", directLightBuffer);
resources->registerUniformOutput("NUM_DIRECTIONAL_LIGHTS", numDirLightBuffer); resources->registerUniformOutput("NUM_DIRECTIONAL_LIGHTS", numDirLightBuffer);
resources->registerBufferOutput("POINT_LIGHTS", pointLightBuffer); resources->registerBufferOutput("POINT_LIGHTS", pointLightBuffer);
resources->registerUniformOutput("NUM_POINT_LIGHTS", numPointLightBuffer); resources->registerUniformOutput("NUM_POINT_LIGHTS", numPointLightBuffer);
TextureCreateInfo textureInfo; TextureCreateInfo textureInfo;
textureInfo.width = dispatchParams.numThreadGroups.x; textureInfo.width = dispatchParams.numThreadGroups.x;
textureInfo.height = dispatchParams.numThreadGroups.y; textureInfo.height = dispatchParams.numThreadGroups.y;
textureInfo.format = Gfx::SE_FORMAT_R32G32_UINT; textureInfo.format = Gfx::SE_FORMAT_R32G32_UINT;
textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT; textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT;
oLightGrid = graphics->createTexture2D(textureInfo); oLightGrid = graphics->createTexture2D(textureInfo);
tLightGrid = graphics->createTexture2D(textureInfo); tLightGrid = graphics->createTexture2D(textureInfo);
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid); resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid); resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
} }
void LightCullingPass::createRenderPass() void LightCullingPass::createRenderPass()
{ {
cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout"); cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout");
//ViewParams //ViewParams
cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
//Dispatchparams //Dispatchparams
cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
//DepthTexture //DepthTexture
cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
//Frustums //Frustums
cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//o_lightIndexCounter //o_lightIndexCounter
cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//t_lightIndexCounter //t_lightIndexCounter
cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//o_lightIndexList //o_lightIndexList
cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//t_lightIndexList //t_lightIndexList
cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//o_lightGrid //o_lightGrid
cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE); cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
//t_lightGrid //t_lightGrid
cullingDescriptorLayout->addDescriptorBinding(9, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE); cullingDescriptorLayout->addDescriptorBinding(9, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv"); lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv");
// Directional Lights // Directional Lights
lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
lightEnvDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); lightEnvDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
// Point Lights // Point Lights
lightEnvDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); lightEnvDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
lightEnvDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); lightEnvDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
cullingLayout = graphics->createPipelineLayout(); cullingLayout = graphics->createPipelineLayout();
cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout); cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout);
cullingLayout->addDescriptorLayout(1, lightEnvDescriptorLayout); cullingLayout->addDescriptorLayout(1, lightEnvDescriptorLayout);
cullingLayout->create(); cullingLayout->create();
ShaderCreateInfo createInfo; ShaderCreateInfo createInfo;
createInfo.name = "Culling"; createInfo.name = "Culling";
std::ifstream codeStream("./shaders/LightCulling.slang", std::ios::ate); std::ifstream codeStream("./shaders/LightCulling.slang", std::ios::ate);
auto fileSize = codeStream.tellg(); auto fileSize = codeStream.tellg();
@@ -224,19 +222,19 @@ void LightCullingPass::createRenderPass()
Array<char> buffer(static_cast<uint32>(fileSize)); Array<char> buffer(static_cast<uint32>(fileSize));
codeStream.read(buffer.data(), fileSize); codeStream.read(buffer.data(), fileSize);
createInfo.shaderCode.add(std::string(buffer.data())); createInfo.shaderCode.add(std::string(buffer.data()));
createInfo.entryPoint = "cullLights"; createInfo.entryPoint = "cullLights";
createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
createInfo.defines["INDEX_LIGHT_ENV"] = "1"; createInfo.defines["INDEX_LIGHT_ENV"] = "1";
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0"; createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0";
cullingShader = graphics->createComputeShader(createInfo); cullingShader = graphics->createComputeShader(createInfo);
ComputePipelineCreateInfo pipelineInfo; ComputePipelineCreateInfo pipelineInfo;
pipelineInfo.computeShader = cullingShader; pipelineInfo.computeShader = cullingShader;
pipelineInfo.pipelineLayout = cullingLayout; pipelineInfo.pipelineLayout = cullingLayout;
cullingPipeline = graphics->createComputePipeline(pipelineInfo); cullingPipeline = graphics->createComputePipeline(pipelineInfo);
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH")->getTexture(); depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH")->getTexture();
} }
void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>&) void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>&)
@@ -246,28 +244,28 @@ void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>&)
void LightCullingPass::setupFrustums() void LightCullingPass::setupFrustums()
{ {
uint32_t viewportWidth = viewport->getSizeX(); uint32_t viewportWidth = viewport->getSizeX();
uint32_t viewportHeight = viewport->getSizeY(); uint32_t viewportHeight = viewport->getSizeY();
glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1)); glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1)); glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1));
viewParams.viewMatrix = source->getViewMatrix(); viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix(); viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix()); viewParams.inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix());
viewParams.screenDimensions = glm::vec2(viewportWidth, viewportHeight); viewParams.screenDimensions = glm::vec2(viewportWidth, viewportHeight);
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0); viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
dispatchParams.numThreads = numThreads; dispatchParams.numThreads = numThreads;
dispatchParams.numThreadGroups = numThreadGroups; dispatchParams.numThreadGroups = numThreadGroups;
Gfx::PDescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout"); Gfx::PDescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout");
frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
frustumDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); frustumDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
frustumLayout = graphics->createPipelineLayout(); frustumLayout = graphics->createPipelineLayout();
frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout); frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout);
frustumLayout->create(); frustumLayout->create();
ShaderCreateInfo createInfo; ShaderCreateInfo createInfo;
createInfo.name = "Frustum"; createInfo.name = "Frustum";
std::ifstream codeStream("./shaders/ComputeFrustums.slang", std::ios::ate); std::ifstream codeStream("./shaders/ComputeFrustums.slang", std::ios::ate);
auto fileSize = codeStream.tellg(); auto fileSize = codeStream.tellg();
@@ -275,51 +273,51 @@ void LightCullingPass::setupFrustums()
Array<char> buffer(static_cast<uint32>(fileSize)); Array<char> buffer(static_cast<uint32>(fileSize));
codeStream.read(buffer.data(), fileSize); codeStream.read(buffer.data(), fileSize);
createInfo.shaderCode.add(std::string(buffer.data())); createInfo.shaderCode.add(std::string(buffer.data()));
createInfo.entryPoint = "computeFrustums"; createInfo.entryPoint = "computeFrustums";
createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
frustumShader = graphics->createComputeShader(createInfo); frustumShader = graphics->createComputeShader(createInfo);
ComputePipelineCreateInfo pipelineInfo; ComputePipelineCreateInfo pipelineInfo;
pipelineInfo.computeShader = frustumShader; pipelineInfo.computeShader = frustumShader;
pipelineInfo.pipelineLayout = frustumLayout; pipelineInfo.pipelineLayout = frustumLayout;
frustumPipeline = graphics->createComputePipeline(pipelineInfo); frustumPipeline = graphics->createComputePipeline(pipelineInfo);
BulkResourceData resourceInfo; BulkResourceData resourceInfo;
UniformBufferCreateInfo uniformInfo; UniformBufferCreateInfo uniformInfo;
resourceInfo.size = sizeof(ViewParameter); resourceInfo.size = sizeof(ViewParameter);
resourceInfo.data = (uint8*)&viewParams; resourceInfo.data = (uint8*)&viewParams;
resourceInfo.owner = Gfx::QueueType::COMPUTE; resourceInfo.owner = Gfx::QueueType::COMPUTE;
uniformInfo.resourceData = resourceInfo; uniformInfo.resourceData = resourceInfo;
uniformInfo.bDynamic = false; uniformInfo.bDynamic = false;
viewParamsBuffer = graphics->createUniformBuffer(uniformInfo); viewParamsBuffer = graphics->createUniformBuffer(uniformInfo);
resourceInfo.size = sizeof(DispatchParams); resourceInfo.size = sizeof(DispatchParams);
resourceInfo.data = (uint8*)&dispatchParams; resourceInfo.data = (uint8*)&dispatchParams;
uniformInfo.resourceData = resourceInfo; uniformInfo.resourceData = resourceInfo;
uniformInfo.bDynamic = false; uniformInfo.bDynamic = false;
dispatchParamsBuffer = graphics->createUniformBuffer(uniformInfo); dispatchParamsBuffer = graphics->createUniformBuffer(uniformInfo);
StructuredBufferCreateInfo structuredInfo; StructuredBufferCreateInfo structuredInfo;
resourceInfo.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z; resourceInfo.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z;
resourceInfo.data = nullptr; resourceInfo.data = nullptr;
structuredInfo.resourceData = resourceInfo; structuredInfo.resourceData = resourceInfo;
structuredInfo.bDynamic = false; structuredInfo.bDynamic = false;
frustumBuffer = graphics->createStructuredBuffer(structuredInfo); frustumBuffer = graphics->createStructuredBuffer(structuredInfo);
frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet(); frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet();
frustumDescriptorSet->updateBuffer(0, viewParamsBuffer); frustumDescriptorSet->updateBuffer(0, viewParamsBuffer);
frustumDescriptorSet->updateBuffer(1, dispatchParamsBuffer); frustumDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
frustumDescriptorSet->updateBuffer(2, frustumBuffer); frustumDescriptorSet->updateBuffer(2, frustumBuffer);
frustumDescriptorSet->writeChanges(); frustumDescriptorSet->writeChanges();
Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand"); Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand");
command->bindPipeline(frustumPipeline); command->bindPipeline(frustumPipeline);
command->bindDescriptor(frustumDescriptorSet); command->bindDescriptor(frustumDescriptorSet);
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z); command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
Array<Gfx::PComputeCommand> commands = {command}; Array<Gfx::PComputeCommand> commands = {command};
graphics->executeCommands(commands); graphics->executeCommands(commands);
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
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);
} }
@@ -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 Job beginFrame() override; virtual void beginFrame() override;
virtual Job render() override; virtual MainJob render() override;
virtual Job endFrame() override; virtual void 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);
@@ -61,3 +61,13 @@ void MeshProcessor::buildMeshDrawCommand(
drawCommand->draw(element); drawCommand->draw(element);
} }
} }
Array<Gfx::PRenderCommand> MeshProcessor::getRenderCommands()
{
return renderCommands;
}
void MeshProcessor::clearCommands()
{
renderCommands.clear();
}
@@ -12,6 +12,8 @@ class MeshProcessor
public: public:
MeshProcessor(Gfx::PGraphics graphics); MeshProcessor(Gfx::PGraphics graphics);
virtual ~MeshProcessor(); virtual ~MeshProcessor();
Array<Gfx::PRenderCommand> getRenderCommands();
void clearCommands();
protected: protected:
PScene scene; PScene scene;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
@@ -36,5 +38,6 @@ protected:
Gfx::PGeometryShader geometryShader, Gfx::PGeometryShader geometryShader,
Gfx::PFragmentShader fragmentShader, Gfx::PFragmentShader fragmentShader,
bool positionOnly); bool positionOnly);
Array<Gfx::PRenderCommand> renderCommands;
}; };
} // namespace Seele } // namespace Seele
+3 -3
View File
@@ -22,9 +22,9 @@ public:
void updateViewFrame(RenderPassDataType viewFrame) { void updateViewFrame(RenderPassDataType viewFrame) {
passData = std::move(viewFrame); passData = std::move(viewFrame);
} }
virtual Job beginFrame() = 0; virtual void beginFrame() = 0;
virtual Job render() = 0; virtual MainJob render() = 0;
virtual Job endFrame() = 0; virtual void 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; }
+3 -5
View File
@@ -15,12 +15,11 @@ UIPass::~UIPass()
} }
Job UIPass::beginFrame() void UIPass::beginFrame()
{ {
co_return;
} }
Job UIPass::render() MainJob UIPass::render()
{ {
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand"); Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand");
@@ -32,9 +31,8 @@ Job UIPass::render()
co_return; co_return;
} }
Job UIPass::endFrame() void 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 Job beginFrame() override; virtual void beginFrame() override;
virtual Job render() override; virtual MainJob render() override;
virtual Job endFrame() override; virtual void endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
private: private:
+6 -6
View File
@@ -65,15 +65,15 @@ ShaderBuffer::~ShaderBuffer()
{ {
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands(); PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
VkDevice device = graphics->getDevice(); VkDevice device = graphics->getDevice();
auto deletionLambda = [](PCmdBuffer cmdBuffer, VkDevice device, VkBuffer buffer) -> Job auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> Job
{ {
co_await cmdBuffer->asyncWait(); //co_await cmdBuffer->asyncWait();
vkDestroyBuffer(device, buffer, nullptr); //vkDestroyBuffer(device, buffer, nullptr);
co_return; co_return;
}; };
for (uint32 i = 0; i < numBuffers; ++i) for (uint32 i = 0; i < numBuffers; ++i)
{ {
deletionLambda(cmdBuffer, device, buffers[i].buffer); deletionLambda(buffers[i].buffer);
buffers[i].allocation = nullptr; buffers[i].allocation = nullptr;
} }
graphics = nullptr; graphics = nullptr;
@@ -85,6 +85,10 @@ void CmdBuffer::endRenderPass()
void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands) void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
{ {
assert(state == State::RenderPassActive); assert(state == State::RenderPassActive);
if(commands.size() == 0)
{
return;
}
std::unique_lock lock(handleLock); std::unique_lock lock(handleLock);
Array<VkCommandBuffer> cmdBuffers(commands.size()); Array<VkCommandBuffer> cmdBuffers(commands.size());
for (uint32 i = 0; i < commands.size(); ++i) for (uint32 i = 0; i < commands.size(); ++i)
@@ -105,6 +109,10 @@ void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands) void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
{ {
std::unique_lock lock(handleLock); std::unique_lock lock(handleLock);
if(commands.size() == 0)
{
return;
}
Array<VkCommandBuffer> cmdBuffers(commands.size()); Array<VkCommandBuffer> cmdBuffers(commands.size());
for (uint32 i = 0; i < commands.size(); ++i) for (uint32 i = 0; i < commands.size(); ++i)
{ {
+2 -2
View File
@@ -168,8 +168,8 @@ TextureHandle::~TextureHandle()
VkImage img = image; VkImage img = image;
auto deletionLambda = [cmdBuffer, device, view, img]() -> Job auto deletionLambda = [cmdBuffer, device, view, img]() -> Job
{ {
vkDestroyImageView(device, view, nullptr); //vkDestroyImageView(device, view, nullptr);
vkDestroyImage(device, img, nullptr); //vkDestroyImage(device, img, nullptr);
co_return; co_return;
}; };
deletionLambda(); deletionLambda();
+1 -1
View File
@@ -1,4 +1,4 @@
#include "MinimalEngine.h" #include "MinimalEngine.h"
Seele::Map<void *, void *> registeredObjects; std::map<void *, void *> registeredObjects;
std::mutex registeredObjectsLock; std::mutex registeredObjectsLock;
+7 -2
View File
@@ -2,6 +2,7 @@
#include "Containers/Map.h" #include "Containers/Map.h"
#include "EngineTypes.h" #include "EngineTypes.h"
#include "Math/Math.h" #include "Math/Math.h"
#include <map>
#define DEFINE_REF(x) \ #define DEFINE_REF(x) \
typedef RefPtr<x> P##x; \ typedef RefPtr<x> P##x; \
@@ -24,7 +25,7 @@
typedef WeakPtr<x> W##x; \ typedef WeakPtr<x> W##x; \
} }
extern Seele::Map<void *, void *> registeredObjects; extern std::map<void *, void *> registeredObjects;
extern std::mutex registeredObjectsLock; extern std::mutex registeredObjectsLock;
namespace Seele namespace Seele
{ {
@@ -124,7 +125,7 @@ public:
} }
else else
{ {
object = (RefObject<T, Deleter> *)registeredObj->value; object = (RefObject<T, Deleter> *)registeredObj->second;
object->addRef(); object->addRef();
} }
} }
@@ -303,6 +304,10 @@ public:
{ {
return handle; return handle;
} }
inline T* getHandle()
{
return handle;
}
bool isValid() bool isValid()
{ {
return handle != nullptr; return handle != nullptr;
+9 -4
View File
@@ -1,4 +1,5 @@
#include "ThreadPool.h" #include "ThreadPool.h"
#include <memory_resource>
using namespace Seele; using namespace Seele;
@@ -6,6 +7,10 @@ Event::Event()
: flag(new std::atomic_bool()) : flag(new std::atomic_bool())
{} {}
Event::Event(nullptr_t)
: flag(nullptr)
{}
Event::Event(const std::string& name) Event::Event(const std::string& name)
: name(name) : name(name)
, flag(new std::atomic_bool()) , flag(new std::atomic_bool())
@@ -32,7 +37,7 @@ ThreadPool::ThreadPool(uint32 threadCount)
running.store(true); running.store(true);
for(uint32 i = 0; i < threadCount; ++i) for(uint32 i = 0; i < threadCount; ++i)
{ {
workers[i] = std::thread(&ThreadPool::threadLoop, this, i == 0); workers[i] = std::thread(&ThreadPool::threadLoop, this, false);
} }
} }
@@ -58,13 +63,13 @@ void ThreadPool::addJob(MainJob&& job)
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);
@@ -143,7 +148,7 @@ void ThreadPool::threadLoop(const bool mainThread)
job.resume(); job.resume();
if(job.done()) if(job.done())
{ {
job.signal(); job.raise();
} }
} }
} }
+71 -10
View File
@@ -10,26 +10,27 @@ extern class ThreadPool& getGlobalThreadPool();
template<bool MainJob> template<bool MainJob>
struct JobBase; struct JobBase;
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() const noexcept;
std::suspend_never final_suspend() const noexcept { return {}; } inline auto final_suspend() const noexcept;
void return_void() noexcept {} void return_void() noexcept {}
void unhandled_exception() noexcept { void unhandled_exception() noexcept {
std::cerr << "Unhandled exception caught" << std::endl; std::cerr << "Unhandled exception" << std::endl;
exit(1); exit(1);
}; };
std::coroutine_handle<> continuation;
}; };
struct Event struct Event
{ {
public: public:
Event(); Event();
Event(nullptr_t);
Event(const std::string& name); Event(const std::string& name);
auto operator<=>(const Event& other) const auto operator<=>(const Event& other) const
{ {
@@ -56,6 +57,7 @@ private:
friend class ThreadPool; friend class ThreadPool;
}; };
static std::atomic_uint64_t globalCounter; static std::atomic_uint64_t globalCounter;
template<bool MainJob> template<bool MainJob>
struct JobBase struct JobBase
@@ -69,8 +71,8 @@ public:
explicit JobBase(std::coroutine_handle<promise_type> handle) explicit JobBase(std::coroutine_handle<promise_type> handle)
: handle(handle) : handle(handle)
, id(globalCounter++) , id(globalCounter++)
, event(std::format("Job {}", id))
{ {
//std::cout << "Creating job " << id << std::endl;
} }
JobBase(const JobBase & rhs) = delete; JobBase(const JobBase & rhs) = delete;
JobBase(JobBase&& rhs) JobBase(JobBase&& rhs)
@@ -84,7 +86,6 @@ public:
{ {
if(handle && handle.done()) if(handle && handle.done())
{ {
//std::cout << "Destroying job " << id << std::endl;
handle.destroy(); handle.destroy();
} }
} }
@@ -104,8 +105,55 @@ public:
{ {
handle.resume(); handle.resume();
} }
void then(JobBase continuation)
{
handle.promise().continuation = continuation.handle;
}
bool done()
{
return handle.done();
}
void raise()
{
event.raise();
}
void reset()
{
event.reset();
}
Event operator co_await()
{
return event;
}
template<typename... Awaitable>
static JobBase all(Awaitable... jobs)
{
co_await jobs;
}
template<typename Iterable>
static JobBase all(Iterable&& collection)
{
for(auto&& it : collection)
{
co_await it;
}
}
template<typename JobFunc, typename IterableParams>
static JobBase launchJobs(JobFunc&& func, IterableParams params)
{
List<JobBase> jobs;
for(auto&& param : params)
{
jobs.add(func(param));
}
for(auto job : jobs)
{
co_await job;
}
}
private: private:
std::coroutine_handle<promise_type> handle; std::coroutine_handle<promise_type> handle;
Event event;
uint64 id; uint64 id;
}; };
@@ -115,16 +163,16 @@ using Job = JobBase<false>;
class ThreadPool class ThreadPool
{ {
public: public:
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency() + 1); ThreadPool(uint32 threadCount = std::thread::hardware_concurrency());
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);
void threadLoop(const bool isMainThread);
private: private:
std::atomic_bool running; std::atomic_bool running;
std::thread* mainThread;
std::vector<std::thread> workers; std::vector<std::thread> workers;
List<MainJob> mainJobs; List<MainJob> mainJobs;
@@ -142,7 +190,6 @@ private:
std::mutex waitingMainLock; std::mutex waitingMainLock;
void tryMainJob(); void tryMainJob();
void threadLoop(const bool isMainThread);
}; };
@@ -165,6 +212,20 @@ inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept
}; };
return JobAwaitable{}; return JobAwaitable{};
} }
template<bool MainJob>
inline auto JobPromiseBase<MainJob>::final_suspend() const noexcept
{
struct JobAwaitable
{
constexpr bool await_ready() const noexcept { return false; }
constexpr auto await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h) const noexcept
{
return h.promise().continuation;
}
constexpr void await_resume() const noexcept {}
};
return JobAwaitable{};
}
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)
+9 -4
View File
@@ -9,6 +9,10 @@ InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const View
: View(graphics, window, createInfo, "InspectorView") : View(graphics, window, createInfo, "InspectorView")
, uiPass(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle()))) , uiPass(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
{ {
PRenderGraphResources resources = new RenderGraphResources();
uiPass.setResources(resources);
uiPass.publishOutputs();
uiPass.createRenderPass();
} }
InspectorView::~InspectorView() InspectorView::~InspectorView()
@@ -34,13 +38,14 @@ void InspectorView::prepareRender()
} }
Job InspectorView::render() MainJob InspectorView::render()
{ {
co_await uiPass.beginFrame(); uiPass.beginFrame();
co_await uiPass.render(); uiPass.render();
co_await uiPass.endFrame(); uiPass.endFrame();
renderFinishedEvent.raise(); renderFinishedEvent.raise();
co_return;
} }
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier) void InspectorView::keyCallback(KeyCode, InputAction, 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 Job render() override; virtual MainJob render() override;
void selectActor(); void selectActor();
protected: protected:
UIPass uiPass; UIPass uiPass;
+15 -15
View File
@@ -18,7 +18,7 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
{ {
scene = new Scene(graphics); scene = new Scene(graphics);
scene->addActor(activeCamera); scene->addActor(activeCamera);
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png"); /*AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png");
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png"); AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png");
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png"); AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png");
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Diffuse.png"); AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Diffuse.png");
@@ -28,9 +28,9 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka")); PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka"));
ayaka->addWorldTranslation(Vector(0, 0, 0)); ayaka->addWorldTranslation(Vector(0, 0, 0));
ayaka->setWorldScale(Vector(10, 10, 10)); ayaka->setWorldScale(Vector(10, 10, 10));
scene->addPrimitiveComponent(ayaka); scene->addPrimitiveComponent(ayaka);*/
/*AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Ely\\Ely.fbx"); AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Ely\\Ely.fbx");
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Cube\\cube.obj"); AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Cube\\cube.obj");
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.fbx"); AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.fbx");
PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane")); PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane"));
@@ -39,7 +39,7 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
arissa->addWorldTranslation(Vector(0, 0, 100)); arissa->addWorldTranslation(Vector(0, 0, 100));
arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f)); arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f));
scene->addPrimitiveComponent(plane); scene->addPrimitiveComponent(plane);
scene->addPrimitiveComponent(arissa);*/ scene->addPrimitiveComponent(arissa);
PRenderGraphResources resources = new RenderGraphResources(); PRenderGraphResources resources = new RenderGraphResources();
depthPrepass.setResources(resources); depthPrepass.setResources(resources);
@@ -61,7 +61,6 @@ Seele::SceneView::~SceneView()
void SceneView::beginUpdate() void SceneView::beginUpdate()
{ {
View::beginUpdate();
scene->tick(Gfx::currentFrameDelta); scene->tick(Gfx::currentFrameDelta);
} }
@@ -83,21 +82,22 @@ void SceneView::prepareRender()
basePass.updateViewFrame(basePassData); basePass.updateViewFrame(basePassData);
} }
Job SceneView::render() MainJob SceneView::render()
{ {
co_await depthPrepass.beginFrame(); depthPrepass.beginFrame();
co_await lightCullingPass.beginFrame(); lightCullingPass.beginFrame();
co_await basePass.beginFrame(); basePass.beginFrame();
co_await depthPrepass.render(); depthPrepass.render();
co_await lightCullingPass.render(); lightCullingPass.render();
co_await basePass.render(); basePass.render();
co_await depthPrepass.endFrame(); depthPrepass.endFrame();
co_await lightCullingPass.endFrame(); lightCullingPass.endFrame();
co_await basePass.endFrame(); basePass.endFrame();
renderFinishedEvent.raise(); renderFinishedEvent.raise();
co_return;
} }
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 Job render() override; virtual MainJob render() override;
PScene getScene() const { return scene; } PScene getScene() const { return scene; }
private: private:
+6 -5
View File
@@ -13,18 +13,19 @@ public:
virtual ~View(); virtual ~View();
// These are called from the view thread, and handle updating game data // These are called from the view thread, and handle updating game data
virtual void beginUpdate() {} virtual void beginUpdate() = 0;
virtual void update() {} virtual void update() = 0;
// End frame is called with a lock, so it is safe to write to shared memory // End frame is called with a lock, so it is safe to write to shared memory
virtual void commitUpdate() {} virtual void commitUpdate() = 0;
// 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() = 0;
virtual Job render() { co_return; } virtual MainJob render() = 0;
void applyArea(URect area); void applyArea(URect area);
void setFocused(); void setFocused();
Event renderFinished() { return renderFinishedEvent; } Event renderFinished() { return renderFinishedEvent; }
void resetRender() { renderFinishedEvent.reset(); }
protected: protected:
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
+2 -2
View File
@@ -40,9 +40,9 @@ MainJob Window::render()
for(auto& windowView : views) for(auto& windowView : views)
{ {
co_await windowView->view->renderFinished(); co_await windowView->view->renderFinished();
windowView->view->resetRender();
} }
gfxHandle->endFrame(); gfxHandle->endFrame();
//Enqueue a new render main job
render(); render();
} }
@@ -55,7 +55,7 @@ void Window::setFocused(PView view)
{ {
auto keyFunction = std::bind(&View::keyCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto keyFunction = std::bind(&View::keyCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
auto mouseMoveFunction = std::bind(&View::mouseMoveCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2); auto mouseMoveFunction = std::bind(&View::mouseMoveCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2);
auto mouseButtonFunction = std::bind(&View::mouseButtonCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto mouseButtonFunction = std::bind(&View::mouseButtonCallback, view.getHandle() , std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
auto scrollFunction = std::bind(&View::scrollCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2); auto scrollFunction = std::bind(&View::scrollCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2);
auto fileFunction = std::bind(&View::fileCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2); auto fileFunction = std::bind(&View::fileCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2);
gfxHandle->setKeyCallback(keyFunction); gfxHandle->setKeyCallback(keyFunction);
+2 -2
View File
@@ -9,7 +9,7 @@ using namespace Seele;
int main() int main()
{ {
PWindowManager windowManager = new WindowManager(); PWindowManager windowManager = new WindowManager();
AssetRegistry::init("/home/dynamitos/TestSeeleProject"); AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject");
WindowCreateInfo mainWindowInfo; WindowCreateInfo mainWindowInfo;
mainWindowInfo.title = "SeeleEngine"; mainWindowInfo.title = "SeeleEngine";
mainWindowInfo.width = 1280; mainWindowInfo.width = 1280;
@@ -35,6 +35,6 @@ int main()
window->addView(inspectorView); window->addView(inspectorView);
sceneView->setFocused(); sceneView->setFocused();
window->render(); window->render();
windowManager->waitForCompletion(); getGlobalThreadPool().threadLoop(true);
return 0; return 0;
} }
-1
View File
@@ -5,6 +5,5 @@ target_sources(Seele_unit_tests
EngineTest.cpp) EngineTest.cpp)
target_include_directories(Seele_unit_tests PUBLIC ./) target_include_directories(Seele_unit_tests PUBLIC ./)
add_subdirectory(Containers/) add_subdirectory(Containers/)
#add_subdirectory(Fibers/)
add_subdirectory(Graphics/) add_subdirectory(Graphics/)
add_subdirectory(Math/) add_subdirectory(Math/)
+1 -50
View File
@@ -1,6 +1,7 @@
#include "EngineTest.h" #include "EngineTest.h"
#include "Containers/Array.h" #include "Containers/Array.h"
#include "MinimalEngine.h" #include "MinimalEngine.h"
#include <algorithm>
#include <time.h> #include <time.h>
#include <chrono> #include <chrono>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@@ -138,56 +139,6 @@ BOOST_AUTO_TEST_CASE(refptr_interaction)
} }
} }
/*BOOST_AUTO_TEST_CASE(benchmark)
{
using namespace std::chrono;
srand(time(NULL));
const uint32 TEST_SIZE = 1024 * 256;
uint32* testSet = new uint32[TEST_SIZE];
#pragma loop( hint_parallel( 0 ) )
for (int i = 0; i < TEST_SIZE; ++i)
{
testSet[i] = rand();
}
high_resolution_clock::time_point start_vector = high_resolution_clock::now();
std::vector<uint32> vec;
for (int i = 0; i < TEST_SIZE; ++i)
{
vec.push_back(testSet[i]);
}
high_resolution_clock::time_point end_vector = high_resolution_clock::now();
float time_vector = duration_cast<milliseconds>(end_vector - start_vector).count();
std::random_shuffle(testSet, testSet + TEST_SIZE);
high_resolution_clock::time_point start_remove_vector = high_resolution_clock::now();
for (int i = 0; i < TEST_SIZE; ++i)
{
vec.erase(std::find(vec.begin(), vec.end(), testSet[i]));
}
high_resolution_clock::time_point end_remove_vector = high_resolution_clock::now();
float remove_vector = duration_cast<milliseconds>(end_remove_vector - start_remove_vector).count();
high_resolution_clock::time_point start_array = high_resolution_clock::now();
Array<uint32> arr;
for (int i = 0; i < TEST_SIZE; ++i)
{
arr.add(testSet[i]);
}
high_resolution_clock::time_point end_array = high_resolution_clock::now();
float time_array = duration_cast<milliseconds>(end_array - start_array).count();
high_resolution_clock::time_point start_remove_array = high_resolution_clock::now();
for (int i = 0; i < TEST_SIZE; ++i)
{
arr.remove(arr.find(testSet[i]), false);
}
high_resolution_clock::time_point end_remove_array = high_resolution_clock::now();
float remove_array = duration_cast<milliseconds>(end_remove_array - start_remove_array).count();
std::cout << "Vector: " << time_vector << "ms Array: " << time_array << "ms" << std::endl;
std::cout << "Vector remove: " << remove_vector << "ms Array remove: " << remove_array << "ms" << std::endl;
delete[] testSet;
}*/
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
+3
View File
@@ -21,6 +21,9 @@ BOOST_AUTO_TEST_CASE(insert_find_basic)
map[4] = 4; map[4] = 4;
BOOST_REQUIRE_EQUAL(map[2], 5); BOOST_REQUIRE_EQUAL(map[2], 5);
BOOST_REQUIRE_EQUAL(map[4], 4); BOOST_REQUIRE_EQUAL(map[4], 4);
BOOST_REQUIRE_EQUAL(map.find(2)->value, 5);
BOOST_REQUIRE_EQUAL(map.find(4)->value, 4);
//BOOST_REQUIRE_EQUAL(map.find(5), map.end());
} }
BOOST_AUTO_TEST_CASE(for_each) BOOST_AUTO_TEST_CASE(for_each)
+31 -4
View File
@@ -1,7 +1,6 @@
#include "EngineTest.h" #include "EngineTest.h"
#include "MinimalEngine.h" #include "MinimalEngine.h"
#define BOOST_TEST_MODULE SeeleEngine #define BOOST_TEST_MODULE SeeleEngine
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
using namespace Seele; using namespace Seele;
@@ -34,7 +33,6 @@ BOOST_AUTO_TEST_CASE(basic_refcount)
} }
BOOST_REQUIRE_EQUAL(ptr->data, 10); BOOST_REQUIRE_EQUAL(ptr->data, 10);
} }
std::shared_ptr<DeclStruct> test;
} }
struct DeclStruct struct DeclStruct
{ {
@@ -76,10 +74,39 @@ BOOST_AUTO_TEST_CASE(inheritance_cast)
BOOST_AUTO_TEST_CASE(unique_ptr) BOOST_AUTO_TEST_CASE(unique_ptr)
{ {
UniquePtr<TestStruct> uptr = new TestStruct(); Seele::UniquePtr<TestStruct> uptr = new TestStruct();
UniquePtr<TestStruct> uptr2 = std::move(uptr); Seele::UniquePtr<TestStruct> uptr2 = std::move(uptr);
BOOST_REQUIRE_EQUAL(uptr2->data, 10); BOOST_REQUIRE_EQUAL(uptr2->data, 10);
BOOST_REQUIRE_EQUAL(uptr.isValid(), false); BOOST_REQUIRE_EQUAL(uptr.isValid(), false);
} }
struct ThisReference
{
ThisReference()
{
}
~ThisReference()
{
data = 12;
}
Seele::RefPtr<ThisReference> getRef()
{
return this;
}
uint32 data = 1;
};
BOOST_AUTO_TEST_CASE(this_reference)
{
Seele::RefPtr<ThisReference> ptr2;
{
Seele::RefPtr<ThisReference> ptr = new ThisReference();
BOOST_REQUIRE_EQUAL(ptr->data, 1);
ptr2 = ptr->getRef();
BOOST_REQUIRE_EQUAL(ptr2->data, 1);
ptr2->data = 5;
BOOST_REQUIRE_EQUAL(ptr->data, 5);
}
BOOST_REQUIRE_EQUAL(ptr2->data, 5);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
-5
View File
@@ -1,5 +0,0 @@
target_sources(Seele_unit_tests
PRIVATE
../../../src/Engine/Fibers/JobQueue.cpp
../../../src/Engine/Fibers/Fibers.cpp
Fibers.cpp)
-61
View File
@@ -1,61 +0,0 @@
#include "EngineTest.h"
#include "MinimalEngine.h"
#include "Fibers/Fibers.h"
#include <coroutine>
#include <boost/test/unit_test.hpp>
using namespace Seele;
using namespace Seele::Fibers;
BOOST_AUTO_TEST_SUITE(Fibers_Suite)
FiberTask basicFiberSync1(PCounter syncCounter)
{
syncCounter->increment();
std::cout << "basicFiberSync1 start" << std::endl;
co_await AwaitCounter{syncCounter, 2};
std::cout << "basicFiberSync1 has resumed, counter is " << syncCounter << std::endl;
co_return;
}
FiberTask basicFiberSync2(PCounter syncCounter)
{
syncCounter->increment();
std::cout << "basicFiberSync2 start" << std::endl;
co_await AwaitCounter(syncCounter, 3);
std::cout << "basicFiberSync2 has resumed, counter is " << syncCounter << std::endl;
co_return;
}
BOOST_AUTO_TEST_CASE(basicFiberSync)
{
PCounter syncCounter = new Counter(1);
PCounter counter1 = new Counter();
FiberJob job1 = FiberJob(counter1, &basicFiberSync1, syncCounter);
JobQueue::runJobs(&job1, 1);
FiberJob job2 = FiberJob(counter1, &basicFiberSync2, syncCounter);
JobQueue::runJobs(&job2, 1);
while(counter1->lessThan(2))
std::this_thread::yield();
BOOST_CHECK_EQUAL(syncCounter->getValue(), 3);
}
FiberTask incrementJob(PCounter localCounter)
{
localCounter->increment();
co_return;
}
BOOST_AUTO_TEST_CASE(jobBatch)
{
PCounter localCounter = new Counter();
PCounter jobCounter = new Counter();
FiberJob jobs[256];
for(int i = 0; i < 256; ++i)
{
jobs[i] = FiberJob(jobCounter, JobPriority::HIGH, &incrementJob, localCounter);
}
JobQueue::runJobs(jobs, 256);
while(jobCounter->lessThan(256))
std::this_thread::yield();
BOOST_CHECK_EQUAL(localCounter->getValue(), 256);
}
BOOST_AUTO_TEST_SUITE_END()