public static bool CheckSwapchainCreateInfo(PhysicalDevice physicalDevice, SwapchainCreateInfoKhr createInfo, bool fixExtend) { SurfaceKhr surface = createInfo.Surface; foreach (uint index in createInfo.QueueFamilyIndices) { if (!physicalDevice.GetSurfaceSupportKHR(index, surface)) { return(false); } } bool supportImageFormat = false; foreach (SurfaceFormatKhr suportedFormat in physicalDevice.GetSurfaceFormatsKHR(surface)) { if (suportedFormat.Format == createInfo.ImageFormat && suportedFormat.ColorSpace == createInfo.ImageColorSpace) { supportImageFormat = true; break; } } if (!supportImageFormat) { return(false); } SurfaceCapabilitiesKhr capabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface); if (fixExtend) { var extend = createInfo.ImageExtent; extend.Width = Clamp(extend.Width, capabilities.MinImageExtent.Width, capabilities.MaxImageExtent.Width); extend.Height = Clamp(extend.Height, capabilities.MinImageExtent.Height, capabilities.MaxImageExtent.Height); createInfo.ImageExtent = extend; } if (createInfo.PreTransform == SurfaceTransformFlagsKhr.Inherit) { createInfo.PreTransform = capabilities.CurrentTransform; } // TODO: Fix up CompositeAlpha if Inherit is set if (capabilities.MinImageCount <= createInfo.MinImageCount && capabilities.MaxImageCount >= createInfo.MinImageCount && capabilities.MaxImageArrayLayers <= createInfo.ImageArrayLayers && ((capabilities.SupportedTransforms & createInfo.PreTransform) == createInfo.PreTransform) && ((capabilities.SupportedCompositeAlpha & createInfo.CompositeAlpha) == createInfo.CompositeAlpha) && ((capabilities.SupportedUsageFlags & createInfo.ImageUsage) == createInfo.ImageUsage) && createInfo.ImageExtent.Width >= capabilities.MinImageExtent.Width && createInfo.ImageExtent.Width <= capabilities.MaxImageExtent.Width && createInfo.ImageExtent.Height >= capabilities.MinImageExtent.Height && createInfo.ImageExtent.Height <= capabilities.MaxImageExtent.Height) { return(true); } return(false); }
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; }
protected void CreateSwapChain() { format = ChooseFormat(data.formats); var presentMode = ChoosePresentMode(data.presentModes); extent = ChooseSwapExtent(); var imageCount = data.surfaceCapabilities.MinImageCount + 1; if (data.surfaceCapabilities.MaxImageCount > 0 && imageCount > data.surfaceCapabilities.MaxImageCount) { imageCount = data.surfaceCapabilities.MaxImageCount; } var swapChainInfo = new SwapchainCreateInfoKhr { Surface = data.surface, MinImageCount = imageCount, ImageFormat = format.Format, ImageColorSpace = format.ColorSpace, ImageExtent = extent, ImageArrayLayers = 1, ImageUsage = ImageUsageFlags.ColorAttachment, PreTransform = data.surfaceCapabilities.CurrentTransform, CompositeAlpha = CompositeAlphaFlagsKhr.Opaque, PresentMode = presentMode, Clipped = true }; var indices = data.queueFamilyIndices; var queueFamilyIndices = new uint[] { (uint)indices.GraphicsFamily, (uint)indices.PresentFamily }; if (indices.PresentFamily != indices.GraphicsFamily) { swapChainInfo.ImageSharingMode = SharingMode.Concurrent; swapChainInfo.QueueFamilyIndexCount = (uint)queueFamilyIndices.Length; swapChainInfo.QueueFamilyIndices = queueFamilyIndices; } else { swapChainInfo.ImageSharingMode = SharingMode.Exclusive; } swapchain = device.CreateSwapchainKHR(swapChainInfo); images = device.GetSwapchainImagesKHR(swapchain); bufferSize = imageCount; }
SwapchainKhr CreateSwapchain(SurfaceKhr surface, SurfaceFormatKhr surfaceFormat) { var swapchainInfo = new SwapchainCreateInfoKhr { Surface = surface, MinImageCount = surfaceCapabilities.MinImageCount, ImageFormat = surfaceFormat.Format, ImageColorSpace = surfaceFormat.ColorSpace, ImageExtent = surfaceCapabilities.CurrentExtent, ImageUsage = ImageUsageFlags.ColorAttachment, PreTransform = SurfaceTransformFlagsKhr.Identity, ImageArrayLayers = 1, ImageSharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint [] { 0 }, PresentMode = PresentModeKhr.Fifo, CompositeAlpha = CompositeAlphaFlagsKhr.Inherit }; return(device.CreateSwapchainKHR(swapchainInfo)); }
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); }
/// <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)); }
private void CreateSwapchain(int swapchainCount) { SurfaceCapabilitiesKhr capabilities = hostDevice.GetCurrentCapabilities(surface); //Clamp the size to within the min and max extends reported by the surface capabilities swapchainSize = nativeWindow.ClientRect.Size.Clamp( new Int2(capabilities.MinImageExtent.Width, capabilities.MinImageExtent.Height), new Int2(capabilities.MaxImageExtent.Width, capabilities.MaxImageExtent.Height)); //Gather info about the swapchain var createInfo = new SwapchainCreateInfoKhr ( surface: surface, minImageCount: swapchainCount, imageFormat: surfaceFormat, imageColorSpace: surfaceColorspace, imageExtent: new Extent2D(swapchainSize.X, swapchainSize.Y), imageArrayLayers: 1, imageUsage: ImageUsages.ColorAttachment, //If the graphics and present queues are different we need to allow sharing the //swapchain images imageSharingMode: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ? SharingMode.Exclusive : SharingMode.Concurrent, queueFamilyIndices: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ? null : new [] { graphicsQueue.FamilyIndex, presentQueue.FamilyIndex }, preTransform: capabilities.CurrentTransform, compositeAlpha: CompositeAlphasKhr.Opaque, presentMode: presentMode, clipped: true ); //Create the swapchain swapchain = logicalDevice.CreateSwapchainKhr(createInfo); var swapchainImages = swapchain.GetImages(); //Verify that we got the amount of images we expected if (swapchainImages.Length != swapchainCount) { throw new Exception( $"[{nameof(Window)}] Incorrect number of swapchain images acquired, expected: {swapchainCount}, got: {swapchainImages.Length}"); } //Create the image targets swapchainTextures = new DeviceTexture[swapchainCount]; for (int i = 0; i < swapchainTextures.Length; i++) { swapchainTextures[i] = DeviceTexture.CreateSwapchainTarget( swapchainSize, surfaceFormat, swapchainImages[i]); } logger?.Log(nameof(Window), $@"Swapchain created: {{ size: {swapchainSize}, texCount: {swapchainTextures.Length}, mode: {presentMode}, format: {surfaceFormat}, colorSpace: {surfaceColorspace} }}"); }
public bool CreateSwapChain(DrunkSpock spock, int extentX, int extentY) { PhysicalDevice phys = mLogical.Parent; SurfaceKhr surf = spock.GetSurface(); SurfaceCapabilitiesKhr surfCaps = phys.GetSurfaceCapabilitiesKhr(surf); SurfaceFormatKhr [] surfFormats = phys.GetSurfaceFormatsKhr(surf); PresentModeKhr [] presModes = phys.GetSurfacePresentModesKhr(surf); if (surfFormats.Length <= 0 || presModes.Length <= 0) { Misc.SafeInvoke(eErrorSpam, "Bad formats or pres modes..."); return(false); } mSwapExtent = new Extent2D(extentX, extentY); int imageCount = surfCaps.MinImageCount + 1; if (surfCaps.MaxImageCount > 0 && imageCount > surfCaps.MaxImageCount) { imageCount = surfCaps.MaxImageCount; } SwapchainCreateInfoKhr scci = new SwapchainCreateInfoKhr( surf, Format.B8G8R8A8UNorm, mSwapExtent, imageCount, ColorSpaceKhr.SRgbNonlinear, 1, ImageUsages.ColorAttachment); scci.ImageSharingMode = SharingMode.Exclusive; if (presModes.Contains(PresentModeKhr.Mailbox)) { scci.PresentMode = PresentModeKhr.Mailbox; } mSwapChain = mLogical.CreateSwapchainKhr(scci); if (mSwapChain == null) { Misc.SafeInvoke(eErrorSpam, "Create swap chain failed..."); return(false); } VulkanCore.Image [] chainImages = mSwapChain.GetImages(); mChainImageViews = new ImageView[chainImages.Length]; for (int i = 0; i < chainImages.Length; i++) { ImageSubresourceRange isr = new ImageSubresourceRange( ImageAspects.Color, 0, 1, 0, 1); ImageViewCreateInfo ivci = new ImageViewCreateInfo( mSwapChain.Format, isr); mChainImageViews[i] = chainImages[i].CreateView(ivci); } //descriptor pool stuff DescriptorPoolSize dps = new DescriptorPoolSize( DescriptorType.UniformBuffer, chainImages.Length); DescriptorPoolCreateInfo dpci = new DescriptorPoolCreateInfo(); dpci.PoolSizes = new DescriptorPoolSize[] { dps }; dpci.MaxSets = chainImages.Length; mDPool = mLogical.CreateDescriptorPool(dpci); return(true); }
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); } }