public unsafe GraphicsAdapterFactoryInstance(bool enableValidation)
        {
            var applicationInfo = new VkApplicationInfo
            {
                sType       = VkStructureType.ApplicationInfo,
                apiVersion  = new VkVersion(1, 0, 0),
                pEngineName = (byte *)Marshal.StringToHGlobalAnsi("Stride"),
                //engineVersion = new VkVersion()
            };

            var validationLayerNames = new[]
            {
                "VK_LAYER_KHRONOS_validation",
            };

            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 = validationLayerNames
                                    .Where(x => availableLayerNames.Contains(x))
                                    .Select(Marshal.StringToHGlobalAnsi).ToArray();

                // Check if validation was really available
                enableValidation = enabledLayerNames.Length > 0;
            }

            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(KHRSurfaceExtensionName);
            if (!availableExtensionNames.Contains(KHRSurfaceExtensionName))
            {
                throw new InvalidOperationException($"Required extension {KHRSurfaceExtensionName} is not available");
            }

            if (Platform.Type == PlatformType.Windows)
            {
                desiredExtensionNames.Add(KHRWin32SurfaceExtensionName);
                if (!availableExtensionNames.Contains(KHRWin32SurfaceExtensionName))
                {
                    throw new InvalidOperationException($"Required extension {KHRWin32SurfaceExtensionName} is not available");
                }
            }
            else if (Platform.Type == PlatformType.Android)
            {
                desiredExtensionNames.Add(KHRAndroidSurfaceExtensionName);
                if (!availableExtensionNames.Contains(KHRAndroidSurfaceExtensionName))
                {
                    throw new InvalidOperationException($"Required extension {KHRAndroidSurfaceExtensionName} is not available");
                }
            }
            else if (Platform.Type == PlatformType.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");
                }
            }

            bool enableDebugReport = enableValidation && availableExtensionNames.Contains(EXTDebugUtilsExtensionName);

            if (enableDebugReport)
            {
                desiredExtensionNames.Add(EXTDebugUtilsExtensionName);
            }

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

            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);
                }

                // Check if validation layer was available (otherwise detected count is 0)
                if (enableValidation)
                {
                    debugReport = DebugReport;
                    var createInfo = new VkDebugUtilsMessengerCreateInfoEXT
                    {
                        sType           = VkStructureType.DebugUtilsMessengerCreateInfoEXT,
                        messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Verbose | VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning,
                        messageType     = VkDebugUtilsMessageTypeFlagsEXT.General | VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance,
                        pfnUserCallback = Marshal.GetFunctionPointerForDelegate(debugReport)
                    };

                    vkCreateDebugUtilsMessengerEXT(NativeInstance, &createInfo, null, out debugReportCallback).CheckResult();
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }

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

                Marshal.FreeHGlobal((IntPtr)applicationInfo.pEngineName);
            }
        }
示例#2
0
        public GraphicsDevice(string applicationName, bool enableValidation, Window window)
        {
            VkString name    = applicationName;
            var      appInfo = new VkApplicationInfo
            {
                sType              = VkStructureType.ApplicationInfo,
                pApplicationName   = name,
                applicationVersion = new VkVersion(1, 0, 0),
                pEngineName        = s_EngineName,
                engineVersion      = new VkVersion(1, 0, 0),
                apiVersion         = vkEnumerateInstanceVersion()
            };

            var instanceExtensions = new List <string>
            {
                KHRSurfaceExtensionName
            };

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                instanceExtensions.Add(KHRWin32SurfaceExtensionName);
            }

            var instanceLayers = new List <string>();

            if (enableValidation)
            {
                FindValidationLayers(instanceLayers);
            }

            if (instanceLayers.Count > 0)
            {
                instanceExtensions.Add(EXTDebugUtilsExtensionName);
            }

            using var vkInstanceExtensions = new VkStringArray(instanceExtensions);

            var instanceCreateInfo = new VkInstanceCreateInfo
            {
                sType                   = VkStructureType.InstanceCreateInfo,
                pApplicationInfo        = &appInfo,
                enabledExtensionCount   = vkInstanceExtensions.Length,
                ppEnabledExtensionNames = vkInstanceExtensions
            };

            using var vkLayerNames = new VkStringArray(instanceLayers);
            if (instanceLayers.Count > 0)
            {
                instanceCreateInfo.enabledLayerCount   = vkLayerNames.Length;
                instanceCreateInfo.ppEnabledLayerNames = vkLayerNames;
            }

            var debugUtilsCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT
            {
                sType = VkStructureType.DebugUtilsMessengerCreateInfoEXT
            };

            if (instanceLayers.Count > 0)
            {
                _debugMessengerCallbackFunc          = DebugMessengerCallback;
                debugUtilsCreateInfo.messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning;
                debugUtilsCreateInfo.messageType     = VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance;
                debugUtilsCreateInfo.pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc);

                instanceCreateInfo.pNext = &debugUtilsCreateInfo;
            }

            VkResult result = vkCreateInstance(&instanceCreateInfo, null, out VkInstance);

            if (result != VkResult.Success)
            {
                throw new InvalidOperationException($"Failed to create vulkan instance: {result}");
            }

            vkLoadInstance(VkInstance);

            if (instanceLayers.Count > 0)
            {
                vkCreateDebugUtilsMessengerEXT(VkInstance, &debugUtilsCreateInfo, null, out _debugMessenger).CheckResult();
            }

            Log.Info($"Created VkInstance with version: {appInfo.apiVersion.Major}.{appInfo.apiVersion.Minor}.{appInfo.apiVersion.Patch}");
            if (instanceLayers.Count > 0)
            {
                foreach (var layer in instanceLayers)
                {
                    Log.Info($"Instance layer '{layer}'");
                }
            }

            foreach (var extension in instanceExtensions)
            {
                Log.Info($"Instance extension '{extension}'");
            }

            _surface = CreateSurface(window);

            // Find physical device, setup queue's and create device.
            var physicalDevices = vkEnumeratePhysicalDevices(VkInstance);

            foreach (var physicalDevice in physicalDevices)
            {
                vkGetPhysicalDeviceProperties(physicalDevice, out var properties);
                var deviceName = properties.GetDeviceName();
            }

            PhysicalDevice = physicalDevices[0];

            var queueFamilies = FindQueueFamilies(PhysicalDevice, _surface);

            var priority        = 1.0f;
            var queueCreateInfo = new VkDeviceQueueCreateInfo
            {
                sType            = VkStructureType.DeviceQueueCreateInfo,
                queueFamilyIndex = queueFamilies.graphicsFamily,
                queueCount       = 1,
                pQueuePriorities = &priority
            };

            List <string> deviceExtensions = new List <string>
            {
                KHRSwapchainExtensionName
            };
            var deviceCreateInfo = new VkDeviceCreateInfo
            {
                sType                = VkStructureType.DeviceCreateInfo,
                pQueueCreateInfos    = &queueCreateInfo,
                queueCreateInfoCount = 1,
                pEnabledFeatures     = null,
            };

            using var deviceExtensionNames           = new VkStringArray(deviceExtensions);
            deviceCreateInfo.enabledExtensionCount   = deviceExtensionNames.Length;
            deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;

            result = vkCreateDevice(PhysicalDevice, &deviceCreateInfo, null, out VkDevice);
            if (result != VkResult.Success)
            {
                throw new Exception($"Failed to create Vulkan Logical Device, {result}");
            }

            vkGetDeviceQueue(VkDevice, queueFamilies.graphicsFamily, 0, out GraphicsQueue);
            vkGetDeviceQueue(VkDevice, queueFamilies.presentFamily, 0, out PresentQueue);

            // Create swap chain
            Swapchain = new Swapchain(this, window);
            _perFrame = new PerFrame[Swapchain.ImageCount];
            for (var i = 0; i < _perFrame.Length; i++)
            {
                VkFenceCreateInfo fenceCreateInfo = new VkFenceCreateInfo(VkFenceCreateFlags.Signaled);
                vkCreateFence(VkDevice, &fenceCreateInfo, null, out _perFrame[i].QueueSubmitFence).CheckResult();

                VkCommandPoolCreateInfo poolCreateInfo = new VkCommandPoolCreateInfo
                {
                    sType            = VkStructureType.CommandPoolCreateInfo,
                    flags            = VkCommandPoolCreateFlags.Transient,
                    queueFamilyIndex = queueFamilies.graphicsFamily,
                };
                vkCreateCommandPool(VkDevice, &poolCreateInfo, null, out _perFrame[i].PrimaryCommandPool).CheckResult();

                VkCommandBufferAllocateInfo commandBufferInfo = new VkCommandBufferAllocateInfo
                {
                    sType              = VkStructureType.CommandBufferAllocateInfo,
                    commandPool        = _perFrame[i].PrimaryCommandPool,
                    level              = VkCommandBufferLevel.Primary,
                    commandBufferCount = 1
                };
                vkAllocateCommandBuffers(VkDevice, &commandBufferInfo, out _perFrame[i].PrimaryCommandBuffer).CheckResult();
            }
        }
示例#3
0
            protected override void Initialize()
            {
                var result = vkInitialize();

                result.CheckResult();

                var version         = vkEnumerateInstanceVersion();
                var queryExtensions = vkEnumerateInstanceExtensionProperties();
                var queryLayers     = vkEnumerateInstanceLayerProperties();

                VkString name    = "01-ClearScreen";
                var      appInfo = new VkApplicationInfo
                {
                    sType              = VkStructureType.ApplicationInfo,
                    pApplicationName   = name,
                    applicationVersion = new VkVersion(1, 0, 0),
                    pEngineName        = s_EngineName,
                    engineVersion      = new VkVersion(1, 0, 0),
                    apiVersion         = VkVersion.Version_1_0,
                };

                var instanceExtensions = new List <string>
                {
                    KHRSurfaceExtensionName,
                    KHRWin32SurfaceExtensionName
                };

                var instanceLayers = new List <string>();

                if (EnableValidationLayers)
                {
                    FindValidationLayers(instanceLayers);
                }

                if (instanceLayers.Count > 0)
                {
                    instanceExtensions.Add(EXTDebugUtilsExtensionName);
                }

                using var vkInstanceExtensions = new VkStringArray(instanceExtensions);
                var instanceCreateInfo = new VkInstanceCreateInfo
                {
                    sType                   = VkStructureType.InstanceCreateInfo,
                    pApplicationInfo        = &appInfo,
                    enabledExtensionCount   = vkInstanceExtensions.Length,
                    ppEnabledExtensionNames = vkInstanceExtensions
                };

                using var vkLayerNames = new VkStringArray(instanceLayers);
                if (instanceLayers.Count > 0)
                {
                    instanceCreateInfo.enabledLayerCount   = vkLayerNames.Length;
                    instanceCreateInfo.ppEnabledLayerNames = vkLayerNames;
                }

                result = vkCreateInstance(&instanceCreateInfo, null, out instance);
                vkLoadInstance(instance);

                if (instanceLayers.Count > 0)
                {
                    _debugMessengerCallbackFunc = DebugMessengerCallback;
                    var debugCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT
                    {
                        sType           = VkStructureType.DebugUtilsMessengerCreateInfoEXT,
                        messageSeverity = /*VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT | */ VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT | VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT,
                        messageType     = VkDebugUtilsMessageTypeFlagsEXT.GeneralEXT | VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT | VkDebugUtilsMessageTypeFlagsEXT.PerformanceEXT,
                        pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc)
                    };

                    vkCreateDebugUtilsMessengerEXT(instance, &debugCreateInfo, null, out debugMessenger).CheckResult();
                }

                var surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR
                {
                    sType     = VkStructureType.Win32SurfaceCreateInfoKHR,
                    hinstance = HInstance,
                    hwnd      = MainWindow.Handle
                };

                result = vkCreateWin32SurfaceKHR(instance, &surfaceCreateInfo, null, out surface);

                var physicalDevices = vkEnumeratePhysicalDevices(instance);

                foreach (var physicalDevice in physicalDevices)
                {
                    vkGetPhysicalDeviceProperties(physicalDevice, out var properties);
                    var deviceName = properties.GetDeviceName();
                }

                physicalDevice = physicalDevices[0];

                var queueFamilies = FindQueueFamilies(physicalDevice, surface);

                var priority        = 1.0f;
                var queueCreateInfo = new VkDeviceQueueCreateInfo
                {
                    sType            = VkStructureType.DeviceQueueCreateInfo,
                    queueFamilyIndex = queueFamilies.graphicsFamily,
                    queueCount       = 1,
                    pQueuePriorities = &priority
                };

                List <string> deviceExtensions = new List <string>
                {
                    KHRSwapchainExtensionName
                };
                var deviceCreateInfo = new VkDeviceCreateInfo
                {
                    sType                = VkStructureType.DeviceCreateInfo,
                    pQueueCreateInfos    = &queueCreateInfo,
                    queueCreateInfoCount = 1,
                    pEnabledFeatures     = null,
                };

                using var deviceExtensionNames           = new VkStringArray(deviceExtensions);
                deviceCreateInfo.enabledExtensionCount   = deviceExtensionNames.Length;
                deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;

                result = vkCreateDevice(physicalDevice, &deviceCreateInfo, null, out device);
                if (result != VkResult.Success)
                {
                    throw new Exception($"Failed to create Vulkan Logical Device, {result}");
                }

                vkGetDeviceQueue(device, queueFamilies.graphicsFamily, 0, out graphicsQueue);
                vkGetDeviceQueue(device, queueFamilies.presentFamily, 0, out presentQueue);

                CreateSwapchain();
                CreateSyncPrimitives();
            }
示例#4
0
        private VkInstance CreateInstance(bool debug)
        {
            VkInstance instance;

            // Specify standard validation layers.
            string surfaceExtension;

            switch (Host.Platform)
            {
            case Platform.Android:
                surfaceExtension = KHRAndroidSurfaceExtensionName;
                break;

            case Platform.Win32:
                surfaceExtension = KHRWin32SurfaceExtensionName;
                break;

            default:
                throw new NotImplementedException();
            }

            VkString name    = "TODO Application Name";
            var      appInfo = new VkApplicationInfo
            {
                sType              = VkStructureType.ApplicationInfo,
                pApplicationName   = name,
                applicationVersion = new VkVersion(1, 0, 0),
                pEngineName        = s_EngineName,
                engineVersion      = new VkVersion(1, 0, 0),
                apiVersion         = VkVersion.Version_1_0,
            };

            var instanceExtensions = new List <string>
            {
                KHRSurfaceExtensionName,
                surfaceExtension
            };

            var instanceLayers = new List <string>();

            if (EnableValidationLayers)
            {
                FindValidationLayers(instanceLayers);
            }

            if (instanceLayers.Count > 0)
            {
                instanceExtensions.Add(EXTDebugUtilsExtensionName);
            }

            using var vkInstanceExtensions = new VkStringArray(instanceExtensions);
            var instanceCreateInfo = new VkInstanceCreateInfo
            {
                sType                   = VkStructureType.InstanceCreateInfo,
                pApplicationInfo        = &appInfo,
                enabledExtensionCount   = vkInstanceExtensions.Length,
                ppEnabledExtensionNames = vkInstanceExtensions
            };


            using var vkLayerNames = new VkStringArray(instanceLayers);
            if (instanceLayers.Count > 0)
            {
                instanceCreateInfo.enabledLayerCount   = vkLayerNames.Length;
                instanceCreateInfo.ppEnabledLayerNames = vkLayerNames;
            }

            VkResult result = vkCreateInstance(&instanceCreateInfo, null, out instance);

            vkLoadInstance(instance);

            if (instanceLayers.Count > 0)
            {
                _debugMessengerCallbackFunc = DebugMessengerCallback;
                var debugCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT
                {
                    sType           = VkStructureType.DebugUtilsMessengerCreateInfoEXT,
                    messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Verbose | VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning,
                    messageType     = VkDebugUtilsMessageTypeFlagsEXT.General | VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance,
                    pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc)
                };

                vkCreateDebugUtilsMessengerEXT(instance, &debugCreateInfo, null, out debugMessenger).CheckResult();
            }

            return(instance);
        }