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 NativeWindow( GraphicsService graphicsService, string title, int x, int y, int width, int height, SDL_WindowFlags flags ) { _width = width; _height = height; _graphicsService = graphicsService; _handle = SDL2Native.SDL_CreateWindow( title, x, y, width, height, flags ); //get sdl version var sysWindowInfo = new SDL_SysWMinfo(); SDL2Native.SDL_GetVersion(&sysWindowInfo.version); _version = sysWindowInfo.version; if (SDL2Native.SDL_GetWMWindowInfo( _handle, &sysWindowInfo ) == 0) { throw new Exception("couldn't retrive sdl window information"); } VkResult error; VkSurfaceKHR surface; if (sysWindowInfo.subsystem == SysWMType.Windows) { var processHandle = ( Process .GetCurrentProcess() .SafeHandle .DangerousGetHandle() ); var win32Info = Unsafe.Read <Win32WindowInfo>(&sysWindowInfo.info); var surfaceInfo = new VkWin32SurfaceCreateInfoKHR { sType = VkStructureType.Win32SurfaceCreateInfoKHR, hinstance = processHandle, hwnd = win32Info.window }; error = VulkanNative.vkCreateWin32SurfaceKHR( graphicsService.Handle, &surfaceInfo, null, &surface ); } else if (sysWindowInfo.subsystem == SysWMType.X11) { var x11Info = Unsafe.Read <X11WindowInfo>(&sysWindowInfo.info); var surfaceInfo = new VkXlibSurfaceCreateInfoKHR { sType = VkStructureType.XlibSurfaceCreateInfoKHR, dpy = (Vulkan.Xlib.Display *)x11Info.display, window = new Vulkan.Xlib.Window { Value = x11Info.window } }; error = VulkanNative.vkCreateXlibSurfaceKHR( graphicsService.Handle, &surfaceInfo, null, &surface ); } else if (sysWindowInfo.subsystem == SysWMType.Wayland) { var waylandINfo = Unsafe.Read <WaylandWindowInfo>(&sysWindowInfo.info); var surfaceInfo = new VkWaylandSurfaceCreateInfoKHR { sType = VkStructureType.WaylandSurfaceCreateInfoKHR, display = (Vulkan.Wayland.wl_display *)waylandINfo.display, surface = (Vulkan.Wayland.wl_surface *)waylandINfo.surface }; error = VulkanNative.vkCreateWaylandSurfaceKHR( graphicsService.Handle, &surfaceInfo, null, &surface ); } else if (sysWindowInfo.subsystem == SysWMType.Android) { var androidInfo = Unsafe.Read <AndroidWindowInfo>(&sysWindowInfo.info); var surfaceInfo = new VkAndroidSurfaceCreateInfoKHR { sType = VkStructureType.AndroidSurfaceCreateInfoKHR, window = (Vulkan.Android.ANativeWindow *)androidInfo.window }; error = VulkanNative.vkCreateAndroidSurfaceKHR( graphicsService.Handle, &surfaceInfo, null, &surface ); } else if (sysWindowInfo.subsystem == SysWMType.Mir) { var mirInfo = Unsafe.Read <MirWindowInfo>(&sysWindowInfo.info); var surfaceInfo = new VkMirSurfaceCreateInfoKHR { sType = VkStructureType.MirSurfaceCreateInfoKHR, connection = (Vulkan.Mir.MirConnection *)mirInfo.connection, mirSurface = (Vulkan.Mir.MirSurface *)mirInfo.mirSurface }; error = VulkanNative.vkCreateMirSurfaceKHR( graphicsService.Handle, &surfaceInfo, null, &surface ); } else if (sysWindowInfo.subsystem == SysWMType.Cocoa) { var cocaInfo = Unsafe.Read <CocoaWindowInfo>(&sysWindowInfo.info); var nsWindow = new NSWindow(cocaInfo.Window); var contentView = nsWindow.contentView; contentView.wantsLayer = true; contentView.layer = CAMetalLayer.New().NativePtr; var surfaceInfo = new VkMacOSSurfaceCreateInfoMVK { sType = VkStructureType.MacosSurfaceCreateInfoMvk, pView = nsWindow.contentView.NativePtr.ToPointer() }; error = VulkanNative.vkCreateMacOSSurfaceMVK( graphicsService.Handle, &surfaceInfo, null, &surface ); } else { throw new PlatformNotSupportedException("this platform is currently not supported"); } if (error != VkResult.Success) { throw new Exception("failed to create window surface"); } _surface = 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; } } } } }
public static IntPtr CreateWindowSurface(IntPtr vulkanInstance, NativeWindowBase window) { EnsureInit(); if (OperatingSystem.IsWindows() && IsExtensionPresent("VK_KHR_win32_surface")) { vkCreateWin32SurfaceKHRDelegate vkCreateWin32SurfaceKHR = Marshal.GetDelegateForFunctionPointer <vkCreateWin32SurfaceKHRDelegate>(_vkGetInstanceProcAddr(vulkanInstance, "vkCreateWin32SurfaceKHR")); VkWin32SurfaceCreateInfoKHR creationInfo = new VkWin32SurfaceCreateInfoKHR { StructType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, Next = IntPtr.Zero, Flags = 0, // Broken warning here there is no platform issues here... #pragma warning disable CA1416 HInstance = Win32.GetWindowLong(window.WindowHandle.RawHandle, Win32.GetWindowLongIndex.GWL_HINSTANCE), #pragma warning restore CA1416 Hwnd = window.WindowHandle.RawHandle }; int res = vkCreateWin32SurfaceKHR(vulkanInstance, ref creationInfo, IntPtr.Zero, out IntPtr surface); if (res != 0) { throw new PlatformException($"vkCreateWin32SurfaceKHR failed: {res}"); } return(surface); } if (OperatingSystem.IsLinux()) { if (IsExtensionPresent("VK_KHR_xcb_surface")) { vkCreateXcbSurfaceKHRDelegate vkCreateXcbSurfaceKHR = Marshal.GetDelegateForFunctionPointer <vkCreateXcbSurfaceKHRDelegate>(_vkGetInstanceProcAddr(vulkanInstance, "vkCreateXcbSurfaceKHR")); VkXcbSurfaceCreateInfoKHR creationInfo = new VkXcbSurfaceCreateInfoKHR { StructType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, Next = IntPtr.Zero, Flags = 0, Connection = X11.GetXCBConnection(window.DisplayHandle.RawHandle), Window = window.WindowHandle.RawHandle }; int res = vkCreateXcbSurfaceKHR(vulkanInstance, ref creationInfo, IntPtr.Zero, out IntPtr surface); if (res != 0) { throw new PlatformException($"vkCreateXcbSurfaceKHR failed: {res}"); } return(surface); } else { vkCreateXlibSurfaceKHRDelegate vkCreateXlibSurfaceKHR = Marshal.GetDelegateForFunctionPointer <vkCreateXlibSurfaceKHRDelegate>(_vkGetInstanceProcAddr(vulkanInstance, "vkCreateXlibSurfaceKHR")); VkXlibSurfaceCreateInfoKHR creationInfo = new VkXlibSurfaceCreateInfoKHR { StructType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, Next = IntPtr.Zero, Flags = 0, Display = window.DisplayHandle.RawHandle, Window = window.WindowHandle.RawHandle }; int res = vkCreateXlibSurfaceKHR(vulkanInstance, ref creationInfo, IntPtr.Zero, out IntPtr surface); if (res != 0) { throw new PlatformException($"vkCreateXlibSurfaceKHR failed: {res}"); } return(surface); } } throw new NotImplementedException(); }
private ulong CreateSurface() { ulong surface; VkResult result; var graphicsProvider = (GraphicsProvider)_graphicsAdapter.GraphicsProvider; switch (_graphicsSurface.Kind) { case GraphicsSurfaceKind.Win32: { var surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR { sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, pNext = null, flags = 0, hinstance = _graphicsSurface.DisplayHandle, hwnd = _graphicsSurface.WindowHandle, }; result = vkCreateWin32SurfaceKHR(graphicsProvider.Instance, &surfaceCreateInfo, pAllocator: null, &surface); if (result != VK_SUCCESS) { ThrowExternalException(nameof(vkCreateWin32SurfaceKHR), (int)result); } break; } case GraphicsSurfaceKind.Xlib: { var surfaceCreateInfo = new VkXlibSurfaceCreateInfoKHR { sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, pNext = null, flags = 0, dpy = (UIntPtr)(void *)_graphicsSurface.DisplayHandle, window = (UIntPtr)(void *)_graphicsSurface.WindowHandle, }; result = vkCreateXlibSurfaceKHR(graphicsProvider.Instance, &surfaceCreateInfo, pAllocator: null, &surface); if (result != VK_SUCCESS) { ThrowExternalException(nameof(vkCreateXlibSurfaceKHR), (int)result); } break; } default: { ThrowArgumentOutOfRangeException(nameof(_graphicsSurface), _graphicsSurface); surface = VK_NULL_HANDLE; break; } } uint supported; result = vkGetPhysicalDeviceSurfaceSupportKHR(_graphicsAdapter.PhysicalDevice, GraphicsQueueFamilyIndex, surface, &supported); if (supported == VK_FALSE) { ThrowArgumentOutOfRangeException(nameof(_graphicsSurface), _graphicsSurface); } return(surface); }