void CreateSwapchain() { var support = GetSwapchainSupport(physicalDevice); var cap = support.cap; var surfaceFormat = ChooseSwapSurfaceFormat(support.formats); var mode = ChooseSwapPresentMode(support.modes); var extent = ChooseSwapExtent(ref cap); int imageCount = cap.minImageCount + 1; if (cap.maxImageCount > 0 && imageCount > cap.maxImageCount) { imageCount = cap.maxImageCount; } var oldSwapchain = swapchain; var info = new VkSwapchainCreateInfo(); info.surface = surface; info.oldSwapchain = oldSwapchain; info.minImageCount = imageCount; info.imageFormat = surfaceFormat.format; info.imageColorSpace = surfaceFormat.colorSpace; info.imageExtent = extent; info.imageArrayLayers = 1; info.imageUsage = VkImageUsageFlags.ColorAttachmentBit; var queueFamilyIndices = new List <int> { graphicsIndex, presentIndex }; if (graphicsIndex != presentIndex) { info.imageSharingMode = VkSharingMode.Concurrent; info.queueFamilyIndices = queueFamilyIndices; } else { info.imageSharingMode = VkSharingMode.Exclusive; } info.preTransform = cap.currentTransform; info.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueBitKhr; info.presentMode = mode; info.clipped = true; swapchain = new VkSwapchain(device, info); oldSwapchain?.Dispose(); swapchainImages = new List <VkImage>(swapchain.Images); swapchainImageFormat = surfaceFormat.format; swapchainExtent = extent; }
private SwapchainKHR CreateSwapchain(out Extent2D extent, out Format swapImageFormat, out SwapchainImage[] swapImages) { QuerySwapchainSupport(this.PhysicalDevice, out var details); var surfaceFormat = ChooseSwapSurfaceFormat(details.Formats); var presentMode = ChooseSwapPresentMode(details.PresentModes); extent = ChooseSwapExtent(details.Capabilities); var imageCount = details.Capabilities.MinImageCount + 1; if (details.Capabilities.MaxImageCount > 0 && imageCount > details.Capabilities.MaxImageCount) { imageCount = details.Capabilities.MaxImageCount; } var createInfo = new SwapchainCreateInfoKHR { SType = StructureType.SwapchainCreateInfoKhr, Surface = this.WindowSurface, MinImageCount = imageCount, ImageFormat = surfaceFormat.Format, ImageColorSpace = surfaceFormat.ColorSpace, ImageExtent = extent, ImageArrayLayers = 1, ImageUsage = ImageUsageFlags.ImageUsageColorAttachmentBit }; if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily) { createInfo.ImageSharingMode = SharingMode.Concurrent; createInfo.QueueFamilyIndexCount = 2; var indices = stackalloc uint[2] { this.QueueIndices.GraphicsFamily.Value, this.QueueIndices.PresentFamily.Value }; createInfo.PQueueFamilyIndices = indices; } else { createInfo.ImageSharingMode = SharingMode.Exclusive; } createInfo.PreTransform = details.Capabilities.CurrentTransform; createInfo.CompositeAlpha = CompositeAlphaFlagsKHR.CompositeAlphaOpaqueBitKhr; createInfo.PresentMode = presentMode; createInfo.Clipped = true; createInfo.OldSwapchain = default; SwapchainKHR swapchain; var res = this.VkSwapchain.CreateSwapchain(Device, &createInfo, null, &swapchain); if (res != Result.Success) { throw new VMASharp.VulkanResultException("Failed to create swapchain!", res); } uint count = 0; res = VkSwapchain.GetSwapchainImages(this.Device, swapchain, &count, null); if (res != Result.Success) { throw new VMASharp.VulkanResultException("Failed to retrieve swapchain images!", res); } var images = stackalloc Image[(int)count]; res = VkSwapchain.GetSwapchainImages(this.Device, swapchain, &count, images); if (res != Result.Success) { throw new VMASharp.VulkanResultException("Failed to retrieve swapchain images!", res); } var viewCreateInfo = new ImageViewCreateInfo { SType = StructureType.ImageViewCreateInfo, ViewType = ImageViewType.ImageViewType2D, Format = surfaceFormat.Format, Components = { R = ComponentSwizzle.Identity, G = ComponentSwizzle.Identity, B = ComponentSwizzle.Identity, A = ComponentSwizzle.Identity }, SubresourceRange = { AspectMask = ImageAspectFlags.ImageAspectColorBit, BaseMipLevel = 0, LevelCount = 1, BaseArrayLayer = 0, LayerCount = 1 } }; var arr = new SwapchainImage[count]; for (int i = 0; i < arr.Length; ++i) { viewCreateInfo.Image = images[i]; ImageView view = default; res = VkApi.CreateImageView(this.Device, &viewCreateInfo, null, &view); if (res != Result.Success) { throw new VMASharp.VulkanResultException("Swapchain image view creation failed!", res); } arr[i] = new SwapchainImage { Image = images[i], View = view }; } swapImageFormat = surfaceFormat.Format; swapImages = arr; return(swapchain); }