void SwapChain::Destroy() { if (m_SwapChain) { fpDestroySwapchainKHR(GetRawDevice(), m_SwapChain, nullptr); m_SwapChain = VK_NULL_HANDLE; } if (m_Surface) { vkDestroySurfaceKHR(RHIRoot::GetInstance(), m_Surface, nullptr); m_Surface = VK_NULL_HANDLE; } }
int XdevLSwapChainVulkan::create(VkCommandBuffer cmdBuffer, uint32_t *width, uint32_t *height) { VkResult result; VkSwapchainKHR oldSwapchain = m_swapChain; // Get physical device surface properties and formats. VkSurfaceCapabilitiesKHR surfCaps; result = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(m_physicalDevice, m_surface, &surfCaps); if(VK_SUCCESS != result) { std::cerr << "vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed: " << vkVkResultToString(result) << std::endl; return 1; } // ------------------------------------------------------------------------- // Get available present modes. // // Get the number of modes. uint32_t presentModeCount; result = fpGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &presentModeCount, nullptr); if(VK_SUCCESS != result) { std::cerr << "vkGetPhysicalDeviceSurfacePresentModesKHR failed: " << vkVkResultToString(result) << std::endl; return 1; } // Use the number of modes and create an array of modes. std::vector<VkPresentModeKHR> presentModes(presentModeCount); result = fpGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &presentModeCount, presentModes.data()); if(VK_SUCCESS != result) { std::cerr << "vkGetPhysicalDeviceSurfacePresentModesKHR failed: " << vkVkResultToString(result) << std::endl; return 1; } // ------------------------------------------------------------------------- VkExtent2D swapchainExtent = {}; // width and height are either both -1, or both not -1. if(surfCaps.currentExtent.width == UINT32_MAX) { // If the surface size is undefined, the size is set to // the size of the images requested. swapchainExtent.width = *width; swapchainExtent.height = *height; } else { // If the surface size is defined, the swap chain size must match swapchainExtent = surfCaps.currentExtent; *width = surfCaps.currentExtent.width; *height = surfCaps.currentExtent.height; } VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; for(size_t i = 0; i < presentModeCount; i++) { if(presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) { swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR; break; } if((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) && (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) { swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; } } // Determine the number of images uint32_t desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1; if((surfCaps.maxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount)) { desiredNumberOfSwapchainImages = surfCaps.maxImageCount; } VkSurfaceTransformFlagsKHR preTransform; if(surfCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; } else { preTransform = surfCaps.currentTransform; } VkSwapchainCreateInfoKHR swapchainCI = {}; swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; swapchainCI.pNext = NULL; swapchainCI.surface = m_surface; swapchainCI.minImageCount = desiredNumberOfSwapchainImages; swapchainCI.imageFormat = m_colorFormat; swapchainCI.imageColorSpace = m_colorSpace; swapchainCI.imageExtent = { swapchainExtent.width, swapchainExtent.height }; swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swapchainCI.preTransform = (VkSurfaceTransformFlagBitsKHR)preTransform; swapchainCI.imageArrayLayers = 1; swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; swapchainCI.queueFamilyIndexCount = 0; swapchainCI.pQueueFamilyIndices = NULL; swapchainCI.presentMode = swapchainPresentMode; swapchainCI.oldSwapchain = oldSwapchain; swapchainCI.clipped = true; swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; // If we recreate a SwapChain we have to destroy the previous one. // Note: destroying the swapchain also cleans up all its associated // presentable images once the platform is done with them. if(m_oldSwapChain != VK_NULL_HANDLE) { fpDestroySwapchainKHR(m_device, m_oldSwapChain, nullptr); } result = fpCreateSwapchainKHR(m_device, &swapchainCI, nullptr, &m_swapChain); if(VK_SUCCESS != result) { std::cerr << "vkCreateSwapchainKHR failed: " << vkVkResultToString(result) << std::endl; return 1; } result = fpGetSwapchainImagesKHR(m_device, m_swapChain, &m_imageCount, nullptr); if(VK_SUCCESS != result) { std::cerr << "vkGetSwapchainImagesKHR failed: " << vkVkResultToString(result) << std::endl; return 1; } m_images.reserve(m_imageCount); m_images.resize(m_imageCount); result = fpGetSwapchainImagesKHR(m_device, m_swapChain, &m_imageCount, m_images.data()); if(VK_SUCCESS != result) { std::cerr << "vkGetSwapchainImagesKHR failed: " << vkVkResultToString(result) << std::endl; return 1; } m_buffers.reserve(m_imageCount); m_buffers.resize(m_imageCount); for(uint32_t i = 0; i < m_imageCount; i++) { VkImageViewCreateInfo colorAttachmentView = {}; colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; colorAttachmentView.pNext = NULL; colorAttachmentView.format = m_colorFormat; colorAttachmentView.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; colorAttachmentView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; colorAttachmentView.subresourceRange.baseMipLevel = 0; colorAttachmentView.subresourceRange.levelCount = 1; colorAttachmentView.subresourceRange.baseArrayLayer = 0; colorAttachmentView.subresourceRange.layerCount = 1; colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D; colorAttachmentView.flags = 0; m_buffers[i].image = m_images[i]; // Transform images from initial (undefined) to present layout setImageLayout( cmdBuffer, m_buffers[i].image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); colorAttachmentView.image = m_buffers[i].image; result = vkCreateImageView(m_device, &colorAttachmentView, nullptr, &m_buffers[i].view); assert(!result); } return 0; }