Ejemplo n.º 1
0
        public static unsafe SwapchainSource GetSwapchainSource(Sdl2Window window)
        {
            IntPtr        sdlHandle = window.SdlWindowHandle;
            SDL_SysWMinfo sysWmInfo;

            Sdl2Native.SDL_GetVersion(&sysWmInfo.version);
            Sdl2Native.SDL_GetWMWindowInfo(sdlHandle, &sysWmInfo);
            switch (sysWmInfo.subsystem)
            {
            case SysWMType.Windows:
                Win32WindowInfo w32Info = Unsafe.Read <Win32WindowInfo>(&sysWmInfo.info);
                return(SwapchainSource.CreateWin32(w32Info.Sdl2Window, w32Info.hinstance));

            case SysWMType.X11:
                X11WindowInfo x11Info = Unsafe.Read <X11WindowInfo>(&sysWmInfo.info);
                return(SwapchainSource.CreateXlib(
                           x11Info.display,
                           x11Info.Sdl2Window));

            case SysWMType.Cocoa:
                CocoaWindowInfo cocoaInfo = Unsafe.Read <CocoaWindowInfo>(&sysWmInfo.info);
                IntPtr          nsWindow  = cocoaInfo.Window;
                return(SwapchainSource.CreateNSWindow(nsWindow));

            default:
                throw new PlatformNotSupportedException("Cannot create a SwapchainSource for " + sysWmInfo.subsystem + ".");
            }
        }
Ejemplo n.º 2
0
        private static unsafe RenderContext CreateVulkanRenderContext(Sdl2Window window)
        {
            IntPtr        sdlHandle = window.SdlWindowHandle;
            SDL_SysWMinfo sysWmInfo;

            Sdl2Native.SDL_GetVersion(&sysWmInfo.version);
            Sdl2Native.SDL_GetWMWindowInfo(sdlHandle, &sysWmInfo);
            Win32WindowInfo w32Info = Unsafe.Read <Win32WindowInfo>(&sysWmInfo.info);

            return(new VkRenderContext(VkSurfaceSource.CreateWin32(w32Info.hinstance, w32Info.window), window.Width, window.Height));
        }
Ejemplo n.º 3
0
        private static unsafe Veldrid.Vk.VkSurfaceSource GetSurfaceSource(SDL_SysWMinfo sysWmInfo)
        {
            switch (sysWmInfo.subsystem)
            {
            case SysWMType.Windows:
                Win32WindowInfo w32Info = Unsafe.Read <Win32WindowInfo>(&sysWmInfo.info);
                return(Vk.VkSurfaceSource.CreateWin32(w32Info.hinstance, w32Info.Sdl2Window));

            default:
                throw new PlatformNotSupportedException("Cannot create a Vulkan surface for " + sysWmInfo.subsystem + ".");
            }
        }
Ejemplo n.º 4
0
        private static unsafe VkSurfaceSource GetSurfaceSource(SDL_SysWMinfo sysWmInfo)
        {
            switch (sysWmInfo.subsystem)
            {
            case SysWMType.Windows:
                Win32WindowInfo w32Info = Unsafe.Read <Win32WindowInfo>(&sysWmInfo.info);
                return(VkSurfaceSource.CreateWin32(w32Info.hinstance, w32Info.Sdl2Window));

            case SysWMType.X11:
                X11WindowInfo x11Info = Unsafe.Read <X11WindowInfo>(&sysWmInfo.info);
                return(VkSurfaceSource.CreateXlib(
                           (Vulkan.Xlib.Display *)x11Info.display,
                           new Vulkan.Xlib.Window()
                {
                    Value = x11Info.Sdl2Window
                }));

            default:
                throw new PlatformNotSupportedException("Cannot create a Vulkan surface for " + sysWmInfo.subsystem + ".");
            }
        }
Ejemplo n.º 5
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;
                        }
                    }
                }
            }
        }