void Window::_InitSwapchain() { // This code is old and the fixed one is below // if( _swapchain_image_count > _surface_capabilities.maxImageCount ) _swapchain_image_count = _surface_capabilities.maxImageCount; // if( _swapchain_image_count < _surface_capabilities.minImageCount + 1 ) _swapchain_image_count = _surface_capabilities.minImageCount + 1; // The code above will work just fine in our tutorials and likely on every possible implementation of vulkan as well // so this change isn't that important. Just to be absolutely sure we don't go over or below the given limits we should check this a // little bit different though. maxImageCount can actually be zero in which case the amount of swapchain images do not have an // upper limit other than available memory. It's also possible that the swapchain image amount is locked to a certain // value on certain systems. The code below takes into consideration both of these possibilities. if( _swapchain_image_count < _surface_capabilities.minImageCount + 1 ) _swapchain_image_count = _surface_capabilities.minImageCount + 1; if( _surface_capabilities.maxImageCount > 0 ) { if( _swapchain_image_count > _surface_capabilities.maxImageCount ) _swapchain_image_count = _surface_capabilities.maxImageCount; } VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; { uint32_t present_mode_count = 0; ErrorCheck( vkGetPhysicalDeviceSurfacePresentModesKHR( _renderer->GetVulkanPhysicalDevice(), _surface, &present_mode_count, nullptr ) ); std::vector<VkPresentModeKHR> present_mode_list( present_mode_count ); ErrorCheck( vkGetPhysicalDeviceSurfacePresentModesKHR( _renderer->GetVulkanPhysicalDevice(), _surface, &present_mode_count, present_mode_list.data() ) ); for( auto m : present_mode_list ) { if( m == VK_PRESENT_MODE_MAILBOX_KHR ) present_mode = m; } } VkSwapchainCreateInfoKHR swapchain_create_info {}; swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; swapchain_create_info.surface = _surface; swapchain_create_info.minImageCount = _swapchain_image_count; swapchain_create_info.imageFormat = _surface_format.format; swapchain_create_info.imageColorSpace = _surface_format.colorSpace; swapchain_create_info.imageExtent.width = _surface_size_x; swapchain_create_info.imageExtent.height = _surface_size_y; swapchain_create_info.imageArrayLayers = 1; swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; swapchain_create_info.queueFamilyIndexCount = 0; swapchain_create_info.pQueueFamilyIndices = nullptr; swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swapchain_create_info.presentMode = present_mode; swapchain_create_info.clipped = VK_TRUE; swapchain_create_info.oldSwapchain = VK_NULL_HANDLE; ErrorCheck( vkCreateSwapchainKHR( _renderer->GetVulkanDevice(), &swapchain_create_info, nullptr, &_swapchain ) ); ErrorCheck( vkGetSwapchainImagesKHR( _renderer->GetVulkanDevice(), _swapchain, &_swapchain_image_count, nullptr ) ); }
void Window::_InitSwapchain() { if (_swapchain_image_count < _surface_capabilities.minImageCount) _swapchain_image_count = _surface_capabilities.minImageCount + 1; if (_swapchain_image_count > _surface_capabilities.maxImageCount) _swapchain_image_count = _surface_capabilities.maxImageCount; VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; { uint32_t present_mode_count = 0; ErrorCheck(vkGetPhysicalDeviceSurfacePresentModesKHR(_renderer->getPhysicalDevice(), _surface, &present_mode_count, nullptr)); std::vector<VkPresentModeKHR> present_mode_list(present_mode_count); ErrorCheck(vkGetPhysicalDeviceSurfacePresentModesKHR(_renderer->getPhysicalDevice(), _surface, &present_mode_count, present_mode_list.data())); for (auto m : present_mode_list) { if (m == VK_PRESENT_MODE_MAILBOX_KHR) present_mode = m; } } VkSwapchainCreateInfoKHR swapchain_create_info {}; swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; swapchain_create_info.surface = _surface; swapchain_create_info.minImageCount = _swapchain_image_count; // Buffers swapchain_create_info.imageFormat = _surface_format.format; swapchain_create_info.imageColorSpace = _surface_format.colorSpace; swapchain_create_info.imageExtent.width = _surface_size_x; swapchain_create_info.imageExtent.height = _surface_size_y; swapchain_create_info.imageArrayLayers = 1; // Number of images (mono, stereo) swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; swapchain_create_info.queueFamilyIndexCount = 0; swapchain_create_info.pQueueFamilyIndices = nullptr; swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swapchain_create_info.presentMode = present_mode; swapchain_create_info.clipped = VK_TRUE; swapchain_create_info.oldSwapchain = VK_NULL_HANDLE; ErrorCheck(vkCreateSwapchainKHR(_renderer->getDevice(), &swapchain_create_info, nullptr, &_swapchain)); ErrorCheck(vkGetSwapchainImagesKHR(_renderer->getDevice(), _swapchain, &_swapchain_image_count, nullptr)); }
void VulkanWindow::InitializeSwapchain() { vkGetPhysicalDeviceSurfaceCapabilitiesKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &mVkSurfaceCapabilitiesKHR ); uint32_t surface_format_count = 0; vkGetPhysicalDeviceSurfaceFormatsKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &surface_format_count, nullptr ); if ( surface_format_count == 0 ) { std::ostringstream stream; stream << "Physical device reports no surface formats."; throw std::runtime_error ( stream.str().c_str() ); } VkSurfaceFormatKHR surface_format_khr; std::vector<VkSurfaceFormatKHR> surface_format_list ( surface_format_count ); vkGetPhysicalDeviceSurfaceFormatsKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &surface_format_count, surface_format_list.data() ); if ( surface_format_list[0].format == VK_FORMAT_UNDEFINED ) { surface_format_khr = mVulkanRenderer.GetSurfaceFormatKHR(); } else { surface_format_khr = surface_format_list[0]; } if ( mSwapchainImageCount < mVkSurfaceCapabilitiesKHR.minImageCount ) { mSwapchainImageCount = mVkSurfaceCapabilitiesKHR.minImageCount; } if ( ( mVkSurfaceCapabilitiesKHR.maxImageCount > 0 ) && ( mSwapchainImageCount > mVkSurfaceCapabilitiesKHR.maxImageCount ) ) { mSwapchainImageCount = mVkSurfaceCapabilitiesKHR.maxImageCount; } VkSwapchainCreateInfoKHR swapchain_create_info{}; swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; swapchain_create_info.surface = mVkSurfaceKHR; swapchain_create_info.minImageCount = mSwapchainImageCount; swapchain_create_info.imageFormat = surface_format_khr.format; swapchain_create_info.imageColorSpace = surface_format_khr.colorSpace; swapchain_create_info.imageExtent.width = mVkSurfaceCapabilitiesKHR.currentExtent.width; swapchain_create_info.imageExtent.height = mVkSurfaceCapabilitiesKHR.currentExtent.height; swapchain_create_info.imageArrayLayers = 1; swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; swapchain_create_info.queueFamilyIndexCount = 0; swapchain_create_info.pQueueFamilyIndices = nullptr; swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR; // This may be reset below. swapchain_create_info.clipped = VK_TRUE; swapchain_create_info.oldSwapchain = mVkSwapchainKHR; // Used for Resising. { uint32_t present_mode_count = 0; vkGetPhysicalDeviceSurfacePresentModesKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &present_mode_count, nullptr ); std::vector<VkPresentModeKHR> present_mode_list ( present_mode_count ); vkGetPhysicalDeviceSurfacePresentModesKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &present_mode_count, present_mode_list.data() ); for ( auto& i : present_mode_list ) { if ( i == VK_PRESENT_MODE_MAILBOX_KHR ) { swapchain_create_info.presentMode = i; break; } } } if ( VkResult result = vkCreateSwapchainKHR ( mVulkanRenderer.GetDevice(), &swapchain_create_info, nullptr, &mVkSwapchainKHR ) ) { std::ostringstream stream; stream << "Call to vkCreateSwapchainKHR failed: ( " << GetVulkanResultString ( result ) << " )"; throw std::runtime_error ( stream.str().c_str() ); } if ( swapchain_create_info.oldSwapchain != VK_NULL_HANDLE ) { vkDestroySwapchainKHR ( mVulkanRenderer.GetDevice(), swapchain_create_info.oldSwapchain, nullptr ); } }