From ae92439164ffd602b7dfb9418346b209eb6411fc Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 24 Mar 2020 21:05:32 +0100 Subject: [PATCH] Implementing Commandbuffers --- .vscode/settings.json | 8 + CMakeLists.txt | 1 + src/Engine/Graphics/GraphicsEnums.h | 2 + src/Engine/Graphics/GraphicsResources.h | 3 - src/Engine/Graphics/RenderCore.cpp | 5 - src/Engine/Graphics/Vulkan/CMakeLists.txt | 11 +- .../Graphics/Vulkan/VulkanAllocator.cpp | 12 +- src/Engine/Graphics/Vulkan/VulkanAllocator.h | 6 +- src/Engine/Graphics/Vulkan/VulkanBuffer.cpp | 66 +-- .../Graphics/Vulkan/VulkanCommandBuffer.cpp | 139 ++++++ .../Graphics/Vulkan/VulkanCommandBuffer.h | 70 ++- .../Graphics/Vulkan/VulkanDescriptorSets.cpp | 2 +- .../Graphics/Vulkan/VulkanFramebuffer.cpp | 0 .../Graphics/Vulkan/VulkanFramebuffer.h | 23 + src/Engine/Graphics/Vulkan/VulkanGraphics.cpp | 141 +++++- src/Engine/Graphics/Vulkan/VulkanGraphics.h | 23 +- .../Graphics/Vulkan/VulkanGraphicsEnums.cpp | 8 +- .../Vulkan/VulkanGraphicsResources.cpp | 20 + .../Graphics/Vulkan/VulkanGraphicsResources.h | 419 ++++++++++-------- .../Graphics/Vulkan/VulkanInitializer.cpp | 6 +- .../Graphics/Vulkan/VulkanInitializer.h | 1 + src/Engine/Graphics/Vulkan/VulkanQueue.cpp | 19 + src/Engine/Graphics/Vulkan/VulkanQueue.h | 36 ++ .../Graphics/Vulkan/VulkanRenderPass.cpp | 0 src/Engine/Graphics/Vulkan/VulkanRenderPass.h | 40 ++ src/Engine/Graphics/WindowManager.cpp | 2 +- src/Engine/MinimalEngine.h | 27 +- 27 files changed, 779 insertions(+), 311 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp create mode 100644 src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp create mode 100644 src/Engine/Graphics/Vulkan/VulkanFramebuffer.h create mode 100644 src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp create mode 100644 src/Engine/Graphics/Vulkan/VulkanQueue.cpp create mode 100644 src/Engine/Graphics/Vulkan/VulkanQueue.h create mode 100644 src/Engine/Graphics/Vulkan/VulkanRenderPass.cpp create mode 100644 src/Engine/Graphics/Vulkan/VulkanRenderPass.h diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4584c8e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "C_Cpp.default.configurationProvider": "go2sh.cmake-integration", + "telemetry.enableTelemetry": false, + "cmake.buildDirectory": "${workspaceFolder}/bin/${buildType}", + "files.associations": { + "xstring": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 923f85f..b9bbf95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ set(GLFW_ROOT ${EXTERNAL_ROOT}/glfw) set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}) set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}) +set(Boost_DETAILED_FAILURE_MSG TRUE) # Configuration types SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) diff --git a/src/Engine/Graphics/GraphicsEnums.h b/src/Engine/Graphics/GraphicsEnums.h index db1cfe2..538eb36 100644 --- a/src/Engine/Graphics/GraphicsEnums.h +++ b/src/Engine/Graphics/GraphicsEnums.h @@ -4,6 +4,8 @@ namespace Seele { namespace Gfx { + static bool useAsyncCompute = true; + typedef uint32_t SeFlags; typedef uint32_t SeBool32; typedef uint64_t SeDeviceSize; diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index b426f82..4d12fca 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -54,9 +54,6 @@ namespace Seele uint32_t offset; uint32_t size; }; - - - class RenderCommandBase { diff --git a/src/Engine/Graphics/RenderCore.cpp b/src/Engine/Graphics/RenderCore.cpp index 304d7f9..8662fa8 100644 --- a/src/Engine/Graphics/RenderCore.cpp +++ b/src/Engine/Graphics/RenderCore.cpp @@ -21,11 +21,6 @@ void Seele::RenderCore::init() void Seele::RenderCore::renderLoop() { - while (true) - { - windowManager->beginFrame(); - windowManager->endFrame(); - } } void Seele::RenderCore::shutdown() diff --git a/src/Engine/Graphics/Vulkan/CMakeLists.txt b/src/Engine/Graphics/Vulkan/CMakeLists.txt index d7d54b4..da9d52b 100644 --- a/src/Engine/Graphics/Vulkan/CMakeLists.txt +++ b/src/Engine/Graphics/Vulkan/CMakeLists.txt @@ -2,12 +2,21 @@ target_sources(SeeleEngine PRIVATE VulkanAllocator.h VulkanAllocator.cpp + VulkanCommandBuffer.h + VulkanCommandBuffer.cpp VulkanBuffer.cpp + VulkanFramebuffer.h + VulkanFramebuffer.cpp VulkanGraphics.h VulkanGraphics.cpp VulkanGraphicsResources.h + VulkanGraphicsResources.cpp VulkanDescriptorSets.cpp VulkanGraphicsEnums.h VulkanGraphicsEnums.cpp VulkanInitializer.h - VulkanInitializer.cpp) \ No newline at end of file + VulkanInitializer.cpp + VulkanRenderPass.h + VulkanRenderPass.cpp + VulkanQueue.h + VulkanQueue.cpp) \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp index 5c9fe82..a96d13b 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp @@ -14,7 +14,7 @@ SubAllocation::SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 s { } -Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated) +Allocation::Allocation(WGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated) : device(graphics->getDevice()) , allocator(allocator) , bytesAllocated(0) @@ -32,13 +32,13 @@ Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, ui freeRanges.add(freeRange); } -PSubAllocation Allocation::getSuballocation(uint32 size, uint32 alignment) +PSubAllocation Allocation::getSuballocation(uint32 requestedSize, uint32 alignment) { if (isDedicated) { if (activeAllocations.size() == 0) { - assert(size == bytesAllocated); + assert(requestedSize == bytesAllocated); activeAllocations.add(freeRanges.back()); freeRanges.clear(); } @@ -53,7 +53,7 @@ PSubAllocation Allocation::getSuballocation(uint32 size, uint32 alignment) uint32 allocatedOffset = freeAllocation->allocatedOffset; uint32 alignedOffset = align(allocatedOffset, alignment); uint32 alignmentAdjustment = alignedOffset - allocatedOffset; - uint32 size = alignmentAdjustment + size; + uint32 size = alignmentAdjustment + requestedSize; if (freeAllocation->size == size) { freeRanges.remove(i); @@ -66,7 +66,7 @@ PSubAllocation Allocation::getSuballocation(uint32 size, uint32 alignment) freeAllocation->allocatedSize -= size; freeAllocation->allocatedOffset += allocatedOffset; freeAllocation->alignedOffset += allocatedOffset; - PSubAllocation subAlloc = new VulkanSubAllocation(this, allocatedOffset, size, alignedOffset, size); + PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size); activeAllocations.add(subAlloc); return subAlloc; } @@ -74,7 +74,7 @@ PSubAllocation Allocation::getSuballocation(uint32 size, uint32 alignment) return nullptr; } -Allocator::Allocator(PGraphics graphics) +Allocator::Allocator(WGraphics graphics) : graphics(graphics) { vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties); diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.h b/src/Engine/Graphics/Vulkan/VulkanAllocator.h index 6fc94c7..a03a4be 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.h +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.h @@ -28,7 +28,7 @@ namespace Seele class Allocation { public: - Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated); + Allocation(WGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated); PSubAllocation getSuballocation(uint32 size, uint32 alignment); private: Allocator* allocator; @@ -50,7 +50,7 @@ namespace Seele class Allocator { public: - Allocator(PGraphics graphics); + Allocator(WGraphics graphics); ~Allocator(); PSubAllocation allocate(uint64 size, const VkMemoryRequirements2& requirements, VkMemoryPropertyFlags props); @@ -66,7 +66,7 @@ namespace Seele }; Array heaps; VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint32* typeIndex); - PGraphics graphics; + WGraphics graphics; VkPhysicalDeviceMemoryProperties memProperties; }; DEFINE_REF(Allocator); diff --git a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp index 136223a..d7792d6 100644 --- a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp @@ -1,67 +1,5 @@ #include "VulkanGraphicsResources.h" +#include "VulkanInitializer.h" +using namespace Seele; using namespace Seele::Vulkan; - -void Buffer::executeOwnershipBarrier(QueueType newOwner) -{ - VkBufferMemoryBarrier barrier = - init::BufferMemoryBarrier(); - CommandBufferManager* sourceManager = getCommands(); - CommandBufferManager* dstManager = nullptr; - VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - if (currentOwner == QueueType::TRANSFER) - { - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.srcQueueFamilyIndex = device->getTransferQueue()->getFamilyIndex(); - srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - } - else if (currentOwner == QueueType::COMPUTE) - { - barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; - barrier.srcQueueFamilyIndex = device->getComputeQueue()->getFamilyIndex(); - srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - } - else if (currentOwner == QueueType::GRAPHICS) - { - barrier.srcAccessMask = getSourceAccessMask(); - barrier.srcQueueFamilyIndex = device->getGraphicsQueue()->getFamilyIndex(); - srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; - } - if (newOwner == QueueType::TRANSFER) - { - barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - barrier.dstQueueFamilyIndex = device->getTransferQueue()->getFamilyIndex(); - dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - dstManager = device->getRHIDevice().getTransferCommands(); - } - else if (newOwner == QueueType::COMPUTE) - { - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.dstQueueFamilyIndex = device->getComputeQueue()->getFamilyIndex(); - dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - dstManager = device->getRHIDevice().getComputeCommands(); - } - else if (newOwner == QueueType::GRAPHICS) - { - barrier.dstAccessMask = getDestAccessMask(); - barrier.dstQueueFamilyIndex = device->getGraphicsQueue()->getFamilyIndex(); - dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; - dstManager = device->getRHIDevice().getGraphicsCommands(); - } - VkCommandBuffer srcCommand = sourceManager->getCmdBuffer()->getHandle(); - VkCommandBuffer dstCommand = dstManager->getCmdBuffer()->getHandle(); - const bool bDynamic = (rhiUsage & BUF_Dynamic) != 0; - uint32_t numBuffers = bDynamic ? NUM_BUFFERS : 1; - VkBufferMemoryBarrier dynamicBarriers[NUM_BUFFERS]; - for (uint32_t i = 0; i < numBuffers; ++i) - { - dynamicBarriers[i] = barrier; - dynamicBarriers[i].buffer = buffers[i]->getHandle(); - dynamicBarriers[i].offset = buffers[i]->getOffset(); - dynamicBarriers[i].size = buffers[i]->getSize(); - } - vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr); - vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr); - sourceManager->submitCommands(); -} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp new file mode 100644 index 0000000..e7a1432 --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp @@ -0,0 +1,139 @@ +#include "VulkanCommandBuffer.h" +#include "VulkanInitializer.h" +#include "VulkanGraphics.h" +#include "VulkanGraphicsEnums.h" +#include "VulkanFramebuffer.h" +#include "VulkanRenderPass.h" + +using namespace Seele; +using namespace Seele::Vulkan; + +CmdBufferBase::CmdBufferBase(WGraphics graphics, VkCommandPool cmdPool) + : graphics(graphics) + , owner(cmdPool) +{ + +} + +CmdBufferBase::~CmdBufferBase() +{ +} + +CmdBuffer::CmdBuffer(WGraphics graphics, VkCommandPool cmdPool) + : CmdBufferBase(graphics, cmdPool) + , renderPass(nullptr) + , framebuffer(nullptr) + , subpassIndex(0) +{ + VkCommandBufferAllocateInfo allocInfo = + init::CommandBufferAllocateInfo(cmdPool, + VK_COMMAND_BUFFER_LEVEL_PRIMARY, + 1); + + VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle)) + state = State::ReadyBegin; +} + +CmdBuffer::~CmdBuffer() +{ + vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); +} + +void CmdBuffer::begin() +{ + VkCommandBufferBeginInfo beginInfo = + init::CommandBufferBeginInfo(); + beginInfo.pInheritanceInfo = nullptr; + VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo)); + state = State::InsideBegin; +} + +void CmdBuffer::end() +{ + VK_CHECK(vkEndCommandBuffer(handle)); + state = State::Ended; +} + +void CmdBuffer::beginRenderPass(WRenderPass renderPass, WFramebuffer framebuffer) +{ + VkRenderPassBeginInfo beginInfo = + init::RenderPassBeginInfo(); + beginInfo.clearValueCount = renderPass->getClearValueCount(); + beginInfo.pClearValues = renderPass->getClearValues(); + beginInfo.renderArea = renderPass->getRenderArea(); + beginInfo.renderPass = renderPass->getHandle(); + beginInfo.framebuffer = framebuffer->getHandle(); + vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents()); +} + +void CmdBuffer::endRenderPass() +{ + vkCmdEndRenderPass(handle); +} + +SecondaryCmdBuffer::SecondaryCmdBuffer(WGraphics graphics, VkCommandPool cmdPool) + : CmdBufferBase(graphics, cmdPool) +{ + VkCommandBufferAllocateInfo allocInfo = + init::CommandBufferAllocateInfo(cmdPool, + VK_COMMAND_BUFFER_LEVEL_SECONDARY, + 1); + VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle)); +} + +SecondaryCmdBuffer::~SecondaryCmdBuffer() +{ + vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); +} + +void SecondaryCmdBuffer::begin(WCmdBuffer parent) +{ + VkCommandBufferBeginInfo beginInfo = + init::CommandBufferBeginInfo(); + VkCommandBufferInheritanceInfo inheritanceInfo = + init::CommandBufferInheritanceInfo(); + inheritanceInfo.framebuffer = parent->framebuffer->getHandle(); + inheritanceInfo.renderPass = parent->renderPass->getHandle(); + inheritanceInfo.subpass = parent->subpassIndex; + beginInfo.pInheritanceInfo = &inheritanceInfo; + VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo)); +} + +void SecondaryCmdBuffer::end() +{ + VK_CHECK(vkEndCommandBuffer(handle)); +} + +CommandBufferManager::CommandBufferManager(WGraphics graphics, WQueue queue) + : graphics(graphics) + , queue(queue) +{ + VkCommandPoolCreateInfo info = + init::CommandPoolCreateInfo(); + info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + info.queueFamilyIndex = queue->getFamilyIndex(); + + VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool)); + + activeCmdBuffer = new CmdBuffer(graphics, commandPool); + activeCmdBuffer->begin(); +} + +CommandBufferManager::~CommandBufferManager() +{ + vkDestroyCommandPool(graphics->getDevice(), commandPool, nullptr); +} + +PCmdBuffer CommandBufferManager::getCommands() +{ + return activeCmdBuffer; +} + +PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer() +{ + return PSecondaryCmdBuffer(); +} + +void Seele::Vulkan::CommandBufferManager::submitCommands(PSemaphore signalSemaphore) +{ +} diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h index c785c58..aabf6da 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h @@ -1,38 +1,90 @@ +#pragma once #include "VulkanGraphicsResources.h" +#include "VulkanQueue.h" namespace Seele { namespace Vulkan { - class CmdBufferBase : public RenderCommandBase + DECLARE_REF(RenderPass); + DECLARE_REF(Framebuffer); + class CmdBufferBase : public Gfx::RenderCommandBase { public: - private: + CmdBufferBase(WGraphics graphics, VkCommandPool cmdPool); + virtual ~CmdBufferBase(); + inline VkCommandBuffer getHandle() + { + return handle; + } + void reset(); + VkViewport currentViewport; + VkRect2D currentScissor; + protected: + WGraphics graphics; VkCommandBuffer handle; + VkCommandPool owner; }; - DEFINE_REF(CmdBuffer); + DEFINE_REF(CmdBufferBase); + DECLARE_REF(SecondaryCmdBuffer); class CmdBuffer : public CmdBufferBase { + public: + CmdBuffer(WGraphics graphics, VkCommandPool cmdPool); + virtual ~CmdBuffer(); + void begin(); + void end(); + void beginRenderPass(WRenderPass renderPass, WFramebuffer framebuffer); + void endRenderPass(); + void executeCommands(Array secondaryCommands); + void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore); + enum State + { + ReadyBegin, + InsideBegin, + RenderPassActive, + Ended, + Submitted, + }; + private: + WRenderPass renderPass; + WFramebuffer framebuffer; + uint32 subpassIndex; + State state; + friend class SecondaryCmdBuffer; }; DEFINE_REF(CmdBuffer); + class SecondaryCmdBuffer : public CmdBufferBase + { + public: + SecondaryCmdBuffer(WGraphics graphics, VkCommandPool cmdPool); + virtual ~SecondaryCmdBuffer(); + void begin(WCmdBuffer parent); + void end(); + private: + }; + DEFINE_REF(SecondaryCmdBuffer); + class CommandBufferManager { public: - CommandBufferManager(Vulkan::PGraphics graphics, PVulkanQueue queue); + CommandBufferManager(WGraphics graphics, WQueue queue); virtual ~CommandBufferManager(); PCmdBuffer getCommands(); - PSecondaryCommandBuffer createSecondaryCmdBuffer(); + PSecondaryCmdBuffer createSecondaryCmdBuffer(); void submitCommands(PSemaphore signalSemaphore = nullptr); - void waitForBuffer(PCommandbuffer cmdBuffer, float timeToWait = 1.0f); + void waitForCommands(PCmdBuffer cmdBuffer, float timeToWait = 1.0f); private: + WGraphics graphics; VkCommandPool commandPool; - QueueType queueType; + WQueue queue; uint32 queueFamilyIndex; - Array allocatedBuffers; + PCmdBuffer activeCmdBuffer; + Array allocatedBuffers; }; - DEFINE_REF(VulkanCommandBufferManager); + DEFINE_REF(CommandBufferManager); } } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp index c594c0c..ffe3e6e 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp @@ -149,7 +149,7 @@ void DescriptorSet::writeChanges() } } -DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout) +DescriptorAllocator::DescriptorAllocator(WGraphics graphics, DescriptorLayout& layout) : layout(layout) , graphics(graphics) { diff --git a/src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanFramebuffer.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Engine/Graphics/Vulkan/VulkanFramebuffer.h b/src/Engine/Graphics/Vulkan/VulkanFramebuffer.h new file mode 100644 index 0000000..f4bb5ea --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanFramebuffer.h @@ -0,0 +1,23 @@ +#pragma once +#include "VulkanGraphicsResources.h" + +namespace Seele +{ + namespace Vulkan + { + class Framebuffer + { + public: + Framebuffer(WGraphics graphics); + virtual ~Framebuffer(); + inline VkFramebuffer getHandle() const + { + return handle; + } + private: + WGraphics graphics; + VkFramebuffer handle; + }; + DEFINE_REF(Framebuffer); + } +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp index 766a1da..256ef94 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp @@ -1,16 +1,15 @@ #include "VulkanGraphics.h" #include "VulkanAllocator.h" +#include "VulkanQueue.h" #include "Containers/Array.h" #include "VulkanInitializer.h" +#include "VulkanCommandBuffer.h" #include using namespace Seele::Vulkan; Graphics::Graphics() - : callback(VK_NULL_HANDLE) - , handle(VK_NULL_HANDLE) - , instance(VK_NULL_HANDLE) - , physicalDevice(VK_NULL_HANDLE) + : callback(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), instance(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE) { glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); @@ -18,6 +17,9 @@ Graphics::Graphics() Graphics::~Graphics() { + vkDestroyDevice(handle, nullptr); + DestroyDebugReportCallbackEXT(instance, nullptr, callback); + vkDestroyInstance(instance, nullptr); glfwTerminate(); } @@ -26,23 +28,28 @@ void Graphics::init(GraphicsInitializer initInfo) initInstance(initInfo); setupDebugCallback(); pickPhysicalDevice(); - allocator = new VulkanAllocator(this); + createDevice(initInfo); + allocator = new Allocator(this); + graphicsCommands = new CommandBufferManager(this, graphicsQueue); + computeCommands = new CommandBufferManager(this, computeQueue); + transferCommands = new CommandBufferManager(this, transferQueue); + dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue); } -void Graphics::beginFrame(void* windowHandle) +void Graphics::beginFrame(void *windowHandle) { - GLFWwindow* window = static_cast(windowHandle); + GLFWwindow *window = static_cast(windowHandle); glfwPollEvents(); } -void Graphics::endFrame(void* windowHandle) +void Graphics::endFrame(void *windowHandle) { - GLFWwindow* window = static_cast(windowHandle); + GLFWwindow *window = static_cast(windowHandle); } -void* Graphics::createWindow(const WindowCreateInfo& createInfo) +void *Graphics::createWindow(const WindowCreateInfo &createInfo) { - GLFWwindow* window = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr); + GLFWwindow *window = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr); return window; } @@ -56,14 +63,15 @@ VkPhysicalDevice Graphics::getPhysicalDevice() const return physicalDevice; } -Array Graphics::getRequiredExtensions() +Array Graphics::getRequiredExtensions() { - Array extensions; + Array extensions; unsigned int glfwExtensionCount = 0; - const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); + const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); - for (unsigned int i = 0; i < glfwExtensionCount; i++) { + for (unsigned int i = 0; i < glfwExtensionCount; i++) + { extensions.add(glfwExtensions[i]); } #ifdef ENABLE_VALIDATION @@ -84,7 +92,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo) VkInstanceCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; info.pApplicationInfo = &appInfo; - Array extensions = getRequiredExtensions(); + Array extensions = getRequiredExtensions(); for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i) { extensions.add(initInfo.instanceExtensions[i]); @@ -119,8 +127,8 @@ void Graphics::pickPhysicalDevice() for (auto physicalDevice : physicalDevices) { uint32 currentRating = 0; - VkPhysicalDeviceProperties props; vkGetPhysicalDeviceProperties(physicalDevice, &props); + vkGetPhysicalDeviceFeatures(physicalDevice, &features); if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { currentRating += 100; @@ -138,7 +146,104 @@ void Graphics::pickPhysicalDevice() this->physicalDevice = bestDevice; } -void Graphics::createDevice() +void Graphics::createDevice(GraphicsInitializer initializer) { + uint32_t numQueueFamilies = 0; + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, nullptr); + Array queueProperties(numQueueFamilies); + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, queueProperties.data()); + Array queueInfos; + int32_t graphicsQueueFamilyIndex = -1; + int32_t transferQueueFamilyIndex = -1; + int32_t dedicatedTransferQueueFamilyIndex = -1; + int32_t computeQueueFamilyIndex = -1; + int32_t asyncComputeFamilyIndex = -1; + for (int32_t familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex) + { + const VkQueueFamilyProperties currProps = queueProperties[familyIndex]; + if ((currProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT) + { + if (graphicsQueueFamilyIndex == -1) + { + graphicsQueueFamilyIndex = familyIndex; + } + } + if ((currProps.queueFlags & VK_QUEUE_COMPUTE_BIT) == VK_QUEUE_COMPUTE_BIT) + { + if (computeQueueFamilyIndex == -1) + { + computeQueueFamilyIndex = familyIndex; + } + if (Gfx::useAsyncCompute) + { + if (asyncComputeFamilyIndex == -1) + { + if (familyIndex == graphicsQueueFamilyIndex) + { + if (currProps.queueCount > 1) + { + asyncComputeFamilyIndex = familyIndex; + } + } + else + { + asyncComputeFamilyIndex = familyIndex; + } + } + } + } + if ((currProps.queueFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT) + { + if (transferQueueFamilyIndex == -1) + { + transferQueueFamilyIndex = familyIndex; + } + if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0) + { + dedicatedTransferQueueFamilyIndex = familyIndex; + } + } + VkDeviceQueueCreateInfo info = + init::DeviceQueueCreateInfo(familyIndex, 1); + queueInfos.add(info); + } + VkDeviceCreateInfo deviceInfo = init::DeviceCreateInfo( + queueInfos.data(), + (uint32)queueInfos.size(), + &features); + 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)); + + graphicsQueue = new Queue(this, QueueType::GRAPHICS, graphicsQueueFamilyIndex, 0); + if (Gfx::useAsyncCompute && asyncComputeFamilyIndex != -1) + { + if (asyncComputeFamilyIndex == graphicsQueueFamilyIndex) + { + // Same family as graphics, but different queue + computeQueue = new Queue(this, QueueType::COMPUTE, asyncComputeFamilyIndex, 1); + } + else + { + // Different family + computeQueue = new Queue(this, QueueType::COMPUTE, asyncComputeFamilyIndex, 0); + } + } + else + { + computeQueue = new Queue(this, QueueType::COMPUTE, computeQueueFamilyIndex, 0); + } + transferQueue = new Queue(this, QueueType::TRANSFER, transferQueueFamilyIndex, 0); + if (dedicatedTransferQueueFamilyIndex != -1) + { + dedicatedTransferQueue = new Queue(this, QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueFamilyIndex, 0); + } + 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 ac76ff8..bef75ce 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.h @@ -1,3 +1,4 @@ +#pragma once #include "Graphics/Graphics.h" #include "VulkanGraphicsResources.h" @@ -6,6 +7,8 @@ namespace Seele namespace Vulkan { DECLARE_REF(Allocator); + DECLARE_REF(CommandBufferManager); + DECLARE_REF(Queue); class Graphics : public Gfx::Graphics { public: @@ -14,6 +17,11 @@ namespace Seele VkDevice getDevice() const; VkPhysicalDevice getPhysicalDevice() const; + PCommandBufferManager getGraphicsCommands(); + PCommandBufferManager getComputeCommands(); + PCommandBufferManager getTransferCommands(); + PCommandBufferManager getDedicatedTransferCommands(); + // Inherited via Graphics virtual void init(GraphicsInitializer initializer) override; virtual void beginFrame(void* windowHandle) override; @@ -24,14 +32,27 @@ namespace Seele void initInstance(GraphicsInitializer initInfo); void setupDebugCallback(); void pickPhysicalDevice(); - void createDevice(); + void createDevice(GraphicsInitializer initInfo); VkDevice handle; VkPhysicalDevice physicalDevice; VkInstance instance; + + WQueue graphicsQueue; + WQueue computeQueue; + WQueue transferQueue; + WQueue dedicatedTransferQueue; + QueueFamilyMapping queueMapping; + PCommandBufferManager graphicsCommands; + PCommandBufferManager computeCommands; + PCommandBufferManager transferCommands; + PCommandBufferManager dedicatedTransferCommands; + VkPhysicalDeviceProperties props; + VkPhysicalDeviceFeatures features; VkDebugReportCallbackEXT callback; Array viewports; PAllocator allocator; + friend class Window; }; DEFINE_REF(Graphics); diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp index b72d512..dc0aac7 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp @@ -3,7 +3,7 @@ using namespace Seele::Vulkan; using namespace Seele::Gfx; -VkDescriptorType cast(const Seele::Gfx::SeDescriptorType& descriptorType) +VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType& descriptorType) { switch (descriptorType) { @@ -41,7 +41,7 @@ VkDescriptorType cast(const Seele::Gfx::SeDescriptorType& descriptorType) return VK_DESCRIPTOR_TYPE_MAX_ENUM; } -Seele::Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType) +Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType& descriptorType) { switch (descriptorType) { @@ -80,7 +80,7 @@ Seele::Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType) return SE_DESCRIPTOR_TYPE_MAX_ENUM; } -VkShaderStageFlagBits cast(const Seele::Gfx::SeShaderStageFlagBits& stage) +VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits& stage) { switch (stage) { @@ -125,7 +125,7 @@ VkShaderStageFlagBits cast(const Seele::Gfx::SeShaderStageFlagBits& stage) return VK_SHADER_STAGE_ALL; } -Seele::Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits& stage) +Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits& stage) { switch (stage) { diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp new file mode 100644 index 0000000..25640ac --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.cpp @@ -0,0 +1,20 @@ +#include "VulkanGraphicsResources.h" +#include "VulkanInitializer.h" +#include "VulkanGraphics.h" +#include "VulkanGraphicsEnums.h" + +using namespace Seele; +using namespace Seele::Vulkan; + +Semaphore::Semaphore(WGraphics graphics) + : graphics(graphics) +{ + VkSemaphoreCreateInfo info = + init::SemaphoreCreateInfo(); + VK_CHECK(vkCreateSemaphore(graphics->getDevice(), &info, nullptr, &handle)); +} + +Semaphore::~Semaphore() +{ + +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 1882418..475f43c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -4,189 +4,240 @@ namespace Seele { - namespace Vulkan +namespace Vulkan +{ + +DECLARE_REF(DescriptorAllocator); +DECLARE_REF(CommandBufferManager); +DECLARE_REF(Graphics); +class Semaphore +{ +public: + Semaphore(WGraphics graphics); + virtual ~Semaphore(); + +private: + VkSemaphore handle; + WGraphics graphics; +}; +DEFINE_REF(Semaphore); + +class DescriptorLayout : public Gfx::DescriptorLayout +{ +public: + DescriptorLayout(WGraphics graphics) + : graphics(graphics), layoutHandle(VK_NULL_HANDLE) { - DECLARE_REF(DescriptorAllocator); - DECLARE_REF(Graphics); - class DescriptorLayout : public Gfx::DescriptorLayout - { - public: - DescriptorLayout(PGraphics graphics) - : graphics(graphics) - , layoutHandle(VK_NULL_HANDLE) - {} - virtual ~DescriptorLayout(); - virtual void create(); - inline VkDescriptorSetLayout getHandle() const - { - return layoutHandle; - } - private: - PGraphics graphics; - Array bindings; - VkDescriptorSetLayout layoutHandle; - friend class PipelineStateCacheManager; - }; - DEFINE_REF(DescriptorLayout); - class PipelineLayout : public Gfx::PipelineLayout - { - public: - PipelineLayout(PGraphics graphics) - : graphics(graphics) - , layoutHash(0) - , layoutHandle(VK_NULL_HANDLE) - {} - virtual ~PipelineLayout(); - virtual void create(); - inline VkPipelineLayout getHandle() const - { - return layoutHandle; - } - virtual uint32 getHash() const - { - return layoutHash; - } - private: - Array vulkanDescriptorLayouts; - uint32 layoutHash; - VkPipelineLayout layoutHandle; - PGraphics graphics; - friend class PipelineStateCacheManager; - }; - DEFINE_REF(PipelineLayout); - - class DescriptorSet : public Gfx::DescriptorSet - { - public: - DescriptorSet(PGraphics graphics, PDescriptorAllocator owner) - : graphics(graphics) - , owner(owner) - , setHandle(VK_NULL_HANDLE) - {} - virtual ~DescriptorSet(); - virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer); - virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer); - virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState); - virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr); - virtual bool operator<(Gfx::PDescriptorSet other); - inline VkDescriptorSet getHandle() const - { - return setHandle; - } - private: - virtual void writeChanges(); - Array imageInfos; - Array bufferInfos; - Array writeDescriptors; - VkDescriptorSet setHandle; - PDescriptorAllocator owner; - PGraphics graphics; - friend class DescriptorAllocator; - }; - DEFINE_REF(DescriptorSet); - - class DescriptorAllocator : public Gfx::DescriptorAllocator - { - public: - DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout); - ~DescriptorAllocator(); - virtual void allocateDescriptorSet(Gfx::PDescriptorSet& descriptorSet); - - inline VkDescriptorPool getHandle() - { - return poolHandle; - } - private: - PGraphics graphics; - int maxSets = 512; - VkDescriptorPool poolHandle; - DescriptorLayout& layout; - }; - DEFINE_REF(DescriptorAllocator); - enum class QueueType - { - GRAPHICS = 1, - COMPUTE = 2, - TRANSFER = 3 - }; - class QueueOwnedResource - { - public: - QueueOwnedResource(PGraphics graphics, QueueType startQueueType); - ~QueueOwnedResource(); - CommandBufferManager* getCommands(); - //Preliminary checks to see if the barrier should be executed at all - void transferOwnership(QueueType newOwner); - protected: - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - QueueType currentOwner; - PGraphics graphics; - CommandBufferManager* cachedCmdBufferManager; - }; - DEFINE_REF(QueueOwnedResource); - - class Buffer : public QueueOwnedResource - { - public: - Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage); - virtual ~Buffer(); - private: - virtual VkAccessFlags getSourceAccessMask() = 0; - virtual VkAccessFlags getDestAccessMask() = 0; - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner); - }; - DEFINE_REF(Buffer); - - class UniformBuffer : public Gfx::UniformBuffer - { - - }; - DEFINE_REF(UniformBuffer); - - class StructuredBuffer : public Gfx::StructuredBuffer - { - - }; - DEFINE_REF(StructuredBuffer); - - class TextureBase - { - private: - uint32 sizeX; - uint32 sizeY; - uint32 sizeZ; - uint32 arrayCount; - uint32 layerCount; - }; - DEFINE_REF(TextureBase); - - class Texture2D : public Gfx::Texture2D - { - public: - private: - PTextureBase textureHandle; - }; - DEFINE_REF(Texture2D); - - class SamplerState - { - public: - VkSampler sampler; - }; - DEFINE_REF(SamplerState); - - class Viewport : public Gfx::Viewport - { - public: - private: - uint32 sizeX; - uint32 sizeY; - uint32 offsetX; - uint32 offsetY; - VkSwapchainKHR swapchain; - void* windowHandle; - }; - DECLARE_REF(Viewport); } -} \ No newline at end of file + virtual ~DescriptorLayout(); + virtual void create(); + inline VkDescriptorSetLayout getHandle() const + { + return layoutHandle; + } + +private: + WGraphics graphics; + Array bindings; + VkDescriptorSetLayout layoutHandle; + friend class PipelineStateCacheManager; +}; +DEFINE_REF(DescriptorLayout); +class PipelineLayout : public Gfx::PipelineLayout +{ +public: + PipelineLayout(WGraphics graphics) + : graphics(graphics), layoutHash(0), layoutHandle(VK_NULL_HANDLE) + { + } + virtual ~PipelineLayout(); + virtual void create(); + inline VkPipelineLayout getHandle() const + { + return layoutHandle; + } + virtual uint32 getHash() const + { + return layoutHash; + } + +private: + Array vulkanDescriptorLayouts; + uint32 layoutHash; + VkPipelineLayout layoutHandle; + WGraphics graphics; + friend class PipelineStateCacheManager; +}; +DEFINE_REF(PipelineLayout); + +class DescriptorSet : public Gfx::DescriptorSet +{ +public: + DescriptorSet(WGraphics graphics, PDescriptorAllocator owner) + : graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE) + { + } + virtual ~DescriptorSet(); + virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer); + virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer); + virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState); + virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr); + virtual bool operator<(Gfx::PDescriptorSet other); + inline VkDescriptorSet getHandle() const + { + return setHandle; + } + +private: + virtual void writeChanges(); + Array imageInfos; + Array bufferInfos; + Array writeDescriptors; + VkDescriptorSet setHandle; + PDescriptorAllocator owner; + WGraphics graphics; + friend class DescriptorAllocator; +}; +DEFINE_REF(DescriptorSet); + +class DescriptorAllocator : public Gfx::DescriptorAllocator +{ +public: + DescriptorAllocator(WGraphics graphics, DescriptorLayout &layout); + ~DescriptorAllocator(); + virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet); + + inline VkDescriptorPool getHandle() + { + return poolHandle; + } + +private: + WGraphics graphics; + int maxSets = 512; + VkDescriptorPool poolHandle; + DescriptorLayout &layout; +}; +DEFINE_REF(DescriptorAllocator); +enum class QueueType +{ + GRAPHICS = 1, + COMPUTE = 2, + TRANSFER = 3, + DEDICATED_TRANSFER = 4 +}; + +struct QueueFamilyMapping +{ + uint32 graphicsFamily; + uint32 computeFamily; + uint32 transferFamily; + uint32 dedicatedTransferFamily; + uint32 getQueueTypeFamilyIndex(QueueType type) + { + switch (type) + { + case QueueType::GRAPHICS: + return graphicsFamily; + case QueueType::COMPUTE: + return computeFamily; + case QueueType::TRANSFER: + return transferFamily; + case QueueType::DEDICATED_TRANSFER: + return dedicatedTransferFamily; + default: + return VK_QUEUE_FAMILY_IGNORED; + } + } + bool needsTransfer(QueueType src, QueueType dst) + { + uint32 srcIndex = getQueueTypeFamilyIndex(src); + uint32 dstIndex = getQueueTypeFamilyIndex(dst); + return srcIndex != dstIndex; + } +}; +class QueueOwnedResource +{ +public: + QueueOwnedResource(WGraphics graphics, QueueType startQueueType); + ~QueueOwnedResource(); + PCommandBufferManager getCommands(); + //Preliminary checks to see if the barrier should be executed at all + void transferOwnership(QueueType newOwner); + +protected: + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + QueueType currentOwner; + WGraphics graphics; + CommandBufferManager *cachedCmdBufferManager; +}; +DEFINE_REF(QueueOwnedResource); + +class Buffer : public QueueOwnedResource +{ +public: + Buffer(WGraphics graphics, uint32 size, VkBufferUsageFlags usage); + virtual ~Buffer(); + +private: + virtual VkAccessFlags getSourceAccessMask() = 0; + virtual VkAccessFlags getDestAccessMask() = 0; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner); +}; +DEFINE_REF(Buffer); + +class UniformBuffer : public Buffer, public Gfx::UniformBuffer +{ +}; +DEFINE_REF(UniformBuffer); + +class StructuredBuffer : public Buffer, public Gfx::StructuredBuffer +{ +}; +DEFINE_REF(StructuredBuffer); + +class TextureBase +{ +public: + TextureBase(); + virtual ~TextureBase(); +private: + uint32 sizeX; + uint32 sizeY; + uint32 sizeZ; + uint32 arrayCount; + uint32 layerCount; + VkImage image; +}; +DEFINE_REF(TextureBase); + +class Texture2D : public Gfx::Texture2D +{ +public: +private: + PTextureBase textureHandle; +}; +DEFINE_REF(Texture2D); + +class SamplerState +{ +public: + VkSampler sampler; +}; +DEFINE_REF(SamplerState); + +class Viewport : public Gfx::Viewport +{ +public: +private: + uint32 sizeX; + uint32 sizeY; + uint32 offsetX; + uint32 offsetY; + VkSwapchainKHR swapchain; + void *windowHandle; +}; +DECLARE_REF(Viewport); +} // namespace Vulkan +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp b/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp index 5c3c7c2..76c4670 100644 --- a/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp @@ -743,11 +743,11 @@ VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStag } -VkBool32 debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userDataManager) { +VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userDataManager) { std::cerr << layerPrefix << ": " << msg << std::endl; return VK_FALSE; } -VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) { +VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) { auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); if (func != nullptr) { return func(instance, pCreateInfo, pAllocator, pCallback); @@ -757,7 +757,7 @@ VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCa } } -void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback) +void Seele::Vulkan::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback) { auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); if (func != nullptr) { diff --git a/src/Engine/Graphics/Vulkan/VulkanInitializer.h b/src/Engine/Graphics/Vulkan/VulkanInitializer.h index 76f64a5..ebbfc69 100644 --- a/src/Engine/Graphics/Vulkan/VulkanInitializer.h +++ b/src/Engine/Graphics/Vulkan/VulkanInitializer.h @@ -1,3 +1,4 @@ +#pragma once #include "Containers/Array.h" #include diff --git a/src/Engine/Graphics/Vulkan/VulkanQueue.cpp b/src/Engine/Graphics/Vulkan/VulkanQueue.cpp new file mode 100644 index 0000000..92a80ed --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanQueue.cpp @@ -0,0 +1,19 @@ +#include "VulkanQueue.h" +#include "VulkanInitializer.h" +#include "VulkanGraphics.h" + +using namespace Seele; +using namespace Seele::Vulkan; + +Queue::Queue(WGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex) + : familyIndex(familyIndex) + , graphics(graphics) + , queueType(queueType) +{ + vkGetDeviceQueue(graphics->getDevice(), familyIndex, queueIndex, &queue); +} + +Queue::~Queue() +{ + +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanQueue.h b/src/Engine/Graphics/Vulkan/VulkanQueue.h new file mode 100644 index 0000000..1538cda --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanQueue.h @@ -0,0 +1,36 @@ +#pragma once +#include "VulkanGraphicsResources.h" + +namespace Seele +{ + namespace Vulkan + { + DECLARE_REF(CmdBuffer); + DECLARE_REF(Graphics); + class Queue + { + public: + Queue(WGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex); + virtual ~Queue(); + void submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores = 0, VkSemaphore* signalSemaphore = nullptr); + inline void submitCommandBuffer(PCmdBuffer cmdBuffer, VkSemaphore signalSemaphore) + { + submitCommandBuffer(cmdBuffer, 1, &signalSemaphore); + } + uint32 getFamilyIndex() const + { + return familyIndex; + } + inline VkQueue getHandle() const + { + return queue; + } + private: + WGraphics graphics; + VkQueue queue; + uint32 familyIndex; + QueueType queueType; + }; + DEFINE_REF(Queue) + } +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanRenderPass.cpp b/src/Engine/Graphics/Vulkan/VulkanRenderPass.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Engine/Graphics/Vulkan/VulkanRenderPass.h b/src/Engine/Graphics/Vulkan/VulkanRenderPass.h new file mode 100644 index 0000000..c131e82 --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanRenderPass.h @@ -0,0 +1,40 @@ +#include "VulkanGraphicsResources.h" + +namespace Seele +{ + namespace Vulkan + { + class RenderPass + { + public: + RenderPass(); + virtual ~RenderPass(); + inline VkRenderPass getHandle() const + { + return renderPass; + } + inline uint32 getClearValueCount() const + { + return clearValues.size(); + } + inline VkClearValue* getClearValues() const + { + return clearValues.data(); + } + inline VkRect2D getRenderArea() const + { + return renderArea; + } + inline VkSubpassContents getSubpassContents() const + { + return subpassContents; + } + private: + VkRenderPass renderPass; + Array clearValues; + VkRect2D renderArea; + VkSubpassContents subpassContents; + }; + DEFINE_REF(RenderPass); + } +} \ No newline at end of file diff --git a/src/Engine/Graphics/WindowManager.cpp b/src/Engine/Graphics/WindowManager.cpp index 6a5b931..9368d29 100644 --- a/src/Engine/Graphics/WindowManager.cpp +++ b/src/Engine/Graphics/WindowManager.cpp @@ -3,7 +3,7 @@ Seele::WindowManager::WindowManager() { - graphics = new VulkanGraphics(); + graphics = new Vulkan::Graphics(); GraphicsInitializer initializer; graphics->init(initializer); } diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 09e4c27..5d0aeb0 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -43,7 +43,6 @@ namespace Seele { } - ~RefObject() {} bool operator==(const RefObject& other) const @@ -81,6 +80,10 @@ namespace Seele { object = nullptr; } + RefPtr(nullptr_t) + { + object = nullptr; + } RefPtr(T* ptr) { object = new RefObject(ptr); @@ -160,14 +163,19 @@ namespace Seele private: RefObject* object; }; + //A weak pointer has no ownership over an object and thus cant delete it template class WeakPtr { public: WeakPtr() + : pointer(nullptr) + {} + WeakPtr(T* ptr) + : pointer(ptr) {} WeakPtr(RefPtr& sharedPtr) - : pointer(sharedPtr.object) + : pointer(sharedPtr.object->handle) {} WeakPtr& operator=(WeakPtr& weakPtr) { @@ -176,17 +184,20 @@ namespace Seele } WeakPtr& operator=(RefPtr& sharedPtr) { - pointer = sharedPtr; + pointer = sharedPtr.object->handle; return *this; } - RefPtr& lock() + WeakPtr& operator=(T* ptr) { - RefPtr temp; - temp.object = pointer; - return temp; + pointer = ptr; + return *this; + } + inline T* operator->() + { + return pointer; } private: - RefObject* pointer; + T* pointer; }; template class UniquePtr