public static bool InitAllAvaliableInstances(AbstractionDesc desc, out List <InstanceBase> instances)
        {
            instances = new List <InstanceBase>();
            if (desc.supportedAPIs == null)
            {
                return(false);
            }

            foreach (var api in desc.supportedAPIs)
            {
                switch (api)
                {
                                        #if WIN32 || WIN32
                case AbstractionAPI.D3D12:
                {
                    if (!LoadNativeLib(Path.Combine(desc.nativeLibPathD3D12, D3D12.Instance.lib)))
                    {
                        continue;
                    }
                    var instanceD3D12 = new D3D12.Instance();
                    if (instanceD3D12.Init(desc.instanceDescD3D12))
                    {
                        instances.Add(instanceD3D12);
                    }
                    else
                    {
                        instanceD3D12.Dispose();
                    }
                }
                break;

                case AbstractionAPI.Vulkan:
                {
                    if (!LoadNativeLib(Path.Combine(desc.nativeLibPathVulkan, Vulkan.Instance.lib)))
                    {
                        continue;
                    }
                    var instanceVulkan = new Vulkan.Instance();
                    if (instanceVulkan.Init(desc.instanceDescVulkan))
                    {
                        instances.Add(instanceVulkan);
                    }
                    else
                    {
                        instanceVulkan.Dispose();
                    }
                }
                break;
                                        #endif
                }
            }

            return(true);
        }
        /// <summary>
        /// Initializes first API avaliable to the hardware
        /// NOTE: 'desc' may be modified
        /// </summary>
        public static bool InitFirstAvaliable(AbstractionDesc desc, out InstanceBase instance, out DeviceBase device)
        {
            // validate supported APIs is configured
            if (desc.supportedAPIs == null)
            {
                instance = null;
                device   = null;
                return(false);
            }

            // try to init each API until we find one supported by this hardware
            foreach (var api in desc.supportedAPIs)
            {
                switch (api)
                {
                                        #if WIN32 || WIN32
                case AbstractionAPI.D3D12:
                {
                    if (!LoadNativeLib(Path.Combine(desc.nativeLibPathD3D12, D3D12.Instance.lib)))
                    {
                        continue;
                    }
                    var instanceD3D12 = new D3D12.Instance();
                    if (instanceD3D12.Init(desc.instanceDescD3D12))
                    {
                        var deviceBase = CreateDevice(desc, instanceD3D12);
                        if (deviceBase is D3D12.Device)
                        {
                            var deviceD3D12 = (D3D12.Device)deviceBase;
                            if (deviceD3D12.Init(desc.deviceDescD3D12))
                            {
                                instance = instanceD3D12;
                                device   = deviceD3D12;
                                return(true);
                            }

                            deviceD3D12.Dispose();
                        }
                        else if (deviceBase is mGPU.Device)
                        {
                            var deviceMGPU = (mGPU.Device)deviceBase;
                            if (deviceMGPU.Init(desc))
                            {
                                instance = instanceD3D12;
                                device   = deviceMGPU;
                                return(true);
                            }

                            deviceMGPU.Dispose();
                        }

                        instanceD3D12.Dispose();
                    }
                    else
                    {
                        instanceD3D12.Dispose();
                    }
                }
                break;

                    /*case AbstractionAPI.Vulkan:
                     * {
                     *      if (!LoadNativeLib(Path.Combine(desc.nativeLibPathVulkan, "vulkan-1.dll"))) continue;
                     *      if (!LoadNativeLib(Path.Combine(desc.nativeLibPathVulkan, Vulkan.Instance.lib))) continue;
                     *      var instanceVulkan = new Vulkan.Instance();
                     *      if (instanceVulkan.Init(desc.instanceDescVulkan))
                     *      {
                     *              var deviceVulkan = new Vulkan.Device(instanceVulkan, desc.deviceType);
                     *              if (deviceVulkan.Init(desc.deviceDescVulkan))
                     *              {
                     *                      instance = instanceVulkan;
                     *                      device = deviceVulkan;
                     *                      return true;
                     *              }
                     *
                     *              deviceVulkan.Dispose();
                     *              instanceVulkan.Dispose();
                     *      }
                     *      else
                     *      {
                     *              instanceVulkan.Dispose();
                     *      }
                     * }
                     * break;*/
                                        #endif
                }
            }

            instance = null;
            device   = null;
            return(false);
        }
        public static bool InitFirstAvaliable(AbstractionDesc desc, out InstanceBase instance, out DeviceBase device)
        {
            if (desc.supportedAPIs == null)
            {
                instance = null;
                device   = null;
                return(false);
            }

            foreach (var api in desc.supportedAPIs)
            {
                switch (api)
                {
                                        #if WIN32 || WIN32
                case AbstractionAPI.D3D12:
                {
                    if (!LoadNativeLib(Path.Combine(desc.nativeLibPathD3D12, D3D12.Instance.lib)))
                    {
                        continue;
                    }
                    var instanceD3D12 = new D3D12.Instance();
                    if (instanceD3D12.Init(desc.instanceDescD3D12))
                    {
                        var deviceD3D12 = new D3D12.Device(instanceD3D12, desc.type);
                        if (deviceD3D12.Init(desc.deviceDescD3D12))
                        {
                            instance = instanceD3D12;
                            device   = deviceD3D12;
                            return(true);
                        }

                        deviceD3D12.Dispose();
                        instanceD3D12.Dispose();
                    }
                    else
                    {
                        instanceD3D12.Dispose();
                    }
                }
                break;

                case AbstractionAPI.Vulkan:
                {
                    if (!LoadNativeLib(Path.Combine(desc.nativeLibPathVulkan, "vulkan-1.dll")))
                    {
                        continue;
                    }
                    if (!LoadNativeLib(Path.Combine(desc.nativeLibPathVulkan, Vulkan.Instance.lib)))
                    {
                        continue;
                    }
                    var instanceVulkan = new Vulkan.Instance();
                    if (instanceVulkan.Init(desc.instanceDescVulkan))
                    {
                        var deviceVulkan = new Vulkan.Device(instanceVulkan, desc.type);
                        if (deviceVulkan.Init(desc.deviceDescVulkan))
                        {
                            instance = instanceVulkan;
                            device   = deviceVulkan;
                            return(true);
                        }

                        deviceVulkan.Dispose();
                        instanceVulkan.Dispose();
                    }
                    else
                    {
                        instanceVulkan.Dispose();
                    }
                }
                break;
                                        #endif
                }
            }

            instance = null;
            device   = null;
            return(false);
        }