private void CreateSwapchain(uint width, uint height) { _currentImageIndex = 0; uint surfaceFormatCount = 0; vkGetPhysicalDeviceSurfaceFormatsKHR(_gd.PhysicalDevice, _surface, ref surfaceFormatCount, null); VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[surfaceFormatCount]; vkGetPhysicalDeviceSurfaceFormatsKHR(_gd.PhysicalDevice, _surface, ref surfaceFormatCount, out formats[0]); VkSurfaceFormatKHR surfaceFormat = new VkSurfaceFormatKHR(); if (formats.Length == 1 && formats[0].format == VkFormat.Undefined) { surfaceFormat = new VkSurfaceFormatKHR { colorSpace = VkColorSpaceKHR.SrgbNonlinearKHR, format = VkFormat.B8g8r8a8Unorm }; } else { foreach (VkSurfaceFormatKHR format in formats) { if (format.colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR && format.format == VkFormat.B8g8r8a8Unorm) { surfaceFormat = format; break; } } if (surfaceFormat.format == VkFormat.Undefined) { surfaceFormat = formats[0]; } } uint presentModeCount = 0; vkGetPhysicalDeviceSurfacePresentModesKHR(_gd.PhysicalDevice, _surface, ref presentModeCount, null); VkPresentModeKHR[] presentModes = new VkPresentModeKHR[presentModeCount]; vkGetPhysicalDeviceSurfacePresentModesKHR(_gd.PhysicalDevice, _surface, ref presentModeCount, out presentModes[0]); VkPresentModeKHR presentMode = VkPresentModeKHR.FifoKHR; if (presentModes.Contains(VkPresentModeKHR.MailboxKHR)) { presentMode = VkPresentModeKHR.MailboxKHR; } else if (presentModes.Contains(VkPresentModeKHR.ImmediateKHR)) { presentMode = VkPresentModeKHR.ImmediateKHR; } vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_gd.PhysicalDevice, _surface, out VkSurfaceCapabilitiesKHR surfaceCapabilities); uint imageCount = surfaceCapabilities.minImageCount + 1; VkSwapchainCreateInfoKHR swapchainCI = VkSwapchainCreateInfoKHR.New(); swapchainCI.surface = _surface; swapchainCI.presentMode = presentMode; swapchainCI.imageFormat = surfaceFormat.format; swapchainCI.imageColorSpace = surfaceFormat.colorSpace; swapchainCI.imageExtent = new VkExtent2D { width = (uint)width, height = (uint)height }; swapchainCI.minImageCount = imageCount; swapchainCI.imageArrayLayers = 1; swapchainCI.imageUsage = VkImageUsageFlags.ColorAttachment; FixedArray2 <uint> queueFamilyIndices = new FixedArray2 <uint>(_gd.GraphicsQueueIndex, _gd.PresentQueueIndex); if (_gd.GraphicsQueueIndex != _gd.PresentQueueIndex) { swapchainCI.imageSharingMode = VkSharingMode.Concurrent; swapchainCI.queueFamilyIndexCount = 2; swapchainCI.pQueueFamilyIndices = &queueFamilyIndices.First; } else { swapchainCI.imageSharingMode = VkSharingMode.Exclusive; swapchainCI.queueFamilyIndexCount = 0; } swapchainCI.preTransform = surfaceCapabilities.currentTransform; swapchainCI.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR; swapchainCI.clipped = true; VkSwapchainKHR oldSwapchain = _swapchain; swapchainCI.oldSwapchain = oldSwapchain; VkResult result = vkCreateSwapchainKHR(_gd.Device, ref swapchainCI, null, out _swapchain); CheckResult(result); if (oldSwapchain != VkSwapchainKHR.Null) { vkDestroySwapchainKHR(_gd.Device, oldSwapchain, null); } // Get the images uint scImageCount = 0; result = vkGetSwapchainImagesKHR(_gd.Device, _swapchain, ref scImageCount, null); CheckResult(result); if (_scImages == null) { _scImages = new VkImage[(int)scImageCount]; } result = vkGetSwapchainImagesKHR(_gd.Device, _swapchain, ref scImageCount, out _scImages[0]); CheckResult(result); _scImageFormat = surfaceFormat.format; _scExtent = swapchainCI.imageExtent; CreateDepthTexture(); CreateFramebuffers(); }
private VkSwapchainKHR CreateSwapchain() { VkSurfaceCapabilitiesKHR capabilities; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Context.PhysicalDevice, Surface, out capabilities).CheckResult(); uint count; vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, null); VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[(int)count]; fixed(VkSurfaceFormatKHR *formatsPtr = formats) vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, formatsPtr).CheckResult(); vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, null).CheckResult(); VkPresentModeKHR[] presentModes = new VkPresentModeKHR[count]; fixed(VkPresentModeKHR *presentModesPtr = presentModes) vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, presentModesPtr).CheckResult(); VkFormat format = formats.Length == 1 && formats[0].format == VkFormat.Undefined ? VkFormat.B8G8R8A8UNorm : formats[0].format; VkPresentModeKHR presentMode = presentModes.Contains(VkPresentModeKHR.Mailbox) ? VkPresentModeKHR.Mailbox : presentModes.Contains(VkPresentModeKHR.FifoRelaxed) ? VkPresentModeKHR.FifoRelaxed : presentModes.Contains(VkPresentModeKHR.Fifo) ? VkPresentModeKHR.Fifo : VkPresentModeKHR.Immediate; SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(Context.PhysicalDevice, Surface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats); uint imageCount = swapChainSupport.Capabilities.minImageCount + 1; if (swapChainSupport.Capabilities.maxImageCount > 0 && imageCount > swapChainSupport.Capabilities.maxImageCount) { imageCount = swapChainSupport.Capabilities.maxImageCount; } SwapchainFormat = format; VkSwapchainCreateInfoKHR swapchainCI = new VkSwapchainCreateInfoKHR() { sType = VkStructureType.SwapchainCreateInfoKHR, pNext = null, surface = Surface, minImageCount = imageCount, imageFormat = format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = capabilities.currentExtent, imageUsage = VkImageUsageFlags.ColorAttachment, preTransform = capabilities.currentTransform, imageArrayLayers = 1, imageSharingMode = VkSharingMode.Exclusive, queueFamilyIndexCount = 0, pQueueFamilyIndices = null, presentMode = presentMode, //oldSwapchain = SwapChain, // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area clipped = true, compositeAlpha = VkCompositeAlphaFlagsKHR.Opaque, }; VkSwapchainKHR SwapChain; vkCreateSwapchainKHR(Context.Device, &swapchainCI, null, out SwapChain).CheckResult(); return(SwapChain); }