diff --git a/Vulkan/Vulkan.vcxproj b/Vulkan/Vulkan.vcxproj
index 08b5691..79956fb 100644
--- a/Vulkan/Vulkan.vcxproj
+++ b/Vulkan/Vulkan.vcxproj
@@ -163,9 +163,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Vulkan/src/Application.cpp b/Vulkan/src/Application.cpp
new file mode 100644
index 0000000..dbc7483
--- /dev/null
+++ b/Vulkan/src/Application.cpp
@@ -0,0 +1,197 @@
+#include "Application.h"
+
+#include "Vertex.h"
+#include "VertexPassthrough.h"
+
+#include
+
+namespace Copium
+{
+ const std::vector vertices = {
+ Vertex{{-0.5f, 0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
+ Vertex{{ 0.5f, 0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
+ Vertex{{ 0.5f, 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
+ Vertex{{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
+ Vertex{{-0.5f, 0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
+ Vertex{{ 0.5f, 0.0f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
+ Vertex{{ 0.5f, 0.0f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
+ Vertex{{-0.5f, 0.0f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
+ };
+
+ const std::vector indices = {
+ 0, 1, 2, 2, 3, 0,
+ 4, 5, 6, 6, 7, 4
+ };
+
+ const std::vector verticesPassthrough = {
+ VertexPassthrough{{-1.0f, -1.0f}},
+ VertexPassthrough{{ 1.0f, -1.0f}},
+ VertexPassthrough{{ 1.0f, 1.0f}},
+ VertexPassthrough{{-1.0f, 1.0f}},
+ };
+
+ const std::vector indicesPassthrough = {
+ 0, 1, 2, 2, 3, 0,
+ };
+
+ struct alignas(64) ShaderUniform
+ {
+ alignas(16) glm::mat4 projection;
+ alignas(16) glm::mat4 view;
+ alignas(16) glm::mat4 model;
+ alignas(16) glm::vec3 lightPos;
+ };
+
+ Application::Application()
+ {
+ InitializeInstance();
+ InitializeFrameBuffer();
+ InitializeGraphicsPipeline();
+ InitializeTextureSampler();
+ InitializeUniformBuffer();
+ InitializeDescriptorSets();
+ InitializeVertexBuffer();
+ InitializeIndexBuffer();
+ InitializeCommandBuffer();
+ }
+
+ Application::~Application()
+ {
+ vkDeviceWaitIdle(instance->GetDevice());
+ }
+
+ bool Application::Update()
+ {
+ if (framebuffer->GetWidth() != instance->GetSwapChain().GetExtent().width || framebuffer->GetHeight() != instance->GetSwapChain().GetExtent().height)
+ {
+ framebuffer->Resize(instance->GetSwapChain().GetExtent().width / 8, instance->GetSwapChain().GetExtent().height / 8);
+ descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
+ }
+ if (!instance->BeginPresent())
+ {
+ return true;
+ }
+
+ RecordCommandBuffer();
+ commandBuffer->SubmitAsGraphicsQueue();
+
+ return instance->EndPresent();
+ }
+
+ void Application::InitializeInstance()
+ {
+ instance = std::make_unique("Copium Engine");
+ }
+
+ void Application::InitializeFrameBuffer()
+ {
+ framebuffer = std::make_unique(*instance, instance->GetSwapChain().GetExtent().width, instance->GetSwapChain().GetExtent().height);
+ }
+
+ void Application::InitializeTextureSampler()
+ {
+ texture2D = std::make_unique(*instance, "res/textures/texture.png");
+ }
+
+ void Application::InitializeUniformBuffer()
+ {
+ shaderUniformBuffer = std::make_unique(*instance, sizeof(ShaderUniform));
+ }
+
+ void Application::InitializeDescriptorSets()
+ {
+ descriptorPool = std::make_unique(*instance);
+
+ descriptorSet = std::make_unique(*instance, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
+ descriptorSet->AddUniform(*shaderUniformBuffer, 0);
+ descriptorSet->AddSampler(*texture2D, 1);
+
+ descriptorSetPassthrough = std::make_unique(*instance, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
+ descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
+ }
+
+ void Application::InitializeGraphicsPipeline()
+ {
+ PipelineCreator creator{framebuffer->GetRenderPass(), "res/shaders/shader.vert", "res/shaders/shader.frag"};
+ creator.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT);
+ 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);
+
+ PipelineCreator creatorPassthrough{instance->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);
+ }
+
+ void Application::InitializeVertexBuffer()
+ {
+ vertexBuffer = std::make_unique(*instance, Vertex::GetDescriptor(), vertices.size());
+ vertexBuffer->Update(0, (void*)vertices.data());
+
+ vertexBufferPassthrough = std::make_unique(*instance, VertexPassthrough::GetDescriptor(), verticesPassthrough.size());
+ vertexBufferPassthrough->Update(0, (void*)verticesPassthrough.data());
+ }
+
+ void Application::InitializeIndexBuffer()
+ {
+ indexBuffer = std::make_unique(*instance, indices.size());
+ indexBuffer->UpdateStaging((void*)indices.data());
+
+ indexBufferPassthrough = std::make_unique(*instance, indicesPassthrough.size());
+ indexBufferPassthrough->UpdateStaging((void*)indicesPassthrough.data());
+ }
+
+ void Application::InitializeCommandBuffer()
+ {
+ commandBuffer = std::make_unique(*instance, CommandBuffer::Type::Dynamic);
+ }
+
+ void Application::RecordCommandBuffer()
+ {
+ commandBuffer->Begin();
+
+ framebuffer->Bind(*commandBuffer);
+ graphicsPipeline->Bind(*commandBuffer);
+
+ UpdateUniformBuffer();
+
+ vertexBuffer->Bind(*commandBuffer);
+ indexBuffer->Bind(*commandBuffer);
+
+ graphicsPipeline->SetDescriptorSet(0, *descriptorSet);
+ graphicsPipeline->BindDescriptorSets(*commandBuffer);
+
+ indexBuffer->Draw(*commandBuffer);
+ framebuffer->Unbind(*commandBuffer);
+
+ instance->GetSwapChain().BeginFrameBuffer(*commandBuffer);
+
+ graphicsPipelinePassthrough->Bind(*commandBuffer);
+ graphicsPipelinePassthrough->SetDescriptorSet(0, *descriptorSetPassthrough);
+ graphicsPipelinePassthrough->BindDescriptorSets(*commandBuffer);
+ vertexBufferPassthrough->Bind(*commandBuffer);
+ indexBufferPassthrough->Bind(*commandBuffer);
+ indexBufferPassthrough->Draw(*commandBuffer);
+
+ instance->GetSwapChain().EndFrameBuffer(*commandBuffer);
+ commandBuffer->End();
+ }
+
+ void Application::UpdateUniformBuffer()
+ {
+ static Timer startTimer;
+
+ float time = startTimer.Elapsed();
+ ShaderUniform shaderUniform;
+ shaderUniform.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
+ shaderUniform.projection = glm::perspective(glm::radians(45.0f), framebuffer->GetWidth() / (float)framebuffer->GetHeight(), 0.1f, 10.0f);
+ shaderUniform.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 1.0f, 0.0f));
+ shaderUniform.projection[1][1] *= -1;
+ shaderUniform.lightPos = glm::rotate(glm::mat4{1.0f}, time * glm::radians(45.0f), glm::vec3(0, 1, 0)) * glm::vec4{0.3, 0.1, 0, 1};
+
+ shaderUniformBuffer->Update(shaderUniform);
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/Application.h b/Vulkan/src/Application.h
index 02187c2..ef3eac1 100644
--- a/Vulkan/src/Application.h
+++ b/Vulkan/src/Application.h
@@ -1,6 +1,5 @@
#pragma once
-#include "Buffer.h"
#include "DescriptorPool.h"
#include "DescriptorSet.h"
#include "Framebuffer.h"
@@ -8,58 +7,14 @@
#include "Instance.h"
#include "Pipeline.h"
#include "Texture2D.h"
-#include "Timer.h"
#include "UniformBuffer.h"
-#include "Vertex.h"
#include "VertexBuffer.h"
-#include "VertexPassthrough.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
namespace Copium
{
- const std::vector vertices = {
- Vertex{{-0.5f, 0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
- Vertex{{ 0.5f, 0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
- Vertex{{ 0.5f, 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
- Vertex{{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
- Vertex{{-0.5f, 0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
- Vertex{{ 0.5f, 0.0f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
- Vertex{{ 0.5f, 0.0f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
- Vertex{{-0.5f, 0.0f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
- };
-
- const std::vector indices = {
- 0, 1, 2, 2, 3, 0,
- 4, 5, 6, 6, 7, 4
- };
-
- const std::vector verticesPassthrough = {
- VertexPassthrough{{-1.0f, -1.0f}},
- VertexPassthrough{{ 1.0f, -1.0f}},
- VertexPassthrough{{ 1.0f, 1.0f}},
- VertexPassthrough{{-1.0f, 1.0f}},
- };
-
- const std::vector indicesPassthrough = {
- 0, 1, 2, 2, 3, 0,
- };
-
- struct alignas(64) ShaderUniform
- {
- alignas(16) glm::mat4 projection;
- alignas(16) glm::mat4 view;
- alignas(16) glm::mat4 model;
- alignas(16) glm::vec3 lightPos;
- };
-
class Application final
{
+ CP_DELETE_COPY_AND_MOVE_CTOR(Application);
private:
std::unique_ptr instance;
std::unique_ptr graphicsPipeline;
@@ -78,164 +33,21 @@ namespace Copium
std::unique_ptr descriptorSetPassthrough;
public:
- Application()
- {
- InitializeInstance();
- InitializeFrameBuffer();
- InitializeGraphicsPipeline();
- InitializeTextureSampler();
- InitializeUniformBuffer();
- InitializeDescriptorSets();
- InitializeVertexBuffer();
- InitializeIndexBuffer();
- InitializeCommandBuffer();
- }
-
- ~Application()
- {
- vkDeviceWaitIdle(instance->GetDevice());
- }
-
- Application(Application&&) = delete;
- Application(const Application&) = delete;
- Application& operator=(Application&&) = delete;
- Application& operator=(const Application&) = delete;
-
- bool Update()
- {
- if (framebuffer->GetWidth() != instance->GetSwapChain().GetExtent().width || framebuffer->GetHeight() != instance->GetSwapChain().GetExtent().height)
- {
- framebuffer->Resize(instance->GetSwapChain().GetExtent().width / 8, instance->GetSwapChain().GetExtent().height / 8);
- descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
- }
- if (!instance->BeginPresent())
- {
- return true;
- }
-
- RecordCommandBuffer();
- commandBuffer->SubmitAsGraphicsQueue();
-
- return instance->EndPresent();
- }
+ Application();
+ ~Application();
+ bool Update();
private:
-
- void InitializeInstance()
- {
- instance = std::make_unique("Copium Engine");
- }
-
- void InitializeFrameBuffer()
- {
- framebuffer = std::make_unique(*instance, instance->GetSwapChain().GetExtent().width, instance->GetSwapChain().GetExtent().height);
- }
-
- void InitializeTextureSampler()
- {
- texture2D = std::make_unique(*instance, "res/textures/texture.png");
- }
-
- void InitializeUniformBuffer()
- {
- shaderUniformBuffer = std::make_unique(*instance, sizeof(ShaderUniform));
- }
-
- void InitializeDescriptorSets()
- {
- descriptorPool = std::make_unique(*instance);
-
- descriptorSet = std::make_unique(*instance, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
- descriptorSet->AddUniform(*shaderUniformBuffer, 0);
- descriptorSet->AddSampler(*texture2D, 1);
-
- descriptorSetPassthrough = std::make_unique(*instance, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
- descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
- }
-
- void InitializeGraphicsPipeline()
- {
- PipelineCreator creator{framebuffer->GetRenderPass(), "res/shaders/shader.vert", "res/shaders/shader.frag"};
- creator.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT);
- 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);
-
- PipelineCreator creatorPassthrough{instance->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);
- }
-
- void InitializeVertexBuffer()
- {
- vertexBuffer = std::make_unique(*instance, Vertex::GetDescriptor(), vertices.size());
- vertexBuffer->Update(0, (void*)vertices.data());
-
- vertexBufferPassthrough = std::make_unique(*instance, VertexPassthrough::GetDescriptor(), verticesPassthrough.size());
- vertexBufferPassthrough->Update(0, (void*)verticesPassthrough.data());
- }
-
- void InitializeIndexBuffer()
- {
- indexBuffer = std::make_unique(*instance, indices.size());
- indexBuffer->UpdateStaging((void*)indices.data());
-
- indexBufferPassthrough = std::make_unique(*instance, indicesPassthrough.size());
- indexBufferPassthrough->UpdateStaging((void*)indicesPassthrough.data());
- }
-
- void InitializeCommandBuffer()
- {
- commandBuffer = std::make_unique(*instance, CommandBuffer::Type::Dynamic);
- }
-
- void RecordCommandBuffer()
- {
- commandBuffer->Begin();
-
- framebuffer->Bind(*commandBuffer);
- graphicsPipeline->Bind(*commandBuffer);
-
- UpdateUniformBuffer();
-
- vertexBuffer->Bind(*commandBuffer);
- indexBuffer->Bind(*commandBuffer);
-
- graphicsPipeline->SetDescriptorSet(0, *descriptorSet);
- graphicsPipeline->BindDescriptorSets(commandBuffer->GetHandle());
-
- indexBuffer->Draw(*commandBuffer);
- framebuffer->Unbind(*commandBuffer);
-
- instance->GetSwapChain().BeginFrameBuffer(*commandBuffer);
-
- graphicsPipelinePassthrough->Bind(*commandBuffer);
- graphicsPipelinePassthrough->SetDescriptorSet(0, *descriptorSetPassthrough);
- graphicsPipelinePassthrough->BindDescriptorSets(commandBuffer->GetHandle());
- vertexBufferPassthrough->Bind(*commandBuffer);
- indexBufferPassthrough->Bind(*commandBuffer);
- indexBufferPassthrough->Draw(*commandBuffer);
-
- instance->GetSwapChain().EndFrameBuffer(*commandBuffer);
- commandBuffer->End();
- }
-
- void UpdateUniformBuffer()
- {
- static Timer startTimer;
-
- float time = startTimer.Elapsed();
- ShaderUniform shaderUniform;
- shaderUniform.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
- shaderUniform.projection = glm::perspective(glm::radians(45.0f), framebuffer->GetWidth() / (float)framebuffer->GetHeight(), 0.1f, 10.0f);
- shaderUniform.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 1.0f, 0.0f));
- shaderUniform.projection[1][1] *= -1;
- shaderUniform.lightPos = glm::rotate(glm::mat4{1.0f}, time * glm::radians(45.0f), glm::vec3(0, 1, 0)) * glm::vec4{0.3, 0.1, 0, 1};
-
- shaderUniformBuffer->Update(shaderUniform);
- }
+ void InitializeInstance();
+ void InitializeFrameBuffer();
+ void InitializeTextureSampler();
+ void InitializeUniformBuffer();
+ void InitializeDescriptorSets();
+ void InitializeGraphicsPipeline();
+ void InitializeVertexBuffer();
+ void InitializeIndexBuffer();
+ void InitializeCommandBuffer();
+ void RecordCommandBuffer();
+ void UpdateUniformBuffer();
};
}
diff --git a/Vulkan/src/Buffer.cpp b/Vulkan/src/Buffer.cpp
new file mode 100644
index 0000000..391561f
--- /dev/null
+++ b/Vulkan/src/Buffer.cpp
@@ -0,0 +1,139 @@
+#include "Buffer.h"
+
+namespace Copium
+{
+ Buffer::Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count)
+ : instance{instance}, size{size}, count{count}
+ {
+ VkBufferCreateInfo createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ createInfo.size = size * (VkDeviceSize)count;
+ createInfo.usage = usage;
+ createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+ CP_VK_ASSERT(vkCreateBuffer(instance.GetDevice(), &createInfo, nullptr, &handle), "Buffer : Failed to initialize buffer");
+
+ VkMemoryRequirements memoryRequirements;
+ vkGetBufferMemoryRequirements(instance.GetDevice(), handle, &memoryRequirements);
+
+ VkMemoryAllocateInfo allocateInfo{};
+ allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ allocateInfo.allocationSize = memoryRequirements.size;
+ allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties);
+
+ CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, &memory), "Buffer : Failed to allocate buffer memory");
+
+ vkBindBufferMemory(instance.GetDevice(), handle, memory, 0);
+ }
+
+ Buffer::~Buffer()
+ {
+ vkFreeMemory(instance.GetDevice(), memory, nullptr);
+ vkDestroyBuffer(instance.GetDevice(), handle, nullptr);
+ }
+
+ void Buffer::Update(void* indexData, int index)
+ {
+ CP_ASSERT(index >= 0 && index < count, "Update : Index is outside of the buffer");
+
+ if (mappedData == nullptr)
+ {
+ void* data;
+ vkMapMemory(instance.GetDevice(), memory, index * size, size, 0, &data);
+ memcpy(data, indexData, size);
+ vkUnmapMemory(instance.GetDevice(), memory);
+ }
+ else
+ {
+ memcpy((char*)mappedData + index * size, indexData, size);
+ }
+ }
+
+ 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};
+
+ stagingBuffer.Update(data, 0);
+
+ CopyBuffer(instance, 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};
+
+ stagingBuffer.Update(data, 0);
+
+ CopyBuffer(instance, 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);
+ return mappedData;
+ }
+
+ void Buffer::Unmap()
+ {
+ CP_ASSERT(mappedData != nullptr, "Unmap : Unmapping an already unmapped buffer");
+
+ vkUnmapMemory(instance.GetDevice(), memory);
+ mappedData = nullptr;
+ }
+
+ Buffer::operator VkBuffer() const
+ {
+ return handle;
+ }
+
+ VkDeviceSize Buffer::GetSize() const
+ {
+ return size;
+ }
+
+ VkDeviceSize Buffer::GetPosition(int index) const
+ {
+ CP_ASSERT(index >= 0 && index < count, "GetPosition : Index is outside of the buffer");
+ return size * (VkDeviceSize)index;
+ }
+
+ void Buffer::CopyBuffer(Instance& instance, 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.commandBufferCount = 1;
+
+ VkCommandBuffer commandBuffer;
+ CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, &commandBuffer), "CopyBuffer : Failed to initialize command buffer");
+
+ VkCommandBufferBeginInfo beginInfo{};
+ beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+
+ vkBeginCommandBuffer(commandBuffer, &beginInfo);
+
+ VkBufferCopy bufferCopy{};
+ bufferCopy.dstOffset = offset;
+ bufferCopy.srcOffset = 0;
+ bufferCopy.size = size;
+
+ vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &bufferCopy);
+
+ vkEndCommandBuffer(commandBuffer);
+
+ VkSubmitInfo submitInfo{};
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &commandBuffer;
+
+ vkQueueSubmit(instance.GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
+ vkQueueWaitIdle(instance.GetGraphicsQueue());
+
+ vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), 1, &commandBuffer);
+ }
+}
diff --git a/Vulkan/src/Buffer.h b/Vulkan/src/Buffer.h
index 4d8fd83..b265ac5 100644
--- a/Vulkan/src/Buffer.h
+++ b/Vulkan/src/Buffer.h
@@ -2,7 +2,7 @@
#include "Common.h"
#include "Instance.h"
-#include
+
#include
namespace Copium
@@ -21,153 +21,20 @@ namespace Copium
void* mappedData = nullptr;
public:
- Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count)
- : instance{instance}, size{size}, count{count}
- {
- VkBufferCreateInfo createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- createInfo.size = size * (VkDeviceSize)count;
- createInfo.usage = usage;
- createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count);
+ virtual ~Buffer();
- CP_VK_ASSERT(vkCreateBuffer(instance.GetDevice(), &createInfo, nullptr, &handle), "Buffer : Failed to initialize buffer");
+ void Update(void* indexData, int index);
+ void UpdateStaging(void* data);
+ void UpdateStaging(void* data, VkDeviceSize offset, VkDeviceSize size);
- VkMemoryRequirements memoryRequirements;
- vkGetBufferMemoryRequirements(instance.GetDevice(), handle, &memoryRequirements);
+ void* Map();
+ void Unmap();
- VkMemoryAllocateInfo allocateInfo{};
- allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- allocateInfo.allocationSize = memoryRequirements.size;
- allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties);
+ operator VkBuffer() const;
+ VkDeviceSize GetSize() const;
+ VkDeviceSize GetPosition(int index) const;
- CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, &memory), "Buffer : Failed to allocate buffer memory");
-
- vkBindBufferMemory(instance.GetDevice(), handle, memory, 0);
- }
-
- virtual ~Buffer()
- {
- vkFreeMemory(instance.GetDevice(), memory, nullptr);
- vkDestroyBuffer(instance.GetDevice(), handle, nullptr);
- }
-
- void Update(void* indexData, int index)
- {
- CP_ASSERT(index >= 0 && index < count, "Update : Index is outside of the buffer");
-
- if (mappedData == nullptr)
- {
- void* data;
- vkMapMemory(instance.GetDevice(), memory, index * size, size, 0, &data);
- memcpy(data, indexData, size);
- vkUnmapMemory(instance.GetDevice(), memory);
- }
- else
- {
- memcpy((char*)mappedData + index * size, indexData, size);
- }
- }
-
- void 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};
-
- stagingBuffer.Update(data, 0);
-
- CopyBuffer(instance, stagingBuffer, *this, 0, bufferSize);
- }
-
- void 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};
-
- stagingBuffer.Update(data, 0);
-
- CopyBuffer(instance, stagingBuffer, *this, offset, size);
- }
-
- void* Map()
- {
- CP_ASSERT(mappedData == nullptr, "Map : Mapping an already mapped buffer");
- vkMapMemory(instance.GetDevice(), memory, 0, size * count, 0, &mappedData);
- return mappedData;
- }
-
- void Unmap()
- {
- CP_ASSERT(mappedData != nullptr, "Unmap : Unmapping an already unmapped buffer");
-
- vkUnmapMemory(instance.GetDevice(), memory);
- mappedData = nullptr;
- }
-
- virtual void Bind(const CommandBuffer& commandBuffer) { CP_UNIMPLEMENTED(); };
-
- void BindAsVertexBuffer(VkCommandBuffer commandBuffer)
- {
- VkDeviceSize offset = 0;
- vkCmdBindVertexBuffers(commandBuffer, 0, 1, &handle, &offset);
- }
-
- void BindAsIndexBuffer(VkCommandBuffer commandBuffer)
- {
- // TODO: Maybe don't assume that indices are uint16?
- vkCmdBindIndexBuffer(commandBuffer, handle, 0, VK_INDEX_TYPE_UINT16);
- }
-
- VkBuffer GetHandle() const
- {
- return handle;
- }
-
- VkDeviceSize GetSize() const
- {
- return size;
- }
-
- VkDeviceSize GetPosition(int index) const
- {
- CP_ASSERT(index >= 0 && index < count, "GetPosition : Index is outside of the buffer");
- return size * (VkDeviceSize)index;
- }
-
- static void CopyBuffer(Instance& instance, 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.commandBufferCount = 1;
-
- VkCommandBuffer commandBuffer;
- CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, &commandBuffer), "CopyBuffer : Failed to initialize command buffer");
-
- VkCommandBufferBeginInfo beginInfo{};
- beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
-
- vkBeginCommandBuffer(commandBuffer, &beginInfo);
-
- VkBufferCopy bufferCopy{};
- bufferCopy.dstOffset = offset;
- bufferCopy.srcOffset = 0;
- bufferCopy.size = size;
-
- vkCmdCopyBuffer(commandBuffer, srcBuffer.GetHandle(), dstBuffer.GetHandle(), 1, &bufferCopy);
-
- vkEndCommandBuffer(commandBuffer);
-
- VkSubmitInfo submitInfo{};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &commandBuffer;
-
- vkQueueSubmit(instance.GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
- vkQueueWaitIdle(instance.GetGraphicsQueue());
-
- vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), 1, &commandBuffer);
- }
+ static void CopyBuffer(Instance& instance, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size);
};
}
diff --git a/Vulkan/src/ColorAttachment.cpp b/Vulkan/src/ColorAttachment.cpp
new file mode 100644
index 0000000..9e3e349
--- /dev/null
+++ b/Vulkan/src/ColorAttachment.cpp
@@ -0,0 +1,52 @@
+#include "ColorAttachment.h"
+
+#include "Image.h"
+
+namespace Copium
+{
+ ColorAttachment::ColorAttachment(Instance& instance, int width, int height)
+ : Sampler{instance}
+ {
+ InitializeColorAttachment(width, height);
+ }
+
+ ColorAttachment::~ColorAttachment()
+ {
+ for (auto&& image : images)
+ vkDestroyImage(instance.GetDevice(), image, nullptr);
+ for (auto&& imageMemory : imageMemories)
+ vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
+ for (auto&& imageView : imageViews)
+ vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
+ }
+
+ VkDescriptorImageInfo ColorAttachment::GetDescriptorImageInfo(int index) const
+ {
+ CP_ASSERT(index >= 0 && index < imageViews.size(), "GetDescriptorImageInfo : index out of bound for color attachment");
+
+ VkDescriptorImageInfo imageInfo{};
+ imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ imageInfo.sampler = sampler;
+ imageInfo.imageView = imageViews[index];
+ return imageInfo;
+ }
+
+ VkImageView ColorAttachment::GetImageView(int index)
+ {
+ CP_ASSERT(index >= 0 && index < imageViews.size(), "GetImageView : Index out of bound");
+
+ return imageViews[index];
+ }
+
+ void ColorAttachment::InitializeColorAttachment(int width, int height)
+ {
+ images.resize(instance.GetMaxFramesInFlight());
+ imageMemories.resize(instance.GetMaxFramesInFlight());
+ imageViews.resize(instance.GetMaxFramesInFlight());
+ 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);
+ }
+ }
+}
diff --git a/Vulkan/src/ColorAttachment.h b/Vulkan/src/ColorAttachment.h
index dbebede..08fe257 100644
--- a/Vulkan/src/ColorAttachment.h
+++ b/Vulkan/src/ColorAttachment.h
@@ -2,12 +2,13 @@
#include "Common.h"
#include "Instance.h"
-#include "Image.h"
#include "Sampler.h"
+#include
+
namespace Copium
{
- class ColorAttachment : public Sampler
+ class ColorAttachment final : public Sampler
{
CP_DELETE_COPY_AND_MOVE_CTOR(ColorAttachment);
private:
@@ -15,51 +16,13 @@ namespace Copium
std::vector imageMemories;
std::vector imageViews;
public:
- ColorAttachment(Instance& instance, int width, int height)
- : Sampler{instance}
- {
- InitializeColorAttachment(width, height);
- }
+ ColorAttachment(Instance& instance, int width, int height);
+ ~ColorAttachment() override;
- ~ColorAttachment() override
- {
- for (auto&& image : images)
- vkDestroyImage(instance.GetDevice(), image, nullptr);
- for (auto&& imageMemory : imageMemories)
- vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
- for (auto&& imageView : imageViews)
- vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
- }
-
- VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override
- {
- CP_ASSERT(index >= 0 && index < imageViews.size(), "GetDescriptorImageInfo : index out of bound for color attachment");
-
- VkDescriptorImageInfo imageInfo{};
- imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- imageInfo.sampler = sampler;
- imageInfo.imageView = imageViews[index];
- return imageInfo;
- }
-
- VkImageView GetImageView(int index)
- {
- CP_ASSERT(index >= 0 && index < imageViews.size(), "GetImageView : Index out of bound");
-
- return imageViews[index];
- }
+ VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
+ VkImageView GetImageView(int index);
private:
- void InitializeColorAttachment(int width, int height)
- {
- images.resize(instance.GetMaxFramesInFlight());
- imageMemories.resize(instance.GetMaxFramesInFlight());
- imageViews.resize(instance.GetMaxFramesInFlight());
- 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);
- }
- }
+ void InitializeColorAttachment(int width, int height);
};
}
diff --git a/Vulkan/src/CommandBuffer.cpp b/Vulkan/src/CommandBuffer.cpp
new file mode 100644
index 0000000..ccc35a5
--- /dev/null
+++ b/Vulkan/src/CommandBuffer.cpp
@@ -0,0 +1,76 @@
+#include "CommandBuffer.h"
+
+namespace Copium
+{
+ CommandBuffer::CommandBuffer(Instance& instance, Type type)
+ : instance{instance}, type{type}
+ {
+ if (type == Type::Dynamic)
+ commandBuffers.resize(instance.GetMaxFramesInFlight());
+ else
+ commandBuffers.resize(1);
+
+ VkCommandBufferAllocateInfo allocateInfo{};
+ allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ allocateInfo.commandPool = instance.GetCommandPool();
+ allocateInfo.commandBufferCount = commandBuffers.size();
+ CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, commandBuffers.data()), "CommandBuffer : Failed to allocate CommandBuffer");
+ }
+
+ CommandBuffer::~CommandBuffer()
+ {
+ vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), commandBuffers.size(), commandBuffers.data());
+ }
+
+ // TODO: Test as constexpr function to see if it avoids the switch case
+ void CommandBuffer::Begin()
+ {
+ VkCommandBufferBeginInfo beginInfo{};
+ 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");
+ }
+
+ void CommandBuffer::End()
+ {
+ vkEndCommandBuffer(currentCommandBuffer);
+ }
+
+ void CommandBuffer::Submit()
+ {
+ VkSubmitInfo submitInfo{};
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = ¤tCommandBuffer;
+
+ vkQueueSubmit(instance.GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
+ // TODO: if singleUse?
+ vkQueueWaitIdle(instance.GetGraphicsQueue());
+ }
+
+ void CommandBuffer::SubmitAsGraphicsQueue()
+ {
+ instance.SubmitGraphicsQueue({currentCommandBuffer});
+ }
+
+ CommandBuffer::operator VkCommandBuffer() const
+ {
+ return currentCommandBuffer;
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/CommandBuffer.h b/Vulkan/src/CommandBuffer.h
index f4a78dc..f73240d 100644
--- a/Vulkan/src/CommandBuffer.h
+++ b/Vulkan/src/CommandBuffer.h
@@ -2,6 +2,7 @@
#include "Common.h"
#include "Instance.h"
+
#include
namespace Copium
@@ -22,81 +23,15 @@ namespace Copium
VkCommandBuffer currentCommandBuffer{VK_NULL_HANDLE};
public:
- CommandBuffer(Instance& instance, Type type)
- : instance{instance}, type{type}
- {
- if (type == Type::Dynamic)
- commandBuffers.resize(instance.GetMaxFramesInFlight());
- else
- commandBuffers.resize(1);
+ CommandBuffer(Instance& instance, Type type);
- VkCommandBufferAllocateInfo allocateInfo{};
- allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- allocateInfo.commandPool = instance.GetCommandPool();
- allocateInfo.commandBufferCount = commandBuffers.size();
- CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, commandBuffers.data()), "CommandBuffer : Failed to allocate CommandBuffer");
- }
+ virtual ~CommandBuffer();
- ~CommandBuffer()
- {
- vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), commandBuffers.size(), commandBuffers.data());
- }
+ void Begin();
+ void End();
+ void Submit();
+ void SubmitAsGraphicsQueue();
- operator VkCommandBuffer() const
- {
- return currentCommandBuffer;
- }
-
- // TODO: Test as constexpr function to see if it avoids the switch case
- void Begin()
- {
- VkCommandBufferBeginInfo beginInfo{};
- 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");
- }
-
- void End()
- {
- vkEndCommandBuffer(currentCommandBuffer);
- }
-
- void Submit()
- {
- VkSubmitInfo submitInfo{};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = ¤tCommandBuffer;
-
- vkQueueSubmit(instance.GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
- // TODO: if singleUse?
- vkQueueWaitIdle(instance.GetGraphicsQueue());
- }
-
- void SubmitAsGraphicsQueue()
- {
- instance.SubmitGraphicsQueue({currentCommandBuffer});
- }
-
- VkCommandBuffer GetHandle() const
- {
- return currentCommandBuffer;
- }
+ operator VkCommandBuffer() const;
};
}
diff --git a/Vulkan/src/CommandBufferScoped.cpp b/Vulkan/src/CommandBufferScoped.cpp
new file mode 100644
index 0000000..e3c9b98
--- /dev/null
+++ b/Vulkan/src/CommandBufferScoped.cpp
@@ -0,0 +1,16 @@
+#include "CommandBufferScoped.h"
+
+namespace Copium
+{
+ CommandBufferScoped::CommandBufferScoped(Instance& instance)
+ : CommandBuffer{instance, Type::SingleUse}
+ {
+ CommandBuffer::Begin();
+ }
+
+ CommandBufferScoped::~CommandBufferScoped()
+ {
+ CommandBuffer::End();
+ CommandBuffer::Submit();
+ }
+}
diff --git a/Vulkan/src/CommandBufferScoped.h b/Vulkan/src/CommandBufferScoped.h
index 4422404..35d432e 100644
--- a/Vulkan/src/CommandBufferScoped.h
+++ b/Vulkan/src/CommandBufferScoped.h
@@ -5,20 +5,12 @@
namespace Copium
{
- class CommandBufferScoped : public CommandBuffer
+ class CommandBufferScoped final : public CommandBuffer
{
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBufferScoped);
public:
- CommandBufferScoped(Instance& instance)
- : CommandBuffer{instance, Type::SingleUse}
- {
- CommandBuffer::Begin();
- }
+ CommandBufferScoped(Instance& instance);
- ~CommandBufferScoped()
- {
- CommandBuffer::End();
- CommandBuffer::Submit();
- }
+ ~CommandBufferScoped() override;
};
}
diff --git a/Vulkan/src/Common.h b/Vulkan/src/Common.h
index 881dafa..52c429f 100644
--- a/Vulkan/src/Common.h
+++ b/Vulkan/src/Common.h
@@ -45,6 +45,9 @@
throw VulkanException(Copium::StringFormat(format, __VA_ARGS__)); \
} \
} while(false)
+
+#define CP_STATIC_CLASS(ClassName)\
+ ClassName() = delete
#define CP_DELETE_COPY_AND_MOVE_CTOR(ClassName) \
ClassName(ClassName&&) = delete; \
ClassName(const ClassName&) = delete; \
diff --git a/Vulkan/src/DebugMessenger.cpp b/Vulkan/src/DebugMessenger.cpp
new file mode 100644
index 0000000..fb69295
--- /dev/null
+++ b/Vulkan/src/DebugMessenger.cpp
@@ -0,0 +1,86 @@
+#include "DebugMessenger.h"
+
+namespace Copium
+{
+#ifndef NDEBUG
+ DebugMessenger::DebugMessenger(VkInstance instance)
+ : instance{instance}
+ {
+ VkDebugUtilsMessengerCreateInfoEXT createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
+ createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+ createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+ createInfo.pfnUserCallback = DebugCallback;
+ createInfo.pUserData = nullptr;
+ CP_VK_ASSERT(vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger), "DebugMessenger : Failed to initialze debug messenger");
+ }
+
+ DebugMessenger::~DebugMessenger()
+ {
+ vkDestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
+ }
+
+ void DebugMessenger::AddRequiredExtensions(std::vector* extensions)
+ {
+ extensions->emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+ }
+
+ void DebugMessenger::AddRequiredLayers(std::vector* layers)
+ {
+ layers->emplace_back("VK_LAYER_KHRONOS_validation");
+ }
+#else
+ DebugMessenger::DebugMessenger(VkInstance instance)
+ : instance{instance}
+ {}
+
+ DebugMessenger::~DebugMessenger()
+ {}
+
+ void DebugMessenger::AddRequiredExtensions(std::vector* extensions)
+ {}
+
+ void DebugMessenger::AddRequiredLayers(std::vector* layers)
+ {}
+#endif
+
+ VKAPI_ATTR VkBool32 VKAPI_CALL DebugMessenger::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageType,
+ const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
+ void* pUserData)
+ {
+ if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
+ {
+ if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
+ CP_ABORT("DebugCallback : %s", pCallbackData->pMessage);
+ else
+ CP_WARN("DebugCallback : %s", pCallbackData->pMessage);
+ }
+ return VK_FALSE;
+ }
+
+ VkResult DebugMessenger::vkCreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDebugUtilsMessengerEXT* pDebugMessenger)
+ {
+ auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
+ if (func != nullptr)
+ return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ void DebugMessenger::vkDestroyDebugUtilsMessengerEXT(VkInstance instance,
+ VkDebugUtilsMessengerEXT debugMessenger,
+ const VkAllocationCallbacks* pAllocator) {
+ auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
+ if (func != nullptr) {
+ func(instance, debugMessenger, pAllocator);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Vulkan/src/DebugMessenger.h b/Vulkan/src/DebugMessenger.h
index 0156c95..abf772a 100644
--- a/Vulkan/src/DebugMessenger.h
+++ b/Vulkan/src/DebugMessenger.h
@@ -1,89 +1,41 @@
#pragma once
#include "Common.h"
+
+#include
+
namespace Copium
{
- class DebugMessenger
+ class DebugMessenger final
{
CP_DELETE_COPY_AND_MOVE_CTOR(DebugMessenger);
public:
VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger;
- DebugMessenger(VkInstance instance)
- : instance{instance}
- {
- #ifndef NDEBUG
- VkDebugUtilsMessengerCreateInfoEXT createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
- createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
- createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
- createInfo.pfnUserCallback = DebugCallback;
- createInfo.pUserData = nullptr;
- CP_VK_ASSERT(vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger), "DebugMessenger : Failed to initialze debug messenger");
- #endif
- }
+ DebugMessenger(VkInstance instance);
+ ~DebugMessenger();
- ~DebugMessenger()
- {
- #ifndef NDEBUG
- vkDestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
- #endif
- }
-
- static void AddRequiredExtensions(std::vector* extensions)
- {
- #ifndef NDEBUG
- extensions->emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
- #endif
- }
-
- static void AddRequiredLayers(std::vector* layers)
- {
- #ifndef NDEBUG
- layers->emplace_back("VK_LAYER_KHRONOS_validation");
- #endif
- }
+ static void AddRequiredExtensions(std::vector* extensions);
+ static void AddRequiredLayers(std::vector* layers);
+
private:
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
- void* pUserData)
- {
- if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
- {
- if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
- CP_ABORT("DebugCallback : %s", pCallbackData->pMessage);
- else
- CP_WARN("DebugCallback : %s", pCallbackData->pMessage);
- }
- return VK_FALSE;
- }
+ void* pUserData);
+
static VkResult vkCreateDebugUtilsMessengerEXT(VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
- VkDebugUtilsMessengerEXT* pDebugMessenger)
- {
- auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
- if (func != nullptr)
- return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
- return VK_ERROR_EXTENSION_NOT_PRESENT;
- }
+ VkDebugUtilsMessengerEXT* pDebugMessenger);
+
static void vkDestroyDebugUtilsMessengerEXT(VkInstance instance,
VkDebugUtilsMessengerEXT debugMessenger,
- const VkAllocationCallbacks* pAllocator) {
- auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
- if (func != nullptr) {
- func(instance, debugMessenger, pAllocator);
- }
- }
+ const VkAllocationCallbacks* pAllocator);
};
}
diff --git a/Vulkan/src/DepthAttachment.cpp b/Vulkan/src/DepthAttachment.cpp
new file mode 100644
index 0000000..d4cff2d
--- /dev/null
+++ b/Vulkan/src/DepthAttachment.cpp
@@ -0,0 +1,40 @@
+#include "DepthAttachment.h"
+
+#include "Image.h"
+
+namespace Copium
+{
+ DepthAttachment::DepthAttachment(Instance& instance, int width, int height)
+ : Sampler{instance}
+ {
+ InitializeDepthAttachment(width, height);
+ }
+
+ DepthAttachment::~DepthAttachment()
+ {
+ vkDestroyImage(instance.GetDevice(), image, nullptr);
+ vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
+ vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
+ }
+
+ VkDescriptorImageInfo DepthAttachment::GetDescriptorImageInfo(int index) const
+ {
+ VkDescriptorImageInfo imageInfo{};
+ imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ imageInfo.sampler = sampler;
+ imageInfo.imageView = imageView;
+ return imageInfo;
+ }
+
+ VkImageView DepthAttachment::GetImageView() const
+ {
+ return imageView;
+ }
+
+ 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);
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/DepthAttachment.h b/Vulkan/src/DepthAttachment.h
index bc08d31..61ae094 100644
--- a/Vulkan/src/DepthAttachment.h
+++ b/Vulkan/src/DepthAttachment.h
@@ -2,12 +2,13 @@
#include "Common.h"
#include "Instance.h"
-#include "Image.h"
#include "Sampler.h"
+#include
+
namespace Copium
{
- class DepthAttachment : public Sampler
+ class DepthAttachment final : public Sampler
{
CP_DELETE_COPY_AND_MOVE_CTOR(DepthAttachment);
private:
@@ -15,39 +16,14 @@ namespace Copium
VkDeviceMemory imageMemory;
VkImageView imageView;
public:
- DepthAttachment(Instance& instance, int width, int height)
- : Sampler{instance}
- {
- InitializeDepthAttachment(width, height);
- }
+ DepthAttachment(Instance& instance, int width, int height);
+ ~DepthAttachment() override;
- ~DepthAttachment() override
- {
- vkDestroyImage(instance.GetDevice(), image, nullptr);
- vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
- vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
- }
-
- VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override
- {
- VkDescriptorImageInfo imageInfo{};
- imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- imageInfo.sampler = sampler;
- imageInfo.imageView = imageView;
- return imageInfo;
- }
-
- VkImageView GetImageView() const
- {
- return imageView;
- }
+ VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
+ VkImageView GetImageView() const;
private:
- void 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);
- }
+ void InitializeDepthAttachment(int width, int height);
+
};
}
diff --git a/Vulkan/src/DescriptorPool.cpp b/Vulkan/src/DescriptorPool.cpp
new file mode 100644
index 0000000..7fcb6ec
--- /dev/null
+++ b/Vulkan/src/DescriptorPool.cpp
@@ -0,0 +1,50 @@
+#include "DescriptorPool.h"
+
+namespace Copium
+{
+ DescriptorPool::DescriptorPool(Instance& instance)
+ : instance{instance}
+ {
+ 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[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
+ poolSizes[1].descriptorCount = DESCRIPTOR_SET_COUNT * instance.GetMaxFramesInFlight(); // 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.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+
+ CP_VK_ASSERT(vkCreateDescriptorPool(instance.GetDevice(), &createInfo, nullptr, &descriptorPool), "DescriptorPool : Failed to initialize descriptor pool");
+ }
+
+ DescriptorPool::~DescriptorPool()
+ {
+ vkDestroyDescriptorPool(instance.GetDevice(), descriptorPool, nullptr);
+ }
+
+ std::vector DescriptorPool::AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout)
+ {
+ std::vector descriptorSets;
+ std::vector layouts{static_cast(instance.GetMaxFramesInFlight()), descriptorSetLayout};
+ VkDescriptorSetAllocateInfo allocateInfo{};
+ allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ allocateInfo.descriptorPool = descriptorPool;
+ allocateInfo.descriptorSetCount = instance.GetMaxFramesInFlight();
+ allocateInfo.pSetLayouts = layouts.data();
+
+ descriptorSets.resize(instance.GetMaxFramesInFlight());
+ CP_VK_ASSERT(vkAllocateDescriptorSets(instance.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());
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/DescriptorPool.h b/Vulkan/src/DescriptorPool.h
index ea2ec78..998df55 100644
--- a/Vulkan/src/DescriptorPool.h
+++ b/Vulkan/src/DescriptorPool.h
@@ -2,6 +2,7 @@
#include "Common.h"
#include "Instance.h"
+
#include
namespace Copium
@@ -15,50 +16,10 @@ namespace Copium
VkDescriptorPool descriptorPool;
static const int DESCRIPTOR_SET_COUNT = 100;
public:
- DescriptorPool(Instance& instance)
- : instance{instance}
- {
- 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?
+ DescriptorPool(Instance& instance);
+ ~DescriptorPool();
- poolSizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
- poolSizes[1].descriptorCount = DESCRIPTOR_SET_COUNT * instance.GetMaxFramesInFlight(); // 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.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
-
- CP_VK_ASSERT(vkCreateDescriptorPool(instance.GetDevice(), &createInfo, nullptr, &descriptorPool), "DescriptorPool : Failed to initialize descriptor pool");
- }
-
- ~DescriptorPool()
- {
- vkDestroyDescriptorPool(instance.GetDevice(), descriptorPool, nullptr);
- }
-
- std::vector AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout)
- {
- std::vector descriptorSets;
- std::vector layouts{static_cast(instance.GetMaxFramesInFlight()), descriptorSetLayout};
- VkDescriptorSetAllocateInfo allocateInfo{};
- allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
- allocateInfo.descriptorPool = descriptorPool;
- allocateInfo.descriptorSetCount = instance.GetMaxFramesInFlight();
- allocateInfo.pSetLayouts = layouts.data();
-
- descriptorSets.resize(instance.GetMaxFramesInFlight());
- CP_VK_ASSERT(vkAllocateDescriptorSets(instance.GetDevice(), &allocateInfo, descriptorSets.data()), "AllocateDescriptorSets : Failed to allocate descriptor sets");
-
- return descriptorSets;
- }
-
- void FreeDescriptorSets(const std::vector& descriptorSets)
- {
- vkFreeDescriptorSets(instance.GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data());
- }
+ std::vector AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout);
+ void FreeDescriptorSets(const std::vector& descriptorSets);
};
}
diff --git a/Vulkan/src/DescriptorSet.cpp b/Vulkan/src/DescriptorSet.cpp
new file mode 100644
index 0000000..8ab50d4
--- /dev/null
+++ b/Vulkan/src/DescriptorSet.cpp
@@ -0,0 +1,57 @@
+#include "DescriptorSet.h"
+
+namespace Copium
+{
+ DescriptorSet::DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout)
+ : instance{instance}, descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout}
+ {
+ descriptorSets = descriptorPool.AllocateDescriptorSets(descriptorSetLayout);
+ }
+
+ DescriptorSet::~DescriptorSet()
+ {
+ descriptorPool.FreeDescriptorSets(descriptorSets);
+ }
+
+ void DescriptorSet::AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding)
+ {
+ for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) {
+ VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(i);
+
+ VkWriteDescriptorSet descriptorWrite{};
+ descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ descriptorWrite.dstSet = descriptorSets[i];
+ descriptorWrite.dstBinding = binding;
+ descriptorWrite.dstArrayElement = 0;
+ descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ descriptorWrite.descriptorCount = 1;
+ descriptorWrite.pBufferInfo = &bufferInfo;
+ descriptorWrite.pImageInfo = nullptr;
+ descriptorWrite.pTexelBufferView = nullptr;
+ vkUpdateDescriptorSets(instance.GetDevice(), 1, &descriptorWrite, 0, nullptr);
+ }
+ }
+
+ void DescriptorSet::AddSampler(const Sampler& sampler, uint32_t binding)
+ {
+ for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) {
+ VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(i);
+ VkWriteDescriptorSet descriptorWrite{};
+ descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ descriptorWrite.dstSet = descriptorSets[i];
+ descriptorWrite.dstBinding = binding;
+ descriptorWrite.dstArrayElement = 0;
+ descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ descriptorWrite.descriptorCount = 1;
+ descriptorWrite.pBufferInfo = nullptr;
+ descriptorWrite.pImageInfo = &imageInfo;
+ descriptorWrite.pTexelBufferView = nullptr;
+ vkUpdateDescriptorSets(instance.GetDevice(), 1, &descriptorWrite, 0, nullptr);
+ }
+ }
+
+ DescriptorSet::operator VkDescriptorSet() const
+ {
+ return descriptorSets[instance.GetFlightIndex()];
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/DescriptorSet.h b/Vulkan/src/DescriptorSet.h
index b548a12..14cadf2 100644
--- a/Vulkan/src/DescriptorSet.h
+++ b/Vulkan/src/DescriptorSet.h
@@ -20,57 +20,11 @@ namespace Copium
std::vector descriptorSets;
public:
- DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout)
- : instance{instance}, descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout}
- {
- descriptorSets = descriptorPool.AllocateDescriptorSets(descriptorSetLayout);
- }
+ DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout);
+ ~DescriptorSet();
- ~DescriptorSet()
- {
- descriptorPool.FreeDescriptorSets(descriptorSets);
- }
-
- void AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding)
- {
- for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) {
- VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(i);
-
- VkWriteDescriptorSet descriptorWrite{};
- descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- descriptorWrite.dstSet = descriptorSets[i];
- descriptorWrite.dstBinding = binding;
- descriptorWrite.dstArrayElement = 0;
- descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- descriptorWrite.descriptorCount = 1;
- descriptorWrite.pBufferInfo = &bufferInfo;
- descriptorWrite.pImageInfo = nullptr;
- descriptorWrite.pTexelBufferView = nullptr;
- vkUpdateDescriptorSets(instance.GetDevice(), 1, &descriptorWrite, 0, nullptr);
- }
- }
-
- void AddSampler(const Sampler& sampler, uint32_t binding)
- {
- for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) {
- VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(i);
- VkWriteDescriptorSet descriptorWrite{};
- descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- descriptorWrite.dstSet = descriptorSets[i];
- descriptorWrite.dstBinding = binding;
- descriptorWrite.dstArrayElement = 0;
- descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- descriptorWrite.descriptorCount = 1;
- descriptorWrite.pBufferInfo = nullptr;
- descriptorWrite.pImageInfo = &imageInfo;
- descriptorWrite.pTexelBufferView = nullptr;
- vkUpdateDescriptorSets(instance.GetDevice(), 1, &descriptorWrite, 0, nullptr);
- }
- }
-
- VkDescriptorSet GetHandle() const
- {
- return descriptorSets[instance.GetFlightIndex()];
- }
+ void AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding);
+ void AddSampler(const Sampler& sampler, uint32_t binding);
+ operator VkDescriptorSet() const;
};
}
\ No newline at end of file
diff --git a/Vulkan/src/FileSystem.cpp b/Vulkan/src/FileSystem.cpp
new file mode 100644
index 0000000..88db09f
--- /dev/null
+++ b/Vulkan/src/FileSystem.cpp
@@ -0,0 +1,66 @@
+#include "FileSystem.h"
+
+namespace Copium
+{
+ std::vector FileSystem::ReadFile(const std::string& filename)
+ {
+ std::ifstream file(filename, std::ios::ate | std::ios::binary);
+ CP_ASSERT(file.is_open(), "ReadFile : Failed to open file");
+
+ size_t fileSize = (size_t)file.tellg();
+ std::vector buffer(fileSize);
+
+ file.seekg(0);
+ file.read(buffer.data(), fileSize);
+
+ return buffer;
+ }
+
+ std::string FileSystem::ReadFileStr(const std::string& filename)
+ {
+ std::ifstream file(filename, std::ios::ate | std::ios::binary);
+ CP_ASSERT(file.is_open(), "ReadFileStr : Failed to open file");
+
+ size_t fileSize = (size_t)file.tellg();
+ std::string buffer;
+ buffer.resize(fileSize);
+
+ file.seekg(0);
+ file.read(buffer.data(), fileSize);
+
+ return buffer;
+ }
+
+ void FileSystem::WriteFile(const std::string& filename, const std::string& data)
+ {
+ std::filesystem::path path{filename};
+ std::filesystem::create_directories(path.parent_path());
+ std::ofstream file(filename, std::ios::binary);
+ CP_ASSERT(file.is_open(), "WriteFile : Failed to open file");
+
+ file.write(data.c_str(), data.size());
+ }
+
+ void FileSystem::WriteFile(const std::string& filename, const char* data, size_t size)
+ {
+ std::filesystem::path path{filename};
+ std::filesystem::create_directories(path.parent_path());
+ std::ofstream file(filename, std::ios::binary);
+ CP_ASSERT(file.is_open(), "WriteFile : Failed to open file");
+
+ file.write(data, size);
+ }
+
+ bool FileSystem::FileExists(const std::string& filename)
+ {
+ std::ifstream file(filename);
+ return file.good();
+ }
+
+ int64_t FileSystem::DateModified(const std::string& filename)
+ {
+ struct stat result;
+ CP_ASSERT(stat(filename.c_str(), &result) == 0, "DataModified : Cannot stat file %s", filename.c_str());
+ return (int64_t)result.st_mtime;
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/FileSystem.h b/Vulkan/src/FileSystem.h
index 11fb42a..db0b8bc 100644
--- a/Vulkan/src/FileSystem.h
+++ b/Vulkan/src/FileSystem.h
@@ -12,68 +12,13 @@ namespace Copium
{
class FileSystem
{
- FileSystem() = delete;
+ CP_STATIC_CLASS(FileSystem);
public:
- static std::vector ReadFile(const std::string& filename)
- {
- std::ifstream file(filename, std::ios::ate | std::ios::binary);
- CP_ASSERT(file.is_open(), "ReadFile : Failed to open file");
-
- size_t fileSize = (size_t)file.tellg();
- std::vector buffer(fileSize);
-
- file.seekg(0);
- file.read(buffer.data(), fileSize);
-
- return buffer;
- }
-
- static std::string ReadFileStr(const std::string& filename)
- {
- std::ifstream file(filename, std::ios::ate | std::ios::binary);
- CP_ASSERT(file.is_open(), "ReadFileStr : Failed to open file");
-
- size_t fileSize = (size_t)file.tellg();
- std::string buffer;
- buffer.resize(fileSize);
-
- file.seekg(0);
- file.read(buffer.data(), fileSize);
-
- return buffer;
- }
-
- static void WriteFile(const std::string& filename, const std::string& data)
- {
- std::filesystem::path path{filename};
- std::filesystem::create_directories(path.parent_path());
- std::ofstream file(filename, std::ios::binary);
- CP_ASSERT(file.is_open(), "WriteFile : Failed to open file");
-
- file.write(data.c_str(), data.size());
- }
-
- static void WriteFile(const std::string& filename, const char* data, size_t size)
- {
- std::filesystem::path path{filename};
- std::filesystem::create_directories(path.parent_path());
- std::ofstream file(filename, std::ios::binary);
- CP_ASSERT(file.is_open(), "WriteFile : Failed to open file");
-
- file.write(data, size);
- }
-
- static bool FileExists(const std::string& filename)
- {
- std::ifstream file(filename);
- return file.good();
- }
-
- static int64_t DateModified(const std::string& filename)
- {
- struct stat result;
- CP_ASSERT(stat(filename.c_str(), &result) == 0, "DataModified : Cannot stat file %s", filename.c_str());
- return (int64_t)result.st_mtime;
- }
+ static std::vector ReadFile(const std::string& filename);
+ static std::string ReadFileStr(const std::string& filename);
+ static void WriteFile(const std::string& filename, const std::string& data);
+ static void WriteFile(const std::string& filename, const char* data, size_t size);
+ static bool FileExists(const std::string& filename);
+ static int64_t DateModified(const std::string& filename);
};
}
\ No newline at end of file
diff --git a/Vulkan/src/Framebuffer.cpp b/Vulkan/src/Framebuffer.cpp
new file mode 100644
index 0000000..e430219
--- /dev/null
+++ b/Vulkan/src/Framebuffer.cpp
@@ -0,0 +1,192 @@
+#include "Framebuffer.h"
+
+#include "CommandBuffer.h"
+#include "Image.h"
+
+namespace Copium
+{
+ Framebuffer::Framebuffer(Instance& instance, uint32_t width, uint32_t height)
+ : instance{instance}, width{width}, height{height}
+ {
+ InitializeImage();
+ InitializeDepthBuffer();
+ InitializeRenderPass();
+ InitializeFramebuffers();
+ }
+
+ Framebuffer::~Framebuffer()
+ {
+ for (auto& framebuffer : framebuffers)
+ vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
+ vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
+ }
+
+ void Framebuffer::Resize(uint32_t width, uint32_t height)
+ {
+ vkDeviceWaitIdle(instance.GetDevice());
+ this->width = width;
+ this->height = height;
+ colorAttachment.reset();
+ depthAttachment.reset();
+ for (auto&& framebuffer : framebuffers)
+ vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
+ InitializeImage();
+ InitializeDepthBuffer();
+ InitializeFramebuffers();
+ }
+
+ void Framebuffer::Bind(const CommandBuffer& commandBuffer)
+ {
+ std::vector clearValues{2};
+ clearValues[0].color = {{0.0f, 0.0f, 0.0f, 1.0f}};
+ clearValues[1].depthStencil = {1.0f, 0};
+
+ VkRenderPassBeginInfo renderPassBeginInfo{};
+ renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+ renderPassBeginInfo.renderPass = renderPass;
+ renderPassBeginInfo.framebuffer = framebuffers[instance.GetFlightIndex()];
+ renderPassBeginInfo.renderArea.offset = {0, 0};
+ renderPassBeginInfo.renderArea.extent = {width, height};
+ renderPassBeginInfo.clearValueCount = clearValues.size();
+ renderPassBeginInfo.pClearValues = clearValues.data();
+ vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+ VkViewport viewport{};
+ viewport.x = 0.0f;
+ viewport.y = 0.0f;
+ viewport.width = width;
+ viewport.height = height;
+ viewport.minDepth = 0.0f;
+ viewport.maxDepth = 1.0f;
+ vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
+ VkRect2D scissor{};
+ scissor.offset = {0, 0};
+ scissor.extent = {width, height};
+ vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
+ }
+
+ void Framebuffer::Unbind(const CommandBuffer& commandBuffer)
+ {
+ vkCmdEndRenderPass(commandBuffer);
+ }
+
+ VkRenderPass Framebuffer::GetRenderPass() const
+ {
+ return renderPass;
+ }
+
+ VkFramebuffer Framebuffer::GetFramebuffer() const
+ {
+ return framebuffers[instance.GetFlightIndex()];
+ }
+
+ const ColorAttachment& Framebuffer::GetColorAttachment() const
+ {
+ return *colorAttachment;
+ }
+
+ uint32_t Framebuffer::GetWidth() const
+ {
+ return width;
+ }
+
+ uint32_t Framebuffer::GetHeight() const
+ {
+ return height;
+ }
+
+ void Framebuffer::InitializeImage()
+ {
+ colorAttachment = std::make_unique(instance, width, height);
+ }
+
+ void Framebuffer::InitializeDepthBuffer()
+ {
+ depthAttachment = std::make_unique(instance, width, height);
+ }
+
+ void Framebuffer::InitializeRenderPass()
+ {
+ VkAttachmentDescription colorAttachment{};
+ colorAttachment.format = VK_FORMAT_R8G8B8A8_SRGB;
+ colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
+ colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ VkAttachmentDescription depthAttachment{};
+ depthAttachment.format = Image::SelectDepthFormat(instance);
+ depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
+ depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+ VkAttachmentReference colorAttachmentRef{};
+ colorAttachmentRef.attachment = 0;
+ colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+ VkAttachmentReference depthAttachmentRef{};
+ depthAttachmentRef.attachment = 1;
+ depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+ VkSubpassDescription subpass{};
+ subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ subpass.colorAttachmentCount = 1;
+ subpass.pColorAttachments = &colorAttachmentRef;
+ subpass.pDepthStencilAttachment = &depthAttachmentRef;
+
+ std::vector dependencies{2};
+ dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
+ dependencies[0].dstSubpass = 0;
+ dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+
+ dependencies[1].srcSubpass = 0;
+ dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
+ dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+
+ std::vector attachments{colorAttachment, depthAttachment};
+ VkRenderPassCreateInfo renderPassCreateInfo{};
+ renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ renderPassCreateInfo.attachmentCount = attachments.size();
+ renderPassCreateInfo.pAttachments = attachments.data();
+ renderPassCreateInfo.subpassCount = 1;
+ renderPassCreateInfo.pSubpasses = &subpass;
+ renderPassCreateInfo.dependencyCount = dependencies.size();
+ renderPassCreateInfo.pDependencies = dependencies.data();
+
+ CP_VK_ASSERT(vkCreateRenderPass(instance.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)
+ {
+ std::vector attachments{colorAttachment->GetImageView(i), depthAttachment->GetImageView()};
+
+ VkFramebufferCreateInfo createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+ createInfo.renderPass = renderPass;
+ createInfo.attachmentCount = attachments.size();
+ createInfo.pAttachments = attachments.data();
+ createInfo.width = width;
+ createInfo.height = height;
+ createInfo.layers = 1;
+
+ CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize framebuffer");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/Framebuffer.h b/Vulkan/src/Framebuffer.h
index 4c446c7..408f861 100644
--- a/Vulkan/src/Framebuffer.h
+++ b/Vulkan/src/Framebuffer.h
@@ -1,7 +1,6 @@
#pragma once
#include "Common.h"
-#include "Image.h"
#include "Instance.h"
#include "ColorAttachment.h"
#include "DepthAttachment.h"
@@ -10,7 +9,7 @@
namespace Copium
{
- class Framebuffer
+ class Framebuffer final
{
CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer);
private:
@@ -24,191 +23,23 @@ namespace Copium
uint32_t width;
uint32_t height;
public:
- Framebuffer(Instance& instance, uint32_t width, uint32_t height)
- : instance{instance}, width{width}, height{height}
- {
- InitializeImage();
- InitializeDepthBuffer();
- InitializeRenderPass();
- InitializeFramebuffers();
- }
+ Framebuffer(Instance& instance, uint32_t width, uint32_t height);
+ ~Framebuffer();
- ~Framebuffer()
- {
- for (auto& framebuffer : framebuffers)
- vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
- vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
- }
+ void Resize(uint32_t width, uint32_t height);
+ void Bind(const CommandBuffer& commandBuffer);
+ void Unbind(const CommandBuffer& commandBuffer);
- void Resize(uint32_t width, uint32_t height)
- {
- vkDeviceWaitIdle(instance.GetDevice());
- this->width = width;
- this->height = height;
- colorAttachment.reset();
- depthAttachment.reset();
- for (auto&& framebuffer : framebuffers)
- vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
- InitializeImage();
- InitializeDepthBuffer();
- InitializeFramebuffers();
- }
-
- void Bind(const CommandBuffer& commandBuffer)
- {
- std::vector clearValues{2};
- clearValues[0].color = {{0.0f, 0.0f, 0.0f, 1.0f}};
- clearValues[1].depthStencil = {1.0f, 0};
-
- VkRenderPassBeginInfo renderPassBeginInfo{};
- renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
- renderPassBeginInfo.renderPass = renderPass;
- renderPassBeginInfo.framebuffer = framebuffers[instance.GetFlightIndex()];
- renderPassBeginInfo.renderArea.offset = {0, 0};
- renderPassBeginInfo.renderArea.extent = {width, height};
- renderPassBeginInfo.clearValueCount = clearValues.size();
- renderPassBeginInfo.pClearValues = clearValues.data();
- vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
-
- VkViewport viewport{};
- viewport.x = 0.0f;
- viewport.y = 0.0f;
- viewport.width = width;
- viewport.height = height;
- viewport.minDepth = 0.0f;
- viewport.maxDepth = 1.0f;
- vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
- VkRect2D scissor{};
- scissor.offset = {0, 0};
- scissor.extent = {width, height};
- vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
- }
-
- void Unbind(const CommandBuffer& commandBuffer)
- {
- vkCmdEndRenderPass(commandBuffer);
- }
-
- VkRenderPass GetRenderPass() const
- {
- return renderPass;
- }
-
- VkFramebuffer GetFramebuffer() const
- {
- return framebuffers[instance.GetFlightIndex()];
- }
-
- const ColorAttachment& GetColorAttachment() const
- {
- return *colorAttachment;
- }
-
- uint32_t GetWidth() const
- {
- return width;
- }
-
- uint32_t GetHeight() const
- {
- return height;
- }
+ VkRenderPass GetRenderPass() const;
+ VkFramebuffer GetFramebuffer() const;
+ const ColorAttachment& GetColorAttachment() const;
+ uint32_t GetWidth() const;
+ uint32_t GetHeight() const;
private:
-
- void InitializeImage()
- {
- colorAttachment = std::make_unique(instance, width, height);
- }
-
- void InitializeDepthBuffer()
- {
- depthAttachment = std::make_unique(instance, width, height);
- }
-
- void InitializeRenderPass()
- {
- VkAttachmentDescription colorAttachment{};
- colorAttachment.format = VK_FORMAT_R8G8B8A8_SRGB;
- colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
- colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-
- VkAttachmentDescription depthAttachment{};
- depthAttachment.format = Image::SelectDepthFormat(instance);
- depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
- depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
- VkAttachmentReference colorAttachmentRef{};
- colorAttachmentRef.attachment = 0;
- colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-
- VkAttachmentReference depthAttachmentRef{};
- depthAttachmentRef.attachment = 1;
- depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
- VkSubpassDescription subpass{};
- subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpass.colorAttachmentCount = 1;
- subpass.pColorAttachments = &colorAttachmentRef;
- subpass.pDepthStencilAttachment = &depthAttachmentRef;
-
- std::vector dependencies{2};
- dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
- dependencies[0].dstSubpass = 0;
- dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-
- dependencies[1].srcSubpass = 0;
- dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
- dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
-
- std::vector attachments{colorAttachment, depthAttachment};
- VkRenderPassCreateInfo renderPassCreateInfo{};
- renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
- renderPassCreateInfo.attachmentCount = attachments.size();
- renderPassCreateInfo.pAttachments = attachments.data();
- renderPassCreateInfo.subpassCount = 1;
- renderPassCreateInfo.pSubpasses = &subpass;
- renderPassCreateInfo.dependencyCount = dependencies.size();
- renderPassCreateInfo.pDependencies = dependencies.data();
-
- CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass");
- }
-
- void InitializeFramebuffers()
- {
- framebuffers.resize(instance.GetMaxFramesInFlight());
-
- for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i)
- {
- std::vector attachments{colorAttachment->GetImageView(i), depthAttachment->GetImageView()};
-
- VkFramebufferCreateInfo createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
- createInfo.renderPass = renderPass;
- createInfo.attachmentCount = attachments.size();
- createInfo.pAttachments = attachments.data();
- createInfo.width = width;
- createInfo.height = height;
- createInfo.layers = 1;
-
- CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize framebuffer");
- }
- }
+ void InitializeImage();
+ void InitializeDepthBuffer();
+ void InitializeRenderPass();
+ void InitializeFramebuffers();
};
}
\ No newline at end of file
diff --git a/Vulkan/src/Image.cpp b/Vulkan/src/Image.cpp
new file mode 100644
index 0000000..b8f93b3
--- /dev/null
+++ b/Vulkan/src/Image.cpp
@@ -0,0 +1,177 @@
+#include "Image.h"
+
+#include "CommandBufferScoped.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)
+ {
+ VkImageCreateInfo createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ createInfo.imageType = VK_IMAGE_TYPE_2D;
+ createInfo.extent.width = width;
+ createInfo.extent.height = height;
+ createInfo.extent.depth = 1;
+ createInfo.mipLevels = 1;
+ createInfo.arrayLayers = 1;
+ createInfo.format = format;
+ createInfo.tiling = tiling;
+ createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ createInfo.usage = usage;
+ createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ createInfo.flags = 0;
+
+ CP_VK_ASSERT(vkCreateImage(instance.GetDevice(), &createInfo, nullptr, image), "InitializeImage : Failed to initialize image");
+
+ VkMemoryRequirements memoryRequirements;
+ vkGetImageMemoryRequirements(instance.GetDevice(), *image, &memoryRequirements);
+
+ VkMemoryAllocateInfo allocateInfo{};
+ allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ allocateInfo.allocationSize = memoryRequirements.size;
+ allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties);
+
+ CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, imageMemory), "InitializeImage : Failed to initiallizse image memory");
+
+ vkBindImageMemory(instance.GetDevice(), *image, *imageMemory, 0);
+ }
+
+ VkImageView Image::InitializeImageView(Instance& instance, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags)
+ {
+ VkImageView imageView;
+ VkImageViewCreateInfo createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ createInfo.image = image;
+ createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ createInfo.format = format;
+ createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+ createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+ createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+ createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+ createInfo.subresourceRange.aspectMask = aspectFlags;
+ createInfo.subresourceRange.baseMipLevel = 0;
+ 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");
+ return imageView;
+ }
+
+ void Image::TransitionImageLayout(Instance& instance, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout)
+ {
+ CommandBufferScoped commandBuffer{instance};
+
+ VkImageMemoryBarrier barrier{};
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.oldLayout = oldLayout;
+ barrier.newLayout = newLayout;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = image;
+ barrier.subresourceRange.baseMipLevel = 0;
+ barrier.subresourceRange.levelCount = 1;
+ barrier.subresourceRange.baseArrayLayer = 0;
+ barrier.subresourceRange.layerCount = 1;
+ barrier.srcAccessMask = 0;
+ barrier.dstAccessMask = 0;
+
+ VkPipelineStageFlags srcStage;
+ VkPipelineStageFlags dstStage;
+
+ if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
+ barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+
+ if (HasStencilComponent(format)) {
+ barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+ }
+ else {
+ barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+
+ if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
+ barrier.srcAccessMask = 0;
+ barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+
+ srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ }
+ else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
+ barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+
+ srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ }
+ else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
+ barrier.srcAccessMask = 0;
+ barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+
+ srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
+ }
+ else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+ barrier.srcAccessMask = 0;
+ barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+
+ srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ dstStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ }
+ else
+ {
+ CP_ABORT("TransitioinImageLayout : Unsupported layout transition");
+ }
+
+ 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)
+ {
+ CommandBufferScoped commandBuffer{instance};
+
+ VkBufferImageCopy region{};
+ region.bufferOffset = 0;
+ region.bufferRowLength = 0;
+ region.bufferImageHeight = 0;
+
+ region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ region.imageSubresource.mipLevel = 0;
+ region.imageSubresource.baseArrayLayer = 0;
+ region.imageSubresource.layerCount = 1;
+
+ region.imageOffset = {0, 0, 0};
+ region.imageExtent = {width, height, 1};
+
+ vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
+ }
+
+
+ VkFormat Image::SelectDepthFormat(Instance& instance)
+ {
+ 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);
+ }
+
+ bool Image::HasStencilComponent(VkFormat format)
+ {
+ 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)
+ {
+ for (VkFormat format : candidates)
+ {
+ VkFormatProperties properties;
+ vkGetPhysicalDeviceFormatProperties(instance.GetPhysicalDevice(), format, &properties);
+ if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
+ {
+ return format;
+ }
+ else if (tiling == VK_IMAGE_TILING_OPTIMAL && (properties.optimalTilingFeatures & features) == features)
+ {
+ return format;
+ }
+ }
+ CP_ABORT("SelectSupportedFormat : Failed to select supported format");
+ }
+}
diff --git a/Vulkan/src/Image.h b/Vulkan/src/Image.h
index 1aa669e..e78b57f 100644
--- a/Vulkan/src/Image.h
+++ b/Vulkan/src/Image.h
@@ -1,187 +1,25 @@
#pragma once
-#include
#include "Buffer.h"
#include "Common.h"
-#include "CommandBufferScoped.h"
#include "Instance.h"
+#include
+
namespace Copium
{
class Image
{
- Image() = delete;
+ 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)
- {
- VkImageCreateInfo createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
- createInfo.imageType = VK_IMAGE_TYPE_2D;
- createInfo.extent.width = width;
- createInfo.extent.height = height;
- createInfo.extent.depth = 1;
- createInfo.mipLevels = 1;
- createInfo.arrayLayers = 1;
- createInfo.format = format;
- createInfo.tiling = tiling;
- createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- createInfo.usage = usage;
- createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
- createInfo.flags = 0;
-
- CP_VK_ASSERT(vkCreateImage(instance.GetDevice(), &createInfo, nullptr, image), "InitializeImage : Failed to initialize image");
-
- VkMemoryRequirements memoryRequirements;
- vkGetImageMemoryRequirements(instance.GetDevice(), *image, &memoryRequirements);
-
- VkMemoryAllocateInfo allocateInfo{};
- allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- allocateInfo.allocationSize = memoryRequirements.size;
- allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties);
-
- CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, imageMemory), "InitializeImage : Failed to initiallizse image memory");
-
- vkBindImageMemory(instance.GetDevice(), *image, *imageMemory, 0);
- }
-
- static VkImageView InitializeImageView(Instance& instance, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags)
- {
- VkImageView imageView;
- VkImageViewCreateInfo createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- createInfo.image = image;
- createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
- createInfo.format = format;
- createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
- createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
- createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
- createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
- createInfo.subresourceRange.aspectMask = aspectFlags;
- createInfo.subresourceRange.baseMipLevel = 0;
- 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");
- return imageView;
- }
-
- static void TransitionImageLayout(Instance& instance, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout)
- {
- CommandBufferScoped commandBuffer{instance};
-
- VkImageMemoryBarrier barrier{};
- barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- barrier.oldLayout = oldLayout;
- barrier.newLayout = newLayout;
- barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- barrier.image = image;
- barrier.subresourceRange.baseMipLevel = 0;
- barrier.subresourceRange.levelCount = 1;
- barrier.subresourceRange.baseArrayLayer = 0;
- barrier.subresourceRange.layerCount = 1;
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = 0;
-
- VkPipelineStageFlags srcStage;
- VkPipelineStageFlags dstStage;
-
- if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
-
- if (HasStencilComponent(format)) {
- barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
- }
- }
- else {
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- }
-
- if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-
- srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
-
- srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-
- srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-
- srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- dstStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- }
- else
- {
- CP_ABORT("TransitioinImageLayout : Unsupported layout transition");
- }
-
- vkCmdPipelineBarrier(commandBuffer, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
- }
-
- static void CopyBufferToImage(Instance& instance, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height)
- {
- CommandBufferScoped commandBuffer{instance};
-
- VkBufferImageCopy region{};
- region.bufferOffset = 0;
- region.bufferRowLength = 0;
- region.bufferImageHeight = 0;
-
- region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.imageSubresource.mipLevel = 0;
- region.imageSubresource.baseArrayLayer = 0;
- region.imageSubresource.layerCount = 1;
-
- region.imageOffset = {0, 0, 0};
- region.imageExtent = {width, height, 1};
-
- vkCmdCopyBufferToImage(commandBuffer, buffer.GetHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
- }
-
-
- static VkFormat SelectDepthFormat(Instance& instance)
- {
- 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);
- }
+ 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);
private:
- static bool HasStencilComponent(VkFormat format)
- {
- return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
- }
-
- static VkFormat SelectSupportedFormat(Instance& instance, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
- {
- for (VkFormat format : candidates)
- {
- VkFormatProperties properties;
- vkGetPhysicalDeviceFormatProperties(instance.GetPhysicalDevice(), format, &properties);
- if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
- {
- return format;
- }
- else if (tiling == VK_IMAGE_TILING_OPTIMAL && (properties.optimalTilingFeatures & features) == features)
- {
- return format;
- }
- }
- CP_ABORT("SelectSupportedFormat : Failed to select supported format");
- }
+ static bool HasStencilComponent(VkFormat format);
+ static VkFormat SelectSupportedFormat(Instance& instance, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
};
}
\ No newline at end of file
diff --git a/Vulkan/src/IndexBuffer.cpp b/Vulkan/src/IndexBuffer.cpp
new file mode 100644
index 0000000..d90d4a0
--- /dev/null
+++ b/Vulkan/src/IndexBuffer.cpp
@@ -0,0 +1,23 @@
+#include "IndexBuffer.h"
+
+#include "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},
+ indexCount{indexCount}
+ {}
+
+ void IndexBuffer::Bind(const CommandBuffer& commandBuffer)
+ {
+ vkCmdBindIndexBuffer(commandBuffer, handle, 0, VK_INDEX_TYPE_UINT16);
+ }
+
+ void IndexBuffer::Draw(const CommandBuffer& commandBuffer)
+ {
+ vkCmdDrawIndexed(commandBuffer, indexCount, 1, 0, 0, 0);
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/IndexBuffer.h b/Vulkan/src/IndexBuffer.h
index 0fcbced..08e9bbe 100644
--- a/Vulkan/src/IndexBuffer.h
+++ b/Vulkan/src/IndexBuffer.h
@@ -1,27 +1,20 @@
#pragma once
#include "Buffer.h"
+#include "Common.h"
+#include "Instance.h"
namespace Copium
{
- class IndexBuffer : public Buffer
+ class IndexBuffer final : public Buffer
{
CP_DELETE_COPY_AND_MOVE_CTOR(IndexBuffer);
private:
int indexCount;
public:
- 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}, indexCount{indexCount}
- {}
+ IndexBuffer(Instance& instance, int indexCount);
- void Bind(const CommandBuffer& commandBuffer) override
- {
- vkCmdBindIndexBuffer(commandBuffer, handle, 0, VK_INDEX_TYPE_UINT16);
- }
-
- void Draw(const CommandBuffer& commandBuffer)
- {
- vkCmdDrawIndexed(commandBuffer, indexCount, 1, 0, 0, 0);
- }
+ void Bind(const CommandBuffer& commandBuffer);
+ void Draw(const CommandBuffer& commandBuffer);
};
}
\ No newline at end of file
diff --git a/Vulkan/src/Instance.cpp b/Vulkan/src/Instance.cpp
new file mode 100644
index 0000000..2c4426b
--- /dev/null
+++ b/Vulkan/src/Instance.cpp
@@ -0,0 +1,408 @@
+#include "Instance.h"
+
+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");
+ }
+
+ VkInstance Instance::GetInstance() const
+ {
+ return instance;
+ }
+
+ 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");
+ }
+
+ 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{};
+ appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ appInfo.pApplicationName = applicationName.c_str();
+ appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
+ appInfo.pEngineName = "Copium Engine";
+ appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
+ appInfo.apiVersion = VK_API_VERSION_1_1;
+
+ std::vector requiredExtensions = GetRequiredExtensions();
+
+ uint32_t extensionCount;
+ vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
+ std::vector extensions{extensionCount};
+ vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
+
+ CP_INFO("InitiaizeInstace : Supported Extensions:");
+ for (auto&& extension : extensions)
+ {
+ CP_INFO_CONT("\t%s", extension.extensionName);
+ }
+
+ std::vector layers{};
+ DebugMessenger::AddRequiredLayers(&layers);
+ CP_ASSERT(CheckLayerSupport(layers), "InitializeInstance : Some required layers are not supported");
+
+ VkInstanceCreateInfo createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ createInfo.pApplicationInfo = &appInfo;
+ createInfo.enabledExtensionCount = requiredExtensions.size();
+ createInfo.ppEnabledExtensionNames = requiredExtensions.data();
+ createInfo.enabledLayerCount = layers.size();
+ createInfo.ppEnabledLayerNames = layers.data();
+ CP_VK_ASSERT(vkCreateInstance(&createInfo, nullptr, &instance), "InitializeInstance : Failed to create instance");
+ }
+
+ void Instance::InitializeDebugMessenger()
+ {
+ debugMessenger = std::make_unique(instance);
+ }
+
+ 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;
+ const char** glfwExtensions;
+ glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
+
+ std::vector extensions{glfwExtensions, glfwExtensions + glfwExtensionCount};
+
+ debugMessenger->AddRequiredExtensions(&extensions);
+
+ return extensions;
+ }
+
+ bool Instance::CheckLayerSupport(const std::vector& layers)
+ {
+ uint32_t layerCount;
+ vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
+
+ std::vector availableLayers(layerCount);
+ vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
+
+ CP_INFO("CheckLayerSupport : Supported Layers:");
+ for (auto&& availableLayer : availableLayers)
+ {
+ CP_INFO_CONT("\t%s", availableLayer.layerName);
+ }
+
+ for (auto&& layer : layers)
+ {
+ bool layerFound = false;
+ for (auto&& availableLayer : availableLayers)
+ {
+ if (std::strcmp(layer, availableLayer.layerName) == 0)
+ {
+ layerFound = true;
+ break;
+ }
+ }
+ if (!layerFound)
+ return false;
+ }
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/Instance.h b/Vulkan/src/Instance.h
index d42e944..4d241bd 100644
--- a/Vulkan/src/Instance.h
+++ b/Vulkan/src/Instance.h
@@ -41,410 +41,40 @@ namespace Copium
Timer timer;
public:
- 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()
- {
- 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 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 EndPresent()
- {
- swapChain->EndPresent(presentQueue, &renderFinishedSemaphores[flightIndex], framebufferResized);
-
- framebufferResized = false;
- flightIndex = (flightIndex + 1) % MAX_FRAMES_IN_FLIGHT;
- return !glfwWindowShouldClose(window);
- }
-
- void 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");
- }
-
- VkInstance GetInstance() const
- {
- return instance;
- }
-
- GLFWwindow* GetWindow() const
- {
- return window;
- }
-
- VkSurfaceKHR GetSurface() const
- {
- return surface;
- }
-
- VkPhysicalDevice GetPhysicalDevice() const
- {
- return physicalDevice;
- }
-
- VkDevice GetDevice() const
- {
- return device;
- }
-
- VkCommandPool GetCommandPool() const
- {
- return commandPool;
- }
-
- VkQueue GetGraphicsQueue() const
- {
- return graphicsQueue;
- }
-
- int GetFlightIndex() const
- {
- return flightIndex;
- }
-
- int GetMaxFramesInFlight() const
- {
- return MAX_FRAMES_IN_FLIGHT;
- }
-
- const SwapChain& GetSwapChain() const
- {
- return *swapChain;
- }
-
+ Instance(const std::string& applicationName);
+ ~Instance();
+ bool BeginPresent();
+ bool EndPresent();
+ void SubmitGraphicsQueue(const std::vector& commandBuffers);
+ VkInstance GetInstance() const;
+ 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)
- {
- 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");
- }
+ uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
private:
- void InitializeWindow(const std::string& applicationName)
- {
- glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+ 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);
-
-#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 InitializeInstance(const std::string& applicationName)
- {
- VkApplicationInfo appInfo{};
- appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
- appInfo.pApplicationName = applicationName.c_str();
- appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
- appInfo.pEngineName = "Copium Engine";
- appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
- appInfo.apiVersion = VK_API_VERSION_1_1;
-
- std::vector requiredExtensions = GetRequiredExtensions();
-
- uint32_t extensionCount;
- vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
- std::vector extensions{extensionCount};
- vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
-
- CP_INFO("InitiaizeInstace : Supported Extensions:");
- for (auto&& extension : extensions)
- {
- CP_INFO_CONT("\t%s", extension.extensionName);
- }
-
- std::vector layers{};
- DebugMessenger::AddRequiredLayers(&layers);
- CP_ASSERT(CheckLayerSupport(layers), "InitializeInstance : Some required layers are not supported");
-
- VkInstanceCreateInfo createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
- createInfo.pApplicationInfo = &appInfo;
- createInfo.enabledExtensionCount = requiredExtensions.size();
- createInfo.ppEnabledExtensionNames = requiredExtensions.data();
- createInfo.enabledLayerCount = layers.size();
- createInfo.ppEnabledLayerNames = layers.data();
- CP_VK_ASSERT(vkCreateInstance(&createInfo, nullptr, &instance), "InitializeInstance : Failed to create instance");
- }
-
- void InitializeDebugMessenger()
- {
- debugMessenger = std::make_unique(instance);
- }
-
- void InitializeSurface()
- {
- CP_VK_ASSERT(glfwCreateWindowSurface(instance, window, nullptr, &surface), "InitializeSurface : Failed to create Vulkan surface");
- }
-
- void 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 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 InitializeSwapChain()
- {
- swapChain = std::make_unique(*this);
- }
-
- void 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 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 GetRequiredExtensions()
- {
- uint32_t glfwExtensionCount;
- const char** glfwExtensions;
- glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
-
- std::vector extensions{glfwExtensions, glfwExtensions + glfwExtensionCount};
-
- debugMessenger->AddRequiredExtensions(&extensions);
-
- return extensions;
- }
-
- bool CheckLayerSupport(const std::vector& layers)
- {
- uint32_t layerCount;
- vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
-
- std::vector availableLayers(layerCount);
- vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
-
- CP_INFO("CheckLayerSupport : Supported Layers:");
- for (auto&& availableLayer : availableLayers)
- {
- CP_INFO_CONT("\t%s", availableLayer.layerName);
- }
-
- for (auto&& layer : layers)
- {
- bool layerFound = false;
- for (auto&& availableLayer : availableLayers)
- {
- if (std::strcmp(layer, availableLayer.layerName) == 0)
- {
- layerFound = true;
- break;
- }
- }
- if (!layerFound)
- return false;
- }
- return true;
- }
-
- bool 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 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 GetRequiredDeviceExtensions()
- {
- return {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
- }
-
- static void FramebufferResizeCallback(GLFWwindow* window, int width, int height)
- {
- Instance* instance = static_cast(glfwGetWindowUserPointer(window));
- instance->framebufferResized = true;
- }
};
}
diff --git a/Vulkan/src/Pipeline.cpp b/Vulkan/src/Pipeline.cpp
new file mode 100644
index 0000000..c832052
--- /dev/null
+++ b/Vulkan/src/Pipeline.cpp
@@ -0,0 +1,209 @@
+#include "Pipeline.h"
+
+#include "FileSystem.h"
+#include "Shader.h"
+
+namespace Copium
+{
+ Pipeline::Pipeline(Instance& instance, PipelineCreator creator)
+ : instance{instance}
+ {
+ InitializeDescriptorSetLayout(creator);
+ InitializePipeline(creator);
+ }
+
+ Pipeline::~Pipeline()
+ {
+ vkDestroyPipeline(instance.GetDevice(), graphicsPipeline, nullptr);
+ vkDestroyPipelineLayout(instance.GetDevice(), pipelineLayout, nullptr);
+ for (auto&& descriptorSetLayout : descriptorSetLayouts)
+ {
+ vkDestroyDescriptorSetLayout(instance.GetDevice(), descriptorSetLayout, nullptr);
+ }
+ }
+
+ void Pipeline::Bind(const CommandBuffer& commandBuffer)
+ {
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
+ }
+
+ void Pipeline::SetDescriptorSet(uint32_t setIndex, const DescriptorSet& descriptorSet)
+ {
+ CP_ASSERT(setIndex < boundDescriptorSets.size(), "SetDescriptorSet : DescriptorSet index is out of bounds");
+ boundDescriptorSets[setIndex] = descriptorSet;
+ }
+
+ void Pipeline::BindDescriptorSets(const CommandBuffer& commandBuffer)
+ {
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, boundDescriptorSets.size(), boundDescriptorSets.data(), 0, nullptr);
+ }
+
+ VkDescriptorSetLayout Pipeline::GetDescriptorSetLayout(uint32_t setIndex) const
+ {
+ return descriptorSetLayouts[setIndex];
+ }
+
+ void Pipeline::InitializeDescriptorSetLayout(const PipelineCreator& creator)
+ {
+ boundDescriptorSets.resize(creator.descriptorSetLayouts.size());
+ descriptorSetLayouts.resize(creator.descriptorSetLayouts.size());
+ int i = 0;
+ for (auto&& bindings : creator.descriptorSetLayouts)
+ {
+ std::vector layoutBindings{bindings.second.size()};
+ int j = 0;
+ for (auto&& binding : bindings.second)
+ {
+ layoutBindings[j].binding = binding.binding;
+ layoutBindings[j].descriptorType = binding.type;
+ layoutBindings[j].descriptorCount = binding.count;
+ layoutBindings[j].stageFlags = binding.flags;
+ layoutBindings[j].pImmutableSamplers = nullptr;
+ j++;
+ }
+
+ VkDescriptorSetLayoutCreateInfo createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ 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");
+ }
+ }
+
+ void Pipeline::InitializePipeline(const PipelineCreator& creator)
+ {
+ Shader shader{instance, Shader::Type::GlslFile, creator.vertexShader, creator.fragmentShader};
+
+ VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo{};
+ vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+ vertexInputCreateInfo.vertexBindingDescriptionCount = creator.vertexDescriptor.GetBindings().size();
+ vertexInputCreateInfo.pVertexBindingDescriptions = creator.vertexDescriptor.GetBindings().data();
+ vertexInputCreateInfo.vertexAttributeDescriptionCount = creator.vertexDescriptor.GetAttributes().size();
+ vertexInputCreateInfo.pVertexAttributeDescriptions = creator.vertexDescriptor.GetAttributes().data();
+
+ VkPipelineInputAssemblyStateCreateInfo inputAssemblyCreateInfo{};
+ inputAssemblyCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+ inputAssemblyCreateInfo.topology = creator.topology;
+ inputAssemblyCreateInfo.primitiveRestartEnable = VK_FALSE;
+
+ VkViewport viewport{};
+ viewport.x = 0;
+ viewport.y = 0;
+ viewport.width = 1;
+ viewport.height = 1;
+ viewport.minDepth = 0.0f;
+ viewport.maxDepth = 1.0f;
+
+ VkRect2D scissor{};
+ scissor.offset = {0, 0};
+ scissor.extent = {1, 1};
+
+ std::vector dynamicStates = {
+ VK_DYNAMIC_STATE_VIEWPORT,
+ VK_DYNAMIC_STATE_SCISSOR
+ };
+
+ VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo{};
+ dynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+ dynamicStateCreateInfo.dynamicStateCount = dynamicStates.size();
+ dynamicStateCreateInfo.pDynamicStates = dynamicStates.data();
+
+ VkPipelineViewportStateCreateInfo viewportStateCreateInfo{};
+ viewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+ viewportStateCreateInfo.viewportCount = 1;
+ viewportStateCreateInfo.pViewports = &viewport;
+ viewportStateCreateInfo.scissorCount = 1;
+ viewportStateCreateInfo.pScissors = &scissor;
+
+ VkPipelineRasterizationStateCreateInfo rasterizerCreateInfo{};
+ rasterizerCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+ rasterizerCreateInfo.depthClampEnable = VK_FALSE;
+ rasterizerCreateInfo.rasterizerDiscardEnable = VK_FALSE;
+ rasterizerCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;
+ rasterizerCreateInfo.lineWidth = 1.0f;
+ rasterizerCreateInfo.cullMode = creator.cullMode;
+ rasterizerCreateInfo.frontFace = creator.frontFace;
+
+ rasterizerCreateInfo.depthBiasEnable = VK_FALSE;
+ rasterizerCreateInfo.depthBiasConstantFactor = 0.0f;
+ rasterizerCreateInfo.depthBiasClamp = 0.0f;
+ rasterizerCreateInfo.depthBiasSlopeFactor = 0.0f;
+
+ VkPipelineMultisampleStateCreateInfo multisampleCreateInfo{};
+ multisampleCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+ multisampleCreateInfo.sampleShadingEnable = VK_FALSE;
+ multisampleCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+ multisampleCreateInfo.minSampleShading = 1.0f;
+ multisampleCreateInfo.pSampleMask = nullptr;
+ multisampleCreateInfo.alphaToCoverageEnable = VK_FALSE;
+ multisampleCreateInfo.alphaToOneEnable = VK_FALSE;
+
+ VkPipelineDepthStencilStateCreateInfo depthStencilCreateInfo{};
+ depthStencilCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+ depthStencilCreateInfo.depthTestEnable = VK_TRUE;
+ depthStencilCreateInfo.depthWriteEnable = VK_TRUE;
+ depthStencilCreateInfo.depthCompareOp = VK_COMPARE_OP_LESS;
+ depthStencilCreateInfo.depthBoundsTestEnable = VK_FALSE;
+ depthStencilCreateInfo.minDepthBounds = 0.0f;
+ depthStencilCreateInfo.maxDepthBounds = 1.0f;
+ depthStencilCreateInfo.stencilTestEnable = VK_FALSE;
+ depthStencilCreateInfo.front = {};
+ depthStencilCreateInfo.back = {};
+
+
+ VkPipelineColorBlendAttachmentState colorBlendAttachment{}; // TODO: Add to PipelineCreator
+ colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
+ VK_COLOR_COMPONENT_G_BIT |
+ VK_COLOR_COMPONENT_B_BIT |
+ VK_COLOR_COMPONENT_A_BIT;
+ colorBlendAttachment.blendEnable = VK_FALSE;
+ colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
+ colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
+ colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
+ colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
+ colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
+ colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
+
+ VkPipelineColorBlendStateCreateInfo colorBlendCreateInfo{};
+ colorBlendCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+ colorBlendCreateInfo.logicOpEnable = VK_FALSE;
+ colorBlendCreateInfo.logicOp = VK_LOGIC_OP_COPY;
+ colorBlendCreateInfo.attachmentCount = 1;
+ colorBlendCreateInfo.pAttachments = &colorBlendAttachment;
+ colorBlendCreateInfo.blendConstants[0] = 0.0f;
+ colorBlendCreateInfo.blendConstants[1] = 0.0f;
+ colorBlendCreateInfo.blendConstants[2] = 0.0f;
+ colorBlendCreateInfo.blendConstants[3] = 0.0f;
+
+ VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{};
+ pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+ pipelineLayoutCreateInfo.setLayoutCount = descriptorSetLayouts.size();
+ pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayouts.data();
+ pipelineLayoutCreateInfo.pushConstantRangeCount = 0;
+ pipelineLayoutCreateInfo.pPushConstantRanges = nullptr;
+
+ CP_VK_ASSERT(vkCreatePipelineLayout(instance.GetDevice(), &pipelineLayoutCreateInfo, nullptr, &pipelineLayout), "InitializePipeline : Failed to initialize pipeline layout");
+
+ const std::vector& shaderStages = shader.GetShaderStages();
+ VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo{};
+ graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+ graphicsPipelineCreateInfo.stageCount = shaderStages.size();
+ graphicsPipelineCreateInfo.pStages = shaderStages.data();
+ graphicsPipelineCreateInfo.pVertexInputState = &vertexInputCreateInfo;
+ graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyCreateInfo;
+ graphicsPipelineCreateInfo.pViewportState = &viewportStateCreateInfo;
+ graphicsPipelineCreateInfo.pRasterizationState = &rasterizerCreateInfo;
+ graphicsPipelineCreateInfo.pMultisampleState = &multisampleCreateInfo;
+ graphicsPipelineCreateInfo.pDepthStencilState = &depthStencilCreateInfo;
+ graphicsPipelineCreateInfo.pColorBlendState = &colorBlendCreateInfo;
+ graphicsPipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo;
+ graphicsPipelineCreateInfo.layout = pipelineLayout;
+ graphicsPipelineCreateInfo.renderPass = creator.renderPass;
+ graphicsPipelineCreateInfo.subpass = 0;
+ 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");
+ }
+}
\ No newline at end of file
diff --git a/Vulkan/src/Pipeline.h b/Vulkan/src/Pipeline.h
index 6b9f060..9691fd4 100644
--- a/Vulkan/src/Pipeline.h
+++ b/Vulkan/src/Pipeline.h
@@ -1,19 +1,17 @@
#pragma once
-#include "Common.h"
#include "CommandBuffer.h"
-#include "Instance.h"
-#include "FileSystem.h"
+#include "Common.h"
#include "DescriptorSet.h"
+#include "Instance.h"
#include "PipelineCreator.h"
-#include "Shader.h"
+#include
#include
-#include