diff --git a/Vulkan/Vulkan.vcxproj b/Vulkan/Vulkan.vcxproj
index d5c896f..08b5691 100644
--- a/Vulkan/Vulkan.vcxproj
+++ b/Vulkan/Vulkan.vcxproj
@@ -168,6 +168,9 @@
+
+
+
@@ -180,6 +183,7 @@
+
diff --git a/Vulkan/Vulkan.vcxproj.filters b/Vulkan/Vulkan.vcxproj.filters
index be9d5e2..6674aa3 100644
--- a/Vulkan/Vulkan.vcxproj.filters
+++ b/Vulkan/Vulkan.vcxproj.filters
@@ -24,6 +24,9 @@
Source Files
+
+ Source Files
+
diff --git a/Vulkan/res/shaders/passthrough.vert b/Vulkan/res/shaders/passthrough.vert
index 544e962..7ef441a 100644
--- a/Vulkan/res/shaders/passthrough.vert
+++ b/Vulkan/res/shaders/passthrough.vert
@@ -6,6 +6,6 @@ layout(location = 0) out vec2 fragTexCoord;
void main()
{
- gl_Position = vec4(inPosition* 0.5, 0.999, 1.0);
+ gl_Position = vec4(inPosition * 0.5, 0.999, 1.0);
fragTexCoord = inPosition * 0.5 + 0.5;
}
\ No newline at end of file
diff --git a/Vulkan/src/Application.h b/Vulkan/src/Application.h
index 8ec7f40..02187c2 100644
--- a/Vulkan/src/Application.h
+++ b/Vulkan/src/Application.h
@@ -103,8 +103,15 @@ namespace Copium
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();
@@ -140,10 +147,10 @@ namespace Copium
descriptorSet = std::make_unique(*instance, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
descriptorSet->AddUniform(*shaderUniformBuffer, 0);
- descriptorSet->AddTexture2D(*texture2D, 1);
+ descriptorSet->AddSampler(*texture2D, 1);
descriptorSetPassthrough = std::make_unique(*instance, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
- descriptorSetPassthrough->AddTexture2D(framebuffer->GetTexture2D(), 0);
+ descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
}
void InitializeGraphicsPipeline()
@@ -188,11 +195,6 @@ namespace Copium
void RecordCommandBuffer()
{
commandBuffer->Begin();
- std::vector clearValues{2};
- clearValues[0].color = {{0.0f, 0.0f, 0.0f, 1.0f}};
- clearValues[1].depthStencil = {1.0f, 0};
-
-
framebuffer->Bind(*commandBuffer);
graphicsPipeline->Bind(*commandBuffer);
@@ -228,7 +230,7 @@ namespace Copium
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), instance->GetSwapChain().GetExtent().width / (float)instance->GetSwapChain().GetExtent().height, 0.1f, 10.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};
diff --git a/Vulkan/src/Buffer.h b/Vulkan/src/Buffer.h
index 99cdd9d..4d8fd83 100644
--- a/Vulkan/src/Buffer.h
+++ b/Vulkan/src/Buffer.h
@@ -30,7 +30,7 @@ namespace Copium
createInfo.usage = usage;
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- CP_VK_ASSERT(vkCreateBuffer(instance.GetDevice(), &createInfo, nullptr, &handle), "Failed to initialize buffer");
+ CP_VK_ASSERT(vkCreateBuffer(instance.GetDevice(), &createInfo, nullptr, &handle), "Buffer : Failed to initialize buffer");
VkMemoryRequirements memoryRequirements;
vkGetBufferMemoryRequirements(instance.GetDevice(), handle, &memoryRequirements);
@@ -40,7 +40,7 @@ namespace Copium
allocateInfo.allocationSize = memoryRequirements.size;
allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties);
- CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, &memory), "Failed to allocate buffer memory");
+ CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, &memory), "Buffer : Failed to allocate buffer memory");
vkBindBufferMemory(instance.GetDevice(), handle, memory, 0);
}
@@ -53,7 +53,7 @@ namespace Copium
void Update(void* indexData, int index)
{
- CP_ASSERT(index >= 0 && index < count, "index is outside of the buffer");
+ CP_ASSERT(index >= 0 && index < count, "Update : Index is outside of the buffer");
if (mappedData == nullptr)
{
@@ -89,14 +89,14 @@ namespace Copium
void* Map()
{
- CP_ASSERT(mappedData == nullptr, "Mapping an already mapped buffer");
+ 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, "Unmapping an already unmapped buffer");
+ CP_ASSERT(mappedData != nullptr, "Unmap : Unmapping an already unmapped buffer");
vkUnmapMemory(instance.GetDevice(), memory);
mappedData = nullptr;
@@ -128,7 +128,7 @@ namespace Copium
VkDeviceSize GetPosition(int index) const
{
- CP_ASSERT(index >= 0 && index < count, "index is outside of the buffer");
+ CP_ASSERT(index >= 0 && index < count, "GetPosition : Index is outside of the buffer");
return size * (VkDeviceSize)index;
}
@@ -142,7 +142,7 @@ namespace Copium
allocateInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer;
- CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, &commandBuffer), "Failed to initialize command buffer");
+ 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;
diff --git a/Vulkan/src/ColorAttachment.h b/Vulkan/src/ColorAttachment.h
new file mode 100644
index 0000000..dbebede
--- /dev/null
+++ b/Vulkan/src/ColorAttachment.h
@@ -0,0 +1,65 @@
+#pragma once
+
+#include "Common.h"
+#include "Instance.h"
+#include "Image.h"
+#include "Sampler.h"
+
+namespace Copium
+{
+ class ColorAttachment : public Sampler
+ {
+ CP_DELETE_COPY_AND_MOVE_CTOR(ColorAttachment);
+ private:
+ std::vector images;
+ std::vector imageMemories;
+ std::vector imageViews;
+ public:
+ ColorAttachment(Instance& instance, int width, int height)
+ : Sampler{instance}
+ {
+ InitializeColorAttachment(width, height);
+ }
+
+ ~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];
+ }
+
+ 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);
+ }
+ }
+ };
+}
diff --git a/Vulkan/src/CommandBuffer.h b/Vulkan/src/CommandBuffer.h
index b7aa988..f4a78dc 100644
--- a/Vulkan/src/CommandBuffer.h
+++ b/Vulkan/src/CommandBuffer.h
@@ -35,7 +35,7 @@ namespace Copium
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocateInfo.commandPool = instance.GetCommandPool();
allocateInfo.commandBufferCount = commandBuffers.size();
- CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, commandBuffers.data()), "Failed to allocate CommandBuffer");
+ CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, commandBuffers.data()), "CommandBuffer : Failed to allocate CommandBuffer");
}
~CommandBuffer()
@@ -65,11 +65,11 @@ namespace Copium
currentCommandBuffer = commandBuffers[instance.GetFlightIndex()];
break;
default:
- CP_WARN("Unhandled enum case: %d", (int)type);
+ CP_ABORT("Begin : Unreachable switch case");
}
vkResetCommandBuffer(currentCommandBuffer, 0);
- CP_VK_ASSERT(vkBeginCommandBuffer(currentCommandBuffer, &beginInfo), "Failed to begin command buffer");
+ CP_VK_ASSERT(vkBeginCommandBuffer(currentCommandBuffer, &beginInfo), "Begin : Failed to begin command buffer");
}
void End()
diff --git a/Vulkan/src/Common.h b/Vulkan/src/Common.h
index 7fd0759..881dafa 100644
--- a/Vulkan/src/Common.h
+++ b/Vulkan/src/Common.h
@@ -57,7 +57,7 @@ namespace Copium
std::string StringFormat(const std::string& format, Args... args)
{
int size = std::snprintf(nullptr, 0, format.c_str(), args...) + 1;
- CP_ASSERT(size > 0, "Error during formatting");
+ CP_ASSERT(size > 0, "StringFormat : Error during formatting");
std::unique_ptr buf(new char[size]);
std::snprintf(buf.get(), size, format.c_str(), args...);
return std::string(buf.get(), buf.get() + size - 1);
diff --git a/Vulkan/src/DebugMessenger.h b/Vulkan/src/DebugMessenger.h
index 7ec21b7..0156c95 100644
--- a/Vulkan/src/DebugMessenger.h
+++ b/Vulkan/src/DebugMessenger.h
@@ -25,7 +25,7 @@ namespace Copium
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
createInfo.pfnUserCallback = DebugCallback;
createInfo.pUserData = nullptr;
- CP_VK_ASSERT(vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger), "Failed to initialze debug messenger");
+ CP_VK_ASSERT(vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger), "DebugMessenger : Failed to initialze debug messenger");
#endif
}
@@ -59,11 +59,9 @@ namespace Copium
if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
{
if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
- {
- CP_ERR(pCallbackData->pMessage);
- throw VulkanException(pCallbackData->pMessage);
- }
- CP_WARN(pCallbackData->pMessage);
+ CP_ABORT("DebugCallback : %s", pCallbackData->pMessage);
+ else
+ CP_WARN("DebugCallback : %s", pCallbackData->pMessage);
}
return VK_FALSE;
}
diff --git a/Vulkan/src/DepthAttachment.h b/Vulkan/src/DepthAttachment.h
new file mode 100644
index 0000000..bc08d31
--- /dev/null
+++ b/Vulkan/src/DepthAttachment.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include "Common.h"
+#include "Instance.h"
+#include "Image.h"
+#include "Sampler.h"
+
+namespace Copium
+{
+ class DepthAttachment : public Sampler
+ {
+ CP_DELETE_COPY_AND_MOVE_CTOR(DepthAttachment);
+ private:
+ VkImage image;
+ VkDeviceMemory imageMemory;
+ VkImageView imageView;
+ public:
+ DepthAttachment(Instance& instance, int width, int height)
+ : Sampler{instance}
+ {
+ InitializeDepthAttachment(width, height);
+ }
+
+ ~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;
+ }
+
+ 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);
+ }
+ };
+}
diff --git a/Vulkan/src/DescriptorPool.h b/Vulkan/src/DescriptorPool.h
index 7ae6cbb..ea2ec78 100644
--- a/Vulkan/src/DescriptorPool.h
+++ b/Vulkan/src/DescriptorPool.h
@@ -32,7 +32,7 @@ namespace Copium
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), "Failed to initialize descriptor pool");
+ CP_VK_ASSERT(vkCreateDescriptorPool(instance.GetDevice(), &createInfo, nullptr, &descriptorPool), "DescriptorPool : Failed to initialize descriptor pool");
}
~DescriptorPool()
@@ -51,7 +51,7 @@ namespace Copium
allocateInfo.pSetLayouts = layouts.data();
descriptorSets.resize(instance.GetMaxFramesInFlight());
- CP_VK_ASSERT(vkAllocateDescriptorSets(instance.GetDevice(), &allocateInfo, descriptorSets.data()), "Failed to allocate descriptor sets");
+ CP_VK_ASSERT(vkAllocateDescriptorSets(instance.GetDevice(), &allocateInfo, descriptorSets.data()), "AllocateDescriptorSets : Failed to allocate descriptor sets");
return descriptorSets;
}
diff --git a/Vulkan/src/DescriptorSet.h b/Vulkan/src/DescriptorSet.h
index 075157f..b548a12 100644
--- a/Vulkan/src/DescriptorSet.h
+++ b/Vulkan/src/DescriptorSet.h
@@ -2,8 +2,9 @@
#include "Common.h"
#include "DescriptorPool.h"
-#include "Texture2D.h"
+#include "Sampler.h"
#include "UniformBuffer.h"
+
#include
namespace Copium
@@ -49,10 +50,10 @@ namespace Copium
}
}
- void AddTexture2D(const Texture2D& texture2D, uint32_t binding)
+ void AddSampler(const Sampler& sampler, uint32_t binding)
{
for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) {
- VkDescriptorImageInfo imageInfo = texture2D.GetDescriptorImageInfo(i);
+ VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(i);
VkWriteDescriptorSet descriptorWrite{};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = descriptorSets[i];
diff --git a/Vulkan/src/FileSystem.h b/Vulkan/src/FileSystem.h
index 305bbdb..11fb42a 100644
--- a/Vulkan/src/FileSystem.h
+++ b/Vulkan/src/FileSystem.h
@@ -1,12 +1,12 @@
#pragma once
-#include
-#include
-#include
#include "Common.h"
+#include
#include
+#include
+#include
namespace Copium
{
@@ -17,7 +17,7 @@ namespace Copium
static std::vector ReadFile(const std::string& filename)
{
std::ifstream file(filename, std::ios::ate | std::ios::binary);
- CP_ASSERT(file.is_open(), "Failed to open file");
+ CP_ASSERT(file.is_open(), "ReadFile : Failed to open file");
size_t fileSize = (size_t)file.tellg();
std::vector buffer(fileSize);
@@ -31,7 +31,7 @@ namespace Copium
static std::string ReadFileStr(const std::string& filename)
{
std::ifstream file(filename, std::ios::ate | std::ios::binary);
- CP_ASSERT(file.is_open(), "Failed to open file");
+ CP_ASSERT(file.is_open(), "ReadFileStr : Failed to open file");
size_t fileSize = (size_t)file.tellg();
std::string buffer;
@@ -45,8 +45,10 @@ namespace Copium
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(), "Failed to open file");
+ CP_ASSERT(file.is_open(), "WriteFile : Failed to open file");
file.write(data.c_str(), data.size());
}
@@ -56,7 +58,7 @@ namespace Copium
std::filesystem::path path{filename};
std::filesystem::create_directories(path.parent_path());
std::ofstream file(filename, std::ios::binary);
- CP_ASSERT(file.is_open(), "Failed to open file");
+ CP_ASSERT(file.is_open(), "WriteFile : Failed to open file");
file.write(data, size);
}
@@ -70,7 +72,7 @@ namespace Copium
static int64_t DateModified(const std::string& filename)
{
struct stat result;
- CP_ASSERT(stat(filename.c_str(), &result) == 0, "Cannot stat file %s", filename.c_str());
+ CP_ASSERT(stat(filename.c_str(), &result) == 0, "DataModified : Cannot stat file %s", filename.c_str());
return (int64_t)result.st_mtime;
}
};
diff --git a/Vulkan/src/Framebuffer.h b/Vulkan/src/Framebuffer.h
index f91943f..4c446c7 100644
--- a/Vulkan/src/Framebuffer.h
+++ b/Vulkan/src/Framebuffer.h
@@ -3,21 +3,21 @@
#include "Common.h"
#include "Image.h"
#include "Instance.h"
-#include "Texture2D.h"
+#include "ColorAttachment.h"
+#include "DepthAttachment.h"
#include
namespace Copium
{
- // TODO: Add resizing (recreate image, depthImage, framebuffers)
class Framebuffer
{
CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer);
private:
Instance& instance;
- std::unique_ptr image;
- std::unique_ptr depthImage;
+ std::unique_ptr colorAttachment;
+ std::unique_ptr depthAttachment;
std::vector framebuffers;
VkRenderPass renderPass;
@@ -27,7 +27,7 @@ namespace Copium
Framebuffer(Instance& instance, uint32_t width, uint32_t height)
: instance{instance}, width{width}, height{height}
{
- InitializeImages();
+ InitializeImage();
InitializeDepthBuffer();
InitializeRenderPass();
InitializeFramebuffers();
@@ -40,6 +40,20 @@ namespace Copium
vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
}
+ 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};
@@ -55,6 +69,19 @@ namespace Copium
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)
@@ -72,21 +99,31 @@ namespace Copium
return framebuffers[instance.GetFlightIndex()];
}
- const Texture2D& GetTexture2D() const
+ const ColorAttachment& GetColorAttachment() const
{
- return *image;
+ return *colorAttachment;
+ }
+
+ uint32_t GetWidth() const
+ {
+ return width;
+ }
+
+ uint32_t GetHeight() const
+ {
+ return height;
}
private:
- void InitializeImages()
+ void InitializeImage()
{
- image = std::make_unique(instance, width, height, Texture2D::Type::Dynamic, Texture2D::Format::Color);
+ colorAttachment = std::make_unique(instance, width, height);
}
void InitializeDepthBuffer()
{
- depthImage = std::make_unique(instance, width, height, Texture2D::Type::Static, Texture2D::Format::Depth);
+ depthAttachment = std::make_unique(instance, width, height);
}
void InitializeRenderPass()
@@ -159,7 +196,7 @@ namespace Copium
for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i)
{
- std::vector attachments{image->GetImageView(i), depthImage->GetImageView()};
+ std::vector attachments{colorAttachment->GetImageView(i), depthAttachment->GetImageView()};
VkFramebufferCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
@@ -170,7 +207,7 @@ namespace Copium
createInfo.height = height;
createInfo.layers = 1;
- CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize swap chain framebuffer");
+ CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize framebuffer");
}
}
};
diff --git a/Vulkan/src/Instance.h b/Vulkan/src/Instance.h
index 4c5dd34..d42e944 100644
--- a/Vulkan/src/Instance.h
+++ b/Vulkan/src/Instance.h
@@ -53,7 +53,7 @@ namespace Copium
InitializeCommandPool();
InitializeSwapChain();
InitializeSyncObjects();
- CP_INFO("Initialized Vulkan in %f seconds", timer.Elapsed());
+ CP_INFO("Instance : Initialized Vulkan in %f seconds", timer.Elapsed());
}
~Instance()
@@ -106,7 +106,7 @@ namespace Copium
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &renderFinishedSemaphores[flightIndex];
- CP_VK_ASSERT(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[flightIndex]), "Failed to submit command buffer");
+ CP_VK_ASSERT(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[flightIndex]), "SubmitGraphicsQueue : Failed to submit command buffer");
}
VkInstance GetInstance() const
@@ -169,7 +169,7 @@ namespace Copium
if ((typeFilter & (1 << i)) && (memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
return i;
}
- throw std::runtime_error("Failed to find suitable memory type");
+ CP_ABORT("FindMemoryType : Failed to find suitable memory type");
}
private:
@@ -190,7 +190,7 @@ namespace Copium
#else
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, applicationName.c_str(), nullptr, nullptr);
#endif
- CP_ASSERT(window, "Failed to initialize glfw window");
+ CP_ASSERT(window, "InitializeWindow : Failed to initialize glfw window");
glfwSetWindowUserPointer(window, this);
glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback);
@@ -213,7 +213,7 @@ namespace Copium
std::vector extensions{extensionCount};
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
- CP_INFO("Supported Extensions:");
+ CP_INFO("InitiaizeInstace : Supported Extensions:");
for (auto&& extension : extensions)
{
CP_INFO_CONT("\t%s", extension.extensionName);
@@ -221,7 +221,7 @@ namespace Copium
std::vector layers{};
DebugMessenger::AddRequiredLayers(&layers);
- CP_ASSERT(CheckLayerSupport(layers), "Some required layers are not supported");
+ CP_ASSERT(CheckLayerSupport(layers), "InitializeInstance : Some required layers are not supported");
VkInstanceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
@@ -230,7 +230,7 @@ namespace Copium
createInfo.ppEnabledExtensionNames = requiredExtensions.data();
createInfo.enabledLayerCount = layers.size();
createInfo.ppEnabledLayerNames = layers.data();
- CP_VK_ASSERT(vkCreateInstance(&createInfo, nullptr, &instance), "Failed to create instance");
+ CP_VK_ASSERT(vkCreateInstance(&createInfo, nullptr, &instance), "InitializeInstance : Failed to create instance");
}
void InitializeDebugMessenger()
@@ -240,18 +240,18 @@ namespace Copium
void InitializeSurface()
{
- CP_VK_ASSERT(glfwCreateWindowSurface(instance, window, nullptr, &surface), "Failed to create Vulkan surface");
+ 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, "No available devices support Vulkan");
+ CP_ASSERT(deviceCount != 0, "SelectPhysicaDevice : No available devices support Vulkan");
std::vector devices(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
- CP_INFO("Available devices:");
+ CP_INFO("SelectPhysicaDevice : Available devices:");
for (auto&& device : devices)
{
VkPhysicalDeviceProperties deviceProperties;
@@ -265,11 +265,11 @@ namespace Copium
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(device, &deviceProperties);
physicalDevice = device;
- CP_INFO("Selecting device: %s", deviceProperties.deviceName);
+ CP_INFO("SelectPhysicaDevice : Selecting device: %s", deviceProperties.deviceName);
break;
}
}
- CP_ASSERT(physicalDevice != VK_NULL_HANDLE, "Failed to find suitable GPU");
+ CP_ASSERT(physicalDevice != VK_NULL_HANDLE, "SelectPhysicaDevice : Failed to find suitable GPU");
}
void InitializeLogicalDevice()
@@ -301,7 +301,7 @@ namespace Copium
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
createInfo.enabledExtensionCount = deviceExtensions.size();
- CP_VK_ASSERT(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device), "Failed to initialize logical device");
+ CP_VK_ASSERT(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device), "InitializeLogicalDevice : Failed to initialize logical device");
graphicsQueueIndex = query.graphicsFamily.value();
presentQueueIndex = query.presentFamily.value();
@@ -320,7 +320,7 @@ namespace Copium
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), "Failed to initialize command pool");
+ CP_VK_ASSERT(vkCreateCommandPool(device, &createInfo, nullptr, &commandPool), "InitializeCommandPool : Failed to initialize command pool");
}
void InitializeSyncObjects()
@@ -332,14 +332,14 @@ namespace Copium
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]), "Failed to initialize available image semaphore");
- CP_VK_ASSERT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]), "Failed to initialize render finished semaphore");
+ 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]), "Failed to initialize in flight fence");
+ CP_VK_ASSERT(vkCreateFence(device, &fenceCreateInfo, nullptr, &inFlightFences[i]), "InitializeSyncObjects : Failed to initialize in flight fence");
}
}
@@ -364,7 +364,7 @@ namespace Copium
std::vector availableLayers(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
- CP_INFO("Supported Layers:");
+ CP_INFO("CheckLayerSupport : Supported Layers:");
for (auto&& availableLayer : availableLayers)
{
CP_INFO_CONT("\t%s", availableLayer.layerName);
diff --git a/Vulkan/src/Pipeline.h b/Vulkan/src/Pipeline.h
index 62cfe91..6b9f060 100644
--- a/Vulkan/src/Pipeline.h
+++ b/Vulkan/src/Pipeline.h
@@ -45,24 +45,11 @@ namespace Copium
void Bind(const CommandBuffer& commandBuffer)
{
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
-
- VkViewport viewport{};
- viewport.x = 0.0f;
- viewport.y = 0.0f;
- viewport.width = instance.GetSwapChain().GetExtent().width;
- viewport.height = instance.GetSwapChain().GetExtent().height;
- viewport.minDepth = 0.0f;
- viewport.maxDepth = 1.0f;
- vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
- VkRect2D scissor{};
- scissor.offset = {0, 0};
- scissor.extent = instance.GetSwapChain().GetExtent();
- vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
}
void SetDescriptorSet(uint32_t setIndex, const DescriptorSet& descriptorSet)
{
- CP_ASSERT(setIndex < boundDescriptorSets.size(), "DescriptorSet index is out of bounds");
+ CP_ASSERT(setIndex < boundDescriptorSets.size(), "SetDescriptorSet : DescriptorSet index is out of bounds");
boundDescriptorSets[setIndex] = descriptorSet.GetHandle();
}
@@ -101,7 +88,7 @@ namespace Copium
createInfo.bindingCount = layoutBindings.size();
createInfo.pBindings = layoutBindings.data();
- CP_VK_ASSERT(vkCreateDescriptorSetLayout(instance.GetDevice(), &createInfo, nullptr, &descriptorSetLayouts[i++]), "Failed to initialize descriptor set layout");
+ CP_VK_ASSERT(vkCreateDescriptorSetLayout(instance.GetDevice(), &createInfo, nullptr, &descriptorSetLayouts[i++]), "InitializeDescriptorSetLayout : Failed to initialize descriptor set layout");
}
}
@@ -124,14 +111,14 @@ namespace Copium
VkViewport viewport{};
viewport.x = 0;
viewport.y = 0;
- viewport.width = instance.GetSwapChain().GetExtent().width;
- viewport.height = instance.GetSwapChain().GetExtent().height;
+ viewport.width = 1;
+ viewport.height = 1;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
VkRect2D scissor{};
scissor.offset = {0, 0};
- scissor.extent = instance.GetSwapChain().GetExtent();
+ scissor.extent = {1, 1};
std::vector dynamicStates = {
VK_DYNAMIC_STATE_VIEWPORT,
@@ -217,7 +204,7 @@ namespace Copium
pipelineLayoutCreateInfo.pushConstantRangeCount = 0;
pipelineLayoutCreateInfo.pPushConstantRanges = nullptr;
- CP_VK_ASSERT(vkCreatePipelineLayout(instance.GetDevice(), &pipelineLayoutCreateInfo, nullptr, &pipelineLayout), "Failed to initialize pipeline layout");
+ CP_VK_ASSERT(vkCreatePipelineLayout(instance.GetDevice(), &pipelineLayoutCreateInfo, nullptr, &pipelineLayout), "InitializePipeline : Failed to initialize pipeline layout");
const std::vector& shaderStages = shader.GetShaderStages();
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo{};
@@ -238,21 +225,7 @@ namespace Copium
graphicsPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
graphicsPipelineCreateInfo.basePipelineIndex = -1;
- CP_VK_ASSERT(vkCreateGraphicsPipelines(instance.GetDevice(), VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &graphicsPipeline), "Failed to initialize graphics pipeline");
+ CP_VK_ASSERT(vkCreateGraphicsPipelines(instance.GetDevice(), VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &graphicsPipeline), "InitializePipeline : Failed to initialize graphics pipeline");
}
-
- VkShaderModule InitializeShaderModule(const std::vector& code)
- {
- VkShaderModuleCreateInfo createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
- createInfo.codeSize = code.size();
- createInfo.pCode = reinterpret_cast(code.data());
-
- VkShaderModule shaderModule;
- CP_VK_ASSERT(vkCreateShaderModule(instance.GetDevice(), &createInfo, nullptr, &shaderModule), "Failed to initialize shader module");
-
- return shaderModule;
- }
-
};
}
\ No newline at end of file
diff --git a/Vulkan/src/QueueFamilies.h b/Vulkan/src/QueueFamilies.h
index 1318891..66efa98 100644
--- a/Vulkan/src/QueueFamilies.h
+++ b/Vulkan/src/QueueFamilies.h
@@ -33,7 +33,6 @@ namespace Copium
}
i++;
}
-
}
bool AllRequiredFamiliesSupported()
diff --git a/Vulkan/src/Sampler.h b/Vulkan/src/Sampler.h
new file mode 100644
index 0000000..0ccf392
--- /dev/null
+++ b/Vulkan/src/Sampler.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "Common.h"
+#include "Instance.h"
+
+#include
+
+namespace Copium
+{
+ class Sampler
+ {
+ CP_DELETE_COPY_AND_MOVE_CTOR(Sampler);
+ protected:
+ Instance& instance;
+ VkSampler sampler;
+ public:
+ Sampler(Instance& instance)
+ : instance{instance}
+ {
+ InitializeSampler();
+ }
+
+ virtual ~Sampler()
+ {
+ vkDestroySampler(instance.GetDevice(), sampler, nullptr);
+ }
+
+ void InitializeSampler()
+ {
+ VkPhysicalDeviceProperties properties{};
+ vkGetPhysicalDeviceProperties(instance.GetPhysicalDevice(), &properties);
+
+ VkSamplerCreateInfo createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+ createInfo.magFilter = VK_FILTER_LINEAR;
+ createInfo.minFilter = VK_FILTER_LINEAR;
+ createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+ createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+ createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+ createInfo.anisotropyEnable = VK_TRUE;
+ createInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
+ createInfo.unnormalizedCoordinates = VK_FALSE;
+ createInfo.compareEnable = VK_FALSE;
+ createInfo.compareOp = VK_COMPARE_OP_ALWAYS;
+ createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
+ createInfo.mipLodBias = 0.0f;
+ createInfo.minLod = 0.0f;
+ createInfo.maxLod = 0.0f;
+
+ CP_VK_ASSERT(vkCreateSampler(instance.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler");
+ }
+
+ virtual VkDescriptorImageInfo GetDescriptorImageInfo(int index) const = 0;
+ };
+}
diff --git a/Vulkan/src/Shader.h b/Vulkan/src/Shader.h
index 430044c..04de51d 100644
--- a/Vulkan/src/Shader.h
+++ b/Vulkan/src/Shader.h
@@ -46,7 +46,7 @@ namespace Copium
fragShaderModule = InitializeShaderModule(FileSystem::ReadFile(fragmentInput));
break;
default:
- CP_ASSERT(false, "Unreachable switch case %d", (int)type);
+ CP_ASSERT(false, "Shader : Unreachable switch case %d", (int)type);
}
shaderStages.resize(2);
@@ -99,7 +99,7 @@ namespace Copium
{
if (FileSystem::DateModified(filename) < FileSystem::DateModified(spvFilename))
{
- CP_DEBUG("Loading cached shader file: %s", filename.c_str());
+ CP_DEBUG("InitializeShaderModuleFromGlslFile : Loading cached shader file: %s", filename.c_str());
std::vector data = FileSystem::ReadFile(spvFilename);
CP_ASSERT(data.size() % 4 == 0, "Spv data size is not a factor of 4");
return InitializeShaderModule((const uint32_t*)data.data(), data.size());
@@ -108,9 +108,9 @@ namespace Copium
}
catch (const std::runtime_error& e)
{
- CP_WARN("Cached shader file is invalid, recreating it");
+ CP_WARN("InitializeShaderModuleFromGlslFile : Cached shader file is invalid, recreating it");
}
- CP_DEBUG("Compiling shader file: %s", filename.c_str());
+ CP_DEBUG("InitializeShaderModuleFromGlslFile : Compiling shader file: %s", filename.c_str());
shaderc::Compiler compiler;
shaderc::CompileOptions options;
@@ -118,7 +118,7 @@ namespace Copium
std::vector glslCode = FileSystem::ReadFile(filename);
shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(glslCode.data(), glslCode.size(), type, filename.c_str(), options);
- CP_ASSERT(result.GetCompilationStatus() == shaderc_compilation_status_success, "Failed to compile shader: %s\n%s", filename.c_str(), result.GetErrorMessage().c_str());
+ CP_ASSERT(result.GetCompilationStatus() == shaderc_compilation_status_success, "InitializeShaderModuleFromGlslFile : Failed to compile shader: %s\n%s", filename.c_str(), result.GetErrorMessage().c_str());
std::vector data{result.cbegin(), result.cend()};
FileSystem::WriteFile(spvFilename, (const char*)data.data(), data.size() * sizeof(uint32_t));
@@ -133,7 +133,7 @@ namespace Copium
options.SetOptimizationLevel(shaderc_optimization_level_size);
shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(code.data(), type, "inline_shader_code", options);
- CP_ASSERT(result.GetCompilationStatus() == shaderc_compilation_status_success, "Failed to compile inline shader code: %s", result.GetErrorMessage());
+ CP_ASSERT(result.GetCompilationStatus() == shaderc_compilation_status_success, "InitializeShaderModuleFromGlslCode : Failed to compile inline shader code: %s", result.GetErrorMessage());
std::vector data{result.cbegin(), result.cend()};
return InitializeShaderModule(data.data(), data.size() * sizeof(uint32_t));
@@ -147,7 +147,7 @@ namespace Copium
createInfo.pCode = data;
VkShaderModule shaderModule;
- CP_VK_ASSERT(vkCreateShaderModule(instance.GetDevice(), &createInfo, nullptr, &shaderModule), "Failed to initialize shader module");
+ CP_VK_ASSERT(vkCreateShaderModule(instance.GetDevice(), &createInfo, nullptr, &shaderModule), "InitializeShaderModule : Failed to initialize shader module");
return shaderModule;
}
diff --git a/Vulkan/src/SwapChain.cpp b/Vulkan/src/SwapChain.cpp
index bda9332..0a5e873 100644
--- a/Vulkan/src/SwapChain.cpp
+++ b/Vulkan/src/SwapChain.cpp
@@ -1,345 +1,358 @@
#include "SwapChain.h"
#include "CommandBuffer.h"
+#include "DepthAttachment.h"
#include "Image.h"
#include "Instance.h"
#include "QueueFamilies.h"
-#include "Texture2D.h"
#include
-#include
#include
+#include
namespace Copium
{
- SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice)
- {
- vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities);
+ SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice)
+ {
+ vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities);
- uint32_t formatCount;
- vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, nullptr);
- if (formatCount != 0)
- {
- formats.resize(formatCount);
- vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, formats.data());
- }
+ uint32_t formatCount;
+ vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, nullptr);
+ if (formatCount != 0)
+ {
+ formats.resize(formatCount);
+ vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, formats.data());
+ }
- uint32_t presentModeCount;
- vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, nullptr);
- if (presentModeCount != 0)
- {
- presentModes.resize(presentModeCount);
- vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data());
- }
- }
+ uint32_t presentModeCount;
+ vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, nullptr);
+ if (presentModeCount != 0)
+ {
+ presentModes.resize(presentModeCount);
+ vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data());
+ }
+ }
- bool SwapChainSupportDetails::Valid()
- {
- return !formats.empty() && !presentModes.empty();
- }
+ bool SwapChainSupportDetails::Valid()
+ {
+ return !formats.empty() && !presentModes.empty();
+ }
- SwapChain::SwapChain(Instance& instance)
- : instance{instance}
- {
- Initialize();
- InitializeImageViews();
- InitializeDepthBuffer();
- InitializeRenderPass();
- InitializeFramebuffers();
- }
+ SwapChain::SwapChain(Instance& instance)
+ : instance{instance}
+ {
+ Initialize();
+ InitializeImageViews();
+ InitializeDepthAttachment();
+ InitializeRenderPass();
+ InitializeFramebuffers();
+ }
- SwapChain::~SwapChain()
- {
- Destroy();
- vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
- }
+ SwapChain::~SwapChain()
+ {
+ Destroy();
+ vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
+ }
- void SwapChain::BeginFrameBuffer(const CommandBuffer& commandBuffer) const
- {
- std::vector clearValues{2};
- clearValues[0].color = {{0.02f, 0.02f, 0.02f, 1.0f}};
- clearValues[1].depthStencil = {1.0f, 0};
+ void SwapChain::BeginFrameBuffer(const CommandBuffer& commandBuffer) const
+ {
+ std::vector clearValues{2};
+ clearValues[0].color = {{0.02f, 0.02f, 0.02f, 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[imageIndex];
- renderPassBeginInfo.renderArea.offset = {0, 0};
- renderPassBeginInfo.renderArea.extent = extent;
- renderPassBeginInfo.clearValueCount = clearValues.size();
- renderPassBeginInfo.pClearValues = clearValues.data();
- vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
- }
+ VkRenderPassBeginInfo renderPassBeginInfo{};
+ renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+ renderPassBeginInfo.renderPass = renderPass;
+ renderPassBeginInfo.framebuffer = framebuffers[imageIndex];
+ renderPassBeginInfo.renderArea.offset = {0, 0};
+ renderPassBeginInfo.renderArea.extent = extent;
+ renderPassBeginInfo.clearValueCount = clearValues.size();
+ renderPassBeginInfo.pClearValues = clearValues.data();
+ vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
- void SwapChain::EndFrameBuffer(const CommandBuffer& commandBuffer) const
- {
- vkCmdEndRenderPass(commandBuffer);
- }
+ VkViewport viewport{};
+ viewport.x = 0.0f;
+ viewport.y = 0.0f;
+ viewport.width = extent.width;
+ viewport.height = extent.height;
+ viewport.minDepth = 0.0f;
+ viewport.maxDepth = 1.0f;
+ vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
+ VkRect2D scissor{};
+ scissor.offset = {0, 0};
+ scissor.extent = extent;
+ vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
+ }
- VkSwapchainKHR SwapChain::GetHandle() const
- {
- return handle;
- }
+ void SwapChain::EndFrameBuffer(const CommandBuffer& commandBuffer) const
+ {
+ vkCmdEndRenderPass(commandBuffer);
+ }
- VkRenderPass SwapChain::GetRenderPass() const
- {
- return renderPass;
- }
+ VkSwapchainKHR SwapChain::GetHandle() const
+ {
+ return handle;
+ }
- VkExtent2D SwapChain::GetExtent() const
- {
- return extent;
- }
+ VkRenderPass SwapChain::GetRenderPass() const
+ {
+ return renderPass;
+ }
- VkFramebuffer SwapChain::GetFramebuffer() const
- {
- return framebuffers[imageIndex];
- }
+ VkExtent2D SwapChain::GetExtent() const
+ {
+ return extent;
+ }
- bool SwapChain::BeginPresent(VkSemaphore signalSemaphore)
- {
- VkResult result = vkAcquireNextImageKHR(instance.GetDevice(), handle, UINT64_MAX, signalSemaphore, VK_NULL_HANDLE, &imageIndex);
- if (result == VK_ERROR_OUT_OF_DATE_KHR)
- {
- Recreate();
- return false;
- }
- return true;
- }
+ VkFramebuffer SwapChain::GetFramebuffer() const
+ {
+ return framebuffers[imageIndex];
+ }
- void SwapChain::EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, bool framebufferResized)
- {
- VkPresentInfoKHR presentInfo{};
- presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
- presentInfo.waitSemaphoreCount = 1;
- presentInfo.pWaitSemaphores = waitSemaphore;
- presentInfo.swapchainCount = 1;
- presentInfo.pSwapchains = &handle;
- presentInfo.pImageIndices = &imageIndex;
- presentInfo.pResults = nullptr;
+ bool SwapChain::BeginPresent(VkSemaphore signalSemaphore)
+ {
+ VkResult result = vkAcquireNextImageKHR(instance.GetDevice(), handle, UINT64_MAX, signalSemaphore, VK_NULL_HANDLE, &imageIndex);
+ if (result == VK_ERROR_OUT_OF_DATE_KHR)
+ {
+ Recreate();
+ return false;
+ }
+ return true;
+ }
- VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo);
- if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized)
- {
- Recreate();
- }
- }
+ void SwapChain::EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, bool framebufferResized)
+ {
+ VkPresentInfoKHR presentInfo{};
+ presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+ presentInfo.waitSemaphoreCount = 1;
+ presentInfo.pWaitSemaphores = waitSemaphore;
+ presentInfo.swapchainCount = 1;
+ presentInfo.pSwapchains = &handle;
+ presentInfo.pImageIndices = &imageIndex;
+ presentInfo.pResults = nullptr;
- void SwapChain::Recreate()
- {
- int width = 0;
- int height = 0;
- glfwGetFramebufferSize(instance.GetWindow(), &width, &height);
- while (width == 0 || height == 0)
- {
- glfwGetFramebufferSize(instance.GetWindow(), &width, &height);
- glfwWaitEvents();
- }
+ VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo);
+ if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized)
+ {
+ Recreate();
+ }
+ }
- vkDeviceWaitIdle(instance.GetDevice());
+ void SwapChain::Recreate()
+ {
+ int width = 0;
+ int height = 0;
+ glfwGetFramebufferSize(instance.GetWindow(), &width, &height);
+ while (width == 0 || height == 0)
+ {
+ glfwGetFramebufferSize(instance.GetWindow(), &width, &height);
+ glfwWaitEvents();
+ }
- Destroy();
+ vkDeviceWaitIdle(instance.GetDevice());
- Initialize();
- InitializeImageViews();
- InitializeDepthBuffer();
- InitializeFramebuffers();
- }
+ Destroy();
- void SwapChain::Initialize()
- {
- SwapChainSupportDetails swapChainSupport{instance.GetSurface(), instance.GetPhysicalDevice()};
+ Initialize();
+ InitializeImageViews();
+ InitializeDepthAttachment();
+ InitializeFramebuffers();
+ }
- VkSurfaceFormatKHR format = SelectSwapSurfaceFormat(swapChainSupport.formats);
- VkPresentModeKHR presentMode = SelectSwapPresentMode(swapChainSupport.presentModes);
- extent = SelectSwapExtent(instance.GetWindow(), swapChainSupport.capabilities);
- imageFormat = format.format;
- uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
- if (swapChainSupport.capabilities.maxImageCount != 0)
- {
- imageCount = std::min(imageCount, swapChainSupport.capabilities.maxImageCount);
- }
+ void SwapChain::Initialize()
+ {
+ SwapChainSupportDetails swapChainSupport{instance.GetSurface(), instance.GetPhysicalDevice()};
- QueueFamiliesQuery queueFamilies{instance.GetSurface(), instance.GetPhysicalDevice()};
- std::vector queueFamilyIndices{queueFamilies.graphicsFamily.value(), queueFamilies.presentFamily.value()};
+ VkSurfaceFormatKHR format = SelectSwapSurfaceFormat(swapChainSupport.formats);
+ VkPresentModeKHR presentMode = SelectSwapPresentMode(swapChainSupport.presentModes);
+ extent = SelectSwapExtent(instance.GetWindow(), swapChainSupport.capabilities);
+ imageFormat = format.format;
+ uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
+ if (swapChainSupport.capabilities.maxImageCount != 0)
+ {
+ imageCount = std::min(imageCount, swapChainSupport.capabilities.maxImageCount);
+ }
- VkSwapchainCreateInfoKHR createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
- createInfo.surface = instance.GetSurface();
- createInfo.minImageCount = imageCount;
- createInfo.imageFormat = format.format;
- createInfo.imageColorSpace = format.colorSpace;
- createInfo.imageExtent = extent;
- createInfo.imageArrayLayers = 1;
- createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
- createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
- createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
- createInfo.presentMode = presentMode;
- createInfo.clipped = VK_TRUE;
- createInfo.oldSwapchain = VK_NULL_HANDLE;
- if (queueFamilies.graphicsFamily != queueFamilies.presentFamily)
- {
- createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
- createInfo.queueFamilyIndexCount = 2;
- createInfo.pQueueFamilyIndices = queueFamilyIndices.data();
- }
- else
- {
- createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
- createInfo.queueFamilyIndexCount = 0;
- createInfo.pQueueFamilyIndices = nullptr;
- }
+ QueueFamiliesQuery queueFamilies{instance.GetSurface(), instance.GetPhysicalDevice()};
+ std::vector queueFamilyIndices{queueFamilies.graphicsFamily.value(), queueFamilies.presentFamily.value()};
- CP_VK_ASSERT(vkCreateSwapchainKHR(instance.GetDevice(), &createInfo, nullptr, &handle), "Failed to initialize the swapchain");
+ VkSwapchainCreateInfoKHR createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ createInfo.surface = instance.GetSurface();
+ createInfo.minImageCount = imageCount;
+ createInfo.imageFormat = format.format;
+ createInfo.imageColorSpace = format.colorSpace;
+ createInfo.imageExtent = extent;
+ createInfo.imageArrayLayers = 1;
+ createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
+ createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+ createInfo.presentMode = presentMode;
+ createInfo.clipped = VK_TRUE;
+ createInfo.oldSwapchain = VK_NULL_HANDLE;
+ if (queueFamilies.graphicsFamily != queueFamilies.presentFamily)
+ {
+ createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
+ createInfo.queueFamilyIndexCount = 2;
+ createInfo.pQueueFamilyIndices = queueFamilyIndices.data();
+ }
+ else
+ {
+ createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ createInfo.queueFamilyIndexCount = 0;
+ createInfo.pQueueFamilyIndices = nullptr;
+ }
- vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, nullptr);
- images.resize(imageCount);
- vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, images.data());
- }
+ CP_VK_ASSERT(vkCreateSwapchainKHR(instance.GetDevice(), &createInfo, nullptr, &handle), "Initialize : Failed to initialize the swapchain");
- void SwapChain::InitializeImageViews()
- {
- imageViews.resize(images.size());
- for (size_t i = 0; i < images.size(); i++)
- {
- imageViews[i] = Image::InitializeImageView(instance, images[i], imageFormat, VK_IMAGE_ASPECT_COLOR_BIT);
- }
- }
+ vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, nullptr);
+ images.resize(imageCount);
+ vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, images.data());
+ }
- void SwapChain::InitializeDepthBuffer()
- {
- depthImage = std::make_unique(instance, extent.width, extent.height, Texture2D::Type::Static, Texture2D::Format::Depth);
- }
+ void SwapChain::InitializeImageViews()
+ {
+ imageViews.resize(images.size());
+ for (size_t i = 0; i < images.size(); i++)
+ {
+ imageViews[i] = Image::InitializeImageView(instance, images[i], imageFormat, VK_IMAGE_ASPECT_COLOR_BIT);
+ }
+ }
- void SwapChain::InitializeRenderPass()
- {
- VkAttachmentDescription colorAttachment{};
- colorAttachment.format = imageFormat;
- 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_PRESENT_SRC_KHR;
+ void SwapChain::InitializeDepthAttachment()
+ {
+ depthAttachment = std::make_unique(instance, extent.width, extent.height);
+ }
- 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;
+ void SwapChain::InitializeRenderPass()
+ {
+ VkAttachmentDescription colorAttachment{};
+ colorAttachment.format = imageFormat;
+ 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_PRESENT_SRC_KHR;
- VkAttachmentReference colorAttachmentRef{};
- colorAttachmentRef.attachment = 0;
- colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_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 depthAttachmentRef{};
- depthAttachmentRef.attachment = 1;
- depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ VkAttachmentReference colorAttachmentRef{};
+ colorAttachmentRef.attachment = 0;
+ colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- VkSubpassDescription subpass{};
- subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpass.colorAttachmentCount = 1;
- subpass.pColorAttachments = &colorAttachmentRef;
- subpass.pDepthStencilAttachment = &depthAttachmentRef;
+ VkAttachmentReference depthAttachmentRef{};
+ depthAttachmentRef.attachment = 1;
+ depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- VkSubpassDependency dependency{};
- dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
- dependency.dstSubpass = 0;
- dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
- dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
- dependency.srcAccessMask = 0;
- dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ VkSubpassDescription subpass{};
+ subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ subpass.colorAttachmentCount = 1;
+ subpass.pColorAttachments = &colorAttachmentRef;
+ subpass.pDepthStencilAttachment = &depthAttachmentRef;
- 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 = 1;
- renderPassCreateInfo.pDependencies = &dependency;
+ VkSubpassDependency dependency{};
+ dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
+ dependency.dstSubpass = 0;
+ dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
+ dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
+ dependency.srcAccessMask = 0;
+ dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
- CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "Failed to initialze render pass");
- }
+ 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 = 1;
+ renderPassCreateInfo.pDependencies = &dependency;
- void SwapChain::InitializeFramebuffers()
- {
- framebuffers.resize(images.size());
+ CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass");
+ }
- for (size_t i = 0; i < imageViews.size(); ++i)
- {
- std::vector attachments{imageViews[i], depthImage->GetImageView()};
+ void SwapChain::InitializeFramebuffers()
+ {
+ framebuffers.resize(images.size());
- VkFramebufferCreateInfo createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
- createInfo.renderPass = renderPass;
- createInfo.attachmentCount = attachments.size();
- createInfo.pAttachments = attachments.data();
- createInfo.width = extent.width;
- createInfo.height = extent.height;
- createInfo.layers = 1;
+ for (size_t i = 0; i < imageViews.size(); ++i)
+ {
+ std::vector attachments{imageViews[i], depthAttachment->GetImageView()};
- CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "Failed to initialize swap chain framebuffer");
- }
- }
+ VkFramebufferCreateInfo createInfo{};
+ createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+ createInfo.renderPass = renderPass;
+ createInfo.attachmentCount = attachments.size();
+ createInfo.pAttachments = attachments.data();
+ createInfo.width = extent.width;
+ createInfo.height = extent.height;
+ createInfo.layers = 1;
- void SwapChain::Destroy()
- {
- for (auto&& framebuffer : framebuffers)
- {
- vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
- }
- for (auto&& swapChainImageView : imageViews)
- {
- vkDestroyImageView(instance.GetDevice(), swapChainImageView, nullptr);
- }
- vkDestroySwapchainKHR(instance.GetDevice(), handle, nullptr);
- }
+ CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize swap chain framebuffer");
+ }
+ }
- VkSurfaceFormatKHR SwapChain::SelectSwapSurfaceFormat(const std::vector& availableFormats)
- {
- for (auto&& availableFormat : availableFormats)
- {
- if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
- {
- return availableFormat;
- }
- }
- return availableFormats[0];
- }
+ void SwapChain::Destroy()
+ {
+ for (auto&& framebuffer : framebuffers)
+ {
+ vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
+ }
+ for (auto&& swapChainImageView : imageViews)
+ {
+ vkDestroyImageView(instance.GetDevice(), swapChainImageView, nullptr);
+ }
+ vkDestroySwapchainKHR(instance.GetDevice(), handle, nullptr);
+ }
- VkPresentModeKHR SwapChain::SelectSwapPresentMode(const std::vector& availablePresentModes)
- {
- return VK_PRESENT_MODE_FIFO_KHR;
- for (auto&& availablePresentMode : availablePresentModes)
- {
- if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
- {
- return availablePresentMode;
- }
- }
+ VkSurfaceFormatKHR SwapChain::SelectSwapSurfaceFormat(const std::vector& availableFormats)
+ {
+ for (auto&& availableFormat : availableFormats)
+ {
+ if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
+ {
+ return availableFormat;
+ }
+ }
+ return availableFormats[0];
+ }
- // VK_PRESENT_MODE_FIFO_KHR is guaranteed to be present
- return VK_PRESENT_MODE_FIFO_KHR;
- }
+ VkPresentModeKHR SwapChain::SelectSwapPresentMode(const std::vector& availablePresentModes)
+ {
+ return VK_PRESENT_MODE_FIFO_KHR;
+ for (auto&& availablePresentMode : availablePresentModes)
+ {
+ if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
+ {
+ return availablePresentMode;
+ }
+ }
- VkExtent2D SwapChain::SelectSwapExtent(GLFWwindow* window, const VkSurfaceCapabilitiesKHR& capabilities)
- {
- if (capabilities.currentExtent.width != std::numeric_limits::max())
- return capabilities.currentExtent;
+ // VK_PRESENT_MODE_FIFO_KHR is guaranteed to be present
+ return VK_PRESENT_MODE_FIFO_KHR;
+ }
- int width, height;
- glfwGetFramebufferSize(window, &width, &height);
+ VkExtent2D SwapChain::SelectSwapExtent(GLFWwindow* window, const VkSurfaceCapabilitiesKHR& capabilities)
+ {
+ if (capabilities.currentExtent.width != std::numeric_limits::max())
+ return capabilities.currentExtent;
- VkExtent2D extent{width, height};
- extent.width = std::clamp(extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
- extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
- return extent;
- }
+ int width, height;
+ glfwGetFramebufferSize(window, &width, &height);
+
+ VkExtent2D extent{width, height};
+ extent.width = std::clamp(extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
+ extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
+ return extent;
+ }
}
diff --git a/Vulkan/src/SwapChain.h b/Vulkan/src/SwapChain.h
index 6173129..ac50e60 100644
--- a/Vulkan/src/SwapChain.h
+++ b/Vulkan/src/SwapChain.h
@@ -10,7 +10,7 @@ namespace Copium
{
class Instance;
class CommandBuffer;
- class Texture2D;
+ class DepthAttachment;
struct SwapChainSupportDetails
{
@@ -32,7 +32,7 @@ namespace Copium
VkRenderPass renderPass;
VkFormat imageFormat;
VkExtent2D extent;
- std::unique_ptr depthImage;
+ std::unique_ptr depthAttachment;
std::vector imageViews;
std::vector images;
std::vector framebuffers;
@@ -56,7 +56,7 @@ namespace Copium
private:
void Initialize();
void InitializeImageViews();
- void InitializeDepthBuffer();
+ void InitializeDepthAttachment();
void InitializeRenderPass();
void InitializeFramebuffers();
void Destroy();
diff --git a/Vulkan/src/Texture2D.cpp b/Vulkan/src/Texture2D.cpp
index e75e31a..bec0d41 100644
--- a/Vulkan/src/Texture2D.cpp
+++ b/Vulkan/src/Texture2D.cpp
@@ -6,28 +6,16 @@
namespace Copium
{
Texture2D::Texture2D(Instance& instance, const std::string& filename)
- : instance{instance}, type{Type::Static}, format{Format::Image}
+ : Sampler{instance}
{
InitializeTextureImage(filename);
- InitializeSampler();
- }
-
- Texture2D::Texture2D(Instance& instance, int width, int height, Type type, Format format)
- : instance{instance}, type{type}, format{format}
- {
- InitializeTexture(width, height);
- InitializeSampler();
}
Texture2D::~Texture2D()
{
- 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);
- vkDestroySampler(instance.GetDevice(), sampler, nullptr);
+ vkDestroyImage(instance.GetDevice(), image, nullptr);
+ vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
+ vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
}
VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const
@@ -35,34 +23,11 @@ namespace Copium
VkDescriptorImageInfo imageInfo{};
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfo.sampler = sampler;
-
- switch (type) {
- case Type::Static:
- imageInfo.imageView = imageViews.front();
- break;
- case Type::Dynamic:
- CP_ASSERT(index >= 0 && index < imageViews.size(), "GetDescriptorImageInfo : index out of bound for dynamic texture");
- imageInfo.imageView = imageViews[index];
- break;
- default:
- CP_ABORT("GetDescriptorImageInfo : Unreachable switch case");
- }
+ imageInfo.imageView = imageView;
return imageInfo;
}
- VkImageView Texture2D::GetImageView() const
- {
- CP_ASSERT(type == Type::Static, "GetImageView : Texture2D is not static");
- return imageViews.front();
- }
-
- VkImageView Texture2D::GetImageView(int index)
- {
- CP_ASSERT(type == Type::Dynamic && index >= 0 && index < imageViews.size(), "GetImageView : Texture2D is not dynamic or index out of bound for SystemTexture");
- return imageViews[index];
- }
-
void Texture2D::InitializeTextureImage(const std::string& filename)
{
int texWidth;
@@ -79,75 +44,10 @@ namespace Copium
stagingBuffer.Unmap();
stbi_image_free(pixels);
- images.resize(1);
- imageMemories.resize(1);
- imageViews.resize(1);
- Image::InitializeImage(instance, texWidth, texHeight, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images.front(), &imageMemories.front());
- Image::TransitionImageLayout(instance, images.front(), VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
- Image::CopyBufferToImage(instance, stagingBuffer, images.front(), texWidth, texHeight);
- Image::TransitionImageLayout(instance, images.front(), VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
- imageViews[0] = Image::InitializeImageView(instance, images.front(), VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
- }
-
- void Texture2D::InitializeTexture(int width, int height)
- {
- int count = 1;
- if (type == Type::Dynamic)
- count = instance.GetMaxFramesInFlight();
- images.resize(count);
- imageMemories.resize(count);
- imageViews.resize(count);
- for (size_t i = 0; i < images.size(); i++)
- {
- switch (format)
- {
- case Format::Color:
- {
- 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]);
- // Image::TransitionImageLayout(instance, images[i], VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
- imageViews[i] = Image::InitializeImageView(instance, images[i], VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
- break;
- }
- case Format::Depth:
- {
- VkFormat depthFormat = Image::SelectDepthFormat(instance);
- Image::InitializeImage(instance, width, height, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images[i], &imageMemories[i]);
- // Image::TransitionImageLayout(instance, images[i], depthFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
- imageViews[i] = Image::InitializeImageView(instance, images[i], depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
- break;
- }
- case Format::Image:
- {
- CP_ABORT("InitializeTexture : Image format currently not supported");
- }
- default:
- CP_ABORT("InitializeTexture : Unreachable switch case");
- }
- }
- }
-
- void Texture2D::InitializeSampler()
- {
- VkPhysicalDeviceProperties properties{};
- vkGetPhysicalDeviceProperties(instance.GetPhysicalDevice(), &properties);
-
- VkSamplerCreateInfo createInfo{};
- createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
- createInfo.magFilter = VK_FILTER_LINEAR;
- createInfo.minFilter = VK_FILTER_LINEAR;
- createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
- createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
- createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
- createInfo.anisotropyEnable = VK_TRUE;
- createInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
- createInfo.unnormalizedCoordinates = VK_FALSE;
- createInfo.compareEnable = VK_FALSE;
- createInfo.compareOp = VK_COMPARE_OP_ALWAYS;
- createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
- createInfo.mipLodBias = 0.0f;
- createInfo.minLod = 0.0f;
- createInfo.maxLod = 0.0f;
-
- CP_VK_ASSERT(vkCreateSampler(instance.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler");
+ Image::InitializeImage(instance, texWidth, texHeight, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory);
+ Image::TransitionImageLayout(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ Image::CopyBufferToImage(instance, stagingBuffer, image, texWidth, texHeight);
+ Image::TransitionImageLayout(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+ imageView = Image::InitializeImageView(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
}
}
diff --git a/Vulkan/src/Texture2D.h b/Vulkan/src/Texture2D.h
index 049072d..b488bee 100644
--- a/Vulkan/src/Texture2D.h
+++ b/Vulkan/src/Texture2D.h
@@ -5,43 +5,23 @@
#include "Common.h"
#include "Image.h"
#include "Instance.h"
+#include "Sampler.h"
namespace Copium
{
- // TODO: Separate Texture2D and Framebuffer Attachments
- class Texture2D
+ class Texture2D : public Sampler
{
CP_DELETE_COPY_AND_MOVE_CTOR(Texture2D);
- public:
- enum class Type
- {
- Static, Dynamic
- };
-
- enum class Format
- {
- Image, Color, Depth
- };
private:
- Instance& instance;
-
- std::vector images;
- std::vector imageMemories;
- std::vector imageViews;
- VkSampler sampler;
- Type type;
- Format format;
+ VkImage image;
+ VkDeviceMemory imageMemory;
+ VkImageView imageView;
public:
Texture2D(Instance& instance, const std::string& filename);
- Texture2D(Instance& instance, int width, int height, Type type, Format format);
- ~Texture2D();
+ ~Texture2D() override;
- VkDescriptorImageInfo GetDescriptorImageInfo(int index) const;
- VkImageView GetImageView() const;
- VkImageView GetImageView(int index);
+ VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
private:
void InitializeTextureImage(const std::string& filename);
- void InitializeTexture(int width, int height);
- void InitializeSampler();
};
}
diff --git a/Vulkan/src/UniformBuffer.h b/Vulkan/src/UniformBuffer.h
index 413c808..0094222 100644
--- a/Vulkan/src/UniformBuffer.h
+++ b/Vulkan/src/UniformBuffer.h
@@ -18,7 +18,7 @@ namespace Copium
template
void Update(const T& t)
{
- CP_ASSERT(sizeof(T) == Buffer::GetSize(), "Template size is not the same as buffer size %u != %u", sizeof(T), Buffer::GetSize());
+ CP_ASSERT(sizeof(T) == Buffer::GetSize(), "Update : Template size is not the same as buffer size %u != %u", sizeof(T), Buffer::GetSize());
Buffer::Update((void*)&t, instance.GetFlightIndex());
}
diff --git a/Vulkan/src/VertexDescriptor.h b/Vulkan/src/VertexDescriptor.h
index 218ef1d..b989df4 100644
--- a/Vulkan/src/VertexDescriptor.h
+++ b/Vulkan/src/VertexDescriptor.h
@@ -15,7 +15,7 @@ namespace Copium
template
void AddAttribute(uint32_t binding, uint32_t location, VkFormat format, uint32_t offset)
{
- CP_ASSERT(binding <= bindings.size(), "Attribute binding must less than or be equal to the amount of current bindings");
+ CP_ASSERT(binding <= bindings.size(), "AddAttribute : Attribute binding must less than or be equal to the amount of current bindings");
if (binding == bindings.size())
AddLayout(binding, sizeof(T));
diff --git a/Vulkan/src/main.cpp b/Vulkan/src/main.cpp
index f3906e9..73aa489 100644
--- a/Vulkan/src/main.cpp
+++ b/Vulkan/src/main.cpp
@@ -16,7 +16,7 @@ int main()
glfwPollEvents();
if (timer.Elapsed() >= 1.0)
{
- CP_DEBUG("%d fps", frames);
+ CP_DEBUG("main : %d fps", frames);
frames = 0;
timer.Start();
}