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);
        }
        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);
        }
Example #3
0
        protected override void CreateWindow_Internal()
        {
            Logger.Info("Starting Up Vulkan Renderer");
            Window = SDL.SDL_CreateWindow("Test", SDL.SDL_WINDOWPOS_UNDEFINED, SDL.SDL_WINDOWPOS_UNDEFINED, (int)ScreenSize.X, (int)ScreenSize.Y, SDL.SDL_WindowFlags.SDL_WINDOW_VULKAN | SDL.SDL_WindowFlags.SDL_WINDOW_SHOWN);
            if (Window == IntPtr.Zero)
            {
                Logger.Error("Failed to create SDL window");
                IEngine.Instance.Shutdown();
            }

            SDL.SDL_SetWindowBordered(Window, SDL.SDL_bool.SDL_TRUE);

            uint ExtensionCount;

            SDL.SDL_Vulkan_GetInstanceExtensions(Window, out ExtensionCount, null);
            IntPtr[] ExtensionNames = new IntPtr[(int)ExtensionCount];
            SDL.SDL_Vulkan_GetInstanceExtensions(Window, out ExtensionCount, ExtensionNames);


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

            for (int i = 0; i < ExtensionNames.Length; i++)
            {
                IntPtr Name = ExtensionNames[i];
                string?Ext  = Marshal.PtrToStringUTF8(Name);
                if (Ext != null)
                {
                    Extensions.Add(Ext);
                    Logger.Info("Enabling Vulkan Extension {0}", Ext);
                }
            }
            Extensions.Add("VK_EXT_debug_report");

            List <string> Layers = new List <string>
            {
                "VK_LAYER_KHRONOS_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"
                 */
            };

            Vulkan.ApplicationInfo applicationInfo = new Vulkan.ApplicationInfo
            {
                EngineName         = "Watertight",
                EngineVersion      = 1,
                ApplicationName    = IEngine.Instance.Name,
                ApplicationVersion = 1,
            };



            Vulkan.InstanceCreateInfo createInfo = new Vulkan.InstanceCreateInfo
            {
                ApplicationInfo       = applicationInfo,
                EnabledExtensionCount = (uint)Extensions.Count,
                EnabledExtensionNames = Extensions.ToArray(),
                EnabledLayerCount     = (uint)Layers.Count,
                EnabledLayerNames     = Layers.ToArray(),
            };

            vkInstance    = new Vulkan.Instance(createInfo);
            DebugCallback = DebugReportCallback;
            vkInstance.EnableDebug(DebugCallback);

            {
                //HACKHACK: SDL and Vulkan do not play nice together, so we have to manually set some internal data.

                //Get the Marshalled ptr from the Instance
                Vulkan.IMarshalling MarshalledInstace = vkInstance;
                ulong SurfaceId = 0;
                SDL.SDL_Vulkan_CreateSurface(Window, MarshalledInstace.Handle, out SurfaceId);

                //Two problems.  1) the constructor for SurfaceKhr is internal, so we need to construct it with Activator
                Vulkan.SurfaceKhr surfaceKhr = Activator.CreateInstance(typeof(Vulkan.SurfaceKhr), true) as Vulkan.SurfaceKhr;
                //The internal marshalled pointer here is a private field named "m".  We got a ulong from SDL above, so we need to set that by using Reflection
                var pointerField = typeof(Vulkan.SurfaceKhr).GetField("m", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                pointerField?.SetValue(surfaceKhr, SurfaceId);

                Surface = surfaceKhr;
            }


            InitializeVulkan(vkInstance.EnumeratePhysicalDevices()[0], Surface);
        }