Beispiel #1
0
        public static VkDevice Create(Settings settings, VkPhysicalDeviceFeatures enabledFeatures, CStringList enabledExtensions,
                                      VkQueueFlags requestedQueueTypes = VkQueueFlags.Graphics | VkQueueFlags.Compute | VkQueueFlags.Transfer)
        {
            instanceExtensions.Add(Vulkan.KHRSurfaceExtensionName);
            instanceExtensions.Add(Vulkan.KHRGetPhysicalDeviceProperties2ExtensionName);

            enabledExtensions.Add(Vulkan.KHRMaintenance1ExtensionName);
            enabledExtensions.Add(Vulkan.EXTInlineUniformBlockExtensionName);

            //enabledExtensions.Add(Strings.VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT);

            CreateInstance(settings);

            // Physical Device
            var physicalDevices = Vulkan.vkEnumeratePhysicalDevices(VkInstance);

            // TODO: Implement arg parsing, etc.
            int selectedDevice = 0;

            PhysicalDevice = physicalDevices[selectedDevice];
            Debug.Assert(PhysicalDevice.Handle != IntPtr.Zero);

            vkGetPhysicalDeviceProperties(PhysicalDevice, out VkPhysicalDeviceProperties properties);
            Properties = properties;

            vkGetPhysicalDeviceFeatures(PhysicalDevice, out VkPhysicalDeviceFeatures features);
            Features = features;

            if (features.tessellationShader)
            {
                enabledFeatures.tessellationShader = true;
            }

            if (features.multiDrawIndirect)
            {
                enabledFeatures.multiDrawIndirect = true;
            }
            // Enable anisotropic filtering if supported
            if (features.samplerAnisotropy)
            {
                enabledFeatures.samplerAnisotropy = true;
            }
            // Enable texture compression
            if (features.textureCompressionBC)
            {
                enabledFeatures.textureCompressionBC = true;
            }
            else if (features.textureCompressionASTC_LDR)
            {
                enabledFeatures.textureCompressionASTC_LDR = true;
            }
            else if (features.textureCompressionETC2)
            {
                enabledFeatures.textureCompressionETC2 = true;
            }

            if (features.sparseBinding && features.sparseResidencyImage2D)
            {
                enabledFeatures.shaderResourceResidency = true;
                enabledFeatures.shaderResourceMinLod    = true;
                enabledFeatures.sparseBinding           = true;
                enabledFeatures.sparseResidencyImage2D  = true;
            }
            else
            {
                Log.Warn("Sparse binding not supported");
            }

            // Memory properties are used regularly for creating all kinds of buffers
            VkPhysicalDeviceMemoryProperties memoryProperties;

            vkGetPhysicalDeviceMemoryProperties(PhysicalDevice, out memoryProperties);
            MemoryProperties = memoryProperties;

            var qf = Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice);

            QueueFamilyProperties.Add(qf);

            var extensions = Vulkan.vkEnumerateDeviceExtensionProperties(PhysicalDevice);

            foreach (var ext in extensions)
            {
                string strExt = UTF8String.FromPointer(ext.extensionName);
                //enabledExtensions.Add((IntPtr)ext.extensionName);
                supportedExtensions.Add(strExt);
            }

            device = CreateLogicalDevice(Features, enabledExtensions, true, requestedQueueTypes);

            if (device != VkDevice.Null)
            {
                VkPipelineCacheCreateInfo pipelineCacheCreateInfo = new VkPipelineCacheCreateInfo()
                {
                    sType = VkStructureType.PipelineCacheCreateInfo
                };

                VulkanUtil.CheckResult(vkCreatePipelineCache(device, &pipelineCacheCreateInfo, null, out pipelineCache));
            }

            return(device);
        }