示例#1
0
        public unsafe GraphicsAdapterFactoryInstance(bool enableValidation)
        {
            var applicationInfo = new ApplicationInfo
            {
                StructureType = StructureType.ApplicationInfo,
                ApiVersion    = new SharpVulkan.Version(1, 0, 0),
                EngineName    = Marshal.StringToHGlobalAnsi("Xenko"),
                //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 = Vulkan.InstanceLayerProperties;
                var availableLayerNames = new HashSet <string>();

                for (int index = 0; index < layers.Length; index++)
                {
                    var properties  = layers[index];
                    var namePointer = new IntPtr(Interop.Fixed(ref properties.LayerName));
                    var name        = Marshal.PtrToStringAnsi(namePointer);

                    availableLayerNames.Add(name);
                }

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

            var extensionProperties     = Vulkan.GetInstanceExtensionProperties();
            var availableExtensionNames = new List <string>();
            var desiredExtensionNames   = new List <string>();

            for (int index = 0; index < extensionProperties.Length; index++)
            {
                var namePointer = new IntPtr(Interop.Fixed(ref extensionProperties[index].ExtensionName));
                var name        = Marshal.PtrToStringAnsi(namePointer);
                availableExtensionNames.Add(name);
            }

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

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            desiredExtensionNames.Add("VK_KHR_win32_surface");
            if (!availableExtensionNames.Contains("VK_KHR_win32_surface"))
            {
                throw new InvalidOperationException("Required extension VK_KHR_win32_surface is not available");
            }
#elif SILICONSTUDIO_PLATFORM_ANDROID
            desiredExtensionNames.Add("VK_KHR_android_surface");
            if (!availableExtensionNames.Contains("VK_KHR_android_surface"))
            {
                throw new InvalidOperationException("Required extension VK_KHR_android_surface is not available");
            }
#elif SILICONSTUDIO_PLATFORM_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");
            }
#endif
            bool enableDebugReport = enableValidation && availableExtensionNames.Contains("VK_EXT_debug_report");
            if (enableDebugReport)
            {
                desiredExtensionNames.Add("VK_EXT_debug_report");
            }

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

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

            try
            {
                fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var instanceCreateInfo = new InstanceCreateInfo
                    {
                        StructureType         = StructureType.InstanceCreateInfo,
                        ApplicationInfo       = new IntPtr(&applicationInfo),
                        EnabledLayerCount     = enabledLayerNames != null ? (uint)enabledLayerNames.Length : 0,
                        EnabledLayerNames     = enabledLayerNames?.Length > 0 ? new IntPtr(Interop.Fixed(enabledLayerNames)) : IntPtr.Zero,
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer)
                    };

                    NativeInstance = Vulkan.CreateInstance(ref instanceCreateInfo);
                }

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

                    debugReport = DebugReport;
                    var createInfo = new DebugReportCallbackCreateInfo
                    {
                        StructureType = StructureType.DebugReportCallbackCreateInfo,
                        Flags         = (uint)(DebugReportFlags.Error | DebugReportFlags.Warning /* | DebugReportFlags.PerformanceWarning | DebugReportFlags.Information | DebugReportFlags.Debug*/),
                        Callback      = 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 = NativeInstance.GetProcAddress((byte *)Interop.Fixed(beginDebugMarkerName));
                    if (ptr != IntPtr.Zero)
                    {
                        BeginDebugMarker = (BeginDebugMarkerDelegate)Marshal.GetDelegateForFunctionPointer(ptr, typeof(BeginDebugMarkerDelegate));
                    }

                    var endDebugMarkerName = System.Text.Encoding.ASCII.GetBytes("vkCmdDebugMarkerEndEXT");
                    ptr = NativeInstance.GetProcAddress((byte *)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(applicationInfo.EngineName);
                Marshal.FreeHGlobal(createDebugReportCallbackName);
            }
        }
        public unsafe GraphicsAdapterFactoryInstance(bool enableValidation)
        {
            var applicationInfo = new ApplicationInfo
            {
                StructureType = StructureType.ApplicationInfo,
                ApiVersion = new SharpVulkan.Version(1, 0, 0),
                EngineName = Marshal.StringToHGlobalAnsi("Xenko"),
                //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 = Vulkan.InstanceLayerProperties;
                var availableLayerNames = new HashSet<string>();

                for (int index = 0; index < layers.Length; index++)
                {
                    var properties = layers[index];
                    var namePointer = new IntPtr(Interop.Fixed(ref properties.LayerName));
                    var name = Marshal.PtrToStringAnsi(namePointer);

                    availableLayerNames.Add(name);
                }

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

            var extensionProperties = Vulkan.GetInstanceExtensionProperties();
            var availableExtensionNames = new List<string>();
            var desiredExtensionNames = new List<string>();

            for (int index = 0; index < extensionProperties.Length; index++)
            {
                var namePointer = new IntPtr(Interop.Fixed(ref extensionProperties[index].ExtensionName));
                var name = Marshal.PtrToStringAnsi(namePointer);
                availableExtensionNames.Add(name);
            }

            desiredExtensionNames.Add("VK_KHR_surface");
            if (!availableExtensionNames.Contains("VK_KHR_surface"))
                throw new InvalidOperationException("Required extension VK_KHR_surface is not available");

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            desiredExtensionNames.Add("VK_KHR_win32_surface");
            if (!availableExtensionNames.Contains("VK_KHR_win32_surface"))
                throw new InvalidOperationException("Required extension VK_KHR_win32_surface is not available");
#elif SILICONSTUDIO_PLATFORM_ANDROID
                desiredExtensionNames.Add("VK_KHR_android_surface");
                if (!availableExtensionNames.Contains("VK_KHR_android_surface"))
                    throw new InvalidOperationException("Required extension VK_KHR_android_surface is not available");
#elif SILICONSTUDIO_PLATFORM_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");
                }
#endif
            bool enableDebugReport = enableValidation && availableExtensionNames.Contains("VK_EXT_debug_report");
            if (enableDebugReport)
                desiredExtensionNames.Add("VK_EXT_debug_report");

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

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

            try
            {
                fixed (void* enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var instanceCreateInfo = new InstanceCreateInfo
                    {
                        StructureType = StructureType.InstanceCreateInfo,
                        ApplicationInfo = new IntPtr(&applicationInfo),
                        EnabledLayerCount = enabledLayerNames != null ? (uint)enabledLayerNames.Length : 0,
                        EnabledLayerNames = enabledLayerNames?.Length > 0 ? new IntPtr(Interop.Fixed(enabledLayerNames)) : IntPtr.Zero,
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer)
                    };

                    NativeInstance = Vulkan.CreateInstance(ref instanceCreateInfo);
                }

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

                    debugReport = DebugReport;
                    var createInfo = new DebugReportCallbackCreateInfo
                    {
                        StructureType = StructureType.DebugReportCallbackCreateInfo,
                        Flags = (uint)(DebugReportFlags.Error | DebugReportFlags.Warning /* | DebugReportFlags.PerformanceWarning | DebugReportFlags.Information | DebugReportFlags.Debug*/),
                        Callback = 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 = NativeInstance.GetProcAddress((byte*)Interop.Fixed(beginDebugMarkerName));
                    if (ptr != IntPtr.Zero)
                        BeginDebugMarker = (BeginDebugMarkerDelegate)Marshal.GetDelegateForFunctionPointer(ptr, typeof(BeginDebugMarkerDelegate));

                    var endDebugMarkerName = System.Text.Encoding.ASCII.GetBytes("vkCmdDebugMarkerEndEXT");
                    ptr = NativeInstance.GetProcAddress((byte*)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(applicationInfo.EngineName);
                Marshal.FreeHGlobal(createDebugReportCallbackName);
            }
        }
        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);
            }
        }