예제 #1
0
        internal GraphicsDevice(Core core, bool validation)
        {
            if (!Glfw.VulkanSupported())
            {
                throw new PlatformNotSupportedException("The Vulkan runtime is not available on this platform");
            }
            Core = core;

            // Create the instance and select the device to use
            InitializeVulkanInstance(validation, out VkInstanceInfo, out VkDebugUtils, out VkDeviceInfo, out Features);
            VkInstance       = VkInstanceInfo.Instance;
            VkPhysicalDevice = VkDeviceInfo.PhysicalDevice;
            LINFO($"Selected device '{VkDeviceInfo.DeviceName}'");

            // Create the device and queue objects
            CreateVulkanDevice(VkDeviceInfo, Features, out VkDevice, out var graphicsQueue, out var graphicsQueueIndex);
            GraphicsQueue = new(this, graphicsQueue, graphicsQueueIndex);
            LINFO("Created Vulkan device instance");
            Limits = new(VkDeviceInfo);

            // Create the memory manager
            Memory = new(this);

            // Create the global binding table for the device
            BindingTable = new(this);

            // Prepare resources
            SamplerPool.Initialize(this);
            Resources = new(this);
        }
예제 #2
0
        private static VkSurfaceKHR CreateUIViewSurface(VkGraphicsDevice gd, VkInstance instance, UIViewSwapchainSource uiViewSource, bool hasExtMetalSurface)
        {
            CAMetalLayer metalLayer = CAMetalLayer.New();
            UIView       uiView     = new UIView(uiViewSource.UIView);

            metalLayer.frame  = uiView.frame;
            metalLayer.opaque = true;
            uiView.layer.addSublayer(metalLayer.NativePtr);

            if (hasExtMetalSurface)
            {
                VkMetalSurfaceCreateInfoEXT surfaceCI = new VkMetalSurfaceCreateInfoEXT();
                surfaceCI.sType  = VkMetalSurfaceCreateInfoEXT.VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
                surfaceCI.pLayer = metalLayer.NativePtr.ToPointer();
                VkSurfaceKHR surface;
                VkResult     result = gd.CreateMetalSurfaceEXT(instance, &surfaceCI, null, &surface);
                CheckResult(result);
                return(surface);
            }
            else
            {
                VkIOSSurfaceCreateInfoMVK surfaceCI = VkIOSSurfaceCreateInfoMVK.New();
                surfaceCI.pView = uiView.NativePtr.ToPointer();
                VkResult result = vkCreateIOSSurfaceMVK(instance, ref surfaceCI, null, out VkSurfaceKHR surface);
                return(surface);
            }
        }
예제 #3
0
        static VkSwapchainKHR CreateSwapchain(VkSwapchainKHR oldSwapchain, VkInstance instance, VkDevice device, VkPhysicalDevice physicalDevice,
                                              VkSurfaceKHR surface, uint queueFamilyIndex)
        {
            vkDestroySwapchainKHR(device, oldSwapchain, null);//Does nothing if oldswapchain is null

            VkSurfaceCapabilitiesKHR capabilities = new VkSurfaceCapabilitiesKHR();

            Assert(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities));

            GetSwapchainFormat(physicalDevice, surface);
            VkSwapchainKHR           swapchain   = VkSwapchainKHR.Null;
            VkSwapchainCreateInfoKHR pCreateInfo = VkSwapchainCreateInfoKHR.New();

            pCreateInfo.surface               = surface;
            pCreateInfo.minImageCount         = capabilities.minImageCount;
            pCreateInfo.imageFormat           = surfaceFormat.format;//SHORTCUT: Some devices might not support
            pCreateInfo.imageColorSpace       = surfaceFormat.colorSpace;
            pCreateInfo.imageExtent           = capabilities.currentExtent;
            pCreateInfo.imageArrayLayers      = 1;
            pCreateInfo.imageUsage            = VkImageUsageFlags.ColorAttachment;
            pCreateInfo.queueFamilyIndexCount = 1;
            pCreateInfo.pQueueFamilyIndices   = &queueFamilyIndex;
            pCreateInfo.preTransform          = VkSurfaceTransformFlagsKHR.IdentityKHR;
            pCreateInfo.compositeAlpha        = VkCompositeAlphaFlagsKHR.OpaqueKHR;
            pCreateInfo.presentMode           = VkPresentModeKHR.MailboxKHR;

            Assert(vkCreateSwapchainKHR(device, &pCreateInfo, null, &swapchain));

            return(swapchain);
        }
예제 #4
0
        public void InitializeVulkan()
        {
            // Create the VUlkan instance that we will use for this app
            _Instance = new VkInstance("Triangle - Sample", 1, "Ratchet", 1);


            // Now lets walk all physical device and find the first one that supports graphics queue
            foreach (VkPhysicalDevice physicalDevice in _Instance.vkEnumeratePhysicalDevices())
            {
                foreach (VkQueueFamilyProperties queueFamilly in physicalDevice.QueueFamilies)
                {
                    if ((queueFamilly.queueFlags & VkQueueFlags.VK_QUEUE_GRAPHICS) != 0)
                    {
                        // We have a physical device that supports graphics queue, we can now create a Device on it
                        // with one queue and use it as our main device for this sample
                        _Device = physicalDevice.CreateDevice(new VkDeviceQueueCreateInfo[] { new VkDeviceQueueCreateInfo()
                                                                                              {
                                                                                                  queueCount = 1, queueFamily = queueFamilly, queuePriorities = new float[] { 1.0f }
                                                                                              } });

                        // Ok now lets grab the graphics queue back. Technically there should only be one
                        // But just to be clean we do an iteration and look for the queue that matches our
                        // need
                        foreach (VkQueue queue in _Device.Queues)
                        {
                            if (queue.Family.queueFlags == queueFamilly.queueFlags)
                            {
                                _Queue = queue;
                                break;
                            }
                        }
                    }
                }
            }
        }
예제 #5
0
        internal static VkSurfaceKHR CreateSurface(VkGraphicsDevice gd, VkInstance instance, SwapchainSource swapchainSource)
        {
            // TODO a null GD is passed from VkSurfaceSource.CreateSurface for compatibility
            //      when VkSurfaceInfo is removed we do not have to handle gd == null anymore
            var doCheck = gd != null;

            if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_SURFACE_EXTENSION_NAME))
            {
                throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_SURFACE_EXTENSION_NAME}");
            }

            switch (swapchainSource)
            {
            case XlibSwapchainSource xlibSource:
                if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
                {
                    throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_XLIB_SURFACE_EXTENSION_NAME}");
                }
                return(CreateXlib(instance, xlibSource));

            case WaylandSwapchainSource waylandSource:
                if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME))
                {
                    throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME}");
                }
                return(CreateWayland(instance, waylandSource));

            case Win32SwapchainSource win32Source:
                if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
                {
                    throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME}");
                }
                return(CreateWin32(instance, win32Source));

            case AndroidSurfaceSwapchainSource androidSource:
                if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_ANDROID_SURFACE_EXTENSION_NAME))
                {
                    throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_ANDROID_SURFACE_EXTENSION_NAME}");
                }
                return(CreateAndroidSurface(instance, androidSource));

            case NSWindowSwapchainSource nsWindowSource:
                if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_MVK_MACOS_SURFACE_EXTENSION_NAME))
                {
                    throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_MVK_MACOS_SURFACE_EXTENSION_NAME}");
                }
                return(CreateNSWindowSurface(instance, nsWindowSource));

            case UIViewSwapchainSource uiViewSource:
                if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_MVK_IOS_SURFACE_EXTENSION_NAME))
                {
                    throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_MVK_IOS_SURFACE_EXTENSION_NAME}");
                }
                return(CreateUIViewSurface(instance, uiViewSource));

            default:
                throw new VeldridException($"The provided SwapchainSource cannot be used to create a Vulkan surface.");
            }
        }
예제 #6
0
        public static VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow window, VkAllocationCallbacks pAllocator, out VkSurfaceKHR surface)
        {
            VkWin32SurfaceCreateInfoKHR pCreateInfo = new VkWin32SurfaceCreateInfoKHR();

            pCreateInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
            pCreateInfo.hwnd  = window.GetHandle().Handle;
            return(Vulkan.vkCreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, out surface));
        }
예제 #7
0
        static VkSurfaceKHR CreateSurface(VkInstance instance, NativeWindow window)
        {
            Assert((VkResult)GLFW.Vulkan.CreateWindowSurface(instance.Handle, window.Handle, IntPtr.Zero, out var ptr));

            VkSurfaceKHR surface = new VkSurfaceKHR((ulong)ptr.ToInt64());

            return(surface);
        }
예제 #8
0
        public static void Load <T>(ref T del, VkInstance instance)
        {
            var    command = GetCommand <T>();
            var    native  = Interop.GetUTF8(command);
            IntPtr ptr     = VK.GetInstanceProcAddr(instance, native);

            del = Marshal.GetDelegateForFunctionPointer <T>(ptr);
        }
예제 #9
0
        public static void vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, VkAllocationCallbacks pAllocator)
        {
            VkPreconditions.CheckNull(instance, nameof(instance));

            if (callback != null)
            {
                GetInstance(instance).DestroyDebugReportCallback(callback);
            }
        }
예제 #10
0
        public static IntPtr GetProcAddr(this VkInstance instance, string name)
        {
            int byteCount = Interop.GetMaxByteCount(name);
            var dstPtr    = stackalloc byte[byteCount];

            Interop.StringToPointer(name, dstPtr, byteCount);
            var addr = Vulkan.vkGetInstanceProcAddr(instance, dstPtr);

            return(addr);
        }
예제 #11
0
 public static extern void DebugReportMessageEXT(
     VkInstance instance,
     VkDebugReportFlagsEXT flags,
     VkDebugReportObjectTypeEXT objectType,
     ulong _object,
     ulong location,
     int messageCode,
     byte[] pLayerPrefix,
     byte[] pMessage
     );
예제 #12
0
        public static void vkLoadInstance(VkInstance instance)
        {
            s_loadedInstance = instance;
            GenLoadInstance(instance.Handle, vkGetInstanceProcAddr);
            GenLoadDevice(instance.Handle, vkGetInstanceProcAddr);

            // Manually load win32 entries.
            vkCreateWin32SurfaceKHR_ptr = LoadCallback <vkCreateWin32SurfaceKHRDelegate>(instance.Handle, vkGetInstanceProcAddr, nameof(vkCreateWin32SurfaceKHR));
            vkGetPhysicalDeviceWin32PresentationSupportKHR_ptr = LoadCallback <vkGetPhysicalDeviceWin32PresentationSupportKHRDelegate>(instance.Handle, vkGetInstanceProcAddr, nameof(vkGetPhysicalDeviceWin32PresentationSupportKHR));
        }
예제 #13
0
        private static VkDevice CreateDevice(VkInstance instance, out VkPhysicalDevice physicalDevice,
                                             VkSurfaceKHR surface, out uint queueFamilyIndex)
        {
            queueFamilyIndex = 0;//SHORTCUT computed from queue properties
            physicalDevice   = PickPhysicalDevice(instance, surface, out queueFamilyIndex);

            List <GCHandle> handles            = new List <GCHandle>();
            List <string>   requiredExtensions = new List <string>();

            requiredExtensions.Add("VK_KHR_swapchain");
            string[] extensionNames        = requiredExtensions.ToArray();
            byte[][] pExtensionNames       = new byte[extensionNames.Length][];
            byte *[] ppExtensionNamesArray = new byte *[extensionNames.Length];

            for (int i = 0; i < pExtensionNames.Length; i++)
            {
                pExtensionNames[i] = Encoding.UTF8.GetBytes(extensionNames[i] + char.MinValue);
                GCHandle handle = GCHandle.Alloc(pExtensionNames[i]);
                handles.Add(handle);
                fixed(byte *p = &(((byte[])handle.Target)[0]))
                {
                    ppExtensionNamesArray[i] = p;
                }
            }
            VkDevice device;

            fixed(byte **extensions = &ppExtensionNamesArray[0])
            {
                float[] pQueuePriorities = new float[] { 1.0f };
                VkDeviceQueueCreateInfo deviceQueueCreateInfo = VkDeviceQueueCreateInfo.New();

                deviceQueueCreateInfo.queueFamilyIndex = queueFamilyIndex;
                deviceQueueCreateInfo.queueCount       = 1;

                fixed(float *ptr = &(pQueuePriorities[0]))
                deviceQueueCreateInfo.pQueuePriorities = ptr;

                VkDeviceCreateInfo createInfo = VkDeviceCreateInfo.New();

                createInfo.queueCreateInfoCount    = 1;
                createInfo.pQueueCreateInfos       = &deviceQueueCreateInfo;
                createInfo.ppEnabledExtensionNames = extensions;
                createInfo.enabledExtensionCount   = (uint)extensionNames.Length;

                device = VkDevice.Null;
                Assert(vkCreateDevice(physicalDevice, &createInfo, null, &device));

                foreach (var handle in handles)
                {
                    handle.Free();
                }
            }

            return(device);
        }
예제 #14
0
        public unsafe override VkSurfaceKHR CreateSurface(VkInstance instance)
        {
            VkWin32SurfaceCreateInfoKHR surfaceCI = VkWin32SurfaceCreateInfoKHR.New();

            surfaceCI.hwnd      = _hwnd;
            surfaceCI.hinstance = _hinstance;
            VkResult result = vkCreateWin32SurfaceKHR(instance, ref surfaceCI, null, out VkSurfaceKHR surface);

            CheckResult(result);
            return(surface);
        }
예제 #15
0
        private static VkSurfaceKHR CreateWayland(VkInstance instance, WaylandSwapchainSource waylandSource)
        {
            VkWaylandSurfaceCreateInfoKHR wsci = VkWaylandSurfaceCreateInfoKHR.New();

            wsci.display = (wl_display *)waylandSource.Display;
            wsci.surface = (wl_surface *)waylandSource.Surface;
            VkResult result = vkCreateWaylandSurfaceKHR(instance, ref wsci, null, out VkSurfaceKHR surface);

            CheckResult(result);
            return(surface);
        }
예제 #16
0
        private static VkSurfaceKHR CreateWin32(VkInstance instance, Win32SwapchainSource win32Source)
        {
            VkWin32SurfaceCreateInfoKHR surfaceCI = VkWin32SurfaceCreateInfoKHR.New();

            surfaceCI.hwnd      = win32Source.Hwnd;
            surfaceCI.hinstance = win32Source.Hinstance;
            VkResult result = vkCreateWin32SurfaceKHR(instance, ref surfaceCI, null, out VkSurfaceKHR surface);

            CheckResult(result);
            return(surface);
        }
예제 #17
0
        public unsafe static TDelegate GetProc <TDelegate>(this VkInstance instance, string name) where TDelegate : class
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            IntPtr ptr = GetProcAddr(instance, name);

            return(Marshal.GetDelegateForFunctionPointer <TDelegate>(ptr));
        }
예제 #18
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);
        }
예제 #19
0
        private static VkSurfaceKHR CreateAndroidSurface(VkInstance instance, AndroidSurfaceSwapchainSource androidSource)
        {
            IntPtr aNativeWindow = AndroidRuntime.ANativeWindow_fromSurface(androidSource.JniEnv, androidSource.Surface);

            VkAndroidSurfaceCreateInfoKHR androidSurfaceCI = VkAndroidSurfaceCreateInfoKHR.New();

            androidSurfaceCI.window = (Vulkan.Android.ANativeWindow *)aNativeWindow;
            VkResult result = vkCreateAndroidSurfaceKHR(instance, ref androidSurfaceCI, null, out VkSurfaceKHR surface);

            CheckResult(result);
            return(surface);
        }
예제 #20
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);
        }
예제 #21
0
    public static void vkLoadInstanceOnly(VkInstance instance)
    {
        s_loadedInstance = instance;
        GenLoadInstance(instance.Handle, vkGetInstanceProcAddr);

        vkGetDeviceProcAddr_ptr = (delegate * unmanaged[Stdcall] < VkDevice, byte *, delegate * unmanaged[Stdcall] < void >>) vkGetInstanceProcAddr(instance.Handle, nameof(vkGetDeviceProcAddr));

        // Manually loaded entries.
        LoadWin32(instance);
        LoadXcb(instance);
        LoadXlib(instance);
        LoadWayland(instance);
    }
예제 #22
0
        protected override void ApplicationStarted()
        {
            ApiName = "Vulkan";

            VK.InitStaticDelegates(System);

            if (requestedValidationLayers.Length > 0)
            {
                FindValidationLayers(validationLayers);
            }

            Instance = CreateVulkanInstance();
        }
예제 #23
0
        public static void vkLoadInstance(VkInstance instance)
        {
            s_loadedInstance = instance;
            GenLoadInstance(instance.Handle, vkGetInstanceProcAddr);
            GenLoadDevice(instance.Handle, vkGetInstanceProcAddr);

            // Manually load win32 entries.
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                vkCreateWin32SurfaceKHR_ptr = vkGetInstanceProcAddr(instance.Handle, nameof(vkCreateWin32SurfaceKHR));
                vkGetPhysicalDeviceWin32PresentationSupportKHR_ptr = vkGetInstanceProcAddr(instance.Handle, nameof(vkGetPhysicalDeviceWin32PresentationSupportKHR));
            }
        }
예제 #24
0
파일: Utils.cs 프로젝트: Svengali/vk.net
        public static IntPtr GetDelegate(VkInstance inst, string name)
        {
            byte[]   n   = System.Text.Encoding.UTF8.GetBytes(name + '\0');
            GCHandle hnd = GCHandle.Alloc(n, GCHandleType.Pinned);
            IntPtr   del = Vk.vkGetInstanceProcAddr(inst, hnd.AddrOfPinnedObject());

            if (del == IntPtr.Zero)
            {
                Console.WriteLine("instance function pointer not found for " + name);
            }
            hnd.Free();
            return(del);
        }
예제 #25
0
        public static ReadOnlySpan <VkPhysicalDevice> vkEnumeratePhysicalDevices(VkInstance instance)
        {
            uint physicalDeviceCount = 0;

            vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, null).CheckResult();

            ReadOnlySpan <VkPhysicalDevice> physicalDevices = new VkPhysicalDevice[physicalDeviceCount];

            fixed(VkPhysicalDevice *physicalDevicesPtr = physicalDevices)
            {
                vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevicesPtr).CheckResult();
            }

            return(physicalDevices);
        }
예제 #26
0
        public static void vkDebugReportMessageEXT(
            VkInstance instance,
            VkDebugReportFlagBitsEXT flags,
            VkDebugReportObjectTypeEXT objectType,
            object obj,
            int location,
            int messageCode,
            string pLayerPrefix,
            string pMessage)
        {
            VkPreconditions.CheckNull(instance, nameof(instance));
            VkPreconditions.CheckString(pMessage, nameof(pMessage));

            GetInstance(instance).DebugReportMessage(flags, objectType, obj, location, messageCode, pLayerPrefix, pMessage);
        }
예제 #27
0
        private VkSurfaceKHR InitSurface(VkInstance instance, IntPtr hwnd, IntPtr processHandle)
        {
            var info = new VkWin32SurfaceCreateInfoKHR {
                sType = VkStructureType.Win32SurfaceCreateInfoKHR
            };

            info.hwnd      = hwnd;
            info.hinstance = processHandle; //Process.GetCurrentProcess().Handle

            VkSurfaceKHR vkSurface;

            vkAPI.vkCreateWin32SurfaceKHR(instance, &info, null, &vkSurface).Check();

            return(vkSurface);
        }
예제 #28
0
        private static VkSurfaceKHR CreateUIViewSurface(VkInstance instance, UIViewSwapchainSource uiViewSource)
        {
            CAMetalLayer metalLayer = CAMetalLayer.New();
            UIView       uiView     = new UIView(uiViewSource.UIView);

            metalLayer.frame  = uiView.frame;
            metalLayer.opaque = true;
            uiView.layer.addSublayer(metalLayer.NativePtr);

            VkIOSSurfaceCreateInfoMVK surfaceCI = VkIOSSurfaceCreateInfoMVK.New();

            surfaceCI.pView = uiView.NativePtr.ToPointer();
            VkResult result = vkCreateIOSSurfaceMVK(instance, ref surfaceCI, null, out VkSurfaceKHR surface);

            return(surface);
        }
        internal static VkSurfaceKHR CreateSurface(VkInstance instance, SwapchainSource swapchainSource)
        {
            switch (swapchainSource)
            {
            case XlibSwapchainSource xlibSource:
                return(CreateXlib(instance, xlibSource));

            case Win32SwapchainSource win32Source:
                return(CreateWin32(instance, win32Source));

            case AndroidSurfaceSwapchainSource androidSource:
                return(CreateAndroidSurface(instance, androidSource));

            default:
                throw new VeldridException($"The provided SwapchainSource cannot be used to create a Vulkan surface.");
            }
        }
예제 #30
0
        private static VkSurfaceKHR CreateNSWindowSurface(VkInstance instance, NSWindowSwapchainSource nsWindowSource)
        {
            CAMetalLayer metalLayer  = CAMetalLayer.New();
            NSWindow     nswindow    = new NSWindow(nsWindowSource.NSWindow);
            NSView       contentView = nswindow.contentView;

            contentView.wantsLayer = true;
            contentView.layer      = metalLayer.NativePtr;

            VkMacOSSurfaceCreateInfoMVK surfaceCI = VkMacOSSurfaceCreateInfoMVK.New();

            surfaceCI.pView = contentView.NativePtr.ToPointer();
            VkResult result = vkCreateMacOSSurfaceMVK(instance, ref surfaceCI, null, out VkSurfaceKHR surface);

            CheckResult(result);
            return(surface);
        }