summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-08-05 22:12:59 -0400
committerJonathan Bradley <jcb@pikum.xyz>2023-08-05 22:12:59 -0400
commit80b984cc672fda24d9cefc378cac68153473e21b (patch)
treed1824f7b87d9a6cdfcb46c07fe4f6bd400888bab /src
parentde67a9ec31e3fe700c77fd60e7868ccc5a7e3253 (diff)
create swapchain
Diffstat (limited to 'src')
-rw-r--r--src/window.cpp154
-rw-r--r--src/window.hpp1
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;