diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj index c55a799..2fdeb30 100644 --- a/CopiumEngine/CopiumEngine.vcxproj +++ b/CopiumEngine/CopiumEngine.vcxproj @@ -1,4 +1,4 @@ - + @@ -166,6 +166,9 @@ + + + @@ -195,6 +198,10 @@ + + + + diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters index cacdba6..861af70 100644 --- a/CopiumEngine/CopiumEngine.vcxproj.filters +++ b/CopiumEngine/CopiumEngine.vcxproj.filters @@ -102,6 +102,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + @@ -194,6 +203,18 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + diff --git a/CopiumEngine/src/copium/buffer/Buffer.cpp b/CopiumEngine/src/copium/buffer/Buffer.cpp index 51c1f8b..1c2256d 100644 --- a/CopiumEngine/src/copium/buffer/Buffer.cpp +++ b/CopiumEngine/src/copium/buffer/Buffer.cpp @@ -1,9 +1,12 @@ #include "copium/buffer/Buffer.h" +#include "copium/core/Device.h" +#include "copium/core/Instance.h" + namespace Copium { - Buffer::Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count) - : instance{instance}, size{size}, count{count} + Buffer::Buffer(Vulkan& vulkan, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count) + : vulkan{vulkan}, size{size}, count{count} { VkBufferCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; @@ -11,25 +14,25 @@ namespace Copium createInfo.usage = usage; createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - CP_VK_ASSERT(vkCreateBuffer(instance.GetDevice(), &createInfo, nullptr, &handle), "Buffer : Failed to initialize buffer"); + CP_VK_ASSERT(vkCreateBuffer(vulkan.GetDevice(), &createInfo, nullptr, &handle), "Buffer : Failed to initialize buffer"); VkMemoryRequirements memoryRequirements; - vkGetBufferMemoryRequirements(instance.GetDevice(), handle, &memoryRequirements); + vkGetBufferMemoryRequirements(vulkan.GetDevice(), handle, &memoryRequirements); VkMemoryAllocateInfo allocateInfo{}; allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocateInfo.allocationSize = memoryRequirements.size; - allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties); + allocateInfo.memoryTypeIndex = vulkan.GetDevice().FindMemoryType(memoryRequirements.memoryTypeBits, properties); - CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, &memory), "Buffer : Failed to allocate buffer memory"); + CP_VK_ASSERT(vkAllocateMemory(vulkan.GetDevice(), &allocateInfo, nullptr, &memory), "Buffer : Failed to allocate buffer memory"); - vkBindBufferMemory(instance.GetDevice(), handle, memory, 0); + vkBindBufferMemory(vulkan.GetDevice(), handle, memory, 0); } Buffer::~Buffer() { - vkFreeMemory(instance.GetDevice(), memory, nullptr); - vkDestroyBuffer(instance.GetDevice(), handle, nullptr); + vkFreeMemory(vulkan.GetDevice(), memory, nullptr); + vkDestroyBuffer(vulkan.GetDevice(), handle, nullptr); } void Buffer::Update(void* indexData, int index) @@ -39,9 +42,9 @@ namespace Copium if (mappedData == nullptr) { void* data; - vkMapMemory(instance.GetDevice(), memory, index * size, size, 0, &data); + vkMapMemory(vulkan.GetDevice(), memory, index * size, size, 0, &data); memcpy(data, indexData, size); - vkUnmapMemory(instance.GetDevice(), memory); + vkUnmapMemory(vulkan.GetDevice(), memory); } else { @@ -52,26 +55,26 @@ namespace Copium void Buffer::UpdateStaging(void* data) { VkDeviceSize bufferSize = size * count; - Buffer stagingBuffer{instance, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1}; + Buffer stagingBuffer{vulkan, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1}; stagingBuffer.Update(data, 0); - CopyBuffer(instance, stagingBuffer, *this, 0, bufferSize); + CopyBuffer(vulkan, stagingBuffer, *this, 0, bufferSize); } void Buffer::UpdateStaging(void* data, VkDeviceSize offset, VkDeviceSize size) { - Buffer stagingBuffer{instance, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, 1}; + Buffer stagingBuffer{vulkan, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, 1}; stagingBuffer.Update(data, 0); - CopyBuffer(instance, stagingBuffer, *this, offset, size); + CopyBuffer(vulkan, stagingBuffer, *this, offset, size); } void* Buffer::Map() { CP_ASSERT(mappedData == nullptr, "Map : Mapping an already mapped buffer"); - vkMapMemory(instance.GetDevice(), memory, 0, size * count, 0, &mappedData); + vkMapMemory(vulkan.GetDevice(), memory, 0, size * count, 0, &mappedData); return mappedData; } @@ -79,7 +82,7 @@ namespace Copium { CP_ASSERT(mappedData != nullptr, "Unmap : Unmapping an already unmapped buffer"); - vkUnmapMemory(instance.GetDevice(), memory); + vkUnmapMemory(vulkan.GetDevice(), memory); mappedData = nullptr; } @@ -99,17 +102,17 @@ namespace Copium return size * (VkDeviceSize)index; } - void Buffer::CopyBuffer(Instance& instance, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size) + void Buffer::CopyBuffer(Vulkan& vulkan, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size) { VkCommandBufferAllocateInfo allocateInfo{}; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocateInfo.commandPool = instance.GetCommandPool(); + allocateInfo.commandPool = vulkan.GetDevice().GetCommandPool(); allocateInfo.commandBufferCount = 1; VkCommandBuffer commandBuffer; - CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, &commandBuffer), "CopyBuffer : Failed to initialize command buffer"); + CP_VK_ASSERT(vkAllocateCommandBuffers(vulkan.GetDevice(), &allocateInfo, &commandBuffer), "CopyBuffer : Failed to initialize command buffer"); VkCommandBufferBeginInfo beginInfo{}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -131,9 +134,9 @@ namespace Copium submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffer; - vkQueueSubmit(instance.GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE); - vkQueueWaitIdle(instance.GetGraphicsQueue()); + vkQueueSubmit(vulkan.GetDevice().GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE); + vkQueueWaitIdle(vulkan.GetDevice().GetGraphicsQueue()); - vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), 1, &commandBuffer); + vkFreeCommandBuffers(vulkan.GetDevice(), vulkan.GetDevice().GetCommandPool(), 1, &commandBuffer); } } diff --git a/CopiumEngine/src/copium/buffer/Buffer.h b/CopiumEngine/src/copium/buffer/Buffer.h index 8e795c5..a3e6070 100644 --- a/CopiumEngine/src/copium/buffer/Buffer.h +++ b/CopiumEngine/src/copium/buffer/Buffer.h @@ -1,6 +1,6 @@ #pragma once -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" #include @@ -11,7 +11,7 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(Buffer); protected: - Instance& instance; + Vulkan& vulkan; VkDeviceMemory memory; VkBuffer handle; @@ -21,7 +21,7 @@ namespace Copium void* mappedData = nullptr; public: - Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count); + Buffer(Vulkan& vulkan, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count); virtual ~Buffer(); void Update(void* indexData, int index); @@ -35,6 +35,6 @@ namespace Copium VkDeviceSize GetSize() const; VkDeviceSize GetPosition(int index) const; - static void CopyBuffer(Instance& instance, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size); + static void CopyBuffer(Vulkan& vulkan, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size); }; } diff --git a/CopiumEngine/src/copium/buffer/CommandBuffer.cpp b/CopiumEngine/src/copium/buffer/CommandBuffer.cpp index 8fc2d70..4eae0a7 100644 --- a/CopiumEngine/src/copium/buffer/CommandBuffer.cpp +++ b/CopiumEngine/src/copium/buffer/CommandBuffer.cpp @@ -1,26 +1,37 @@ #include "copium/buffer/CommandBuffer.h" +#include "copium/core/Device.h" +#include "copium/core/Instance.h" +#include "copium/core/SwapChain.h" + namespace Copium { - CommandBuffer::CommandBuffer(Instance& instance, Type type) - : instance{instance}, type{type} + CommandBuffer::CommandBuffer(Vulkan& vulkan, Type type) + : vulkan{vulkan}, type{type} { - if (type == Type::Dynamic) - commandBuffers.resize(instance.GetMaxFramesInFlight()); - else + switch (type) + { + case Type::SingleUse: commandBuffers.resize(1); + break; + case Type::Dynamic: + commandBuffers.resize(SwapChain::MAX_FRAMES_IN_FLIGHT); + break; + default: + CP_ABORT("CommandBuffer : Unreachable switch case"); + } VkCommandBufferAllocateInfo allocateInfo{}; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocateInfo.commandPool = instance.GetCommandPool(); + allocateInfo.commandPool = vulkan.GetDevice().GetCommandPool(); allocateInfo.commandBufferCount = commandBuffers.size(); - CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, commandBuffers.data()), "CommandBuffer : Failed to allocate CommandBuffer"); + CP_VK_ASSERT(vkAllocateCommandBuffers(vulkan.GetDevice(), &allocateInfo, commandBuffers.data()), "CommandBuffer : Failed to allocate CommandBuffer"); } CommandBuffer::~CommandBuffer() { - vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), commandBuffers.size(), commandBuffers.data()); + vkFreeCommandBuffers(vulkan.GetDevice(), vulkan.GetDevice().GetCommandPool(), commandBuffers.size(), commandBuffers.data()); } // TODO: Test as constexpr function to see if it avoids the switch case @@ -30,26 +41,25 @@ namespace Copium beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.flags = 0; beginInfo.pInheritanceInfo = nullptr; + switch (type) { case Type::SingleUse: beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - currentCommandBuffer = commandBuffers.front(); break; case Type::Dynamic: - currentCommandBuffer = commandBuffers[instance.GetFlightIndex()]; break; default: CP_ABORT("Begin : Unreachable switch case"); } - vkResetCommandBuffer(currentCommandBuffer, 0); - CP_VK_ASSERT(vkBeginCommandBuffer(currentCommandBuffer, &beginInfo), "Begin : Failed to begin command buffer"); + vkResetCommandBuffer(commandBuffers[vulkan.GetSwapChain().GetFlightIndex()], 0); + CP_VK_ASSERT(vkBeginCommandBuffer(commandBuffers[vulkan.GetSwapChain().GetFlightIndex()], &beginInfo), "Begin : Failed to begin command buffer"); } void CommandBuffer::End() { - vkEndCommandBuffer(currentCommandBuffer); + vkEndCommandBuffer(commandBuffers[vulkan.GetSwapChain().GetFlightIndex()]); } void CommandBuffer::Submit() @@ -57,20 +67,15 @@ namespace Copium VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = ¤tCommandBuffer; + submitInfo.pCommandBuffers = &commandBuffers[vulkan.GetSwapChain().GetFlightIndex()]; - vkQueueSubmit(instance.GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE); + vkQueueSubmit(vulkan.GetDevice().GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE); // TODO: if singleUse? - vkQueueWaitIdle(instance.GetGraphicsQueue()); - } - - void CommandBuffer::SubmitAsGraphicsQueue() - { - instance.SubmitGraphicsQueue({currentCommandBuffer}); + vkQueueWaitIdle(vulkan.GetDevice().GetGraphicsQueue()); } CommandBuffer::operator VkCommandBuffer() const { - return currentCommandBuffer; + return commandBuffers[vulkan.GetSwapChain().GetFlightIndex()]; } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/buffer/CommandBuffer.h b/CopiumEngine/src/copium/buffer/CommandBuffer.h index 022aede..67ce2cb 100644 --- a/CopiumEngine/src/copium/buffer/CommandBuffer.h +++ b/CopiumEngine/src/copium/buffer/CommandBuffer.h @@ -1,6 +1,6 @@ #pragma once -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" #include @@ -16,21 +16,18 @@ namespace Copium SingleUse, Dynamic }; private: - Instance& instance; + Vulkan& vulkan; std::vector commandBuffers; const Type type; - VkCommandBuffer currentCommandBuffer{VK_NULL_HANDLE}; public: - CommandBuffer(Instance& instance, Type type); - + CommandBuffer(Vulkan& vulkan, Type type); virtual ~CommandBuffer(); void Begin(); void End(); void Submit(); - void SubmitAsGraphicsQueue(); operator VkCommandBuffer() const; }; diff --git a/CopiumEngine/src/copium/buffer/CommandBufferScoped.cpp b/CopiumEngine/src/copium/buffer/CommandBufferScoped.cpp index 2aa4377..dcf9512 100644 --- a/CopiumEngine/src/copium/buffer/CommandBufferScoped.cpp +++ b/CopiumEngine/src/copium/buffer/CommandBufferScoped.cpp @@ -2,8 +2,8 @@ namespace Copium { - CommandBufferScoped::CommandBufferScoped(Instance& instance) - : CommandBuffer{instance, Type::SingleUse} + CommandBufferScoped::CommandBufferScoped(Vulkan& vulkan) + : CommandBuffer{vulkan, Type::SingleUse} { CommandBuffer::Begin(); } diff --git a/CopiumEngine/src/copium/buffer/CommandBufferScoped.h b/CopiumEngine/src/copium/buffer/CommandBufferScoped.h index d459de7..e17b5c6 100644 --- a/CopiumEngine/src/copium/buffer/CommandBufferScoped.h +++ b/CopiumEngine/src/copium/buffer/CommandBufferScoped.h @@ -1,7 +1,7 @@ #pragma once #include "copium/buffer/CommandBuffer.h" -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" namespace Copium @@ -10,7 +10,7 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(CommandBufferScoped); public: - CommandBufferScoped(Instance& instance); + CommandBufferScoped(Vulkan& vulkan); ~CommandBufferScoped() override; }; diff --git a/CopiumEngine/src/copium/buffer/Framebuffer.cpp b/CopiumEngine/src/copium/buffer/Framebuffer.cpp index 7c7ebb7..811f8c6 100644 --- a/CopiumEngine/src/copium/buffer/Framebuffer.cpp +++ b/CopiumEngine/src/copium/buffer/Framebuffer.cpp @@ -1,12 +1,14 @@ #include "copium/buffer/Framebuffer.h" #include "copium/buffer/CommandBuffer.h" +#include "copium/core/Device.h" +#include "copium/core/SwapChain.h" #include "copium/sampler/Image.h" namespace Copium { - Framebuffer::Framebuffer(Instance& instance, uint32_t width, uint32_t height) - : instance{instance}, width{width}, height{height} + Framebuffer::Framebuffer(Vulkan& vulkan, uint32_t width, uint32_t height) + : vulkan{vulkan}, width{width}, height{height} { InitializeImage(); InitializeDepthBuffer(); @@ -17,19 +19,19 @@ namespace Copium Framebuffer::~Framebuffer() { for (auto& framebuffer : framebuffers) - vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr); - vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr); + vkDestroyFramebuffer(vulkan.GetDevice(), framebuffer, nullptr); + vkDestroyRenderPass(vulkan.GetDevice(), renderPass, nullptr); } void Framebuffer::Resize(uint32_t width, uint32_t height) { - vkDeviceWaitIdle(instance.GetDevice()); + vkDeviceWaitIdle(vulkan.GetDevice()); this->width = width; this->height = height; colorAttachment.reset(); depthAttachment.reset(); for (auto&& framebuffer : framebuffers) - vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr); + vkDestroyFramebuffer(vulkan.GetDevice(), framebuffer, nullptr); InitializeImage(); InitializeDepthBuffer(); InitializeFramebuffers(); @@ -44,7 +46,8 @@ namespace Copium VkRenderPassBeginInfo renderPassBeginInfo{}; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassBeginInfo.renderPass = renderPass; - renderPassBeginInfo.framebuffer = framebuffers[instance.GetFlightIndex()]; + renderPassBeginInfo.framebuffer = framebuffers[vulkan.GetSwapChain().GetFlightIndex()]; +; renderPassBeginInfo.renderArea.offset = {0, 0}; renderPassBeginInfo.renderArea.extent = {width, height}; renderPassBeginInfo.clearValueCount = clearValues.size(); @@ -77,7 +80,7 @@ namespace Copium VkFramebuffer Framebuffer::GetFramebuffer() const { - return framebuffers[instance.GetFlightIndex()]; + return framebuffers[vulkan.GetSwapChain().GetFlightIndex()]; } const ColorAttachment& Framebuffer::GetColorAttachment() const @@ -97,12 +100,12 @@ namespace Copium void Framebuffer::InitializeImage() { - colorAttachment = std::make_unique(instance, width, height); + colorAttachment = std::make_unique(vulkan, width, height); } void Framebuffer::InitializeDepthBuffer() { - depthAttachment = std::make_unique(instance, width, height); + depthAttachment = std::make_unique(vulkan, width, height); } void Framebuffer::InitializeRenderPass() @@ -118,7 +121,7 @@ namespace Copium colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkAttachmentDescription depthAttachment{}; - depthAttachment.format = Image::SelectDepthFormat(instance); + depthAttachment.format = Image::SelectDepthFormat(vulkan); depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -166,14 +169,13 @@ namespace Copium renderPassCreateInfo.dependencyCount = dependencies.size(); renderPassCreateInfo.pDependencies = dependencies.data(); - CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass"); + CP_VK_ASSERT(vkCreateRenderPass(vulkan.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass"); } void Framebuffer::InitializeFramebuffers() { - framebuffers.resize(instance.GetMaxFramesInFlight()); - - for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) + framebuffers.resize(SwapChain::MAX_FRAMES_IN_FLIGHT); + for (size_t i = 0; i < framebuffers.size(); ++i) { std::vector attachments{colorAttachment->GetImageView(i), depthAttachment->GetImageView()}; @@ -186,7 +188,7 @@ namespace Copium createInfo.height = height; createInfo.layers = 1; - CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize framebuffer"); + CP_VK_ASSERT(vkCreateFramebuffer(vulkan.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize framebuffer"); } } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/buffer/Framebuffer.h b/CopiumEngine/src/copium/buffer/Framebuffer.h index 83fce4a..74a79b3 100644 --- a/CopiumEngine/src/copium/buffer/Framebuffer.h +++ b/CopiumEngine/src/copium/buffer/Framebuffer.h @@ -1,6 +1,7 @@ #pragma once -#include "copium/core/Instance.h" +#include "copium/buffer/CommandBuffer.h" +#include "copium/core/Vulkan.h" #include "copium/sampler/ColorAttachment.h" #include "copium/sampler/DepthAttachment.h" #include "copium/util/Common.h" @@ -13,7 +14,7 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer); private: - Instance& instance; + Vulkan& vulkan; std::unique_ptr colorAttachment; std::unique_ptr depthAttachment; @@ -23,7 +24,7 @@ namespace Copium uint32_t width; uint32_t height; public: - Framebuffer(Instance& instance, uint32_t width, uint32_t height); + Framebuffer(Vulkan& vulkan, uint32_t width, uint32_t height); ~Framebuffer(); void Resize(uint32_t width, uint32_t height); diff --git a/CopiumEngine/src/copium/buffer/IndexBuffer.cpp b/CopiumEngine/src/copium/buffer/IndexBuffer.cpp index 9df91cb..4cf94b1 100644 --- a/CopiumEngine/src/copium/buffer/IndexBuffer.cpp +++ b/CopiumEngine/src/copium/buffer/IndexBuffer.cpp @@ -1,13 +1,11 @@ #include "copium/buffer/IndexBuffer.h" -#include "copium/buffer/CommandBuffer.h" - #include namespace Copium { - IndexBuffer::IndexBuffer(Instance& instance, int indexCount) - : Buffer{instance, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexCount * sizeof(uint16_t), 1}, + IndexBuffer::IndexBuffer(Vulkan& vulkan, int indexCount) + : Buffer{vulkan, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexCount * sizeof(uint16_t), 1}, indexCount{indexCount} {} diff --git a/CopiumEngine/src/copium/buffer/IndexBuffer.h b/CopiumEngine/src/copium/buffer/IndexBuffer.h index d61247d..e157d05 100644 --- a/CopiumEngine/src/copium/buffer/IndexBuffer.h +++ b/CopiumEngine/src/copium/buffer/IndexBuffer.h @@ -1,7 +1,8 @@ #pragma once #include "copium/buffer/Buffer.h" -#include "copium/core/Instance.h" +#include "copium/buffer/CommandBuffer.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" namespace Copium @@ -12,7 +13,7 @@ namespace Copium private: int indexCount; public: - IndexBuffer(Instance& instance, int indexCount); + IndexBuffer(Vulkan& vulkan, int indexCount); void Bind(const CommandBuffer& commandBuffer); void Draw(const CommandBuffer& commandBuffer); diff --git a/CopiumEngine/src/copium/buffer/UniformBuffer.cpp b/CopiumEngine/src/copium/buffer/UniformBuffer.cpp index 9a2af14..a9dbf52 100644 --- a/CopiumEngine/src/copium/buffer/UniformBuffer.cpp +++ b/CopiumEngine/src/copium/buffer/UniformBuffer.cpp @@ -1,9 +1,11 @@ #include "copium/buffer/UniformBuffer.h" +#include "copium/core/SwapChain.h" + namespace Copium { - UniformBuffer::UniformBuffer(Instance& instance, VkDeviceSize size) - : Buffer{instance, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, instance.GetMaxFramesInFlight()} + UniformBuffer::UniformBuffer(Vulkan& vulkan, VkDeviceSize size) + : Buffer{vulkan, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, SwapChain::MAX_FRAMES_IN_FLIGHT} {} VkDescriptorBufferInfo UniformBuffer::GetDescriptorBufferInfo(int index) const diff --git a/CopiumEngine/src/copium/buffer/UniformBuffer.h b/CopiumEngine/src/copium/buffer/UniformBuffer.h index 19353b9..6ab9498 100644 --- a/CopiumEngine/src/copium/buffer/UniformBuffer.h +++ b/CopiumEngine/src/copium/buffer/UniformBuffer.h @@ -1,7 +1,7 @@ #pragma once #include "copium/buffer/Buffer.h" -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" #include @@ -13,18 +13,19 @@ namespace Copium CP_DELETE_COPY_AND_MOVE_CTOR(UniformBuffer); public: - UniformBuffer(Instance& instance, VkDeviceSize size); + UniformBuffer(Vulkan& vulkan, VkDeviceSize size); VkDescriptorBufferInfo GetDescriptorBufferInfo(int index) const; template void Update(const T& t); + }; template void UniformBuffer::Update(const T& t) { CP_ASSERT(sizeof(T) == Buffer::GetSize(), "Update : Template size is not the same as buffer size %u != %u", sizeof(T), Buffer::GetSize()); - Buffer::Update((void*)&t, instance.GetFlightIndex()); + Buffer::Update((void*)&t, vulkan.GetSwapChain().GetFlightIndex()); } } diff --git a/CopiumEngine/src/copium/buffer/VertexBuffer.cpp b/CopiumEngine/src/copium/buffer/VertexBuffer.cpp index af9c4f7..52d01b4 100644 --- a/CopiumEngine/src/copium/buffer/VertexBuffer.cpp +++ b/CopiumEngine/src/copium/buffer/VertexBuffer.cpp @@ -2,8 +2,8 @@ namespace Copium { - VertexBuffer::VertexBuffer(Instance& instance, const VertexDescriptor& descriptor, int vertexCount) - : Buffer{instance, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, descriptor.GetVertexSize() * vertexCount, 1} + VertexBuffer::VertexBuffer(Vulkan& vulkan, const VertexDescriptor& descriptor, int vertexCount) + : Buffer{vulkan, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, descriptor.GetVertexSize() * vertexCount, 1} { VkDeviceSize offset = 0; for (auto&& binding : descriptor.GetBindings()) diff --git a/CopiumEngine/src/copium/buffer/VertexBuffer.h b/CopiumEngine/src/copium/buffer/VertexBuffer.h index 9818a6d..27a041b 100644 --- a/CopiumEngine/src/copium/buffer/VertexBuffer.h +++ b/CopiumEngine/src/copium/buffer/VertexBuffer.h @@ -2,7 +2,7 @@ #include "copium/buffer/Buffer.h" #include "copium/buffer/CommandBuffer.h" -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/pipeline/VertexDescriptor.h" #include "copium/util/Common.h" @@ -18,7 +18,7 @@ namespace Copium std::vector bindingOffsets; std::vector bindingSizes; public: - VertexBuffer(Instance& instance, const VertexDescriptor& descriptor, int vertexCount); + VertexBuffer(Vulkan& vulkan, const VertexDescriptor& descriptor, int vertexCount); void Bind(const CommandBuffer& commandBuffer); void UpdateStaging(uint32_t binding, void* data); diff --git a/CopiumEngine/src/copium/core/Application.cpp b/CopiumEngine/src/copium/core/Application.cpp index aed14f9..fa04805 100644 --- a/CopiumEngine/src/copium/core/Application.cpp +++ b/CopiumEngine/src/copium/core/Application.cpp @@ -2,6 +2,10 @@ #include "copium/mesh/Vertex.h" #include "copium/mesh/VertexPassthrough.h" +#include "copium/core/Device.h" +#include "copium/core/Instance.h" +#include "copium/core/SwapChain.h" +#include "copium/core/Window.h" #include @@ -44,7 +48,7 @@ namespace Copium Application::Application() { - InitializeInstance(); + InitializeVulkan(); InitializeFrameBuffer(); InitializeGraphicsPipeline(); InitializeTextureSampler(); @@ -56,56 +60,61 @@ namespace Copium Application::~Application() { - vkDeviceWaitIdle(instance->GetDevice()); + vkDeviceWaitIdle(vulkan->GetDevice()); } bool Application::Update() { - if (framebuffer->GetWidth() != instance->GetSwapChain().GetExtent().width || framebuffer->GetHeight() != instance->GetSwapChain().GetExtent().height) + if (framebuffer->GetWidth() != vulkan->GetSwapChain().GetExtent().width || framebuffer->GetHeight() != vulkan->GetSwapChain().GetExtent().height) { - framebuffer->Resize(instance->GetSwapChain().GetExtent().width / 8, instance->GetSwapChain().GetExtent().height / 8); + framebuffer->Resize(vulkan->GetSwapChain().GetExtent().width / 8, vulkan->GetSwapChain().GetExtent().height / 8); descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0); } - if (!instance->BeginPresent()) - { + + if (!vulkan->GetSwapChain().BeginPresent()) return true; - } RecordCommandBuffer(); - commandBuffer->SubmitAsGraphicsQueue(); + vulkan->GetSwapChain().SubmitToGraphicsQueue(*commandBuffer); - return instance->EndPresent(); + vulkan->GetSwapChain().EndPresent(); + return !glfwWindowShouldClose(vulkan->GetWindow().GetWindow()); } - void Application::InitializeInstance() + void Application::InitializeVulkan() { - instance = std::make_unique("Copium Engine"); + vulkan = std::make_unique(); + vulkan->SetInstance(std::make_unique("Copium Engine")); + vulkan->SetWindow(std::make_unique(*vulkan, "Copium Engine", 1920, 1080, Window::Mode::Windowed)); + vulkan->SetDevice(std::make_unique(*vulkan)); + vulkan->SetSwapChain(std::make_unique(*vulkan)); + CP_ASSERT(vulkan->Valid(), "Vulkan Manager was not initialized correctly"); } void Application::InitializeFrameBuffer() { - framebuffer = std::make_unique(*instance, instance->GetSwapChain().GetExtent().width, instance->GetSwapChain().GetExtent().height); + framebuffer = std::make_unique(*vulkan, vulkan->GetSwapChain().GetExtent().width, vulkan->GetSwapChain().GetExtent().height); } void Application::InitializeTextureSampler() { - texture2D = std::make_unique(*instance, "res/textures/texture.png"); + texture2D = std::make_unique(*vulkan, "res/textures/texture.png"); } void Application::InitializeUniformBuffer() { - shaderUniformBuffer = std::make_unique(*instance, sizeof(ShaderUniform)); + shaderUniformBuffer = std::make_unique(*vulkan, sizeof(ShaderUniform)); } void Application::InitializeDescriptorSets() { - descriptorPool = std::make_unique(*instance); + descriptorPool = std::make_unique(*vulkan); - descriptorSet = std::make_unique(*instance, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0)); + descriptorSet = std::make_unique(*vulkan, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0)); descriptorSet->AddUniform(*shaderUniformBuffer, 0); descriptorSet->AddSampler(*texture2D, 1); - descriptorSetPassthrough = std::make_unique(*instance, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0)); + descriptorSetPassthrough = std::make_unique(*vulkan, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0)); descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0); } @@ -116,24 +125,24 @@ namespace Copium creator.AddDescriptorSetLayoutBinding(0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT); creator.SetVertexDescriptor(Vertex::GetDescriptor()); creator.SetCullMode(VK_CULL_MODE_NONE); - graphicsPipeline = std::make_unique(*instance, creator); + graphicsPipeline = std::make_unique(*vulkan, creator); - PipelineCreator creatorPassthrough{instance->GetSwapChain().GetRenderPass(), "res/shaders/passthrough.vert", "res/shaders/passthrough.frag"}; + PipelineCreator creatorPassthrough{vulkan->GetSwapChain().GetRenderPass(), "res/shaders/passthrough.vert", "res/shaders/passthrough.frag"}; creatorPassthrough.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT); creatorPassthrough.SetVertexDescriptor(VertexPassthrough::GetDescriptor()); creatorPassthrough.SetCullMode(VK_CULL_MODE_NONE); - graphicsPipelinePassthrough = std::make_unique(*instance, creatorPassthrough); + graphicsPipelinePassthrough = std::make_unique(*vulkan, creatorPassthrough); } void Application::InitializeMesh() { - mesh = std::make_unique(*instance, vertices, indices); - meshPassthrough = std::make_unique(*instance, verticesPassthrough, indicesPassthrough); + mesh = std::make_unique(*vulkan, vertices, indices); + meshPassthrough = std::make_unique(*vulkan, verticesPassthrough, indicesPassthrough); } void Application::InitializeCommandBuffer() { - commandBuffer = std::make_unique(*instance, CommandBuffer::Type::Dynamic); + commandBuffer = std::make_unique(*vulkan, CommandBuffer::Type::Dynamic); } void Application::RecordCommandBuffer() @@ -153,7 +162,7 @@ namespace Copium framebuffer->Unbind(*commandBuffer); - instance->GetSwapChain().BeginFrameBuffer(*commandBuffer); + vulkan->GetSwapChain().BeginFrameBuffer(*commandBuffer); graphicsPipelinePassthrough->Bind(*commandBuffer); graphicsPipelinePassthrough->SetDescriptorSet(0, *descriptorSetPassthrough); @@ -162,7 +171,7 @@ namespace Copium meshPassthrough->Bind(*commandBuffer); meshPassthrough->Render(*commandBuffer); - instance->GetSwapChain().EndFrameBuffer(*commandBuffer); + vulkan->GetSwapChain().EndFrameBuffer(*commandBuffer); commandBuffer->End(); } diff --git a/CopiumEngine/src/copium/core/Application.h b/CopiumEngine/src/copium/core/Application.h index 08f154e..0a18aa1 100644 --- a/CopiumEngine/src/copium/core/Application.h +++ b/CopiumEngine/src/copium/core/Application.h @@ -4,7 +4,9 @@ #include "copium/buffer/IndexBuffer.h" #include "copium/buffer/UniformBuffer.h" #include "copium/buffer/VertexBuffer.h" +#include "copium/core/Device.h" #include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/mesh/Mesh.h" #include "copium/pipeline/DescriptorPool.h" #include "copium/pipeline/DescriptorSet.h" @@ -17,6 +19,7 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(Application); private: + std::unique_ptr vulkan; std::unique_ptr instance; std::unique_ptr framebuffer; std::unique_ptr texture2D; @@ -30,14 +33,13 @@ namespace Copium std::unique_ptr meshPassthrough; std::unique_ptr commandBuffer; - public: Application(); ~Application(); bool Update(); private: - void InitializeInstance(); + void InitializeVulkan(); void InitializeFrameBuffer(); void InitializeTextureSampler(); void InitializeUniformBuffer(); diff --git a/CopiumEngine/src/copium/core/Device.cpp b/CopiumEngine/src/copium/core/Device.cpp new file mode 100644 index 0000000..584d036 --- /dev/null +++ b/CopiumEngine/src/copium/core/Device.cpp @@ -0,0 +1,189 @@ +#include "Device.h" + +#include "copium/core/Instance.h" +#include "copium/core/SwapChain.h" +#include "copium/core/Window.h" + +namespace Copium +{ + Device::Device(Vulkan& vulkan) + : vulkan{vulkan} + { + SelectPhysicalDevice(); + InitializeLogicalDevice(); + InitializeCommandPool(); + } + Device::~Device() + { + vkDestroyCommandPool(device, commandPool, nullptr); + + vkDestroyDevice(device, nullptr); + } + + VkQueue Device::GetGraphicsQueue() const + { + return graphicsQueue; + } + + VkQueue Device::GetPresentQueue() const + { + return presentQueue; + } + + VkCommandPool Device::GetCommandPool() const + { + return commandPool; + } + + VkPhysicalDevice Device::GetPhysicalDevice() const + { + return physicalDevice; + } + + Device::operator VkDevice() const + { + return device; + } + + uint32_t Device::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) + { + VkPhysicalDeviceMemoryProperties memoryProperties; + vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties); + for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) + { + if ((typeFilter & (1 << i)) && (memoryProperties.memoryTypes[i].propertyFlags & properties) == properties) + return i; + } + CP_ABORT("FindMemoryType : Failed to find suitable memory type"); + } + + void Device::SelectPhysicalDevice() + { + uint32_t deviceCount; + vkEnumeratePhysicalDevices(vulkan.GetInstance(), &deviceCount, nullptr); + CP_ASSERT(deviceCount != 0, "SelectPhysicaDevice : No available devices support Vulkan"); + + std::vector devices(deviceCount); + vkEnumeratePhysicalDevices(vulkan.GetInstance(), &deviceCount, devices.data()); + CP_INFO("SelectPhysicaDevice : Available devices:"); + for (auto&& device : devices) + { + VkPhysicalDeviceProperties deviceProperties; + vkGetPhysicalDeviceProperties(device, &deviceProperties); + CP_INFO_CONT("\t%s", deviceProperties.deviceName); + } + for (auto&& device : devices) + { + if (IsPhysicalDeviceSuitable(device)) + { + VkPhysicalDeviceProperties deviceProperties; + vkGetPhysicalDeviceProperties(device, &deviceProperties); + physicalDevice = device; + CP_INFO("SelectPhysicaDevice : Selecting device: %s", deviceProperties.deviceName); + break; + } + } + CP_ASSERT(physicalDevice != VK_NULL_HANDLE, "SelectPhysicaDevice : Failed to find suitable GPU"); + } + + void Device::InitializeLogicalDevice() + { + QueueFamiliesQuery query{vulkan.GetWindow().GetSurface(), physicalDevice}; + + float queuePriority = 1.0f; + + std::vector queueCreateInfos{}; + std::set uniqueQueueFamilies{query.graphicsFamily.value(), query.presentFamily.value()}; + for (auto&& queueFamily : uniqueQueueFamilies) + { + VkDeviceQueueCreateInfo queueCreateInfo{}; + queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfo.queueFamilyIndex = queueFamily; + queueCreateInfo.queueCount = 1; + queueCreateInfo.pQueuePriorities = &queuePriority; + queueCreateInfos.emplace_back(queueCreateInfo); + } + std::vector deviceExtensions = GetRequiredDeviceExtensions(); + VkPhysicalDeviceFeatures deviceFeatures{}; + deviceFeatures.fillModeNonSolid = VK_TRUE; + deviceFeatures.samplerAnisotropy = VK_TRUE; + VkDeviceCreateInfo createInfo{}; + createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + createInfo.pQueueCreateInfos = queueCreateInfos.data(); + createInfo.queueCreateInfoCount = queueCreateInfos.size(); + createInfo.pEnabledFeatures = &deviceFeatures; + createInfo.ppEnabledExtensionNames = deviceExtensions.data(); + createInfo.enabledExtensionCount = deviceExtensions.size(); + + CP_VK_ASSERT(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device), "InitializeLogicalDevice : Failed to initialize logical device"); + + graphicsQueueIndex = query.graphicsFamily.value(); + presentQueueIndex = query.presentFamily.value(); + vkGetDeviceQueue(device, graphicsQueueIndex, 0, &graphicsQueue); + vkGetDeviceQueue(device, presentQueueIndex, 0, &presentQueue); + } + + void Device::InitializeCommandPool() + { + VkCommandPoolCreateInfo createInfo{}; + createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + createInfo.queueFamilyIndex = graphicsQueueIndex; + CP_VK_ASSERT(vkCreateCommandPool(device, &createInfo, nullptr, &commandPool), "InitializeCommandPool : Failed to initialize command pool"); + } + + bool Device::IsPhysicalDeviceSuitable(VkPhysicalDevice device) + { + VkPhysicalDeviceProperties deviceProperties; + vkGetPhysicalDeviceProperties(device, &deviceProperties); + if (deviceProperties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + return false; + + VkPhysicalDeviceFeatures deviceFeatures; + vkGetPhysicalDeviceFeatures(device, &deviceFeatures); + if (!deviceFeatures.fillModeNonSolid || !deviceFeatures.samplerAnisotropy) + return false; + + QueueFamiliesQuery query{vulkan.GetWindow().GetSurface(), device}; + if (!query.AllRequiredFamiliesSupported()) + return false; + + if (!CheckDeviceExtensionSupport(device)) + return false; + + SwapChainSupportDetails details{vulkan.GetWindow().GetSurface(), device}; + if (!details.Valid()) + return false; + + return true; + } + + bool Device::CheckDeviceExtensionSupport(VkPhysicalDevice device) + { + uint32_t extensionCount; + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); + std::vector extensions{extensionCount}; + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, extensions.data()); + + for (auto&& requiredExtension : GetRequiredDeviceExtensions()) + { + bool found = false; + for (auto&& extension : extensions) + { + if (std::strcmp(requiredExtension, extension.extensionName) == 0) + { + found = true; + break; + } + } + if (!found) + return false; + } + return true; + } + + std::vector Device::GetRequiredDeviceExtensions() + { + return {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; + } +} diff --git a/CopiumEngine/src/copium/core/Device.h b/CopiumEngine/src/copium/core/Device.h new file mode 100644 index 0000000..0920c2b --- /dev/null +++ b/CopiumEngine/src/copium/core/Device.h @@ -0,0 +1,48 @@ +#pragma once + +#include "copium/core/QueueFamilies.h" +#include "copium/core/Vulkan.h" +#include "copium/util/Common.h" + +#include + +namespace Copium +{ + class Vulkan; + class Device + { + CP_DELETE_COPY_AND_MOVE_CTOR(Device); + private: + Vulkan& vulkan; + + VkPhysicalDevice physicalDevice; + VkDevice device; + VkCommandPool commandPool; + + // TODO: Move to SwapChain? + uint32_t graphicsQueueIndex; + uint32_t presentQueueIndex; + VkQueue graphicsQueue; + VkQueue presentQueue; + // TODO end + + public: + Device(Vulkan& vulkan); + ~Device(); + + VkQueue GetGraphicsQueue() const; + VkQueue GetPresentQueue() const; + VkCommandPool GetCommandPool() const; + VkPhysicalDevice GetPhysicalDevice() const; + operator VkDevice() const; + uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); + + private: + void SelectPhysicalDevice(); + void InitializeLogicalDevice(); + void InitializeCommandPool(); + bool IsPhysicalDeviceSuitable(VkPhysicalDevice device); + bool CheckDeviceExtensionSupport(VkPhysicalDevice device); + std::vector GetRequiredDeviceExtensions(); + }; +} \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Instance.cpp b/CopiumEngine/src/copium/core/Instance.cpp index aaa0e91..76768d5 100644 --- a/CopiumEngine/src/copium/core/Instance.cpp +++ b/CopiumEngine/src/copium/core/Instance.cpp @@ -1,6 +1,7 @@ #include "Instance.h" #include "copium/core/QueueFamilies.h" +#include "copium/core/SwapChain.h" #include "copium/util/Common.h" namespace Copium @@ -8,126 +9,15 @@ namespace Copium Instance::Instance(const std::string& applicationName) { timer.Start(); - InitializeWindow(applicationName); InitializeInstance(applicationName); InitializeDebugMessenger(); - InitializeSurface(); - SelectPhysicalDevice(); - InitializeLogicalDevice(); - InitializeCommandPool(); - InitializeSwapChain(); - InitializeSyncObjects(); CP_INFO("Instance : Initialized Vulkan in %f seconds", timer.Elapsed()); } Instance::~Instance() { - for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) - { - vkDestroyFence(device, inFlightFences[i], nullptr); - vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr); - vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr); - } - vkDestroyCommandPool(device, commandPool, nullptr); - swapChain.reset(); - vkDestroyDevice(device, nullptr); - vkDestroySurfaceKHR(instance, surface, nullptr); debugMessenger.reset(); vkDestroyInstance(instance, nullptr); - glfwDestroyWindow(window); - } - - bool Instance::BeginPresent() - { - vkWaitForFences(device, 1, &inFlightFences[flightIndex], VK_TRUE, UINT64_MAX); - - if (!swapChain->BeginPresent(imageAvailableSemaphores[flightIndex])) - return false; - - vkResetFences(device, 1, &inFlightFences[flightIndex]); - return true; - } - - bool Instance::EndPresent() - { - swapChain->EndPresent(presentQueue, &renderFinishedSemaphores[flightIndex], framebufferResized); - - framebufferResized = false; - flightIndex = (flightIndex + 1) % MAX_FRAMES_IN_FLIGHT; - return !glfwWindowShouldClose(window); - } - - void Instance::SubmitGraphicsQueue(const std::vector& commandBuffers) - { - VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; - VkSubmitInfo submitInfo{}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = &imageAvailableSemaphores[flightIndex]; - submitInfo.pWaitDstStageMask = waitStages; - submitInfo.commandBufferCount = commandBuffers.size(); - submitInfo.pCommandBuffers = commandBuffers.data(); - submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &renderFinishedSemaphores[flightIndex]; - - CP_VK_ASSERT(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[flightIndex]), "SubmitGraphicsQueue : Failed to submit command buffer"); - } - - GLFWwindow* Instance::GetWindow() const - { - return window; - } - - VkSurfaceKHR Instance::GetSurface() const - { - return surface; - } - - VkPhysicalDevice Instance::GetPhysicalDevice() const - { - return physicalDevice; - } - - VkDevice Instance::GetDevice() const - { - return device; - } - - VkCommandPool Instance::GetCommandPool() const - { - return commandPool; - } - - VkQueue Instance::GetGraphicsQueue() const - { - return graphicsQueue; - } - - int Instance::GetFlightIndex() const - { - return flightIndex; - } - - int Instance::GetMaxFramesInFlight() const - { - return MAX_FRAMES_IN_FLIGHT; - } - - const SwapChain& Instance::GetSwapChain() const - { - return *swapChain; - } - - uint32_t Instance::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) - { - VkPhysicalDeviceMemoryProperties memoryProperties; - vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties); - for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) - { - if ((typeFilter & (1 << i)) && (memoryProperties.memoryTypes[i].propertyFlags & properties) == properties) - return i; - } - CP_ABORT("FindMemoryType : Failed to find suitable memory type"); } Instance::operator VkInstance() const @@ -135,29 +25,6 @@ namespace Copium return instance; } - void Instance::InitializeWindow(const std::string& applicationName) - { - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - - -#if defined(FULLSCREEN) - GLFWmonitor* monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - window = glfwCreateWindow(mode->width, mode->height, applicationName.c_str(), glfwGetPrimaryMonitor(), nullptr); -#elif defined(BORDERLESS_WINDOWED) - GLFWmonitor* monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - window = glfwCreateWindow(mode->width, mode->height, applicationName.c_str(), nullptr, nullptr); - glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); -#else - window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, applicationName.c_str(), nullptr, nullptr); -#endif - CP_ASSERT(window, "InitializeWindow : Failed to initialize glfw window"); - - glfwSetWindowUserPointer(window, this); - glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback); - } - void Instance::InitializeInstance(const std::string& applicationName) { VkApplicationInfo appInfo{}; @@ -200,111 +67,6 @@ namespace Copium debugMessenger = std::make_unique(*this); } - void Instance::InitializeSurface() - { - CP_VK_ASSERT(glfwCreateWindowSurface(instance, window, nullptr, &surface), "InitializeSurface : Failed to create Vulkan surface"); - } - - void Instance::SelectPhysicalDevice() - { - uint32_t deviceCount; - vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); - CP_ASSERT(deviceCount != 0, "SelectPhysicaDevice : No available devices support Vulkan"); - - std::vector devices(deviceCount); - vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); - CP_INFO("SelectPhysicaDevice : Available devices:"); - for (auto&& device : devices) - { - VkPhysicalDeviceProperties deviceProperties; - vkGetPhysicalDeviceProperties(device, &deviceProperties); - CP_INFO_CONT("\t%s", deviceProperties.deviceName); - } - for (auto&& device : devices) - { - if (IsPhysicalDeviceSuitable(device)) - { - VkPhysicalDeviceProperties deviceProperties; - vkGetPhysicalDeviceProperties(device, &deviceProperties); - physicalDevice = device; - CP_INFO("SelectPhysicaDevice : Selecting device: %s", deviceProperties.deviceName); - break; - } - } - CP_ASSERT(physicalDevice != VK_NULL_HANDLE, "SelectPhysicaDevice : Failed to find suitable GPU"); - } - - void Instance::InitializeLogicalDevice() - { - QueueFamiliesQuery query{surface, physicalDevice}; - - float queuePriority = 1.0f; - - std::vector queueCreateInfos{}; - std::set uniqueQueueFamilies{query.graphicsFamily.value(), query.presentFamily.value()}; - for (auto&& queueFamily : uniqueQueueFamilies) - { - VkDeviceQueueCreateInfo queueCreateInfo{}; - queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfo.queueFamilyIndex = queueFamily; - queueCreateInfo.queueCount = 1; - queueCreateInfo.pQueuePriorities = &queuePriority; - queueCreateInfos.emplace_back(queueCreateInfo); - } - std::vector deviceExtensions = GetRequiredDeviceExtensions(); - VkPhysicalDeviceFeatures deviceFeatures{}; - deviceFeatures.fillModeNonSolid = VK_TRUE; - deviceFeatures.samplerAnisotropy = VK_TRUE; - VkDeviceCreateInfo createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - createInfo.pQueueCreateInfos = queueCreateInfos.data(); - createInfo.queueCreateInfoCount = queueCreateInfos.size(); - createInfo.pEnabledFeatures = &deviceFeatures; - createInfo.ppEnabledExtensionNames = deviceExtensions.data(); - createInfo.enabledExtensionCount = deviceExtensions.size(); - - CP_VK_ASSERT(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device), "InitializeLogicalDevice : Failed to initialize logical device"); - - graphicsQueueIndex = query.graphicsFamily.value(); - presentQueueIndex = query.presentFamily.value(); - vkGetDeviceQueue(device, graphicsQueueIndex, 0, &graphicsQueue); - vkGetDeviceQueue(device, presentQueueIndex, 0, &presentQueue); - } - - void Instance::InitializeSwapChain() - { - swapChain = std::make_unique(*this); - } - - void Instance::InitializeCommandPool() - { - VkCommandPoolCreateInfo createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - createInfo.queueFamilyIndex = graphicsQueueIndex; - CP_VK_ASSERT(vkCreateCommandPool(device, &createInfo, nullptr, &commandPool), "InitializeCommandPool : Failed to initialize command pool"); - } - - void Instance::InitializeSyncObjects() - { - imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT); - renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT); - inFlightFences.resize(MAX_FRAMES_IN_FLIGHT); - VkSemaphoreCreateInfo semaphoreCreateInfo{}; - semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) - { - CP_VK_ASSERT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &imageAvailableSemaphores[i]), "InitializeSyncObjects : Failed to initialize available image semaphore"); - CP_VK_ASSERT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]), "InitializeSyncObjects : Failed to initialize render finished semaphore"); - - VkFenceCreateInfo fenceCreateInfo{}; - fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - - CP_VK_ASSERT(vkCreateFence(device, &fenceCreateInfo, nullptr, &inFlightFences[i]), "InitializeSyncObjects : Failed to initialize in flight fence"); - } - } - std::vector Instance::GetRequiredExtensions() { uint32_t glfwExtensionCount; @@ -349,63 +111,11 @@ namespace Copium return true; } - bool Instance::IsPhysicalDeviceSuitable(VkPhysicalDevice device) - { - VkPhysicalDeviceProperties deviceProperties; - vkGetPhysicalDeviceProperties(device, &deviceProperties); - if (deviceProperties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) - return false; - - VkPhysicalDeviceFeatures deviceFeatures; - vkGetPhysicalDeviceFeatures(device, &deviceFeatures); - if (!deviceFeatures.fillModeNonSolid || !deviceFeatures.samplerAnisotropy) - return false; - - QueueFamiliesQuery query{surface, device}; - if (!query.AllRequiredFamiliesSupported()) - return false; - - if (!CheckDeviceExtensionSupport(device)) - return false; - SwapChainSupportDetails details{surface, device}; - if (!details.Valid()) - return false; - - return true; - } - - bool Instance::CheckDeviceExtensionSupport(VkPhysicalDevice device) - { - uint32_t extensionCount; - vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); - std::vector extensions{extensionCount}; - vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, extensions.data()); - - for (auto&& requiredExtension : GetRequiredDeviceExtensions()) - { - bool found = false; - for (auto&& extension : extensions) - { - if (std::strcmp(requiredExtension, extension.extensionName) == 0) - { - found = true; - break; - } - } - if (!found) - return false; - } - return true; - } - - std::vector Instance::GetRequiredDeviceExtensions() - { - return {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; - } - void Instance::FramebufferResizeCallback(GLFWwindow* window, int width, int height) { Instance* instance = static_cast(glfwGetWindowUserPointer(window)); - instance->framebufferResized = true; + // TODO: Fix swap chain resizing again + // instance->swapChain->ResizeFramebuffer(); // TODO: Should maybe be handled by an event system? + CP_UNIMPLEMENTED("Framebuffer resizing currently not supported"); } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Instance.h b/CopiumEngine/src/copium/core/Instance.h index 70e4a66..66e10eb 100644 --- a/CopiumEngine/src/copium/core/Instance.h +++ b/CopiumEngine/src/copium/core/Instance.h @@ -1,7 +1,6 @@ #pragma once #include "copium/core/DebugMessenger.h" -#include "copium/core/SwapChain.h" #include "copium/util/Timer.h" #include @@ -14,67 +13,29 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(Instance); private: - static const int MAX_FRAMES_IN_FLIGHT = 2; - static const int WINDOW_WIDTH = 1920; - static const int WINDOW_HEIGHT = 1080; - VkInstance instance; - GLFWwindow* window; - VkSurfaceKHR surface; std::unique_ptr debugMessenger; - VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; - VkDevice device; + + // TODO: Move to SwapChain? uint32_t graphicsQueueIndex; uint32_t presentQueueIndex; VkQueue graphicsQueue; VkQueue presentQueue; - std::unique_ptr swapChain; - int flightIndex; - std::vector imageAvailableSemaphores; - std::vector renderFinishedSemaphores; - std::vector inFlightFences; - VkCommandPool commandPool; - bool framebufferResized = false; + // TODO end - int frameCount = 0; Timer timer; public: Instance(const std::string& applicationName); ~Instance(); - bool BeginPresent(); - bool EndPresent(); - void SubmitGraphicsQueue(const std::vector& commandBuffers); - GLFWwindow* GetWindow() const; - VkSurfaceKHR GetSurface() const; - VkPhysicalDevice GetPhysicalDevice() const; - VkDevice GetDevice() const; - VkCommandPool GetCommandPool() const; - VkQueue GetGraphicsQueue() const; - int GetFlightIndex() const; - int GetMaxFramesInFlight() const; - const SwapChain& GetSwapChain() const; - // TODO: Create Device class and move this there - uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); operator VkInstance() const; private: - void InitializeWindow(const std::string& applicationName); void InitializeInstance(const std::string& applicationName); void InitializeDebugMessenger(); - void InitializeSurface(); - void SelectPhysicalDevice(); - void InitializeLogicalDevice(); - void InitializeSwapChain(); - void InitializeCommandPool(); - void InitializeSyncObjects(); std::vector GetRequiredExtensions(); bool CheckLayerSupport(const std::vector& layers); - bool IsPhysicalDeviceSuitable(VkPhysicalDevice device); - bool CheckDeviceExtensionSupport(VkPhysicalDevice device); - std::vector GetRequiredDeviceExtensions(); static void FramebufferResizeCallback(GLFWwindow* window, int width, int height); - }; } diff --git a/CopiumEngine/src/copium/core/SwapChain.cpp b/CopiumEngine/src/copium/core/SwapChain.cpp index 33fd91b..8590af9 100644 --- a/CopiumEngine/src/copium/core/SwapChain.cpp +++ b/CopiumEngine/src/copium/core/SwapChain.cpp @@ -1,15 +1,11 @@ #include "copium/core/SwapChain.h" -#include "copium/buffer/CommandBuffer.h" +#include "copium/core/Device.h" #include "copium/core/Instance.h" #include "copium/core/QueueFamilies.h" -#include "copium/sampler/DepthAttachment.h" +#include "copium/core/Window.h" #include "copium/sampler/Image.h" -#include -#include -#include - namespace Copium { SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice) @@ -38,20 +34,27 @@ namespace Copium return !formats.empty() && !presentModes.empty(); } - SwapChain::SwapChain(Instance& instance) - : instance{instance} + SwapChain::SwapChain(Vulkan& vulkan) + : vulkan{vulkan} { Initialize(); InitializeImageViews(); InitializeDepthAttachment(); InitializeRenderPass(); InitializeFramebuffers(); + InitializeSyncObjects(); } SwapChain::~SwapChain() { + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) + { + vkDestroyFence(vulkan.GetDevice(), inFlightFences[i], nullptr); + vkDestroySemaphore(vulkan.GetDevice(), renderFinishedSemaphores[i], nullptr); + vkDestroySemaphore(vulkan.GetDevice(), imageAvailableSemaphores[i], nullptr); + } Destroy(); - vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr); + vkDestroyRenderPass(vulkan.GetDevice(), renderPass, nullptr); } void SwapChain::BeginFrameBuffer(const CommandBuffer& commandBuffer) const @@ -109,47 +112,75 @@ namespace Copium return framebuffers[imageIndex]; } - bool SwapChain::BeginPresent(VkSemaphore signalSemaphore) + bool SwapChain::BeginPresent() { - VkResult result = vkAcquireNextImageKHR(instance.GetDevice(), handle, UINT64_MAX, signalSemaphore, VK_NULL_HANDLE, &imageIndex); + vkWaitForFences(vulkan.GetDevice(), 1, &inFlightFences[flightIndex], VK_TRUE, UINT64_MAX); + + VkResult result = vkAcquireNextImageKHR(vulkan.GetDevice(), handle, UINT64_MAX, imageAvailableSemaphores[flightIndex], VK_NULL_HANDLE, &imageIndex); if (result == VK_ERROR_OUT_OF_DATE_KHR) { Recreate(); return false; } + vkResetFences(vulkan.GetDevice(), 1, &inFlightFences[flightIndex]); return true; } - void SwapChain::EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, bool framebufferResized) + void SwapChain::SubmitToGraphicsQueue(const CommandBuffer& commandBuffer) + { + VkCommandBuffer cmd = commandBuffer; + VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.waitSemaphoreCount = 1; + submitInfo.pWaitSemaphores = &imageAvailableSemaphores[flightIndex]; + submitInfo.pWaitDstStageMask = waitStages; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &cmd; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = &renderFinishedSemaphores[flightIndex]; + + CP_VK_ASSERT(vkQueueSubmit(vulkan.GetDevice().GetGraphicsQueue(), 1, &submitInfo, inFlightFences[flightIndex]), "SubmitGraphicsQueue : Failed to submit command buffer"); + } + + void SwapChain::EndPresent() { VkPresentInfoKHR presentInfo{}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = waitSemaphore; + presentInfo.pWaitSemaphores = &renderFinishedSemaphores[flightIndex]; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = &handle; presentInfo.pImageIndices = &imageIndex; presentInfo.pResults = nullptr; - VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo); - if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) + VkResult result = vkQueuePresentKHR(vulkan.GetDevice().GetPresentQueue(), &presentInfo); + if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || resizeFramebuffer) { Recreate(); + resizeFramebuffer = false; } + + flightIndex = (flightIndex + 1) % MAX_FRAMES_IN_FLIGHT; + } + + void SwapChain::ResizeFramebuffer() + { + resizeFramebuffer = true; } void SwapChain::Recreate() { int width = 0; int height = 0; - glfwGetFramebufferSize(instance.GetWindow(), &width, &height); + glfwGetFramebufferSize(vulkan.GetWindow().GetWindow(), &width, &height); while (width == 0 || height == 0) { - glfwGetFramebufferSize(instance.GetWindow(), &width, &height); + glfwGetFramebufferSize(vulkan.GetWindow().GetWindow(), &width, &height); glfwWaitEvents(); } - vkDeviceWaitIdle(instance.GetDevice()); + vkDeviceWaitIdle(vulkan.GetDevice()); Destroy(); @@ -159,13 +190,18 @@ namespace Copium InitializeFramebuffers(); } + int SwapChain::GetFlightIndex() const + { + return flightIndex; + } + void SwapChain::Initialize() { - SwapChainSupportDetails swapChainSupport{instance.GetSurface(), instance.GetPhysicalDevice()}; + SwapChainSupportDetails swapChainSupport{vulkan.GetWindow().GetSurface(), vulkan.GetDevice().GetPhysicalDevice()}; VkSurfaceFormatKHR format = SelectSwapSurfaceFormat(swapChainSupport.formats); VkPresentModeKHR presentMode = SelectSwapPresentMode(swapChainSupport.presentModes); - extent = SelectSwapExtent(instance.GetWindow(), swapChainSupport.capabilities); + extent = SelectSwapExtent(vulkan.GetWindow().GetWindow(), swapChainSupport.capabilities); imageFormat = format.format; uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; if (swapChainSupport.capabilities.maxImageCount != 0) @@ -173,12 +209,12 @@ namespace Copium imageCount = std::min(imageCount, swapChainSupport.capabilities.maxImageCount); } - QueueFamiliesQuery queueFamilies{instance.GetSurface(), instance.GetPhysicalDevice()}; + QueueFamiliesQuery queueFamilies{vulkan.GetWindow().GetSurface(), vulkan.GetDevice().GetPhysicalDevice()}; std::vector queueFamilyIndices{queueFamilies.graphicsFamily.value(), queueFamilies.presentFamily.value()}; VkSwapchainCreateInfoKHR createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - createInfo.surface = instance.GetSurface(); + createInfo.surface = vulkan.GetWindow().GetSurface(); createInfo.minImageCount = imageCount; createInfo.imageFormat = format.format; createInfo.imageColorSpace = format.colorSpace; @@ -203,11 +239,11 @@ namespace Copium createInfo.pQueueFamilyIndices = nullptr; } - CP_VK_ASSERT(vkCreateSwapchainKHR(instance.GetDevice(), &createInfo, nullptr, &handle), "Initialize : Failed to initialize the swapchain"); + CP_VK_ASSERT(vkCreateSwapchainKHR(vulkan.GetDevice(), &createInfo, nullptr, &handle), "Initialize : Failed to initialize the swapchain"); - vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, nullptr); + vkGetSwapchainImagesKHR(vulkan.GetDevice(), handle, &imageCount, nullptr); images.resize(imageCount); - vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, images.data()); + vkGetSwapchainImagesKHR(vulkan.GetDevice(), handle, &imageCount, images.data()); } void SwapChain::InitializeImageViews() @@ -215,13 +251,13 @@ namespace Copium imageViews.resize(images.size()); for (size_t i = 0; i < images.size(); i++) { - imageViews[i] = Image::InitializeImageView(instance, images[i], imageFormat, VK_IMAGE_ASPECT_COLOR_BIT); + imageViews[i] = Image::InitializeImageView(vulkan, images[i], imageFormat, VK_IMAGE_ASPECT_COLOR_BIT); } } void SwapChain::InitializeDepthAttachment() { - depthAttachment = std::make_unique(instance, extent.width, extent.height); + depthAttachment = std::make_unique(vulkan, extent.width, extent.height); } void SwapChain::InitializeRenderPass() @@ -237,7 +273,7 @@ namespace Copium colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; VkAttachmentDescription depthAttachment{}; - depthAttachment.format = Image::SelectDepthFormat(instance); + depthAttachment.format = Image::SelectDepthFormat(vulkan); depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -278,7 +314,7 @@ namespace Copium renderPassCreateInfo.dependencyCount = 1; renderPassCreateInfo.pDependencies = &dependency; - CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass"); + CP_VK_ASSERT(vkCreateRenderPass(vulkan.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass"); } void SwapChain::InitializeFramebuffers() @@ -298,7 +334,27 @@ namespace Copium createInfo.height = extent.height; createInfo.layers = 1; - CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize swap chain framebuffer"); + CP_VK_ASSERT(vkCreateFramebuffer(vulkan.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize swap chain framebuffer"); + } + } + + void SwapChain::InitializeSyncObjects() + { + imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT); + renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT); + inFlightFences.resize(MAX_FRAMES_IN_FLIGHT); + VkSemaphoreCreateInfo semaphoreCreateInfo{}; + semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) + { + CP_VK_ASSERT(vkCreateSemaphore(vulkan.GetDevice(), &semaphoreCreateInfo, nullptr, &imageAvailableSemaphores[i]), "InitializeSyncObjects : Failed to initialize available image semaphore"); + CP_VK_ASSERT(vkCreateSemaphore(vulkan.GetDevice(), &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]), "InitializeSyncObjects : Failed to initialize render finished semaphore"); + + VkFenceCreateInfo fenceCreateInfo{}; + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + + CP_VK_ASSERT(vkCreateFence(vulkan.GetDevice(), &fenceCreateInfo, nullptr, &inFlightFences[i]), "InitializeSyncObjects : Failed to initialize in flight fence"); } } @@ -306,13 +362,13 @@ namespace Copium { for (auto&& framebuffer : framebuffers) { - vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr); + vkDestroyFramebuffer(vulkan.GetDevice(), framebuffer, nullptr); } for (auto&& swapChainImageView : imageViews) { - vkDestroyImageView(instance.GetDevice(), swapChainImageView, nullptr); + vkDestroyImageView(vulkan.GetDevice(), swapChainImageView, nullptr); } - vkDestroySwapchainKHR(instance.GetDevice(), handle, nullptr); + vkDestroySwapchainKHR(vulkan.GetDevice(), handle, nullptr); } VkSurfaceFormatKHR SwapChain::SelectSwapSurfaceFormat(const std::vector& availableFormats) diff --git a/CopiumEngine/src/copium/core/SwapChain.h b/CopiumEngine/src/copium/core/SwapChain.h index 228c437..6c02c09 100644 --- a/CopiumEngine/src/copium/core/SwapChain.h +++ b/CopiumEngine/src/copium/core/SwapChain.h @@ -1,5 +1,8 @@ #pragma once +#include "copium/buffer/CommandBuffer.h" +#include "copium/core/Vulkan.h" +#include "copium/sampler/DepthAttachment.h" #include "copium/util/Common.h" #include @@ -8,10 +11,6 @@ namespace Copium { - class Instance; - class CommandBuffer; - class DepthAttachment; - struct SwapChainSupportDetails { VkSurfaceCapabilitiesKHR capabilities; @@ -25,8 +24,10 @@ namespace Copium class SwapChain final { CP_DELETE_COPY_AND_MOVE_CTOR(SwapChain); + public: + static const int MAX_FRAMES_IN_FLIGHT = 2; private: - Instance& instance; + Vulkan& vulkan; VkSwapchainKHR handle; VkRenderPass renderPass; @@ -37,9 +38,15 @@ namespace Copium std::vector images; std::vector framebuffers; uint32_t imageIndex; + bool resizeFramebuffer; + + int flightIndex; + std::vector imageAvailableSemaphores; + std::vector renderFinishedSemaphores; + std::vector inFlightFences; public: - SwapChain(Instance& instance); + SwapChain(Vulkan& vulkan); ~SwapChain(); void BeginFrameBuffer(const CommandBuffer& commandBuffer) const; @@ -48,10 +55,13 @@ namespace Copium VkRenderPass GetRenderPass() const; VkExtent2D GetExtent() const; VkFramebuffer GetFramebuffer() const; - bool BeginPresent(VkSemaphore signalSemaphore); - void EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, bool framebufferResized); + bool BeginPresent(); + void SubmitToGraphicsQueue(const CommandBuffer& commandBuffer); + void EndPresent(); + void ResizeFramebuffer(); void Recreate(); + int GetFlightIndex() const; private: void Initialize(); @@ -59,6 +69,7 @@ namespace Copium void InitializeDepthAttachment(); void InitializeRenderPass(); void InitializeFramebuffers(); + void InitializeSyncObjects(); void Destroy(); VkSurfaceFormatKHR SelectSwapSurfaceFormat(const std::vector& availableFormats); diff --git a/CopiumEngine/src/copium/core/Vulkan.cpp b/CopiumEngine/src/copium/core/Vulkan.cpp new file mode 100644 index 0000000..552e100 --- /dev/null +++ b/CopiumEngine/src/copium/core/Vulkan.cpp @@ -0,0 +1,54 @@ +#include "copium/core/Vulkan.h" + +#include "copium/core/Device.h" +#include "copium/core/Instance.h" +#include "copium/core/SwapChain.h" +#include "copium/core/Window.h" + +namespace Copium +{ + void Vulkan::SetInstance(std::unique_ptr&& instance) + { + this->instance = std::move(instance); + } + + void Vulkan::SetWindow(std::unique_ptr&& window) + { + this->window = std::move(window); + } + + void Vulkan::SetDevice(std::unique_ptr&& device) + { + this->device = std::move(device); + } + + void Vulkan::SetSwapChain(std::unique_ptr&& swapChain) + { + this->swapChain = std::move(swapChain); + } + + Instance& Vulkan::GetInstance() const + { + return *instance; + } + + Window& Vulkan::GetWindow() const + { + return *window; + } + + Device& Vulkan::GetDevice() const + { + return *device; + } + + SwapChain& Vulkan::GetSwapChain() const + { + return *swapChain; + } + + bool Vulkan::Valid() + { + return instance && window && device && swapChain; + } +} \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Vulkan.h b/CopiumEngine/src/copium/core/Vulkan.h new file mode 100644 index 0000000..6e4aed9 --- /dev/null +++ b/CopiumEngine/src/copium/core/Vulkan.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +namespace Copium +{ + class Instance; + class Window; + class Device; + class SwapChain; + + class Vulkan + { + private: + std::unique_ptr instance; + std::unique_ptr window; + std::unique_ptr device; + std::unique_ptr swapChain; + public: + void SetInstance(std::unique_ptr&& instance); + void SetWindow(std::unique_ptr&& window); + void SetDevice(std::unique_ptr&& device); + void SetSwapChain(std::unique_ptr&& swapChain); + Instance& GetInstance() const; + Window& GetWindow() const; + Device& GetDevice() const; + SwapChain& GetSwapChain() const; + bool Valid(); + + }; +} \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Window.cpp b/CopiumEngine/src/copium/core/Window.cpp new file mode 100644 index 0000000..24c7858 --- /dev/null +++ b/CopiumEngine/src/copium/core/Window.cpp @@ -0,0 +1,78 @@ +#include "copium/core/Window.h" + +#include "copium/core/Instance.h" +#include "copium/core/SwapChain.h" + +namespace Copium +{ + Window::Window(Vulkan& vulkan, const std::string& windowName, int width, int height, Mode mode) + : vulkan{vulkan} + { + InitializeWindow(windowName, width, height, mode); + InitializeSurface(); + } + + Window::~Window() + { + vkDestroySurfaceKHR(vulkan.GetInstance(), surface, nullptr); + glfwDestroyWindow(window); + } + + VkSurfaceKHR Window::GetSurface() const + { + return surface; + } + + GLFWwindow* Window::GetWindow() + { + return window; + } + + void Window::InitializeWindow(const std::string& windowName, int width, int height, Mode mode) + { + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + + switch (mode) + { + case Mode::Fullscreen: + { + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + window = glfwCreateWindow(mode->width, mode->height, windowName.c_str(), glfwGetPrimaryMonitor(), nullptr); + break; + } + case Mode::BorderlessWindowed: + { + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + window = glfwCreateWindow(mode->width, mode->height, windowName.c_str(), nullptr, nullptr); + glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); + break; + } + case Mode::Windowed: + { + window = glfwCreateWindow(width, height, windowName.c_str(), nullptr, nullptr); + break; + } + default: + CP_ABORT("Window : Unreachable switch case"); + } + + CP_ASSERT(window, "InitializeWindow : Failed to initialize glfw window"); + + glfwSetWindowUserPointer(window, this); + glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback); + } + + void Window::InitializeSurface() + { + CP_VK_ASSERT(glfwCreateWindowSurface(vulkan.GetInstance(), window, nullptr, &surface), "InitializeSurface : Failed to create Vulkan surface"); + } + + void Window::FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height) + { + Window* window = static_cast(glfwGetWindowUserPointer(glfwWindow)); + window->vulkan.GetSwapChain().ResizeFramebuffer(); // TODO: Should maybe be handled by an event system? + } + +} \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Window.h b/CopiumEngine/src/copium/core/Window.h new file mode 100644 index 0000000..6e60df9 --- /dev/null +++ b/CopiumEngine/src/copium/core/Window.h @@ -0,0 +1,37 @@ +#pragma once + +#include "copium/core/Vulkan.h" +#include "copium/util/Common.h" + +#include + +namespace Copium +{ + class Window final + { + CP_DELETE_COPY_AND_MOVE_CTOR(Window); + public: + enum class Mode + { + Fullscreen, BorderlessWindowed, Windowed + }; + private: + Vulkan& vulkan; + + GLFWwindow* window; + VkSurfaceKHR surface; + + public: + Window(Vulkan& vulkan, const std::string& windowName, int width, int height, Mode mode); + ~Window(); + + VkSurfaceKHR GetSurface() const; + GLFWwindow* GetWindow(); + + private: + void InitializeWindow(const std::string& windowName, int width, int height, Mode mode); + void InitializeSurface(); + static void FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height); + + }; +} \ No newline at end of file diff --git a/CopiumEngine/src/copium/mesh/Mesh.h b/CopiumEngine/src/copium/mesh/Mesh.h index 7ce99c4..d32788f 100644 --- a/CopiumEngine/src/copium/mesh/Mesh.h +++ b/CopiumEngine/src/copium/mesh/Mesh.h @@ -3,7 +3,7 @@ #include "copium/buffer/IndexBuffer.h" #include "copium/buffer/VertexBuffer.h" #include "copium/buffer/CommandBuffer.h" -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" #include @@ -19,18 +19,18 @@ namespace Copium std::unique_ptr vertexBuffer; public: template - Mesh(Instance& instance, const std::vector& vertices, const std::vector& indices); + Mesh(Vulkan& vulkan, const std::vector& vertices, const std::vector& indices); void Bind(const CommandBuffer& commandBuffer); void Render(const CommandBuffer& commandBuffer); }; template - Mesh::Mesh(Instance& instance, const std::vector& vertices, const std::vector& indices) + Mesh::Mesh(Vulkan& vulkan, const std::vector& vertices, const std::vector& indices) { - indexBuffer = std::make_unique(instance, indices.size()); + indexBuffer = std::make_unique(vulkan, indices.size()); indexBuffer->UpdateStaging((void*)indices.data()); - vertexBuffer = std::make_unique(instance, T::GetDescriptor(), vertices.size()); + vertexBuffer = std::make_unique(vulkan, T::GetDescriptor(), vertices.size()); vertexBuffer ->UpdateStaging(0, (void*)vertices.data()); } } diff --git a/CopiumEngine/src/copium/pipeline/DescriptorPool.cpp b/CopiumEngine/src/copium/pipeline/DescriptorPool.cpp index 133fd24..d5cb0ec 100644 --- a/CopiumEngine/src/copium/pipeline/DescriptorPool.cpp +++ b/CopiumEngine/src/copium/pipeline/DescriptorPool.cpp @@ -1,50 +1,52 @@ #include "copium/pipeline/DescriptorPool.h" +#include "copium/core/Device.h" +#include "copium/core/SwapChain.h" + namespace Copium { - DescriptorPool::DescriptorPool(Instance& instance) - : instance{instance} + DescriptorPool::DescriptorPool(Vulkan& vulkan) + : vulkan{vulkan} { std::vector poolSizes{2}; poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - poolSizes[0].descriptorCount = DESCRIPTOR_SET_COUNT * instance.GetMaxFramesInFlight(); // TODO: how should this actually be determined? + poolSizes[0].descriptorCount = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT; // TODO: how should this actually be determined? poolSizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; - poolSizes[1].descriptorCount = DESCRIPTOR_SET_COUNT * instance.GetMaxFramesInFlight(); // TODO: how should this actually be determined? + poolSizes[1].descriptorCount = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT; // TODO: how should this actually be determined? VkDescriptorPoolCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; createInfo.poolSizeCount = poolSizes.size(); createInfo.pPoolSizes = poolSizes.data(); - createInfo.maxSets = DESCRIPTOR_SET_COUNT * instance.GetMaxFramesInFlight(); + createInfo.maxSets = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT; createInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; - CP_VK_ASSERT(vkCreateDescriptorPool(instance.GetDevice(), &createInfo, nullptr, &descriptorPool), "DescriptorPool : Failed to initialize descriptor pool"); + CP_VK_ASSERT(vkCreateDescriptorPool(vulkan.GetDevice(), &createInfo, nullptr, &descriptorPool), "DescriptorPool : Failed to initialize descriptor pool"); } DescriptorPool::~DescriptorPool() { - vkDestroyDescriptorPool(instance.GetDevice(), descriptorPool, nullptr); + vkDestroyDescriptorPool(vulkan.GetDevice(), descriptorPool, nullptr); } std::vector DescriptorPool::AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout) { - std::vector descriptorSets; - std::vector layouts{static_cast(instance.GetMaxFramesInFlight()), descriptorSetLayout}; + std::vector descriptorSets{SwapChain::MAX_FRAMES_IN_FLIGHT}; + std::vector layouts{SwapChain::MAX_FRAMES_IN_FLIGHT, descriptorSetLayout}; VkDescriptorSetAllocateInfo allocateInfo{}; allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; allocateInfo.descriptorPool = descriptorPool; - allocateInfo.descriptorSetCount = instance.GetMaxFramesInFlight(); + allocateInfo.descriptorSetCount = descriptorSets.size(); allocateInfo.pSetLayouts = layouts.data(); - descriptorSets.resize(instance.GetMaxFramesInFlight()); - CP_VK_ASSERT(vkAllocateDescriptorSets(instance.GetDevice(), &allocateInfo, descriptorSets.data()), "AllocateDescriptorSets : Failed to allocate descriptor sets"); + CP_VK_ASSERT(vkAllocateDescriptorSets(vulkan.GetDevice(), &allocateInfo, descriptorSets.data()), "AllocateDescriptorSets : Failed to allocate descriptor sets"); return descriptorSets; } void DescriptorPool::FreeDescriptorSets(const std::vector& descriptorSets) { - vkFreeDescriptorSets(instance.GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data()); + vkFreeDescriptorSets(vulkan.GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data()); } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/pipeline/DescriptorPool.h b/CopiumEngine/src/copium/pipeline/DescriptorPool.h index 5e3181b..1d4c1e9 100644 --- a/CopiumEngine/src/copium/pipeline/DescriptorPool.h +++ b/CopiumEngine/src/copium/pipeline/DescriptorPool.h @@ -1,7 +1,7 @@ #pragma once #include "copium/util/Common.h" -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include @@ -11,12 +11,12 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorPool); private: - Instance& instance; + Vulkan& vulkan; VkDescriptorPool descriptorPool; static const int DESCRIPTOR_SET_COUNT = 100; public: - DescriptorPool(Instance& instance); + DescriptorPool(Vulkan& vulkan); ~DescriptorPool(); std::vector AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout); diff --git a/CopiumEngine/src/copium/pipeline/DescriptorSet.cpp b/CopiumEngine/src/copium/pipeline/DescriptorSet.cpp index 9b1a918..23baa99 100644 --- a/CopiumEngine/src/copium/pipeline/DescriptorSet.cpp +++ b/CopiumEngine/src/copium/pipeline/DescriptorSet.cpp @@ -1,9 +1,12 @@ #include "copium/pipeline/DescriptorSet.h" +#include "copium/core/Device.h" +#include "copium/core/SwapChain.h" + namespace Copium { - DescriptorSet::DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout) - : instance{instance}, descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout} + DescriptorSet::DescriptorSet(Vulkan& vulkan, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout) + : vulkan{vulkan}, descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout} { descriptorSets = descriptorPool.AllocateDescriptorSets(descriptorSetLayout); } @@ -15,7 +18,7 @@ namespace Copium void DescriptorSet::AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding) { - for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) { + for (size_t i = 0; i < descriptorSets.size(); ++i) { VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(i); VkWriteDescriptorSet descriptorWrite{}; @@ -28,13 +31,13 @@ namespace Copium descriptorWrite.pBufferInfo = &bufferInfo; descriptorWrite.pImageInfo = nullptr; descriptorWrite.pTexelBufferView = nullptr; - vkUpdateDescriptorSets(instance.GetDevice(), 1, &descriptorWrite, 0, nullptr); + vkUpdateDescriptorSets(vulkan.GetDevice(), 1, &descriptorWrite, 0, nullptr); } } void DescriptorSet::AddSampler(const Sampler& sampler, uint32_t binding) { - for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) { + for (size_t i = 0; i < descriptorSets.size(); ++i) { VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(i); VkWriteDescriptorSet descriptorWrite{}; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -46,12 +49,12 @@ namespace Copium descriptorWrite.pBufferInfo = nullptr; descriptorWrite.pImageInfo = &imageInfo; descriptorWrite.pTexelBufferView = nullptr; - vkUpdateDescriptorSets(instance.GetDevice(), 1, &descriptorWrite, 0, nullptr); + vkUpdateDescriptorSets(vulkan.GetDevice(), 1, &descriptorWrite, 0, nullptr); } } DescriptorSet::operator VkDescriptorSet() const { - return descriptorSets[instance.GetFlightIndex()]; + return descriptorSets[vulkan.GetSwapChain().GetFlightIndex()]; } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/pipeline/DescriptorSet.h b/CopiumEngine/src/copium/pipeline/DescriptorSet.h index a6dc0fc..70a7b53 100644 --- a/CopiumEngine/src/copium/pipeline/DescriptorSet.h +++ b/CopiumEngine/src/copium/pipeline/DescriptorSet.h @@ -13,14 +13,14 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorSet); private: - Instance& instance; + Vulkan& vulkan; DescriptorPool& descriptorPool; VkDescriptorSetLayout descriptorSetLayout; std::vector descriptorSets; public: - DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout); + DescriptorSet(Vulkan& vulkan, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout); ~DescriptorSet(); void AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding); diff --git a/CopiumEngine/src/copium/pipeline/Pipeline.cpp b/CopiumEngine/src/copium/pipeline/Pipeline.cpp index 6ff9b9e..4d67cc4 100644 --- a/CopiumEngine/src/copium/pipeline/Pipeline.cpp +++ b/CopiumEngine/src/copium/pipeline/Pipeline.cpp @@ -1,12 +1,13 @@ #include "copium/pipeline/Pipeline.h" +#include "copium/core/Device.h" #include "copium/pipeline/Shader.h" #include "copium/util/FileSystem.h" namespace Copium { - Pipeline::Pipeline(Instance& instance, PipelineCreator creator) - : instance{instance} + Pipeline::Pipeline(Vulkan& vulkan, PipelineCreator creator) + : vulkan{vulkan} { InitializeDescriptorSetLayout(creator); InitializePipeline(creator); @@ -14,11 +15,11 @@ namespace Copium Pipeline::~Pipeline() { - vkDestroyPipeline(instance.GetDevice(), graphicsPipeline, nullptr); - vkDestroyPipelineLayout(instance.GetDevice(), pipelineLayout, nullptr); + vkDestroyPipeline(vulkan.GetDevice(), graphicsPipeline, nullptr); + vkDestroyPipelineLayout(vulkan.GetDevice(), pipelineLayout, nullptr); for (auto&& descriptorSetLayout : descriptorSetLayouts) { - vkDestroyDescriptorSetLayout(instance.GetDevice(), descriptorSetLayout, nullptr); + vkDestroyDescriptorSetLayout(vulkan.GetDevice(), descriptorSetLayout, nullptr); } } @@ -67,13 +68,13 @@ namespace Copium createInfo.bindingCount = layoutBindings.size(); createInfo.pBindings = layoutBindings.data(); - CP_VK_ASSERT(vkCreateDescriptorSetLayout(instance.GetDevice(), &createInfo, nullptr, &descriptorSetLayouts[i++]), "InitializeDescriptorSetLayout : Failed to initialize descriptor set layout"); + CP_VK_ASSERT(vkCreateDescriptorSetLayout(vulkan.GetDevice(), &createInfo, nullptr, &descriptorSetLayouts[i++]), "InitializeDescriptorSetLayout : Failed to initialize descriptor set layout"); } } void Pipeline::InitializePipeline(const PipelineCreator& creator) { - Shader shader{instance, Shader::Type::GlslFile, creator.vertexShader, creator.fragmentShader}; + Shader shader{vulkan, Shader::Type::GlslFile, creator.vertexShader, creator.fragmentShader}; VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo{}; vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; @@ -183,7 +184,7 @@ namespace Copium pipelineLayoutCreateInfo.pushConstantRangeCount = 0; pipelineLayoutCreateInfo.pPushConstantRanges = nullptr; - CP_VK_ASSERT(vkCreatePipelineLayout(instance.GetDevice(), &pipelineLayoutCreateInfo, nullptr, &pipelineLayout), "InitializePipeline : Failed to initialize pipeline layout"); + CP_VK_ASSERT(vkCreatePipelineLayout(vulkan.GetDevice(), &pipelineLayoutCreateInfo, nullptr, &pipelineLayout), "InitializePipeline : Failed to initialize pipeline layout"); const std::vector& shaderStages = shader.GetShaderStages(); VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo{}; @@ -204,6 +205,6 @@ namespace Copium graphicsPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; graphicsPipelineCreateInfo.basePipelineIndex = -1; - CP_VK_ASSERT(vkCreateGraphicsPipelines(instance.GetDevice(), VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &graphicsPipeline), "InitializePipeline : Failed to initialize graphics pipeline"); + CP_VK_ASSERT(vkCreateGraphicsPipelines(vulkan.GetDevice(), VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &graphicsPipeline), "InitializePipeline : Failed to initialize graphics pipeline"); } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/pipeline/Pipeline.h b/CopiumEngine/src/copium/pipeline/Pipeline.h index 5faaba6..791fd9e 100644 --- a/CopiumEngine/src/copium/pipeline/Pipeline.h +++ b/CopiumEngine/src/copium/pipeline/Pipeline.h @@ -1,7 +1,7 @@ #pragma once #include "copium/buffer/CommandBuffer.h" -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/pipeline/DescriptorSet.h" #include "copium/pipeline/PipelineCreator.h" #include "copium/util/Common.h" @@ -15,7 +15,7 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(Pipeline); private: - Instance& instance; + Vulkan& vulkan; std::vector descriptorSetLayouts{}; std::vector boundDescriptorSets; @@ -23,7 +23,7 @@ namespace Copium VkPipeline graphicsPipeline; public: - Pipeline(Instance& instance, PipelineCreator creator); + Pipeline(Vulkan& vulkan, PipelineCreator creator); ~Pipeline(); void Bind(const CommandBuffer& commandBuffer); void SetDescriptorSet(uint32_t setIndex, const DescriptorSet& descriptorSet); diff --git a/CopiumEngine/src/copium/pipeline/Shader.cpp b/CopiumEngine/src/copium/pipeline/Shader.cpp index 7859511..be11eb4 100644 --- a/CopiumEngine/src/copium/pipeline/Shader.cpp +++ b/CopiumEngine/src/copium/pipeline/Shader.cpp @@ -1,11 +1,12 @@ #include "Shader.h" #include "copium/util/FileSystem.h" +#include "copium/core/Device.h" namespace Copium { - Shader::Shader(Instance& instance, Type type, const std::string& vertexInput, const std::string& fragmentInput) - : instance{instance} + Shader::Shader(Vulkan& vulkan, Type type, const std::string& vertexInput, const std::string& fragmentInput) + : vulkan{vulkan} { switch (type) { @@ -45,8 +46,8 @@ namespace Copium Shader::~Shader() { - vkDestroyShaderModule(instance.GetDevice(), vertShaderModule, nullptr); - vkDestroyShaderModule(instance.GetDevice(), fragShaderModule, nullptr); + vkDestroyShaderModule(vulkan.GetDevice(), vertShaderModule, nullptr); + vkDestroyShaderModule(vulkan.GetDevice(), fragShaderModule, nullptr); } const std::vector Shader::GetShaderStages() const @@ -126,7 +127,7 @@ namespace Copium createInfo.pCode = data; VkShaderModule shaderModule; - CP_VK_ASSERT(vkCreateShaderModule(instance.GetDevice(), &createInfo, nullptr, &shaderModule), "InitializeShaderModule : Failed to initialize shader module"); + CP_VK_ASSERT(vkCreateShaderModule(vulkan.GetDevice(), &createInfo, nullptr, &shaderModule), "InitializeShaderModule : Failed to initialize shader module"); return shaderModule; } diff --git a/CopiumEngine/src/copium/pipeline/Shader.h b/CopiumEngine/src/copium/pipeline/Shader.h index 18f834c..d646686 100644 --- a/CopiumEngine/src/copium/pipeline/Shader.h +++ b/CopiumEngine/src/copium/pipeline/Shader.h @@ -1,9 +1,10 @@ #pragma once -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" #include +#include namespace Copium { @@ -17,13 +18,13 @@ namespace Copium }; private: - Instance& instance; + Vulkan& vulkan; VkShaderModule vertShaderModule; VkShaderModule fragShaderModule; std::vector shaderStages; public: - Shader(Instance& instance, Type type, const std::string& vertexInput, const std::string& fragmentInput); + Shader(Vulkan& vulkan, Type type, const std::string& vertexInput, const std::string& fragmentInput); ~Shader(); const std::vector GetShaderStages() const; diff --git a/CopiumEngine/src/copium/sampler/ColorAttachment.cpp b/CopiumEngine/src/copium/sampler/ColorAttachment.cpp index d6945e2..88c669e 100644 --- a/CopiumEngine/src/copium/sampler/ColorAttachment.cpp +++ b/CopiumEngine/src/copium/sampler/ColorAttachment.cpp @@ -1,11 +1,13 @@ #include "copium/sampler/ColorAttachment.h" +#include "copium/core/Device.h" +#include "copium/core/SwapChain.h" #include "copium/sampler/Image.h" namespace Copium { - ColorAttachment::ColorAttachment(Instance& instance, int width, int height) - : Sampler{instance} + ColorAttachment::ColorAttachment(Vulkan& vulkan, int width, int height) + : Sampler{vulkan} { InitializeColorAttachment(width, height); } @@ -13,11 +15,11 @@ namespace Copium ColorAttachment::~ColorAttachment() { for (auto&& image : images) - vkDestroyImage(instance.GetDevice(), image, nullptr); + vkDestroyImage(vulkan.GetDevice(), image, nullptr); for (auto&& imageMemory : imageMemories) - vkFreeMemory(instance.GetDevice(), imageMemory, nullptr); + vkFreeMemory(vulkan.GetDevice(), imageMemory, nullptr); for (auto&& imageView : imageViews) - vkDestroyImageView(instance.GetDevice(), imageView, nullptr); + vkDestroyImageView(vulkan.GetDevice(), imageView, nullptr); } VkDescriptorImageInfo ColorAttachment::GetDescriptorImageInfo(int index) const @@ -40,13 +42,13 @@ namespace Copium void ColorAttachment::InitializeColorAttachment(int width, int height) { - images.resize(instance.GetMaxFramesInFlight()); - imageMemories.resize(instance.GetMaxFramesInFlight()); - imageViews.resize(instance.GetMaxFramesInFlight()); + images.resize(SwapChain::MAX_FRAMES_IN_FLIGHT); + imageViews.resize(SwapChain::MAX_FRAMES_IN_FLIGHT); + imageMemories.resize(SwapChain::MAX_FRAMES_IN_FLIGHT); for (size_t i = 0; i < images.size(); i++) { - Image::InitializeImage(instance, width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images[i], &imageMemories[i]); - imageViews[i] = Image::InitializeImageView(instance, images[i], VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); + Image::InitializeImage(vulkan, width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images[i], &imageMemories[i]); + imageViews[i] = Image::InitializeImageView(vulkan, images[i], VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); } } } diff --git a/CopiumEngine/src/copium/sampler/ColorAttachment.h b/CopiumEngine/src/copium/sampler/ColorAttachment.h index cc0ac55..f887695 100644 --- a/CopiumEngine/src/copium/sampler/ColorAttachment.h +++ b/CopiumEngine/src/copium/sampler/ColorAttachment.h @@ -1,6 +1,6 @@ #pragma once -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/sampler/Sampler.h" #include "copium/util/Common.h" @@ -16,7 +16,7 @@ namespace Copium std::vector imageMemories; std::vector imageViews; public: - ColorAttachment(Instance& instance, int width, int height); + ColorAttachment(Vulkan& vulkan, int width, int height); ~ColorAttachment() override; VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override; diff --git a/CopiumEngine/src/copium/sampler/DepthAttachment.cpp b/CopiumEngine/src/copium/sampler/DepthAttachment.cpp index 4309018..fcedc74 100644 --- a/CopiumEngine/src/copium/sampler/DepthAttachment.cpp +++ b/CopiumEngine/src/copium/sampler/DepthAttachment.cpp @@ -1,20 +1,21 @@ #include "copium/sampler/DepthAttachment.h" +#include "copium/core/Device.h" #include "copium/sampler/Image.h" namespace Copium { - DepthAttachment::DepthAttachment(Instance& instance, int width, int height) - : Sampler{instance} + DepthAttachment::DepthAttachment(Vulkan& vulkan, int width, int height) + : Sampler{vulkan} { InitializeDepthAttachment(width, height); } DepthAttachment::~DepthAttachment() { - vkDestroyImage(instance.GetDevice(), image, nullptr); - vkFreeMemory(instance.GetDevice(), imageMemory, nullptr); - vkDestroyImageView(instance.GetDevice(), imageView, nullptr); + vkDestroyImage(vulkan.GetDevice(), image, nullptr); + vkFreeMemory(vulkan.GetDevice(), imageMemory, nullptr); + vkDestroyImageView(vulkan.GetDevice(), imageView, nullptr); } VkDescriptorImageInfo DepthAttachment::GetDescriptorImageInfo(int index) const @@ -33,8 +34,8 @@ namespace Copium void DepthAttachment::InitializeDepthAttachment(int width, int height) { - VkFormat depthFormat = Image::SelectDepthFormat(instance); - Image::InitializeImage(instance, width, height, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory); - imageView = Image::InitializeImageView(instance, image, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT); + VkFormat depthFormat = Image::SelectDepthFormat(vulkan); + Image::InitializeImage(vulkan, width, height, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory); + imageView = Image::InitializeImageView(vulkan, image, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT); } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/sampler/DepthAttachment.h b/CopiumEngine/src/copium/sampler/DepthAttachment.h index aa0c770..0f31635 100644 --- a/CopiumEngine/src/copium/sampler/DepthAttachment.h +++ b/CopiumEngine/src/copium/sampler/DepthAttachment.h @@ -1,6 +1,6 @@ #pragma once -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/sampler/Sampler.h" #include "copium/util/Common.h" @@ -16,7 +16,7 @@ namespace Copium VkDeviceMemory imageMemory; VkImageView imageView; public: - DepthAttachment(Instance& instance, int width, int height); + DepthAttachment(Vulkan& vulkan, int width, int height); ~DepthAttachment() override; VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override; diff --git a/CopiumEngine/src/copium/sampler/Image.cpp b/CopiumEngine/src/copium/sampler/Image.cpp index 1fa0567..f3d8c56 100644 --- a/CopiumEngine/src/copium/sampler/Image.cpp +++ b/CopiumEngine/src/copium/sampler/Image.cpp @@ -1,10 +1,11 @@ #include "copium/sampler/Image.h" #include "copium/buffer/CommandBufferScoped.h" +#include "copium/core/Device.h" namespace Copium { - void Image::InitializeImage(Instance& instance, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory) + void Image::InitializeImage(Vulkan& vulkan, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory) { VkImageCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; @@ -22,22 +23,22 @@ namespace Copium createInfo.samples = VK_SAMPLE_COUNT_1_BIT; createInfo.flags = 0; - CP_VK_ASSERT(vkCreateImage(instance.GetDevice(), &createInfo, nullptr, image), "InitializeImage : Failed to initialize image"); + CP_VK_ASSERT(vkCreateImage(vulkan.GetDevice(), &createInfo, nullptr, image), "InitializeImage : Failed to initialize image"); VkMemoryRequirements memoryRequirements; - vkGetImageMemoryRequirements(instance.GetDevice(), *image, &memoryRequirements); + vkGetImageMemoryRequirements(vulkan.GetDevice(), *image, &memoryRequirements); VkMemoryAllocateInfo allocateInfo{}; allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocateInfo.allocationSize = memoryRequirements.size; - allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties); + allocateInfo.memoryTypeIndex = vulkan.GetDevice().FindMemoryType(memoryRequirements.memoryTypeBits, properties); - CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, imageMemory), "InitializeImage : Failed to initiallizse image memory"); + CP_VK_ASSERT(vkAllocateMemory(vulkan.GetDevice(), &allocateInfo, nullptr, imageMemory), "InitializeImage : Failed to initiallizse image memory"); - vkBindImageMemory(instance.GetDevice(), *image, *imageMemory, 0); + vkBindImageMemory(vulkan.GetDevice(), *image, *imageMemory, 0); } - VkImageView Image::InitializeImageView(Instance& instance, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags) + VkImageView Image::InitializeImageView(Vulkan& vulkan, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags) { VkImageView imageView; VkImageViewCreateInfo createInfo{}; @@ -54,13 +55,13 @@ namespace Copium createInfo.subresourceRange.levelCount = 1; createInfo.subresourceRange.baseArrayLayer = 0; createInfo.subresourceRange.layerCount = 1; - CP_VK_ASSERT(vkCreateImageView(instance.GetDevice(), &createInfo, nullptr, &imageView), "InitializeImageView : Failed to initialize image view"); + CP_VK_ASSERT(vkCreateImageView(vulkan.GetDevice(), &createInfo, nullptr, &imageView), "InitializeImageView : Failed to initialize image view"); return imageView; } - void Image::TransitionImageLayout(Instance& instance, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) + void Image::TransitionImageLayout(Vulkan& vulkan, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) { - CommandBufferScoped commandBuffer{instance}; + CommandBufferScoped commandBuffer{vulkan}; VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -126,9 +127,9 @@ namespace Copium vkCmdPipelineBarrier(commandBuffer, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); } - void Image::CopyBufferToImage(Instance& instance, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height) + void Image::CopyBufferToImage(Vulkan& vulkan, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height) { - CommandBufferScoped commandBuffer{instance}; + CommandBufferScoped commandBuffer{vulkan}; VkBufferImageCopy region{}; region.bufferOffset = 0; @@ -147,9 +148,9 @@ namespace Copium } - VkFormat Image::SelectDepthFormat(Instance& instance) + VkFormat Image::SelectDepthFormat(Vulkan& vulkan) { - return SelectSupportedFormat(instance, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + return SelectSupportedFormat(vulkan, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); } bool Image::HasStencilComponent(VkFormat format) @@ -157,12 +158,12 @@ namespace Copium return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT; } - VkFormat Image::SelectSupportedFormat(Instance& instance, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) + VkFormat Image::SelectSupportedFormat(Vulkan& vulkan, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) { for (VkFormat format : candidates) { VkFormatProperties properties; - vkGetPhysicalDeviceFormatProperties(instance.GetPhysicalDevice(), format, &properties); + vkGetPhysicalDeviceFormatProperties(vulkan.GetDevice().GetPhysicalDevice(), format, &properties); if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features) { return format; diff --git a/CopiumEngine/src/copium/sampler/Image.h b/CopiumEngine/src/copium/sampler/Image.h index 8823e61..39bf0cf 100644 --- a/CopiumEngine/src/copium/sampler/Image.h +++ b/CopiumEngine/src/copium/sampler/Image.h @@ -1,7 +1,7 @@ #pragma once #include "copium/buffer/Buffer.h" -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" #include @@ -12,14 +12,14 @@ namespace Copium { CP_STATIC_CLASS(Image); public: - static void InitializeImage(Instance& instance, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory); - static VkImageView InitializeImageView(Instance& instance, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags); - static void TransitionImageLayout(Instance& instance, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout); - static void CopyBufferToImage(Instance& instance, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height); - static VkFormat SelectDepthFormat(Instance& instance); + static void InitializeImage(Vulkan& vulkan, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory); + static VkImageView InitializeImageView(Vulkan& vulkan, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags); + static void TransitionImageLayout(Vulkan& vulkan, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout); + static void CopyBufferToImage(Vulkan& vulkan, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height); + static VkFormat SelectDepthFormat(Vulkan& vulkan); private: static bool HasStencilComponent(VkFormat format); - static VkFormat SelectSupportedFormat(Instance& instance, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features); + static VkFormat SelectSupportedFormat(Vulkan& vulkan, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features); }; } \ No newline at end of file diff --git a/CopiumEngine/src/copium/sampler/Sampler.cpp b/CopiumEngine/src/copium/sampler/Sampler.cpp index 0b43b5a..976ad0e 100644 --- a/CopiumEngine/src/copium/sampler/Sampler.cpp +++ b/CopiumEngine/src/copium/sampler/Sampler.cpp @@ -1,22 +1,24 @@ #include "copium/sampler/Sampler.h" +#include "copium/core/Device.h" + namespace Copium { - Sampler::Sampler(Instance& instance) - : instance{instance} + Sampler::Sampler(Vulkan& vulkan) + : vulkan{vulkan} { InitializeSampler(); } Sampler::~Sampler() { - vkDestroySampler(instance.GetDevice(), sampler, nullptr); + vkDestroySampler(vulkan.GetDevice(), sampler, nullptr); } void Sampler::InitializeSampler() { VkPhysicalDeviceProperties properties{}; - vkGetPhysicalDeviceProperties(instance.GetPhysicalDevice(), &properties); + vkGetPhysicalDeviceProperties(vulkan.GetDevice().GetPhysicalDevice(), &properties); VkSamplerCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; @@ -35,6 +37,6 @@ namespace Copium createInfo.minLod = 0.0f; createInfo.maxLod = 0.0f; - CP_VK_ASSERT(vkCreateSampler(instance.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler"); + CP_VK_ASSERT(vkCreateSampler(vulkan.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler"); } } \ No newline at end of file diff --git a/CopiumEngine/src/copium/sampler/Sampler.h b/CopiumEngine/src/copium/sampler/Sampler.h index a3caefb..19a1470 100644 --- a/CopiumEngine/src/copium/sampler/Sampler.h +++ b/CopiumEngine/src/copium/sampler/Sampler.h @@ -1,6 +1,6 @@ #pragma once -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/util/Common.h" #include @@ -11,10 +11,10 @@ namespace Copium { CP_DELETE_COPY_AND_MOVE_CTOR(Sampler); protected: - Instance& instance; + Vulkan& vulkan; VkSampler sampler; public: - Sampler(Instance& instance); + Sampler(Vulkan& vulkan); virtual ~Sampler(); virtual VkDescriptorImageInfo GetDescriptorImageInfo(int index) const = 0; diff --git a/CopiumEngine/src/copium/sampler/Texture2D.cpp b/CopiumEngine/src/copium/sampler/Texture2D.cpp index 3fa3c02..c93b04f 100644 --- a/CopiumEngine/src/copium/sampler/Texture2D.cpp +++ b/CopiumEngine/src/copium/sampler/Texture2D.cpp @@ -1,21 +1,23 @@ #include "copium/sampler/Texture2D.h" +#include "copium/core/Device.h" + #define STB_IMAGE_IMPLEMENTATION #include namespace Copium { - Texture2D::Texture2D(Instance& instance, const std::string& filename) - : Sampler{instance} + Texture2D::Texture2D(Vulkan& vulkan, const std::string& filename) + : Sampler{vulkan} { InitializeTextureImage(filename); } Texture2D::~Texture2D() { - vkDestroyImage(instance.GetDevice(), image, nullptr); - vkFreeMemory(instance.GetDevice(), imageMemory, nullptr); - vkDestroyImageView(instance.GetDevice(), imageView, nullptr); + vkDestroyImage(vulkan.GetDevice(), image, nullptr); + vkFreeMemory(vulkan.GetDevice(), imageMemory, nullptr); + vkDestroyImageView(vulkan.GetDevice(), imageView, nullptr); } VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const @@ -38,16 +40,16 @@ namespace Copium CP_ASSERT(pixels, "InitializeTextureImage : Failed to load texture image"); VkDeviceSize bufferSize = texWidth * texHeight * 4; - Buffer stagingBuffer{instance, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1}; + Buffer stagingBuffer{vulkan, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1}; void* data = stagingBuffer.Map(); memcpy(data, pixels, bufferSize); stagingBuffer.Unmap(); stbi_image_free(pixels); - Image::InitializeImage(instance, texWidth, texHeight, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory); - Image::TransitionImageLayout(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - Image::CopyBufferToImage(instance, stagingBuffer, image, texWidth, texHeight); - Image::TransitionImageLayout(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - imageView = Image::InitializeImageView(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); + Image::InitializeImage(vulkan, texWidth, texHeight, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory); + Image::TransitionImageLayout(vulkan, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + Image::CopyBufferToImage(vulkan, stagingBuffer, image, texWidth, texHeight); + Image::TransitionImageLayout(vulkan, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + imageView = Image::InitializeImageView(vulkan, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); } } diff --git a/CopiumEngine/src/copium/sampler/Texture2D.h b/CopiumEngine/src/copium/sampler/Texture2D.h index b0f708f..6fec95e 100644 --- a/CopiumEngine/src/copium/sampler/Texture2D.h +++ b/CopiumEngine/src/copium/sampler/Texture2D.h @@ -1,7 +1,7 @@ #pragma once #include "copium/buffer/CommandBufferScoped.h" -#include "copium/core/Instance.h" +#include "copium/core/Vulkan.h" #include "copium/sampler/Image.h" #include "copium/sampler/Sampler.h" #include "copium/util/Common.h" @@ -18,7 +18,7 @@ namespace Copium VkDeviceMemory imageMemory; VkImageView imageView; public: - Texture2D(Instance& instance, const std::string& filename); + Texture2D(Vulkan& vulkan, const std::string& filename); ~Texture2D() override; VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;