More threadpool bs
This commit is contained in:
Vendored
+7
-4
@@ -3,7 +3,8 @@
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/src/**"
|
||||
"${workspaceFolder}/src/**",
|
||||
"${workspaceFolder}/external/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
@@ -15,7 +16,7 @@
|
||||
"cppStandard": "c++20",
|
||||
"browse": {
|
||||
"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"
|
||||
@@ -23,7 +24,9 @@
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/src/**"
|
||||
"${workspaceFolder}/src/**",
|
||||
"${workspaceFolder}/external/**"
|
||||
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
@@ -34,7 +37,7 @@
|
||||
"cppStandard": "c++20",
|
||||
"browse": {
|
||||
"path": [
|
||||
"external/**"
|
||||
"${workspaceFolder}/src/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
|
||||
set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
||||
set(Boost_NO_WARN_NEW_VERSIONS 1)
|
||||
|
||||
if (USE_SUPERBUILD)
|
||||
project (SUPERBUILD NONE)
|
||||
|
||||
@@ -35,24 +35,9 @@ public:
|
||||
{
|
||||
std::unique_lock lck(lock);
|
||||
this->status = status;
|
||||
if(status == Status::Ready)
|
||||
{
|
||||
readyCV.notify_all();
|
||||
}
|
||||
}
|
||||
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::condition_variable readyCV;
|
||||
std::ifstream& getReadStream();
|
||||
std::ofstream& getWriteStream();
|
||||
private:
|
||||
|
||||
@@ -43,6 +43,6 @@ void MeshAsset::addMesh(PMesh mesh)
|
||||
|
||||
const Array<PMesh> MeshAsset::getMeshes()
|
||||
{
|
||||
waitReady();
|
||||
std::unique_lock lck(lock);
|
||||
return meshes;
|
||||
}
|
||||
@@ -223,11 +223,7 @@ namespace Seele
|
||||
}
|
||||
~Array()
|
||||
{
|
||||
if (_data)
|
||||
{
|
||||
deallocateArray(_data, allocated);
|
||||
_data = nullptr;
|
||||
}
|
||||
clear();
|
||||
}
|
||||
|
||||
constexpr bool operator==(const Array &other)
|
||||
@@ -347,6 +343,10 @@ namespace Seele
|
||||
}
|
||||
constexpr void clear()
|
||||
{
|
||||
if(_data == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for(size_type i = 0; i < arraySize; ++i)
|
||||
{
|
||||
_data[i].~T();
|
||||
|
||||
+24
-34
@@ -234,7 +234,7 @@ public:
|
||||
, _size(other._size)
|
||||
, comp(other.comp)
|
||||
{
|
||||
markIteratorDirty();
|
||||
markIteratorsDirty();
|
||||
}
|
||||
Map(Map&& other)
|
||||
: nodeContainer(other.nodeContainer)
|
||||
@@ -242,7 +242,7 @@ public:
|
||||
, _size(std::move(other._size))
|
||||
, comp(std::move(other.comp))
|
||||
{
|
||||
markIteratorDirty();
|
||||
markIteratorsDirty();
|
||||
}
|
||||
~Map()
|
||||
{
|
||||
@@ -255,7 +255,7 @@ public:
|
||||
root = other.root;
|
||||
_size = other._size;
|
||||
comp = other.comp;
|
||||
markIteratorDirty();
|
||||
markIteratorsDirty();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -267,34 +267,34 @@ public:
|
||||
root = std::move(other.root);
|
||||
_size = std::move(other._size);
|
||||
comp = std::move(other.comp);
|
||||
markIteratorDirty();
|
||||
markIteratorsDirty();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
inline mapped_type& operator[](const key_type& key)
|
||||
{
|
||||
root = splay(root, key);
|
||||
markIteratorDirty();
|
||||
if (root >= nodeContainer.size()
|
||||
if (!isValid(root)
|
||||
|| comp(getNode(root)->pair.key, key)
|
||||
|| comp(key, getNode(root)->pair.key))
|
||||
{
|
||||
root = insert(root, key);
|
||||
_size++;
|
||||
}
|
||||
markIteratorsDirty();
|
||||
return getNode(root)->pair.value;
|
||||
}
|
||||
inline mapped_type& operator[](key_type&& key)
|
||||
{
|
||||
root = splay(root, std::move(key));
|
||||
markIteratorDirty();
|
||||
if (root >= nodeContainer.size()
|
||||
if (!isValid(root)
|
||||
|| comp(getNode(root)->pair.key, key)
|
||||
|| comp(key, getNode(root)->pair.key))
|
||||
{
|
||||
root = insert(root, std::move(key));
|
||||
_size++;
|
||||
}
|
||||
markIteratorsDirty();
|
||||
return getNode(root)->pair.value;
|
||||
}
|
||||
iterator find(const key_type& key)
|
||||
@@ -338,7 +338,7 @@ public:
|
||||
nodeContainer.clear();
|
||||
root = -1;
|
||||
_size = 0;
|
||||
markIteratorDirty();
|
||||
markIteratorsDirty();
|
||||
}
|
||||
bool exists(key_type&& key)
|
||||
{
|
||||
@@ -423,7 +423,7 @@ private:
|
||||
{
|
||||
return index < nodeContainer.size();
|
||||
}
|
||||
void markIteratorDirty()
|
||||
void markIteratorsDirty()
|
||||
{
|
||||
iteratorsDirty = true;
|
||||
}
|
||||
@@ -435,41 +435,31 @@ private:
|
||||
}
|
||||
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();
|
||||
beginTraversal.pop();
|
||||
return Iterator(beginIndex, &nodeContainer, std::move(beginTraversal));
|
||||
}
|
||||
return Iterator(beginIndex, &nodeContainer, std::move(beginTraversal));
|
||||
}
|
||||
inline Iterator calcEndIterator() const
|
||||
{
|
||||
if (!isValid(root))
|
||||
size_t endIndex = root;
|
||||
Array<size_t> endTraversal;
|
||||
while (isValid(endIndex))
|
||||
{
|
||||
return Iterator(-1, &nodeContainer);
|
||||
}
|
||||
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));
|
||||
endTraversal.add(endIndex);
|
||||
endIndex = getNode(endIndex)->rightChild;
|
||||
}
|
||||
return Iterator(endIndex, &nodeContainer, std::move(endTraversal));
|
||||
|
||||
}
|
||||
Array<Node, NodeAlloc> nodeContainer;
|
||||
size_t root;
|
||||
|
||||
@@ -67,16 +67,6 @@ Job BasePassMeshProcessor::processMeshBatch(
|
||||
co_return;
|
||||
}
|
||||
|
||||
Array<Gfx::PRenderCommand> BasePassMeshProcessor::getRenderCommands()
|
||||
{
|
||||
return renderCommands;
|
||||
}
|
||||
|
||||
void BasePassMeshProcessor::clearCommands()
|
||||
{
|
||||
renderCommands.clear();
|
||||
}
|
||||
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
|
||||
: RenderPass(graphics, viewport)
|
||||
, processor(new BasePassMeshProcessor(viewport, graphics, false))
|
||||
@@ -122,7 +112,7 @@ BasePass::~BasePass()
|
||||
{
|
||||
}
|
||||
|
||||
Job BasePass::beginFrame()
|
||||
void BasePass::beginFrame()
|
||||
{
|
||||
processor->clearCommands();
|
||||
primitiveLayout->reset();
|
||||
@@ -142,10 +132,9 @@ Job BasePass::beginFrame()
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
||||
co_return;
|
||||
}
|
||||
|
||||
Job BasePass::render()
|
||||
MainJob BasePass::render()
|
||||
{
|
||||
oLightIndexList->pipelineBarrier(
|
||||
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));
|
||||
}
|
||||
for(auto& job : jobs)
|
||||
{
|
||||
co_await job;
|
||||
}
|
||||
co_await Job::all(jobs);
|
||||
graphics->executeCommands(processor->getRenderCommands());
|
||||
graphics->endRenderPass();
|
||||
co_return;
|
||||
}
|
||||
|
||||
Job BasePass::endFrame()
|
||||
void BasePass::endFrame()
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
void BasePass::publishOutputs()
|
||||
|
||||
@@ -19,10 +19,7 @@ public:
|
||||
Gfx::PDescriptorLayout primitiveLayout,
|
||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||
int32 staticMeshId = -1) override;
|
||||
Array<Gfx::PRenderCommand> getRenderCommands();
|
||||
void clearCommands();
|
||||
private:
|
||||
Array<Gfx::PRenderCommand> renderCommands;
|
||||
//Array<Gfx::PDescriptorSet> cachedPrimitiveSets;
|
||||
Gfx::PViewport target;
|
||||
uint8 translucentBasePass;
|
||||
@@ -40,9 +37,9 @@ class BasePass : public RenderPass<BasePassData>
|
||||
public:
|
||||
BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
|
||||
virtual ~BasePass();
|
||||
virtual Job beginFrame() override;
|
||||
virtual Job render() override;
|
||||
virtual Job endFrame() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual MainJob render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
|
||||
|
||||
@@ -64,18 +64,6 @@ Job DepthPrepassMeshProcessor::processMeshBatch(
|
||||
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)
|
||||
: RenderPass(graphics, viewport)
|
||||
, processor(new DepthPrepassMeshProcessor(viewport, graphics))
|
||||
@@ -105,7 +93,7 @@ DepthPrepass::~DepthPrepass()
|
||||
{
|
||||
}
|
||||
|
||||
Job DepthPrepass::beginFrame()
|
||||
void DepthPrepass::beginFrame()
|
||||
{
|
||||
processor->clearCommands();
|
||||
primitiveLayout->reset();
|
||||
@@ -123,10 +111,9 @@ Job DepthPrepass::beginFrame()
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
||||
co_return;
|
||||
}
|
||||
|
||||
Job DepthPrepass::render()
|
||||
MainJob DepthPrepass::render()
|
||||
{
|
||||
depthAttachment->getTexture()->pipelineBarrier(
|
||||
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));
|
||||
}
|
||||
for(auto& job : jobs)
|
||||
{
|
||||
co_await job;
|
||||
}
|
||||
co_await Job::all(jobs);
|
||||
graphics->executeCommands(processor->getRenderCommands());
|
||||
graphics->endRenderPass();
|
||||
co_return;
|
||||
}
|
||||
|
||||
Job DepthPrepass::endFrame()
|
||||
void DepthPrepass::endFrame()
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
void DepthPrepass::publishOutputs()
|
||||
|
||||
@@ -19,10 +19,7 @@ public:
|
||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||
int32 staticMeshId = -1) override;
|
||||
|
||||
Array<Gfx::PRenderCommand> getRenderCommands();
|
||||
void clearCommands();
|
||||
private:
|
||||
Array<Gfx::PRenderCommand> renderCommands;
|
||||
//Array<Gfx::PDescriptorSet> cachedPrimitiveSets;
|
||||
Gfx::PViewport target;
|
||||
//uint32 cachedPrimitiveIndex;
|
||||
@@ -39,9 +36,9 @@ class DepthPrepass : public RenderPass<DepthPrepassData>
|
||||
public:
|
||||
DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
|
||||
~DepthPrepass();
|
||||
virtual Job beginFrame() override;
|
||||
virtual Job render() override;
|
||||
virtual Job endFrame() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual MainJob render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
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 viewportHeight = viewport->getSizeY();
|
||||
uint32_t viewportHeight = viewport->getSizeY();
|
||||
|
||||
BulkResourceData uniformUpdate;
|
||||
viewParams.viewMatrix = source->getViewMatrix();
|
||||
@@ -32,211 +32,209 @@ Job LightCullingPass::beginFrame()
|
||||
uniformUpdate.size = sizeof(ViewParameter);
|
||||
uniformUpdate.data = (uint8*)&viewParams;
|
||||
viewParamsBuffer->updateContents(uniformUpdate);
|
||||
|
||||
const LightEnv& lightEnv = passData.lightEnv;
|
||||
uniformUpdate.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
|
||||
uniformUpdate.data = (uint8*)&lightEnv.directionalLights;
|
||||
directLightBuffer->updateContents(uniformUpdate);
|
||||
uniformUpdate.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
|
||||
uniformUpdate.data = (uint8*)&lightEnv.pointLights;
|
||||
pointLightBuffer->updateContents(uniformUpdate);
|
||||
|
||||
uniformUpdate.size = sizeof(uint32);
|
||||
uniformUpdate.data = (uint8*)&lightEnv.numDirectionalLights;
|
||||
numDirLightBuffer->updateContents(uniformUpdate);
|
||||
uniformUpdate.data = (uint8*)&lightEnv.numPointLights;
|
||||
numPointLightBuffer->updateContents(uniformUpdate);
|
||||
|
||||
const LightEnv& lightEnv = passData.lightEnv;
|
||||
uniformUpdate.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
|
||||
uniformUpdate.data = (uint8*)&lightEnv.directionalLights;
|
||||
directLightBuffer->updateContents(uniformUpdate);
|
||||
uniformUpdate.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
|
||||
uniformUpdate.data = (uint8*)&lightEnv.pointLights;
|
||||
pointLightBuffer->updateContents(uniformUpdate);
|
||||
|
||||
uniformUpdate.size = sizeof(uint32);
|
||||
uniformUpdate.data = (uint8*)&lightEnv.numDirectionalLights;
|
||||
numDirLightBuffer->updateContents(uniformUpdate);
|
||||
uniformUpdate.data = (uint8*)&lightEnv.numPointLights;
|
||||
numPointLightBuffer->updateContents(uniformUpdate);
|
||||
|
||||
BulkResourceData counterReset;
|
||||
uint32 reset = 0;
|
||||
counterReset.data = (uint8*)&reset;
|
||||
counterReset.size = sizeof(uint32);
|
||||
oLightIndexCounter->updateContents(counterReset);
|
||||
tLightIndexCounter->updateContents(counterReset);
|
||||
BulkResourceData counterReset;
|
||||
uint32 reset = 0;
|
||||
counterReset.data = (uint8*)&reset;
|
||||
counterReset.size = sizeof(uint32);
|
||||
oLightIndexCounter->updateContents(counterReset);
|
||||
tLightIndexCounter->updateContents(counterReset);
|
||||
|
||||
cullingDescriptorLayout->reset();
|
||||
lightEnvDescriptorLayout->reset();
|
||||
cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet();
|
||||
lightEnvDescriptorSet = lightEnvDescriptorLayout->allocateDescriptorSet();
|
||||
cullingDescriptorLayout->reset();
|
||||
lightEnvDescriptorLayout->reset();
|
||||
cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet();
|
||||
lightEnvDescriptorSet = lightEnvDescriptorLayout->allocateDescriptorSet();
|
||||
|
||||
cullingDescriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
cullingDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
|
||||
cullingDescriptorSet->updateBuffer(3, frustumBuffer);
|
||||
cullingDescriptorSet->updateBuffer(4, oLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(5, tLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(6, oLightIndexList);
|
||||
cullingDescriptorSet->updateBuffer(7, tLightIndexList);
|
||||
cullingDescriptorSet->updateTexture(8, oLightGrid);
|
||||
cullingDescriptorSet->updateTexture(9, tLightGrid);
|
||||
cullingDescriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
cullingDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
|
||||
cullingDescriptorSet->updateBuffer(3, frustumBuffer);
|
||||
cullingDescriptorSet->updateBuffer(4, oLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(5, tLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(6, oLightIndexList);
|
||||
cullingDescriptorSet->updateBuffer(7, tLightIndexList);
|
||||
cullingDescriptorSet->updateTexture(8, oLightGrid);
|
||||
cullingDescriptorSet->updateTexture(9, tLightGrid);
|
||||
|
||||
|
||||
lightEnvDescriptorSet->updateBuffer(0, directLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(1, numDirLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer);
|
||||
lightEnvDescriptorSet->writeChanges();
|
||||
co_return;
|
||||
lightEnvDescriptorSet->updateBuffer(0, directLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(1, numDirLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer);
|
||||
lightEnvDescriptorSet->writeChanges();
|
||||
}
|
||||
|
||||
Job LightCullingPass::render()
|
||||
MainJob LightCullingPass::render()
|
||||
{
|
||||
oLightIndexList->pipelineBarrier(
|
||||
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);
|
||||
oLightGrid->pipelineBarrier(
|
||||
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);
|
||||
depthAttachment->pipelineBarrier(
|
||||
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);
|
||||
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||
depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE);
|
||||
cullingDescriptorSet->updateTexture(2, depthAttachment);
|
||||
cullingDescriptorSet->writeChanges();
|
||||
Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||
computeCommand->bindPipeline(cullingPipeline);
|
||||
Array<Gfx::PDescriptorSet> descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet};
|
||||
computeCommand->bindDescriptor(descriptorSets);
|
||||
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||
Array<Gfx::PComputeCommand> commands = {computeCommand};
|
||||
graphics->executeCommands(commands);
|
||||
oLightIndexList->pipelineBarrier(
|
||||
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);
|
||||
oLightGrid->pipelineBarrier(
|
||||
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);
|
||||
depthAttachment->pipelineBarrier(
|
||||
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);
|
||||
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||
depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE);
|
||||
cullingDescriptorSet->updateTexture(2, depthAttachment);
|
||||
cullingDescriptorSet->writeChanges();
|
||||
Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||
computeCommand->bindPipeline(cullingPipeline);
|
||||
Array<Gfx::PDescriptorSet> descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet};
|
||||
computeCommand->bindDescriptor(descriptorSets);
|
||||
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||
Array<Gfx::PComputeCommand> commands = {computeCommand};
|
||||
graphics->executeCommands(commands);
|
||||
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
depthAttachment->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
co_return;
|
||||
depthAttachment->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
co_return;
|
||||
}
|
||||
|
||||
Job LightCullingPass::endFrame()
|
||||
void LightCullingPass::endFrame()
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
void LightCullingPass::publishOutputs()
|
||||
{
|
||||
setupFrustums();
|
||||
setupFrustums();
|
||||
uint32_t viewportWidth = viewport->getSizeX();
|
||||
uint32_t viewportHeight = viewport->getSizeY();
|
||||
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
||||
dispatchParams.numThreadGroups = numThreadGroups;
|
||||
dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1);
|
||||
uint32_t viewportHeight = viewport->getSizeY();
|
||||
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
||||
dispatchParams.numThreadGroups = numThreadGroups;
|
||||
dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1);
|
||||
|
||||
BulkResourceData resourceData;
|
||||
StructuredBufferCreateInfo structInfo;
|
||||
uint32 counterReset = 0;
|
||||
resourceData.size = sizeof(uint32);
|
||||
resourceData.data = (uint8*)&counterReset;
|
||||
resourceData.owner = Gfx::QueueType::COMPUTE;
|
||||
structInfo.bDynamic = true;
|
||||
structInfo.resourceData = resourceData;
|
||||
oLightIndexCounter = graphics->createStructuredBuffer(structInfo);
|
||||
tLightIndexCounter = graphics->createStructuredBuffer(structInfo);
|
||||
resourceData.data = nullptr;
|
||||
resourceData.size = sizeof(uint32_t)
|
||||
* dispatchParams.numThreadGroups.x
|
||||
* dispatchParams.numThreadGroups.y
|
||||
* dispatchParams.numThreadGroups.z * 200;
|
||||
structInfo.resourceData = resourceData;
|
||||
structInfo.bDynamic = false;
|
||||
oLightIndexList = graphics->createStructuredBuffer(structInfo);
|
||||
tLightIndexList = graphics->createStructuredBuffer(structInfo);
|
||||
resources->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
|
||||
resources->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
|
||||
|
||||
resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
|
||||
structInfo.resourceData = resourceData;
|
||||
structInfo.bDynamic = true;
|
||||
directLightBuffer = graphics->createStructuredBuffer(structInfo);
|
||||
resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
|
||||
structInfo.resourceData = resourceData;
|
||||
pointLightBuffer = graphics->createStructuredBuffer(structInfo);
|
||||
|
||||
UniformBufferCreateInfo uniformInfo;
|
||||
resourceData.size = sizeof(uint32);
|
||||
uniformInfo.resourceData = resourceData;
|
||||
uniformInfo.bDynamic = true;
|
||||
numDirLightBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
uniformInfo.resourceData = resourceData;
|
||||
uniformInfo.bDynamic = true;
|
||||
numPointLightBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
|
||||
resources->registerBufferOutput("DIRECTIONAL_LIGHTS", directLightBuffer);
|
||||
resources->registerUniformOutput("NUM_DIRECTIONAL_LIGHTS", numDirLightBuffer);
|
||||
resources->registerBufferOutput("POINT_LIGHTS", pointLightBuffer);
|
||||
resources->registerUniformOutput("NUM_POINT_LIGHTS", numPointLightBuffer);
|
||||
|
||||
TextureCreateInfo textureInfo;
|
||||
textureInfo.width = dispatchParams.numThreadGroups.x;
|
||||
textureInfo.height = dispatchParams.numThreadGroups.y;
|
||||
textureInfo.format = Gfx::SE_FORMAT_R32G32_UINT;
|
||||
textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT;
|
||||
oLightGrid = graphics->createTexture2D(textureInfo);
|
||||
tLightGrid = graphics->createTexture2D(textureInfo);
|
||||
|
||||
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
|
||||
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
|
||||
BulkResourceData resourceData;
|
||||
StructuredBufferCreateInfo structInfo;
|
||||
uint32 counterReset = 0;
|
||||
resourceData.size = sizeof(uint32);
|
||||
resourceData.data = (uint8*)&counterReset;
|
||||
resourceData.owner = Gfx::QueueType::COMPUTE;
|
||||
structInfo.bDynamic = true;
|
||||
structInfo.resourceData = resourceData;
|
||||
oLightIndexCounter = graphics->createStructuredBuffer(structInfo);
|
||||
tLightIndexCounter = graphics->createStructuredBuffer(structInfo);
|
||||
resourceData.data = nullptr;
|
||||
resourceData.size = sizeof(uint32_t)
|
||||
* dispatchParams.numThreadGroups.x
|
||||
* dispatchParams.numThreadGroups.y
|
||||
* dispatchParams.numThreadGroups.z * 200;
|
||||
structInfo.resourceData = resourceData;
|
||||
structInfo.bDynamic = false;
|
||||
oLightIndexList = graphics->createStructuredBuffer(structInfo);
|
||||
tLightIndexList = graphics->createStructuredBuffer(structInfo);
|
||||
resources->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
|
||||
resources->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
|
||||
|
||||
resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
|
||||
structInfo.resourceData = resourceData;
|
||||
structInfo.bDynamic = true;
|
||||
directLightBuffer = graphics->createStructuredBuffer(structInfo);
|
||||
resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
|
||||
structInfo.resourceData = resourceData;
|
||||
pointLightBuffer = graphics->createStructuredBuffer(structInfo);
|
||||
|
||||
UniformBufferCreateInfo uniformInfo;
|
||||
resourceData.size = sizeof(uint32);
|
||||
uniformInfo.resourceData = resourceData;
|
||||
uniformInfo.bDynamic = true;
|
||||
numDirLightBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
uniformInfo.resourceData = resourceData;
|
||||
uniformInfo.bDynamic = true;
|
||||
numPointLightBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
|
||||
resources->registerBufferOutput("DIRECTIONAL_LIGHTS", directLightBuffer);
|
||||
resources->registerUniformOutput("NUM_DIRECTIONAL_LIGHTS", numDirLightBuffer);
|
||||
resources->registerBufferOutput("POINT_LIGHTS", pointLightBuffer);
|
||||
resources->registerUniformOutput("NUM_POINT_LIGHTS", numPointLightBuffer);
|
||||
|
||||
TextureCreateInfo textureInfo;
|
||||
textureInfo.width = dispatchParams.numThreadGroups.x;
|
||||
textureInfo.height = dispatchParams.numThreadGroups.y;
|
||||
textureInfo.format = Gfx::SE_FORMAT_R32G32_UINT;
|
||||
textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT;
|
||||
oLightGrid = graphics->createTexture2D(textureInfo);
|
||||
tLightGrid = graphics->createTexture2D(textureInfo);
|
||||
|
||||
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
|
||||
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
|
||||
}
|
||||
|
||||
|
||||
void LightCullingPass::createRenderPass()
|
||||
{
|
||||
cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout");
|
||||
|
||||
//ViewParams
|
||||
cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
//Dispatchparams
|
||||
cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
//DepthTexture
|
||||
cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
//Frustums
|
||||
cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//o_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//t_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//o_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//t_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//o_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
//t_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(9, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout");
|
||||
|
||||
//ViewParams
|
||||
cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
//Dispatchparams
|
||||
cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
//DepthTexture
|
||||
cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
//Frustums
|
||||
cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//o_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//t_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//o_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//t_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//o_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
//t_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(9, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
|
||||
|
||||
lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv");
|
||||
// Directional Lights
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
// Point Lights
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv");
|
||||
// Directional Lights
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
// Point Lights
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
|
||||
cullingLayout = graphics->createPipelineLayout();
|
||||
cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout);
|
||||
cullingLayout->addDescriptorLayout(1, lightEnvDescriptorLayout);
|
||||
cullingLayout->create();
|
||||
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.name = "Culling";
|
||||
|
||||
cullingLayout = graphics->createPipelineLayout();
|
||||
cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout);
|
||||
cullingLayout->addDescriptorLayout(1, lightEnvDescriptorLayout);
|
||||
cullingLayout->create();
|
||||
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.name = "Culling";
|
||||
|
||||
std::ifstream codeStream("./shaders/LightCulling.slang", std::ios::ate);
|
||||
auto fileSize = codeStream.tellg();
|
||||
codeStream.seekg(0);
|
||||
Array<char> buffer(static_cast<uint32>(fileSize));
|
||||
codeStream.read(buffer.data(), fileSize);
|
||||
|
||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
||||
createInfo.entryPoint = "cullLights";
|
||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
createInfo.defines["INDEX_LIGHT_ENV"] = "1";
|
||||
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0";
|
||||
cullingShader = graphics->createComputeShader(createInfo);
|
||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
||||
createInfo.entryPoint = "cullLights";
|
||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
createInfo.defines["INDEX_LIGHT_ENV"] = "1";
|
||||
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0";
|
||||
cullingShader = graphics->createComputeShader(createInfo);
|
||||
|
||||
ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = cullingShader;
|
||||
pipelineInfo.pipelineLayout = cullingLayout;
|
||||
cullingPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH")->getTexture();
|
||||
ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = cullingShader;
|
||||
pipelineInfo.pipelineLayout = cullingLayout;
|
||||
cullingPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH")->getTexture();
|
||||
}
|
||||
|
||||
void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>&)
|
||||
@@ -246,80 +244,80 @@ void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>&)
|
||||
void LightCullingPass::setupFrustums()
|
||||
{
|
||||
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 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (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));
|
||||
|
||||
viewParams.viewMatrix = source->getViewMatrix();
|
||||
viewParams.projectionMatrix = source->getProjectionMatrix();
|
||||
viewParams.inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix());
|
||||
viewParams.screenDimensions = glm::vec2(viewportWidth, viewportHeight);
|
||||
viewParams.inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix());
|
||||
viewParams.screenDimensions = glm::vec2(viewportWidth, viewportHeight);
|
||||
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
||||
dispatchParams.numThreads = numThreads;
|
||||
dispatchParams.numThreadGroups = numThreadGroups;
|
||||
dispatchParams.numThreads = numThreads;
|
||||
dispatchParams.numThreadGroups = numThreadGroups;
|
||||
|
||||
Gfx::PDescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout");
|
||||
frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
frustumDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
frustumLayout = graphics->createPipelineLayout();
|
||||
frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout);
|
||||
frustumLayout->create();
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.name = "Frustum";
|
||||
|
||||
Gfx::PDescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout");
|
||||
frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
frustumDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
frustumLayout = graphics->createPipelineLayout();
|
||||
frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout);
|
||||
frustumLayout->create();
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.name = "Frustum";
|
||||
|
||||
std::ifstream codeStream("./shaders/ComputeFrustums.slang", std::ios::ate);
|
||||
auto fileSize = codeStream.tellg();
|
||||
codeStream.seekg(0);
|
||||
Array<char> buffer(static_cast<uint32>(fileSize));
|
||||
codeStream.read(buffer.data(), fileSize);
|
||||
|
||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
||||
createInfo.entryPoint = "computeFrustums";
|
||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
frustumShader = graphics->createComputeShader(createInfo);
|
||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
||||
createInfo.entryPoint = "computeFrustums";
|
||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
frustumShader = graphics->createComputeShader(createInfo);
|
||||
|
||||
|
||||
ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = frustumShader;
|
||||
pipelineInfo.pipelineLayout = frustumLayout;
|
||||
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
BulkResourceData resourceInfo;
|
||||
UniformBufferCreateInfo uniformInfo;
|
||||
resourceInfo.size = sizeof(ViewParameter);
|
||||
resourceInfo.data = (uint8*)&viewParams;
|
||||
resourceInfo.owner = Gfx::QueueType::COMPUTE;
|
||||
uniformInfo.resourceData = resourceInfo;
|
||||
uniformInfo.bDynamic = false;
|
||||
viewParamsBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
|
||||
ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = frustumShader;
|
||||
pipelineInfo.pipelineLayout = frustumLayout;
|
||||
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
BulkResourceData resourceInfo;
|
||||
UniformBufferCreateInfo uniformInfo;
|
||||
resourceInfo.size = sizeof(ViewParameter);
|
||||
resourceInfo.data = (uint8*)&viewParams;
|
||||
resourceInfo.owner = Gfx::QueueType::COMPUTE;
|
||||
uniformInfo.resourceData = resourceInfo;
|
||||
uniformInfo.bDynamic = false;
|
||||
viewParamsBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
|
||||
resourceInfo.size = sizeof(DispatchParams);
|
||||
resourceInfo.data = (uint8*)&dispatchParams;
|
||||
uniformInfo.resourceData = resourceInfo;
|
||||
uniformInfo.bDynamic = false;
|
||||
dispatchParamsBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
resourceInfo.size = sizeof(DispatchParams);
|
||||
resourceInfo.data = (uint8*)&dispatchParams;
|
||||
uniformInfo.resourceData = resourceInfo;
|
||||
uniformInfo.bDynamic = false;
|
||||
dispatchParamsBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
|
||||
StructuredBufferCreateInfo structuredInfo;
|
||||
resourceInfo.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z;
|
||||
resourceInfo.data = nullptr;
|
||||
structuredInfo.resourceData = resourceInfo;
|
||||
structuredInfo.bDynamic = false;
|
||||
frustumBuffer = graphics->createStructuredBuffer(structuredInfo);
|
||||
|
||||
frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet();
|
||||
frustumDescriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
frustumDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
|
||||
frustumDescriptorSet->updateBuffer(2, frustumBuffer);
|
||||
frustumDescriptorSet->writeChanges();
|
||||
|
||||
Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand");
|
||||
command->bindPipeline(frustumPipeline);
|
||||
command->bindDescriptor(frustumDescriptorSet);
|
||||
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
||||
Array<Gfx::PComputeCommand> commands = {command};
|
||||
graphics->executeCommands(commands);
|
||||
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);
|
||||
StructuredBufferCreateInfo structuredInfo;
|
||||
resourceInfo.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z;
|
||||
resourceInfo.data = nullptr;
|
||||
structuredInfo.resourceData = resourceInfo;
|
||||
structuredInfo.bDynamic = false;
|
||||
frustumBuffer = graphics->createStructuredBuffer(structuredInfo);
|
||||
|
||||
frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet();
|
||||
frustumDescriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
frustumDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
|
||||
frustumDescriptorSet->updateBuffer(2, frustumBuffer);
|
||||
frustumDescriptorSet->writeChanges();
|
||||
|
||||
Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand");
|
||||
command->bindPipeline(frustumPipeline);
|
||||
command->bindDescriptor(frustumDescriptorSet);
|
||||
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
||||
Array<Gfx::PComputeCommand> commands = {command};
|
||||
graphics->executeCommands(commands);
|
||||
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);
|
||||
}
|
||||
@@ -18,9 +18,9 @@ class LightCullingPass : public RenderPass<LightCullingPassData>
|
||||
public:
|
||||
LightCullingPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera);
|
||||
virtual ~LightCullingPass();
|
||||
virtual Job beginFrame() override;
|
||||
virtual Job render() override;
|
||||
virtual Job endFrame() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual MainJob render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
|
||||
|
||||
@@ -60,4 +60,14 @@ void MeshProcessor::buildMeshDrawCommand(
|
||||
drawCommand->bindIndexBuffer(element.indexBuffer);
|
||||
drawCommand->draw(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Array<Gfx::PRenderCommand> MeshProcessor::getRenderCommands()
|
||||
{
|
||||
return renderCommands;
|
||||
}
|
||||
|
||||
void MeshProcessor::clearCommands()
|
||||
{
|
||||
renderCommands.clear();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ class MeshProcessor
|
||||
public:
|
||||
MeshProcessor(Gfx::PGraphics graphics);
|
||||
virtual ~MeshProcessor();
|
||||
Array<Gfx::PRenderCommand> getRenderCommands();
|
||||
void clearCommands();
|
||||
protected:
|
||||
PScene scene;
|
||||
Gfx::PGraphics graphics;
|
||||
@@ -36,5 +38,6 @@ protected:
|
||||
Gfx::PGeometryShader geometryShader,
|
||||
Gfx::PFragmentShader fragmentShader,
|
||||
bool positionOnly);
|
||||
Array<Gfx::PRenderCommand> renderCommands;
|
||||
};
|
||||
} // namespace Seele
|
||||
|
||||
@@ -22,9 +22,9 @@ public:
|
||||
void updateViewFrame(RenderPassDataType viewFrame) {
|
||||
passData = std::move(viewFrame);
|
||||
}
|
||||
virtual Job beginFrame() = 0;
|
||||
virtual Job render() = 0;
|
||||
virtual Job endFrame() = 0;
|
||||
virtual void beginFrame() = 0;
|
||||
virtual MainJob render() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
virtual void publishOutputs() = 0;
|
||||
virtual void createRenderPass() = 0;
|
||||
void setResources(PRenderGraphResources resources) { this->resources = resources; }
|
||||
|
||||
@@ -15,12 +15,11 @@ UIPass::~UIPass()
|
||||
|
||||
}
|
||||
|
||||
Job UIPass::beginFrame()
|
||||
void UIPass::beginFrame()
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
Job UIPass::render()
|
||||
MainJob UIPass::render()
|
||||
{
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand");
|
||||
@@ -32,9 +31,8 @@ Job UIPass::render()
|
||||
co_return;
|
||||
}
|
||||
|
||||
Job UIPass::endFrame()
|
||||
void 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 Job beginFrame() override;
|
||||
virtual Job render() override;
|
||||
virtual Job endFrame() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual MainJob render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
@@ -65,15 +65,15 @@ ShaderBuffer::~ShaderBuffer()
|
||||
{
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||
VkDevice device = graphics->getDevice();
|
||||
auto deletionLambda = [](PCmdBuffer cmdBuffer, VkDevice device, VkBuffer buffer) -> Job
|
||||
auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> Job
|
||||
{
|
||||
co_await cmdBuffer->asyncWait();
|
||||
vkDestroyBuffer(device, buffer, nullptr);
|
||||
co_return;
|
||||
};
|
||||
//co_await cmdBuffer->asyncWait();
|
||||
//vkDestroyBuffer(device, buffer, nullptr);
|
||||
co_return;
|
||||
};
|
||||
for (uint32 i = 0; i < numBuffers; ++i)
|
||||
{
|
||||
deletionLambda(cmdBuffer, device, buffers[i].buffer);
|
||||
deletionLambda(buffers[i].buffer);
|
||||
buffers[i].allocation = nullptr;
|
||||
}
|
||||
graphics = nullptr;
|
||||
|
||||
@@ -85,6 +85,10 @@ void CmdBuffer::endRenderPass()
|
||||
void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||
{
|
||||
assert(state == State::RenderPassActive);
|
||||
if(commands.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::unique_lock lock(handleLock);
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
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)
|
||||
{
|
||||
std::unique_lock lock(handleLock);
|
||||
if(commands.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
|
||||
@@ -168,8 +168,8 @@ TextureHandle::~TextureHandle()
|
||||
VkImage img = image;
|
||||
auto deletionLambda = [cmdBuffer, device, view, img]() -> Job
|
||||
{
|
||||
vkDestroyImageView(device, view, nullptr);
|
||||
vkDestroyImage(device, img, nullptr);
|
||||
//vkDestroyImageView(device, view, nullptr);
|
||||
//vkDestroyImage(device, img, nullptr);
|
||||
co_return;
|
||||
};
|
||||
deletionLambda();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
Seele::Map<void *, void *> registeredObjects;
|
||||
std::map<void *, void *> registeredObjects;
|
||||
std::mutex registeredObjectsLock;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Containers/Map.h"
|
||||
#include "EngineTypes.h"
|
||||
#include "Math/Math.h"
|
||||
#include <map>
|
||||
|
||||
#define DEFINE_REF(x) \
|
||||
typedef RefPtr<x> P##x; \
|
||||
@@ -24,7 +25,7 @@
|
||||
typedef WeakPtr<x> W##x; \
|
||||
}
|
||||
|
||||
extern Seele::Map<void *, void *> registeredObjects;
|
||||
extern std::map<void *, void *> registeredObjects;
|
||||
extern std::mutex registeredObjectsLock;
|
||||
namespace Seele
|
||||
{
|
||||
@@ -124,7 +125,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
object = (RefObject<T, Deleter> *)registeredObj->value;
|
||||
object = (RefObject<T, Deleter> *)registeredObj->second;
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
@@ -303,6 +304,10 @@ public:
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
inline T* getHandle()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
bool isValid()
|
||||
{
|
||||
return handle != nullptr;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ThreadPool.h"
|
||||
#include <memory_resource>
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -6,6 +7,10 @@ Event::Event()
|
||||
: flag(new std::atomic_bool())
|
||||
{}
|
||||
|
||||
Event::Event(nullptr_t)
|
||||
: flag(nullptr)
|
||||
{}
|
||||
|
||||
Event::Event(const std::string& name)
|
||||
: name(name)
|
||||
, flag(new std::atomic_bool())
|
||||
@@ -32,7 +37,7 @@ ThreadPool::ThreadPool(uint32 threadCount)
|
||||
running.store(true);
|
||||
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));
|
||||
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::unique_lock lock(waitingLock);
|
||||
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::unique_lock lock(waitingMainLock);
|
||||
@@ -143,7 +148,7 @@ void ThreadPool::threadLoop(const bool mainThread)
|
||||
job.resume();
|
||||
if(job.done())
|
||||
{
|
||||
job.signal();
|
||||
job.raise();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+72
-11
@@ -10,26 +10,27 @@ extern class ThreadPool& getGlobalThreadPool();
|
||||
|
||||
template<bool MainJob>
|
||||
struct JobBase;
|
||||
|
||||
template<bool MainJob>
|
||||
struct JobPromiseBase
|
||||
{
|
||||
JobBase<MainJob> get_return_object() 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 unhandled_exception() noexcept {
|
||||
std::cerr << "Unhandled exception caught" << std::endl;
|
||||
std::cerr << "Unhandled exception" << std::endl;
|
||||
exit(1);
|
||||
};
|
||||
std::coroutine_handle<> continuation;
|
||||
};
|
||||
|
||||
struct Event
|
||||
{
|
||||
public:
|
||||
Event();
|
||||
Event(nullptr_t);
|
||||
Event(const std::string& name);
|
||||
auto operator<=>(const Event& other) const
|
||||
{
|
||||
@@ -56,6 +57,7 @@ private:
|
||||
friend class ThreadPool;
|
||||
};
|
||||
|
||||
|
||||
static std::atomic_uint64_t globalCounter;
|
||||
template<bool MainJob>
|
||||
struct JobBase
|
||||
@@ -69,8 +71,8 @@ public:
|
||||
explicit JobBase(std::coroutine_handle<promise_type> handle)
|
||||
: handle(handle)
|
||||
, id(globalCounter++)
|
||||
, event(std::format("Job {}", id))
|
||||
{
|
||||
//std::cout << "Creating job " << id << std::endl;
|
||||
}
|
||||
JobBase(const JobBase & rhs) = delete;
|
||||
JobBase(JobBase&& rhs)
|
||||
@@ -82,9 +84,8 @@ public:
|
||||
}
|
||||
~JobBase()
|
||||
{
|
||||
if(handle && handle.done())
|
||||
if(handle && handle.done())
|
||||
{
|
||||
//std::cout << "Destroying job " << id << std::endl;
|
||||
handle.destroy();
|
||||
}
|
||||
}
|
||||
@@ -104,8 +105,55 @@ public:
|
||||
{
|
||||
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:
|
||||
std::coroutine_handle<promise_type> handle;
|
||||
Event event;
|
||||
uint64 id;
|
||||
};
|
||||
|
||||
@@ -115,16 +163,16 @@ using Job = JobBase<false>;
|
||||
class ThreadPool
|
||||
{
|
||||
public:
|
||||
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency() + 1);
|
||||
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency());
|
||||
virtual ~ThreadPool();
|
||||
void addJob(Job&& job);
|
||||
void addJob(MainJob&& job);
|
||||
void enqueueWaiting(Event& event, Job job);
|
||||
void enqueueWaiting(Event& event, MainJob job);
|
||||
void enqueueWaiting(Event& event, Job&& job);
|
||||
void enqueueWaiting(Event& event, MainJob&& job);
|
||||
void notify(Event& event);
|
||||
void threadLoop(const bool isMainThread);
|
||||
private:
|
||||
std::atomic_bool running;
|
||||
std::thread* mainThread;
|
||||
std::vector<std::thread> workers;
|
||||
|
||||
List<MainJob> mainJobs;
|
||||
@@ -142,7 +190,6 @@ private:
|
||||
std::mutex waitingMainLock;
|
||||
|
||||
void tryMainJob();
|
||||
void threadLoop(const bool isMainThread);
|
||||
};
|
||||
|
||||
|
||||
@@ -165,6 +212,20 @@ inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept
|
||||
};
|
||||
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>
|
||||
inline constexpr void Event::await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
|
||||
|
||||
@@ -9,6 +9,10 @@ InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const View
|
||||
: View(graphics, window, createInfo, "InspectorView")
|
||||
, uiPass(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
|
||||
{
|
||||
PRenderGraphResources resources = new RenderGraphResources();
|
||||
uiPass.setResources(resources);
|
||||
uiPass.publishOutputs();
|
||||
uiPass.createRenderPass();
|
||||
}
|
||||
|
||||
InspectorView::~InspectorView()
|
||||
@@ -34,13 +38,14 @@ void InspectorView::prepareRender()
|
||||
|
||||
}
|
||||
|
||||
Job InspectorView::render()
|
||||
MainJob InspectorView::render()
|
||||
{
|
||||
co_await uiPass.beginFrame();
|
||||
co_await uiPass.render();
|
||||
co_await uiPass.endFrame();
|
||||
uiPass.beginFrame();
|
||||
uiPass.render();
|
||||
uiPass.endFrame();
|
||||
|
||||
renderFinishedEvent.raise();
|
||||
co_return;
|
||||
}
|
||||
|
||||
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier)
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
virtual void commitUpdate() override;
|
||||
|
||||
virtual void prepareRender() override;
|
||||
virtual Job render() override;
|
||||
virtual MainJob render() override;
|
||||
void selectActor();
|
||||
protected:
|
||||
UIPass uiPass;
|
||||
|
||||
@@ -18,7 +18,7 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
|
||||
{
|
||||
scene = new Scene(graphics);
|
||||
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_Face_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"));
|
||||
ayaka->addWorldTranslation(Vector(0, 0, 0));
|
||||
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\\Plane\\plane.fbx");
|
||||
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->setWorldScale(Vector(0.1f, 0.1f, 0.1f));
|
||||
scene->addPrimitiveComponent(plane);
|
||||
scene->addPrimitiveComponent(arissa);*/
|
||||
scene->addPrimitiveComponent(arissa);
|
||||
|
||||
PRenderGraphResources resources = new RenderGraphResources();
|
||||
depthPrepass.setResources(resources);
|
||||
@@ -61,7 +61,6 @@ Seele::SceneView::~SceneView()
|
||||
|
||||
void SceneView::beginUpdate()
|
||||
{
|
||||
View::beginUpdate();
|
||||
scene->tick(Gfx::currentFrameDelta);
|
||||
}
|
||||
|
||||
@@ -83,21 +82,22 @@ void SceneView::prepareRender()
|
||||
basePass.updateViewFrame(basePassData);
|
||||
}
|
||||
|
||||
Job SceneView::render()
|
||||
MainJob SceneView::render()
|
||||
{
|
||||
co_await depthPrepass.beginFrame();
|
||||
co_await lightCullingPass.beginFrame();
|
||||
co_await basePass.beginFrame();
|
||||
depthPrepass.beginFrame();
|
||||
lightCullingPass.beginFrame();
|
||||
basePass.beginFrame();
|
||||
|
||||
co_await depthPrepass.render();
|
||||
co_await lightCullingPass.render();
|
||||
co_await basePass.render();
|
||||
depthPrepass.render();
|
||||
lightCullingPass.render();
|
||||
basePass.render();
|
||||
|
||||
co_await depthPrepass.endFrame();
|
||||
co_await lightCullingPass.endFrame();
|
||||
co_await basePass.endFrame();
|
||||
depthPrepass.endFrame();
|
||||
lightCullingPass.endFrame();
|
||||
basePass.endFrame();
|
||||
|
||||
renderFinishedEvent.raise();
|
||||
co_return;
|
||||
}
|
||||
|
||||
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier)
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
virtual void commitUpdate() override;
|
||||
|
||||
virtual void prepareRender() override;
|
||||
virtual Job render() override;
|
||||
virtual MainJob render() override;
|
||||
|
||||
PScene getScene() const { return scene; }
|
||||
private:
|
||||
|
||||
@@ -13,18 +13,19 @@ public:
|
||||
virtual ~View();
|
||||
|
||||
// These are called from the view thread, and handle updating game data
|
||||
virtual void beginUpdate() {}
|
||||
virtual void update() {}
|
||||
virtual void beginUpdate() = 0;
|
||||
virtual void update() = 0;
|
||||
// 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
|
||||
// prepare render is also locked, so reading from shared memory is also safe
|
||||
virtual void prepareRender() {}
|
||||
virtual Job render() { co_return; }
|
||||
virtual void prepareRender() = 0;
|
||||
virtual MainJob render() = 0;
|
||||
void applyArea(URect area);
|
||||
void setFocused();
|
||||
Event renderFinished() { return renderFinishedEvent; }
|
||||
void resetRender() { renderFinishedEvent.reset(); }
|
||||
|
||||
protected:
|
||||
Gfx::PGraphics graphics;
|
||||
|
||||
@@ -40,9 +40,9 @@ MainJob Window::render()
|
||||
for(auto& windowView : views)
|
||||
{
|
||||
co_await windowView->view->renderFinished();
|
||||
windowView->view->resetRender();
|
||||
}
|
||||
gfxHandle->endFrame();
|
||||
//Enqueue a new render main job
|
||||
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 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 fileFunction = std::bind(&View::fileCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2);
|
||||
gfxHandle->setKeyCallback(keyFunction);
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ using namespace Seele;
|
||||
int main()
|
||||
{
|
||||
PWindowManager windowManager = new WindowManager();
|
||||
AssetRegistry::init("/home/dynamitos/TestSeeleProject");
|
||||
AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject");
|
||||
WindowCreateInfo mainWindowInfo;
|
||||
mainWindowInfo.title = "SeeleEngine";
|
||||
mainWindowInfo.width = 1280;
|
||||
@@ -35,6 +35,6 @@ int main()
|
||||
window->addView(inspectorView);
|
||||
sceneView->setFocused();
|
||||
window->render();
|
||||
windowManager->waitForCompletion();
|
||||
getGlobalThreadPool().threadLoop(true);
|
||||
return 0;
|
||||
}
|
||||
@@ -5,6 +5,5 @@ target_sources(Seele_unit_tests
|
||||
EngineTest.cpp)
|
||||
target_include_directories(Seele_unit_tests PUBLIC ./)
|
||||
add_subdirectory(Containers/)
|
||||
#add_subdirectory(Fibers/)
|
||||
add_subdirectory(Graphics/)
|
||||
add_subdirectory(Math/)
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "EngineTest.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include <algorithm>
|
||||
#include <time.h>
|
||||
#include <chrono>
|
||||
#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()
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ BOOST_AUTO_TEST_CASE(insert_find_basic)
|
||||
map[4] = 4;
|
||||
BOOST_REQUIRE_EQUAL(map[2], 5);
|
||||
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)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "EngineTest.h"
|
||||
#include "MinimalEngine.h"
|
||||
#define BOOST_TEST_MODULE SeeleEngine
|
||||
#define BOOST_TEST_DYN_LINK
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace Seele;
|
||||
@@ -34,7 +33,6 @@ BOOST_AUTO_TEST_CASE(basic_refcount)
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(ptr->data, 10);
|
||||
}
|
||||
std::shared_ptr<DeclStruct> test;
|
||||
}
|
||||
struct DeclStruct
|
||||
{
|
||||
@@ -76,10 +74,39 @@ BOOST_AUTO_TEST_CASE(inheritance_cast)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(unique_ptr)
|
||||
{
|
||||
UniquePtr<TestStruct> uptr = new TestStruct();
|
||||
UniquePtr<TestStruct> uptr2 = std::move(uptr);
|
||||
Seele::UniquePtr<TestStruct> uptr = new TestStruct();
|
||||
Seele::UniquePtr<TestStruct> uptr2 = std::move(uptr);
|
||||
BOOST_REQUIRE_EQUAL(uptr2->data, 10);
|
||||
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()
|
||||
@@ -1,5 +0,0 @@
|
||||
target_sources(Seele_unit_tests
|
||||
PRIVATE
|
||||
../../../src/Engine/Fibers/JobQueue.cpp
|
||||
../../../src/Engine/Fibers/Fibers.cpp
|
||||
Fibers.cpp)
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user