diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-08-05 22:12:59 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-08-05 22:12:59 -0400 |
| commit | 80b984cc672fda24d9cefc378cac68153473e21b (patch) | |
| tree | d1824f7b87d9a6cdfcb46c07fe4f6bd400888bab /src | |
| parent | de67a9ec31e3fe700c77fd60e7868ccc5a7e3253 (diff) | |
create swapchain
Diffstat (limited to 'src')
| -rw-r--r-- | src/window.cpp | 154 | ||||
| -rw-r--r-- | src/window.hpp | 1 |
2 files changed, 149 insertions, 6 deletions
diff --git a/src/window.cpp b/src/window.cpp index 66473a7..8aaed26 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -10,6 +10,12 @@ #define NELEMS(x) (sizeof(x) / sizeof((x)[0])) +const bool ENABLE_VALIDATION_LAYERS = true; +const bool VULKAN_DEBUG_REPORT = true; + +/* + * Initialization + */ GLFWwindow *window = nullptr; VkInstance vkInstance = nullptr; VkPhysicalDevice vkPhysicalDevice = nullptr; @@ -18,9 +24,22 @@ VkSurfaceKHR vkSurfaceKHR = nullptr; VkDebugReportCallbackEXT vkDebugReport = nullptr; VkAllocationCallbacks vkAllocatorStruct = {}; VkAllocationCallbacks *vkAllocator = nullptr; - -const bool ENABLE_VALIDATION_LAYERS = true; -const bool VULKAN_DEBUG_REPORT = true; +unsigned int graphicsFamilyIndex; +unsigned int presentFamilyIndex; + +/* + * Instantiation + */ +unsigned int CURRENT_FRAME = 0; +unsigned int selectedSurfaceIndex = -1u; +unsigned int selectedPresentIndex = -1u; +unsigned int swapchainLength = 0u; +VkSwapchainKHR vkSwapchainKHR = nullptr; +VkSurfaceFormatKHR vkSurfaceFormatKHR; +VkPresentModeKHR vkPresentModeKHR; +VkExtent2D extent; +VkImage *swapchainImages = nullptr; +VkImageView *swapchainImageViews = nullptr; const std::vector<const char *> REQUIRED_EXTENSIONS = std::vector<const char *> { VK_KHR_SWAPCHAIN_EXTENSION_NAME @@ -177,7 +196,7 @@ void InitVulkan() { debugReportCallbackCreateInfo.pfnCallback = DebugReport; debugReportCallbackCreateInfo.pUserData = nullptr; - VkResult result = func(vkInstance, &debugReportCallbackCreateInfo, nullptr, &vkDebugReport); + result = func(vkInstance, &debugReportCallbackCreateInfo, nullptr, &vkDebugReport); if (result != VK_SUCCESS) { fprintf(stderr, "%s\n", "Failed to create debug report!"); @@ -195,8 +214,8 @@ void InitVulkan() { assert(physicalDeviceCount > 0); std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount); vkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, physicalDevices.data()); - unsigned int graphicsFamilyIndex = 0; - unsigned int presentFamilyIndex = 0; + graphicsFamilyIndex = 0; + presentFamilyIndex = 0; for (const auto &device : physicalDevices) { // check queue families @@ -307,12 +326,134 @@ void InitVulkan() { } } +void CreateSwapchain() { + + VkSurfaceCapabilitiesKHR surfaceCapabilities; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vkPhysicalDevice, vkSurfaceKHR, &surfaceCapabilities); + + if (selectedSurfaceIndex == -1u) { + unsigned int surfaceFormatCounts; + vkGetPhysicalDeviceSurfaceFormatsKHR(vkPhysicalDevice, vkSurfaceKHR, &surfaceFormatCounts, nullptr); + VkSurfaceFormatKHR *surfaceFormats = new VkSurfaceFormatKHR[surfaceFormatCounts]; + vkGetPhysicalDeviceSurfaceFormatsKHR(vkPhysicalDevice, vkSurfaceKHR, &surfaceFormatCounts, surfaceFormats); + selectedSurfaceIndex = 0; + for (long i = 0; i < surfaceFormatCounts; ++i) { + if (surfaceFormats[i].format != VkFormat::VK_FORMAT_B8G8R8A8_SRGB) continue; + if (surfaceFormats[i].colorSpace != VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) continue; + selectedSurfaceIndex = i; + vkSurfaceFormatKHR.colorSpace = surfaceFormats[i].colorSpace; + vkSurfaceFormatKHR.format = surfaceFormats[i].format; + break; + } + + delete[] surfaceFormats; + } + + int width, height; + glfwGetFramebufferSize(window, &width, &height); + extent.width = width; + extent.height = height; + // clamp + width = extent.width < surfaceCapabilities.minImageExtent.width ? surfaceCapabilities.minImageExtent.width : extent.width; + extent.width = width > surfaceCapabilities.maxImageExtent.width ? surfaceCapabilities.maxImageExtent.width : width; + height = extent.height < surfaceCapabilities.minImageExtent.height ? surfaceCapabilities.minImageExtent.height : extent.height; + extent.height = height > surfaceCapabilities.maxImageExtent.height ? surfaceCapabilities.maxImageExtent.height : height; + + if (selectedPresentIndex == -1u) { + unsigned int presentModeCount = 0; + vkGetPhysicalDeviceSurfacePresentModesKHR(vkPhysicalDevice, vkSurfaceKHR, &presentModeCount, nullptr); + VkPresentModeKHR *presentModes = new VkPresentModeKHR[presentModeCount]; + vkGetPhysicalDeviceSurfacePresentModesKHR(vkPhysicalDevice, vkSurfaceKHR, &presentModeCount, nullptr); + unsigned long mailboxIndex = -1; + unsigned long fifoRelaxedIndex = -1; + for (long i = 0; i < presentModeCount; ++i) { + if (presentModes[i] != VkPresentModeKHR::VK_PRESENT_MODE_MAILBOX_KHR) { + mailboxIndex = i; + } else if (presentModes[i] != VkPresentModeKHR::VK_PRESENT_MODE_FIFO_RELAXED_KHR) { + fifoRelaxedIndex = i; + } + } + selectedPresentIndex = mailboxIndex != -1ul ? mailboxIndex : fifoRelaxedIndex; + vkPresentModeKHR = presentModes[selectedPresentIndex]; + delete[] presentModes; + } + + VkSwapchainCreateInfoKHR vkSwapchainCreateInfo{}; + vkSwapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + vkSwapchainCreateInfo.flags = 0; + vkSwapchainCreateInfo.minImageCount = MAX_FRAMES_IN_FLIGHT; + vkSwapchainCreateInfo.imageFormat = vkSurfaceFormatKHR.format; + vkSwapchainCreateInfo.imageColorSpace = vkSurfaceFormatKHR.colorSpace; + vkSwapchainCreateInfo.imageExtent = extent; + vkSwapchainCreateInfo.imageArrayLayers = 1; + vkSwapchainCreateInfo.imageUsage = VkImageUsageFlagBits::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + vkSwapchainCreateInfo.preTransform = surfaceCapabilities.currentTransform; + vkSwapchainCreateInfo.compositeAlpha = VkCompositeAlphaFlagBitsKHR::VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + vkSwapchainCreateInfo.presentMode = vkPresentModeKHR; + vkSwapchainCreateInfo.clipped = VK_TRUE; + vkSwapchainCreateInfo.oldSwapchain = vkSwapchainKHR; + vkSwapchainCreateInfo.surface = vkSurfaceKHR; + + unsigned int qfi[2] = { graphicsFamilyIndex, presentFamilyIndex }; + if (graphicsFamilyIndex != presentFamilyIndex) { + vkSwapchainCreateInfo.imageSharingMode = VkSharingMode::VK_SHARING_MODE_CONCURRENT; + vkSwapchainCreateInfo.queueFamilyIndexCount = 2; + vkSwapchainCreateInfo.pQueueFamilyIndices = qfi; + } else { + vkSwapchainCreateInfo.imageSharingMode = VkSharingMode::VK_SHARING_MODE_EXCLUSIVE; + vkSwapchainCreateInfo.queueFamilyIndexCount = 0; + } + + vkCreateSwapchainKHR(vkDevice, &vkSwapchainCreateInfo, vkAllocator, &vkSwapchainKHR); + + VkImageSubresourceRange vkImageSubresourceRange; + vkImageSubresourceRange.aspectMask = VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT; + vkImageSubresourceRange.baseMipLevel = 0u; + vkImageSubresourceRange.levelCount = 1u; + vkImageSubresourceRange.baseArrayLayer = 0u; + vkImageSubresourceRange.layerCount = 1u; + + VkImageViewCreateInfo vkImageViewCreateInfo{}; + vkImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + vkImageViewCreateInfo.flags = 0; + vkImageViewCreateInfo.viewType = VkImageViewType::VK_IMAGE_VIEW_TYPE_2D; + vkImageViewCreateInfo.format = vkSurfaceFormatKHR.format; + vkImageViewCreateInfo.components = { + VkComponentSwizzle::VK_COMPONENT_SWIZZLE_IDENTITY, + VkComponentSwizzle::VK_COMPONENT_SWIZZLE_IDENTITY, + VkComponentSwizzle::VK_COMPONENT_SWIZZLE_IDENTITY, + VkComponentSwizzle::VK_COMPONENT_SWIZZLE_IDENTITY, + }; + vkImageViewCreateInfo.subresourceRange = vkImageSubresourceRange; + + vkGetSwapchainImagesKHR(vkDevice, vkSwapchainKHR, &swapchainLength, nullptr); + swapchainImages = new VkImage[swapchainLength]; + vkGetSwapchainImagesKHR(vkDevice, vkSwapchainKHR, &swapchainLength, swapchainImages); + swapchainImageViews = new VkImageView[swapchainLength]; + for (long i = 0; i < swapchainLength; ++i) { + vkImageViewCreateInfo.image = swapchainImages[i]; + vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &swapchainImageViews[i]); + } +} + +void DestroySwapchain() { + if (swapchainImageViews!= nullptr && swapchainImageViews != reinterpret_cast<VkImageView *>(0xCAFEBABE)) { + for (long i = 0; i < swapchainLength; ++i) { + vkDestroyImageView(vkDevice, swapchainImageViews[i], vkAllocator); + } + } + vkDestroySwapchainKHR(vkDevice, vkSwapchainKHR, vkAllocator); + swapchainImages = reinterpret_cast<VkImage *>(0xCAFEBABE); + swapchainImageViews = reinterpret_cast<VkImageView *>(0xCAFEBABE); +} + void CreateWindow(PKEWindowProperties *wp) { if (vkInstance != nullptr) return; glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); window = glfwCreateWindow(wp->width, wp->height, "Pikul", nullptr, nullptr); InitVulkan(); + CreateSwapchain(); } void DestroyWindow() { @@ -321,6 +462,7 @@ void DestroyWindow() { auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(vkInstance, "vkDestroyDebugReportCallbackEXT"); vkDestroyDebugReportCallbackEXT(vkInstance, vkDebugReport, nullptr); } + DestroySwapchain(); vkDestroySurfaceKHR(vkInstance, vkSurfaceKHR, vkAllocator); vkDestroyDevice(vkDevice, vkAllocator); vkDestroyInstance(vkInstance, vkAllocator); diff --git a/src/window.hpp b/src/window.hpp index 4997327..38f3151 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -10,6 +10,7 @@ extern GLFWwindow *glfwWindow; extern VkInstance vkInstance; extern VkPhysicalDevice vkPhysicalDevice; extern VkSurfaceKHR vkSurfaceKHR; +extern VkDevice vkDevice; struct PKEWindowProperties { unsigned int width = 1280; |
