示例#1
0
        static void Main(string[] args)
        {
            VkInstance inst;

            using (VkApplicationInfo ai = new VkApplicationInfo()) {
                using (VkInstanceCreateInfo ci = new VkInstanceCreateInfo {
                    pApplicationInfo = ai
                }){
                    CheckResult(vkCreateInstance(ci, IntPtr.Zero, out inst));
                }
            }

            Vk.LoadInstanceFunctionPointers(inst);

            CheckResult(vkEnumeratePhysicalDevices(inst, out uint phyCount, IntPtr.Zero));

            VkPhysicalDevice[] phys = new VkPhysicalDevice[phyCount];

            CheckResult(vkEnumeratePhysicalDevices(inst, out phyCount, phys.Pin()));

            for (int i = 0; i < phys.Length; i++)
            {
                vkGetPhysicalDeviceProperties(phys[i], out VkPhysicalDeviceProperties props);
                Console.WriteLine($"{props.deviceName}");
                Console.WriteLine($"\tdeviceType:   {props.deviceType,20}");
                Console.WriteLine($"\tapiVersion:   {(Version)props.apiVersion,20}");
                Console.WriteLine($"\tdriverVersion:{props.driverVersion,20}");
                Console.WriteLine($"\tvendorID:     {props.vendorID,20}");
            }

            vkDestroyInstance(inst, IntPtr.Zero);
        }
示例#2
0
        private VkInstance InitInstance()
        {
            var extensions = new string[] { vkAPI.VK_KHR_surface, vkAPI.VK_KHR_win32_surface, vkAPI.VK_EXT_debug_report };

            VkLayerProperties[] layerProperties = vkAPI.InstanceLayerProperties();
            string layers = layerProperties.Any(
                l => Marshal.PtrToStringAnsi((IntPtr)l.layerName) == VK_LAYER_LUNARG_standard_validation)
                ? VK_LAYER_LUNARG_standard_validation
                : null;

            var appInfo = new VkApplicationInfo {
                sType = VkStructureType.ApplicationInfo
            };

            appInfo.apiVersion       = Vulkan.VkVersion.Make(1, 0, 0);
            appInfo.pApplicationName = "Hello Vulkan";
            appInfo.pEngineName      = "Hello Engine";

            var info = new VkInstanceCreateInfo {
                sType = VkStructureType.InstanceCreateInfo
            };

            info.EnabledExtensions = extensions;
            info.EnabledLayers     = layers;
            info.pApplicationInfo  = &appInfo;

            VkInstance vkInstance;

            vkAPI.vkCreateInstance(&info, null, &vkInstance).Check();

            info.Free();
            appInfo.Free();

            return(vkInstance);
        }
示例#3
0
        private VkResult CreateInstance(bool enableValidation)
        {
            Settings.Validation = enableValidation;

            VkApplicationInfo appInfo = new VkApplicationInfo()
            {
                sType            = VkStructureType.ApplicationInfo,
                apiVersion       = new Version(1, 0, 0),
                pApplicationName = Name,
                pEngineName      = Name,
            };

            NativeList <IntPtr> instanceExtensions = new NativeList <IntPtr>(2);

            instanceExtensions.Add(Strings.VK_KHR_SURFACE_EXTENSION_NAME);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                instanceExtensions.Add(Strings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                instanceExtensions.Add(Strings.VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
            }
            else
            {
                throw new PlatformNotSupportedException();
            }

            VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New();

            instanceCreateInfo.pApplicationInfo = &appInfo;

            if (instanceExtensions.Count > 0)
            {
                if (enableValidation)
                {
                    instanceExtensions.Add(Strings.VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
                }
                instanceCreateInfo.enabledExtensionCount   = instanceExtensions.Count;
                instanceCreateInfo.ppEnabledExtensionNames = (byte **)instanceExtensions.Data;
            }


            if (enableValidation)
            {
                NativeList <IntPtr> enabledLayerNames = new NativeList <IntPtr>(1);
                enabledLayerNames.Add(Strings.StandardValidationLayeName);
                instanceCreateInfo.enabledLayerCount   = enabledLayerNames.Count;
                instanceCreateInfo.ppEnabledLayerNames = (byte **)enabledLayerNames.Data;
            }

            VkInstance instance;
            VkResult   result = vkCreateInstance(&instanceCreateInfo, null, &instance);

            Instance = instance;
            return(result);
        }
        private void CreateInstance()
        {
#if DEBUG
            if (!this.CheckValidationLayerSupport())
            {
                throw new Exception("Validation layers requested, but not available!");
            }
#endif
            VkApplicationInfo appInfo = new VkApplicationInfo()
            {
                sType              = VkStructureType.VK_STRUCTURE_TYPE_APPLICATION_INFO,
                pApplicationName   = "Hello Triangle".ToPointer(),
                applicationVersion = Helpers.Version(1, 0, 0),
                pEngineName        = "No Engine".ToPointer(),
                engineVersion      = Helpers.Version(1, 0, 0),
                apiVersion         = Helpers.Version(1, 2, 0),
            };

            VkInstanceCreateInfo createInfo = default;
            createInfo.sType            = VkStructureType.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
            createInfo.pApplicationInfo = &appInfo;

            // Extensions
            this.GetAllInstanceExtensionsAvailables();

            IntPtr *extensionsToBytesArray = stackalloc IntPtr[extensions.Length];
            for (int i = 0; i < extensions.Length; i++)
            {
                extensionsToBytesArray[i] = Marshal.StringToHGlobalAnsi(extensions[i]);
            }
            createInfo.enabledExtensionCount   = (uint)extensions.Length;
            createInfo.ppEnabledExtensionNames = (byte **)extensionsToBytesArray;

            // Validation layers
#if DEBUG
            IntPtr *layersToBytesArray = stackalloc IntPtr[validationLayers.Length];
            for (int i = 0; i < validationLayers.Length; i++)
            {
                layersToBytesArray[i] = Marshal.StringToHGlobalAnsi(validationLayers[i]);
            }

            createInfo.enabledLayerCount   = (uint)validationLayers.Length;
            createInfo.ppEnabledLayerNames = (byte **)layersToBytesArray;
#else
            createInfo.enabledLayerCount = 0;
            createInfo.pNext             = null;
#endif

            fixed(VkInstance *instancePtr = &instance)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateInstance(&createInfo, null, instancePtr));
                VulkanNative.LoadFuncionPointers(instance);
            }
        }
示例#5
0
        private VkInstance CreateVulkanInstance()
        {
            NativeString name   = App.Name;
            NativeString engine = "Foster.Framework";

            // create the App Info
            var appInfo = new VkApplicationInfo
            {
                sType              = VkStructureType.ApplicationInfo,
                pApplicationName   = name,
                applicationVersion = VK.MAKE_VERSION(1, 0, 0),
                pEngineName        = engine,
                engineVersion      = VK.MAKE_VERSION(App.Version),
                apiVersion         = VK.MAKE_VERSION(1, 0, 0),
            };

            var createInfo = new VkInstanceCreateInfo
            {
                sType            = VkStructureType.InstanceCreateInfo,
                pApplicationInfo = &appInfo,
            };

            // required validation layers
            using var validationLayerNames = new NativeStringArray(validationLayers);
            if (HasValidationLayers)
            {
                createInfo.enabledLayerCount   = validationLayerNames.Length;
                createInfo.ppEnabledLayerNames = validationLayerNames;
            }

            // get the required Vulkan Extensions
            var exts = System.GetVKExtensions();

            if (HasValidationLayers)
            {
                exts.Add(VkConst.EXT_DEBUG_UTILS_EXTENSION_NAME);
            }

            using var extensions               = new NativeStringArray(exts);
            createInfo.enabledExtensionCount   = extensions.Length;
            createInfo.ppEnabledExtensionNames = extensions;

            // create instance
            var result = VK.CreateInstance(&createInfo, null, out var instance);

            if (result != VkResult.Success)
            {
                throw new Exception($"Failed to create Vulkan Instance, {result}");
            }

            return(instance);
        }
示例#6
0
        private VkResult CreateInstance(bool enableValidation)
        {
            Settings.Validation = enableValidation;

            VkApplicationInfo appInfo = new VkApplicationInfo();

            {
                appInfo.sType      = ApplicationInfo;
                appInfo.apiVersion = VkVersion.Make(1, 0, 0);
                //Name.Set(ref appInfo.pApplicationName);
                appInfo.pApplicationName = Name;
                //Name.Set(ref appInfo.pEngineName);
                appInfo.pEngineName = Name;
            };

            var instanceExtensions = new List <string>();

            instanceExtensions.Add(Strings.VK_KHR_SURFACE_EXTENSION_NAME);
            instanceExtensions.Add(Strings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME);

            VkInstanceCreateInfo instanceCreateInfo = new VkInstanceCreateInfo();

            instanceCreateInfo.sType            = InstanceCreateInfo;
            instanceCreateInfo.pApplicationInfo = &appInfo;

            if (instanceExtensions.Count > 0)
            {
                if (enableValidation)
                {
                    instanceExtensions.Add(Strings.VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
                }
                //instanceExtensions.ToArray().Set(ref instanceCreateInfo.ppEnabledExtensionNames, ref instanceCreateInfo.enabledExtensionCount);
                instanceCreateInfo.EnabledExtensions = instanceExtensions.ToArray();
            }


            if (enableValidation)
            {
                var enabledLayerNames = new List <string>();
                enabledLayerNames.Add(Strings.StandardValidationLayeName);
                //enabledLayerNames.ToArray().Set(ref instanceCreateInfo.ppEnabledLayerNames, ref instanceCreateInfo.enabledLayerCount);
                instanceCreateInfo.EnabledLayers = enabledLayerNames.ToArray();
            }

            VkInstance instance;
            VkResult   result = vkCreateInstance(&instanceCreateInfo, null, &instance);

            Instance = instance;
            return(result);
        }
示例#7
0
        void CreateInstance(InstanceCreateInfo mInfo)
        {
            InteropString appName    = null;
            InteropString engineName = null;
            Marshalled <VkApplicationInfo> appInfoMarshalled = null;

            var extensionsMarshalled = new NativeStringArray(mInfo.extensions);
            var layersMarshalled     = new NativeStringArray(mInfo.layers);

            var info = new VkInstanceCreateInfo();

            info.sType = VkStructureType.InstanceCreateInfo;
            info.enabledExtensionCount   = (uint)extensionsMarshalled.Count;
            info.ppEnabledExtensionNames = extensionsMarshalled.Address;
            info.enabledLayerCount       = (uint)layersMarshalled.Count;
            info.ppEnabledLayerNames     = layersMarshalled.Address;

            if (mInfo.applicationInfo != null)
            {
                var appInfo = new VkApplicationInfo();
                appInfo.sType              = VkStructureType.ApplicationInfo;
                appInfo.apiVersion         = mInfo.applicationInfo.apiVersion;
                appInfo.engineVersion      = mInfo.applicationInfo.engineVersion;
                appInfo.applicationVersion = mInfo.applicationInfo.applicationVersion;

                appName = new InteropString(mInfo.applicationInfo.applicationName);
                appInfo.pApplicationName = appName.Address;

                engineName          = new InteropString(mInfo.applicationInfo.engineName);
                appInfo.pEngineName = engineName.Address;

                appInfoMarshalled     = new Marshalled <VkApplicationInfo>(appInfo);
                info.pApplicationInfo = appInfoMarshalled.Address;
            }

            using (appName) //appName, engineName, and appInfoMarshalled may be null
                using (engineName)
                    using (appInfoMarshalled)
                        using (extensionsMarshalled)
                            using (layersMarshalled) {
                                var result = createInstance(ref info, alloc, out instance);
                                if (result != VkResult.Success)
                                {
                                    throw new InstanceException(string.Format("Error creating instance: {0}", result));
                                }
                            }
        }
示例#8
0
        void CreateInstance()
        {
            var extensions = new List <string>(GLFW.GetRequiredInstanceExceptions());

            var appInfo = new VkApplicationInfo {
                apiVersion         = new VkVersion(1, 0, 0),
                applicationVersion = new VkVersion(1, 0, 0),
                engineVersion      = new VkVersion(1, 0, 0),
                applicationName    = "All Colors",
            };

            var info = new VkInstanceCreateInfo {
                applicationInfo = appInfo,
                extensions      = extensions,
                layers          = layers
            };

            instance = new VkInstance(info);
        }
示例#9
0
        private void createInstance()
        {
            if (enableValidationLayers && !checkValidationLayerSupport())
            {
                throw Program.Throw("validation layers requested, but not available");
            }

            VkApplicationInfo appInfo = new VkApplicationInfo();

            appInfo.sType              = VkStructureType.VK_STRUCTURE_TYPE_APPLICATION_INFO;
            appInfo.pApplicationName   = "Hello Triangle";
            appInfo.applicationVersion = Vulkan.VK_MAKE_VERSION(1, 0, 0);
            appInfo.pEngineName        = "No Engine";
            appInfo.engineVersion      = Vulkan.VK_MAKE_VERSION(1, 0, 0);
            appInfo.apiVersion         = VkApiVersion.VK_API_VERSION_1_0;

            VkInstanceCreateInfo createInfo = new VkInstanceCreateInfo();

            createInfo.sType            = VkStructureType.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
            createInfo.pApplicationInfo = appInfo;

            List <string> extensions = getRequiredExtensions();

            createInfo.enabledExtensionCount   = extensions.Count;
            createInfo.ppEnabledExtensionNames = extensions.ToArray();

            if (enableValidationLayers)
            {
                createInfo.enabledLayerCount   = validationLayers.Length;
                createInfo.ppEnabledLayerNames = validationLayers;
            }
            else
            {
                createInfo.enabledLayerCount = 0;
            }

            VkResult result = Vulkan.vkCreateInstance(createInfo, null, out instance);

            if (result != VkResult.VK_SUCCESS)
            {
                throw Program.Throw("failed to create instance!", result);
            }
        }
示例#10
0
        void CreateInstance()
        {
            var appName = new InteropString("Hello Triangle");

            var appInfo = new VkApplicationInfo();

            appInfo.sType              = CSGL.Vulkan.VkStructureType.ApplicationInfo;
            appInfo.pApplicationName   = appName.Address;
            appInfo.applicationVersion = new CSGL.Vulkan.VkVersion(1, 0, 0);
            appInfo.engineVersion      = new CSGL.Vulkan.VkVersion(0, 0, 1);
            appInfo.apiVersion         = new CSGL.Vulkan.VkVersion(1, 0, 0);

            var appInfoNative = new Native <VkApplicationInfo>(appInfo);

            var info = new VkInstanceCreateInfo();

            info.sType            = CSGL.Vulkan.VkStructureType.InstanceCreateInfo;
            info.pApplicationInfo = appInfoNative.Address;

            var extensions       = GLFW.GetRequiredInstanceExceptions();
            var extensionsNative = new NativeStringArray(extensions);

            info.ppEnabledExtensionNames = extensionsNative.Address;
            info.enabledExtensionCount   = (uint)extensions.Count;

            var layersNative = new NativeStringArray(layers);

            info.ppEnabledLayerNames = layersNative.Address;
            info.enabledLayerCount   = (uint)layers.Length;

            var result = VK.CreateInstance(ref info, alloc, out instance);

            appName.Dispose();
            appInfoNative.Dispose();
            extensionsNative.Dispose();
            layersNative.Dispose();
        }
示例#11
0
        void CreateInstance()
        {
            var extensions = new List <string>(GLFW.GetRequiredInstanceExceptions());

            foreach (var extension in instanceExtensions)
            {
                extensions.Add(extension);
            }

            var appInfo = new VkApplicationInfo {
                apiVersion         = new VkVersion(1, 0, 0),
                applicationVersion = new VkVersion(1, 0, 0),
                engineVersion      = new VkVersion(1, 0, 0),
                applicationName    = "Hello Triangle"
            };

            var info = new VkInstanceCreateInfo {
                applicationInfo = appInfo,
                extensions      = extensions,
                layers          = layers
            };

            instance = new VkInstance(info);
        }
示例#12
0
        private void CreateInstance()
        {
            var appInfo = new VkApplicationInfo
            {
                ApplicationName    = "Hello Triangle",
                ApplicationVersion = (uint)new VkApiVersion(1, 0, 0).Raw,
                EngineName         = "No Engine",
                EngineVersion      = (uint)new VkApiVersion(1, 0, 0).Raw,
                ApiVersion         = new VkApiVersion(1, 0, 0)
            };
            var instanceCreateInfo = new VkInstanceCreateInfo
            {
                ApplicationInfo       = appInfo,
                EnabledExtensionNames = new[]
                {
                    "VK_KHR_surface",
                    "VK_KHR_win32_surface",
                    VkDefines.VK_EXT_DEBUG_REPORT_EXTENSION_NAME
                },
                EnabledLayerNames = LayerNames
            };

            instance = vkGlobal.CreateInstance(instanceCreateInfo, null).Object;
        }
示例#13
0
        static void Main(string[] args)
        {
            VkInstance instance;

#if AUTO_SET_STYPE
            Console.WriteLine("AUTO_SET_STYPE: ON");
            using (VkApplicationInfo ai = new VkApplicationInfo()) {
                using (VkInstanceCreateInfo ci = new VkInstanceCreateInfo {
                    pApplicationInfo = ai
                }){
                    Console.WriteLine(vkCreateInstance(ci, IntPtr.Zero, out instance));
                }
            }
#else
            Console.WriteLine("AUTO_SET_STYPE: OFF");
            using (VkApplicationInfo ai = VkApplicationInfo.New) {
                VkInstanceCreateInfo ci = VkInstanceCreateInfo.New;
                ci.pApplicationInfo = ai;
                Console.WriteLine(vkCreateInstance(ci, IntPtr.Zero, out instance));
                ci.Dispose();
            }
#endif
            vkDestroyInstance(instance, IntPtr.Zero);
        }
示例#14
0
        public static void Init()
        {
            optionalExtn_avail      = new bool[optionalDeviceExtns.Length];
            Console.BackgroundColor = ConsoleColor.Black;
            Console.ForegroundColor = ConsoleColor.White;
            Window = new GameWindow(AppName);
            fixed(IntPtr *instancePtr = &instanceHndl)
            fixed(IntPtr * surfacePtr = &surfaceHndl)
            {
                VkResult res;
                var      instLayers  = new List <string>();
                var      instExtns   = new List <string>();
                var      devExtns    = new List <string>();
                uint     glfwExtnCnt = 0;
                var      glfwExtns   = glfwGetRequiredInstanceExtensions(&glfwExtnCnt);

                for (int i = 0; i < glfwExtnCnt; i++)
                {
                    instExtns.Add(Marshal.PtrToStringAnsi(glfwExtns[i]));
                }

                instExtns.Add(VkKhrGetPhysicalDeviceProperties2ExtensionName);

                if (EnableValidation)
                {
                    instLayers.Add("VK_LAYER_KHRONOS_validation");
                    instExtns.Add(VkExtDebugUtilsExtensionName);
                }

                var layers = stackalloc IntPtr[instLayers.Count];

                for (int i = 0; i < instLayers.Count; i++)
                {
                    layers[i] = Marshal.StringToHGlobalAnsi(instLayers[i]);
                }

                var extns = stackalloc IntPtr[instExtns.Count];

                for (int i = 0; i < instExtns.Count; i++)
                {
                    extns[i] = Marshal.StringToHGlobalAnsi(instExtns[i]);
                }
                {
                    var appInfo =
                        new VkApplicationInfo()
                    {
                        sType              = VkStructureType.StructureTypeApplicationInfo,
                        pApplicationName   = AppName,
                        pEngineName        = EngineName,
                        apiVersion         = VkApiVersion12,
                        applicationVersion = 1,
                        engineVersion      = 1,
                        pNext              = IntPtr.Zero
                    };
                    var appInfo_ptr = appInfo.Pointer();

                    var instCreatInfo = new VkInstanceCreateInfo()
                    {
                        sType            = VkStructureType.StructureTypeInstanceCreateInfo,
                        pApplicationInfo = appInfo_ptr,
                    };

                    instCreatInfo.ppEnabledLayerNames     = layers;
                    instCreatInfo.enabledLayerCount       = (uint)instLayers.Count;
                    instCreatInfo.ppEnabledExtensionNames = extns;
                    instCreatInfo.enabledExtensionCount   = (uint)instExtns.Count;

                    var instCreatInfo_ptr = instCreatInfo.Pointer();

                    //register instance create debug message handler
                    debugCreatInfo = new VkDebugUtilsMessengerCreateInfoEXT()
                    {
                        sType           = VkStructureType.StructureTypeDebugUtilsMessengerCreateInfoExt,
                        messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt | VkDebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt | VkDebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityVerboseBitExt | VkDebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityInfoBitExt,
                        messageType     = VkDebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeGeneralBitExt | VkDebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt | VkDebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt,
                        pfnUserCallback = DebugCallback
                    };
                    var debugCreatInfo_ptr = debugCreatInfo.Pointer();

                    if (EnableValidation)
                    {
                        instCreatInfo.pNext = debugCreatInfo_ptr;
                    }

                    res = vkCreateInstance(instCreatInfo_ptr, null, instancePtr);
                    if (res != VkResult.Success)
                    {
                        throw new Exception("Failed to create instance.");
                    }
                }

                if (EnableValidation)
                {
                    SetupDebugMessengers(instanceHndl);
                    var debugCreatInfo_ptr = debugCreatInfo.Pointer();

                    fixed(IntPtr *dbg_ptr = &debugMessenger)
                    res = CreateDebugUtilsMessengerEXT(instanceHndl, debugCreatInfo_ptr, IntPtr.Zero, dbg_ptr);

                    if (res != VkResult.Success)
                    {
                        throw new Exception("Failed to register debug callback.");
                    }
                }

                res = Window.CreateSurface(instanceHndl, surfacePtr);
                if (res != VkResult.Success)
                {
                    throw new Exception("Failed to create surface.");
                }

                uint devCount = 0;

                vkEnumeratePhysicalDevices(instanceHndl, &devCount, null);
                if (devCount == 0)
                {
                    throw new Exception("Failed to find Vulkan compatible devices.");
                }

                var devices = new IntPtr[devCount];

                fixed(IntPtr *devicesPtr = devices)
                vkEnumeratePhysicalDevices(instanceHndl, &devCount, devicesPtr);

                var ratedDevices = new List <(uint, IntPtr)>();

                for (int i = 0; i < devices.Length; i++)
                {
                    //rate each device
                    ratedDevices.Add((RateDevice(devices[i]), devices[i]));
                }
                var orderedDevices = ratedDevices.OrderByDescending(a => a.Item1)
                                     .Select(a => a.Item2)
                                     .ToArray();

                DeviceInformation    = new DeviceInfo[orderedDevices.Length];
                DeviceInformation[0] = new DeviceInfo()
                {
                    PhysicalDevice = orderedDevices[0]
                };
                //TODO for now just choose the first device

                {
                    //allocate queues for primary device
                    uint graphicsFamily = ~0u;
                    uint computeFamily  = ~0u;
                    uint transferFamily = ~0u;
                    uint presentFamily  = ~0u;

                    uint qfam_cnt = 0;
                    vkGetPhysicalDeviceQueueFamilyProperties(orderedDevices[0], &qfam_cnt, null);
                    var qFams_ptr = new ManagedPtrArray <VkQueueFamilyProperties>(qfam_cnt);
                    vkGetPhysicalDeviceQueueFamilyProperties(orderedDevices[0], &qfam_cnt, qFams_ptr);
                    var qFams = qFams_ptr.Value;

                    uint qFamIdx = 0;
                    foreach (var qFam in qFams)
                    {
                        bool presentSupport = false;
                        vkGetPhysicalDeviceSurfaceSupportKHR(orderedDevices[0], qFamIdx, surfaceHndl, &presentSupport);

                        if ((qFam.queueFlags & VkQueueFlags.QueueGraphicsBit) != 0 && graphicsFamily == ~0u)
                        {
                            graphicsFamily = qFamIdx;
                            if (presentSupport)
                            {
                                presentFamily = qFamIdx;
                            }
                            qFamIdx++;
                            continue;
                        }

                        if ((qFam.queueFlags & VkQueueFlags.QueueComputeBit) != 0 && computeFamily == ~0u)
                        {
                            computeFamily = qFamIdx;
                            if ((qFam.queueFlags & VkQueueFlags.QueueTransferBit) != 0)
                            {
                                transferFamily = qFamIdx;
                            }
                            qFamIdx++;
                            continue;
                        }

                        if ((qFam.queueFlags & VkQueueFlags.QueueTransferBit) != 0)
                        {
                            transferFamily = qFamIdx;
                        }

                        if (graphicsFamily != ~0u && computeFamily != ~0u && transferFamily != ~0u && presentFamily != ~0u)
                        {
                            break;
                        }
                        qFamIdx++;
                    }

                    if (presentFamily == ~0u)
                    {
                        throw new Exception("Separate present queue support hasn't been implemented.");
                    }

                    var max_q_priority          = stackalloc float[] { 1.0f };
                    var dual_graph_q_priority   = stackalloc float[] { 1.0f };
                    var triple_graph_q_priority = stackalloc float[] { 1.0f, 1.0f, 1.0f };

                    VkDeviceQueueCreateInfo graphics_qCreatInfo = new VkDeviceQueueCreateInfo()
                    {
                        sType            = VkStructureType.StructureTypeDeviceQueueCreateInfo,
                        queueFamilyIndex = graphicsFamily,
                        queueCount       = 1,
                        pQueuePriorities = max_q_priority
                    };

                    VkDeviceQueueCreateInfo compute_qCreatInfo = new VkDeviceQueueCreateInfo
                    {
                        sType            = VkStructureType.StructureTypeDeviceQueueCreateInfo,
                        queueFamilyIndex = computeFamily,
                        queueCount       = 1,
                        pQueuePriorities = max_q_priority
                    };

                    VkDeviceQueueCreateInfo transfer_qCreatInfo = new VkDeviceQueueCreateInfo();
                    if (transferFamily != graphicsFamily)
                    {
                        transfer_qCreatInfo.sType            = VkStructureType.StructureTypeDeviceQueueCreateInfo;
                        transfer_qCreatInfo.queueFamilyIndex = transferFamily;
                        transfer_qCreatInfo.queueCount       = 1;
                        transfer_qCreatInfo.pQueuePriorities = max_q_priority;
                    }
                    else
                    {
                        graphics_qCreatInfo.queueCount       = 2;
                        graphics_qCreatInfo.pQueuePriorities = dual_graph_q_priority;
                    }


                    var qCreatInfos = new VkDeviceQueueCreateInfo[3];
                    qCreatInfos[0] = graphics_qCreatInfo;
                    qCreatInfos[1] = compute_qCreatInfo;
                    if (transferFamily != graphicsFamily)
                    {
                        qCreatInfos[2] = transfer_qCreatInfo;
                    }

                    DeviceInformation[0].GraphicsFamily = graphicsFamily;
                    DeviceInformation[0].ComputeFamily  = computeFamily;
                    DeviceInformation[0].TransferFamily = transferFamily;
                    DeviceInformation[0].PresentFamily  = presentFamily;

                    VkPhysicalDeviceFeatures devFeats = new VkPhysicalDeviceFeatures()
                    {
                        multiDrawIndirect              = true,
                        drawIndirectFirstInstance      = true,
                        fullDrawIndexUint32            = true,
                        tessellationShader             = true,
                        fragmentStoresAndAtomics       = true,
                        vertexPipelineStoresAndAtomics = true,
                        robustBufferAccess             = EnableValidation,
                        shaderInt16       = true,
                        samplerAnisotropy = true,
                        fillModeNonSolid  = true,
                        largePoints       = true,
                    };

                    var devFeats11 = new VkPhysicalDeviceVulkan11Features()
                    {
                        sType = VkStructureType.StructureTypePhysicalDeviceVulkan11Features,
                        shaderDrawParameters = true,
                        //storageBuffer16BitAccess = true,
                        //uniformAndStorageBuffer16BitAccess = true,
                        //storagePushConstant16 = true,
                    };
                    var devFeats11_ptr = devFeats11.Pointer();

                    /*
                     * var depthStenc = new VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures()
                     * {
                     *  sType = VkStructureType.StructureTypePhysicalDeviceSeparateDepthStencilLayoutsFeatures,
                     *  separateDepthStencilLayouts = true,
                     *  pNext = devFeats11_ptr
                     * };
                     * var depthStenc_ptr = depthStenc.Pointer();
                     *
                     * var timelineSems = new VkPhysicalDeviceTimelineSemaphoreFeatures()
                     * {
                     *  sType = VkStructureType.StructureTypePhysicalDeviceTimelineSemaphoreFeatures,
                     *  timelineSemaphore = true,
                     *  pNext = depthStenc_ptr,
                     * };
                     * var timelineSems_ptr = timelineSems.Pointer();
                     *
                     * var indirectCnt = new VkPhysicalDeviceShaderFloat16Int8Features()
                     * {
                     *  sType = VkStructureType.StructureTypePhysicalDeviceShaderFloat16Int8Features,
                     *  shaderFloat16 = true,
                     *  shaderInt8 = true,
                     *  pNext = timelineSems_ptr,
                     * };
                     * var indirectCnt_ptr = indirectCnt.Pointer();
                     *
                     * var uboLayout = new VkPhysicalDeviceUniformBufferStandardLayoutFeatures()
                     * {
                     *  sType = VkStructureType.StructureTypePhysicalDeviceUniformBufferStandardLayoutFeatures,
                     *  uniformBufferStandardLayout = true,
                     *  pNext = indirectCnt_ptr
                     * };
                     * var uboLayout_ptr = uboLayout.Pointer();
                     *
                     * var storageByte = new VkPhysicalDevice8BitStorageFeatures()
                     * {
                     *  sType = VkStructureType.StructureTypePhysicalDevice8bitStorageFeatures,
                     *  storageBuffer8BitAccess = true,
                     *  uniformAndStorageBuffer8BitAccess = true,
                     *  pNext = uboLayout_ptr
                     * };
                     * var storageByte_ptr = storageByte.Pointer();
                     * var descIndexing = new VkPhysicalDeviceDescriptorIndexingFeatures()
                     * {
                     *  sType = VkStructureType.StructureTypePhysicalDeviceDescriptorIndexingFeatures,
                     *  descriptorBindingSampledImageUpdateAfterBind = true,
                     *  descriptorBindingStorageBufferUpdateAfterBind = true,
                     *  descriptorBindingStorageImageUpdateAfterBind = true,
                     *  descriptorBindingStorageTexelBufferUpdateAfterBind = true,
                     *  descriptorBindingUniformBufferUpdateAfterBind = true,
                     *  descriptorBindingUniformTexelBufferUpdateAfterBind = true,
                     *  descriptorBindingUpdateUnusedWhilePending = true,
                     *  descriptorBindingPartiallyBound = true,
                     *  shaderStorageTexelBufferArrayDynamicIndexing = true,
                     *  pNext = storageByte_ptr,
                     * };
                     * var descIndexing_ptr = descIndexing.Pointer();*/

                    //var drawIndirectCount = new VkDrawIndirecCount

                    var devFeats12 = new VkPhysicalDeviceVulkan12Features()
                    {
                        sType = VkStructureType.StructureTypePhysicalDeviceVulkan12Features,
                        separateDepthStencilLayouts = true,
                        timelineSemaphore           = true,
                        drawIndirectCount           = true,
                        shaderFloat16 = true,
                        shaderInt8    = true,
                        uniformBufferStandardLayout       = true,
                        storageBuffer8BitAccess           = true,
                        uniformAndStorageBuffer8BitAccess = true,
                        descriptorIndexing = true,
                        descriptorBindingSampledImageUpdateAfterBind       = true,
                        descriptorBindingStorageBufferUpdateAfterBind      = true,
                        descriptorBindingStorageImageUpdateAfterBind       = true,
                        descriptorBindingStorageTexelBufferUpdateAfterBind = true,
                        descriptorBindingUniformBufferUpdateAfterBind      = true,
                        descriptorBindingUniformTexelBufferUpdateAfterBind = true,
                        descriptorBindingUpdateUnusedWhilePending          = true,
                        descriptorBindingPartiallyBound = true,
                        shaderStorageTexelBufferArrayDynamicIndexing = true,

                        shaderStorageBufferArrayNonUniformIndexing = true,
                        runtimeDescriptorArray = true,
                        descriptorBindingVariableDescriptorCount = true,

                        pNext = devFeats11_ptr
                    };
                    var devFeats12_ptr = devFeats12.Pointer();

                    devExtns.AddRange(requiredDeviceExtns);
                    for (int i = 0; i < optionalExtn_avail.Length; i++)
                    {
                        if (optionalExtn_avail[i])
                        {
                            devExtns.Add(optionalDeviceExtns[i]);
                        }
                    }
                    var devExtns_ptr = stackalloc IntPtr[devExtns.Count];
                    for (int i = 0; i < devExtns.Count; i++)
                    {
                        devExtns_ptr[i] = Marshal.StringToHGlobalAnsi(devExtns[i]);
                    }

                    var qCreatInfos_ptr = qCreatInfos.Pointer();
                    var devFeats_ptr    = devFeats.Pointer();
                    var devCreatInfo    = new VkDeviceCreateInfo()
                    {
                        sType = VkStructureType.StructureTypeDeviceCreateInfo,
                        queueCreateInfoCount    = (uint)(transferFamily != graphicsFamily ? 3 : 2),
                        enabledExtensionCount   = (uint)devExtns.Count,
                        ppEnabledExtensionNames = devExtns_ptr,
                        enabledLayerCount       = (uint)instLayers.Count,
                        ppEnabledLayerNames     = layers,
                        pEnabledFeatures        = devFeats_ptr,
                        pQueueCreateInfos       = qCreatInfos_ptr,
                        pNext = devFeats12_ptr
                    };
                    var    devCreatInfo_ptr = devCreatInfo.Pointer();
                    IntPtr deviceHndl       = IntPtr.Zero;
                    res = vkCreateDevice(orderedDevices[0], devCreatInfo_ptr, null, &deviceHndl);
                    if (res != VkResult.Success)
                    {
                        throw new Exception("Failed to create logical device.");
                    }
                    DeviceInformation[0].Device = deviceHndl;

                    //Setup memory allocator
                    var allocCreatInfo = new VmaAllocatorCreateInfo()
                    {
                        physicalDevice = DeviceInformation[0].PhysicalDevice,
                        device         = DeviceInformation[0].Device
                    };
                    var allocCreatInfo_ptr = allocCreatInfo.Pointer();

                    fixed(IntPtr *vma_alloc_ptr = &DeviceInformation[0].vmaAllocator)
                    res = vmaCreateAllocator(allocCreatInfo_ptr, vma_alloc_ptr);

                    if (res != VkResult.Success)
                    {
                        throw new Exception("Failed to initialize allocator.");
                    }

                    IntPtr graph_q_hndl = IntPtr.Zero;
                    IntPtr trans_q_hndl = IntPtr.Zero;
                    IntPtr comp_q_hndl  = IntPtr.Zero;
                    vkGetDeviceQueue(DeviceInformation[0].Device, graphicsFamily, 0, &graph_q_hndl);
                    vkGetDeviceQueue(DeviceInformation[0].Device, computeFamily, 0, &comp_q_hndl);
                    if (transferFamily != graphicsFamily)
                    {
                        vkGetDeviceQueue(DeviceInformation[0].Device, transferFamily, 0, &trans_q_hndl);
                    }
                    else
                    {
                        vkGetDeviceQueue(DeviceInformation[0].Device, graphicsFamily, 1, &trans_q_hndl);
                    }

                    DeviceInformation[0].GraphicsQueue = new GpuQueue(CommandQueueKind.Graphics, graph_q_hndl, graphicsFamily, 0);
                    DeviceInformation[0].TransferQueue = new GpuQueue(CommandQueueKind.Transfer, trans_q_hndl, transferFamily, 0);
                    DeviceInformation[0].ComputeQueue  = new GpuQueue(CommandQueueKind.Compute, comp_q_hndl, computeFamily, 0);

                    var queue_indices = new List <uint>();
                    if (!queue_indices.Contains(DeviceInformation[0].GraphicsFamily))
                    {
                        queue_indices.Add(DeviceInformation[0].GraphicsFamily);
                    }
                    if (!queue_indices.Contains(DeviceInformation[0].ComputeFamily))
                    {
                        queue_indices.Add(DeviceInformation[0].ComputeFamily);
                    }
                    if (!queue_indices.Contains(DeviceInformation[0].PresentFamily))
                    {
                        queue_indices.Add(DeviceInformation[0].PresentFamily);
                    }
                    if (!queue_indices.Contains(DeviceInformation[0].TransferFamily))
                    {
                        queue_indices.Add(DeviceInformation[0].TransferFamily);
                    }
                    DeviceInformation[0].QueueFamilyIndices = queue_indices.ToArray();

                    var physDeviceProps = new ManagedPtr <VkPhysicalDeviceProperties>();
                    vkGetPhysicalDeviceProperties(DeviceInformation[0].PhysicalDevice, physDeviceProps);
                    DeviceInformation[0].Properties = physDeviceProps.Value;

                    var caps_ptr = new ManagedPtr <VkSurfaceCapabilitiesKHR>();
                    vkGetPhysicalDeviceSurfaceCapabilitiesKHR(DeviceInformation[0].PhysicalDevice, surfaceHndl, caps_ptr);
                    var caps = caps_ptr.Value;

                    VkExtent2D cur_extent = new VkExtent2D();
                    if (caps.currentExtent.width != uint.MaxValue)
                    {
                        cur_extent = caps.currentExtent;
                    }
                    else
                    {
                        cur_extent.width  = System.Math.Clamp((uint)Window.Width, caps.minImageExtent.width, caps.maxImageExtent.width);
                        cur_extent.height = System.Math.Clamp((uint)Window.Height, caps.minImageExtent.height, caps.maxImageExtent.height);
                    }

                    uint img_cnt = caps.minImageCount + 1;

                    VkSwapchainCreateInfoKHR swapCreatInfo = new VkSwapchainCreateInfoKHR()
                    {
                        sType                 = VkStructureType.StructureTypeSwapchainCreateInfoKhr,
                        surface               = surfaceHndl,
                        minImageCount         = img_cnt,
                        imageFormat           = surface_fmt.format,
                        imageColorSpace       = surface_fmt.colorSpace,
                        imageExtent           = cur_extent,
                        imageArrayLayers      = 1,
                        imageUsage            = VkImageUsageFlags.ImageUsageColorAttachmentBit | VkImageUsageFlags.ImageUsageTransferDstBit | VkImageUsageFlags.ImageUsageTransferSrcBit,
                        imageSharingMode      = VkSharingMode.SharingModeExclusive,
                        queueFamilyIndexCount = 0,
                        pQueueFamilyIndices   = null,
                        preTransform          = caps.currentTransform,
                        compositeAlpha        = VkCompositeAlphaFlagsKHR.CompositeAlphaOpaqueBitKhr,
                        presentMode           = present_mode,
                        clipped               = true,
                        oldSwapchain          = IntPtr.Zero
                    };
                    var swapCreatInfo_ptr = swapCreatInfo.Pointer();

                    fixed(IntPtr *swapchain_ptr = &swapChainHndl)
                    res = vkCreateSwapchainKHR(DeviceInformation[0].Device, swapCreatInfo_ptr, null, swapchain_ptr);

                    if (res != VkResult.Success)
                        throw new Exception("Failed to create swapchain.");

                    fixed(uint *swapchain_img_cnt_ptr = &swapchain_img_cnt)
                    {
                        vkGetSwapchainImagesKHR(DeviceInformation[0].Device, swapChainHndl, swapchain_img_cnt_ptr, null);
                        var swapchainImages_l = new IntPtr[swapchain_img_cnt];

                        fixed(IntPtr *swapchain_imgs = swapchainImages_l)
                        vkGetSwapchainImagesKHR(DeviceInformation[0].Device, swapChainHndl, swapchain_img_cnt_ptr, swapchain_imgs);

                        MaxFramesInFlight = swapchain_img_cnt;
                        MaxFrameCount     = swapchain_img_cnt;
                        swapchainImages   = new Image[swapchain_img_cnt];
                        for (int i = 0; i < swapchainImages.Length; i++)
                        {
                            swapchainImages[i] = new Image($"Swapchain_{i}")
                            {
                                Dimensions    = 2,
                                Width         = cur_extent.width,
                                Height        = cur_extent.height,
                                Depth         = 1,
                                Format        = (ImageFormat)surface_fmt.format,
                                Layers        = 1,
                                Levels        = 1,
                                MemoryUsage   = MemoryUsage.GpuOnly,
                                Usage         = ImageUsage.Sampled,
                                InitialLayout = ImageLayout.Undefined,
                                Cubemappable  = false,
                            };
                            swapchainImages[i].Build(0, swapchainImages_l[i]);
                        }


                        surface_extent     = cur_extent;
                        swapchainViews     = new ImageView[swapchain_img_cnt];
                        DefaultFramebuffer = new Framebuffer[swapchain_img_cnt];
                        for (int i = 0; i < swapchainImages.Length; i++)
                        {
                            swapchainViews[i] = new ImageView($"Swapchain_{i}")
                            {
                                BaseLayer  = 0,
                                BaseLevel  = 0,
                                Format     = (ImageFormat)surface_fmt.format,
                                LayerCount = 1,
                                LevelCount = 1,
                                ViewType   = ImageViewType.View2D,
                            };
                            swapchainViews[i].Build(swapchainImages[i]);

                            DefaultFramebuffer[i]                  = new Framebuffer();
                            DefaultFramebuffer[i].Width            = surface_extent.width;
                            DefaultFramebuffer[i].Height           = surface_extent.height;
                            DefaultFramebuffer[i].Name             = $"Swapchain_{i}";
                            DefaultFramebuffer[i].ColorAttachments = new ImageView[] { swapchainViews[i] };
                        }
                    }

                    for (int i = 0; i < instLayers.Count; i++)
                    {
                        Marshal.FreeHGlobal(layers[i]);
                    }
                    for (int i = 0; i < instExtns.Count; i++)
                    {
                        Marshal.FreeHGlobal(extns[i]);
                    }
                    for (int i = 0; i < devExtns.Count; i++)
                    {
                        Marshal.FreeHGlobal(devExtns_ptr[i]);
                    }

                    //TODO allocate compute and trasnfer queues for all secondary devices
                }

                for (int i = 0; i < 1 /*DeviceInformation.Length*/; i++)
                {
                    var    devInfo    = DeviceInformation[i];
                    IntPtr rrCtxtHndl = IntPtr.Zero;

                    if (rrCreateContextVk(RrApiVersion, devInfo.Device, devInfo.PhysicalDevice, devInfo.ComputeQueue.Handle, devInfo.ComputeFamily, &rrCtxtHndl) != RRError.RrSuccess)
                    {
                        Console.WriteLine($"Failed to initialize RadeonRays for device #{i}.");
                    }
                    DeviceInformation[i].RaysContext = rrCtxtHndl;
                }

                FrameFinishedSemaphore  = new GpuSemaphore[MaxFramesInFlight];
                ImageAvailableSemaphore = new GpuSemaphore[MaxFramesInFlight];
                InflightFences          = new Fence[MaxFramesInFlight];
                for (int i = 0; i < MaxFramesInFlight; i++)
                {
                    FrameFinishedSemaphore[i] = new GpuSemaphore();
                    FrameFinishedSemaphore[i].Build(0, false, 0);

                    ImageAvailableSemaphore[i] = new GpuSemaphore();
                    ImageAvailableSemaphore[i].Build(0, false, 0);

                    InflightFences[i] = new Fence
                    {
                        CreateSignaled = true
                    };
                    InflightFences[i].Build(0);
                }

                Width  = (uint)Window.Width;
                Height = (uint)Window.Height;
            }
        }
        public unsafe GraphicsAdapterFactoryInstance(bool enableValidation)
        {
            var applicationInfo = new VkApplicationInfo
            {
                sType       = VkStructureType.ApplicationInfo,
                apiVersion  = new VkVersion(1, 0, 0),
                pEngineName = (byte *)Marshal.StringToHGlobalAnsi("Stride"),
                //engineVersion = new VkVersion()
            };

            var validationLayerNames = new[]
            {
                "VK_LAYER_KHRONOS_validation",
            };

            IntPtr[] enabledLayerNames = new IntPtr[0];

            if (enableValidation)
            {
                var layers = vkEnumerateInstanceLayerProperties();
                var availableLayerNames = new HashSet <string>();

                for (int index = 0; index < layers.Length; index++)
                {
                    var properties  = layers[index];
                    var namePointer = properties.layerName;
                    var name        = Marshal.PtrToStringAnsi((IntPtr)namePointer);

                    availableLayerNames.Add(name);
                }

                enabledLayerNames = validationLayerNames
                                    .Where(x => availableLayerNames.Contains(x))
                                    .Select(Marshal.StringToHGlobalAnsi).ToArray();

                // Check if validation was really available
                enableValidation = enabledLayerNames.Length > 0;
            }

            var extensionProperties     = vkEnumerateInstanceExtensionProperties();
            var availableExtensionNames = new List <string>();
            var desiredExtensionNames   = new List <string>();

            for (int index = 0; index < extensionProperties.Length; index++)
            {
                var extensionProperty = extensionProperties[index];
                var name = Marshal.PtrToStringAnsi((IntPtr)extensionProperty.extensionName);
                availableExtensionNames.Add(name);
            }

            desiredExtensionNames.Add(KHRSurfaceExtensionName);
            if (!availableExtensionNames.Contains(KHRSurfaceExtensionName))
            {
                throw new InvalidOperationException($"Required extension {KHRSurfaceExtensionName} is not available");
            }

            if (Platform.Type == PlatformType.Windows)
            {
                desiredExtensionNames.Add(KHRWin32SurfaceExtensionName);
                if (!availableExtensionNames.Contains(KHRWin32SurfaceExtensionName))
                {
                    throw new InvalidOperationException($"Required extension {KHRWin32SurfaceExtensionName} is not available");
                }
            }
            else if (Platform.Type == PlatformType.Android)
            {
                desiredExtensionNames.Add(KHRAndroidSurfaceExtensionName);
                if (!availableExtensionNames.Contains(KHRAndroidSurfaceExtensionName))
                {
                    throw new InvalidOperationException($"Required extension {KHRAndroidSurfaceExtensionName} is not available");
                }
            }
            else if (Platform.Type == PlatformType.Linux)
            {
                if (availableExtensionNames.Contains("VK_KHR_xlib_surface"))
                {
                    desiredExtensionNames.Add("VK_KHR_xlib_surface");
                    HasXlibSurfaceSupport = true;
                }
                else if (availableExtensionNames.Contains("VK_KHR_xcb_surface"))
                {
                    desiredExtensionNames.Add("VK_KHR_xcb_surface");
                }
                else
                {
                    throw new InvalidOperationException("None of the supported surface extensions VK_KHR_xcb_surface or VK_KHR_xlib_surface is available");
                }
            }

            bool enableDebugReport = enableValidation && availableExtensionNames.Contains(EXTDebugUtilsExtensionName);

            if (enableDebugReport)
            {
                desiredExtensionNames.Add(EXTDebugUtilsExtensionName);
            }

            var enabledExtensionNames = desiredExtensionNames.Select(Marshal.StringToHGlobalAnsi).ToArray();

            try
            {
                fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var instanceCreateInfo = new VkInstanceCreateInfo
                    {
                        sType                   = VkStructureType.InstanceCreateInfo,
                        pApplicationInfo        = &applicationInfo,
                        enabledLayerCount       = enabledLayerNames != null ? (uint)enabledLayerNames.Length : 0,
                        ppEnabledLayerNames     = enabledLayerNames?.Length > 0 ? (byte **)Core.Interop.Fixed(enabledLayerNames) : null,
                        enabledExtensionCount   = (uint)enabledExtensionNames.Length,
                        ppEnabledExtensionNames = (byte **)enabledExtensionNamesPointer,
                    };

                    vkCreateInstance(&instanceCreateInfo, null, out NativeInstance);
                    vkLoadInstance(NativeInstance);
                }

                // Check if validation layer was available (otherwise detected count is 0)
                if (enableValidation)
                {
                    debugReport = DebugReport;
                    var createInfo = new VkDebugUtilsMessengerCreateInfoEXT
                    {
                        sType           = VkStructureType.DebugUtilsMessengerCreateInfoEXT,
                        messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Verbose | VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning,
                        messageType     = VkDebugUtilsMessageTypeFlagsEXT.General | VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance,
                        pfnUserCallback = Marshal.GetFunctionPointerForDelegate(debugReport)
                    };

                    vkCreateDebugUtilsMessengerEXT(NativeInstance, &createInfo, null, out debugReportCallback).CheckResult();
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }

                foreach (var enabledLayerName in enabledLayerNames)
                {
                    Marshal.FreeHGlobal(enabledLayerName);
                }

                Marshal.FreeHGlobal((IntPtr)applicationInfo.pEngineName);
            }
        }
示例#16
0
            protected override void Initialize()
            {
                var result = vkInitialize();

                result.CheckResult();

                var version         = vkEnumerateInstanceVersion();
                var queryExtensions = vkEnumerateInstanceExtensionProperties();
                var queryLayers     = vkEnumerateInstanceLayerProperties();

                VkString name    = "01-ClearScreen";
                var      appInfo = new VkApplicationInfo
                {
                    sType              = VkStructureType.ApplicationInfo,
                    pApplicationName   = name,
                    applicationVersion = new VkVersion(1, 0, 0),
                    pEngineName        = s_EngineName,
                    engineVersion      = new VkVersion(1, 0, 0),
                    apiVersion         = VkVersion.Version_1_0,
                };

                var instanceExtensions = new List <string>
                {
                    KHRSurfaceExtensionName,
                    KHRWin32SurfaceExtensionName
                };

                var instanceLayers = new List <string>();

                if (EnableValidationLayers)
                {
                    FindValidationLayers(instanceLayers);
                }

                if (instanceLayers.Count > 0)
                {
                    instanceExtensions.Add(EXTDebugUtilsExtensionName);
                }

                using var vkInstanceExtensions = new VkStringArray(instanceExtensions);
                var instanceCreateInfo = new VkInstanceCreateInfo
                {
                    sType                   = VkStructureType.InstanceCreateInfo,
                    pApplicationInfo        = &appInfo,
                    enabledExtensionCount   = vkInstanceExtensions.Length,
                    ppEnabledExtensionNames = vkInstanceExtensions
                };

                using var vkLayerNames = new VkStringArray(instanceLayers);
                if (instanceLayers.Count > 0)
                {
                    instanceCreateInfo.enabledLayerCount   = vkLayerNames.Length;
                    instanceCreateInfo.ppEnabledLayerNames = vkLayerNames;
                }

                result = vkCreateInstance(&instanceCreateInfo, null, out instance);
                vkLoadInstance(instance);

                if (instanceLayers.Count > 0)
                {
                    _debugMessengerCallbackFunc = DebugMessengerCallback;
                    var debugCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT
                    {
                        sType           = VkStructureType.DebugUtilsMessengerCreateInfoEXT,
                        messageSeverity = /*VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT | */ VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT | VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT,
                        messageType     = VkDebugUtilsMessageTypeFlagsEXT.GeneralEXT | VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT | VkDebugUtilsMessageTypeFlagsEXT.PerformanceEXT,
                        pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc)
                    };

                    vkCreateDebugUtilsMessengerEXT(instance, &debugCreateInfo, null, out debugMessenger).CheckResult();
                }

                var surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR
                {
                    sType     = VkStructureType.Win32SurfaceCreateInfoKHR,
                    hinstance = HInstance,
                    hwnd      = MainWindow.Handle
                };

                result = vkCreateWin32SurfaceKHR(instance, &surfaceCreateInfo, null, out surface);

                var physicalDevices = vkEnumeratePhysicalDevices(instance);

                foreach (var physicalDevice in physicalDevices)
                {
                    vkGetPhysicalDeviceProperties(physicalDevice, out var properties);
                    var deviceName = properties.GetDeviceName();
                }

                physicalDevice = physicalDevices[0];

                var queueFamilies = FindQueueFamilies(physicalDevice, surface);

                var priority        = 1.0f;
                var queueCreateInfo = new VkDeviceQueueCreateInfo
                {
                    sType            = VkStructureType.DeviceQueueCreateInfo,
                    queueFamilyIndex = queueFamilies.graphicsFamily,
                    queueCount       = 1,
                    pQueuePriorities = &priority
                };

                List <string> deviceExtensions = new List <string>
                {
                    KHRSwapchainExtensionName
                };
                var deviceCreateInfo = new VkDeviceCreateInfo
                {
                    sType                = VkStructureType.DeviceCreateInfo,
                    pQueueCreateInfos    = &queueCreateInfo,
                    queueCreateInfoCount = 1,
                    pEnabledFeatures     = null,
                };

                using var deviceExtensionNames           = new VkStringArray(deviceExtensions);
                deviceCreateInfo.enabledExtensionCount   = deviceExtensionNames.Length;
                deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;

                result = vkCreateDevice(physicalDevice, &deviceCreateInfo, null, out device);
                if (result != VkResult.Success)
                {
                    throw new Exception($"Failed to create Vulkan Logical Device, {result}");
                }

                vkGetDeviceQueue(device, queueFamilies.graphicsFamily, 0, out graphicsQueue);
                vkGetDeviceQueue(device, queueFamilies.presentFamily, 0, out presentQueue);

                CreateSwapchain();
                CreateSyncPrimitives();
            }
        public unsafe GraphicsAdapterFactoryInstance(bool enableValidation)
        {
            var applicationInfo = new VkApplicationInfo
            {
                sType       = VkStructureType.ApplicationInfo,
                apiVersion  = new VkVersion(1, 0, 0),
                pEngineName = (byte *)Marshal.StringToHGlobalAnsi("Focus"),
                //EngineVersion = new SharpVulkan.Version()
            };

            var desiredLayerNames = new[]
            {
                //"VK_LAYER_LUNARG_standard_validation",
                "VK_LAYER_GOOGLE_threading",
                "VK_LAYER_LUNARG_parameter_validation",
                "VK_LAYER_LUNARG_device_limits",
                "VK_LAYER_LUNARG_object_tracker",
                "VK_LAYER_LUNARG_image",
                "VK_LAYER_LUNARG_core_validation",
                "VK_LAYER_LUNARG_swapchain",
                "VK_LAYER_GOOGLE_unique_objects",
                //"VK_LAYER_LUNARG_api_dump",
                //"VK_LAYER_LUNARG_vktrace"
            };

            IntPtr[] enabledLayerNames = new IntPtr[0];

            if (enableValidation)
            {
                var layers = vkEnumerateInstanceLayerProperties();
                var availableLayerNames = new HashSet <string>();

                for (int index = 0; index < layers.Length; index++)
                {
                    var properties  = layers[index];
                    var namePointer = properties.layerName;
                    var name        = Marshal.PtrToStringAnsi((IntPtr)namePointer);

                    availableLayerNames.Add(name);
                }

                enabledLayerNames = desiredLayerNames
                                    .Where(x => availableLayerNames.Contains(x))
                                    .Select(Marshal.StringToHGlobalAnsi).ToArray();
            }

            var extensionProperties     = vkEnumerateInstanceExtensionProperties();
            var availableExtensionNames = new List <string>();
            var desiredExtensionNames   = new List <string>();

            for (int index = 0; index < extensionProperties.Length; index++)
            {
                var extensionProperty = extensionProperties[index];
                var name = Marshal.PtrToStringAnsi((IntPtr)extensionProperty.extensionName);
                availableExtensionNames.Add(name);
            }

            desiredExtensionNames.Add("VK_KHR_surface");
            desiredExtensionNames.Add("VK_KHR_win32_surface");                // windows
            desiredExtensionNames.Add("VK_KHR_android_surface");              // android
            desiredExtensionNames.Add("VK_KHR_xlib_surface");                 // linux
            desiredExtensionNames.Add("VK_KHR_xcb_surface");                  // linux
            desiredExtensionNames.Add("VK_MVK_macos_surface");                // macos
            desiredExtensionNames.Add("VK_EXT_metal_surface");                // macos
            desiredExtensionNames.Add("VK_MVK_moltenvk");                     // macos
            desiredExtensionNames.Add("VK_NV_external_memory_capabilities");  // NVIDIA needs this one for OpenVR
            desiredExtensionNames.Add("VK_KHR_external_memory_capabilities"); // this one might be used in the future for OpenVR

            bool enableDebugReport = enableValidation && availableExtensionNames.Contains("VK_EXT_debug_report");

            if (enableDebugReport)
            {
                desiredExtensionNames.Add("VK_EXT_debug_report");
            }

            // take out any extensions not supported
            for (int i = 0; i < desiredExtensionNames.Count; i++)
            {
                if (availableExtensionNames.Contains(desiredExtensionNames[i]) == false)
                {
                    desiredExtensionNames.RemoveAt(i);
                    i--;
                }
            }

            var enabledExtensionNames = desiredExtensionNames.Select(Marshal.StringToHGlobalAnsi).ToArray();

            var createDebugReportCallbackName = Marshal.StringToHGlobalAnsi("vkCreateDebugReportCallbackEXT");

            try
            {
                fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var instanceCreateInfo = new VkInstanceCreateInfo
                    {
                        sType                   = VkStructureType.InstanceCreateInfo,
                        pApplicationInfo        = &applicationInfo,
                        enabledLayerCount       = enabledLayerNames != null ? (uint)enabledLayerNames.Length : 0,
                        ppEnabledLayerNames     = enabledLayerNames?.Length > 0 ? (byte **)Core.Interop.Fixed(enabledLayerNames) : null,
                        enabledExtensionCount   = (uint)enabledExtensionNames.Length,
                        ppEnabledExtensionNames = (byte **)enabledExtensionNamesPointer,
                    };

                    vkCreateInstance(&instanceCreateInfo, null, out NativeInstance);
                    vkLoadInstance(NativeInstance);
                }

                if (enableDebugReport)
                {
                    var createDebugReportCallback = (CreateDebugReportCallbackDelegate)Marshal.GetDelegateForFunctionPointer(vkGetInstanceProcAddr(NativeInstance, (byte *)createDebugReportCallbackName), typeof(CreateDebugReportCallbackDelegate));

                    debugReport = DebugReport;
                    var createInfo = new VkDebugReportCallbackCreateInfoEXT
                    {
                        sType       = VkStructureType.DebugReportCallbackCreateInfoEXT,
                        flags       = VkDebugReportFlagsEXT.ErrorEXT | VkDebugReportFlagsEXT.WarningEXT /* | VkDebugReportFlagsEXT.PerformanceWarningEXT | VkDebugReportFlagsEXT.InformationEXT | VkDebugReportFlagsEXT.DebugEXT*/,
                        pfnCallback = Marshal.GetFunctionPointerForDelegate(debugReport)
                    };
                    createDebugReportCallback(NativeInstance, ref createInfo, null, out debugReportCallback);
                }

                if (availableExtensionNames.Contains("VK_EXT_debug_marker"))
                {
                    var beginDebugMarkerName = System.Text.Encoding.ASCII.GetBytes("vkCmdDebugMarkerBeginEXT");

                    var ptr = vkGetInstanceProcAddr(NativeInstance, (byte *)Core.Interop.Fixed(beginDebugMarkerName));
                    if (ptr != IntPtr.Zero)
                    {
                        BeginDebugMarker = (BeginDebugMarkerDelegate)Marshal.GetDelegateForFunctionPointer(ptr, typeof(BeginDebugMarkerDelegate));
                    }

                    var endDebugMarkerName = System.Text.Encoding.ASCII.GetBytes("vkCmdDebugMarkerEndEXT");
                    ptr = vkGetInstanceProcAddr(NativeInstance, (byte *)Core.Interop.Fixed(endDebugMarkerName));
                    if (ptr != IntPtr.Zero)
                    {
                        EndDebugMarker = (EndDebugMarkerDelegate)Marshal.GetDelegateForFunctionPointer(ptr, typeof(EndDebugMarkerDelegate));
                    }
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }

                foreach (var enabledLayerName in enabledLayerNames)
                {
                    Marshal.FreeHGlobal(enabledLayerName);
                }

                Marshal.FreeHGlobal((IntPtr)applicationInfo.pEngineName);
                Marshal.FreeHGlobal(createDebugReportCallbackName);
            }
        }
示例#18
0
        private IntPtr CreateInstance()
        {
            var enabledExtensionCount            = 0u;
            var isSurfaceExtensionSupported      = false;
            var isWin32SurfaceExtensionSupported = false;
            var isXlibSurfaceExtensionSupported  = false;
            var isDebugReportExtensionSupported  = false;

            var extensionPropertyCount = 0u;

            ThrowExternalExceptionIfFailed(nameof(vkEnumerateInstanceExtensionProperties), vkEnumerateInstanceExtensionProperties(pLayerName: null, &extensionPropertyCount, pProperties: null));

            var extensionProperties = new VkExtensionProperties[extensionPropertyCount];

            fixed(VkExtensionProperties *pExtensionProperties = extensionProperties)
            {
                ThrowExternalExceptionIfFailed(nameof(vkEnumerateInstanceExtensionProperties), vkEnumerateInstanceExtensionProperties(pLayerName: null, &extensionPropertyCount, pExtensionProperties));
            }

            for (var i = 0; i < extensionProperties.Length; i++)
            {
                var extensionName = new ReadOnlySpan <sbyte>(Unsafe.AsPointer(ref extensionProperties[i].extensionName[0]), int.MaxValue);
                extensionName = extensionName.Slice(0, extensionName.IndexOf((sbyte)'\0') + 1);

                if (!isSurfaceExtensionSupported && VK_KHR_SURFACE_EXTENSION_NAME.SequenceEqual(extensionName))
                {
                    isSurfaceExtensionSupported = true;
                    enabledExtensionCount++;
                }

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    if (!isWin32SurfaceExtensionSupported && VK_KHR_WIN32_SURFACE_EXTENSION_NAME.SequenceEqual(extensionName))
                    {
                        isWin32SurfaceExtensionSupported = true;
                        enabledExtensionCount++;
                    }
                }
                else
                {
                    if (!isXlibSurfaceExtensionSupported && VK_KHR_XLIB_SURFACE_EXTENSION_NAME.SequenceEqual(extensionName))
                    {
                        isXlibSurfaceExtensionSupported = true;
                        enabledExtensionCount++;
                    }
                }

#if DEBUG
                if (!isDebugReportExtensionSupported && VK_EXT_DEBUG_REPORT_EXTENSION_NAME.SequenceEqual(extensionName))
                {
                    isDebugReportExtensionSupported = true;
                    enabledExtensionCount++;
                }
#endif
            }

            var enabledExtensionNames = stackalloc sbyte *[(int)enabledExtensionCount];

            if (!isSurfaceExtensionSupported)
            {
                ThrowInvalidOperationException(nameof(isSurfaceExtensionSupported), isSurfaceExtensionSupported);
            }

            enabledExtensionNames[0] = (sbyte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(VK_KHR_SURFACE_EXTENSION_NAME));

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                if (!isWin32SurfaceExtensionSupported)
                {
                    ThrowInvalidOperationException(nameof(isWin32SurfaceExtensionSupported), isWin32SurfaceExtensionSupported);
                }

                enabledExtensionNames[1] = (sbyte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(VK_KHR_WIN32_SURFACE_EXTENSION_NAME));
            }
            else
            {
                if (!isXlibSurfaceExtensionSupported)
                {
                    ThrowInvalidOperationException(nameof(isXlibSurfaceExtensionSupported), isXlibSurfaceExtensionSupported);
                }

                enabledExtensionNames[1] = (sbyte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(VK_KHR_XLIB_SURFACE_EXTENSION_NAME));
            }

            if (isDebugReportExtensionSupported)
            {
                // We don't want to throw if the debug extension isn't available
                enabledExtensionNames[2] = (sbyte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(VK_EXT_DEBUG_REPORT_EXTENSION_NAME));
            }

            var enabledLayerCount = 0u;
            var isLunarGStandardValidationLayerSupported = false;

#if DEBUG
            var layerPropertyCount = 0u;
            ThrowExternalExceptionIfFailed(nameof(vkEnumerateInstanceLayerProperties), vkEnumerateInstanceLayerProperties(&layerPropertyCount, pProperties: null));

            var layerProperties = new VkLayerProperties[layerPropertyCount];

            fixed(VkLayerProperties *pLayerProperties = layerProperties)
            {
                ThrowExternalExceptionIfFailed(nameof(vkEnumerateInstanceLayerProperties), vkEnumerateInstanceLayerProperties(&layerPropertyCount, pLayerProperties));
            }

            for (var i = 0; i < layerProperties.Length; i++)
            {
                var layerName = new ReadOnlySpan <sbyte>(Unsafe.AsPointer(ref layerProperties[i].layerName[0]), int.MaxValue);
                layerName = layerName.Slice(0, layerName.IndexOf((sbyte)'\0') + 1);

                if (!isLunarGStandardValidationLayerSupported && VK_LAYER_LUNARG_STANDARD_VALIDATION_LAYER_NAME.SequenceEqual(layerName))
                {
                    isLunarGStandardValidationLayerSupported = true;
                    enabledLayerCount++;
                }
            }
#endif

            var enabledLayerNames = stackalloc sbyte *[(int)enabledLayerCount];

            if (isLunarGStandardValidationLayerSupported)
            {
                enabledLayerNames[0] = (sbyte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(VK_LAYER_LUNARG_STANDARD_VALIDATION_LAYER_NAME));
            }

            var applicationInfo = new VkApplicationInfo {
                sType              = VK_STRUCTURE_TYPE_APPLICATION_INFO,
                pNext              = null,
                pApplicationName   = null,
                applicationVersion = 1,
                pEngineName        = (sbyte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(s_engineName)),
                engineVersion      = VK_MAKE_VERSION(0, 1, 0),
                apiVersion         = VK_API_VERSION_1_0,
            };

            var createInfo = new VkInstanceCreateInfo {
                sType                   = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
                pNext                   = null,
                flags                   = 0,
                pApplicationInfo        = &applicationInfo,
                enabledLayerCount       = enabledLayerCount,
                ppEnabledLayerNames     = enabledLayerNames,
                enabledExtensionCount   = enabledExtensionCount,
                ppEnabledExtensionNames = enabledExtensionNames,
            };

            IntPtr instance;
            var    result = vkCreateInstance(&createInfo, null, &instance);

            if (result != VK_SUCCESS)
            {
                ThrowExternalException(nameof(vkCreateInstance), (int)result);
            }

            if (isDebugReportExtensionSupported && isLunarGStandardValidationLayerSupported)
            {
#if DEBUG
                ulong debugReportCallbackExt;

                _debugReportCallback = new NativeDelegate <PFN_vkDebugReportCallbackEXT>(DebugReportCallback);

                var debugReportCallbackCreateInfo = new VkDebugReportCallbackCreateInfoEXT {
                    sType       = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
                    pNext       = null,
                    flags       = (uint)(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT),
                    pfnCallback = _debugReportCallback,
                    pUserData   = null,
                };

                // We don't want to fail if creating the debug report callback failed
                var vkCreateDebugReportCallbackEXT = vkGetInstanceProcAddr(instance, (sbyte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(VKCREATEDEBUGREPORTCALLBACKEXT_FUNCTION_NAME)));
                _ = Marshal.GetDelegateForFunctionPointer <PFN_vkCreateDebugReportCallbackEXT>(vkCreateDebugReportCallbackEXT)(instance, &debugReportCallbackCreateInfo, pAllocator : null, &debugReportCallbackExt);
                _debugReportCallbackExt = debugReportCallbackExt;
#endif
            }

            return(instance);
        }
示例#19
0
        public VkInstance CreateInstance()
        {
            VkApplicationInfo AppInfo = new VkApplicationInfo()
            {
                sType              = VkStructureType.ApplicationInfo,
                apiVersion         = new Version(1, 0, 0),
                applicationVersion = new Version(0, 0, 1),
                engineVersion      = new Version(0, 0, 2),
                pApplicationName   = Interop.String.ToPointer("Zeckoxe Engine"),
                pEngineName        = Interop.String.ToPointer("Zeckoxe"),
            };


            if (Parameters.Settings.Validation)
            {
                // TODO:
            }

            EnumerateInstanceExtensions = Tools.EnumerateInstanceExtensions();

            if (EnumerateInstanceExtensions.Contains("VK_KHR_surface"))
            {
                InstanceExtensions.Add("VK_KHR_surface");
            }


            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                if (EnumerateInstanceExtensions.Contains("VK_KHR_win32_surface"))
                {
                    InstanceExtensions.Add("VK_KHR_win32_surface");
                }
            }


            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                if (EnumerateInstanceExtensions.Contains("VK_MVK_macos_surface"))
                {
                    InstanceExtensions.Add("VK_MVK_macos_surface");
                }


                if (EnumerateInstanceExtensions.Contains("VK_MVK_ios_surface"))
                {
                    InstanceExtensions.Add("VK_MVK_ios_surface");
                }
            }


            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                if (EnumerateInstanceExtensions.Contains("VK_KHR_android_surface"))
                {
                    InstanceExtensions.Add("VK_KHR_android_surface");
                }


                if (EnumerateInstanceExtensions.Contains("VK_KHR_xlib_surface"))
                {
                    InstanceExtensions.Add("VK_KHR_xlib_surface");
                }


                if (EnumerateInstanceExtensions.Contains("VK_KHR_wayland_surface"))
                {
                    InstanceExtensions.Add("VK_KHR_wayland_surface");
                }
            }



            VkInstanceCreateInfo instanceCreateInfo = new VkInstanceCreateInfo()
            {
                sType                   = VkStructureType.InstanceCreateInfo,
                pNext                   = null,
                pApplicationInfo        = &AppInfo,
                enabledExtensionCount   = (uint)InstanceExtensions.Count(),
                ppEnabledExtensionNames = Interop.String.AllocToPointers(InstanceExtensions.ToArray()),
            };


            VkInstance instance;

            VulkanNative.vkCreateInstance(&instanceCreateInfo, (VkAllocationCallbacks *)null, &instance);
            return(instance);
        }
示例#20
0
        void init()
        {
            List <IntPtr> instanceExtensions = new List <IntPtr> ();
            List <IntPtr> enabledLayerNames  = new List <IntPtr> ();

            instanceExtensions.Add(Strings.VK_KHR_SURFACE_EXTENSION_NAME);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                instanceExtensions.Add(Strings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                instanceExtensions.Add(Strings.VK_KHR_XCB_SURFACE_EXTENSION_NAME);
            }
            else
            {
                throw new PlatformNotSupportedException();
            }

            if (VALIDATION)
            {
                enabledLayerNames.Add(Strings.LayerValidation);
            }
            if (RENDER_DOC_CAPTURE)
            {
                enabledLayerNames.Add(Strings.RenderdocCaptureLayerName);
            }

            if (DEBUG_UTILS)
            {
                instanceExtensions.Add(Strings.VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
                instanceExtensions.Add(Strings.VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
            }

            VkApplicationInfo appInfo = new VkApplicationInfo()
            {
                sType            = VkStructureType.ApplicationInfo,
                apiVersion       = new Vulkan.Version(1, 0, 0),
                pApplicationName = Strings.Name,
                pEngineName      = Strings.Name,
            };

            VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New();

            instanceCreateInfo.pApplicationInfo = appInfo.Pin();

            if (instanceExtensions.Count > 0)
            {
                instanceCreateInfo.enabledExtensionCount   = (uint)instanceExtensions.Count;
                instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.Pin();
            }
            if (enabledLayerNames.Count > 0)
            {
                instanceCreateInfo.enabledLayerCount   = (uint)enabledLayerNames.Count;
                instanceCreateInfo.ppEnabledLayerNames = enabledLayerNames.Pin();
            }

            VkResult result = vkCreateInstance(ref instanceCreateInfo, IntPtr.Zero, out inst);

            if (result != VkResult.Success)
            {
                throw new InvalidOperationException("Could not create Vulkan instance. Error: " + result);
            }

            Vk.LoadInstanceFunctionPointers(inst);

            appInfo.Unpin();

            if (instanceExtensions.Count > 0)
            {
                instanceExtensions.Unpin();
            }
            if (enabledLayerNames.Count > 0)
            {
                enabledLayerNames.Unpin();
            }
        }
示例#21
0
        static void Main(string[] args)
        {
            VkInstance inst;

            using (VkApplicationInfo ai = new VkApplicationInfo()) {
                using (VkInstanceCreateInfo ci = new VkInstanceCreateInfo {
                    pApplicationInfo = ai
                }){
                    CheckResult(vkCreateInstance(ci, IntPtr.Zero, out inst));
                }
            }

            Vk.LoadInstanceFunctionPointers(inst);

            if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.DiscreteGpu, out VkPhysicalDevice phy))
            {
                if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.IntegratedGpu, out phy))
                {
                    if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.Cpu, out phy))
                    {
                        throw new Exception("no suitable physical device found");
                    }
                }
            }

            foreach (VkPhysicalDeviceToolPropertiesEXT toolProp in GetToolProperties(phy))
            {
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine($"Enabled Tool: {toolProp.name}({toolProp.version})");
                Console.ResetColor();
            }

            vkGetPhysicalDeviceQueueFamilyProperties(phy, out uint queueFamilyCount, IntPtr.Zero);
            VkQueueFamilyProperties[] qFamProps = new VkQueueFamilyProperties[queueFamilyCount];
            vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, qFamProps.Pin());
            qFamProps.Unpin();
            Console.WriteLine($"Queues:");
            for (int i = 0; i < queueFamilyCount; i++)
            {
                Console.WriteLine($"\t{i}: {qFamProps[i].queueFlags,-60} ({qFamProps[i].queueCount})");
            }

            uint qFamIndex = (uint)qFamProps.Select((qFam, index) => (qFam, index))
                             .First(qfp => qfp.qFam.queueFlags.HasFlag(VkQueueFlags.Graphics)).index;

            VkDevice dev = default;

            float[] priorities = { 0 };
            using (VkDeviceQueueCreateInfo qInfo = new VkDeviceQueueCreateInfo(qFamIndex, 1, priorities)) {
                using (VkDeviceCreateInfo deviceCreateInfo = new VkDeviceCreateInfo()
                {
                    pQueueCreateInfos = qInfo
                }) {
                    CheckResult(vkCreateDevice(phy, deviceCreateInfo, IntPtr.Zero, out dev));
                }
            }
            vkGetDeviceQueue(dev, qFamIndex, 0, out VkQueue gQ);

            vkDestroyDevice(dev, IntPtr.Zero);

            vkDestroyInstance(inst, IntPtr.Zero);
        }
示例#22
0
        private void CreateInstance(bool debug)
        {
            HashSet <string> availableInstanceLayers     = new HashSet <string>(EnumerateInstanceLayers());
            HashSet <string> availableInstanceExtensions = new HashSet <string>(EnumerateInstanceExtensions());

            VkInstanceCreateInfo instanceCI      = VkInstanceCreateInfo.New();
            VkApplicationInfo    applicationInfo = new VkApplicationInfo();

            applicationInfo.apiVersion         = new VkVersion(1, 0, 0);
            applicationInfo.applicationVersion = new VkVersion(1, 0, 0);
            applicationInfo.engineVersion      = new VkVersion(1, 0, 0);
            applicationInfo.pApplicationName   = s_name;
            applicationInfo.pEngineName        = s_name;

            instanceCI.pApplicationInfo = &applicationInfo;

            StackList <IntPtr, Size64Bytes> instanceExtensions = new StackList <IntPtr, Size64Bytes>();
            StackList <IntPtr, Size64Bytes> instanceLayers     = new StackList <IntPtr, Size64Bytes>();

            if (!availableInstanceExtensions.Contains(CommonStrings.VK_KHR_SURFACE_EXTENSION_NAME))
            {
                throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_SURFACE_EXTENSION_NAME}");
            }

            instanceExtensions.Add(CommonStrings.VK_KHR_SURFACE_EXTENSION_NAME);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                if (!availableInstanceExtensions.Contains(CommonStrings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
                {
                    throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME}");
                }

                instanceExtensions.Add(CommonStrings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                if (!availableInstanceExtensions.Contains(CommonStrings.VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
                {
                    throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_XLIB_SURFACE_EXTENSION_NAME}");
                }

                instanceExtensions.Add(CommonStrings.VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
            }
            else
            {
                throw new NotSupportedException("This platform does not support Vulkan.");
            }

            bool debugReportExtensionAvailable = false;

            if (debug)
            {
                if (availableInstanceExtensions.Contains(CommonStrings.VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
                {
                    debugReportExtensionAvailable = true;
                    instanceExtensions.Add(CommonStrings.VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
                }
                if (availableInstanceLayers.Contains(CommonStrings.StandardValidationLayerName))
                {
                    instanceLayers.Add(CommonStrings.StandardValidationLayerName);
                }
            }

            instanceCI.enabledExtensionCount   = instanceExtensions.Count;
            instanceCI.ppEnabledExtensionNames = (byte **)instanceExtensions.Data;

            instanceCI.enabledLayerCount   = instanceLayers.Count;
            instanceCI.ppEnabledLayerNames = (byte **)instanceLayers.Data;

            VkResult result = vkCreateInstance(ref instanceCI, null, out _instance);

            CheckResult(result);

            if (debug && debugReportExtensionAvailable)
            {
                EnableDebugCallback();
            }
        }
示例#23
0
        /// <summary>
        /// Create a new vulkan instance with enabled extensions given as argument.
        /// </summary>
        /// <param name="extensions">List of extension to enable if supported</param>
        public Instance(params string[] extensions)
        {
            List <IntPtr> instanceExtensions = new List <IntPtr> ();
            List <IntPtr> enabledLayerNames  = new List <IntPtr> ();

            string[] supportedExts = SupportedExtensions(IntPtr.Zero);

            using (PinnedObjects pctx = new PinnedObjects()) {
                for (int i = 0; i < extensions.Length; i++)
                {
                    if (supportedExts.Contains(extensions [i]))
                    {
                        instanceExtensions.Add(extensions [i].Pin(pctx));
                        if (extensions [i] == Ext.I.VK_EXT_debug_utils)
                        {
                            debugUtilsEnabled = true;
                        }
                    }
                    else
                    {
                        Console.WriteLine($"Vulkan initialisation: Unsupported extension: {extensions [i]}");
                    }
                }


                if (VALIDATION)
                {
                    enabledLayerNames.Add(strValidationLayer.Pin(pctx));
                }
                if (RENDER_DOC_CAPTURE)
                {
                    enabledLayerNames.Add(strRenderDocLayer.Pin(pctx));
                }


                VkApplicationInfo appInfo = new VkApplicationInfo()
                {
                    sType            = VkStructureType.ApplicationInfo,
                    apiVersion       = new Vulkan.Version(VK_MAJOR, VK_MINOR, 0),
                    pApplicationName = ENGINE_NAME.Pin(pctx),
                    pEngineName      = APPLICATION_NAME.Pin(pctx),
                };

                VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New();
                instanceCreateInfo.pApplicationInfo = appInfo.Pin(pctx);

                if (instanceExtensions.Count > 0)
                {
                    instanceCreateInfo.enabledExtensionCount   = (uint)instanceExtensions.Count;
                    instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.Pin(pctx);
                }
                if (enabledLayerNames.Count > 0)
                {
                    instanceCreateInfo.enabledLayerCount   = (uint)enabledLayerNames.Count;
                    instanceCreateInfo.ppEnabledLayerNames = enabledLayerNames.Pin(pctx);
                }

                VkResult result = vkCreateInstance(ref instanceCreateInfo, IntPtr.Zero, out inst);
                if (result != VkResult.Success)
                {
                    throw new InvalidOperationException("Could not create Vulkan instance. Error: " + result);
                }

                Vk.LoadInstanceFunctionPointers(inst);
            }
        }
示例#24
0
        private void CreateInstance()
        {
            ////var availableExtensions = EnumerateInstanceExtensions();
            ////var availableLayers = EnumerateInstanceLayers();

            VkApplicationInfo appInfo = new VkApplicationInfo()
            {
                sType            = VkStructureType.VK_STRUCTURE_TYPE_APPLICATION_INFO,
                pApplicationName = "Hello Triangle".ToPointer(),
                pEngineName      = "WaveEngine".ToPointer(),
                engineVersion    = Helpers.Version(3, 0, 0),
            };

            string[] extensions = new string[]
            {
                "VK_KHR_surface",
                "VK_KHR_win32_surface",
                "VK_EXT_debug_report",
            };

            IntPtr *extensionsToEnableArray = stackalloc IntPtr[extensions.Length];

            for (int i = 0; i < extensions.Length; i++)
            {
                string extension = extensions[i];
                extensionsToEnableArray[i] = Marshal.StringToHGlobalAnsi(extension);
            }

            string[] layers = new string[]
            {
                "VK_LAYER_LUNARG_standard_validation"
            };

            IntPtr *layersToEnableArray = stackalloc IntPtr[layers.Length];

            for (int i = 0; i < layers.Length; i++)
            {
                string layer = layers[i];
                layersToEnableArray[i] = Marshal.StringToHGlobalAnsi(layer);
            }

            VkInstanceCreateInfo createInfo = new VkInstanceCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
                ppEnabledExtensionNames = (byte **)extensionsToEnableArray,
                enabledExtensionCount   = (uint)extensions.Length,
                enabledLayerCount       = (uint)layers.Length,
                ppEnabledLayerNames     = (byte **)layersToEnableArray,
                pApplicationInfo        = &appInfo,
            };

            VkInstance newInstance;
            var        result = VulkanNative.vkCreateInstance(&createInfo, null, &newInstance);

            this.vkInstance = newInstance;
            Helpers.CheckErrors(result);

            for (int i = 0; i < extensions.Length; i++)
            {
                Marshal.FreeHGlobal(extensionsToEnableArray[i]);
            }

            for (int i = 0; i < layers.Length; i++)
            {
                Marshal.FreeHGlobal(layersToEnableArray[i]);
            }

            EnableDebugCallback();
        }
示例#25
0
        static VkInstance CreateInstance(Settings settings)
        {
            bool enableValidation = settings.Validation;

            vkInitialize().CheckResult();

            var appInfo = new VkApplicationInfo
            {
                sType              = VkStructureType.ApplicationInfo,
                pApplicationName   = settings.ApplicationName,
                applicationVersion = new VkVersion(1, 0, 0),
                pEngineName        = engineName,
                engineVersion      = new VkVersion(1, 0, 0),
                apiVersion         = vkEnumerateInstanceVersion()
            };

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                instanceExtensions.Add("VK_KHR_win32_surface");
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                instanceExtensions.Add("VK_KHR_xlib_surface");
            }
            else
            {
                throw new PlatformNotSupportedException();
            }

            VkInstanceCreateInfo instanceCreateInfo = new VkInstanceCreateInfo {
                sType = VkStructureType.InstanceCreateInfo
            };

            instanceCreateInfo.pApplicationInfo = &appInfo;

            if (instanceExtensions.Count > 0)
            {
                if (enableValidation)
                {
                    instanceExtensions.Add(Vulkan.EXTDebugReportExtensionName);
                }
                instanceCreateInfo.enabledExtensionCount   = instanceExtensions.Count;
                instanceCreateInfo.ppEnabledExtensionNames = (byte **)instanceExtensions.Data;
            }

            using CStringList enabledLayerNames = new CStringList { "VK_LAYER_KHRONOS_validation" };

            if (enableValidation)
            {
                instanceCreateInfo.enabledLayerCount   = enabledLayerNames.Count;
                instanceCreateInfo.ppEnabledLayerNames = (byte **)enabledLayerNames.Data;
            }

            VulkanUtil.CheckResult(vkCreateInstance(&instanceCreateInfo, null, out VkInstance instance));
            VkInstance = instance;

            vkLoadInstance(VkInstance);

            if (settings.Validation)
            {
                debugReportCallbackExt = CreateDebugReportCallback();
            }

            return(instance);
        }
        public unsafe GraphicsService()
        {
            //create vulkan info
            var applicationInfo = new VkApplicationInfo
            {
                sType              = VkStructureType.ApplicationInfo,
                apiVersion         = new VkVersion(1, 0, 0),
                applicationVersion = new VkVersion(1, 0, 0),
                engineVersion      = new VkVersion(1, 0, 0),
                pApplicationName   = new FixedUtf8String("Tortuga"),
                pEngineName        = new FixedUtf8String("Tortuga")
            };

            //vulkan extensions
            var instanceExtensions = new NativeList <IntPtr>();

            instanceExtensions.Add(GraphicsApiConstants.VK_KHR_SURFACE_EXTENSION_NAME);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                instanceExtensions.Add(GraphicsApiConstants.VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                instanceExtensions.Add(GraphicsApiConstants.VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                instanceExtensions.Add(GraphicsApiConstants.VK_MVK_SURFACE_EXTENSION_NAME);
            }
            else
            {
                throw new NotSupportedException("This platform is not supported");
            }

            if (Settings.IsGraphicsApiDebugingEnabled)
            {
                instanceExtensions.Add(GraphicsApiConstants.VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
            }

            //vulkan validation layers
            var validationLayer = new NativeList <IntPtr>();

            if (Settings.IsGraphicsApiDebugingEnabled)
            {
                uint supportedLayersCount;
                VulkanNative.vkEnumerateInstanceLayerProperties(&supportedLayersCount, null);
                var supportedLayers = new NativeList <VkLayerProperties>(supportedLayersCount);
                supportedLayers.Count = supportedLayersCount;
                VulkanNative.vkEnumerateInstanceLayerProperties(
                    &supportedLayersCount,
                    (VkLayerProperties *)supportedLayers.Data.ToPointer()
                    );
                foreach (var vl in supportedLayers)
                {
                    var validationName = Encoding.ASCII.GetString(vl.layerName, 256).Replace("\0", "");
                    Console.WriteLine($"Supported Validation Layer: {validationName}");
                    validationLayer.Add(new IntPtr(vl.layerName));
                }
            }

            var instanceInfo = new VkInstanceCreateInfo
            {
                sType                   = VkStructureType.InstanceCreateInfo,
                pApplicationInfo        = &applicationInfo,
                enabledExtensionCount   = instanceExtensions.Count,
                ppEnabledExtensionNames = (byte **)instanceExtensions.Data,
                enabledLayerCount       = validationLayer.Count,
                ppEnabledLayerNames     = (byte **)validationLayer.Data
            };

            VkInstance instance;

            if (VulkanNative.vkCreateInstance(
                    &instanceInfo,
                    null,
                    &instance
                    ) != VkResult.Success)
            {
                throw new Exception("failed to initialize graphics api");
            }
            _handle = instance;

            if (Settings.IsGraphicsApiDebugingEnabled)
            {
                if (CreateDebugReportCallback(
                        GetVulkanDebugFlags
                        ) != VkResult.Success)
                {
                    throw new Exception("failed to start graphics api debugger");
                }
            }
            //get vulkan physical device list
            uint deviceCount = 0;

            if (VulkanNative.vkEnumeratePhysicalDevices(
                    _handle,
                    ref deviceCount,
                    null
                    ) != VkResult.Success)
            {
                throw new Exception("could not get physical devices");
            }
            var physicalDevices = new NativeList <VkPhysicalDevice>(deviceCount);

            physicalDevices.Count = deviceCount;
            if (VulkanNative.vkEnumeratePhysicalDevices(
                    _handle,
                    ref deviceCount,
                    (VkPhysicalDevice *)physicalDevices.Data.ToPointer()
                    ) != VkResult.Success)
            {
                throw new Exception("could not get physical devices");
            }

            //setup devices
            _devices = new List <Device>();
            for (int i = 0; i < deviceCount; i++)
            {
                _devices.Add(new Device(physicalDevices[i]));
            }

            //sort devices with best to worst
            _devices.Sort((a, b) => b.Score.CompareTo(a.Score));
        }
示例#27
0
        public GraphicsDevice(string applicationName, bool enableValidation, Window?window)
        {
            VkString name    = applicationName;
            var      appInfo = new VkApplicationInfo
            {
                sType              = VkStructureType.ApplicationInfo,
                pApplicationName   = name,
                applicationVersion = new VkVersion(1, 0, 0),
                pEngineName        = s_EngineName,
                engineVersion      = new VkVersion(1, 0, 0),
                apiVersion         = vkEnumerateInstanceVersion()
            };

            List <string> instanceExtensions = new List <string>
            {
                KHRSurfaceExtensionName
            };

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                instanceExtensions.Add(KHRWin32SurfaceExtensionName);
            }

            List <string> instanceLayers = new List <string>();

            if (enableValidation)
            {
                FindValidationLayers(instanceLayers);
            }

            if (instanceLayers.Count > 0)
            {
                instanceExtensions.Add(EXTDebugUtilsExtensionName);
            }

            using var vkInstanceExtensions = new VkStringArray(instanceExtensions);

            var instanceCreateInfo = new VkInstanceCreateInfo
            {
                sType                   = VkStructureType.InstanceCreateInfo,
                pApplicationInfo        = &appInfo,
                enabledExtensionCount   = vkInstanceExtensions.Length,
                ppEnabledExtensionNames = vkInstanceExtensions
            };

            using var vkLayerNames = new VkStringArray(instanceLayers);
            if (instanceLayers.Count > 0)
            {
                instanceCreateInfo.enabledLayerCount   = vkLayerNames.Length;
                instanceCreateInfo.ppEnabledLayerNames = vkLayerNames;
            }

            var debugUtilsCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT
            {
                sType = VkStructureType.DebugUtilsMessengerCreateInfoEXT
            };

            if (instanceLayers.Count > 0)
            {
                _debugMessengerCallbackFunc          = DebugMessengerCallback;
                debugUtilsCreateInfo.messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning;
                debugUtilsCreateInfo.messageType     = VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance;
                debugUtilsCreateInfo.pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc);

                instanceCreateInfo.pNext = &debugUtilsCreateInfo;
            }

            VkResult result = vkCreateInstance(&instanceCreateInfo, null, out VkInstance);

            if (result != VkResult.Success)
            {
                throw new InvalidOperationException($"Failed to create vulkan instance: {result}");
            }

            vkLoadInstance(VkInstance);

            if (instanceLayers.Count > 0)
            {
                vkCreateDebugUtilsMessengerEXT(VkInstance, &debugUtilsCreateInfo, null, out _debugMessenger).CheckResult();
            }

            Log.Info($"Created VkInstance with version: {appInfo.apiVersion.Major}.{appInfo.apiVersion.Minor}.{appInfo.apiVersion.Patch}");
            if (instanceLayers.Count > 0)
            {
                foreach (var layer in instanceLayers)
                {
                    Log.Info($"Instance layer '{layer}'");
                }
            }

            foreach (string extension in instanceExtensions)
            {
                Log.Info($"Instance extension '{extension}'");
            }

            _surface = CreateSurface(window);

            // Find physical device, setup queue's and create device.
            var physicalDevices = vkEnumeratePhysicalDevices(VkInstance);

            foreach (var physicalDevice in physicalDevices)
            {
                vkGetPhysicalDeviceProperties(physicalDevice, out var properties);
                var deviceName = properties.GetDeviceName();
            }

            PhysicalDevice = physicalDevices[0];

            var queueFamilies = FindQueueFamilies(PhysicalDevice, _surface);

            var priority        = 1.0f;
            var queueCreateInfo = new VkDeviceQueueCreateInfo
            {
                sType            = VkStructureType.DeviceQueueCreateInfo,
                queueFamilyIndex = queueFamilies.graphicsFamily,
                queueCount       = 1,
                pQueuePriorities = &priority
            };

            List <string> deviceExtensions = new List <string>
            {
                KHRSwapchainExtensionName
            };
            var deviceCreateInfo = new VkDeviceCreateInfo
            {
                sType                = VkStructureType.DeviceCreateInfo,
                pQueueCreateInfos    = &queueCreateInfo,
                queueCreateInfoCount = 1,
                pEnabledFeatures     = null,
            };

            using var deviceExtensionNames           = new VkStringArray(deviceExtensions);
            deviceCreateInfo.enabledExtensionCount   = deviceExtensionNames.Length;
            deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;

            result = vkCreateDevice(PhysicalDevice, &deviceCreateInfo, null, out VkDevice);
            if (result != VkResult.Success)
            {
                throw new Exception($"Failed to create Vulkan Logical Device, {result}");
            }

            vkGetDeviceQueue(VkDevice, queueFamilies.graphicsFamily, 0, out GraphicsQueue);
            vkGetDeviceQueue(VkDevice, queueFamilies.presentFamily, 0, out PresentQueue);

            // Create swap chain
            Swapchain = new Swapchain(this, window);
            _perFrame = new PerFrame[Swapchain.ImageCount];
            for (var i = 0; i < _perFrame.Length; i++)
            {
                VkFenceCreateInfo fenceCreateInfo = new VkFenceCreateInfo(VkFenceCreateFlags.Signaled);
                vkCreateFence(VkDevice, &fenceCreateInfo, null, out _perFrame[i].QueueSubmitFence).CheckResult();

                VkCommandPoolCreateInfo poolCreateInfo = new VkCommandPoolCreateInfo
                {
                    sType            = VkStructureType.CommandPoolCreateInfo,
                    flags            = VkCommandPoolCreateFlags.Transient,
                    queueFamilyIndex = queueFamilies.graphicsFamily,
                };
                vkCreateCommandPool(VkDevice, &poolCreateInfo, null, out _perFrame[i].PrimaryCommandPool).CheckResult();

                VkCommandBufferAllocateInfo commandBufferInfo = new VkCommandBufferAllocateInfo
                {
                    sType              = VkStructureType.CommandBufferAllocateInfo,
                    commandPool        = _perFrame[i].PrimaryCommandPool,
                    level              = VkCommandBufferLevel.Primary,
                    commandBufferCount = 1
                };
                vkAllocateCommandBuffers(VkDevice, &commandBufferInfo, out _perFrame[i].PrimaryCommandBuffer).CheckResult();
            }
        }
示例#28
0
        private VkInstance CreateInstance(bool debug)
        {
            VkInstance instance;

            // Specify standard validation layers.
            string surfaceExtension;

            switch (Host.Platform)
            {
            case Platform.Android:
                surfaceExtension = KHRAndroidSurfaceExtensionName;
                break;

            case Platform.Win32:
                surfaceExtension = KHRWin32SurfaceExtensionName;
                break;

            default:
                throw new NotImplementedException();
            }

            VkString name    = "TODO Application Name";
            var      appInfo = new VkApplicationInfo
            {
                sType              = VkStructureType.ApplicationInfo,
                pApplicationName   = name,
                applicationVersion = new VkVersion(1, 0, 0),
                pEngineName        = s_EngineName,
                engineVersion      = new VkVersion(1, 0, 0),
                apiVersion         = VkVersion.Version_1_0,
            };

            var instanceExtensions = new List <string>
            {
                KHRSurfaceExtensionName,
                surfaceExtension
            };

            var instanceLayers = new List <string>();

            if (EnableValidationLayers)
            {
                FindValidationLayers(instanceLayers);
            }

            if (instanceLayers.Count > 0)
            {
                instanceExtensions.Add(EXTDebugUtilsExtensionName);
            }

            using var vkInstanceExtensions = new VkStringArray(instanceExtensions);
            var instanceCreateInfo = new VkInstanceCreateInfo
            {
                sType                   = VkStructureType.InstanceCreateInfo,
                pApplicationInfo        = &appInfo,
                enabledExtensionCount   = vkInstanceExtensions.Length,
                ppEnabledExtensionNames = vkInstanceExtensions
            };


            using var vkLayerNames = new VkStringArray(instanceLayers);
            if (instanceLayers.Count > 0)
            {
                instanceCreateInfo.enabledLayerCount   = vkLayerNames.Length;
                instanceCreateInfo.ppEnabledLayerNames = vkLayerNames;
            }

            VkResult result = vkCreateInstance(&instanceCreateInfo, null, out instance);

            vkLoadInstance(instance);

            if (instanceLayers.Count > 0)
            {
                _debugMessengerCallbackFunc = DebugMessengerCallback;
                var debugCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT
                {
                    sType           = VkStructureType.DebugUtilsMessengerCreateInfoEXT,
                    messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Verbose | VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning,
                    messageType     = VkDebugUtilsMessageTypeFlagsEXT.General | VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance,
                    pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc)
                };

                vkCreateDebugUtilsMessengerEXT(instance, &debugCreateInfo, null, out debugMessenger).CheckResult();
            }

            return(instance);
        }
示例#29
0
        public Instance(ICollection <VkExtension> preferredExtensions, ICollection <VkExtension> requiredExtensions,
                        ICollection <string> preferredLayers, ICollection <string> requiredLayers)
        {
            var supportedLayers = Vulkan.EnumerateLayerProperties().Select(x => x.LayerNameString).ToHashSet();

            Log.Info($"Supported instance layers: {string.Join(", ", supportedLayers)}");
            foreach (var requiredLayer in requiredLayers)
            {
                if (!supportedLayers.Contains(requiredLayer))
                {
                    throw new NotSupportedException($"Layer {requiredLayer} isn't supported");
                }
            }
            var layersToUse = requiredLayers.Union(preferredLayers.Where(supportedLayers.Contains)).ToList();

            var supportedExtensions = Vulkan.EnumerateExtensionProperties(null).Union(
                layersToUse.SelectMany(Vulkan.EnumerateExtensionProperties)).Select(x => x.ExtensionNameString)
                                      .ToHashSet();

            Log.Info($"Supported instance extensions: {string.Join(", ", supportedExtensions)}");
            foreach (var requiredExtension in requiredExtensions)
            {
                if (!supportedExtensions.Contains(VkExtensionDatabase.Extension(requiredExtension).Extension))
                {
                    throw new NotSupportedException($"Extension {requiredExtension} isn't supported");
                }
            }

            var extensionsToUse = requiredExtensions.Select(VkExtensionDatabase.Extension).Select(x => x.Extension)
                                  .Union(
                preferredExtensions.Select(VkExtensionDatabase.Extension).Select(x => x.Extension)
                .Where(supportedExtensions.Contains)).ToList();

            _enabledExtensions =
                extensionsToUse.Select(VkExtensionDatabase.Extension).Where(y => y != null).Select(x => x.ExtensionId).ToHashSet();
            _enableExtensionsByName = extensionsToUse.ToHashSet();

            Log.Info($"Using instance layers: {string.Join(", ", layersToUse)}");
            Log.Info($"Using instance extensions: {string.Join(", ", extensionsToUse)}");

            unsafe
            {
                var layersToUseAnsi = new IntPtr[layersToUse.Count];
                for (var i = 0; i < layersToUse.Count; i++)
                {
                    layersToUseAnsi[i] = Marshal.StringToHGlobalAnsi(layersToUse[i]);
                }
                var extensionsToUseAnsi = new IntPtr[extensionsToUse.Count];
                for (var i = 0; i < extensionsToUse.Count; i++)
                {
                    extensionsToUseAnsi[i] = Marshal.StringToHGlobalAnsi(extensionsToUse[i]);
                }

                var pinnedLayersToUse     = GCHandle.Alloc(layersToUseAnsi, GCHandleType.Pinned);
                var pinnedExtensionsToUse = GCHandle.Alloc(extensionsToUseAnsi, GCHandleType.Pinned);
                try
                {
                    AllocationCallbacks = (VkAllocationCallbacks *)0;
                    var appInfo = new VkApplicationInfo()
                    {
                        SType            = VkStructureType.ApplicationInfo,
                        ApiVersion       = new VkVersion(1, 0, 0),
                        PApplicationName = (byte *)0,
                        PEngineName      = (byte *)0,
                        PNext            = IntPtr.Zero
                    };

                    var instanceInfo = new VkInstanceCreateInfo()
                    {
                        SType = VkStructureType.InstanceCreateInfo,
                        EnabledExtensionCount   = (uint)extensionsToUse.Count,
                        PpEnabledExtensionNames = extensionsToUse.Count > 0
                            ? (byte **)Marshal.UnsafeAddrOfPinnedArrayElement(extensionsToUseAnsi, 0).ToPointer()
                            : (byte **)0,
                        EnabledLayerCount   = (uint)layersToUse.Count,
                        PpEnabledLayerNames = layersToUse.Count > 0
                            ? (byte **)Marshal.UnsafeAddrOfPinnedArrayElement(layersToUseAnsi, 0).ToPointer()
                            : (byte **)0,
                        Flags            = 0,
                        PApplicationInfo = &appInfo,
                        PNext            = IntPtr.Zero
                    };
                    Handle = Vulkan.CreateInstance(&instanceInfo, AllocationCallbacks);
                }
                finally
                {
                    pinnedLayersToUse.Free();
                    pinnedExtensionsToUse.Free();
                    foreach (var ptr in layersToUseAnsi)
                    {
                        Marshal.FreeHGlobal(ptr);
                    }
                    foreach (var ptr in extensionsToUseAnsi)
                    {
                        Marshal.FreeHGlobal(ptr);
                    }
                }
            }

            var devs = new List <PhysicalDevice>();

            foreach (var dev in Handle.EnumeratePhysicalDevices())
            {
                devs.Add(new PhysicalDevice(this, dev));
            }
            PhysicalDevices = devs;
        }