Пример #1
0
        private unsafe VkResult CreateDebugReportCallback(
            VkDebugReportFlagsEXT flags
            )
        {
            _debugCallbackFunction = DebugCallback;
            var debugFunctionPtr  = Marshal.GetFunctionPointerForDelegate(_debugCallbackFunction);
            var debugCallbackInfo = new VkDebugReportCallbackCreateInfoEXT
            {
                sType       = VkStructureType.DebugReportCallbackCreateInfoEXT,
                flags       = flags,
                pfnCallback = debugFunctionPtr
            };

            var createFunctionPtr = VulkanNative.vkGetInstanceProcAddr(
                _handle,
                new FixedUtf8String("vkCreateDebugReportCallbackEXT")
                );

            if (createFunctionPtr == IntPtr.Zero)
            {
                return(VkResult.ErrorValidationFailedEXT);
            }

            var createDelegate = Marshal.GetDelegateForFunctionPointer <vkCreateDebugReportCallbackEXT_d>(
                createFunctionPtr
                );

            return(createDelegate(
                       _handle,
                       &debugCallbackInfo,
                       IntPtr.Zero,
                       out _debugCallbackHandle
                       ));
        }
Пример #2
0
        private void EnableDebugCallback(VkDebugReportFlagBitsEXT flags = VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_ERROR_BIT_EXT | VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_WARNING_BIT_EXT | VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_DEBUG_BIT_EXT)
        {
            Debug.WriteLine("Enabling Vulkan Debug callbacks.");

            this.debugCallbackFunc = this.DebugCallback;
            IntPtr debugFunctionPtr = Marshal.GetFunctionPointerForDelegate(this.debugCallbackFunc);

            VkDebugReportCallbackCreateInfoEXT debugCallbackCI = new VkDebugReportCallbackCreateInfoEXT();

            debugCallbackCI.sType       = VkStructureType.VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
            debugCallbackCI.flags       = flags;
            debugCallbackCI.pfnCallback = debugFunctionPtr;

            var createFnPtr = VulkanNative.vkGetInstanceProcAddr(this.vkInstance, "vkCreateDebugReportCallbackEXT".ToPointer());

            if (createFnPtr == IntPtr.Zero)
            {
                return;
            }

            vkCreateDebugReportCallbackEXT_d createDelegate = Marshal.GetDelegateForFunctionPointer <vkCreateDebugReportCallbackEXT_d>(createFnPtr);
            VkResult result = createDelegate(this.vkInstance, &debugCallbackCI, IntPtr.Zero, out this.debugCallbackHandle);

            Helpers.CheckErrors(result);
        }
Пример #3
0
        public DebugReport(Instance instance, VkDebugReportFlagsEXT flags = VkDebugReportFlagsEXT.ErrorEXT | VkDebugReportFlagsEXT.WarningEXT)
        {
            inst = instance;

            VkDebugReportCallbackCreateInfoEXT dbgInfo = new VkDebugReportCallbackCreateInfoEXT {
                sType       = VkStructureType.DebugReportCallbackCreateInfoEXT,
                flags       = flags,
                pfnCallback = Marshal.GetFunctionPointerForDelegate(debugCallbackDelegate)
            };

            Utils.CheckResult(vkCreateDebugReportCallbackEXT(inst.Handle, ref dbgInfo, IntPtr.Zero, out handle));
        }
Пример #4
0
        private void SetupDebugCallback()
        {
            if (!EnableValidationLayers)
            {
                return;
            }
            var createInfo = new VkDebugReportCallbackCreateInfoEXT
            {
                Flags    = VkDebugReportFlagsEXT.Error | VkDebugReportFlagsEXT.Warning,
                Callback = DebugCallback
            };

            callback = instance.CreateDebugReportCallbackEXT(createInfo, null).Object;
        }
Пример #5
0
        public void EnableDebugCallback(VkDebugReportFlagsEXT flags = VkDebugReportFlagsEXT.WarningEXT | VkDebugReportFlagsEXT.ErrorEXT)
        {
            _debugCallbackFunc = DebugCallback;
            IntPtr debugFunctionPtr = Marshal.GetFunctionPointerForDelegate(_debugCallbackFunc);
            VkDebugReportCallbackCreateInfoEXT debugCallbackCI = VkDebugReportCallbackCreateInfoEXT.New();

            debugCallbackCI.flags       = flags;
            debugCallbackCI.pfnCallback = debugFunctionPtr;
            FixedUtf8String debugExtFnName = "vkCreateDebugReportCallbackEXT";
            IntPtr          createFnPtr    = vkGetInstanceProcAddr(_instance, debugExtFnName);
            vkCreateDebugReportCallbackEXT_d createDelegate = Marshal.GetDelegateForFunctionPointer <vkCreateDebugReportCallbackEXT_d>(createFnPtr);

            createDelegate(_instance, &debugCallbackCI, IntPtr.Zero, out _debugCallbackHandle);
        }
Пример #6
0
        private void setupDebugCallback()
        {
            if (!enableValidationLayers)
            {
                return;
            }

            VkDebugReportCallbackCreateInfoEXT createInfo = new VkDebugReportCallbackCreateInfoEXT();

            createInfo.sType       = VkStructureType.VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
            createInfo.flags       = VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_ERROR_BIT_EXT | VkDebugReportFlagBitsEXT.VK_DEBUG_REPORT_WARNING_BIT_EXT;
            createInfo.pfnCallback = debugCallback;

            if (Vulkan.vkCreateDebugReportCallbackEXT(instance, createInfo, null, out callback) != VkResult.VK_SUCCESS)
            {
                throw Program.Throw("failed to set up debug callback!");
            }
        }
Пример #7
0
        public void EnableDebugCallback(VkDebugReportFlagsEXT flags = VkDebugReportFlagsEXT.WarningEXT | VkDebugReportFlagsEXT.ErrorEXT)
        {
            Debug.WriteLine("Enabling Vulkan Debug callbacks.");
            _debugCallbackFunc = DebugCallback;
            IntPtr debugFunctionPtr = Marshal.GetFunctionPointerForDelegate(_debugCallbackFunc);
            VkDebugReportCallbackCreateInfoEXT debugCallbackCI = VkDebugReportCallbackCreateInfoEXT.New();

            debugCallbackCI.flags       = flags;
            debugCallbackCI.pfnCallback = debugFunctionPtr;
            IntPtr createFnPtr;

            using (FixedUtf8String debugExtFnName = "vkCreateDebugReportCallbackEXT")
            {
                createFnPtr = vkGetInstanceProcAddr(_instance, debugExtFnName);
            }
            vkCreateDebugReportCallbackEXT_d createDelegate = Marshal.GetDelegateForFunctionPointer <vkCreateDebugReportCallbackEXT_d>(createFnPtr);
            VkResult result = createDelegate(_instance, &debugCallbackCI, IntPtr.Zero, out _debugCallbackHandle);

            CheckResult(result);
        }
Пример #8
0
        internal DebugReportCallbackExt(VkInstance parent, VkDebugReportFlagsEXT flags,
                                        Func <DebugReportCallbackInfo, bool> callback, IntPtr userData = default(IntPtr))
        {
            Parent = parent;

            Func <DebugReportCallbackInfo, bool> createInfoCallback = callback;
            IntPtr callbackHandle = IntPtr.Zero;

            if (createInfoCallback != null)
            {
                _callback = (flags, objectType, @object, location, messageCode, layerPrefix, message, userData)
                            => createInfoCallback(new DebugReportCallbackInfo
                {
                    Flags       = flags,
                    ObjectType  = objectType,
                    Object      = @object,
                    Location    = location,
                    MessageCode = messageCode,
                    LayerPrefix = Utilities.FromPointer(layerPrefix),
                    Message     = Utilities.FromPointer(message),
                    UserData    = userData
                });
                callbackHandle = Marshal.GetFunctionPointerForDelegate(_callback);
            }

            var nativeCreateInfo = new VkDebugReportCallbackCreateInfoEXT
            {
                sType       = VkStructureType.DebugReportCallbackCreateInfoEXT,
                flags       = flags,
                pfnCallback = callbackHandle,
                pUserData   = (void *)userData
            };

            long     handle;
            VkResult result = vkCreateDebugReportCallbackEXT(Parent)(Parent.Handle, &nativeCreateInfo, null, &handle);

            this.handle = (ulong)handle;
        }
Пример #9
0
 public static extern VkResult CreateDebugReportCallbackEXT(
     VkInstance instance,
     ref VkDebugReportCallbackCreateInfoEXT pCreateInfo,
     IntPtr pAllocator,
     out VkDebugReportCallbackEXT pCallback
     );
        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);
            }
        }
Пример #11
0
 public VkResult CreateDebugReportCallback(VkDebugReportCallbackCreateInfoEXT pCreateInfo, out VkDebugReportCallbackEXT pCallback)
 {
     pCallback = new VkDebugReportCallbackEXT(this, pCreateInfo);
     m_ReportCallbacks.Add(pCallback);
     return(VkResult.VK_SUCCESS);
 }
Пример #12
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);
        }
Пример #13
0
        private VkInstance CreateInstance()
        {
            List <GCHandle> handles = new List <GCHandle>();

            bool debug = false;

            string[] debugOnlyLayers = new string[] {
                //"VK_LAYER_GOOGLE_threading",
                //"VK_LAYER_LUNARG_parameter_validation",
                //"VK_LAYER_LUNARG_device_limits", Not Present?
                //"VK_LAYER_LUNARG_object_tracker",
                //"VK_LAYER_LUNARG_image", Not Present?
                "VK_LAYER_LUNARG_core_validation",
                //"VK_LAYER_LUNARG_swapchain",
                //"VK_LAYER_GOOGLE_unique_objects",
            };
            List <string> layerList = new List <string>();

            if (debug)
            {
                layerList.AddRange(debugOnlyLayers);
            }

            string[] layers       = layerList.ToArray();
            byte[][] pDebugLayers = new byte[layers.Length][];


            byte *[] ppDebugLayerArray = new byte *[pDebugLayers.Length];
            if (!debug)
            {
                ppDebugLayerArray = new byte *[1];//this is to give a null ptr to use later
            }
            for (int i = 0; i < pDebugLayers.Length; i++)
            {
                pDebugLayers[i] = Encoding.UTF8.GetBytes(layers[i] + char.MinValue);
                GCHandle handle = GCHandle.Alloc(pDebugLayers[i]);
                handles.Add(handle);
                fixed(byte *p = &(((byte[])handle.Target)[0]))
                {
                    ppDebugLayerArray[i] = p;
                }
            }

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

            requiredExtensions.Add("VK_EXT_debug_report");
            requiredExtensions.AddRange(GLFW.Vulkan.GetRequiredInstanceExtensions());

            string[] extensionNames = requiredExtensions.ToArray();



            byte[][] pExtensionNames = new byte[extensionNames.Length][];

            byte *[] ppExtensionNamesArray = new byte *[extensionNames.Length];

            for (int i = 0; i < pExtensionNames.Length; i++)
            {
                pExtensionNames[i] = Encoding.UTF8.GetBytes(extensionNames[i] + char.MinValue);
                GCHandle handle = GCHandle.Alloc(pExtensionNames[i]);
                handles.Add(handle);
                fixed(byte *p = &(((byte[])handle.Target)[0]))
                {
                    ppExtensionNamesArray[i] = p;
                }
            }
            VkInstance instance = new VkInstance();

            fixed(byte **layersptr = &ppDebugLayerArray[0])
            {
                fixed(byte **extensions = &ppExtensionNamesArray[0])
                {
                    VkInstanceCreateInfo pCreateInfo = VkInstanceCreateInfo.New();

                    pCreateInfo.ppEnabledLayerNames     = layersptr;
                    pCreateInfo.ppEnabledExtensionNames = extensions;
                    pCreateInfo.enabledLayerCount       = (uint)pDebugLayers.Length;
                    pCreateInfo.enabledExtensionCount   = (uint)extensionNames.Length;

                    Assert(vkCreateInstance(&pCreateInfo, null, &instance));
                }
            }

            foreach (var handle in handles)
            {
                handle.Free();
            }

            DebugDelegate debugDelegate = new DebugDelegate(DebugCallback);

            //PFN_vkDebugReportCallbackEXT _debugCallbackFunc =(PFN_vkDebugReportCallbackEXT) debugDelegate;



            IntPtr debugFunctionPtr = Marshal.GetFunctionPointerForDelegate(debugDelegate);

            debugDelegateHandle = GCHandle.Alloc(debugDelegate);

            VkDebugReportCallbackCreateInfoEXT createInfoEXT = VkDebugReportCallbackCreateInfoEXT.New();

            createInfoEXT.pfnCallback = debugFunctionPtr;
            createInfoEXT.flags       = //VkDebugReportFlagsEXT.DebugEXT | VkDebugReportFlagsEXT.ErrorEXT | VkDebugReportFlagsEXT.WarningEXT |
                                        (VkDebugReportFlagsEXT)int.MaxValue;

            byte[] debugExtFnName = Encoding.UTF8.GetBytes("vkCreateDebugReportCallbackEXT" + char.MinValue);



            IntPtr createFnPtr;

            fixed(byte *namePtr = &(debugExtFnName[0]))
            {
                createFnPtr = vkGetInstanceProcAddr(instance, namePtr);
            }

            vkCreateDebugReportCallbackEXT_d createDelegate = Marshal.GetDelegateForFunctionPointer <vkCreateDebugReportCallbackEXT_d>(createFnPtr);



            VkDebugReportCallbackCreateInfoEXT *createInfoPtr = (&createInfoEXT);

            fixed(ulong *ptr = &(debugReport.Handle))
            {
                Assert(createDelegate(instance, createInfoPtr, IntPtr.Zero, out debugReport));
            }

            return(instance);
        }