/// <summary> /// Initializes a new instance of the <see cref="SwapchainCreateInfoKhr"/> structure. /// </summary> /// <param name="surface"> /// The <see cref="SurfaceKhr"/> that the swapchain will present images to. /// </param> /// <param name="imageExtent"> /// The size (in pixels) of the swapchain. /// <para> /// Behavior is platform-dependent when the image extent does not match the surface's <see /// cref="SurfaceCapabilitiesKhr.CurrentExtent"/> as returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>. /// </para> /// </param> /// <param name="preTransform"> /// A bitmask describing the transform, relative to the presentation engine's natural /// orientation, applied to the image content prior to presentation. /// <para> /// If it does not match the <see cref="SurfaceCapabilitiesKhr.CurrentTransform"/> value /// returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>, the /// presentation engine will transform the image content as part of the presentation operation. /// </para> /// </param> /// <param name="imageUsage"> /// A bitmask indicating how the application will use the swapchain's presentable images. /// </param> /// <param name="flags">A bitmask indicating parameters of swapchain creation.</param> /// <param name="minImageCount"> /// The minimum number of presentable images that the application needs. The platform will /// either create the swapchain with at least that many images, or will fail to create the swapchain. /// </param> /// <param name="imageFormat">A format that is valid for swapchains on the specified surface.</param> /// <param name="compositeAlpha"> /// A bitmask indicating the alpha compositing mode to use when this surface is composited /// together with other surfaces on certain window systems. /// </param> /// <param name="imageArrayLayers"> /// The number of views in a multiview/stereo surface. For non-stereoscopic-3D applications, /// this value is 1. /// </param> /// <param name="presentMode"> /// The presentation mode the swapchain will use. /// <para> /// A swapchain's present mode determines how incoming present requests will be processed and /// queued internally. /// </para> /// </param> /// <param name="clipped"> /// Indicates whether the Vulkan implementation is allowed to discard rendering operations /// that affect regions of the surface which are not visible. /// </param> /// <param name="oldSwapchain">Existing swapchain to replace, if any.</param> public SwapchainCreateInfoKhr( SurfaceKhr surface, Format imageFormat, Extent2D imageExtent, SurfaceTransformsKhr preTransform, PresentModeKhr presentMode, SwapchainCreateFlagsKhr flags = 0, int minImageCount = 2, ImageUsages imageUsage = ImageUsages.ColorAttachment | ImageUsages.TransferDst, CompositeAlphasKhr compositeAlpha = CompositeAlphasKhr.Opaque, int imageArrayLayers = 1, bool clipped = true, SwapchainKhr oldSwapchain = null) { Flags = flags; Surface = surface; ImageUsage = imageUsage; MinImageCount = minImageCount; ImageFormat = imageFormat; ImageColorSpace = 0; ImageExtent = imageExtent; ImageArrayLayers = imageArrayLayers; ImageSharingMode = 0; QueueFamilyIndices = null; PreTransform = preTransform; CompositeAlpha = compositeAlpha; PresentMode = presentMode; Clipped = clipped; OldSwapchain = oldSwapchain; }
/// <summary> /// Initializes a new instance of the <see cref="SwapchainCreateInfoKhr"/> structure. /// </summary> /// <param name="surface"> /// The <see cref="SurfaceKhr"/> that the swapchain will present images to. /// </param> /// <param name="imageFormat">A format that is valid for swapchains on the specified surface.</param> /// <param name="imageExtent"> /// The size (in pixels) of the swapchain. /// <para> /// Behavior is platform-dependent when the image extent does not match the surface's <see /// cref="SurfaceCapabilitiesKhr.CurrentExtent"/> as returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>. /// </para> /// </param> /// <param name="minImageCount"> /// The minimum number of presentable images that the application needs. The platform will /// either create the swapchain with at least that many images, or will fail to create the swapchain. /// </param> /// <param name="imageColorSpace">Color space value specifying the way the swapchain interprets image data.</param> /// <param name="imageArrayLayers"> /// The number of views in a multiview/stereo surface. /// <para>For non-stereoscopic-3D applications, this value is 1.</para> /// </param> /// <param name="imageUsage">A bitmask describing the intended usage of the (acquired) swapchain images.</param> /// <param name="imageSharingMode">The sharing mode used for the image(s) of the swapchain.</param> /// <param name="queueFamilyIndices"> /// Queue family indices having access to the image(s) of the swapchain when <see /// cref="ImageSharingMode"/> is <see cref="SharingMode.Concurrent"/>. /// </param> /// <param name="preTransform"> /// A value describing the transform, relative to the presentation engine's natural /// orientation, applied to the image content prior to presentation. /// <para> /// If it does not match the <see cref="SurfaceCapabilitiesKhr.CurrentTransform"/> value /// returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>, the /// presentation engine will transform the image content as part of the presentation operation. /// </para> /// </param> /// <param name="compositeAlpha"> /// A bitmask indicating the alpha compositing mode to use when this surface is composited /// together with other surfaces on certain window systems. /// </param> /// <param name="presentMode"> /// The presentation mode the swapchain will use. /// <para> /// A swapchain's present mode determines how incoming present requests will be processed and /// queued internally. /// </para> /// </param> /// <param name="clipped"> /// Indicates whether the Vulkan implementation is allowed to discard rendering operations /// that affect regions of the surface which are not visible.</param> /// <param name="oldSwapchain">Existing swapchain to replace, if any.</param> public SwapchainCreateInfoKhr( SurfaceKhr surface, Format imageFormat, Extent2D imageExtent, int minImageCount = 2, ColorSpaceKhr imageColorSpace = ColorSpaceKhr.SRgbNonlinear, int imageArrayLayers = 1, ImageUsages imageUsage = ImageUsages.ColorAttachment | ImageUsages.TransferDst, SharingMode imageSharingMode = SharingMode.Exclusive, int[] queueFamilyIndices = null, SurfaceTransformsKhr preTransform = SurfaceTransformsKhr.Identity, CompositeAlphasKhr compositeAlpha = CompositeAlphasKhr.Opaque, PresentModeKhr presentMode = PresentModeKhr.Fifo, bool clipped = true, SwapchainKhr oldSwapchain = null) { Flags = SwapchainCreateFlagsKhr.None; Surface = surface; MinImageCount = minImageCount; ImageFormat = imageFormat; ImageColorSpace = imageColorSpace; ImageExtent = imageExtent; ImageArrayLayers = imageArrayLayers; ImageUsage = imageUsage; ImageSharingMode = imageSharingMode; QueueFamilyIndices = queueFamilyIndices; PreTransform = preTransform; CompositeAlpha = compositeAlpha; PresentMode = presentMode; Clipped = clipped; OldSwapchain = oldSwapchain; }
public Swapchain(GraphicsDevice gdevice, Vk.Instance instance, Vk.PhysicalDevice pDevice, Vk.Device device) { Device = gdevice; _window = gdevice.Application.Window; _vkInstance = instance; _vkPhysicalDevice = pDevice; _vkDevice = device; // Create the surface long surfHandle = Glfw.CreateWindowSurface(instance, _window.Handle); Vk.AllocationCallbacks?acb = null; Surface = new VkKhr.SurfaceKhr(instance, ref acb, surfHandle); if (VkKhr.PhysicalDeviceExtensions.GetSurfaceSupportKhr(pDevice, gdevice.Queues.Graphics.FamilyIndex, Surface) == Vk.Constant.False) { LFATAL($"The physical device '{gdevice.Info.Name}' does not support surface presentation."); throw new PlatformNotSupportedException("Physical device does not support surface presentation."); } LINFO("Created Vulkan presentation surface."); // Check the surface for swapchain support levels var sFmts = VkKhr.PhysicalDeviceExtensions.GetSurfaceFormatsKhr(pDevice, Surface); var pModes = VkKhr.PhysicalDeviceExtensions.GetSurfacePresentModesKhr(pDevice, Surface); if (sFmts.Length == 0) { throw new PlatformNotSupportedException("The chosen device does not support any presentation formats."); } if (pModes.Length == 0) { throw new PlatformNotSupportedException("The chosen device does not support any presentation modes."); } // Choose the best available surface format if (sFmts.Length == 1 && sFmts[0].Format == Vk.Format.Undefined) // We are allowed to pick! { _surfaceFormat = PREFERRED_SURFACE_FORMATS[0]; } else // Check if one of the preferred formats is available, otherwise just use the first format given { var sfmt = PREFERRED_SURFACE_FORMATS.FirstOrDefault(fmt => sFmts.Contains(fmt)); if (sfmt.Format == 0 && sfmt.ColorSpace == 0) { _surfaceFormat = sFmts[0]; } else { _surfaceFormat = sfmt; } } // Choose the presentation mode (prefer mailbox -> fifo -> imm) _presentMode = pModes.Contains(VkKhr.PresentModeKhr.Mailbox) ? VkKhr.PresentModeKhr.Mailbox : pModes.Contains(VkKhr.PresentModeKhr.Fifo) ? VkKhr.PresentModeKhr.Fifo : VkKhr.PresentModeKhr.Immediate; // Prepare the synchronization objects _syncObjects.ImageAvailable = new Vk.Semaphore[MAX_INFLIGHT_FRAMES]; _syncObjects.BlitComplete = new Vk.Semaphore[MAX_INFLIGHT_FRAMES]; for (int i = 0; i < MAX_INFLIGHT_FRAMES; ++i) { _syncObjects.ImageAvailable[i] = device.CreateSemaphore(); _syncObjects.BlitComplete[i] = device.CreateSemaphore(); } // Setup the command buffers var cpci = new Vk.CommandPoolCreateInfo(_presentQueue.FamilyIndex, Vk.CommandPoolCreateFlags.Transient | Vk.CommandPoolCreateFlags.ResetCommandBuffer); _commandPool = device.CreateCommandPool(cpci); var cbai = new Vk.CommandBufferAllocateInfo(Vk.CommandBufferLevel.Primary, 1); _commandBuffer = _commandPool.AllocateBuffers(cbai)[0]; _blitFence = device.CreateFence(); // Do NOT start this signalled, as it is needed in rebuildSwapchain() below _rtTransferBarrier = new Vk.ImageMemoryBarrier( null, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1), Vk.Accesses.ColorAttachmentWrite, Vk.Accesses.TransferRead, Vk.ImageLayout.ColorAttachmentOptimal, Vk.ImageLayout.TransferSrcOptimal ); _rtAttachBarrier = new Vk.ImageMemoryBarrier( null, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1), Vk.Accesses.TransferRead, Vk.Accesses.ColorAttachmentWrite, Vk.ImageLayout.TransferSrcOptimal, Vk.ImageLayout.ColorAttachmentOptimal ); // Build the swapchain rebuildSwapchain(); }