/// <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; }
internal Window( string title, INativeWindow nativeWindow, SurfaceKhr surface, HostDevice hostDevice, HostDeviceRequirements deviceRequirements, Logger logger = null) { if (nativeWindow == null) { throw new ArgumentNullException(nameof(nativeWindow)); } if (surface == null) { throw new ArgumentNullException(nameof(surface)); } if (hostDevice == null) { throw new ArgumentNullException(nameof(hostDevice)); } this.title = title; this.nativeWindow = nativeWindow; this.surface = surface; this.hostDevice = hostDevice; this.logger = logger; //Subscribe to callbacks for the native window nativeWindow.CloseRequested += OnNativeWindowCloseRequested; nativeWindow.Resized += OnNativeWindowResized; //Create a logical device (and queues on the device) IList <string> enabledExtensions; (logicalDevice, graphicsQueue, presentQueue, enabledExtensions) = hostDevice.CreateLogicalDevice( surface: surface, deviceRequirements: deviceRequirements); hasDebugMarkerExtension = enabledExtensions.Contains("VK_EXT_debug_marker"); if (hasDebugMarkerExtension) { logger?.Log(nameof(Window), "Enabled debug-markers"); } //Get a presentmode to use presentMode = hostDevice.GetPresentMode(surface); //Get the surfaceformat to use (surfaceFormat, surfaceColorspace) = hostDevice.GetSurfaceFormat(surface); //Gets how many swapchain images we should use swapchainCount = hostDevice.GetSwapchainCount(surface); //Create a command-pool attached to this device commandPool = logicalDevice.CreateCommandPool(new CommandPoolCreateInfo( queueFamilyIndex: graphicsQueue.FamilyIndex, flags: CommandPoolCreateFlags.None )); //Create the swapchain (images to present to the screen) CreateSwapchain(swapchainCount); //Synchronization objects are used to sync the rendering and presenting CreateSynchronizationObjects(); }
internal static SwapchainKhr CreateSwapchain(Context ctx) { // Get the window surface capabilities SurfaceCapabilitiesKhr capabilities = ctx.PhysicalDevice.GetSurfaceCapabilitiesKhr(ctx.Surface); // Get the window surface's supported formats SurfaceFormatKhr[] formats = ctx.PhysicalDevice.GetSurfaceFormatsKhr(ctx.Surface); // Get the window surface's supported present modes PresentModeKhr[] presentModes = ctx.PhysicalDevice.GetSurfacePresentModesKhr(ctx.Surface); // If the only format available is undedined then pick 32 bit BGRA Format format = formats.Length == 1 && formats[0].Format == Format.Undefined ? Format.B8G8R8A8UNorm : formats[0].Format; // Pick a present mode, preferring mailbox PresentModeKhr presentMode = presentModes.Contains(PresentModeKhr.Mailbox) ? PresentModeKhr.Mailbox : presentModes.Contains(PresentModeKhr.FifoRelaxed) ? PresentModeKhr.FifoRelaxed : presentModes.Contains(PresentModeKhr.Fifo) ? PresentModeKhr.Fifo : PresentModeKhr.Immediate; // Finally create a swapchain with the wanted settings return(ctx.Device.CreateSwapchainKhr(new SwapchainCreateInfoKhr( ctx.Surface, format, capabilities.CurrentExtent, capabilities.CurrentTransform, presentMode))); }
private void CreateSwapChain() { var swapChainSupport = new SwapChainSupportDetails(vkPhysicalDevice, vkSurface); SurfaceFormatKhr surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.formats); PresentModeKhr presentMode = ChooseSwapPresentMode(swapChainSupport.presentModes); Extent2D extent = ChooseSwapExtent(swapChainSupport.capabilities); uint imageCount = swapChainSupport.capabilities.MinImageCount + 1; if (swapChainSupport.capabilities.MaxImageCount > 0) { imageCount = Math.Min(imageCount, swapChainSupport.capabilities.MaxImageCount); } var createInfo = new SwapchainCreateInfoKhr() { MinImageCount = imageCount, ImageFormat = surfaceFormat.Format, ImageColorSpace = surfaceFormat.ColorSpace, ImageExtent = extent, ImageArrayLayers = 1, ImageUsage = ImageUsageFlags.ColorAttachment, PreTransform = swapChainSupport.capabilities.CurrentTransform, CompositeAlpha = CompositeAlphaFlagsKhr.Opaque, PresentMode = presentMode, Surface = vkSurface, }; var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface); if (indices.GraphicsFamily != indices.PresentFamily) { createInfo.ImageSharingMode = SharingMode.Concurrent; createInfo.QueueFamilyIndices = new[] { (uint)indices.GraphicsFamily, (uint)indices.PresentFamily, }; } else { createInfo.ImageSharingMode = SharingMode.Exclusive; } vkSwapChain = vkDevice.CreateSwapchainKHR(createInfo); vkSwapChainImages = vkDevice.GetSwapchainImagesKHR(vkSwapChain); vkSwapChainImageFormat = surfaceFormat.Format; vkSwapChainExtent = extent; }
private PresentModeKhr ChooseSwapPresentMode(PresentModeKhr[] presentModes) { PresentModeKhr bestMode = PresentModeKhr.Fifo; foreach (var availablePresentMode in presentModes) { if (availablePresentMode == PresentModeKhr.Mailbox) { return(availablePresentMode); } else if (availablePresentMode == PresentModeKhr.Immediate) { bestMode = PresentModeKhr.Immediate; } } return(bestMode); }
private SwapchainKhr CreateSwapchain() { SurfaceCapabilitiesKhr capabilities = Context.PhysicalDevice.GetSurfaceCapabilitiesKhr(Surface); SurfaceFormatKhr[] formats = Context.PhysicalDevice.GetSurfaceFormatsKhr(Surface); PresentModeKhr[] presentModes = Context.PhysicalDevice.GetSurfacePresentModesKhr(Surface); Format format = formats.Length == 1 && formats[0].Format == Format.Undefined ? Format.B8G8R8A8UNorm : formats[0].Format; PresentModeKhr presentMode = presentModes.Contains(PresentModeKhr.Mailbox) ? PresentModeKhr.Mailbox : presentModes.Contains(PresentModeKhr.FifoRelaxed) ? PresentModeKhr.FifoRelaxed : presentModes.Contains(PresentModeKhr.Fifo) ? PresentModeKhr.Fifo : PresentModeKhr.Immediate; return(Context.Device.CreateSwapchainKhr(new SwapchainCreateInfoKhr( Surface, format, capabilities.CurrentExtent, capabilities.CurrentTransform, presentMode))); }
public static bool TryCreateSwapChain(Instance instance, PhysicalDevice physicalDevice, Device device, SurfaceKhr surface, uint queue, ref System.Drawing.Size size, Format format, ColorSpaceKhr colorSpace, PresentModeKhr presentMode, ref SwapchainKhr swapchain) { SwapchainCreateInfoKhr swapChainCreateInfo = new SwapchainCreateInfoKhr { Surface = surface, MinImageCount = 2, ImageFormat = format, ImageColorSpace = colorSpace, ImageExtent = ToExtent2D(size), ImageArrayLayers = 1, ImageUsage = ImageUsageFlags.ColorAttachment, ImageSharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint[] { queue }, PreTransform = SurfaceTransformFlagsKhr.Inherit, CompositeAlpha = CompositeAlphaFlagsKhr.Opaque, // TODO : set this to Ingerit if it can be fixed in Check PresentMode = presentMode, Clipped = false, OldSwapchain = swapchain, }; if (!CheckSwapchainCreateInfo(physicalDevice, swapChainCreateInfo, true)) { return(false); } size.Width = (int)swapChainCreateInfo.ImageExtent.Width; size.Height = (int)swapChainCreateInfo.ImageExtent.Height; SwapchainKhr newSwapchain = device.CreateSwapchainKHR(swapChainCreateInfo); if (newSwapchain != null) { swapchain = newSwapchain; return(true); } return(false); }
public void CreateSwapChain(PresentModeKhr presentMode, uint imageCount) { SwapchainKhr oldSwapChain = SwapChain; if (SwapSurface == null) { // == Create Surface for Swap Chain IntPtr hInstance = System.Runtime.InteropServices.Marshal.GetHINSTANCE(this.GetType().Module); Win32SurfaceCreateInfoKhr surfaceInfo = new Win32SurfaceCreateInfoKhr() { Hwnd = window.Handle, Flags = 0, Hinstance = hInstance, }; SurfaceKhr surface = Instance.CreateWin32SurfaceKHR(surfaceInfo, null); QueueInfo graphicsQueueInfo = GetQueue(QueueFlags.Graphics); Queue graphicsQueue = Device.GetQueue(graphicsQueueInfo.queueFamilyIndex, graphicsQueueInfo.queueIndex); SwapSurface = surface; } // == Create Swap Chain // TODO : this is bugged in Vulkan-Mono PresentModeKhr can not be called from Marshal.SizeOf /*bool presentModeSupported = false; * PresentModeKhr[] presentModes = Gpu.GetSurfacePresentModesKHR(SwapSurface); * foreach (PresentModeKhr checkMode in presentModes) * { * if(checkMode == presentMode) * { * presentModeSupported = true; * break; * } * } * if(!presentModeSupported ) * { * throw new Exception("PresentMode :" + presentMode + " not supported by gpu."); * }*/ SurfaceCapabilitiesKhr surfaceCapabilities = Gpu.GetSurfaceCapabilitiesKHR(SwapSurface); if (surfaceCapabilities.CurrentExtent.Width == uint.MaxValue) { BackBufferWidth = (uint)window.Width; BackBufferHeight = (uint)window.Height; } else { BackBufferWidth = surfaceCapabilities.CurrentExtent.Width; BackBufferHeight = surfaceCapabilities.CurrentExtent.Height; } uint reqImageCount = surfaceCapabilities.MinImageCount + imageCount; if (reqImageCount > 0 && reqImageCount > surfaceCapabilities.MaxImageCount) { reqImageCount = surfaceCapabilities.MaxImageCount; } SurfaceFormatKhr[] surfaceFormats = Gpu.GetSurfaceFormatsKHR(SwapSurface); Format format = surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined ? Format.B8g8r8a8Unorm : surfaceFormats[0].Format; SurfaceTransformFlagsKhr preTransform = (surfaceCapabilities.SupportedTransforms & SurfaceTransformFlagsKhr.Identity) == SurfaceTransformFlagsKhr.Identity ? SurfaceTransformFlagsKhr.Identity : surfaceCapabilities.CurrentTransform; SwapchainCreateInfoKhr swapChainInfo = new SwapchainCreateInfoKhr { Surface = SwapSurface, MinImageCount = reqImageCount, ImageFormat = format, ImageColorSpace = surfaceFormats[0].ColorSpace, ImageExtent = new Extent2D { Width = BackBufferWidth, Height = BackBufferHeight, }, ImageUsage = (uint)ImageUsageFlags.ColorAttachment, PreTransform = preTransform, CompositeAlpha = CompositeAlphaFlagsKhr.Opaque, ImageArrayLayers = 1, ImageSharingMode = SharingMode.Exclusive, PresentMode = presentMode, // TODO : Vulkan : we cant assing a null swapChain //OldSwapchain = oldSwapChain != null ? oldSwapChain : null, Clipped = true, }; if (oldSwapChain != null) { // this is a workaround as we cant assing a null one swapChainInfo.OldSwapchain = oldSwapChain; Device.DestroySwapchainKHR(oldSwapChain, null); oldSwapChain = null; } SwapchainKhr swapChain = Device.CreateSwapchainKHR(swapChainInfo, null); // == Create Images Image[] swapImages = Device.GetSwapchainImagesKHR(swapChain); SwapChainBuffer[] buffers = new SwapChainBuffer[swapImages.Length]; for (uint i = 0; i < buffers.Length; i++) { ImageViewCreateInfo imageViewInfo = new ImageViewCreateInfo { Format = format, Components = new ComponentMapping { R = ComponentSwizzle.R, G = ComponentSwizzle.G, B = ComponentSwizzle.B, A = ComponentSwizzle.A, }, SubresourceRange = new ImageSubresourceRange { AspectMask = (uint)ImageAspectFlags.Color, BaseMipLevel = 1, BaseArrayLayer = 0, LayerCount = 1, }, ViewType = ImageViewType.View2D, Flags = 0, Image = swapImages[i], }; ImageView view = Device.CreateImageView(imageViewInfo, null); buffers[i] = new SwapChainBuffer { image = swapImages[i], view = view, }; } }
public void Create(CommandBuffer commandBuffer) { var surfaceCapabilities = PhysicalDevice.GetSurfaceCapabilitiesKHR(Surface); Extent2D swapChainExtend = new Extent2D { Width = surfaceCapabilities.CurrentExtent.Width, Height = surfaceCapabilities.CurrentExtent.Height }; var presentModes = PhysicalDevice.GetSurfacePresentModesKHR(Surface); PresentModeKhr presentMode = GetBestPresentMode(presentModes); var desiredImages = surfaceCapabilities.MinImageCount + 1; if (surfaceCapabilities.MaxImageCount > 0 && desiredImages > surfaceCapabilities.MaxImageCount) { desiredImages = surfaceCapabilities.MaxImageCount; } var preTransform = surfaceCapabilities.CurrentTransform; if (surfaceCapabilities.SupportedTransforms.HasFlag(SurfaceTransformFlagsKhr.Identity)) { preTransform = SurfaceTransformFlagsKhr.Identity; } var oldSwapChain = Swapchain; var swapChainCreateInfo = new SwapchainCreateInfoKhr { Surface = Surface, MinImageCount = desiredImages, ImageFormat = ColorFormat, ImageColorSpace = ColorSpace, ImageExtent = swapChainExtend, ImageUsage = ImageUsageFlags.ColorAttachment, PreTransform = preTransform, ImageArrayLayers = 1, ImageSharingMode = SharingMode.Exclusive, QueueFamilyIndexCount = 0, QueueFamilyIndices = null, PresentMode = presentMode, Clipped = true, // Alpha on the window surface should be opaque: // If it was not we could create transparent regions of our window which // would require support from the Window compositor. You can totally do // that if you wanted though ;) CompositeAlpha = CompositeAlphaFlagsKhr.Opaque }; Swapchain = Device.CreateSwapchainKHR(swapChainCreateInfo); if (oldSwapChain != null) { Device.DestroySwapchainKHR(oldSwapChain); } Images = Device.GetSwapchainImagesKHR(Swapchain).ToList(); // Create the image views for the swap chain. They will all be single // layer, 2D images, with no mipmaps. // Check the VkImageViewCreateInfo structure to see other views you // can potentially create. for (var i = 0; i < Images.Count; i++) { var buffer = new SwapChainBuffer(); var colorAttachmentView = new ImageViewCreateInfo { Format = ColorFormat, Components = new ComponentMapping { R = ComponentSwizzle.R, G = ComponentSwizzle.G, B = ComponentSwizzle.B, A = ComponentSwizzle.A }, SubresourceRange = new ImageSubresourceRange { AspectMask = ImageAspectFlags.Color, BaseMipLevel = 0, LevelCount = 1, BaseArrayLayer = 0, LayerCount = 1 }, ViewType = ImageViewType.View2D }; buffer.Image = Images[i]; SetImageLayout(commandBuffer, buffer.Image, ImageAspectFlags.Color, ImageLayout.Undefined, ImageLayout.PresentSrcKhr); buffer.View = Device.CreateImageView(colorAttachmentView); Buffers.Add(buffer); } }