public unsafe override VkSurfaceKHR CreateSurface(VkInstance instance) { VkXlibSurfaceCreateInfoKHR xsci = VkXlibSurfaceCreateInfoKHR.New(); xsci.dpy = _display; xsci.window = _window; VkResult result = vkCreateXlibSurfaceKHR(instance, ref xsci, null, out VkSurfaceKHR surface); CheckResult(result); return(surface); }
private static VkSurfaceKHR CreateXlib(VkInstance instance, XlibSwapchainSource xlibSource) { VkXlibSurfaceCreateInfoKHR xsci = VkXlibSurfaceCreateInfoKHR.New(); xsci.dpy = (Display *)xlibSource.Display; xsci.window = new Window { Value = xlibSource.Window }; VkResult result = vkCreateXlibSurfaceKHR(instance, ref xsci, null, out VkSurfaceKHR surface); CheckResult(result); return(surface); }
public unsafe void InitSurface(IntPtr sdlWindow) { SDL_version version; SDL_GetVersion(&version); SDL_SysWMinfo sysWmInfo; sysWmInfo.version = version; int result = SDL_GetWMWindowInfo(sdlWindow, &sysWmInfo); if (result == 0) { throw new InvalidOperationException("Couldn't retrieve SDL window info."); } VkResult err; if (sysWmInfo.subsystem == SysWMType.Windows) { Win32WindowInfo win32Info = Unsafe.Read <Win32WindowInfo>(&sysWmInfo.info); // Create the os-specific Surface VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = VkWin32SurfaceCreateInfoKHR.New(); var processHandle = Process.GetCurrentProcess().SafeHandle.DangerousGetHandle(); surfaceCreateInfo.hinstance = processHandle; surfaceCreateInfo.hwnd = win32Info.Sdl2Window; VkSurfaceKHR surface; err = vkCreateWin32SurfaceKHR(Instance, &surfaceCreateInfo, null, &surface); Surface = surface; } else if (sysWmInfo.subsystem == SysWMType.X11) { X11WindowInfo x11Info = Unsafe.Read <X11WindowInfo>(&sysWmInfo.info); VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = VkXlibSurfaceCreateInfoKHR.New(); surfaceCreateInfo.dpy = (global::Vulkan.Xlib.Display *)x11Info.display; surfaceCreateInfo.window = new global::Vulkan.Xlib.Window { Value = x11Info.Sdl2Window }; VkSurfaceKHR surface; err = vkCreateXlibSurfaceKHR(Instance, &surfaceCreateInfo, null, out surface); Surface = surface; } else { throw new NotImplementedException($"SDL backend not implemented: {sysWmInfo.subsystem}."); } // Get available queue family properties uint queueCount; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null); Debug.Assert(queueCount >= 1); using (NativeList <VkQueueFamilyProperties> queueProps = new NativeList <VkQueueFamilyProperties>(queueCount)) { vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, (VkQueueFamilyProperties *)queueProps.Data.ToPointer()); queueProps.Count = queueCount; // 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 & VkQueueFlags.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); using (NativeList <VkSurfaceFormatKHR> surfaceFormats = new NativeList <VkSurfaceFormatKHR>(formatCount)) { err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, (VkSurfaceFormatKHR *)surfaceFormats.Data.ToPointer()); surfaceFormats.Count = formatCount; 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; } } } } }