From 3b6eb3ebccc93760759094a5d56274a267eaa12b Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Thu, 18 Jul 2024 11:45:56 +0200 Subject: [PATCH] Fixing destruction --- res/shaders/BasePass.slang | 4 +- src/Benchmark/main.cpp | 1 + src/Editor/Asset/MeshLoader.cpp | 6 +-- src/Editor/Asset/TextureLoader.cpp | 14 ++--- src/Editor/main.cpp | 2 + src/Engine/Asset/AssetRegistry.cpp | 6 +++ src/Engine/Asset/AssetRegistry.h | 1 + src/Engine/Asset/TextureAsset.cpp | 5 +- src/Engine/Asset/TextureAsset.h | 3 +- src/Engine/Containers/List.h | 2 +- src/Engine/Graphics/Command.cpp | 2 + src/Engine/Graphics/Mesh.cpp | 5 -- src/Engine/Graphics/Mesh.h | 2 - src/Engine/Graphics/StaticMeshVertexData.cpp | 2 + src/Engine/Graphics/VertexData.cpp | 33 +++++++++++- src/Engine/Graphics/VertexData.h | 4 +- src/Engine/Graphics/Vulkan/Buffer.cpp | 21 +++++--- src/Engine/Graphics/Vulkan/Command.cpp | 11 +++- src/Engine/Graphics/Vulkan/Command.h | 1 + src/Engine/Graphics/Vulkan/Descriptor.cpp | 7 +-- src/Engine/Graphics/Vulkan/Descriptor.h | 5 -- src/Engine/Graphics/Vulkan/Graphics.cpp | 10 ++-- src/Engine/Graphics/Vulkan/RayTracing.cpp | 4 +- src/Engine/Material/Material.cpp | 6 +++ src/Engine/Material/Material.h | 1 + src/Engine/Scene/Scene.cpp | 10 +++- src/Engine/Scene/Scene.h | 2 + src/Engine/ThreadPool.cpp | 55 ++++++++++++++------ src/Engine/ThreadPool.h | 16 ++++-- src/Engine/Window/GameView.cpp | 12 ++--- src/Engine/Window/WindowManager.h | 2 +- 31 files changed, 173 insertions(+), 82 deletions(-) diff --git a/res/shaders/BasePass.slang b/res/shaders/BasePass.slang index ff02129..219ab0c 100644 --- a/res/shaders/BasePass.slang +++ b/res/shaders/BasePass.slang @@ -32,8 +32,8 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target } result += brdf.evaluateAmbient(); // gamma correction - result = result / (result + float3(1.0)); - result = pow(result, float3(1.0/2.2)); + //result = result / (result + float3(1.0)); + //result = pow(result, float3(1.0/2.2)); return float4(result, brdf.getAlpha()); } \ No newline at end of file diff --git a/src/Benchmark/main.cpp b/src/Benchmark/main.cpp index 5f1833a..9c58bb4 100644 --- a/src/Benchmark/main.cpp +++ b/src/Benchmark/main.cpp @@ -54,6 +54,7 @@ int main(int argc, char** argv) { while (windowManager->isActive()) { windowManager->render(); } + graphics->waitDeviceIdle(); vd->destroy(); return 0; diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index 4e8c1da..3db8101 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -533,8 +533,6 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArrayvertexData = vertexData; globalMeshes[meshIndex]->id = id; globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex]; - globalMeshes[meshIndex]->meshlets = std::move(meshlets); - globalMeshes[meshIndex]->indices = std::move(indices); globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices; globalMeshes[meshIndex]->blas = graphics->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{ .mesh = globalMeshes[meshIndex], @@ -563,8 +561,8 @@ void MeshLoader::import(MeshImportArgs args, PMeshAsset meshAsset) { meshAsset->setStatus(Asset::Status::Loading); Assimp::Importer importer; importer.ReadFile(args.filePath.string().c_str(), - (uint32)(aiProcess_JoinIdenticalVertices | aiProcess_FlipUVs | aiProcess_Triangulate | aiProcess_SortByPType | - aiProcess_GenBoundingBoxes | aiProcess_GenSmoothNormals | aiProcess_ImproveCacheLocality | + (uint32)(aiProcess_FlipUVs | aiProcess_Triangulate | aiProcess_SortByPType | + aiProcess_GenBoundingBoxes | aiProcess_GenSmoothNormals | aiProcess_GenUVCoords | aiProcess_FindDegenerates)); const aiScene* scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace); std::cout << importer.GetErrorString() << std::endl; diff --git a/src/Editor/Asset/TextureLoader.cpp b/src/Editor/Asset/TextureLoader.cpp index c73b854..a20ee04 100644 --- a/src/Editor/Asset/TextureLoader.cpp +++ b/src/Editor/Asset/TextureLoader.cpp @@ -14,6 +14,7 @@ #include #pragma GCC diagnostic pop #include "ktx.h" +#include #include using namespace Seele; @@ -110,13 +111,12 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { ktxBasisParams basisParams = { .structSize = sizeof(ktxBasisParams), .uastc = true, - .threadCount = std::thread::hardware_concurrency() - 2, + .threadCount = std::thread::hardware_concurrency(), .uastcFlags = KTX_PACK_UASTC_LEVEL_DEFAULT, .uastcRDO = true, }; //KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams)); - // - //KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 15)); + //KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 20)); char writer[100]; snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1"); @@ -126,7 +126,7 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { size_t texSize; KTX_ASSERT(ktxTexture_WriteToMemory(ktxTexture(kTexture), &texData, &texSize)); - //ktxTexture_WriteToNamedFile(ktxTexture(kTexture), args.filePath.filename().replace_extension(".ktx").generic_string().c_str()); + // ktxTexture_WriteToNamedFile(ktxTexture(kTexture), args.filePath.filename().replace_extension(".ktx").generic_string().c_str()); Array serialized(texSize); std::memcpy(serialized.data(), texData, texSize); @@ -138,7 +138,7 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { return; } - textureAsset->setTexture(std::move(serialized)); + //textureAsset->setTexture(std::move(serialized)); std::string path = (std::filesystem::path(args.importPath) / textureAsset->getName()).string().append(".asset"); auto assetStream = AssetRegistry::createWriteStream(std::move(path), std::ios::binary); @@ -150,11 +150,13 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { // write folder Serialization::save(buffer, textureAsset->getFolderPath()); // write asset data - textureAsset->save(buffer); + //textureAsset->save(buffer); + Serialization::save(buffer, serialized); buffer.writeToStream(assetStream); buffer.rewind(); + std::unique_lock l(AssetRegistry::get().assetLock); AssetRegistry::get().loadAsset(buffer); } diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index ad754bc..789ec04 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -93,6 +93,8 @@ int main() { while (windowManager->isActive() && getGlobals().running) { windowManager->render(); } + graphics->waitDeviceIdle(); + Material::destroy(); vd->destroy(); // export game diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index 2f204bf..bb0faa1 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -100,6 +100,7 @@ AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string_view fu } void AssetRegistry::initialize(const std::filesystem::path& _rootFolder, Gfx::PGraphics _graphics) { + std::unique_lock l(get().assetLock); this->graphics = _graphics; this->rootFolder = _rootFolder; this->assetRoot = new AssetFolder(""); @@ -279,26 +280,31 @@ void AssetRegistry::saveAsset(PAsset asset, uint64 identifier, const std::filesy std::filesystem::path AssetRegistry::getRootFolder() { return get().rootFolder; } void AssetRegistry::registerMesh(OMeshAsset mesh) { + std::unique_lock l(assetLock); AssetFolder* folder = getOrCreateFolder(mesh->getFolderPath()); folder->meshes[mesh->getName()] = std::move(mesh); } void AssetRegistry::registerTexture(OTextureAsset texture) { + std::unique_lock l(assetLock); AssetFolder* folder = getOrCreateFolder(texture->getFolderPath()); folder->textures[texture->getName()] = std::move(texture); } void AssetRegistry::registerFont(OFontAsset font) { + std::unique_lock l(assetLock); AssetFolder* folder = getOrCreateFolder(font->getFolderPath()); folder->fonts[font->getName()] = std::move(font); } void AssetRegistry::registerMaterial(OMaterialAsset material) { + std::unique_lock l(assetLock); AssetFolder* folder = getOrCreateFolder(material->getFolderPath()); folder->materials[material->getName()] = std::move(material); } void AssetRegistry::registerMaterialInstance(OMaterialInstanceAsset material) { + std::unique_lock l(assetLock); AssetFolder* folder = getOrCreateFolder(material->getFolderPath()); folder->instances[material->getName()] = std::move(material); } diff --git a/src/Engine/Asset/AssetRegistry.h b/src/Engine/Asset/AssetRegistry.h index 59bd09d..f3156a2 100644 --- a/src/Engine/Asset/AssetRegistry.h +++ b/src/Engine/Asset/AssetRegistry.h @@ -71,6 +71,7 @@ class AssetRegistry { std::ifstream internalCreateReadStream(const std::filesystem::path& relaitvePath, std::ios_base::openmode openmode = std::ios::in); std::filesystem::path rootFolder; + std::mutex assetLock; AssetFolder* assetRoot; Gfx::PGraphics graphics; bool release = false; diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index c3223ac..f8f5ec9 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -22,10 +22,13 @@ TextureAsset::TextureAsset(std::string_view folderPath, std::string_view name) : TextureAsset::~TextureAsset() {} -void TextureAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, ktxData); } +void TextureAsset::save(ArchiveBuffer& buffer) const { /* + Serialization::save(buffer, ktxData);*/ +} void TextureAsset::load(ArchiveBuffer& buffer) { ktxTexture2* ktxHandle; + Array ktxData; Serialization::load(buffer, ktxData); KTX_ASSERT( ktxTexture_CreateFromMemory(ktxData.data(), ktxData.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, (ktxTexture**)&ktxHandle)); diff --git a/src/Engine/Asset/TextureAsset.h b/src/Engine/Asset/TextureAsset.h index b42ccd3..b1fe4f7 100644 --- a/src/Engine/Asset/TextureAsset.h +++ b/src/Engine/Asset/TextureAsset.h @@ -13,13 +13,12 @@ class TextureAsset : public Asset { virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; Gfx::PTexture getTexture() { return texture; } - void setTexture(Array data) { ktxData = std::move(data); } + void setTexture(Array data) { } uint32 getWidth(); uint32 getHeight(); private: Gfx::OTexture texture; - Array ktxData; friend class TextureLoader; }; DEFINE_REF(TextureAsset) diff --git a/src/Engine/Containers/List.h b/src/Engine/Containers/List.h index 2bb908d..161191e 100644 --- a/src/Engine/Containers/List.h +++ b/src/Engine/Containers/List.h @@ -182,7 +182,7 @@ template > c _size = 0; } // Insert at the end - constexpr iterator add(const T& value) { return addInternal(value); } + constexpr iterator add(const T& value = T()) { return addInternal(value); } constexpr iterator add(T&& value) { return addInternal(std::move(value)); } template constexpr reference emplace(args... arguments) { std::allocator_traits::construct(allocator, tail, tail->prev, tail->next, arguments...); diff --git a/src/Engine/Graphics/Command.cpp b/src/Engine/Graphics/Command.cpp index c0002b8..2e72ba2 100644 --- a/src/Engine/Graphics/Command.cpp +++ b/src/Engine/Graphics/Command.cpp @@ -1,4 +1,5 @@ #include "Command.h" +#include "Command.h" using namespace Seele; using namespace Seele::Gfx; @@ -10,3 +11,4 @@ RenderCommand::~RenderCommand() {} ComputeCommand::ComputeCommand() {} ComputeCommand::~ComputeCommand() {} + diff --git a/src/Engine/Graphics/Mesh.cpp b/src/Engine/Graphics/Mesh.cpp index d40aecb..329c3a5 100644 --- a/src/Engine/Graphics/Mesh.cpp +++ b/src/Engine/Graphics/Mesh.cpp @@ -12,8 +12,6 @@ void Mesh::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, transform); Serialization::save(buffer, vertexData->getTypeName()); Serialization::save(buffer, vertexCount); - Serialization::save(buffer, indices); - Serialization::save(buffer, meshlets); Serialization::save(buffer, referencedMaterial->getFolderPath()); Serialization::save(buffer, referencedMaterial->getName()); vertexData->serializeMesh(id, vertexCount, buffer); @@ -25,15 +23,12 @@ void Mesh::load(ArchiveBuffer& buffer) { Serialization::load(buffer, typeName); Serialization::load(buffer, vertexCount); vertexData = VertexData::findByTypeName(typeName); - Serialization::load(buffer, indices); - Serialization::load(buffer, meshlets); std::string refFolder; Serialization::load(buffer, refFolder); std::string refId; Serialization::load(buffer, refId); referencedMaterial = AssetRegistry::findMaterialInstance(refFolder, refId); id = vertexData->allocateVertexData(vertexCount); - vertexData->loadMesh(id, indices, meshlets); vertexData->deserializeMesh(id, buffer); blas = buffer.getGraphics()->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{ .mesh = this, diff --git a/src/Engine/Graphics/Mesh.h b/src/Engine/Graphics/Mesh.h index 9366a5f..6ecbc6e 100644 --- a/src/Engine/Graphics/Mesh.h +++ b/src/Engine/Graphics/Mesh.h @@ -16,8 +16,6 @@ class Mesh { MeshId id; uint64 vertexCount; PMaterialInstanceAsset referencedMaterial; - Array indices; - Array meshlets; Gfx::OBottomLevelAS blas; void save(ArchiveBuffer& buffer) const; void load(ArchiveBuffer& buffer); diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 69d6a0b..704519c 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -53,6 +53,7 @@ void Seele::StaticMeshVertexData::loadColors(uint64 offset, const Array } void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) { + VertexData::serializeMesh(id, numVertices, buffer); uint64 offset; { std::unique_lock l(vertexDataLock); @@ -82,6 +83,7 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB } void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) { + VertexData::deserializeMesh(id, buffer); uint64 offset; { std::unique_lock l(vertexDataLock); diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 1f6a454..c2015cb 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -147,8 +147,7 @@ void VertexData::createDescriptors() { } } } - for (uint32 i = 0; i < transparentData.size(); ++i) - { + for (uint32 i = 0; i < transparentData.size(); ++i) { transparentData[i].offsets.instanceOffset = instanceData.size(); instanceData.add(transparentData[i].instanceData); instanceMeshData.add(transparentData[i].meshData); @@ -299,6 +298,35 @@ MeshId VertexData::allocateVertexData(uint64 numVertices) { return res; } +void VertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) { + std::unique_lock l(vertexDataLock); + Array out; + MeshData data = meshData[id]; + for (size_t i = 0; i < data.numMeshlets; ++i) + { + MeshletDescription& desc = meshlets[i + data.meshletOffset]; + Meshlet m; + std::memcpy(m.uniqueVertices, &vertexIndices[desc.vertexOffset], desc.vertexCount * sizeof(uint32)); + std::memcpy(m.primitiveLayout, &primitiveIndices[desc.primitiveOffset], desc.primitiveCount * 3 * sizeof(uint8)); + m.numPrimitives = desc.primitiveCount; + m.numVertices = desc.vertexCount; + m.boundingBox = desc.bounding; + out.add(std::move(m)); + } + Array ind(data.numIndices); + std::memcpy(ind.data(), &indices[data.firstIndex], data.numIndices * sizeof(uint32)); + Serialization::save(buffer, out); + Serialization::save(buffer, ind); +} + +void VertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) { + Array in; + Array ind; + Serialization::load(buffer, in); + Serialization::load(buffer, ind); + loadMesh(id, ind, in); +} + List vertexDataList; List VertexData::getList() { return vertexDataList; } @@ -362,6 +390,7 @@ void VertexData::init(Gfx::PGraphics _graphics) { } void VertexData::destroy() { + cullingOffsetBuffer = nullptr; instanceBuffer = nullptr; instanceMeshDataBuffer = nullptr; instanceDataLayout = nullptr; diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 0b5bb66..b35d39b 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -61,8 +61,8 @@ class VertexData { MeshId allocateVertexData(uint64 numVertices); uint64 getMeshOffset(MeshId id) const { return meshOffsets[id]; } uint64 getMeshVertexCount(MeshId id) { return meshVertexCounts[id]; } - virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) = 0; - virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) = 0; + virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer); + virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer); virtual void bindBuffers(Gfx::PRenderCommand command) = 0; virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0; virtual Gfx::PDescriptorSet getVertexDataSet() = 0; diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 79e86e0..9e143a6 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -54,6 +54,7 @@ void BufferAllocation::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageF .offset = 0, .size = size, }; + commandBuffer->bindResource(this); vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr); } @@ -77,6 +78,8 @@ void BufferAllocation::transferOwnership(Gfx::QueueType newOwner) { PCommandPool sourcePool = graphics->getQueueCommands(owner); PCommandPool dstPool = graphics->getQueueCommands(newOwner); assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex); + sourcePool->getCommands()->bindResource(this); + dstPool->getCommands()->bindResource(this); vkCmdPipelineBarrier(sourcePool->getCommands()->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr); vkCmdPipelineBarrier(dstPool->getCommands()->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, @@ -110,17 +113,15 @@ void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, vo Gfx::QueueType prevOwner = owner; // transferOwnership(Gfx::QueueType::TRANSFER); - PCommand cmd = graphics->getQueueCommands(Gfx::QueueType::TRANSFER)->getCommands(); + PCommand cmd = graphics->getQueueCommands(Gfx::QueueType::GRAPHICS)->getCommands(); VkBufferCopy copy = { .srcOffset = 0, .dstOffset = regionOffset, .size = regionSize, }; - vkCmdCopyBuffer(cmd->getHandle(), staging->buffer, buffer, 1, ©); - pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT); cmd->bindResource(PBufferAllocation(this)); cmd->bindResource(PBufferAllocation(staging)); + vkCmdCopyBuffer(cmd->getHandle(), staging->buffer, buffer, 1, ©); // transferOwnership(prevOwner); graphics->getDestructionManager()->queueResourceForDestruction(std::move(staging)); @@ -153,9 +154,9 @@ void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void .dstOffset = 0, .size = regionSize, }; - vkCmdCopyBuffer(cmd->getHandle(), buffer, staging->buffer, 1, ©); cmd->bindResource(PBufferAllocation(this)); cmd->bindResource(PBufferAllocation(staging)); + vkCmdCopyBuffer(cmd->getHandle(), buffer, staging->buffer, 1, ©); pool->submitCommands(); cmd->getFence()->wait(1000000); @@ -250,6 +251,7 @@ void Buffer::createBuffer(uint64 size, uint32 destIndex) { buffers[destIndex] = new BufferAllocation(graphics, name, info, allocInfo, initialOwner); if (createCleared) { PCommand command = graphics->getQueueCommands(initialOwner)->getCommands(); + command->bindResource(PBufferAllocation(buffers[destIndex])); vkCmdFillBuffer(command->getHandle(), buffers[destIndex]->buffer, 0, VK_WHOLE_SIZE, clearValue); pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); @@ -284,6 +286,8 @@ void Buffer::copyBuffer(uint64 src, uint64 dst) { .size = buffers[dst]->size, }; VkBufferMemoryBarrier srcBarriers[] = {srcBarrier, clearBarrier}; + command->bindResource(PBufferAllocation(buffers[src])); + command->bindResource(PBufferAllocation(buffers[dst])); vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 2, srcBarriers, 0, nullptr); VkBufferCopy region = { @@ -291,6 +295,8 @@ void Buffer::copyBuffer(uint64 src, uint64 dst) { .dstOffset = 0, .size = buffers[src]->size, }; + command->bindResource(PBufferAllocation(buffers[src])); + command->bindResource(PBufferAllocation(buffers[dst])); vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer, buffers[dst]->buffer, 1, ®ion); VkBufferMemoryBarrier dstBarrier = { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, @@ -303,6 +309,7 @@ void Buffer::copyBuffer(uint64 src, uint64 dst) { .offset = 0, .size = buffers[dst]->size, }; + command->bindResource(PBufferAllocation(buffers[dst])); vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &dstBarrier, 0, nullptr); } @@ -383,7 +390,9 @@ void ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) { } void ShaderBuffer::clear() { - vkCmdFillBuffer(graphics->getQueueCommands(getAlloc()->owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, + PCommand command = graphics->getQueueCommands(getAlloc()->owner)->getCommands(); + command->bindResource(PBufferAllocation(getAlloc())); + vkCmdFillBuffer(command->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0); } diff --git a/src/Engine/Graphics/Vulkan/Command.cpp b/src/Engine/Graphics/Vulkan/Command.cpp index 4c95b04..bb85746 100644 --- a/src/Engine/Graphics/Vulkan/Command.cpp +++ b/src/Engine/Graphics/Vulkan/Command.cpp @@ -245,7 +245,7 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array(); assert(descriptor->writeDescriptors.size() == 0); descriptor->bind(); - boundResources.add(descriptor.getHandle()); + boundResources.add(descriptor); for (auto binding : descriptor->boundResources) { for (auto res : binding) { res->bind(); @@ -269,7 +269,7 @@ void RenderCommand::bindDescriptor(const Array& descriptorS auto descriptorSet = descriptorSets[i].cast(); assert(descriptorSet->writeDescriptors.size() == 0); descriptorSet->bind(); - boundResources.add(descriptorSet.getHandle()); + boundResources.add(descriptorSet); for (auto binding : descriptorSet->boundResources) { for (auto res : binding) { @@ -550,3 +550,10 @@ void CommandPool::submitCommands(PSemaphore signalSemaphore) { command->begin(); command->waitForSemaphore(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, waitSemaphore); } + +void CommandPool::refreshCommands() { + for (uint32 i = 0; i < allocatedBuffers.size(); ++i) + { + allocatedBuffers[i]->checkFence(); + } +} diff --git a/src/Engine/Graphics/Vulkan/Command.h b/src/Engine/Graphics/Vulkan/Command.h index acb764e..100ca17 100644 --- a/src/Engine/Graphics/Vulkan/Command.h +++ b/src/Engine/Graphics/Vulkan/Command.h @@ -144,6 +144,7 @@ class CommandPool { OComputeCommand createComputeCommand(const std::string& name); constexpr VkCommandPool getHandle() const { return commandPool; } void submitCommands(PSemaphore signalSemaphore = nullptr); + void refreshCommands(); private: PGraphics graphics; diff --git a/src/Engine/Graphics/Vulkan/Descriptor.cpp b/src/Engine/Graphics/Vulkan/Descriptor.cpp index 771bf6b..8f71274 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.cpp +++ b/src/Engine/Graphics/Vulkan/Descriptor.cpp @@ -125,7 +125,7 @@ Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() { if (cachedHandles[setIndex] == nullptr) { cachedHandles[setIndex] = new DescriptorSet(graphics, this); } - if (cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) { + if (cachedHandles[setIndex]->isCurrentlyBound()) { // Currently in use, skip continue; } @@ -133,7 +133,6 @@ Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() { // If it hasnt been initialized, allocate it VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle)); } - cachedHandles[setIndex]->allocate(); PDescriptorSet vulkanSet = cachedHandles[setIndex]; @@ -153,7 +152,6 @@ void DescriptorPool::reset() { if (cachedHandles[i] == nullptr) { return; } - cachedHandles[i]->free(); } if (nextAlloc != nullptr) { nextAlloc->reset(); @@ -161,8 +159,7 @@ void DescriptorPool::reset() { } DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) - : Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), setHandle(VK_NULL_HANDLE), graphics(graphics), owner(owner), - bindCount(0), currentlyInUse(false) { + : Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), setHandle(VK_NULL_HANDLE), graphics(graphics), owner(owner){ boundResources.resize(owner->getLayout()->getBindings().size()); for (uint32 i = 0; i < boundResources.size(); ++i) { diff --git a/src/Engine/Graphics/Vulkan/Descriptor.h b/src/Engine/Graphics/Vulkan/Descriptor.h index e23982d..4226ad0 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.h +++ b/src/Engine/Graphics/Vulkan/Descriptor.h @@ -60,9 +60,6 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource { virtual void updateSamplerArray(uint32 binding, Array samplers) override; virtual void updateAccelerationStructure(uint32 binding, Gfx::PTopLevelAS as) override; - constexpr bool isCurrentlyInUse() const { return currentlyInUse; } - constexpr void allocate() { currentlyInUse = true; } - constexpr void free() { currentlyInUse = false; } constexpr VkDescriptorSet getHandle() const { return setHandle; } private: @@ -78,8 +75,6 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource { VkDescriptorSet setHandle; PGraphics graphics; PDescriptorPool owner; - uint32 bindCount; - bool currentlyInUse; friend class DescriptorPool; friend class Command; friend class RenderCommand; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index aeb9e4a..7535afa 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -100,7 +100,6 @@ VkDeviceAddress vkGetAccelerationStructureDeviceAddressKHR(VkDevice device, cons Graphics::Graphics() : instance(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE), callback(VK_NULL_HANDLE) {} Graphics::~Graphics() { - vkDeviceWaitIdle(handle); pipelineCache = nullptr; allocatedFramebuffers.clear(); shaderCompiler = nullptr; @@ -166,7 +165,10 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { void Graphics::endRenderPass() { getGraphicsCommands()->getCommands()->endRenderPass(); } -void Graphics::waitDeviceIdle() { vkDeviceWaitIdle(handle); } +void Graphics::waitDeviceIdle() { + vkDeviceWaitIdle(handle); + getGraphicsCommands()->refreshCommands(); +} void Graphics::executeCommands(Array commands) { getGraphicsCommands()->getCommands()->executeCommands(std::move(commands)); @@ -527,11 +529,9 @@ void Graphics::buildBottomLevelAccelerationStructures(Array PCommand cmd = graphicsCommands->getCommands(); vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), buildGeometries.size(), buildGeometries.data(), buildRangePointers.data()); - transformBuffer->bind(); cmd->bindResource(PBufferAllocation(transformBuffer)); destructionManager->queueResourceForDestruction(std::move(transformBuffer)); for (auto& scratchAlloc : scratchBuffers) { - scratchAlloc->bind(); cmd->bindResource(PBufferAllocation(scratchAlloc)); destructionManager->queueResourceForDestruction(std::move(scratchAlloc)); } @@ -655,7 +655,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo) { extensions.add("VK_KHR_portability_enumeration"); #endif Array layers = initInfo.layers; - layers.add("VK_LAYER_KHRONOS_validation"); + //layers.add("VK_LAYER_KHRONOS_validation"); VkInstanceCreateInfo info = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pNext = nullptr, diff --git a/src/Engine/Graphics/Vulkan/RayTracing.cpp b/src/Engine/Graphics/Vulkan/RayTracing.cpp index 3b593ca..7eee20f 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.cpp +++ b/src/Engine/Graphics/Vulkan/RayTracing.cpp @@ -190,14 +190,12 @@ TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& crea }; vkCmdPipelineBarrier(cmd->getHandle(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0, 0, nullptr, 1, &barrier, 0, nullptr); - scratchBuffer->bind(); + cmd->bindResource(PBufferAllocation(scratchBuffer)); graphics->getDestructionManager()->queueResourceForDestruction(std::move(scratchBuffer)); - buffer->bind(); cmd->bindResource(PBufferAllocation(buffer)); - instanceAllocation->bind(); cmd->bindResource(PBufferAllocation(instanceAllocation)); } diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index bc90b05..5ed5eed 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -63,6 +63,12 @@ void Material::init(Gfx::PGraphics graphics) { }); } +void Material::destroy() { + floatBuffer = nullptr; + set = nullptr; + layout = nullptr; +} + void Material::updateDescriptor() { floatBuffer->rotateBuffer(floatData.size() * sizeof(float)); floatBuffer->updateContents(ShaderBufferCreateInfo{ diff --git a/src/Engine/Material/Material.h b/src/Engine/Material/Material.h index 966a914..175b4e2 100644 --- a/src/Engine/Material/Material.h +++ b/src/Engine/Material/Material.h @@ -14,6 +14,7 @@ class Material { std::string materialName, Array expressions, Array parameter, MaterialNode brdf); ~Material(); static void init(Gfx::PGraphics graphics); + static void destroy(); static Gfx::PDescriptorLayout getDescriptorLayout() { return layout; } static Gfx::PDescriptorSet getDescriptorSet() { return set; } static void updateDescriptor(); diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp index 2d1c67f..c7ae0ee 100644 --- a/src/Engine/Scene/Scene.cpp +++ b/src/Engine/Scene/Scene.cpp @@ -9,7 +9,7 @@ #include "Component/Transform.h" #include "Graphics/Graphics.h" #include "Graphics/Mesh.h" - +#include "Graphics/StaticMeshVertexData.h" using namespace Seele; @@ -17,4 +17,12 @@ Scene::Scene(Gfx::PGraphics graphics) : graphics(graphics), lightEnv(new LightEn Scene::~Scene() {} +void Scene::bakeLighting() { + const auto& matData = StaticMeshVertexData::getInstance()->getMaterialData(); + for (const auto& mat : matData) + { + + } +} + void Scene::update(float deltaTime) { physics.update(deltaTime); } diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h index b2deed0..59d7238 100644 --- a/src/Engine/Scene/Scene.h +++ b/src/Engine/Scene/Scene.h @@ -15,6 +15,7 @@ class Scene { public: Scene(Gfx::PGraphics graphics); ~Scene(); + void bakeLighting(); void update(float deltaTime); entt::entity createEntity() { return registry.create(); } void destroyEntity(entt::entity identifier) { registry.destroy(identifier); } @@ -39,6 +40,7 @@ class Scene { Gfx::PGraphics graphics; OLightEnvironment lightEnv; PhysicsSystem physics; + Array lightMaps; }; DEFINE_REF(Scene) } // namespace Seele \ No newline at end of file diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index 11fc4ab..07b1fce 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -15,9 +15,9 @@ ThreadPool::ThreadPool(uint32 numWorkers) { ThreadPool::~ThreadPool() { { - std::unique_lock l(taskLock); + std::unique_lock l(queueLock); running = false; - taskCV.notify_all(); + queueCV.notify_all(); } for (auto& worker : workers) { worker.join(); @@ -26,33 +26,54 @@ ThreadPool::~ThreadPool() { void ThreadPool::runAndWait(List> functions) { std::unique_lock l(taskLock); - currentTask.numRemaining = functions.size(); - currentTask.functions = std::move(functions); - taskCV.notify_all(); - - while (currentTask.numRemaining > 0) { + auto newTask = runningTasks.add(); + newTask->numRemaining = functions.size(); + { + std::unique_lock q(queueLock); + while (!functions.empty()) { + queue.add(QueueEntry{ + .func = std::move(functions.back()), + .task = &*newTask, + }); + functions.popBack(); + } + queueCV.notify_all(); + } + while (newTask->numRemaining > 0) { completedCV.wait(l); } + runningTasks.remove(newTask); +} + +void ThreadPool::runAsync(std::function func) { + std::unique_lock l(queueLock); + queue.add(QueueEntry{ + .func = std::move(func), + .task = nullptr, + }); + queueCV.notify_one(); } void ThreadPool::work() { while (running) { - std::unique_lock l(taskLock); - while (currentTask.functions.empty()) { - taskCV.wait(l); + std::unique_lock l(queueLock); + while (queue.empty()) { + queueCV.wait(l); if (!running) { return; } } - auto func = std::move(currentTask.functions.front()); - currentTask.functions.popFront(); + auto entry = std::move(queue.front()); + queue.popFront(); l.unlock(); - func(); + entry.func(); l.lock(); - currentTask.numRemaining--; - if (currentTask.numRemaining == 0) { - currentTask.functions.clear(); - completedCV.notify_one(); + if (entry.task != nullptr) { + std::unique_lock t(taskLock); + entry.task->numRemaining--; + if (entry.task->numRemaining == 0) { + completedCV.notify_one(); + } } } } diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index 15e4e2e..0eef80b 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -12,16 +12,24 @@ class ThreadPool { void runAndWait(List> functions); void runAsync(std::function func); private: - struct Task { + struct TaskGroup { uint64 numRemaining = 0; - List> functions; }; + struct QueueEntry { + std::function func; + TaskGroup* task = nullptr; + }; + + std::mutex queueLock; + std::condition_variable queueCV; + List queue; + void work(); Array workers; + std::mutex taskLock; - std::condition_variable taskCV; std::condition_variable completedCV; - Task currentTask; + List runningTasks; bool running = true; }; ThreadPool& getThreadPool(); diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index 5a8a0a1..e40c96b 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -23,12 +23,12 @@ using namespace Seele; GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath) : View(graphics, window, createInfo, "Game"), scene(new Scene(graphics)), gameInterface(dllPath) { reloadGame(); - //renderGraph.addPass(new CachedDepthPass(graphics, scene)); - //renderGraph.addPass(new DepthCullingPass(graphics, scene)); - //renderGraph.addPass(new VisibilityPass(graphics, scene)); - //renderGraph.addPass(new LightCullingPass(graphics, scene)); - //renderGraph.addPass(new BasePass(graphics, scene)); - renderGraph.addPass(new RayTracingPass(graphics, scene)); + renderGraph.addPass(new CachedDepthPass(graphics, scene)); + renderGraph.addPass(new DepthCullingPass(graphics, scene)); + renderGraph.addPass(new VisibilityPass(graphics, scene)); + renderGraph.addPass(new LightCullingPass(graphics, scene)); + renderGraph.addPass(new BasePass(graphics, scene)); + //renderGraph.addPass(new RayTracingPass(graphics, scene)); renderGraph.setViewport(viewport); renderGraph.createRenderPass(); } diff --git a/src/Engine/Window/WindowManager.h b/src/Engine/Window/WindowManager.h index c447d47..0361ed5 100644 --- a/src/Engine/Window/WindowManager.h +++ b/src/Engine/Window/WindowManager.h @@ -11,7 +11,7 @@ class WindowManager { OWindow addWindow(Gfx::PGraphics graphics, const WindowCreateInfo& createInfo); void render(); void notifyWindowClosed(PWindow window); - bool isActive() const { return windows.size(); } + bool isActive() const { return getGlobals().running && windows.size(); } private: Array windows;