Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        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;
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        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();
        }
Ejemplo n.º 6
0
        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);
        }