public static unsafe ReturnSet <Instance> Create()
        {
            try
            {
                var applicationInfo = new ApplicationInfo
                {
                    StructureType = StructureType.ApplicationInfo,
                    EngineVersion = 0,
                    ApiVersion    = Vulkan.ApiVersion
                };

                var enabledExtensionNames =
                    BuildExtensionArray(ExtensionNames.VK_KHR_surface, ExtensionNames.VK_KHR_win32_surface,
                                        ExtensionNames.VK_EXT_debug_report);

                fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var instanceCreateInfo = new InstanceCreateInfo
                    {
                        StructureType         = StructureType.InstanceCreateInfo,
                        ApplicationInfo       = new IntPtr(&applicationInfo),
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                    };

                    return(new ReturnSet <Instance>(Vulkan.CreateInstance(ref instanceCreateInfo)));
                }
            }
            catch (Exception ex)
            {
                return(new ReturnSet <Instance>(ex));
            }
        }
Example #2
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);
            }
        }
Example #3
0
        protected virtual void CreateInstance()
        {
            var applicationInfo = new ApplicationInfo
            {
                StructureType = StructureType.ApplicationInfo,
                EngineVersion = 0,
                ApiVersion    = Vulkan.ApiVersion
            };

            var enabledLayerNames = new []
            {
                Marshal.StringToHGlobalAnsi("VK_LAYER_LUNARG_standard_validation"),
            };

            var enabledExtensionNames = new []
            {
                Marshal.StringToHGlobalAnsi("VK_KHR_surface"),
                Marshal.StringToHGlobalAnsi("VK_KHR_win32_surface"),
                Marshal.StringToHGlobalAnsi("VK_EXT_debug_report"),
            };

            try
            {
                fixed(void *enabledLayerNamesPointer = &enabledLayerNames[0])
                fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var instanceCreateInfo = new InstanceCreateInfo
                    {
                        StructureType         = StructureType.InstanceCreateInfo,
                        ApplicationInfo       = new IntPtr(&applicationInfo),
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                    };

                    if (validate)
                    {
                        instanceCreateInfo.EnabledLayerCount = (uint)enabledLayerNames.Length;
                        instanceCreateInfo.EnabledLayerNames = new IntPtr(enabledLayerNamesPointer);
                    }

                    instance = Vulkan.CreateInstance(ref instanceCreateInfo);
                }

                if (validate)
                {
                    var createDebugReportCallbackName = Encoding.ASCII.GetBytes("vkCreateDebugReportCallbackEXT");
                    fixed(byte *createDebugReportCallbackNamePointer = &createDebugReportCallbackName[0])
                    {
                        var createDebugReportCallback = Marshal.GetDelegateForFunctionPointer <CreateDebugReportCallbackDelegate>(instance.GetProcAddress(createDebugReportCallbackNamePointer));

                        debugReport = DebugReport;
                        var createInfo = new DebugReportCallbackCreateInfo
                        {
                            StructureType = StructureType.DebugReportCallbackCreateInfo,
                            Flags         = (uint)(DebugReportFlags.Error | DebugReportFlags.Warning | DebugReportFlags.PerformanceWarning),
                            Callback      = Marshal.GetFunctionPointerForDelegate(debugReport)
                        };

                        createDebugReportCallback(instance, ref createInfo, null, out debugReportCallback);
                    }
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }

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

            physicalDevice = instance.PhysicalDevices[0];

            var props = physicalDevice.QueueFamilyProperties;
        }
Example #4
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;
        }
Example #5
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");
            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_EXT_metal_surface");                // 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 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);
            }
        }