internal void init_queue_family() { VkPhysicalDevice PhysicalDevice = NativeDevice.NativeAdapter.handle; // Get available queue family properties uint queueCount; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null); VkQueueFamilyProperties *queueProps = stackalloc VkQueueFamilyProperties[(int)queueCount]; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, queueProps); // 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, out 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 & VkQueueFlags.Graphics) != 0) { if (graphicsQueueNodeIndex is uint.MaxValue) { graphicsQueueNodeIndex = i; } if (supportsPresent[i] == true) { graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; } } } if (presentQueueNodeIndex is 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 is uint.MaxValue || presentQueueNodeIndex is 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!"); } if (vultaik_debug) { string message = $"QueueNodeIndex = {presentQueueNodeIndex}, Type = {queueProps[presentQueueNodeIndex].queueFlags}"; ConsoleLog.Info("SwapChain", message); } // Get list of supported Surface formats uint formatCount; vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, surface, &formatCount, null); VkSurfaceFormatKHR *surfaceFormats = stackalloc VkSurfaceFormatKHR[(int)formatCount]; vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, surface, &formatCount, surfaceFormats); // 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 is 1) && (surfaceFormats[0].format is VkFormat.Undefined)) { color_format = VkFormat.B8G8R8A8UNorm; color_space = surfaceFormats[0].colorSpace; }
internal VkSurfaceKHR CreateSurface() { VkInstance instance = NativeDevice.NativeAdapter.instance; VkSurfaceKHR surface = 0; //PFN_vkCreateWin32SurfaceKHRDelegate vkCreateWin32SurfaceKHR = NativeDevice.GetInstanceProcAddr<PFN_vkCreateWin32SurfaceKHRDelegate>("vkCreateWin32SurfaceKHR"); //PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = NativeDevice.GetInstanceProcAddr<PFN_vkCreateXlibSurfaceKHR>("vkCreateXlibSurfaceKHR"); //PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR = NativeDevice.GetInstanceProcAddr<PFN_vkCreateWaylandSurfaceKHR>("vkCreateWaylandSurfaceKHR"); //if (SwapchainSource is WindowSwapchainSource sourcewin) //{ // surface = new VkSurfaceKHR(sourcewin.Surface); //} if (SwapchainSource is Win32SwapchainSource sourcewin32 && NativeDevice.NativeAdapter.SupportsWin32Surface) { VkWin32SurfaceCreateInfoKHR win32_surface_create_info = new() { sType = VkStructureType.Win32SurfaceCreateInfoKHR, pNext = null, flags = VkWin32SurfaceCreateFlagsKHR.None, hinstance = sourcewin32.Hinstance, hwnd = sourcewin32.Hwnd, }; vkCreateWin32SurfaceKHR(instance, &win32_surface_create_info, null, out surface); if (vultaik_debug) { string message = $"Win32, Handle = 0x{surface.Handle.ToString("X")}, Hwnd = 0x{win32_surface_create_info.hwnd.ToString("X")}"; ConsoleLog.Info("SwapChain - Surface", message, true); } } if (SwapchainSource is XlibSwapchainSource xlibsource) { VkXlibSurfaceCreateInfoKHR xlib_surface_create_info = new() { sType = VkStructureType.XlibSurfaceCreateInfoKHR, pNext = null, flags = 0, display = xlibsource.Display, window = xlibsource.Window }; vkCreateXlibSurfaceKHR(instance, &xlib_surface_create_info, null, out surface); if (vultaik_debug) { string message = $"SwapChain - Xlib, Handle = 0x{surface.Handle.ToString("X")}, Display = 0x{xlib_surface_create_info.display.ToString("X")}, window = 0x{xlib_surface_create_info.window.ToString("X")}"; ConsoleLog.Info("Surface", message); } } if (SwapchainSource is WaylandSwapchainSource Waylandsource) { VkWaylandSurfaceCreateInfoKHR XlibSurfaceCreateInfo = new() { sType = VkStructureType.WaylandSurfaceCreateInfoKHR, pNext = null, flags = 0, display = Waylandsource.Display, surface = Waylandsource.Surface }; vkCreateWaylandSurfaceKHR(instance, &XlibSurfaceCreateInfo, null, out surface); } return(surface); }