internal SwapchainKhr(Device parent, ref SwapchainCreateInfoKhr createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; Format = createInfo.ImageFormat; long handle; createInfo.ToNative(out SwapchainCreateInfoKhr.Native nativeCreateInfo); Result result = vkCreateSwapchainKHR(Parent, &nativeCreateInfo, NativeAllocator, &handle); nativeCreateInfo.Free(); VulkanException.ThrowForInvalidResult(result); Handle = handle; }
private void rebuildSwapchain() { var sCaps = VkKhr.PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr(_vkPhysicalDevice, Surface); // Calculate the size of the images if (sCaps.CurrentExtent.Width != Int32.MaxValue) // We have to use the given size { Extent = sCaps.CurrentExtent; } else // We can choose an extent, but we will just make it the size of the window { Extent = Point.Max(sCaps.MinImageExtent, Point.Min(sCaps.MaxImageExtent, _window.Size)); } // Calculate the number of images int imCount = sCaps.MinImageCount + 1; if (sCaps.MaxImageCount != 0) { imCount = Math.Min(imCount, sCaps.MaxImageCount); } _syncObjects.MaxInflightFrames = (uint)Math.Min(imCount, MAX_INFLIGHT_FRAMES); // Create the swapchain var oldSwapChain = _swapChain; VkKhr.SwapchainCreateInfoKhr cInfo = new VkKhr.SwapchainCreateInfoKhr( Surface, _surfaceFormat.Format, Extent, minImageCount: imCount, imageColorSpace: _surfaceFormat.ColorSpace, imageUsage: Vk.ImageUsages.ColorAttachment | Vk.ImageUsages.TransferDst, presentMode: _presentMode, oldSwapchain: oldSwapChain ); _swapChain = VkKhr.DeviceExtensions.CreateSwapchainKhr(_vkDevice, cInfo); // Destroy the old swapchain oldSwapChain?.Dispose(); // Get the new swapchain images var imgs = _swapChain.GetImages(); _swapChainImages = new SwapchainImage[imgs.Length]; imgs.ForEach((img, idx) => { Vk.ImageViewCreateInfo vInfo = new Vk.ImageViewCreateInfo( _surfaceFormat.Format, DEFAULT_SUBRESOURCE_RANGE, viewType: Vk.ImageViewType.Image2D, components: default ); var view = img.CreateView(vInfo); _swapChainImages[idx] = new SwapchainImage { Image = img, View = view, TransferBarrier = new Vk.ImageMemoryBarrier( img, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1), Vk.Accesses.ColorAttachmentRead, Vk.Accesses.TransferWrite, Vk.ImageLayout.PresentSrcKhr, Vk.ImageLayout.TransferDstOptimal ), PresentBarrier = new Vk.ImageMemoryBarrier( img, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1), Vk.Accesses.TransferWrite, Vk.Accesses.ColorAttachmentRead, Vk.ImageLayout.TransferDstOptimal, Vk.ImageLayout.PresentSrcKhr ) }; }); // Perform the initial layout transitions to present mode _commandBuffer.Begin(ONE_TIME_SUBMIT); var imb = new Vk.ImageMemoryBarrier(null, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1), Vk.Accesses.TransferWrite, Vk.Accesses.ColorAttachmentRead, Vk.ImageLayout.Undefined, Vk.ImageLayout.PresentSrcKhr); _commandBuffer.CmdPipelineBarrier(Vk.PipelineStages.AllCommands, Vk.PipelineStages.AllCommands, imageMemoryBarriers: _swapChainImages.Select(sci => { imb.Image = sci.Image; return(imb); }).ToArray()); _commandBuffer.End(); _presentQueue.Submit(new Vk.SubmitInfo(commandBuffers: new[] { _commandBuffer }), _blitFence); _blitFence.Wait(); // Do not reset // Report LDEBUG($"Presentation swapchain rebuilt @ {Extent} " + $"(F:{_surfaceFormat.Format}:{_surfaceFormat.ColorSpace==VkKhr.ColorSpaceKhr.SRgbNonlinear} I:{_swapChainImages.Length}:{_syncObjects.MaxInflightFrames})."); Dirty = false; }
/// <summary> /// Create a swapchain. /// </summary> /// <param name="device">The device to create the swapchain for.</param> /// <param name="createInfo">The structure specifying the parameters of the created swapchain.</param> /// <param name="allocator"> /// The allocator used for host memory allocated for the swapchain object when there is no /// more specific allocator available. /// </param> /// <returns>Created swapchain object.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static SwapchainKhr CreateSwapchainKhr(this Device device, SwapchainCreateInfoKhr createInfo, AllocationCallbacks?allocator = null) { return(new SwapchainKhr(device, ref createInfo, ref allocator)); }