コード例 #1
0
        private bool IsPhysicalDeviceSuitable(VkPhysicalDevice physicalDevice)
        {
            QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice);

            bool extensionsSupported = this.CheckPhysicalDeviceExtensionSupport(physicalDevice);

            // acquire Raytracing features
            VkPhysicalDeviceRayTracingFeaturesKHR rayTracingFeatures = new VkPhysicalDeviceRayTracingFeaturesKHR()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR,
                pNext = null,
            };

            VkPhysicalDeviceFeatures2 deviceFeatures2 = new VkPhysicalDeviceFeatures2()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
                pNext = &rayTracingFeatures,
            };

            VulkanNative.vkGetPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures2);

            extensionsSupported = extensionsSupported && rayTracingFeatures.rayTracing;

            bool swapChainAdequate = false;

            if (extensionsSupported)
            {
                SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(physicalDevice);
                swapChainAdequate = (swapChainSupport.formats.Length != 0 && swapChainSupport.presentModes.Length != 0);
            }

            return(indices.IsComplete() && extensionsSupported && swapChainAdequate);
        }
コード例 #2
0
ファイル: GraphicsDevice.cs プロジェクト: ab4d/Vortice.Vulkan
        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()
            };

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

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

            List <string> 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 (string 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];
            vkGetPhysicalDeviceProperties(PhysicalDevice, out VkPhysicalDeviceProperties properties);

            var queueFamilies = FindQueueFamilies(PhysicalDevice, _surface);

            var availableDeviceExtensions = vkEnumerateDeviceExtensionProperties(PhysicalDevice);

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

            if (CheckDeviceExtensionSupport(KHRSpirv14ExtensionName, availableDeviceExtensions))
            {
                deviceExtensions.Add(KHRSpirv14ExtensionName);
            }

            if (CheckDeviceExtensionSupport(KHRFragmentShadingRateExtensionName, availableDeviceExtensions))
            {
                deviceExtensions.Add(KHRFragmentShadingRateExtensionName);
            }

            if (CheckDeviceExtensionSupport(NVMeshShaderExtensionName, availableDeviceExtensions))
            {
                deviceExtensions.Add(NVMeshShaderExtensionName);
            }

            VkPhysicalDeviceVulkan11Features features_1_1 = new VkPhysicalDeviceVulkan11Features
            {
                sType = VkStructureType.PhysicalDeviceVulkan11Features
            };

            VkPhysicalDeviceVulkan12Features features_1_2 = new VkPhysicalDeviceVulkan12Features
            {
                sType = VkStructureType.PhysicalDeviceVulkan12Features
            };

            VkPhysicalDeviceFeatures2 deviceFeatures2 = new VkPhysicalDeviceFeatures2
            {
                sType = VkStructureType.PhysicalDeviceFeatures2
            };

            deviceFeatures2.pNext = &features_1_1;
            features_1_1.pNext    = &features_1_2;

            void **features_chain = &features_1_2.pNext;

            VkPhysicalDevice8BitStorageFeatures storage_8bit_features = default;

            if (properties.apiVersion <= VkVersion.Version_1_2)
            {
                if (CheckDeviceExtensionSupport(KHR8bitStorageExtensionName, availableDeviceExtensions))
                {
                    deviceExtensions.Add(KHR8bitStorageExtensionName);
                    storage_8bit_features.sType = VkStructureType.PhysicalDevice8bitStorageFeatures;
                    *features_chain = &storage_8bit_features;
                    features_chain = &storage_8bit_features.pNext;
                }
            }

            VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features = default;

            if (CheckDeviceExtensionSupport(KHRAccelerationStructureExtensionName, availableDeviceExtensions))
            {
                deviceExtensions.Add(KHRAccelerationStructureExtensionName);
                acceleration_structure_features.sType = VkStructureType.PhysicalDeviceAccelerationStructureFeaturesKHR;
                *features_chain = &acceleration_structure_features;
                features_chain = &acceleration_structure_features.pNext;
            }

            vkGetPhysicalDeviceFeatures2(PhysicalDevice, out deviceFeatures2);

            using var deviceExtensionNames = new VkStringArray(deviceExtensions);

            var deviceCreateInfo = new VkDeviceCreateInfo
            {
                sType = VkStructureType.DeviceCreateInfo,
                pNext = &deviceFeatures2,
                queueCreateInfoCount    = 1,
                pQueueCreateInfos       = &queueCreateInfo,
                enabledExtensionCount   = deviceExtensionNames.Length,
                ppEnabledExtensionNames = deviceExtensionNames,
                pEnabledFeatures        = null,
            };

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