From 42b0d5034c0962f8b60aee2f33d7700566b14b25 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Sun, 14 Nov 2021 20:36:53 +0100 Subject: [PATCH] looks like command buffers need to be externally synchronized --- src/Engine/Asset/AssetRegistry.cpp | 1 + src/Engine/Containers/Array.h | 2 +- src/Engine/Containers/Map.h | 2 +- src/Engine/Graphics/CMakeLists.txt | 1 + src/Engine/Graphics/GraphicsResources.h | 3 +- src/Engine/Graphics/MeshBatch.cpp | 28 + src/Engine/Graphics/MeshBatch.h | 26 +- src/Engine/Graphics/ShaderCompiler.cpp | 1 + .../Graphics/Vulkan/VulkanAllocator.cpp | 498 +++++------ src/Engine/Graphics/Vulkan/VulkanBuffer.cpp | 14 +- .../Graphics/Vulkan/VulkanCommandBuffer.cpp | 34 + .../Graphics/Vulkan/VulkanCommandBuffer.h | 4 + .../Graphics/Vulkan/VulkanFramebuffer.cpp | 4 +- src/Engine/Graphics/Vulkan/VulkanGraphics.cpp | 811 +++++++++--------- src/Engine/Graphics/Vulkan/VulkanGraphics.h | 126 ++- .../Vulkan/VulkanGraphicsResources.cpp | 55 +- .../Graphics/Vulkan/VulkanGraphicsResources.h | 572 ++++++------ .../Graphics/Vulkan/VulkanPipelineCache.cpp | 3 + .../Graphics/Vulkan/VulkanPipelineCache.h | 1 + src/Engine/Graphics/Vulkan/VulkanTexture.cpp | 11 +- src/Engine/Material/MaterialAsset.cpp | 1 + src/Engine/MinimalEngine.h | 22 +- src/Engine/ThreadPool.cpp | 4 +- src/Engine/ThreadPool.h | 4 + src/Engine/UI/Elements/Element.cpp | 1 + src/Engine/UI/System.cpp | 1 + src/Engine/Window/InspectorView.cpp | 2 + src/Engine/Window/SceneView.cpp | 2 + src/Engine/Window/Window.cpp | 1 + 29 files changed, 1121 insertions(+), 1114 deletions(-) create mode 100644 src/Engine/Graphics/MeshBatch.cpp diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index f316225..c485937 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -5,6 +5,7 @@ #include "MaterialLoader.h" #include "MeshLoader.h" #include "Material/MaterialAsset.h" +#include "Graphics/Mesh.h" #include "Graphics/Graphics.h" #include "Window/WindowManager.h" #include "MeshAsset.h" diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 3afa991..b5191ab 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -179,7 +179,7 @@ namespace Seele } allocator = other.allocator; } - if(other.arraySize > allocated) + if(_data == nullptr || other.arraySize > allocated) { if(_data != nullptr) { diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 1dc7d53..0aba1f8 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -502,7 +502,7 @@ private: if (!isValid(r)) { nodeContainer.emplace(std::forward(key)); - return 0; + return nodeContainer.size() - 1; } r = splay(r, key); Node* node = getNode(r); diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index c465e57..07b9db9 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -10,6 +10,7 @@ target_sources(SeeleEngine Mesh.h Mesh.cpp MeshBatch.h + MeshBatch.cpp RenderMaterial.h RenderMaterial.cpp ShaderCompiler.h diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index ecd3d4b..1dcd4d7 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -3,7 +3,6 @@ #include "Containers/Array.h" #include "Containers/List.h" #include "GraphicsInitializer.h" -#include "MeshBatch.h" #include #include @@ -17,6 +16,8 @@ namespace Seele struct VertexInputStream; struct VertexStreamComponent; class VertexInputType; +struct MeshBatchElement; +DECLARE_REF(MaterialAsset) namespace Gfx { DECLARE_REF(Graphics) diff --git a/src/Engine/Graphics/MeshBatch.cpp b/src/Engine/Graphics/MeshBatch.cpp new file mode 100644 index 0000000..5c5091b --- /dev/null +++ b/src/Engine/Graphics/MeshBatch.cpp @@ -0,0 +1,28 @@ +#include "MeshBatch.h" +#include "GraphicsResources.h" +#include "VertexShaderInput.h" +#include "Material/MaterialAsset.h" + +using namespace Seele; + +MeshBatchElement::MeshBatchElement() + : uniformBuffer(nullptr) + , indexBuffer(nullptr) + , firstIndex(0) + , numPrimitives(0) + , numInstances(1) + , baseVertexIndex(0) + , minVertexIndex(0) + , maxVertexIndex(0) + , indirectArgsBuffer(nullptr) +{} +MeshBatch::MeshBatch() + : useReverseCulling(false) + , isBackfaceCullingDisabled(false) + , isCastingShadow(true) + , useWireframe(false) + , topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) + , vertexInput(nullptr) + , material(nullptr) +{ +} \ No newline at end of file diff --git a/src/Engine/Graphics/MeshBatch.h b/src/Engine/Graphics/MeshBatch.h index 5b2a33f..b9ffc8a 100644 --- a/src/Engine/Graphics/MeshBatch.h +++ b/src/Engine/Graphics/MeshBatch.h @@ -1,9 +1,10 @@ #pragma once +#include "GraphicsEnums.h" namespace Seele { -DECLARE_REF(MaterialAsset) DECLARE_REF(VertexShaderInput) +DECLARE_REF(MaterialAsset) DECLARE_NAME_REF(Gfx, VertexBuffer) DECLARE_NAME_REF(Gfx, IndexBuffer) DECLARE_NAME_REF(Gfx, UniformBuffer) @@ -29,17 +30,7 @@ public: uint8 isInstanced : 1; Gfx::PVertexBuffer indirectArgsBuffer; - MeshBatchElement() - : uniformBuffer(nullptr) - , indexBuffer(nullptr) - , firstIndex(0) - , numPrimitives(0) - , numInstances(1) - , baseVertexIndex(0) - , minVertexIndex(0) - , maxVertexIndex(0) - , indirectArgsBuffer(nullptr) - {} + MeshBatchElement(); }; struct MeshBatch { @@ -76,16 +67,7 @@ struct MeshBatch return count; } - MeshBatch() - : useReverseCulling(false) - , isBackfaceCullingDisabled(false) - , isCastingShadow(true) - , useWireframe(false) - , topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) - , vertexInput(nullptr) - , material(nullptr) - { - } + MeshBatch(); }; DECLARE_REF(PrimitiveComponent) struct StaticMeshBatch : public MeshBatch diff --git a/src/Engine/Graphics/ShaderCompiler.cpp b/src/Engine/Graphics/ShaderCompiler.cpp index 0dee341..99000bb 100644 --- a/src/Engine/Graphics/ShaderCompiler.cpp +++ b/src/Engine/Graphics/ShaderCompiler.cpp @@ -1,6 +1,7 @@ #include "ShaderCompiler.h" #include "Material/MaterialAsset.h" #include "VertexShaderInput.h" +#include "Graphics.h" using namespace Seele; using namespace Seele::Gfx; diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp index 45003e1..5e81b27 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp @@ -5,67 +5,67 @@ using namespace Seele::Vulkan; SubAllocation::SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize) - : owner(owner) - , size(size) - , allocatedOffset(allocatedOffset) - , alignedOffset(alignedOffset) - , allocatedSize(allocatedSize) + : owner(owner) + , size(size) + , allocatedOffset(allocatedOffset) + , alignedOffset(alignedOffset) + , allocatedSize(allocatedSize) { } SubAllocation::~SubAllocation() { - owner->markFree(this); + owner->markFree(this); } VkDeviceMemory SubAllocation::getHandle() const { - return owner->getHandle(); + return owner->getHandle(); } bool SubAllocation::isReadable() const { - return owner->isReadable(); + return owner->isReadable(); } void *SubAllocation::getMappedPointer() { - return (uint8 *)owner->getMappedPointer() + alignedOffset; + return (uint8 *)owner->getMappedPointer() + alignedOffset; } void SubAllocation::flushMemory() { - owner->flushMemory(); + owner->flushMemory(); } void SubAllocation::invalidateMemory() { - owner->invalidateMemory(); + owner->invalidateMemory(); } Allocation::Allocation(PGraphics graphics, Allocator *allocator, VkDeviceSize size, uint8 memoryTypeIndex, - VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo) - : device(graphics->getDevice()) - , allocator(allocator) - , bytesAllocated(0) - , bytesUsed(0) - , readable(properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) - , properties(properties) - , memoryTypeIndex(memoryTypeIndex) + VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo) + : device(graphics->getDevice()) + , allocator(allocator) + , bytesAllocated(0) + , bytesUsed(0) + , readable(properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + , properties(properties) + , memoryTypeIndex(memoryTypeIndex) { - VkMemoryAllocateInfo allocInfo = - init::MemoryAllocateInfo(); - allocInfo.allocationSize = size; - allocInfo.memoryTypeIndex = memoryTypeIndex; - isDedicated = dedicatedInfo != nullptr; - allocInfo.pNext = dedicatedInfo; - VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory)); - bytesAllocated = size; - PSubAllocation freeRange = new SubAllocation(this, 0, size, 0, size); - freeRanges[0] = freeRange; + VkMemoryAllocateInfo allocInfo = + init::MemoryAllocateInfo(); + allocInfo.allocationSize = size; + allocInfo.memoryTypeIndex = memoryTypeIndex; + isDedicated = dedicatedInfo != nullptr; + allocInfo.pNext = dedicatedInfo; + VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory)); + bytesAllocated = size; + PSubAllocation freeRange = new SubAllocation(this, 0, size, 0, size); + freeRanges[0] = freeRange; - canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - isMapped = false; + canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + isMapped = false; } Allocation::~Allocation() @@ -74,203 +74,213 @@ Allocation::~Allocation() PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment) { - std::unique_lock lck(lock); - if (isDedicated) - { - if (activeAllocations.empty() && requestedSize == bytesAllocated) - { - PSubAllocation suballoc = freeRanges[0]; - activeAllocations[0] = suballoc.getHandle(); - freeRanges.clear(); - bytesUsed += requestedSize; - return suballoc; - } - else - { - return nullptr; - } - } - for (auto it : freeRanges) - { - PSubAllocation freeAllocation = it.value; - VkDeviceSize allocatedOffset = freeAllocation->allocatedOffset; - VkDeviceSize alignedOffset = align(allocatedOffset, alignment); - VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset; - VkDeviceSize size = alignmentAdjustment + requestedSize; - if (freeAllocation->size == size) - { - freeRanges.erase(allocatedOffset); - activeAllocations[allocatedOffset] = freeAllocation.getHandle(); - bytesUsed += size; - return freeAllocation; - } - else if (size < freeAllocation->allocatedSize) - { - freeAllocation->size -= size; - freeAllocation->allocatedSize -= size; - freeAllocation->allocatedOffset += size; - freeAllocation->alignedOffset += size; - PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size); - activeAllocations[allocatedOffset] = subAlloc.getHandle(); - freeRanges.erase(allocatedOffset); - freeRanges[freeAllocation->allocatedOffset] = freeAllocation; - bytesUsed += size; - return subAlloc; - } - } - return nullptr; + std::unique_lock lck(lock); + if (isDedicated) + { + if (activeAllocations.empty() && requestedSize == bytesAllocated) + { + PSubAllocation suballoc = freeRanges[0]; + activeAllocations[0] = suballoc.getHandle(); + freeRanges.clear(); + bytesUsed += requestedSize; + return suballoc; + } + else + { + return nullptr; + } + } + for (auto it : freeRanges) + { + PSubAllocation freeAllocation = it.value; + VkDeviceSize allocatedOffset = freeAllocation->allocatedOffset; + VkDeviceSize alignedOffset = align(allocatedOffset, alignment); + VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset; + VkDeviceSize size = alignmentAdjustment + requestedSize; + if (freeAllocation->size == size) + { + freeRanges.erase(allocatedOffset); + activeAllocations[allocatedOffset] = freeAllocation.getHandle(); + bytesUsed += size; + return freeAllocation; + } + else if (size < freeAllocation->allocatedSize) + { + freeAllocation->size -= size; + freeAllocation->allocatedSize -= size; + freeAllocation->allocatedOffset += size; + freeAllocation->alignedOffset += size; + PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size); + activeAllocations[allocatedOffset] = subAlloc.getHandle(); + freeRanges.erase(allocatedOffset); + freeRanges[freeAllocation->allocatedOffset] = freeAllocation; + bytesUsed += size; + return subAlloc; + } + } + return nullptr; } void Allocation::markFree(SubAllocation *allocation) { - // Dont free if it is already a free allocation, since they also mark themselves on deletion - if (freeRanges.find(allocation->allocatedOffset) != freeRanges.end()) - { - return; - } - VkDeviceSize lowerBound = allocation->allocatedOffset; - VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize; - PSubAllocation allocHandle; - std::unique_lock lck(lock); - //Join lower bound - for (auto freeRange : freeRanges) - { - PSubAllocation freeAlloc = freeRange.value; - if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound) - { - //extend freeAlloc by the allocatedSize - freeAlloc->allocatedSize += allocation->allocatedSize; - allocHandle = freeAlloc; - break; - } - } - //Join upper bound - auto foundAlloc = freeRanges.find(upperBound); - if (foundAlloc != freeRanges.end()) - { - // There is a free allocation ending where the new free one ends - if (allocHandle != nullptr) - { - // extend allocHandle by another foundAlloc->allocatedSize bytes - allocHandle->allocatedSize += foundAlloc->value->allocatedSize; - freeRanges.erase(foundAlloc->key); - } - else - { - // set foundAlloc back by size amount - allocHandle = foundAlloc->value; - // remove from offset map since key changes - freeRanges.erase(foundAlloc->key); - allocHandle->allocatedOffset -= allocation->allocatedSize; - allocHandle->alignedOffset -= allocation->allocatedSize; - // place back at correct offset - freeRanges[allocHandle->allocatedOffset] = allocHandle; - } - } - if (allocHandle == nullptr) - { - allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize); - freeRanges[allocation->allocatedOffset] = allocHandle; - } - activeAllocations.erase(allocation->allocatedOffset); - bytesUsed -= allocation->allocatedSize; + // Dont free if it is already a free allocation, since they also mark themselves on deletion + if (freeRanges.find(allocation->allocatedOffset) != freeRanges.end()) + { + return; + } + VkDeviceSize lowerBound = allocation->allocatedOffset; + VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize; + PSubAllocation allocHandle; + PSubAllocation freeRangeToDelete; - // TODO: delete allocation when bytesUsed == 0 + std::unique_lock lck(lock); + //Join lower bound + for (auto freeRange : freeRanges) + { + PSubAllocation freeAlloc = freeRange.value; + if (freeAlloc->allocatedOffset <= lowerBound + && freeAlloc->allocatedOffset + freeAlloc->allocatedSize >= upperBound) + { + // allocation is already in a free region + return; + } + if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound) + { + //extend freeAlloc by the allocatedSize + freeAlloc->allocatedSize += allocation->allocatedSize; + allocHandle = freeAlloc; + break; + } + } + //Join upper bound + auto foundAlloc = freeRanges.find(upperBound); + if (foundAlloc != freeRanges.end()) + { + freeRangeToDelete = foundAlloc->value; + // There is a free allocation ending where the new free one ends + if (allocHandle != nullptr) + { + // extend allocHandle by another foundAlloc->allocatedSize bytes + allocHandle->allocatedSize += foundAlloc->value->allocatedSize; + freeRanges.erase(foundAlloc->key); + } + else + { + // set foundAlloc back by size amount + allocHandle = foundAlloc->value; + allocHandle->allocatedOffset -= allocation->allocatedSize; + allocHandle->alignedOffset -= allocation->allocatedSize; + // place back at correct offset + freeRanges[allocHandle->allocatedOffset] = allocHandle; + // remove from offset map since key changes + freeRanges.erase(foundAlloc->key); + } + } + + if (allocHandle == nullptr) + { + allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize); + freeRanges[allocation->allocatedOffset] = allocHandle; + } + activeAllocations.erase(allocation->allocatedOffset); + lock.unlock(); + bytesUsed -= allocation->allocatedSize; + // TODO: delete allocation when bytesUsed == 0 } Allocator::Allocator(PGraphics graphics) - : graphics(graphics) + : graphics(graphics) { - vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties); - heaps.resize(memProperties.memoryHeapCount); - for (size_t i = 0; i < memProperties.memoryHeapCount; ++i) - { - VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i]; - HeapInfo &heapInfo = heaps[i]; - heapInfo.maxSize = memoryHeap.size; - } + vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties); + heaps.resize(memProperties.memoryHeapCount); + for (size_t i = 0; i < memProperties.memoryHeapCount; ++i) + { + VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i]; + HeapInfo &heapInfo = heaps[i]; + heapInfo.maxSize = memoryHeap.size; + } } Allocator::~Allocator() { - std::unique_lock lck(lock); - for (auto heap : heaps) - { - for (auto alloc : heap.allocations) - { - assert(alloc->activeAllocations.empty()); - assert(alloc->freeRanges.size() == 1); - } - heap.allocations.clear(); - } - graphics = nullptr; + std::unique_lock lck(lock); + for (auto heap : heaps) + { + for (auto alloc : heap.allocations) + { + assert(alloc->activeAllocations.empty()); + assert(alloc->freeRanges.size() == 1); + } + heap.allocations.clear(); + } + graphics = nullptr; } PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo) { - std::unique_lock lck(lock); - const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements; - uint8 memoryTypeIndex; - VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex)); - uint32 heapIndex = memProperties.memoryTypes[memoryTypeIndex].heapIndex; + std::unique_lock lck(lock); + const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements; + uint8 memoryTypeIndex; + VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex)); + uint32 heapIndex = memProperties.memoryTypes[memoryTypeIndex].heapIndex; - if (memRequirements2.pNext != nullptr) - { - VkMemoryDedicatedRequirements *dedicatedReq = (VkMemoryDedicatedRequirements *)memRequirements2.pNext; - if (dedicatedReq->prefersDedicatedAllocation) - { - PAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo); - heaps[heapIndex].allocations.add(newAllocation); - return newAllocation->getSuballocation(requirements.size, requirements.alignment); - } - } - for (auto alloc : heaps[heapIndex].allocations) - { - PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment); - if (suballoc != nullptr) - { - return suballoc; - } - } + if (memRequirements2.pNext != nullptr) + { + VkMemoryDedicatedRequirements *dedicatedReq = (VkMemoryDedicatedRequirements *)memRequirements2.pNext; + if (dedicatedReq->prefersDedicatedAllocation) + { + PAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo); + heaps[heapIndex].allocations.add(newAllocation); + return newAllocation->getSuballocation(requirements.size, requirements.alignment); + } + } + for (auto alloc : heaps[heapIndex].allocations) + { + PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment); + if (suballoc != nullptr) + { + return suballoc; + } + } - // no suitable allocations found, allocate new block - PAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr); - heaps[heapIndex].allocations.add(newAllocation); - return newAllocation->getSuballocation(requirements.size, requirements.alignment); + // no suitable allocations found, allocate new block + PAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr); + heaps[heapIndex].allocations.add(newAllocation); + return newAllocation->getSuballocation(requirements.size, requirements.alignment); } void Allocator::free(Allocation *allocation) { - std::unique_lock lck(lock); - for (auto heap : heaps) - { - for (uint32 i = 0; i < heap.allocations.size(); ++i) - { - if (heap.allocations[i] == allocation) - { - heap.allocations.remove(i, false); - return; - } - } - } + std::unique_lock lck(lock); + for (auto heap : heaps) + { + for (uint32 i = 0; i < heap.allocations.size(); ++i) + { + if (heap.allocations[i] == allocation) + { + heap.allocations.remove(i, false); + return; + } + } + } } VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8 *typeIndex) { - for (uint8 memoryIndex = 0; memoryIndex < memProperties.memoryTypeCount && typeBits; ++memoryIndex) - { - if ((typeBits & 1) == 1) - { - if ((memProperties.memoryTypes[memoryIndex].propertyFlags & properties) == properties) - { - *typeIndex = memoryIndex; - return VK_SUCCESS; - } - } - typeBits >>= 1; - } + for (uint8 memoryIndex = 0; memoryIndex < memProperties.memoryTypeCount && typeBits; ++memoryIndex) + { + if ((typeBits & 1) == 1) + { + if ((memProperties.memoryTypes[memoryIndex].propertyFlags & properties) == properties) + { + *typeIndex = memoryIndex; + return VK_SUCCESS; + } + } + typeBits >>= 1; + } - return VK_ERROR_FORMAT_NOT_SUPPORTED; + return VK_ERROR_FORMAT_NOT_SUPPORTED; } StagingBuffer::StagingBuffer() @@ -282,7 +292,7 @@ StagingBuffer::~StagingBuffer() } StagingManager::StagingManager(PGraphics graphics, PAllocator allocator) - : graphics(graphics), allocator(allocator) + : graphics(graphics), allocator(allocator) { } @@ -296,55 +306,55 @@ void StagingManager::clearPending() PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead) { - std::unique_lock l(lock); - for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it) - { - auto freeBuffer = *it; - if (freeBuffer->getSize() == size && freeBuffer->isReadable() == bCPURead && freeBuffer->usage == usage) - { - //std::cout << "Reusing staging buffer" << std::endl; - activeBuffers.add(freeBuffer.getHandle()); - freeBuffers.remove(it, false); - return freeBuffer; - } - } - //std::cout << "Creating new stagingbuffer" << std::endl; - PStagingBuffer stagingBuffer = new StagingBuffer(); - VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size); - stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - VkDevice vulkanDevice = graphics->getDevice(); + std::unique_lock l(lock); + for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it) + { + auto freeBuffer = *it; + if (freeBuffer->getSize() == size && freeBuffer->isReadable() == bCPURead && freeBuffer->usage == usage) + { + //std::cout << "Reusing staging buffer" << std::endl; + activeBuffers.add(freeBuffer.getHandle()); + freeBuffers.remove(it, false); + return freeBuffer; + } + } + //std::cout << "Creating new stagingbuffer" << std::endl; + PStagingBuffer stagingBuffer = new StagingBuffer(); + VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size); + stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + VkDevice vulkanDevice = graphics->getDevice(); - VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer)); + VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer)); - VkMemoryDedicatedRequirements dedicatedReqs; - dedicatedReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; - dedicatedReqs.pNext = nullptr; - VkMemoryRequirements2 memReqs; - memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; - memReqs.pNext = &dedicatedReqs; - VkBufferMemoryRequirementsInfo2 bufferQuery; - bufferQuery.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2; - bufferQuery.pNext = nullptr; - bufferQuery.buffer = stagingBuffer->buffer; - vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs); + VkMemoryDedicatedRequirements dedicatedReqs; + dedicatedReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; + dedicatedReqs.pNext = nullptr; + VkMemoryRequirements2 memReqs; + memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; + memReqs.pNext = &dedicatedReqs; + VkBufferMemoryRequirementsInfo2 bufferQuery; + bufferQuery.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2; + bufferQuery.pNext = nullptr; + bufferQuery.buffer = stagingBuffer->buffer; + vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs); - memReqs.memoryRequirements.alignment = - (16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment; - - stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), stagingBuffer->buffer); - stagingBuffer->bReadable = bCPURead; - stagingBuffer->size = size; - stagingBuffer->usage = usage; - vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset()); + memReqs.memoryRequirements.alignment = + (16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment; + + stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), stagingBuffer->buffer); + stagingBuffer->bReadable = bCPURead; + stagingBuffer->size = size; + stagingBuffer->usage = usage; + vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset()); - activeBuffers.add(stagingBuffer.getHandle()); - - return stagingBuffer; + activeBuffers.add(stagingBuffer.getHandle()); + + return stagingBuffer; } void StagingManager::releaseStagingBuffer(PStagingBuffer buffer) { - std::unique_lock l(lock); - freeBuffers.add(buffer); - activeBuffers.remove(activeBuffers.find(buffer.getHandle())); + std::unique_lock l(lock); + freeBuffers.add(buffer); + activeBuffers.remove(activeBuffers.find(buffer.getHandle())); } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp index 75c05e2..886ca2c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp @@ -3,6 +3,7 @@ #include "VulkanGraphics.h" #include "VulkanCommandBuffer.h" #include "VulkanAllocator.h" +#include "ThreadPool.h" using namespace Seele; using namespace Seele::Vulkan; @@ -62,14 +63,17 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u ShaderBuffer::~ShaderBuffer() { - auto cmdBuffer = graphics->getQueueCommands(owner)->getCommands(); - auto &deletionQueue = graphics->getDeletionQueue(); + PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands(); VkDevice device = graphics->getDevice(); - VkBuffer buf[Gfx::numFramesBuffered]; + auto deletionLambda = [](PCmdBuffer cmdBuffer, VkDevice device, VkBuffer buffer) -> Job + { + co_await cmdBuffer->asyncWait(); + vkDestroyBuffer(device, buffer, nullptr); + co_return; + }; for (uint32 i = 0; i < numBuffers; ++i) { - buf[i] = buffers[i].buffer; - deletionQueue.addPendingDelete(cmdBuffer, [device, buf, i]() { vkDestroyBuffer(device, buf[i], nullptr); }); + deletionLambda(cmdBuffer, device, 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 55ec641..464997c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp @@ -25,6 +25,7 @@ CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferMa init::CommandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); + std::unique_lock lock(handleLock); VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle)) fence = new Fence(graphics); @@ -33,6 +34,7 @@ CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferMa CmdBuffer::~CmdBuffer() { + std::unique_lock lock(handleLock); vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); renderPass = nullptr; framebuffer = nullptr; @@ -44,18 +46,21 @@ void CmdBuffer::begin() VkCommandBufferBeginInfo beginInfo = init::CommandBufferBeginInfo(); beginInfo.pInheritanceInfo = nullptr; + std::unique_lock lock(handleLock); VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo)); state = State::InsideBegin; } void CmdBuffer::end() { + std::unique_lock lock(handleLock); VK_CHECK(vkEndCommandBuffer(handle)); state = State::Ended; } void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFramebuffer) { + std::unique_lock lock(handleLock); renderPass = newRenderPass; framebuffer = newFramebuffer; @@ -72,6 +77,7 @@ void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFrame void CmdBuffer::endRenderPass() { + std::unique_lock lock(handleLock); vkCmdEndRenderPass(handle); state = State::InsideBegin; } @@ -79,6 +85,7 @@ void CmdBuffer::endRenderPass() void CmdBuffer::executeCommands(const Array& commands) { assert(state == State::RenderPassActive); + std::unique_lock lock(handleLock); Array cmdBuffers(commands.size()); for (uint32 i = 0; i < commands.size(); ++i) { @@ -97,6 +104,7 @@ void CmdBuffer::executeCommands(const Array& commands) void CmdBuffer::executeCommands(const Array& commands) { + std::unique_lock lock(handleLock); Array cmdBuffers(commands.size()); for (uint32 i = 0; i < commands.size(); ++i) { @@ -115,12 +123,14 @@ void CmdBuffer::executeCommands(const Array& commands) void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore) { + std::unique_lock lock(handleLock); waitSemaphores.add(semaphore); waitFlags.add(flags); } void CmdBuffer::refreshFence() { + std::unique_lock lock(handleLock); if (state == State::Submitted) { if (fence->isSignaled()) @@ -153,10 +163,16 @@ void CmdBuffer::refreshFence() void CmdBuffer::waitForCommand(uint32 timeout) { + std::unique_lock lock(handleLock); fence->wait(timeout); refreshFence(); } +Event CmdBuffer::asyncWait() const +{ + return fence->asyncWait(); +} + PFence CmdBuffer::getFence() { @@ -187,6 +203,7 @@ RenderCommand::~RenderCommand() void RenderCommand::begin(PCmdBuffer parent) { + threadId = std::this_thread::get_id(); ready = false; VkCommandBufferBeginInfo beginInfo = init::CommandBufferBeginInfo(); @@ -202,11 +219,13 @@ void RenderCommand::begin(PCmdBuffer parent) void RenderCommand::end() { + assert(threadId == std::this_thread::get_id()); VK_CHECK(vkEndCommandBuffer(handle)); } void RenderCommand::reset() { + assert(threadId == std::this_thread::get_id()); vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); boundDescriptors.clear(); ready = true; @@ -219,6 +238,7 @@ bool RenderCommand::isReady() void RenderCommand::setViewport(Gfx::PViewport viewport) { + assert(threadId == std::this_thread::get_id()); VkViewport vp = viewport.cast()->getHandle(); VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY()); vkCmdSetViewport(handle, 0, 1, &vp); @@ -227,11 +247,13 @@ void RenderCommand::setViewport(Gfx::PViewport viewport) void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline) { + assert(threadId == std::this_thread::get_id()); pipeline = gfxPipeline.cast(); pipeline->bind(handle); } void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) { + assert(threadId == std::this_thread::get_id()); auto descriptor = descriptorSet.cast(); boundDescriptors.add(descriptor.getHandle()); descriptor->bind(); @@ -241,6 +263,7 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) } void RenderCommand::bindDescriptor(const Array& descriptorSets) { + assert(threadId == std::this_thread::get_id()); VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()]; for(uint32 i = 0; i < descriptorSets.size(); ++i) { @@ -255,6 +278,7 @@ void RenderCommand::bindDescriptor(const Array& descriptorS } void RenderCommand::bindVertexBuffer(const Array& streams) { + assert(threadId == std::this_thread::get_id()); Array buffers(streams.size()); Array offsets(streams.size()); for(uint32 i = 0; i < streams.size(); ++i) @@ -267,16 +291,19 @@ void RenderCommand::bindVertexBuffer(const Array& streams) } void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) { + assert(threadId == std::this_thread::get_id()); PIndexBuffer buf = indexBuffer.cast(); vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType())); } void RenderCommand::draw(const MeshBatchElement& data) { + assert(threadId == std::this_thread::get_id()); vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0); } void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) { + assert(threadId == std::this_thread::get_id()); vkCmdDraw(handle, vertexCount, instanceCount, firstVertex, firstInstance); } @@ -299,6 +326,7 @@ ComputeCommand::~ComputeCommand() void ComputeCommand::begin(PCmdBuffer) { + threadId = std::this_thread::get_id(); ready = false; VkCommandBufferBeginInfo beginInfo = init::CommandBufferBeginInfo(); @@ -313,11 +341,13 @@ void ComputeCommand::begin(PCmdBuffer) void ComputeCommand::end() { + assert(threadId == std::this_thread::get_id()); VK_CHECK(vkEndCommandBuffer(handle)); } void ComputeCommand::reset() { + assert(threadId == std::this_thread::get_id()); vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); boundDescriptors.clear(); ready = true; @@ -329,12 +359,14 @@ bool ComputeCommand::isReady() void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline) { + assert(threadId == std::this_thread::get_id()); pipeline = computePipeline.cast(); pipeline->bind(handle); } void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) { + assert(threadId == std::this_thread::get_id()); auto descriptor = descriptorSet.cast(); boundDescriptors.add(descriptor.getHandle()); descriptor->bind(); @@ -345,6 +377,7 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) void ComputeCommand::bindDescriptor(const Array& descriptorSets) { + assert(threadId == std::this_thread::get_id()); VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()]; for(uint32 i = 0; i < descriptorSets.size(); ++i) { @@ -360,6 +393,7 @@ void ComputeCommand::bindDescriptor(const Array& descriptor void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) { + assert(threadId == std::this_thread::get_id()); vkCmdDispatch(handle, threadX, threadY, threadZ); } diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h index da7786f..dad4831 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h @@ -32,6 +32,7 @@ public: void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore); void refreshFence(); void waitForCommand(uint32 timeToWait = 1000000u); + Event asyncWait() const; PFence getFence(); PCommandBufferManager getManager(); enum State @@ -53,6 +54,7 @@ private: State state; VkViewport currentViewport; VkRect2D currentScissor; + std::mutex handleLock; VkCommandBuffer handle; VkCommandPool owner; Array waitSemaphores; @@ -96,6 +98,7 @@ private: VkViewport currentViewport; VkRect2D currentScissor; PGraphics graphics; + std::thread::id threadId; VkCommandBuffer handle; VkCommandPool owner; friend class CmdBuffer; @@ -126,6 +129,7 @@ private: VkViewport currentViewport; VkRect2D currentScissor; PGraphics graphics; + std::thread::id threadId; VkCommandBuffer handle; VkCommandPool owner; friend class CmdBuffer; diff --git a/src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp index 9ad4adb..64657a8 100644 --- a/src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp @@ -8,7 +8,9 @@ using namespace Seele; using namespace Seele::Vulkan; Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRenderTargetLayout renderTargetLayout) - : graphics(graphics), layout(renderTargetLayout), renderPass(renderPass) + : graphics(graphics) + , layout(renderTargetLayout) + , renderPass(renderPass) { FramebufferDescription description; std::memset(&description, 0, sizeof(FramebufferDescription)); diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp index 93f9f3e..2a8d98d 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp @@ -15,587 +15,576 @@ using namespace Seele::Vulkan; Graphics::Graphics() - : instance(VK_NULL_HANDLE) - , handle(VK_NULL_HANDLE) - , physicalDevice(VK_NULL_HANDLE) - , callback(VK_NULL_HANDLE) + : instance(VK_NULL_HANDLE) + , handle(VK_NULL_HANDLE) + , physicalDevice(VK_NULL_HANDLE) + , callback(VK_NULL_HANDLE) { } Graphics::~Graphics() { - viewports.clear(); - vkDestroyDevice(handle, nullptr); - DestroyDebugReportCallbackEXT(instance, nullptr, callback); - vkDestroyInstance(instance, nullptr); + viewports.clear(); + vkDestroyDevice(handle, nullptr); + DestroyDebugReportCallbackEXT(instance, nullptr, callback); + vkDestroyInstance(instance, nullptr); } void Graphics::init(GraphicsInitializer initInfo) { - initInstance(initInfo); + initInstance(initInfo); #if ENABLE_VALIDATION - setupDebugCallback(); + setupDebugCallback(); #endif - pickPhysicalDevice(); - createDevice(initInfo); - allocator = new Allocator(this); - stagingManager = new StagingManager(this, allocator); - pipelineCache = new PipelineCache(this, "pipeline.cache"); + pickPhysicalDevice(); + createDevice(initInfo); + allocator = new Allocator(this); + stagingManager = new StagingManager(this, allocator); + pipelineCache = new PipelineCache(this, "pipeline.cache"); } Gfx::PWindow Graphics::createWindow(const WindowCreateInfo &createInfo) { - PWindow result = new Window(this, createInfo); - return result; + PWindow result = new Window(this, createInfo); + return result; } Gfx::PViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo) { - PViewport result = new Viewport(this, owner, viewportInfo); - viewports.add(result); - return result; + PViewport result = new Viewport(this, owner, viewportInfo); + std::unique_lock lock(viewportLock); + viewports.add(result); + return result; } Gfx::PRenderPass Graphics::createRenderPass(Gfx::PRenderTargetLayout layout, Gfx::PViewport renderArea) { - PRenderPass result = new RenderPass(this, layout, renderArea); - return result; + PRenderPass result = new RenderPass(this, layout, renderArea); + return result; } void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { - PRenderPass rp = renderPass.cast(); - uint32 framebufferHash = rp->getFramebufferHash(); - PFramebuffer framebuffer; - auto found = allocatedFramebuffers.find(framebufferHash); - if (found == allocatedFramebuffers.end()) - { - framebuffer = new Framebuffer(this, rp, rp->getLayout()); - allocatedFramebuffers[framebufferHash] = framebuffer; - } - else - { - framebuffer = found->value; - } - getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer); + PRenderPass rp = renderPass.cast(); + uint32 framebufferHash = rp->getFramebufferHash(); + PFramebuffer framebuffer; + { + std::unique_lock lock(allocatedFrameBufferLock); + auto found = allocatedFramebuffers.find(framebufferHash); + if (found == allocatedFramebuffers.end()) + { + framebuffer = new Framebuffer(this, rp, rp->getLayout()); + allocatedFramebuffers[framebufferHash] = framebuffer; + } + else + { + framebuffer = found->value; + } + } + getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer); } void Graphics::endRenderPass() { - getGraphicsCommands()->getCommands()->endRenderPass(); - getGraphicsCommands()->submitCommands(); + getGraphicsCommands()->getCommands()->endRenderPass(); + getGraphicsCommands()->submitCommands(); } void Graphics::executeCommands(const Array& commands) { - getGraphicsCommands()->getCommands()->executeCommands(commands); + getGraphicsCommands()->getCommands()->executeCommands(commands); } void Graphics::executeCommands(const Array& commands) { - getComputeCommands()->getCommands()->executeCommands(commands); + getComputeCommands()->getCommands()->executeCommands(commands); } Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo) { - PTexture2D result = new Texture2D(this, createInfo); - return result; + PTexture2D result = new Texture2D(this, createInfo); + return result; } Gfx::PUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData) { - PUniformBuffer uniformBuffer = new UniformBuffer(this, bulkData); - return uniformBuffer; + PUniformBuffer uniformBuffer = new UniformBuffer(this, bulkData); + return uniformBuffer; } Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) { - PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData); - return structuredBuffer; + PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData); + return structuredBuffer; } Gfx::PVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData) { - PVertexBuffer vertexBuffer = new VertexBuffer(this, bulkData); - return vertexBuffer; + PVertexBuffer vertexBuffer = new VertexBuffer(this, bulkData); + return vertexBuffer; } Gfx::PIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData) { - PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData); - return indexBuffer; + PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData); + return indexBuffer; } Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name) { - PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(name); - return cmdBuffer; + PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(name); + return cmdBuffer; } Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name) { - PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name); - return cmdBuffer; + PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name); + return cmdBuffer; } Gfx::PVertexDeclaration Graphics::createVertexDeclaration(const Array& element) { - PVertexDeclaration declaration = new VertexDeclaration(element); - return declaration; + PVertexDeclaration declaration = new VertexDeclaration(element); + return declaration; } Gfx::PVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo) { - PVertexShader shader = new VertexShader(this); - shader->create(createInfo); - return shader; + PVertexShader shader = new VertexShader(this); + shader->create(createInfo); + return shader; } Gfx::PControlShader Graphics::createControlShader(const ShaderCreateInfo& createInfo) { - PControlShader shader = new ControlShader(this); - shader->create(createInfo); - return shader; + PControlShader shader = new ControlShader(this); + shader->create(createInfo); + return shader; } Gfx::PEvaluationShader Graphics::createEvaluationShader(const ShaderCreateInfo& createInfo) { - PEvaluationShader shader = new EvaluationShader(this); - shader->create(createInfo); - return shader; + PEvaluationShader shader = new EvaluationShader(this); + shader->create(createInfo); + return shader; } Gfx::PGeometryShader Graphics::createGeometryShader(const ShaderCreateInfo& createInfo) { - PGeometryShader shader = new GeometryShader(this); - shader->create(createInfo); - return shader; + PGeometryShader shader = new GeometryShader(this); + shader->create(createInfo); + return shader; } Gfx::PFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo) { - PFragmentShader shader = new FragmentShader(this); - shader->create(createInfo); - return shader; + PFragmentShader shader = new FragmentShader(this); + shader->create(createInfo); + return shader; } Gfx::PComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo) { - PComputeShader shader = new ComputeShader(this); - shader->create(createInfo); - return shader; + PComputeShader shader = new ComputeShader(this); + shader->create(createInfo); + return shader; } Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) { - PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); - return pipeline; + PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); + return pipeline; } Gfx::PComputePipeline Graphics::createComputePipeline(const ComputePipelineCreateInfo& createInfo) { - PComputePipeline pipeline = pipelineCache->createPipeline(createInfo); - return pipeline; + PComputePipeline pipeline = pipelineCache->createPipeline(createInfo); + return pipeline; } Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo&) { - PSamplerState sampler = new SamplerState(); // TODO: proper sampler creation - VkSamplerCreateInfo vkInfo = - init::SamplerCreateInfo(); - VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler)); - return sampler; + PSamplerState sampler = new SamplerState(); // TODO: proper sampler creation + VkSamplerCreateInfo vkInfo = + init::SamplerCreateInfo(); + VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler)); + return sampler; } Gfx::PDescriptorLayout Graphics::createDescriptorLayout(const std::string& name) { - PDescriptorLayout layout = new DescriptorLayout(this, name); - return layout; + PDescriptorLayout layout = new DescriptorLayout(this, name); + return layout; } Gfx::PPipelineLayout Graphics::createPipelineLayout() { - PPipelineLayout layout = new PipelineLayout(this); - return layout; + PPipelineLayout layout = new PipelineLayout(this); + return layout; } void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) { - Texture2D* src = (Texture2D*)srcTexture->getTexture2D(); - Texture2D* dst = (Texture2D*)dstTexture->getTexture2D(); - TextureHandle* srcHandle = (TextureHandle*)src->getNativeHandle(); - TextureHandle* dstHandle = (TextureHandle*)dst->getNativeHandle(); - Gfx::SeImageLayout srcLayout = srcHandle->getLayout(); - Gfx::SeImageLayout dstLayout = dstHandle->getLayout(); - Gfx::QueueType dstOwner = dstHandle->currentOwner; - src->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - dst->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - dstTexture->transferOwnership(srcHandle->currentOwner); - PCmdBuffer cmdBuffer = getQueueCommands(srcHandle->currentOwner)->getCommands(); - if(srcHandle->getAspect() != dstHandle->getAspect()) - { - /*VkMemoryRequirements imageRequirements; - vkGetImageMemoryRequirements(handle, srcHandle->getImage(), &imageRequirements); - PStructuredBuffer tempBuffer = createStructuredBuffer(); - VkBufferImageCopy bufferImageCopy; - bufferImageCopy.bufferOffset = 0; - bufferImageCopy.bufferRowLength = srcTexture->getSizeX(); - bufferImageCopy.bufferImageHeight = srcTexture->getSizeY(); - bufferImageCopy.imageExtent.width = srcTexture->getSizeX(); - bufferImageCopy.imageExtent.height = srcTexture->getSizeY(); - bufferImageCopy.imageExtent.depth = 1; - bufferImageCopy.imageOffset.x = 0; - bufferImageCopy.imageOffset.y = 0; - bufferImageCopy.imageOffset.z = 0; - bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - bufferImageCopy.imageSubresource.baseArrayLayer = 0; - bufferImageCopy.imageSubresource.layerCount = 1; - bufferImageCopy.imageSubresource.mipLevel = 0; + Texture2D* src = (Texture2D*)srcTexture->getTexture2D(); + Texture2D* dst = (Texture2D*)dstTexture->getTexture2D(); + TextureHandle* srcHandle = (TextureHandle*)src->getNativeHandle(); + TextureHandle* dstHandle = (TextureHandle*)dst->getNativeHandle(); + Gfx::SeImageLayout srcLayout = srcHandle->getLayout(); + Gfx::SeImageLayout dstLayout = dstHandle->getLayout(); + Gfx::QueueType dstOwner = dstHandle->currentOwner; + src->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + dst->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + dstTexture->transferOwnership(srcHandle->currentOwner); + PCmdBuffer cmdBuffer = getQueueCommands(srcHandle->currentOwner)->getCommands(); + if(srcHandle->getAspect() != dstHandle->getAspect()) + { + /*VkMemoryRequirements imageRequirements; + vkGetImageMemoryRequirements(handle, srcHandle->getImage(), &imageRequirements); + PStructuredBuffer tempBuffer = createStructuredBuffer(); + VkBufferImageCopy bufferImageCopy; + bufferImageCopy.bufferOffset = 0; + bufferImageCopy.bufferRowLength = srcTexture->getSizeX(); + bufferImageCopy.bufferImageHeight = srcTexture->getSizeY(); + bufferImageCopy.imageExtent.width = srcTexture->getSizeX(); + bufferImageCopy.imageExtent.height = srcTexture->getSizeY(); + bufferImageCopy.imageExtent.depth = 1; + bufferImageCopy.imageOffset.x = 0; + bufferImageCopy.imageOffset.y = 0; + bufferImageCopy.imageOffset.z = 0; + bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + bufferImageCopy.imageSubresource.baseArrayLayer = 0; + bufferImageCopy.imageSubresource.layerCount = 1; + bufferImageCopy.imageSubresource.mipLevel = 0; - vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tempBufferAllocation->getHandle(), 1, &bufferImageCopy); + vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tempBufferAllocation->getHandle(), 1, &bufferImageCopy); - bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - vkCmdCopyBufferToImage(cmdBuffer->getHandle(), tempBufferAllocation->getHandle(), dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopy); - delete tempBufferAllocation;*/ - throw new std::logic_error("Not yet implemented!"); - } - else if (src->getSizeX() != dst->getSizeX() - || src->getSizeY() != dst->getSizeY()) - { - throw new std::logic_error("Not yet implemented!"); - } - else - { - VkImageCopy copy; - std::memset(©, 0, sizeof(VkImageCopy)); - copy.extent.width = srcTexture->getSizeX(); - copy.extent.height = srcTexture->getSizeY(); - copy.extent.depth = 1; - copy.srcSubresource.aspectMask = srcHandle->getAspect(); - copy.srcSubresource.layerCount = 1; - copy.dstSubresource.aspectMask = dstHandle->getAspect(); - copy.dstSubresource.layerCount = 1; - vkCmdCopyImage(cmdBuffer->getHandle(), - srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ©); - src->changeLayout(srcLayout); - dst->changeLayout(dstLayout); - dstTexture->transferOwnership(dstOwner); - } -} - -VkInstance Graphics::getInstance() const -{ - return instance; -} - -VkDevice Graphics::getDevice() const -{ - return handle; -} - -VkPhysicalDevice Graphics::getPhysicalDevice() const -{ - return physicalDevice; + bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + vkCmdCopyBufferToImage(cmdBuffer->getHandle(), tempBufferAllocation->getHandle(), dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopy); + delete tempBufferAllocation;*/ + throw new std::logic_error("Not yet implemented!"); + } + else if (src->getSizeX() != dst->getSizeX() + || src->getSizeY() != dst->getSizeY()) + { + throw new std::logic_error("Not yet implemented!"); + } + else + { + VkImageCopy copy; + std::memset(©, 0, sizeof(VkImageCopy)); + copy.extent.width = srcTexture->getSizeX(); + copy.extent.height = srcTexture->getSizeY(); + copy.extent.depth = 1; + copy.srcSubresource.aspectMask = srcHandle->getAspect(); + copy.srcSubresource.layerCount = 1; + copy.dstSubresource.aspectMask = dstHandle->getAspect(); + copy.dstSubresource.layerCount = 1; + vkCmdCopyImage(cmdBuffer->getHandle(), + srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, ©); + src->changeLayout(srcLayout); + dst->changeLayout(dstLayout); + dstTexture->transferOwnership(dstOwner); + } } PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType) { - switch (queueType) - { - case Gfx::QueueType::GRAPHICS: - return getGraphicsCommands(); - case Gfx::QueueType::COMPUTE: - return getComputeCommands(); - case Gfx::QueueType::TRANSFER: - return getTransferCommands(); - case Gfx::QueueType::DEDICATED_TRANSFER: - return getDedicatedTransferCommands(); - default: - throw new std::logic_error("invalid queue type"); - } + switch (queueType) + { + case Gfx::QueueType::GRAPHICS: + return getGraphicsCommands(); + case Gfx::QueueType::COMPUTE: + return getComputeCommands(); + case Gfx::QueueType::TRANSFER: + return getTransferCommands(); + case Gfx::QueueType::DEDICATED_TRANSFER: + return getDedicatedTransferCommands(); + default: + throw new std::logic_error("invalid queue type"); + } } std::mutex graphicsCommandLock; PCommandBufferManager Graphics::getGraphicsCommands() { - std::unique_lock lock(graphicsCommandLock); - auto id = std::this_thread::get_id(); - if(graphicsCommands.find(id) == graphicsCommands.end()) - { - graphicsCommands[id] = new CommandBufferManager(this, graphicsQueue); - } - return graphicsCommands[id]; + std::unique_lock lock(graphicsCommandLock); + auto id = std::this_thread::get_id(); + if(graphicsCommands.find(id) == graphicsCommands.end()) + { + graphicsCommands[id] = new CommandBufferManager(this, graphicsQueue); + } + return graphicsCommands[id]; } std::mutex computeCommandLock; PCommandBufferManager Graphics::getComputeCommands() { - std::unique_lock lock(computeCommandLock); - auto id = std::this_thread::get_id(); - if(computeCommands.find(id) == computeCommands.end()) - { - computeCommands[id] = new CommandBufferManager(this, computeQueue); - } - return computeCommands[id]; + std::unique_lock lock(computeCommandLock); + auto id = std::this_thread::get_id(); + if(computeCommands.find(id) == computeCommands.end()) + { + computeCommands[id] = new CommandBufferManager(this, computeQueue); + } + return computeCommands[id]; } std::mutex transferCommandLock; PCommandBufferManager Graphics::getTransferCommands() { - std::unique_lock lock(transferCommandLock); - auto id = std::this_thread::get_id(); - if(transferCommands.find(id) == transferCommands.end()) - { - transferCommands[id] = new CommandBufferManager(this, transferQueue); - } - return transferCommands[id]; + std::unique_lock lock(transferCommandLock); + auto id = std::this_thread::get_id(); + if(transferCommands.find(id) == transferCommands.end()) + { + transferCommands[id] = new CommandBufferManager(this, transferQueue); + } + return transferCommands[id]; } std::mutex dedicatedCommandLock; PCommandBufferManager Graphics::getDedicatedTransferCommands() { - std::unique_lock lock(dedicatedCommandLock); - auto id = std::this_thread::get_id(); - if(dedicatedTransferCommands.find(id) == dedicatedTransferCommands.end()) - { - dedicatedTransferCommands[id] = new CommandBufferManager(this, dedicatedTransferQueue); - } - return dedicatedTransferCommands[id]; + std::unique_lock lock(dedicatedCommandLock); + auto id = std::this_thread::get_id(); + if(dedicatedTransferCommands.find(id) == dedicatedTransferCommands.end()) + { + dedicatedTransferCommands[id] = new CommandBufferManager(this, dedicatedTransferQueue); + } + return dedicatedTransferCommands[id]; } PAllocator Graphics::getAllocator() { - return allocator; + return allocator; } PStagingManager Graphics::getStagingManager() { - return stagingManager; + return stagingManager; } - Array Graphics::getRequiredExtensions() { - Array extensions; + Array extensions; - unsigned int glfwExtensionCount = 0; - const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); + unsigned int glfwExtensionCount = 0; + const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); - for (unsigned int i = 0; i < glfwExtensionCount; i++) - { - extensions.add(glfwExtensions[i]); - } + for (unsigned int i = 0; i < glfwExtensionCount; i++) + { + extensions.add(glfwExtensions[i]); + } #if ENABLE_VALIDATION - extensions.add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + extensions.add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); #endif // ENABLE_VALIDATION - return extensions; + return extensions; } void Graphics::initInstance(GraphicsInitializer initInfo) { - glfwInit(); - VkApplicationInfo appInfo = {}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = initInfo.applicationName; - appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 1); - appInfo.pEngineName = initInfo.engineName; - appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1); - appInfo.apiVersion = VK_API_VERSION_1_2; + glfwInit(); + VkApplicationInfo appInfo = {}; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = initInfo.applicationName; + appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 1); + appInfo.pEngineName = initInfo.engineName; + appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1); + appInfo.apiVersion = VK_API_VERSION_1_2; - VkInstanceCreateInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - info.pApplicationInfo = &appInfo; - Array extensions = getRequiredExtensions(); - for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i) - { - extensions.add(initInfo.instanceExtensions[i]); - } - info.enabledExtensionCount = (uint32)extensions.size(); - info.ppEnabledExtensionNames = extensions.data(); + VkInstanceCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + info.pApplicationInfo = &appInfo; + Array extensions = getRequiredExtensions(); + for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i) + { + extensions.add(initInfo.instanceExtensions[i]); + } + info.enabledExtensionCount = (uint32)extensions.size(); + info.ppEnabledExtensionNames = extensions.data(); #if ENABLE_VALIDATION - info.enabledLayerCount = (uint32)initInfo.layers.size(); - info.ppEnabledLayerNames = initInfo.layers.data(); + info.enabledLayerCount = (uint32)initInfo.layers.size(); + info.ppEnabledLayerNames = initInfo.layers.data(); #else - info.enabledLayerCount = 0; + info.enabledLayerCount = 0; #endif - VK_CHECK(vkCreateInstance(&info, nullptr, &instance)); + VK_CHECK(vkCreateInstance(&info, nullptr, &instance)); } void Graphics::setupDebugCallback() { - VkDebugReportCallbackCreateInfoEXT createInfo = - init::DebugReportCallbackCreateInfo( - VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT); + VkDebugReportCallbackCreateInfoEXT createInfo = + init::DebugReportCallbackCreateInfo( + VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT); - VK_CHECK(CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback)); + VK_CHECK(CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback)); - crashTracker.Initialize(); + crashTracker.Initialize(); } void Graphics::pickPhysicalDevice() { - uint32 physicalDeviceCount; - vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr); - Array physicalDevices(physicalDeviceCount); - vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()); - VkPhysicalDevice bestDevice = VK_NULL_HANDLE; - uint32 deviceRating = 0; - for (auto dev : physicalDevices) - { - uint32 currentRating = 0; - vkGetPhysicalDeviceProperties(dev, &props); - vkGetPhysicalDeviceFeatures(dev, &features); - if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) - { - std::cout << "found dedicated gpu " << props.deviceName << std::endl; - currentRating += 100; - } - else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) - { - std::cout << "found integrated gpu " << props.deviceName << std::endl; - currentRating += 10; - } - if (currentRating > deviceRating) - { - deviceRating = currentRating; - bestDevice = dev; - std::cout << "bestDevice: " << props.deviceName << std::endl; - } - } - physicalDevice = bestDevice; - vkGetPhysicalDeviceProperties(physicalDevice, &props); - vkGetPhysicalDeviceFeatures(physicalDevice, &features); + uint32 physicalDeviceCount; + vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr); + Array physicalDevices(physicalDeviceCount); + vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()); + VkPhysicalDevice bestDevice = VK_NULL_HANDLE; + uint32 deviceRating = 0; + for (auto dev : physicalDevices) + { + uint32 currentRating = 0; + vkGetPhysicalDeviceProperties(dev, &props); + vkGetPhysicalDeviceFeatures(dev, &features); + if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + { + std::cout << "found dedicated gpu " << props.deviceName << std::endl; + currentRating += 100; + } + else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) + { + std::cout << "found integrated gpu " << props.deviceName << std::endl; + currentRating += 10; + } + if (currentRating > deviceRating) + { + deviceRating = currentRating; + bestDevice = dev; + std::cout << "bestDevice: " << props.deviceName << std::endl; + } + } + physicalDevice = bestDevice; + vkGetPhysicalDeviceProperties(physicalDevice, &props); + vkGetPhysicalDeviceFeatures(physicalDevice, &features); } void Graphics::createDevice(GraphicsInitializer initializer) { - uint32_t numQueueFamilies = 0; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, nullptr); - Array queueProperties(numQueueFamilies); - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, queueProperties.data()); + uint32_t numQueueFamilies = 0; + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, nullptr); + Array queueProperties(numQueueFamilies); + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, queueProperties.data()); - Array queueInfos; - struct QueueCreateInfo - { - int32 familyIndex = -1; - int32 queueIndex = -1; - }; - QueueCreateInfo graphicsQueueInfo; - QueueCreateInfo transferQueueInfo; - QueueCreateInfo dedicatedTransferQueueInfo; - QueueCreateInfo computeQueueInfo; - QueueCreateInfo asyncComputeInfo; - uint32 numPriorities = 0; - auto checkFamilyProperty = [](VkQueueFamilyProperties currProps, uint32 checkBit){ - return (currProps.queueFlags & checkBit) == checkBit; - }; - for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex) - { - uint32 numQueuesForFamily = 0; - VkQueueFamilyProperties currProps = queueProperties[familyIndex]; + Array queueInfos; + struct QueueCreateInfo + { + int32 familyIndex = -1; + int32 queueIndex = -1; + }; + QueueCreateInfo graphicsQueueInfo; + QueueCreateInfo transferQueueInfo; + QueueCreateInfo dedicatedTransferQueueInfo; + QueueCreateInfo computeQueueInfo; + QueueCreateInfo asyncComputeInfo; + uint32 numPriorities = 0; + auto checkFamilyProperty = [](VkQueueFamilyProperties currProps, uint32 checkBit){ + return (currProps.queueFlags & checkBit) == checkBit; + }; + for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex) + { + uint32 numQueuesForFamily = 0; + VkQueueFamilyProperties currProps = queueProperties[familyIndex]; - if (checkFamilyProperty(currProps, VK_QUEUE_GRAPHICS_BIT)) - { - if (graphicsQueueInfo.familyIndex == -1) - { - graphicsQueueInfo.familyIndex = familyIndex; - numQueuesForFamily++; - } - } - if ((currProps.queueFlags & VK_QUEUE_COMPUTE_BIT) == VK_QUEUE_COMPUTE_BIT) - { - if (computeQueueInfo.familyIndex == -1) - { - computeQueueInfo.familyIndex = familyIndex; - } - if (Gfx::useAsyncCompute && numQueueFamilies > 1) - { - if (asyncComputeInfo.familyIndex == -1) - { - if (familyIndex == (uint32)graphicsQueueInfo.familyIndex) - { - if (currProps.queueCount > 1) - { - asyncComputeInfo.familyIndex = familyIndex; - numQueuesForFamily++; - } - } - else - { - asyncComputeInfo.familyIndex = familyIndex; - } - } - } - } - if ((currProps.queueFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT) - { - if (transferQueueInfo.familyIndex == -1) - { - transferQueueInfo.familyIndex = familyIndex; - numQueuesForFamily++; - } - if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0) - { - dedicatedTransferQueueInfo.familyIndex = familyIndex; - numQueuesForFamily++; - } - } - if (numQueuesForFamily > 0) - { - VkDeviceQueueCreateInfo info = - init::DeviceQueueCreateInfo(familyIndex, numQueuesForFamily); - numPriorities += numQueuesForFamily; - queueInfos.add(info); - } - } - Array queuePriorities; - queuePriorities.resize(numPriorities); - float *currentPriority = queuePriorities.data(); - for (uint32 index = 0; index < queueInfos.size(); ++index) - { - VkDeviceQueueCreateInfo &currQueue = queueInfos[index]; - currQueue.pQueuePriorities = currentPriority; + if (checkFamilyProperty(currProps, VK_QUEUE_GRAPHICS_BIT)) + { + if (graphicsQueueInfo.familyIndex == -1) + { + graphicsQueueInfo.familyIndex = familyIndex; + numQueuesForFamily++; + } + } + if ((currProps.queueFlags & VK_QUEUE_COMPUTE_BIT) == VK_QUEUE_COMPUTE_BIT) + { + if (computeQueueInfo.familyIndex == -1) + { + computeQueueInfo.familyIndex = familyIndex; + } + if (Gfx::useAsyncCompute && numQueueFamilies > 1) + { + if (asyncComputeInfo.familyIndex == -1) + { + if (familyIndex == (uint32)graphicsQueueInfo.familyIndex) + { + if (currProps.queueCount > 1) + { + asyncComputeInfo.familyIndex = familyIndex; + numQueuesForFamily++; + } + } + else + { + asyncComputeInfo.familyIndex = familyIndex; + } + } + } + } + if ((currProps.queueFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT) + { + if (transferQueueInfo.familyIndex == -1) + { + transferQueueInfo.familyIndex = familyIndex; + numQueuesForFamily++; + } + if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0) + { + dedicatedTransferQueueInfo.familyIndex = familyIndex; + numQueuesForFamily++; + } + } + if (numQueuesForFamily > 0) + { + VkDeviceQueueCreateInfo info = + init::DeviceQueueCreateInfo(familyIndex, numQueuesForFamily); + numPriorities += numQueuesForFamily; + queueInfos.add(info); + } + } + Array queuePriorities; + queuePriorities.resize(numPriorities); + float *currentPriority = queuePriorities.data(); + for (uint32 index = 0; index < queueInfos.size(); ++index) + { + VkDeviceQueueCreateInfo &currQueue = queueInfos[index]; + currQueue.pQueuePriorities = currentPriority; - for (int32_t queueIndex = 0; queueIndex < (int32_t)currQueue.queueCount; ++queueIndex) - { - *currentPriority++ = 1.0f; - } - } - VkDeviceCreateInfo deviceInfo = init::DeviceCreateInfo( - queueInfos.data(), - (uint32)queueInfos.size(), - &features); + for (int32_t queueIndex = 0; queueIndex < (int32_t)currQueue.queueCount; ++queueIndex) + { + *currentPriority++ = 1.0f; + } + } + VkDeviceCreateInfo deviceInfo = init::DeviceCreateInfo( + queueInfos.data(), + (uint32)queueInfos.size(), + &features); #if ENABLE_VALIDATION - VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo; - crashDiagInfo.sType = VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV; - crashDiagInfo.pNext = nullptr; - crashDiagInfo.flags = - VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV | - VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV | - VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV; - deviceInfo.pNext = &crashDiagInfo; + VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo; + crashDiagInfo.sType = VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV; + crashDiagInfo.pNext = nullptr; + crashDiagInfo.flags = + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV | + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV | + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV; + deviceInfo.pNext = &crashDiagInfo; #endif - deviceInfo.enabledExtensionCount = (uint32)initializer.deviceExtensions.size(); - deviceInfo.ppEnabledExtensionNames = initializer.deviceExtensions.data(); - deviceInfo.enabledLayerCount = (uint32_t)initializer.layers.size(); - deviceInfo.ppEnabledLayerNames = initializer.layers.data(); + deviceInfo.enabledExtensionCount = (uint32)initializer.deviceExtensions.size(); + deviceInfo.ppEnabledExtensionNames = initializer.deviceExtensions.data(); + deviceInfo.enabledLayerCount = (uint32_t)initializer.layers.size(); + deviceInfo.ppEnabledLayerNames = initializer.layers.data(); - VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle)); + VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle)); + std::cout << "Vulkan handle: " << handle << std::endl; - graphicsQueue = new Queue(this, Gfx::QueueType::GRAPHICS, graphicsQueueInfo.familyIndex, 0); - if (Gfx::useAsyncCompute && asyncComputeInfo.familyIndex != -1) - { - if (asyncComputeInfo.familyIndex == graphicsQueueInfo.familyIndex) - { - // Same family as graphics, but different queue - computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, asyncComputeInfo.familyIndex, 1); - } - else - { - // Different family - computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, asyncComputeInfo.familyIndex, 0); - } - } - else - { - computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, computeQueueInfo.familyIndex, 0); - } - transferQueue = new Queue(this, Gfx::QueueType::TRANSFER, transferQueueInfo.familyIndex, 0); - if (dedicatedTransferQueueInfo.familyIndex != -1) - { - dedicatedTransferQueue = new Queue(this, Gfx::QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueInfo.familyIndex, 0); - } - else - { - dedicatedTransferQueue = transferQueue; - } - queueMapping.graphicsFamily = graphicsQueue->getFamilyIndex(); - queueMapping.computeFamily = computeQueue->getFamilyIndex(); - queueMapping.transferFamily = transferQueue->getFamilyIndex(); - queueMapping.dedicatedTransferFamily = dedicatedTransferQueue->getFamilyIndex(); + graphicsQueue = new Queue(this, Gfx::QueueType::GRAPHICS, graphicsQueueInfo.familyIndex, 0); + if (Gfx::useAsyncCompute && asyncComputeInfo.familyIndex != -1) + { + if (asyncComputeInfo.familyIndex == graphicsQueueInfo.familyIndex) + { + // Same family as graphics, but different queue + computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, asyncComputeInfo.familyIndex, 1); + } + else + { + // Different family + computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, asyncComputeInfo.familyIndex, 0); + } + } + else + { + computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, computeQueueInfo.familyIndex, 0); + } + transferQueue = new Queue(this, Gfx::QueueType::TRANSFER, transferQueueInfo.familyIndex, 0); + if (dedicatedTransferQueueInfo.familyIndex != -1) + { + dedicatedTransferQueue = new Queue(this, Gfx::QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueInfo.familyIndex, 0); + } + else + { + dedicatedTransferQueue = transferQueue; + } + queueMapping.graphicsFamily = graphicsQueue->getFamilyIndex(); + queueMapping.computeFamily = computeQueue->getFamilyIndex(); + queueMapping.transferFamily = transferQueue->getFamilyIndex(); + queueMapping.dedicatedTransferFamily = dedicatedTransferQueue->getFamilyIndex(); } diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.h b/src/Engine/Graphics/Vulkan/VulkanGraphics.h index e578bf0..4dcd5f1 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.h @@ -17,91 +17,87 @@ DECLARE_REF(PipelineCache) class Graphics : public Gfx::Graphics { public: - Graphics(); - virtual ~Graphics(); - VkInstance getInstance() const; - VkDevice getDevice() const; - VkPhysicalDevice getPhysicalDevice() const; + Graphics(); + virtual ~Graphics(); + constexpr VkInstance getInstance() const { return instance; }; + constexpr VkDevice getDevice() const { return handle; }; + constexpr VkPhysicalDevice getPhysicalDevice() const { return physicalDevice; }; - PCommandBufferManager getQueueCommands(Gfx::QueueType queueType); - PCommandBufferManager getGraphicsCommands(); - PCommandBufferManager getComputeCommands(); - PCommandBufferManager getTransferCommands(); - PCommandBufferManager getDedicatedTransferCommands(); + PCommandBufferManager getQueueCommands(Gfx::QueueType queueType); + PCommandBufferManager getGraphicsCommands(); + PCommandBufferManager getComputeCommands(); + PCommandBufferManager getTransferCommands(); + PCommandBufferManager getDedicatedTransferCommands(); - QueueOwnedResourceDeletion &getDeletionQueue() - { - return deletionQueue; - } + PAllocator getAllocator(); + PStagingManager getStagingManager(); - PAllocator getAllocator(); - PStagingManager getStagingManager(); + // Inherited via Graphics + virtual void init(GraphicsInitializer initializer) override; + virtual Gfx::PWindow createWindow(const WindowCreateInfo &createInfo) override; + virtual Gfx::PViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override; - // Inherited via Graphics - virtual void init(GraphicsInitializer initializer) override; - virtual Gfx::PWindow createWindow(const WindowCreateInfo &createInfo) override; - virtual Gfx::PViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override; + virtual Gfx::PRenderPass createRenderPass(Gfx::PRenderTargetLayout layout, Gfx::PViewport renderArea) override; + virtual void beginRenderPass(Gfx::PRenderPass renderPass) override; + virtual void endRenderPass() override; - virtual Gfx::PRenderPass createRenderPass(Gfx::PRenderTargetLayout layout, Gfx::PViewport renderArea) override; - virtual void beginRenderPass(Gfx::PRenderPass renderPass) override; - virtual void endRenderPass() override; - - virtual void executeCommands(const Array& commands) override; + virtual void executeCommands(const Array& commands) override; virtual void executeCommands(const Array& commands) override; - virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override; - virtual Gfx::PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override; - virtual Gfx::PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) override; - virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override; - virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override; - virtual Gfx::PRenderCommand createRenderCommand(const std::string& name) override; - virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override; - virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array& element) override; + virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override; + virtual Gfx::PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override; + virtual Gfx::PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) override; + virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override; + virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override; + virtual Gfx::PRenderCommand createRenderCommand(const std::string& name) override; + virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override; + virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array& element) override; virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override; - virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override; - virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override; + virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override; + virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override; virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override; - virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override; - virtual Gfx::PPipelineLayout createPipelineLayout() override; + virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override; + virtual Gfx::PPipelineLayout createPipelineLayout() override; - virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override; + virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override; protected: - Array getRequiredExtensions(); - void initInstance(GraphicsInitializer initInfo); - void setupDebugCallback(); - void pickPhysicalDevice(); - void createDevice(GraphicsInitializer initInfo); + Array getRequiredExtensions(); + void initInstance(GraphicsInitializer initInfo); + void setupDebugCallback(); + void pickPhysicalDevice(); + void createDevice(GraphicsInitializer initInfo); - VkInstance instance; - VkDevice handle; - VkPhysicalDevice physicalDevice; + VkInstance instance; + VkDevice handle; + VkPhysicalDevice physicalDevice; - PQueue graphicsQueue; - PQueue computeQueue; - PQueue transferQueue; - PQueue dedicatedTransferQueue; - QueueOwnedResourceDeletion deletionQueue; - PPipelineCache pipelineCache; - Map graphicsCommands; - Map computeCommands; - Map transferCommands; - Map dedicatedTransferCommands; - VkPhysicalDeviceProperties props; - VkPhysicalDeviceFeatures features; - VkDebugReportCallbackEXT callback; - Array viewports; - Map allocatedFramebuffers; - PAllocator allocator; - PStagingManager stagingManager; - GpuCrashTracker crashTracker; + PQueue graphicsQueue; + PQueue computeQueue; + PQueue transferQueue; + PQueue dedicatedTransferQueue; + PPipelineCache pipelineCache; + Map graphicsCommands; + Map computeCommands; + Map transferCommands; + Map dedicatedTransferCommands; + VkPhysicalDeviceProperties props; + VkPhysicalDeviceFeatures features; + VkDebugReportCallbackEXT callback; + std::mutex viewportLock; + Array viewports; + std::mutex allocatedFrameBufferLock; + Map allocatedFramebuffers; + PAllocator allocator; + PStagingManager stagingManager; + GpuCrashTracker crashTracker; - friend class Window; + friend class Window; }; DEFINE_REF(Graphics) } // namespace Vulkan diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp index 007c34a..192ac15 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp @@ -7,48 +7,6 @@ using namespace Seele; using namespace Seele::Vulkan; -List QueueOwnedResourceDeletion::deletionQueue; -volatile bool QueueOwnedResourceDeletion::running; -std::mutex QueueOwnedResourceDeletion::mutex; -std::condition_variable QueueOwnedResourceDeletion::cv; - -QueueOwnedResourceDeletion::QueueOwnedResourceDeletion() -{ - worker = std::thread(&run); - running = true; -} - -QueueOwnedResourceDeletion::~QueueOwnedResourceDeletion() -{ - worker.join(); -} - -void QueueOwnedResourceDeletion::addPendingDelete(PCmdBuffer cmdbuffer, std::function func) -{ - PendingItem item; - item.cmdBuffer = cmdbuffer; - item.func = func; - deletionQueue.add(item); - std::unique_lock lock(mutex); - cv.notify_all(); -} - -void QueueOwnedResourceDeletion::run() -{ - while (running || !deletionQueue.empty()) - { - std::unique_lock lock(mutex); - cv.wait(lock); - auto entry = deletionQueue.begin(); - PCmdBuffer cmdBuffer = entry->cmdBuffer; - //cmdBuffer->getManager()->waitForCommands(cmdBuffer); - //cmdBuffer->begin(); - - //entry->func(); - deletionQueue.remove(entry); - } -} - Semaphore::Semaphore(PGraphics graphics) : graphics(graphics) { @@ -65,7 +23,7 @@ Semaphore::~Semaphore() Fence::Fence(PGraphics graphics) : graphics(graphics) - , signaled(false) + , signaled("Fence") { VkFenceCreateInfo info = init::FenceCreateInfo(0); @@ -87,7 +45,7 @@ bool Fence::isSignaled() switch (res) { case VK_SUCCESS: - signaled = true; + signaled.raise(); return true; case VK_NOT_READY: break; @@ -102,7 +60,7 @@ void Fence::reset() if (signaled) { vkResetFences(graphics->getDevice(), 1, &fence); - signaled = false; + signaled.reset(); } } @@ -113,7 +71,7 @@ void Fence::wait(uint32 timeout) switch (r) { case VK_SUCCESS: - signaled = true; + signaled.raise(); break; case VK_TIMEOUT: break; @@ -122,6 +80,11 @@ void Fence::wait(uint32 timeout) break; } } +Event Fence::asyncWait() const +{ + return signaled; +} + VertexDeclaration::VertexDeclaration(const Array& elementList) : elementList(elementList) diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 3f2a241..89d514b 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -2,6 +2,8 @@ #include #include #include "Graphics/GraphicsResources.h" +#include "VulkanAllocator.h" +#include "ThreadPool.h" namespace Seele { @@ -16,117 +18,97 @@ DECLARE_REF(SubAllocation) class Semaphore { public: - Semaphore(PGraphics graphics); - virtual ~Semaphore(); - inline VkSemaphore getHandle() const - { - return handle; - } + Semaphore(PGraphics graphics); + virtual ~Semaphore(); + inline VkSemaphore getHandle() const + { + return handle; + } private: - VkSemaphore handle; - PGraphics graphics; + VkSemaphore handle; + PGraphics graphics; }; DEFINE_REF(Semaphore) class Fence { public: - Fence(PGraphics graphics); - ~Fence(); - bool isSignaled(); - void reset(); - inline VkFence getHandle() const - { - return fence; - } - void wait(uint32 timeout); - bool operator<(const Fence &other) const - { - return fence < other.fence; - } + Fence(PGraphics graphics); + ~Fence(); + bool isSignaled(); + void reset(); + inline VkFence getHandle() const + { + return fence; + } + void wait(uint32 timeout); + Event asyncWait() const; + bool operator<(const Fence &other) const + { + return fence < other.fence; + } private: - PGraphics graphics; - bool signaled; - VkFence fence; + PGraphics graphics; + Event signaled; + VkFence fence; }; DEFINE_REF(Fence) class VertexDeclaration : public Gfx::VertexDeclaration { public: - Array elementList; + Array elementList; - VertexDeclaration(const Array& elementList); - virtual ~VertexDeclaration(); + VertexDeclaration(const Array& elementList); + virtual ~VertexDeclaration(); private: }; DEFINE_REF(VertexDeclaration) -class QueueOwnedResourceDeletion -{ -public: - QueueOwnedResourceDeletion(); - virtual ~QueueOwnedResourceDeletion(); - static void addPendingDelete(PCmdBuffer fence, std::function function); - -private: - std::thread worker; - static volatile bool running; - static void run(); - struct PendingItem - { - PCmdBuffer cmdBuffer; - std::function func; - }; - static std::mutex mutex; - static std::condition_variable cv; - static List deletionQueue; -}; - class ShaderBuffer { public: - ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false); - virtual ~ShaderBuffer(); - VkBuffer getHandle() const - { - return buffers[currentBuffer].buffer; - } - uint32 getSize() const - { - return size; - } - VkDeviceSize getOffset() const; - void advanceBuffer() - { - currentBuffer = (currentBuffer + 1) % numBuffers; - } - virtual void *lock(bool bWriteOnly = true); - virtual void unlock(); + ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false); + virtual ~ShaderBuffer(); + VkBuffer getHandle() const + { + return buffers[currentBuffer].buffer; + } + uint32 getSize() const + { + return size; + } + VkDeviceSize getOffset() const; + void advanceBuffer() + { + currentBuffer = (currentBuffer + 1) % numBuffers; + } + virtual void *lock(bool bWriteOnly = true); + virtual void unlock(); protected: - struct BufferAllocation - { - VkBuffer buffer; - PSubAllocation allocation; - }; - PGraphics graphics; - uint32 currentBuffer; - uint32 size; - Gfx::QueueType& owner; - BufferAllocation buffers[Gfx::numFramesBuffered]; - uint32 numBuffers; + struct BufferAllocation + { + VkBuffer buffer; + PSubAllocation allocation; + }; + PGraphics graphics; + uint32 currentBuffer; + uint32 size; + Gfx::QueueType& owner; + BufferAllocation buffers[Gfx::numFramesBuffered]; + uint32 numBuffers; - void executeOwnershipBarrier(Gfx::QueueType newOwner); - void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0; + void executeOwnershipBarrier(Gfx::QueueType newOwner); + void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0; - virtual VkAccessFlags getSourceAccessMask() = 0; - virtual VkAccessFlags getDestAccessMask() = 0; + virtual VkAccessFlags getSourceAccessMask() = 0; + virtual VkAccessFlags getDestAccessMask() = 0; }; DEFINE_REF(ShaderBuffer) @@ -134,217 +116,217 @@ DECLARE_REF(StagingBuffer) class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer { public: - UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &resourceData); - virtual ~UniformBuffer(); - virtual bool updateContents(const BulkResourceData &resourceData); - - virtual void* lock(bool bWriteOnly = true) override; - virtual void unlock() override; + UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &resourceData); + virtual ~UniformBuffer(); + virtual bool updateContents(const BulkResourceData &resourceData); + + virtual void* lock(bool bWriteOnly = true) override; + virtual void unlock() override; protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask(); - virtual VkAccessFlags getDestAccessMask(); - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask(); + virtual VkAccessFlags getDestAccessMask(); + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); private: - PStagingBuffer dedicatedStagingBuffer; + PStagingBuffer dedicatedStagingBuffer; }; DEFINE_REF(UniformBuffer) class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer { public: - StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData); - virtual ~StructuredBuffer(); - virtual bool updateContents(const BulkResourceData &resourceData); + StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData); + virtual ~StructuredBuffer(); + virtual bool updateContents(const BulkResourceData &resourceData); - virtual void* lock(bool bWriteOnly = true) override; - virtual void unlock() override; + virtual void* lock(bool bWriteOnly = true) override; + virtual void unlock() override; protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask(); - virtual VkAccessFlags getDestAccessMask(); - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask(); + virtual VkAccessFlags getDestAccessMask(); + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); private: - PStagingBuffer dedicatedStagingBuffer; + PStagingBuffer dedicatedStagingBuffer; }; DEFINE_REF(StructuredBuffer) class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer { public: - VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData); - virtual ~VertexBuffer(); + VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData); + virtual ~VertexBuffer(); protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask(); - virtual VkAccessFlags getDestAccessMask(); - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask(); + virtual VkAccessFlags getDestAccessMask(); + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); }; DEFINE_REF(VertexBuffer) class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer { public: - IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData); - virtual ~IndexBuffer(); + IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData); + virtual ~IndexBuffer(); protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask(); - virtual VkAccessFlags getDestAccessMask(); - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask(); + virtual VkAccessFlags getDestAccessMask(); + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); }; DEFINE_REF(IndexBuffer) class TextureHandle { public: - TextureHandle(PGraphics graphics, VkImageViewType viewType, - const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE); - virtual ~TextureHandle(); + TextureHandle(PGraphics graphics, VkImageViewType viewType, + const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE); + virtual ~TextureHandle(); - inline VkImage getImage() const - { - return image; - } - inline VkImageView getView() const - { - return defaultView; - } - inline Gfx::SeImageLayout getLayout() const - { - return layout; - } - inline VkImageAspectFlags getAspect() const - { - return aspect; - } - inline VkImageUsageFlags getUsage() const - { - return usage; - } - inline Gfx::SeFormat getFormat() const - { - return format; - } - inline Gfx::SeSampleCountFlags getNumSamples() const - { - return samples; - } - inline uint32 getMipLevels() const - { - return mipLevels; - } - inline bool isDepthStencil() const - { - return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); - } - void executeOwnershipBarrier(Gfx::QueueType newOwner); - void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - void changeLayout(Gfx::SeImageLayout newLayout); + inline VkImage getImage() const + { + return image; + } + inline VkImageView getView() const + { + return defaultView; + } + inline Gfx::SeImageLayout getLayout() const + { + return layout; + } + inline VkImageAspectFlags getAspect() const + { + return aspect; + } + inline VkImageUsageFlags getUsage() const + { + return usage; + } + inline Gfx::SeFormat getFormat() const + { + return format; + } + inline Gfx::SeSampleCountFlags getNumSamples() const + { + return samples; + } + inline uint32 getMipLevels() const + { + return mipLevels; + } + inline bool isDepthStencil() const + { + return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + } + void executeOwnershipBarrier(Gfx::QueueType newOwner); + void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + void changeLayout(Gfx::SeImageLayout newLayout); private: - //Updates via reference - Gfx::QueueType& currentOwner; - PGraphics graphics; - PSubAllocation allocation; - uint32 sizeX; - uint32 sizeY; - uint32 sizeZ; - uint32 arrayCount; - uint32 mipLevels; - uint32 samples; - Gfx::SeFormat format; - Gfx::SeImageUsageFlags usage; - VkImage image; - VkImageView defaultView; - VkImageAspectFlags aspect; - Gfx::SeImageLayout layout; - friend class TextureBase; - friend class Texture2D; - friend class Graphics; + //Updates via reference + Gfx::QueueType& currentOwner; + PGraphics graphics; + PSubAllocation allocation; + uint32 sizeX; + uint32 sizeY; + uint32 sizeZ; + uint32 arrayCount; + uint32 mipLevels; + uint32 samples; + Gfx::SeFormat format; + Gfx::SeImageUsageFlags usage; + VkImage image; + VkImageView defaultView; + VkImageAspectFlags aspect; + Gfx::SeImageLayout layout; + friend class TextureBase; + friend class Texture2D; + friend class Graphics; }; class TextureBase { public: - static TextureHandle* cast(Gfx::PTexture texture); + static TextureHandle* cast(Gfx::PTexture texture); protected: - TextureHandle* textureHandle; - friend class Graphics; + TextureHandle* textureHandle; + friend class Graphics; }; DECLARE_REF(TextureBase) class Texture2D : public Gfx::Texture2D, public TextureBase { public: - Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); - virtual ~Texture2D(); - virtual uint32 getSizeX() const override - { - return textureHandle->sizeX; - } - virtual uint32 getSizeY() const override - { - return textureHandle->sizeY; - } - virtual uint32 getSizeZ() const override - { - return textureHandle->sizeZ; - } - virtual Gfx::SeFormat getFormat() const override - { - return textureHandle->format; - } - virtual Gfx::SeSampleCountFlags getNumSamples() const override - { - return textureHandle->getNumSamples(); - } - virtual uint32 getMipLevels() const override - { - return textureHandle->getMipLevels(); - } - virtual void changeLayout(Gfx::SeImageLayout newLayout) override; - virtual void* getNativeHandle() override - { - return textureHandle; - } - inline VkImage getHandle() const - { - return textureHandle->image; - } - inline VkImageView getView() const - { - return textureHandle->defaultView; - } - inline bool isDepthStencil() const - { - return textureHandle->isDepthStencil(); - } + Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); + virtual ~Texture2D(); + virtual uint32 getSizeX() const override + { + return textureHandle->sizeX; + } + virtual uint32 getSizeY() const override + { + return textureHandle->sizeY; + } + virtual uint32 getSizeZ() const override + { + return textureHandle->sizeZ; + } + virtual Gfx::SeFormat getFormat() const override + { + return textureHandle->format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return textureHandle->getNumSamples(); + } + virtual uint32 getMipLevels() const override + { + return textureHandle->getMipLevels(); + } + virtual void changeLayout(Gfx::SeImageLayout newLayout) override; + virtual void* getNativeHandle() override + { + return textureHandle; + } + inline VkImage getHandle() const + { + return textureHandle->image; + } + inline VkImageView getView() const + { + return textureHandle->defaultView; + } + inline bool isDepthStencil() const + { + return textureHandle->isDepthStencil(); + } protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); }; DEFINE_REF(Texture2D) @@ -352,74 +334,74 @@ DEFINE_REF(Texture2D) class SamplerState : public Gfx::SamplerState { public: - VkSampler sampler; + VkSampler sampler; }; DEFINE_REF(SamplerState) class Window : public Gfx::Window { public: - Window(PGraphics graphics, const WindowCreateInfo &createInfo); - virtual ~Window(); - virtual void beginFrame() override; - virtual void endFrame() override; - virtual Gfx::PTexture2D getBackBuffer() const override; - virtual void onWindowCloseEvent() override; - virtual void setKeyCallback(std::function callback) override; - virtual void setMouseMoveCallback(std::function callback) override; - virtual void setMouseButtonCallback(std::function callback) override; - virtual void setScrollCallback(std::function callback) override; - virtual void setFileCallback(std::function callback) override; - virtual void setCloseCallback(std::function callback); + Window(PGraphics graphics, const WindowCreateInfo &createInfo); + virtual ~Window(); + virtual void beginFrame() override; + virtual void endFrame() override; + virtual Gfx::PTexture2D getBackBuffer() const override; + virtual void onWindowCloseEvent() override; + virtual void setKeyCallback(std::function callback) override; + virtual void setMouseMoveCallback(std::function callback) override; + virtual void setMouseButtonCallback(std::function callback) override; + virtual void setScrollCallback(std::function callback) override; + virtual void setFileCallback(std::function callback) override; + virtual void setCloseCallback(std::function callback); - std::function keyCallback; - std::function mouseMoveCallback; - std::function mouseButtonCallback; - std::function scrollCallback; - std::function fileCallback; - std::function closeCallback; + std::function keyCallback; + std::function mouseMoveCallback; + std::function mouseButtonCallback; + std::function scrollCallback; + std::function fileCallback; + std::function closeCallback; protected: - void advanceBackBuffer(); - void recreateSwapchain(const WindowCreateInfo &createInfo); - void present(); - void destroySwapchain(); - void createSwapchain(); - void chooseSurfaceFormat(const Array &available, Gfx::SeFormat preferred); - void choosePresentMode(const Array &modes); + void advanceBackBuffer(); + void recreateSwapchain(const WindowCreateInfo &createInfo); + void present(); + void destroySwapchain(); + void createSwapchain(); + void chooseSurfaceFormat(const Array &available, Gfx::SeFormat preferred); + void choosePresentMode(const Array &modes); - PTexture2D backBufferImages[Gfx::numFramesBuffered]; - PSemaphore renderFinished[Gfx::numFramesBuffered]; - PSemaphore imageAcquired[Gfx::numFramesBuffered]; - PSemaphore imageAcquiredSemaphore; + PTexture2D backBufferImages[Gfx::numFramesBuffered]; + PSemaphore renderFinished[Gfx::numFramesBuffered]; + PSemaphore imageAcquired[Gfx::numFramesBuffered]; + PSemaphore imageAcquiredSemaphore; - PGraphics graphics; - VkInstance instance; - VkSwapchainKHR swapchain; - VkSampleCountFlags numSamples; - VkFormat pixelFormat; - VkPresentModeKHR presentMode; - VkSurfaceKHR surface; - VkSurfaceFormatKHR surfaceFormat; - void *windowHandle; - int32 currentImageIndex; - int32 acquiredImageIndex; - int32 preAcquiredImageIndex; - int32 semaphoreIndex; + PGraphics graphics; + VkInstance instance; + VkSwapchainKHR swapchain; + VkSampleCountFlags numSamples; + VkFormat pixelFormat; + VkPresentModeKHR presentMode; + VkSurfaceKHR surface; + VkSurfaceFormatKHR surfaceFormat; + void *windowHandle; + int32 currentImageIndex; + int32 acquiredImageIndex; + int32 preAcquiredImageIndex; + int32 semaphoreIndex; }; DEFINE_REF(Window) class Viewport : public Gfx::Viewport { public: - Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo); - virtual ~Viewport(); - virtual void resize(uint32 newX, uint32 newY); - virtual void move(uint32 newOffsetX, uint32 newOffsetY); - VkViewport getHandle() const { return handle; } + Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo); + virtual ~Viewport(); + virtual void resize(uint32 newX, uint32 newY); + virtual void move(uint32 newOffsetX, uint32 newOffsetY); + VkViewport getHandle() const { return handle; } private: - VkViewport handle; - PGraphics graphics; - friend class Graphics; + VkViewport handle; + PGraphics graphics; + friend class Graphics; }; DECLARE_REF(Viewport) } // namespace Vulkan diff --git a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp index 2d591f6..47b64dc 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp @@ -29,6 +29,7 @@ PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePat stream.read((char*)cacheData.data(), fileSize); cacheCreateInfo.initialDataSize = fileSize; cacheCreateInfo.pInitialData = cacheData.data(); + std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl; } VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache)); } @@ -44,6 +45,7 @@ PipelineCache::~PipelineCache() stream.flush(); stream.close(); vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr); + std::cout << "Written " << cacheSize << " bytes to cache" << std::endl; } struct PipelineCreateHashStruct @@ -321,6 +323,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo uint32 hash = crc.checksum(); VkPipeline pipelineHandle; + std::unique_lock lock(createdPipelinesLock); auto foundPipeline = createdPipelines.find(hash); if (foundPipeline != createdPipelines.end()) { diff --git a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h index e156360..94e458c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h +++ b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h @@ -16,6 +16,7 @@ private: VkPipelineCache cache; PGraphics graphics; std::string cacheFile; + std::mutex createdPipelinesLock; Map createdPipelines; }; DEFINE_REF(PipelineCache) diff --git a/src/Engine/Graphics/Vulkan/VulkanTexture.cpp b/src/Engine/Graphics/Vulkan/VulkanTexture.cpp index b22b7bf..3aa3859 100644 --- a/src/Engine/Graphics/Vulkan/VulkanTexture.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanTexture.cpp @@ -4,6 +4,7 @@ #include "VulkanGraphicsEnums.h" #include "VulkanAllocator.h" #include "VulkanCommandBuffer.h" +#include "ThreadPool.h" #include using namespace Seele; @@ -161,13 +162,17 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, TextureHandle::~TextureHandle() { - auto &deletionQueue = graphics->getDeletionQueue(); auto cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); VkDevice device = graphics->getDevice(); VkImageView view = defaultView; VkImage img = image; - deletionQueue.addPendingDelete(cmdBuffer, [device, view]() { vkDestroyImageView(device, view, nullptr); }); - deletionQueue.addPendingDelete(cmdBuffer, [device, img]() { vkDestroyImage(device, img, nullptr); }); + auto deletionLambda = [cmdBuffer, device, view, img]() -> Job + { + vkDestroyImageView(device, view, nullptr); + vkDestroyImage(device, img, nullptr); + co_return; + }; + deletionLambda(); } TextureHandle* TextureBase::cast(Gfx::PTexture texture) diff --git a/src/Engine/Material/MaterialAsset.cpp b/src/Engine/Material/MaterialAsset.cpp index 4e96886..78bb2e7 100644 --- a/src/Engine/Material/MaterialAsset.cpp +++ b/src/Engine/Material/MaterialAsset.cpp @@ -1,6 +1,7 @@ #include "MaterialAsset.h" #include "Window/WindowManager.h" #include "Asset/AssetRegistry.h" +#include "Asset/TextureAsset.h" #include "BRDF.h" #include #include diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index b9bed65..afa2dc7 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -38,13 +38,9 @@ public: : handle(ptr) , deleter(std::move(deleter)) , refCount(1) - { - registeredObjects[ptr] = this; - } - inline RefObject(const RefObject &rhs) - : handle(rhs.handle), refCount(rhs.refCount) { } + RefObject(const RefObject &rhs) = delete; RefObject(RefObject &&rhs) : handle(std::move(rhs.handle)), refCount(std::move(rhs.refCount)) { @@ -56,18 +52,11 @@ public: registeredObjects.erase(handle); } // #pragma warning( disable: 4150) - //deleter(handle); + deleter(handle); + handle = nullptr; // #pragma warning( default: 4150) } - RefObject &operator=(const RefObject &rhs) - { - if (*this != rhs) - { - handle = rhs.handle; - refCount = rhs.refCount; - } - return *this; - } + RefObject &operator=(const RefObject &rhs) = delete; RefObject &operator=(RefObject &&rhs) { if (*this != rhs) @@ -131,11 +120,10 @@ public: if (registeredObj == registeredEnd) { object = new RefObject(ptr, std::move(deleter)); - l.unlock(); + registeredObjects[ptr] = object; } else { - l.unlock(); object = (RefObject *)registeredObj->value; object->addRef(); } diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index 7a39f62..61b4ab7 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -38,6 +38,7 @@ ThreadPool::ThreadPool(uint32 threadCount) ThreadPool::~ThreadPool() { + running.store(false); for(auto& thread : workers) { thread.join(); @@ -74,7 +75,7 @@ void ThreadPool::notify(Event* event) { std::unique_lock lock(jobQueueLock); std::unique_lock lock2(waitingLock); - while(!waitingJobs.empty()) + while(!waitingJobs[*event].empty()) { //std::cout << "Waking up job " << job << std::endl; jobQueue.add(std::move(waitingJobs[*event].retrieve())); @@ -90,7 +91,6 @@ void ThreadPool::notify(Event* event) mainJobCV.notify_one(); } } - event->reset(); } void ThreadPool::threadLoop(const bool mainThread) { diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index 2d3c8a2..7898a7d 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -91,6 +91,10 @@ public: { return *this; } + operator bool() + { + return flag->load(); + } void raise(); void reset(); diff --git a/src/Engine/UI/Elements/Element.cpp b/src/Engine/UI/Elements/Element.cpp index 8fe0a5a..f56625e 100644 --- a/src/Engine/UI/Elements/Element.cpp +++ b/src/Engine/UI/Elements/Element.cpp @@ -1,4 +1,5 @@ #include "Element.h" +#include "UI/System.h" using namespace Seele; using namespace Seele::UI; diff --git a/src/Engine/UI/System.cpp b/src/Engine/UI/System.cpp index 6edd7fd..56d897e 100644 --- a/src/Engine/UI/System.cpp +++ b/src/Engine/UI/System.cpp @@ -1,4 +1,5 @@ #include "System.h" +#include "Elements/Panel.h" using namespace Seele; using namespace Seele::UI; diff --git a/src/Engine/Window/InspectorView.cpp b/src/Engine/Window/InspectorView.cpp index e8aa618..17581e4 100644 --- a/src/Engine/Window/InspectorView.cpp +++ b/src/Engine/Window/InspectorView.cpp @@ -1,4 +1,6 @@ #include "InspectorView.h" +#include "Graphics/Graphics.h" +#include "Scene/Actor/Actor.h" #include "Window.h" using namespace Seele; diff --git a/src/Engine/Window/SceneView.cpp b/src/Engine/Window/SceneView.cpp index 123ab2e..b6ca1a9 100644 --- a/src/Engine/Window/SceneView.cpp +++ b/src/Engine/Window/SceneView.cpp @@ -1,6 +1,8 @@ #include "SceneView.h" #include "Scene/Scene.h" #include "Window.h" +#include "Graphics/Graphics.h" +#include "Asset/MeshAsset.h" #include "Asset/AssetRegistry.h" #include "Scene/Actor/CameraActor.h" #include "Scene/Components/CameraComponent.h" diff --git a/src/Engine/Window/Window.cpp b/src/Engine/Window/Window.cpp index c1b3494..4917cbb 100644 --- a/src/Engine/Window/Window.cpp +++ b/src/Engine/Window/Window.cpp @@ -30,6 +30,7 @@ MainJob Window::render() for(auto& windowView : views) { co_await windowView->updateFinished; + windowView->updateFinished.reset(); { std::unique_lock lock(windowView->workerMutex); windowView->view->prepareRender();