diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index afb5a75..511fc50 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -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/**" ] } } diff --git a/CMakeLists.txt b/CMakeLists.txt index 188241c..2a8921d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/src/Engine/Asset/Asset.h b/src/Engine/Asset/Asset.h index e6da6e7..b748f21 100644 --- a/src/Engine/Asset/Asset.h +++ b/src/Engine/Asset/Asset.h @@ -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: diff --git a/src/Engine/Asset/MeshAsset.cpp b/src/Engine/Asset/MeshAsset.cpp index daebe45..319a5ff 100644 --- a/src/Engine/Asset/MeshAsset.cpp +++ b/src/Engine/Asset/MeshAsset.cpp @@ -43,6 +43,6 @@ void MeshAsset::addMesh(PMesh mesh) const Array MeshAsset::getMeshes() { - waitReady(); + std::unique_lock lck(lock); return meshes; } \ No newline at end of file diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index b5191ab..ef5bec5 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -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(); diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 0aba1f8..51872dd 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -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 beginTraversal; + while (isValid(beginIndex)) { - return Iterator(-1, &nodeContainer); + beginTraversal.add(beginIndex); + beginIndex = getNode(beginIndex)->leftChild; } - else + if(!beginTraversal.empty()) { - size_t beginIndex = root; - Array 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 endTraversal; + while (isValid(endIndex)) { - return Iterator(-1, &nodeContainer); - } - else - { - size_t endIndex = root; - Array 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 nodeContainer; size_t root; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index d536abf..1e6ce6e 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -67,16 +67,6 @@ Job BasePassMeshProcessor::processMeshBatch( co_return; } -Array 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() diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index 24d3851..f2234f3 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -19,10 +19,7 @@ public: Gfx::PDescriptorLayout primitiveLayout, Array descriptorSets, int32 staticMeshId = -1) override; - Array getRenderCommands(); - void clearCommands(); private: - Array renderCommands; //Array cachedPrimitiveSets; Gfx::PViewport target; uint8 translucentBasePass; @@ -40,9 +37,9 @@ class BasePass : public RenderPass 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& defines); diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 00e1a57..53dd6f5 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -64,18 +64,6 @@ Job DepthPrepassMeshProcessor::processMeshBatch( co_return; } -Array 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() diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.h b/src/Engine/Graphics/RenderPass/DepthPrepass.h index 59738cd..bb53568 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.h @@ -19,10 +19,7 @@ public: Array descriptorSets, int32 staticMeshId = -1) override; - Array getRenderCommands(); - void clearCommands(); private: - Array renderCommands; //Array cachedPrimitiveSets; Gfx::PViewport target; //uint32 cachedPrimitiveIndex; @@ -39,9 +36,9 @@ class DepthPrepass : public RenderPass 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& defines); diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 73fc453..7bd2b10 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -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 descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet}; - computeCommand->bindDescriptor(descriptorSets); - computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z); - Array 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 descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet}; + computeCommand->bindDescriptor(descriptorSets); + computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z); + Array 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 buffer(static_cast(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&) @@ -246,80 +244,80 @@ void LightCullingPass::modifyRenderPassMacros(Map&) 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 buffer(static_cast(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 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 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); } \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index cee2fa2..8a3baa6 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -18,9 +18,9 @@ class LightCullingPass : public RenderPass 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& defines); diff --git a/src/Engine/Graphics/RenderPass/MeshProcessor.cpp b/src/Engine/Graphics/RenderPass/MeshProcessor.cpp index 4555d0d..d3540a0 100644 --- a/src/Engine/Graphics/RenderPass/MeshProcessor.cpp +++ b/src/Engine/Graphics/RenderPass/MeshProcessor.cpp @@ -60,4 +60,14 @@ void MeshProcessor::buildMeshDrawCommand( drawCommand->bindIndexBuffer(element.indexBuffer); drawCommand->draw(element); } -} \ No newline at end of file +} + +Array MeshProcessor::getRenderCommands() +{ + return renderCommands; +} + +void MeshProcessor::clearCommands() +{ + renderCommands.clear(); +} diff --git a/src/Engine/Graphics/RenderPass/MeshProcessor.h b/src/Engine/Graphics/RenderPass/MeshProcessor.h index b09594f..18ae91e 100644 --- a/src/Engine/Graphics/RenderPass/MeshProcessor.h +++ b/src/Engine/Graphics/RenderPass/MeshProcessor.h @@ -12,6 +12,8 @@ class MeshProcessor public: MeshProcessor(Gfx::PGraphics graphics); virtual ~MeshProcessor(); + Array getRenderCommands(); + void clearCommands(); protected: PScene scene; Gfx::PGraphics graphics; @@ -36,5 +38,6 @@ protected: Gfx::PGeometryShader geometryShader, Gfx::PFragmentShader fragmentShader, bool positionOnly); + Array renderCommands; }; } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index 96da6f6..83e4663 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -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; } diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index a2972b9..f6376e3 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -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() diff --git a/src/Engine/Graphics/RenderPass/UIPass.h b/src/Engine/Graphics/RenderPass/UIPass.h index d506d3d..877e9c1 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.h +++ b/src/Engine/Graphics/RenderPass/UIPass.h @@ -16,9 +16,9 @@ class UIPass : public RenderPass 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: diff --git a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp index 886ca2c..87ecc94 100644 --- a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp @@ -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; diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp index 464997c..d6758bb 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp @@ -85,6 +85,10 @@ void CmdBuffer::endRenderPass() void CmdBuffer::executeCommands(const Array& commands) { assert(state == State::RenderPassActive); + if(commands.size() == 0) + { + return; + } std::unique_lock lock(handleLock); Array cmdBuffers(commands.size()); for (uint32 i = 0; i < commands.size(); ++i) @@ -105,6 +109,10 @@ void CmdBuffer::executeCommands(const Array& commands) void CmdBuffer::executeCommands(const Array& commands) { std::unique_lock lock(handleLock); + if(commands.size() == 0) + { + return; + } Array cmdBuffers(commands.size()); for (uint32 i = 0; i < commands.size(); ++i) { diff --git a/src/Engine/Graphics/Vulkan/VulkanTexture.cpp b/src/Engine/Graphics/Vulkan/VulkanTexture.cpp index 3aa3859..3bb87d1 100644 --- a/src/Engine/Graphics/Vulkan/VulkanTexture.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanTexture.cpp @@ -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(); diff --git a/src/Engine/MinimalEngine.cpp b/src/Engine/MinimalEngine.cpp index 2f51672..c1ad5e4 100644 --- a/src/Engine/MinimalEngine.cpp +++ b/src/Engine/MinimalEngine.cpp @@ -1,4 +1,4 @@ #include "MinimalEngine.h" -Seele::Map registeredObjects; +std::map registeredObjects; std::mutex registeredObjectsLock; diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index afa2dc7..21fdaa9 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -2,6 +2,7 @@ #include "Containers/Map.h" #include "EngineTypes.h" #include "Math/Math.h" +#include #define DEFINE_REF(x) \ typedef RefPtr P##x; \ @@ -24,7 +25,7 @@ typedef WeakPtr W##x; \ } -extern Seele::Map registeredObjects; +extern std::map registeredObjects; extern std::mutex registeredObjectsLock; namespace Seele { @@ -124,7 +125,7 @@ public: } else { - object = (RefObject *)registeredObj->value; + object = (RefObject *)registeredObj->second; object->addRef(); } } @@ -303,6 +304,10 @@ public: { return handle; } + inline T* getHandle() + { + return handle; + } bool isValid() { return handle != nullptr; diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index 7c42cb7..57d14b3 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -1,4 +1,5 @@ #include "ThreadPool.h" +#include 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(); } } } diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index 52ced57..a756f09 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -10,26 +10,27 @@ extern class ThreadPool& getGlobalThreadPool(); template struct JobBase; - template struct JobPromiseBase { JobBase 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 struct JobBase @@ -69,8 +71,8 @@ public: explicit JobBase(std::coroutine_handle 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 + static JobBase all(Awaitable... jobs) + { + co_await jobs; + } + template + static JobBase all(Iterable&& collection) + { + for(auto&& it : collection) + { + co_await it; + } + } + template + static JobBase launchJobs(JobFunc&& func, IterableParams params) + { + List jobs; + for(auto&& param : params) + { + jobs.add(func(param)); + } + for(auto job : jobs) + { + co_await job; + } + } private: std::coroutine_handle handle; + Event event; uint64 id; }; @@ -115,16 +163,16 @@ using Job = JobBase; 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 workers; List mainJobs; @@ -142,7 +190,6 @@ private: std::mutex waitingMainLock; void tryMainJob(); - void threadLoop(const bool isMainThread); }; @@ -165,6 +212,20 @@ inline auto JobPromiseBase::initial_suspend() const noexcept }; return JobAwaitable{}; } +template +inline auto JobPromiseBase::final_suspend() const noexcept +{ + struct JobAwaitable + { + constexpr bool await_ready() const noexcept { return false; } + constexpr auto await_suspend(std::coroutine_handle> h) const noexcept + { + return h.promise().continuation; + } + constexpr void await_resume() const noexcept {} + }; + return JobAwaitable{}; +} template inline constexpr void Event::await_suspend(std::coroutine_handle> h) diff --git a/src/Engine/Window/InspectorView.cpp b/src/Engine/Window/InspectorView.cpp index e74cc07..047c08f 100644 --- a/src/Engine/Window/InspectorView.cpp +++ b/src/Engine/Window/InspectorView.cpp @@ -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) diff --git a/src/Engine/Window/InspectorView.h b/src/Engine/Window/InspectorView.h index bca0bf6..dd7227a 100644 --- a/src/Engine/Window/InspectorView.h +++ b/src/Engine/Window/InspectorView.h @@ -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; diff --git a/src/Engine/Window/SceneView.cpp b/src/Engine/Window/SceneView.cpp index 1c335d2..c7e1e3d 100644 --- a/src/Engine/Window/SceneView.cpp +++ b/src/Engine/Window/SceneView.cpp @@ -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) diff --git a/src/Engine/Window/SceneView.h b/src/Engine/Window/SceneView.h index 9fc213a..b6b0ef7 100644 --- a/src/Engine/Window/SceneView.h +++ b/src/Engine/Window/SceneView.h @@ -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: diff --git a/src/Engine/Window/View.h b/src/Engine/Window/View.h index 75a1a37..f9a0b2b 100644 --- a/src/Engine/Window/View.h +++ b/src/Engine/Window/View.h @@ -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; diff --git a/src/Engine/Window/Window.cpp b/src/Engine/Window/Window.cpp index b9c2217..815e775 100644 --- a/src/Engine/Window/Window.cpp +++ b/src/Engine/Window/Window.cpp @@ -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); diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index ea5cf11..1865485 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -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; } \ No newline at end of file diff --git a/test/Engine/CMakeLists.txt b/test/Engine/CMakeLists.txt index b1acf4b..86f8b74 100644 --- a/test/Engine/CMakeLists.txt +++ b/test/Engine/CMakeLists.txt @@ -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/) \ No newline at end of file diff --git a/test/Engine/Containers/Array.cpp b/test/Engine/Containers/Array.cpp index 00c13ec..e56bdd9 100644 --- a/test/Engine/Containers/Array.cpp +++ b/test/Engine/Containers/Array.cpp @@ -1,6 +1,7 @@ #include "EngineTest.h" #include "Containers/Array.h" #include "MinimalEngine.h" +#include #include #include #include @@ -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 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(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(end_remove_vector - start_remove_vector).count(); - - high_resolution_clock::time_point start_array = high_resolution_clock::now(); - Array 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(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(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() diff --git a/test/Engine/Containers/Map.cpp b/test/Engine/Containers/Map.cpp index 894f26e..16b2bbf 100644 --- a/test/Engine/Containers/Map.cpp +++ b/test/Engine/Containers/Map.cpp @@ -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) diff --git a/test/Engine/EngineTest.cpp b/test/Engine/EngineTest.cpp index ffc0742..066d7f8 100644 --- a/test/Engine/EngineTest.cpp +++ b/test/Engine/EngineTest.cpp @@ -1,7 +1,6 @@ #include "EngineTest.h" #include "MinimalEngine.h" #define BOOST_TEST_MODULE SeeleEngine -#define BOOST_TEST_DYN_LINK #include using namespace Seele; @@ -34,7 +33,6 @@ BOOST_AUTO_TEST_CASE(basic_refcount) } BOOST_REQUIRE_EQUAL(ptr->data, 10); } - std::shared_ptr test; } struct DeclStruct { @@ -76,10 +74,39 @@ BOOST_AUTO_TEST_CASE(inheritance_cast) BOOST_AUTO_TEST_CASE(unique_ptr) { - UniquePtr uptr = new TestStruct(); - UniquePtr uptr2 = std::move(uptr); + Seele::UniquePtr uptr = new TestStruct(); + Seele::UniquePtr uptr2 = std::move(uptr); BOOST_REQUIRE_EQUAL(uptr2->data, 10); BOOST_REQUIRE_EQUAL(uptr.isValid(), false); } +struct ThisReference +{ + ThisReference() + { + } + ~ThisReference() + { + data = 12; + } + Seele::RefPtr getRef() + { + return this; + } + uint32 data = 1; +}; + +BOOST_AUTO_TEST_CASE(this_reference) +{ + Seele::RefPtr ptr2; + { + Seele::RefPtr 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() \ No newline at end of file diff --git a/test/Engine/Fibers/CMakeLists.txt b/test/Engine/Fibers/CMakeLists.txt deleted file mode 100644 index 7a89398..0000000 --- a/test/Engine/Fibers/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -target_sources(Seele_unit_tests - PRIVATE - ../../../src/Engine/Fibers/JobQueue.cpp - ../../../src/Engine/Fibers/Fibers.cpp - Fibers.cpp) \ No newline at end of file diff --git a/test/Engine/Fibers/Fibers.cpp b/test/Engine/Fibers/Fibers.cpp deleted file mode 100644 index ea290ec..0000000 --- a/test/Engine/Fibers/Fibers.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "EngineTest.h" -#include "MinimalEngine.h" -#include "Fibers/Fibers.h" -#include -#include - -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() \ No newline at end of file