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(); }