protected VkSwapchainKHR CreateSwapchain(VkDevice device, VkSurfaceKHR surface, VkSurfaceFormatKHR surfaceFormat, VkSurfaceCapabilitiesKHR surfaceCapabilities) { var compositeAlpha = surfaceCapabilities.supportedCompositeAlpha.HasFlag( VkCompositeAlphaFlagBitsKHR.InheritKHR) ? VkCompositeAlphaFlagBitsKHR.InheritKHR : VkCompositeAlphaFlagBitsKHR.OpaqueKHR; UInt32 index = 0; var info = new VkSwapchainCreateInfoKHR { sType = VkStructureType.SwapchainCreateInfoKHR }; info.surface = surface; info.minImageCount = surfaceCapabilities.minImageCount; info.imageFormat = surfaceFormat.format; info.imageColorSpace = surfaceFormat.colorSpace; info.imageExtent = surfaceCapabilities.currentExtent; info.imageUsage = VkImageUsageFlagBits.ColorAttachment; info.preTransform = VkSurfaceTransformFlagBitsKHR.IdentityKHR; info.imageArrayLayers = 1; info.imageSharingMode = VkSharingMode.Exclusive; info.queueFamilyIndices = index; info.presentMode = VkPresentModeKHR.FifoKHR; info.compositeAlpha = compositeAlpha; //return device.CreateSwapchainKHR(ref info, null); VkSwapchainKHR swapchain; vkAPI.vkCreateSwapchainKHR(device, &info, null, &swapchain).Check(); return(swapchain); }
internal void SetNewSwapchain( VkSwapchainKHR deviceSwapchain, uint width, uint height, VkSurfaceFormatKHR surfaceFormat, VkExtent2D swapchainExtent) { _desiredWidth = width; _desiredHeight = height; // Get the images uint scImageCount = 0; VkResult result = vkGetSwapchainImagesKHR(_gd.Device, deviceSwapchain, ref scImageCount, null); CheckResult(result); if (_scImages == null) { _scImages = new VkImage[(int)scImageCount]; } result = vkGetSwapchainImagesKHR(_gd.Device, deviceSwapchain, ref scImageCount, out _scImages[0]); CheckResult(result); _scImageFormat = surfaceFormat.format; _scExtent = swapchainExtent; CreateDepthTexture(); CreateFramebuffers(); _outputDescription = OutputDescription.CreateFromFramebuffer(this); }
static void GetSwapchainFormat(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { uint formatCount = 0; vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, null); VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[formatCount]; fixed(VkSurfaceFormatKHR *ptr = &formats[0]) Assert(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, ptr)); for (int i = 0; i < formatCount; i++) { Console.WriteLine($"Format {formats[i].format} {formats[i].colorSpace} is available."); for (int k = 0; k < UNORM_FORMATS.Length; k++) { if (formats[i].format == UNORM_FORMATS[k]) { surfaceFormat = formats[i]; return; } } } surfaceFormat = formats[0];//Fallback }
protected VkRenderPass CreateRenderPass(VkDevice device, VkSurfaceFormatKHR surfaceFormat) { var attDesc = new VkAttachmentDescription(surfaceFormat.format, VkSampleCountFlagBits._1, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.Store, VkAttachmentLoadOp.DontCare, VkAttachmentStoreOp.DontCare, VkImageLayout.Undefined, VkImageLayout.PresentSrcKHR, 0); var subpassDesc = new VkSubpassDescription(VkPipelineBindPoint.Graphics); subpassDesc.colorAttachments = new VkAttachmentReference(VkImageLayout.ColorAttachmentOptimal, 0); var info = new VkRenderPassCreateInfo { sType = VkStructureType.RenderPassCreateInfo }; info.attachments = attDesc; info.subpasses = subpassDesc; //return device.CreateRenderPass(ref info); VkRenderPass renderPass; vkAPI.vkCreateRenderPass(device, &info, null, &renderPass).Check(); info.Free(); subpassDesc.Free(); return(renderPass); }
public Swapchain(GraphicsDevice device, Window window) { Device = device; Window = window; SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(device.PhysicalDevice, device._surface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats); VkPresentModeKHR presentMode = ChooseSwapPresentMode(swapChainSupport.PresentModes); _extent = ChooseSwapExtent(swapChainSupport.Capabilities); CreateRenderPass(surfaceFormat.format); uint imageCount = swapChainSupport.Capabilities.minImageCount + 1; if (swapChainSupport.Capabilities.maxImageCount > 0 && imageCount > swapChainSupport.Capabilities.maxImageCount) { imageCount = swapChainSupport.Capabilities.maxImageCount; } var createInfo = new VkSwapchainCreateInfoKHR { sType = VkStructureType.SwapchainCreateInfoKHR, surface = device._surface, minImageCount = imageCount, imageFormat = surfaceFormat.format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = _extent, imageArrayLayers = 1, imageUsage = VkImageUsageFlags.ColorAttachment, imageSharingMode = VkSharingMode.Exclusive, preTransform = swapChainSupport.Capabilities.currentTransform, compositeAlpha = VkCompositeAlphaFlagsKHR.Opaque, presentMode = presentMode, clipped = true, oldSwapchain = VkSwapchainKHR.Null }; vkCreateSwapchainKHR(device.VkDevice, &createInfo, null, out Handle).CheckResult(); var swapChainImages = vkGetSwapchainImagesKHR(device.VkDevice, Handle); _swapChainImageViews = new VkImageView[swapChainImages.Length]; _framebuffers = new VkFramebuffer[swapChainImages.Length]; for (var i = 0; i < swapChainImages.Length; i++) { var viewCreateInfo = new VkImageViewCreateInfo( swapChainImages[i], VkImageViewType.Image2D, surfaceFormat.format, VkComponentMapping.Identity, new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1) ); vkCreateImageView(Device.VkDevice, &viewCreateInfo, null, out _swapChainImageViews[i]).CheckResult(); vkCreateFramebuffer(Device.VkDevice, RenderPass, new[] { _swapChainImageViews[i] }, (uint)_extent.Width, (uint)_extent.Height, 1u, out _framebuffers[i]); } }
public SoftwareFormSurface(SoftwareInstance instance, VkWin32SurfaceCreateInfoKHR createInfo) { this.m_Formats = new List <VkSurfaceFormatKHR>() { VkSurfaceFormatKHR.Create(VkFormat.VK_FORMAT_B8G8R8A8_UNORM, VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) }; this.m_PresentModes = new List <VkPresentModeKHR>() { VkPresentModeKHR.VK_PRESENT_MODE_IMMEDIATE_KHR }; this.m_instance = instance; this.m_createInfo = createInfo; foreach (Form form in Application.OpenForms) { if (form.Handle == createInfo.hwnd) { m_Form = form; } } if (m_Form == null) { throw new ArgumentException(string.Format("Form not found for the handle informed on the field {0}.{1}", nameof(VkWin32SurfaceCreateInfoKHR), nameof(VkWin32SurfaceCreateInfoKHR.hwnd))); } var m_OriginalExtents = VkExtent2D.Create(GetWidth(), GetHeight()); m_CurrentSurfaceExtents = m_OriginalExtents; this.m_Capabilities = new VkSurfaceCapabilitiesKHR(); this.m_Capabilities.currentExtent = m_OriginalExtents; this.m_Capabilities.maxImageExtent = m_OriginalExtents; this.m_Capabilities.minImageExtent = m_OriginalExtents; this.m_Capabilities.minImageCount = 1; this.m_Capabilities.maxImageCount = 8; this.m_Capabilities.maxImageArrayLayers = 1; this.m_Capabilities.supportedTransforms = VkSurfaceTransformFlagBitsKHR.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; this.m_Capabilities.currentTransform = VkSurfaceTransformFlagBitsKHR.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; this.m_Capabilities.supportedCompositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; this.m_Capabilities.supportedUsageFlags = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; this.m_SurfacePresentMode = FormSurfacePresentMode.DibBitmapBitBlt; InternalResize(); m_Form.Resize += Form_Resize; }
public VkSurfaceFormatKHR [] GetSurfaceFormats(VkSurfaceKHR surf) { vkGetPhysicalDeviceSurfaceFormatsKHR(phy, surf, out uint count, IntPtr.Zero); VkSurfaceFormatKHR [] formats = new VkSurfaceFormatKHR [count]; vkGetPhysicalDeviceSurfaceFormatsKHR(phy, surf, out count, formats.Pin()); formats.Unpin(); return(formats); }
protected VkFramebuffer[] CreateFramebuffers(VkDevice device, VkImage[] images, VkSurfaceFormatKHR surfaceFormat, VkRenderPass renderPass, VkSurfaceCapabilitiesKHR surfaceCapabilities) { var displayViews = new VkImageView[images.Length]; var viewInfo = new VkImageViewCreateInfo { sType = VkStructureType.ImageViewCreateInfo }; viewInfo.viewType = VkImageViewType._2d; viewInfo.format = surfaceFormat.format; viewInfo.components = new VkComponentMapping { r = VkComponentSwizzle.R, g = VkComponentSwizzle.G, b = VkComponentSwizzle.B, a = VkComponentSwizzle.A }; viewInfo.subresourceRange = new VkImageSubresourceRange { aspectMask = VkImageAspectFlagBits.Color, levelCount = 1, layerCount = 1 }; for (int i = 0; i < images.Length; i++) { viewInfo.image = images[i]; //displayViews[i] = device.CreateImageView(ref info); VkImageView view; vkAPI.vkCreateImageView(device, &viewInfo, null, &view).Check(); displayViews[i] = view; } var framebuffers = new VkFramebuffer[images.Length]; var fbInfo = new VkFramebufferCreateInfo { sType = VkStructureType.FramebufferCreateInfo }; fbInfo.layers = 1; fbInfo.renderPass = renderPass; fbInfo.width = surfaceCapabilities.currentExtent.width; fbInfo.height = surfaceCapabilities.currentExtent.height; for (int i = 0; i < images.Length; i++) { fbInfo.attachments = displayViews[i]; //framebuffers[i] = device.CreateFramebuffer(ref info); VkFramebuffer framebuffer; vkAPI.vkCreateFramebuffer(device, &fbInfo, null, &framebuffer).Check(); framebuffers[i] = framebuffer; } fbInfo.Free(); return(framebuffers); }
private void CreateSwapchain() { SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(physicalDevice, surface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats); VkPresentModeKHR presentMode = ChooseSwapPresentMode(swapChainSupport.PresentModes); var extent = ChooseSwapExtent(swapChainSupport.Capabilities); uint imageCount = swapChainSupport.Capabilities.minImageCount + 1; if (swapChainSupport.Capabilities.maxImageCount > 0 && imageCount > swapChainSupport.Capabilities.maxImageCount) { imageCount = swapChainSupport.Capabilities.maxImageCount; } var createInfo = new VkSwapchainCreateInfoKHR { sType = VkStructureType.SwapchainCreateInfoKHR, surface = surface, minImageCount = imageCount, imageFormat = surfaceFormat.format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = extent, imageArrayLayers = 1, imageUsage = VkImageUsageFlags.ColorAttachment, imageSharingMode = VkSharingMode.Exclusive, preTransform = swapChainSupport.Capabilities.currentTransform, compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR, presentMode = presentMode, clipped = true, oldSwapchain = VkSwapchainKHR.Null }; vkCreateSwapchainKHR(device, &createInfo, null, out swapchain).CheckResult(); var swapChainImages = vkGetSwapchainImagesKHR(device, swapchain); swapChainImageViews = new VkImageView[swapChainImages.Length]; for (var i = 0; i < swapChainImages.Length; i++) { var viewCreateInfo = new VkImageViewCreateInfo( swapChainImages[i], VkImageViewType.Image2D, surfaceFormat.format, VkComponentMapping.Identity, new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1) ); vkCreateImageView(device, &viewCreateInfo, null, out swapChainImageViews[i]).CheckResult(); } }
public static ReadOnlySpan <VkSurfaceFormatKHR> vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { int surfaceFormatCount = 0; vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &surfaceFormatCount, null).CheckResult(); ReadOnlySpan <VkSurfaceFormatKHR> surfaceFormats = new VkSurfaceFormatKHR[surfaceFormatCount]; fixed(VkSurfaceFormatKHR *surfaceFormatsPtr = surfaceFormats) { vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &surfaceFormatCount, surfaceFormatsPtr).CheckResult(); } return(surfaceFormats); }
public VkSurfaceFormatKHR[] GetPhysicalDeviceSurfaceFormatsKHR(VkSurfaceKHR surface) { unsafe { VkSurfaceFormatKHR[] props; uint count = 0; do { props = new VkSurfaceFormatKHR[count]; fixed(VkSurfaceFormatKHR *pptr = props) VkException.Check(vkGetPhysicalDeviceSurfaceFormatsKHR(this, surface, &count, pptr)); } while (props.Length != count); return(props); } }
private VkSurfaceFormatKHR chooseSwapSurfaceFormat(VkSurfaceFormatKHR[] availableFormats) { if (availableFormats.Length == 1 && availableFormats[0].format == VkFormat.VK_FORMAT_UNDEFINED) { return(VkSurfaceFormatKHR.Create(VkFormat.VK_FORMAT_B8G8R8A8_UNORM, VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)); } foreach (var availableFormat in availableFormats) { if (availableFormat.format == VkFormat.VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { return(availableFormat); } } return(availableFormats[0]); }
private static VkSurfaceFormatKHR ChooseSwapSurfaceFormat(IReadOnlyList <VkSurfaceFormatKHR> availableFormats) { var preferred = new VkSurfaceFormatKHR { Format = VkFormat.B8G8R8A8_UNORM, ColorSpace = VkColorSpaceKHR.SRGB_NONLINEAR_KHR }; if (availableFormats.Count == 1 && availableFormats[0].Format == VkFormat.Undefined) { return(preferred); } if (availableFormats.Any(x => x.Format == preferred.Format && x.ColorSpace == preferred.ColorSpace)) { return(preferred); } return(availableFormats.First()); }
VkSurfaceFormatKHR ChooseSwapSurfaceFormat(List <VkSurfaceFormatKHR> formats) { if (formats.Count == 1 && formats[0].format == VkFormat.Undefined) { var result = new VkSurfaceFormatKHR(); result.format = VkFormat.B8G8R8A8_Unorm; result.colorSpace = VkColorSpaceKHR.SrgbNonlinearKhr; return(result); } foreach (var f in formats) { if (f.format == VkFormat.B8G8R8A8_Unorm && f.colorSpace == VkColorSpaceKHR.SrgbNonlinearKhr) { return(f); } } return(formats[0]); }
protected VkSurfaceFormatKHR SelectFormat(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { VkSurfaceFormatKHR[] formats; //physicalDevice.GetSurfaceFormatsKHR(surface, out formats); { UInt32 count; vkAPI.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count, null).Check(); formats = new VkSurfaceFormatKHR[count]; fixed(VkSurfaceFormatKHR *pointer = formats) { vkAPI.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count, pointer).Check(); } } foreach (var f in formats) { if (f.format == VkFormat.R8g8b8a8Unorm || f.format == VkFormat.B8g8r8a8Unorm) { return(f); } } throw new System.Exception("didn't find the R8G8B8A8Unorm or B8G8R8A8Unorm format"); }
private void CreateSwapchain(uint width, uint height) { _currentImageIndex = 0; uint surfaceFormatCount = 0; vkGetPhysicalDeviceSurfaceFormatsKHR(_gd.PhysicalDevice, _surface, ref surfaceFormatCount, null); VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[surfaceFormatCount]; vkGetPhysicalDeviceSurfaceFormatsKHR(_gd.PhysicalDevice, _surface, ref surfaceFormatCount, out formats[0]); VkSurfaceFormatKHR surfaceFormat = new VkSurfaceFormatKHR(); if (formats.Length == 1 && formats[0].format == VkFormat.Undefined) { surfaceFormat = new VkSurfaceFormatKHR { colorSpace = VkColorSpaceKHR.SrgbNonlinearKHR, format = VkFormat.B8g8r8a8Unorm }; } else { foreach (VkSurfaceFormatKHR format in formats) { if (format.colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR && format.format == VkFormat.B8g8r8a8Unorm) { surfaceFormat = format; break; } } if (surfaceFormat.format == VkFormat.Undefined) { surfaceFormat = formats[0]; } } uint presentModeCount = 0; vkGetPhysicalDeviceSurfacePresentModesKHR(_gd.PhysicalDevice, _surface, ref presentModeCount, null); VkPresentModeKHR[] presentModes = new VkPresentModeKHR[presentModeCount]; vkGetPhysicalDeviceSurfacePresentModesKHR(_gd.PhysicalDevice, _surface, ref presentModeCount, out presentModes[0]); VkPresentModeKHR presentMode = VkPresentModeKHR.FifoKHR; if (presentModes.Contains(VkPresentModeKHR.MailboxKHR)) { presentMode = VkPresentModeKHR.MailboxKHR; } else if (presentModes.Contains(VkPresentModeKHR.ImmediateKHR)) { presentMode = VkPresentModeKHR.ImmediateKHR; } vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_gd.PhysicalDevice, _surface, out VkSurfaceCapabilitiesKHR surfaceCapabilities); uint imageCount = surfaceCapabilities.minImageCount + 1; VkSwapchainCreateInfoKHR swapchainCI = VkSwapchainCreateInfoKHR.New(); swapchainCI.surface = _surface; swapchainCI.presentMode = presentMode; swapchainCI.imageFormat = surfaceFormat.format; swapchainCI.imageColorSpace = surfaceFormat.colorSpace; swapchainCI.imageExtent = new VkExtent2D { width = (uint)width, height = (uint)height }; swapchainCI.minImageCount = imageCount; swapchainCI.imageArrayLayers = 1; swapchainCI.imageUsage = VkImageUsageFlags.ColorAttachment; FixedArray2 <uint> queueFamilyIndices = new FixedArray2 <uint>(_gd.GraphicsQueueIndex, _gd.PresentQueueIndex); if (_gd.GraphicsQueueIndex != _gd.PresentQueueIndex) { swapchainCI.imageSharingMode = VkSharingMode.Concurrent; swapchainCI.queueFamilyIndexCount = 2; swapchainCI.pQueueFamilyIndices = &queueFamilyIndices.First; } else { swapchainCI.imageSharingMode = VkSharingMode.Exclusive; swapchainCI.queueFamilyIndexCount = 0; } swapchainCI.preTransform = surfaceCapabilities.currentTransform; swapchainCI.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR; swapchainCI.clipped = true; VkSwapchainKHR oldSwapchain = _swapchain; swapchainCI.oldSwapchain = oldSwapchain; VkResult result = vkCreateSwapchainKHR(_gd.Device, ref swapchainCI, null, out _swapchain); CheckResult(result); if (oldSwapchain != VkSwapchainKHR.Null) { vkDestroySwapchainKHR(_gd.Device, oldSwapchain, null); } // Get the images uint scImageCount = 0; result = vkGetSwapchainImagesKHR(_gd.Device, _swapchain, ref scImageCount, null); CheckResult(result); if (_scImages == null) { _scImages = new VkImage[(int)scImageCount]; } result = vkGetSwapchainImagesKHR(_gd.Device, _swapchain, ref scImageCount, out _scImages[0]); CheckResult(result); _scImageFormat = surfaceFormat.format; _scExtent = swapchainCI.imageExtent; CreateDepthTexture(); CreateFramebuffers(); }
private VkSwapchainKHR CreateSwapchain() { VkSurfaceCapabilitiesKHR capabilities; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Context.PhysicalDevice, Surface, out capabilities).CheckResult(); uint count; vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, null); VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[(int)count]; fixed(VkSurfaceFormatKHR *formatsPtr = formats) vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, formatsPtr).CheckResult(); vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, null).CheckResult(); VkPresentModeKHR[] presentModes = new VkPresentModeKHR[count]; fixed(VkPresentModeKHR *presentModesPtr = presentModes) vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, presentModesPtr).CheckResult(); VkFormat format = formats.Length == 1 && formats[0].format == VkFormat.Undefined ? VkFormat.B8G8R8A8UNorm : formats[0].format; VkPresentModeKHR presentMode = presentModes.Contains(VkPresentModeKHR.Mailbox) ? VkPresentModeKHR.Mailbox : presentModes.Contains(VkPresentModeKHR.FifoRelaxed) ? VkPresentModeKHR.FifoRelaxed : presentModes.Contains(VkPresentModeKHR.Fifo) ? VkPresentModeKHR.Fifo : VkPresentModeKHR.Immediate; SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(Context.PhysicalDevice, Surface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats); uint imageCount = swapChainSupport.Capabilities.minImageCount + 1; if (swapChainSupport.Capabilities.maxImageCount > 0 && imageCount > swapChainSupport.Capabilities.maxImageCount) { imageCount = swapChainSupport.Capabilities.maxImageCount; } SwapchainFormat = format; VkSwapchainCreateInfoKHR swapchainCI = new VkSwapchainCreateInfoKHR() { sType = VkStructureType.SwapchainCreateInfoKHR, pNext = null, surface = Surface, minImageCount = imageCount, imageFormat = format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = capabilities.currentExtent, imageUsage = VkImageUsageFlags.ColorAttachment, preTransform = capabilities.currentTransform, imageArrayLayers = 1, imageSharingMode = VkSharingMode.Exclusive, queueFamilyIndexCount = 0, pQueueFamilyIndices = null, presentMode = presentMode, //oldSwapchain = SwapChain, // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area clipped = true, compositeAlpha = VkCompositeAlphaFlagsKHR.Opaque, }; VkSwapchainKHR SwapChain; vkCreateSwapchainKHR(Context.Device, &swapchainCI, null, out SwapChain).CheckResult(); return(SwapChain); }
public unsafe void InitSurface(IntPtr sdlWindow) { VkResult err; // Create the os-specific Surface VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR(); surfaceCreateInfo.sType = Win32SurfaceCreateInfoKHR; var processHandle = Process.GetCurrentProcess().Handle;//.SafeHandle.DangerousGetHandle(); surfaceCreateInfo.hinstance = processHandle; surfaceCreateInfo.hwnd = sdlWindow; VkSurfaceKHR surface; err = vkCreateWin32SurfaceKHR(Instance, &surfaceCreateInfo, null, &surface); Surface = surface; // Get available queue family properties uint queueCount; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null); Debug.Assert(queueCount >= 1); var queueProps = new VkQueueFamilyProperties[queueCount]; fixed(VkQueueFamilyProperties *pointer = queueProps) { vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, pointer); } // Iterate over each queue to learn whether it supports presenting: // Find a queue with present support // Will be used to present the swap chain Images to the windowing system VkBool32 *supportsPresent = stackalloc VkBool32[(int)queueCount]; for (uint i = 0; i < queueCount; i++) { vkGetPhysicalDeviceSurfaceSupportKHR(PhysicalDevice, i, Surface, &supportsPresent[i]); } // Search for a graphics and a present queue in the array of queue // families, try to find one that supports both uint graphicsQueueNodeIndex = uint.MaxValue; uint presentQueueNodeIndex = uint.MaxValue; for (uint i = 0; i < queueCount; i++) { if ((queueProps[i].queueFlags & VkQueueFlagBits.Graphics) != 0) { if (graphicsQueueNodeIndex == uint.MaxValue) { graphicsQueueNodeIndex = i; } if (supportsPresent[i] == true) { graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; } } } if (presentQueueNodeIndex == uint.MaxValue) { // If there's no queue that supports both present and graphics // try to find a separate present queue for (uint i = 0; i < queueCount; ++i) { if (supportsPresent[i] == true) { presentQueueNodeIndex = i; break; } } } // Exit if either a graphics or a presenting queue hasn't been found if (graphicsQueueNodeIndex == uint.MaxValue || presentQueueNodeIndex == uint.MaxValue) { throw new InvalidOperationException("Could not find a graphics and/or presenting queue!"); } // todo : Add support for separate graphics and presenting queue if (graphicsQueueNodeIndex != presentQueueNodeIndex) { throw new InvalidOperationException("Separate graphics and presenting queues are not supported yet!"); } QueueNodeIndex = graphicsQueueNodeIndex; // Get list of supported Surface formats uint formatCount; err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, null); Debug.Assert(err == VkResult.Success); Debug.Assert(formatCount > 0); var surfaceFormats = new VkSurfaceFormatKHR[formatCount]; fixed(VkSurfaceFormatKHR *pointer = surfaceFormats) { err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, pointer); Debug.Assert(err == VkResult.Success); } // If the Surface format list only includes one entry with VK_FORMAT_UNDEFINED, // there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM if ((formatCount == 1) && (surfaceFormats[0].format == VkFormat.Undefined)) { ColorFormat = VkFormat.B8g8r8a8Unorm; ColorSpace = surfaceFormats[0].colorSpace; } else { // iterate over the list of available Surface format and // check for the presence of VK_FORMAT_B8G8R8A8_UNORM bool found_B8G8R8A8_UNORM = false; foreach (var surfaceFormat in surfaceFormats) { if (surfaceFormat.format == VkFormat.B8g8r8a8Unorm) { ColorFormat = surfaceFormat.format; ColorSpace = surfaceFormat.colorSpace; found_B8G8R8A8_UNORM = true; break; } } // in case VK_FORMAT_B8G8R8A8_UNORM is not available // select the first available color format if (!found_B8G8R8A8_UNORM) { ColorFormat = surfaceFormats[0].format; ColorSpace = surfaceFormats[0].colorSpace; } } }
public unsafe Swapchain(Device device, NativeWindow window) { _device = device; _window = window; //get present queue _presentQueueFamily = GetQueueFamilyWithPresentationSupport( device, window ); //get surface capabilities _surfaceCapabilities = GetSurfaceCapabilities( device, window ); //get surface format support _supportedSurfaceFormats = GetSupportedSurfaceFormats( device, window ); //get present mode support _supportedPresentModes = GetSupportedPresentModes( device, window ); //choose best surface format #region Surface Format if ( _supportedSurfaceFormats.Count == 1 && _supportedSurfaceFormats[0].format == VkFormat.Undefined ) { _surfaceFormat = new VkSurfaceFormatKHR { colorSpace = VkColorSpaceKHR.SrgbNonlinearKHR, format = VkFormat.R8g8b8Unorm }; } else { bool choosenFormat = false; foreach (var format in _supportedSurfaceFormats) { if ( format.format == VkFormat.R8g8b8Unorm && format.colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR ) { _surfaceFormat = format; choosenFormat = true; break; } } if (choosenFormat == false) { _surfaceFormat = _supportedSurfaceFormats[0]; } } #endregion #region Surface Present Mode _surfacePresentMode = VkPresentModeKHR.FifoKHR; foreach (var presentMode in _supportedPresentModes) { if (presentMode == VkPresentModeKHR.MailboxKHR) { _surfacePresentMode = presentMode; break; } else if (presentMode == VkPresentModeKHR.ImmediateKHR) { _surfacePresentMode = presentMode; } } #endregion #region Surface Extent if (_surfaceCapabilities.currentExtent.width != uint.MaxValue) { _surfaceExtent = _surfaceCapabilities.currentExtent; } else { _surfaceExtent = new VkExtent2D { width = Math.Clamp( Convert.ToUInt32(window.Width), _surfaceCapabilities.minImageExtent.width, _surfaceCapabilities.maxImageExtent.width ), height = Math.Clamp( Convert.ToUInt32(window.Height), _surfaceCapabilities.minImageExtent.height, _surfaceCapabilities.maxImageExtent.height ) }; } #endregion #region Images Count var imagesCount = _surfaceCapabilities.minImageCount + 1; if (_surfaceCapabilities.maxImageCount > 0) { if (imagesCount > _surfaceCapabilities.maxImageCount) { imagesCount = Math.Min(_surfaceCapabilities.maxImageCount, 2); } } #endregion var queueFamilyIndices = new NativeList <uint>(); foreach (var queueFamily in device.QueueFamilies) { queueFamilyIndices.Add(queueFamily.Index); } var swapchainInfo = new VkSwapchainCreateInfoKHR { sType = VkStructureType.SwapchainCreateInfoKHR, compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR, minImageCount = imagesCount, imageFormat = _surfaceFormat.format, imageColorSpace = _surfaceFormat.colorSpace, imageExtent = _surfaceExtent, imageArrayLayers = 1, imageUsage = ( VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransferDst ), imageSharingMode = VkSharingMode.Concurrent, preTransform = _surfaceCapabilities.currentTransform, presentMode = _surfacePresentMode, surface = window.Surface, clipped = true, queueFamilyIndexCount = queueFamilyIndices.Count, pQueueFamilyIndices = (uint *)queueFamilyIndices.Data.ToPointer() }; VkSwapchainKHR swapchain; if (VulkanNative.vkCreateSwapchainKHR( device.Handle, &swapchainInfo, null, &swapchain ) != VkResult.Success) { throw new Exception("failed to create swapchain"); } _handle = swapchain; SetupSwapchainImages(); }
public void Init(IntPtr hwnd, IntPtr processHandle) { if (this.isInitialized) { return; } this.instance = InitInstance(); InitDebugCallback(this.instance); this.surface = InitSurface(this.instance, hwnd, processHandle); this.vkPhysicalDevice = InitPhysicalDevice(this.instance); VkSurfaceFormatKHR surfaceFormat = SelectFormat(this.vkPhysicalDevice, this.surface); this.device = CreateDevice(this.vkPhysicalDevice, this.surface); this.vkQueue = this.device.GetQueue(0, 0); VkSurfaceCapabilitiesKHR surfaceCapabilities; //this.vkPhysicalDevice.GetSurfaceCapabilitiesKhr(this.vkSurface, out surfaceCapabilities); vkAPI.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(this.vkPhysicalDevice, this.surface, &surfaceCapabilities).Check(); this.swapchain = CreateSwapchain(this.device, this.surface, surfaceFormat, surfaceCapabilities); this.vkImages = this.device.GetSwapchainImages(this.swapchain); this.renderPass = CreateRenderPass(this.device, surfaceFormat); this.framebuffers = CreateFramebuffers(this.device, this.vkImages, surfaceFormat, this.renderPass, surfaceCapabilities); this.vkFence = this.device.CreateFence(); this.vkSemaphore = this.device.CreateSemaphore(); // buffers for vertex data. VkBuffer vertexBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, Vertices, VkBufferUsageFlagBits.VertexBuffer, typeof(float)); VkBuffer indexBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, Indexes, VkBufferUsageFlagBits.IndexBuffer, typeof(short)); var uniformBufferData = new AreaUniformBuffer(1, 1); this.originalWidth = 1; this.width = this.originalWidth; this.originalHeight = 1; this.height = this.originalHeight; this.uniformBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, uniformBufferData, VkBufferUsageFlagBits.UniformBuffer, typeof(AreaUniformBuffer)); this.descriptorSetLayout = CreateDescriptorSetLayout(this.device); this.vkPipelineLayout = CreatePipelineLayout(this.device, this.descriptorSetLayout); VkPipeline pipeline = CreatePipeline(this.device, surfaceCapabilities, this.renderPass, this.vkPipelineLayout); this.descriptorSet = CreateDescriptorSet(this.device, this.descriptorSetLayout); UpdateDescriptorSets(this.device, this.uniformBuffer, this.descriptorSet); this.commandBuffers = CreateCommandBuffers( this.device, this.renderPass, surfaceCapabilities, this.vkImages, this.framebuffers, pipeline, vertexBuffer, indexBuffer, (uint)Indexes.Length, this.vkPipelineLayout, this.descriptorSet); this.isInitialized = true; }
private void CreateSwapChain() { var swapChainSupport = new SwapChainSupportDetails(vkPhysicalDevice, vkSurface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.formats); VkPresentModeKHR presentMode = ChooseSwapPresentMode(swapChainSupport.presentModes); VkExtent2D extent = ChooseSwapExtent(swapChainSupport.capabilities); uint imageCount = swapChainSupport.capabilities.minImageCount + 1; if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { imageCount = Math.Min(imageCount, swapChainSupport.capabilities.maxImageCount); } var createInfo = new VkSwapchainCreateInfoKHR() { sType = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, surface = vkSurface, minImageCount = imageCount, imageFormat = surfaceFormat.format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = extent, imageArrayLayers = 1, imageUsage = VkImageUsageFlagBits.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, preTransform = swapChainSupport.capabilities.currentTransform, compositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, presentMode = presentMode, clipped = true, }; var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface); uint *QueueFamilyIndicesPtr = stackalloc uint[] { (uint)indices.GraphicsFamily, (uint)indices.PresentFamily, }; if (indices.GraphicsFamily != indices.PresentFamily) { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_CONCURRENT; createInfo.pQueueFamilyIndices = QueueFamilyIndicesPtr; } else { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE; } VkSwapchainKHR newSwapChain; var result = VulkanNative.vkCreateSwapchainKHR(vkDevice, &createInfo, null, &newSwapChain); vkSwapChain = newSwapChain; Helpers.CheckErrors(result); VulkanNative.vkGetSwapchainImagesKHR(vkDevice, vkSwapChain, &imageCount, null); VkImage *images = stackalloc VkImage[(int)imageCount]; result = VulkanNative.vkGetSwapchainImagesKHR(vkDevice, vkSwapChain, &imageCount, images); Helpers.CheckErrors(result); vkSwapChainImages = new VkImage[imageCount]; for (int i = 0; i < imageCount; i++) { vkSwapChainImages[i] = images[i]; } vkSwapChainImageFormat = surfaceFormat.format; vkSwapChainExtent = extent; }
private void CreateSwapChain() { // Create SwapChain SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice); VkSurfaceFormatKHR surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.formats); VkPresentModeKHR presentMode = this.ChooseSwapPresentMode(swapChainSupport.presentModes); VkExtent2D extent = this.ChooseSwapExtent(swapChainSupport.capabilities); uint imageCount = swapChainSupport.capabilities.minImageCount + 1; if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { imageCount = swapChainSupport.capabilities.maxImageCount; } VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.surface = surface; createInfo.minImageCount = imageCount; createInfo.imageFormat = surfaceFormat.format; createInfo.imageColorSpace = surfaceFormat.colorSpace; createInfo.imageExtent = extent; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; QueueFamilyIndices indices = this.FindQueueFamilies(this.physicalDevice); uint *queueFamilyIndices = stackalloc uint[] { indices.graphicsFamily.Value, indices.presentFamily.Value }; if (indices.graphicsFamily != indices.presentFamily) { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_CONCURRENT; createInfo.queueFamilyIndexCount = 2; createInfo.pQueueFamilyIndices = queueFamilyIndices; } else { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE; createInfo.queueFamilyIndexCount = 0; //Optional createInfo.pQueueFamilyIndices = null; //Optional } createInfo.preTransform = swapChainSupport.capabilities.currentTransform; createInfo.compositeAlpha = VkCompositeAlphaFlagsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; createInfo.presentMode = presentMode; createInfo.clipped = true; createInfo.oldSwapchain = 0; fixed(VkSwapchainKHR *swapChainPtr = &swapChain) { Helpers.CheckErrors(VulkanNative.vkCreateSwapchainKHR(device, &createInfo, null, swapChainPtr)); } // SwapChain Images VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, null); this.swapChainImages = new VkImage[imageCount]; fixed(VkImage *swapChainImagesPtr = &this.swapChainImages[0]) { VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImagesPtr); } this.swapChainImageFormat = surfaceFormat.format; this.swapChainExtent = extent; }
private static uint RateDevice(IntPtr physDevice) { var devProps = new ManagedPtr <VkPhysicalDeviceProperties>(); var devFeats = new ManagedPtr <VkPhysicalDeviceFeatures>(); vkGetPhysicalDeviceProperties(physDevice, devProps); vkGetPhysicalDeviceFeatures(physDevice, devFeats); var devProps_ = devProps.Value; var devFeats_ = devFeats.Value; uint score = 0; if (devProps_.deviceType == VkPhysicalDeviceType.PhysicalDeviceTypeDiscreteGpu) { score += 100; } score += devProps_.limits.maxImageDimension2D; if (!devFeats_.multiDrawIndirect) { return(0); } if (!devFeats_.tessellationShader) { return(0); } if (!ExtensionsSupported(physDevice)) { return(0); } var caps_ptr = new ManagedPtr <VkSurfaceCapabilitiesKHR>(); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDevice, surfaceHndl, caps_ptr); var caps = caps_ptr.Value; uint fmt_cnt = 0; vkGetPhysicalDeviceSurfaceFormatsKHR(physDevice, surfaceHndl, &fmt_cnt, null); var fmts_ptr = new ManagedPtrArray <VkSurfaceFormatKHR>(fmt_cnt); vkGetPhysicalDeviceSurfaceFormatsKHR(physDevice, surfaceHndl, &fmt_cnt, fmts_ptr); var fmts = fmts_ptr.Value; bool fmt_valid = false; VkSurfaceFormatKHR chosen_fmt = new VkSurfaceFormatKHR(); foreach (var avail_fmt in fmts) { if (avail_fmt.format == VkFormat.FormatB8g8r8a8Unorm && avail_fmt.colorSpace == VkColorSpaceKHR.ColorSpaceSrgbNonlinearKhr) { chosen_fmt = avail_fmt; fmt_valid = true; break; } } if (!fmt_valid && fmts.Length > 0) { chosen_fmt = fmts[0]; fmt_valid = true; } uint present_mode_cnt = 0; vkGetPhysicalDeviceSurfacePresentModesKHR(physDevice, surfaceHndl, &present_mode_cnt, null); var present_modes = stackalloc VkPresentModeKHR[(int)present_mode_cnt]; vkGetPhysicalDeviceSurfacePresentModesKHR(physDevice, surfaceHndl, &present_mode_cnt, present_modes); bool present_valid = false; VkPresentModeKHR chosen_present = VkPresentModeKHR.PresentModeBeginRangeKhr; for (int i = 0; i < present_mode_cnt; i++) { var avail_present = present_modes[i]; if (avail_present == VkPresentModeKHR.PresentModeMailboxKhr) { present_valid = true; chosen_present = VkPresentModeKHR.PresentModeMailboxKhr; } else if (avail_present == VkPresentModeKHR.PresentModeFifoRelaxedKhr) { present_valid = true; chosen_present = VkPresentModeKHR.PresentModeFifoRelaxedKhr; } } if (!present_valid) { present_valid = true; chosen_present = VkPresentModeKHR.PresentModeFifoKhr; } chosen_present = VkPresentModeKHR.PresentModeImmediateKhr; if (!fmt_valid) { return(0); } if (!present_valid) { return(0); } present_mode = chosen_present; surface_fmt = chosen_fmt; return(score); }
private void createSwapChain() { SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities); int imageCount = swapChainSupport.capabilities.minImageCount + 1; if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { imageCount = swapChainSupport.capabilities.maxImageCount; } VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.surface = surface; createInfo.minImageCount = imageCount; createInfo.imageFormat = surfaceFormat.format; createInfo.imageColorSpace = surfaceFormat.colorSpace; createInfo.imageExtent = extent; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; QueueFamilyIndices indices = findQueueFamilies(physicalDevice); var queueFamilyIndices = new List <int>() { indices.graphicsFamily, indices.presentFamily }; if (indices.graphicsFamily != indices.presentFamily) { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_CONCURRENT; createInfo.queueFamilyIndexCount = queueFamilyIndices.Count; createInfo.pQueueFamilyIndices = queueFamilyIndices.ToArray(); } else { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE; } createInfo.preTransform = (VkSurfaceTransformFlagBitsKHR)swapChainSupport.capabilities.currentTransform; createInfo.compositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; createInfo.presentMode = presentMode; createInfo.clipped = VkBool32.VK_TRUE; createInfo.oldSwapchain = null; VkResult result = Vulkan.vkCreateSwapchainKHR(device, createInfo, null, out swapChain); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create swap chain!", result); } swapChainImages = new VkImage[imageCount]; Vulkan.vkGetSwapchainImagesKHR(device, swapChain, ref imageCount, swapChainImages); swapChainImageFormat = surfaceFormat.format; swapChainExtent = extent; }