internal DebugReportCallbackExt(Instance parent,
                                        ref DebugReportCallbackCreateInfoExt createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            Func <DebugReportCallbackInfo, bool> createInfoCallback = createInfo.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 = Interop.String.FromPointer(layerPrefix),
                    Message     = Interop.String.FromPointer(message),
                    UserData    = userData
                });
                callbackHandle = Interop.GetFunctionPointerForDelegate(_callback);
            }
            createInfo.ToNative(out DebugReportCallbackCreateInfoExt.Native nativeCreateInfo, callbackHandle);

            long   handle;
            Result result = vkCreateDebugReportCallbackEXT(Parent)(Parent, &nativeCreateInfo, NativeAllocator, &handle);

            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
        // Creates a VkInstance
        private void createVulkanInstance(out Vk.Instance instance, out VkExt.DebugReportCallbackExt debugReport)
        {
            var appVersion = Application.AppParameters.Version;
            var engVersion = Assembly.GetExecutingAssembly().GetName().Version;

            // Build the app info
            Vk.ApplicationInfo aInfo = new Vk.ApplicationInfo(
                Application.AppParameters.Name,
                appVersion.ToVkVersion(),
                "Spectrum",
                new Vk.Version(engVersion.Major, engVersion.Minor, engVersion.Revision),
                new Vk.Version(1, 0, 0)
                );

            // Get available instance extensions, and ensure the required ones are present
            var           availExt = Vk.Instance.EnumerateExtensionProperties().Select(ext => ext.ExtensionName).ToArray();
            List <string> reqExt   = new List <string>();

            reqExt.Add(Vk.Constant.InstanceExtension.KhrSurface);
            switch (Platform.OS)
            {
            case PlatformOS.Windows: reqExt.Add(Vk.Constant.InstanceExtension.KhrWin32Surface); break;

            case PlatformOS.Linux: reqExt.Add(Vk.Constant.InstanceExtension.KhrXlibSurface); break;

            case PlatformOS.OSX: reqExt.Add(Vk.Constant.InstanceExtension.MvkMacOSSurface); break;
            }
            {
                var missingExts = reqExt.FindAll(extName => !availExt.Contains(extName));
                if (missingExts.Count > 0)
                {
                    string msg = $"Required Vulkan extensions are missing: {String.Join(", ", missingExts)}";
                    LFATAL(msg);
                    throw new PlatformNotSupportedException(msg);
                }
            }

            // Check for validation layers, if requested
            bool hasDebug = false;

            if (Application.AppParameters.EnableValidationLayers)
            {
                if (availExt.Contains(Vk.Constant.InstanceExtension.ExtDebugReport))
                {
                    var availLay = Vk.Instance.EnumerateLayerProperties().Select(layer => layer.LayerName).ToArray();

                    hasDebug = availLay.Contains("VK_LAYER_KHRONOS_validation");
                    if (hasDebug)
                    {
                        reqExt.Add(Vk.Constant.InstanceExtension.ExtDebugReport);
                    }
                    else
                    {
                        LERROR("Application requested Vulkan validation layers, but the standard layers are not available.");
                    }
                }
                else
                {
                    LERROR("Application requested Vulkan validation layers, but the debug report extension is not available.");
                }
            }

            // Create the instance
            Vk.InstanceCreateInfo iInfo = new Vk.InstanceCreateInfo(
                aInfo,
                hasDebug ? new[] { "VK_LAYER_KHRONOS_validation" } : null,
                reqExt.ToArray(),
                IntPtr.Zero
                );
            instance = new Vk.Instance(iInfo, null);
            LINFO("Created Vulkan instance.");

            // Create the debug callback if needed
            debugReport = null;
            if (hasDebug)
            {
                VkExt.DebugReportCallbackCreateInfoExt dbInfo = new VkExt.DebugReportCallbackCreateInfoExt(
                    (VkExt.DebugReportFlagsExt.PerformanceWarning | VkExt.DebugReportFlagsExt.Warning | VkExt.DebugReportFlagsExt.Error),
                    _DebugReportCallback,
                    IntPtr.Zero
                    );
                debugReport = VkExt.InstanceExtensions.CreateDebugReportCallbackExt(instance, dbInfo, null);
                LINFO("Created Vulkan debug report callback.");
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Create a debug report callback object.
 /// </summary>
 /// <param name="instance">The instance the callback will be logged on.</param>
 /// <param name="createInfo">
 /// The structure which defines the conditions under which this callback will be called.
 /// </param>
 /// <param name="allocator">Controls host memory allocation.</param>
 /// <returns>A <see cref="DebugReportCallbackExt"/> handle.</returns>
 /// <exception cref="InvalidOperationException">Vulkan command not found.</exception>
 /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
 public static DebugReportCallbackExt CreateDebugReportCallbackExt(this Instance instance,
                                                                   DebugReportCallbackCreateInfoExt createInfo, AllocationCallbacks?allocator = null)
 {
     return(new DebugReportCallbackExt(instance, ref createInfo, ref allocator));
 }