diff --git a/kraken/KRSurface.cpp b/kraken/KRSurface.cpp index 6d3d6bf..cd5589a 100644 --- a/kraken/KRSurface.cpp +++ b/kraken/KRSurface.cpp @@ -45,6 +45,10 @@ KRSurface::KRSurface(KRContext& context) , m_swapChain(VK_NULL_HANDLE) , m_swapChainImageFormat(VK_FORMAT_UNDEFINED) , m_swapChainExtent({ 0, 0 }) + , m_depthImageFormat(VK_FORMAT_UNDEFINED) + , m_depthImage(VK_NULL_HANDLE) + , m_depthImageAllocation(VK_NULL_HANDLE) + , m_depthImageView(VK_NULL_HANDLE) , m_imageAvailableSemaphore(VK_NULL_HANDLE) , m_renderFinishedSemaphore(VK_NULL_HANDLE) , m_renderPass(VK_NULL_HANDLE) @@ -236,6 +240,78 @@ KrResult KRSurface::createSwapChain() } } + m_depthImageFormat = VK_FORMAT_UNDEFINED; + VkFormatFeatureFlags requiredFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + std::vector candidateFormats; + candidateFormats.push_back(VK_FORMAT_D32_SFLOAT_S8_UINT); + candidateFormats.push_back(VK_FORMAT_D24_UNORM_S8_UINT); + for (VkFormat format : candidateFormats) { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(device->m_device, format, &props); + + if ((props.optimalTilingFeatures & requiredFeatures) == requiredFeatures) { + m_depthImageFormat = format; + break; + } + } + + if (m_depthImageFormat == VK_FORMAT_UNDEFINED) { + return KR_ERROR_VULKAN_DEPTHBUFFER; + } + + /* + createImage(swapChainExtent.width, swapChainExtent.height, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, depthImage, depthImageMemory); + depthImageView = createImageView(depthImage, depthFormat); + */ + { + VkImageCreateInfo imageInfo{}; + imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.extent.width = m_swapChainExtent.width; + imageInfo.extent.height = m_swapChainExtent.height; + imageInfo.extent.depth = 1; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = 1; + imageInfo.format = m_depthImageFormat; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.flags = 0; + + VmaAllocator allocator = device->getAllocator(); + VmaAllocationCreateInfo allocationCreateInfo{}; + allocationCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + allocationCreateInfo.requiredFlags = VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + if (vmaCreateImage(allocator, &imageInfo, &allocationCreateInfo, &m_depthImage, &m_depthImageAllocation, nullptr) != VK_SUCCESS) { + return KR_ERROR_VULKAN_DEPTHBUFFER; + } + + VkImageViewCreateInfo viewInfo{}; + viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + viewInfo.image = m_depthImage; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.format = m_depthImageFormat; + viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + viewInfo.subresourceRange.baseMipLevel = 0; + viewInfo.subresourceRange.levelCount = 1; + viewInfo.subresourceRange.baseArrayLayer = 0; + viewInfo.subresourceRange.layerCount = 1; + + if (vkCreateImageView(device->m_logicalDevice, &viewInfo, nullptr, &m_depthImageView) != VK_SUCCESS) { + return KR_ERROR_VULKAN_DEPTHBUFFER; + } + + /* + TODO - Track memory usage + + VkMemoryRequirements memRequirements; + vkGetImageMemoryRequirements(device->m_logicalDevice, m_depthImage, &memRequirements); + */ + } + createRenderPasses(); m_swapChainFramebuffers.resize(m_swapChainImageViews.size()); @@ -278,9 +354,21 @@ void KRSurface::destroySwapChain() if (m_swapChain != VK_NULL_HANDLE) { vkDestroySwapchainKHR(device->m_logicalDevice, m_swapChain, nullptr); + m_swapChain = VK_NULL_HANDLE; } } - m_swapChain = VK_NULL_HANDLE; + + if (m_depthImageView) { + vkDestroyImageView(device->m_logicalDevice, m_depthImageView, nullptr); + m_depthImageView = VK_NULL_HANDLE; + } + + if (m_depthImage) { + vmaDestroyImage(device->getAllocator(), m_depthImage, m_depthImageAllocation); + m_depthImage = VK_NULL_HANDLE; + m_depthImageAllocation = VK_NULL_HANDLE; + } + m_swapChainFramebuffers.clear(); m_swapChainImageViews.clear(); } diff --git a/kraken/KRSurface.h b/kraken/KRSurface.h index 766324f..91a779f 100644 --- a/kraken/KRSurface.h +++ b/kraken/KRSurface.h @@ -70,6 +70,10 @@ public: VkExtent2D m_swapChainExtent; std::vector m_swapChainImageViews; std::vector m_swapChainFramebuffers; + VkFormat m_depthImageFormat; + VkImage m_depthImage; + VmaAllocation m_depthImageAllocation; + VkImageView m_depthImageView; VkSemaphore m_imageAvailableSemaphore; VkSemaphore m_renderFinishedSemaphore; diff --git a/kraken/public/kraken.h b/kraken/public/kraken.h index bea878f..565998a 100644 --- a/kraken/public/kraken.h +++ b/kraken/public/kraken.h @@ -50,6 +50,7 @@ typedef enum { KR_ERROR_VULKAN_REQUIRED, KR_ERROR_VULKAN_SWAP_CHAIN, KR_ERROR_VULKAN_FRAMEBUFFER, + KR_ERROR_VULKAN_DEPTHBUFFER, KR_ERROR_NO_DEVICE, KR_ERROR_SHADER_COMPILE_FAILED, KR_ERROR_UNEXPECTED = 0x10000000,