示例#1
0
        public static Device CreateDevice(Vk api, PhysicalDevice physicalDevice, uint queueFamilyIndex, string[] supportedExtensions, uint queueCount)
        {
            if (queueCount > QueuesCount)
            {
                queueCount = QueuesCount;
            }

            float *queuePriorities = stackalloc float[(int)queueCount];

            for (int i = 0; i < queueCount; i++)
            {
                queuePriorities[i] = 1f;
            }

            var queueCreateInfo = new DeviceQueueCreateInfo()
            {
                SType            = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = queueFamilyIndex,
                QueueCount       = queueCount,
                PQueuePriorities = queuePriorities
            };

            var features = new PhysicalDeviceFeatures()
            {
                DepthBiasClamp           = true,
                DepthClamp               = true,
                DualSrcBlend             = true,
                FragmentStoresAndAtomics = true,
                GeometryShader           = true,
                ImageCubeArray           = true,
                IndependentBlend         = true,
                LogicOp                   = true,
                MultiViewport             = true,
                PipelineStatisticsQuery   = true,
                SamplerAnisotropy         = true,
                ShaderClipDistance        = true,
                ShaderImageGatherExtended = true,
                // ShaderStorageImageReadWithoutFormat = true,
                // ShaderStorageImageWriteWithoutFormat = true,
                VertexPipelineStoresAndAtomics = true
            };

            var featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT()
            {
                SType          = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt,
                IndexTypeUint8 = supportedExtensions.Contains("VK_EXT_index_type_uint8")
            };

            var featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
            {
                SType             = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
                PNext             = &featuresIndexU8,
                TransformFeedback = true
            };

            var featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
            {
                SType          = StructureType.PhysicalDeviceRobustness2FeaturesExt,
                PNext          = &featuresTransformFeedback,
                NullDescriptor = true
            };

            var featuresVk12 = new PhysicalDeviceVulkan12Features()
            {
                SType             = StructureType.PhysicalDeviceVulkan12Features,
                PNext             = &featuresRobustness2,
                DrawIndirectCount = supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName)
            };

            var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray();

            IntPtr *ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];

            for (int i = 0; i < enabledExtensions.Length; i++)
            {
                ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
            }

            var deviceCreateInfo = new DeviceCreateInfo()
            {
                SType = StructureType.DeviceCreateInfo,
                PNext = &featuresVk12,
                QueueCreateInfoCount    = 1,
                PQueueCreateInfos       = &queueCreateInfo,
                PpEnabledExtensionNames = (byte **)ppEnabledExtensions,
                EnabledExtensionCount   = (uint)enabledExtensions.Length,
                PEnabledFeatures        = &features
            };

            api.CreateDevice(physicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();

            for (int i = 0; i < enabledExtensions.Length; i++)
            {
                Marshal.FreeHGlobal(ppEnabledExtensions[i]);
            }

            return(device);
        }
示例#2
0
        private unsafe void LoadFeatures(string[] supportedExtensions, uint maxQueueCount, uint queueFamilyIndex)
        {
            FormatCapabilities = new FormatCapabilities(Api, _physicalDevice);

            var supportedFeatures = Api.GetPhysicalDeviceFeature(_physicalDevice);

            if (Api.TryGetDeviceExtension(_instance, _device, out ExtConditionalRendering conditionalRenderingApi))
            {
                ConditionalRenderingApi = conditionalRenderingApi;
            }

            if (Api.TryGetDeviceExtension(_instance, _device, out ExtExtendedDynamicState extendedDynamicStateApi))
            {
                ExtendedDynamicStateApi = extendedDynamicStateApi;
            }

            if (Api.TryGetDeviceExtension(_instance, _device, out KhrPushDescriptor pushDescriptorApi))
            {
                PushDescriptorApi = pushDescriptorApi;
            }

            if (Api.TryGetDeviceExtension(_instance, _device, out ExtTransformFeedback transformFeedbackApi))
            {
                TransformFeedbackApi = transformFeedbackApi;
            }

            if (Api.TryGetDeviceExtension(_instance, _device, out KhrDrawIndirectCount drawIndirectCountApi))
            {
                DrawIndirectCountApi = drawIndirectCountApi;
            }

            if (maxQueueCount >= 2)
            {
                Api.GetDeviceQueue(_device, queueFamilyIndex, 1, out var backgroundQueue);
                BackgroundQueue     = backgroundQueue;
                BackgroundQueueLock = new object();
            }

            PhysicalDeviceProperties2 properties2 = new PhysicalDeviceProperties2()
            {
                SType = StructureType.PhysicalDeviceProperties2
            };

            PhysicalDeviceSubgroupSizeControlPropertiesEXT propertiesSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlPropertiesEXT()
            {
                SType = StructureType.PhysicalDeviceSubgroupSizeControlPropertiesExt
            };

            if (Capabilities.SupportsSubgroupSizeControl)
            {
                properties2.PNext = &propertiesSubgroupSizeControl;
            }

            bool supportsTransformFeedback = supportedExtensions.Contains(ExtTransformFeedback.ExtensionName);

            PhysicalDeviceTransformFeedbackPropertiesEXT propertiesTransformFeedback = new PhysicalDeviceTransformFeedbackPropertiesEXT()
            {
                SType = StructureType.PhysicalDeviceTransformFeedbackPropertiesExt
            };

            if (supportsTransformFeedback)
            {
                propertiesTransformFeedback.PNext = properties2.PNext;
                properties2.PNext = &propertiesTransformFeedback;
            }

            Api.GetPhysicalDeviceProperties2(_physicalDevice, &properties2);

            PhysicalDeviceFeatures2 features2 = new PhysicalDeviceFeatures2()
            {
                SType = StructureType.PhysicalDeviceFeatures2
            };

            PhysicalDeviceRobustness2FeaturesEXT featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
            {
                SType = StructureType.PhysicalDeviceRobustness2FeaturesExt
            };

            if (supportedExtensions.Contains("VK_EXT_robustness2"))
            {
                features2.PNext = &featuresRobustness2;
            }

            Api.GetPhysicalDeviceFeatures2(_physicalDevice, &features2);

            Capabilities = new HardwareCapabilities(
                supportedExtensions.Contains("VK_EXT_index_type_uint8"),
                supportedExtensions.Contains("VK_EXT_custom_border_color"),
                supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName),
                supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"),
                supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"),
                supportedExtensions.Contains("VK_EXT_subgroup_size_control"),
                supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
                supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
                features2.Features.MultiViewport,
                featuresRobustness2.NullDescriptor,
                supportedExtensions.Contains(KhrPushDescriptor.ExtensionName),
                supportsTransformFeedback,
                propertiesTransformFeedback.TransformFeedbackQueries,
                supportedFeatures.GeometryShader,
                propertiesSubgroupSizeControl.MinSubgroupSize,
                propertiesSubgroupSizeControl.MaxSubgroupSize,
                propertiesSubgroupSizeControl.RequiredSubgroupSizeStages);

            ref var properties = ref properties2.Properties;
示例#3
0
        public static Device CreateDevice(Vk api, PhysicalDevice physicalDevice, uint queueFamilyIndex, string[] supportedExtensions, uint queueCount)
        {
            if (queueCount > QueuesCount)
            {
                queueCount = QueuesCount;
            }

            float *queuePriorities = stackalloc float[(int)queueCount];

            for (int i = 0; i < queueCount; i++)
            {
                queuePriorities[i] = 1f;
            }

            var queueCreateInfo = new DeviceQueueCreateInfo()
            {
                SType            = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = queueFamilyIndex,
                QueueCount       = queueCount,
                PQueuePriorities = queuePriorities
            };

            api.GetPhysicalDeviceProperties(physicalDevice, out var properties);
            bool useRobustBufferAccess = VendorUtils.FromId(properties.VendorID) == Vendor.Nvidia;

            var supportedFeatures = api.GetPhysicalDeviceFeature(physicalDevice);

            var features = new PhysicalDeviceFeatures()
            {
                DepthBiasClamp           = true,
                DepthClamp               = true,
                DualSrcBlend             = true,
                FragmentStoresAndAtomics = true,
                GeometryShader           = true,
                ImageCubeArray           = true,
                IndependentBlend         = true,
                LogicOp                   = true,
                MultiViewport             = true,
                PipelineStatisticsQuery   = true,
                SamplerAnisotropy         = true,
                ShaderClipDistance        = true,
                ShaderFloat64             = supportedFeatures.ShaderFloat64,
                ShaderImageGatherExtended = true,
                // ShaderStorageImageReadWithoutFormat = true,
                // ShaderStorageImageWriteWithoutFormat = true,
                TessellationShader             = true,
                VertexPipelineStoresAndAtomics = true,
                RobustBufferAccess             = useRobustBufferAccess
            };

            void *pExtendedFeatures = null;

            var featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
            {
                SType             = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
                PNext             = pExtendedFeatures,
                TransformFeedback = true
            };

            pExtendedFeatures = &featuresTransformFeedback;

            var featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
            {
                SType          = StructureType.PhysicalDeviceRobustness2FeaturesExt,
                PNext          = pExtendedFeatures,
                NullDescriptor = true
            };

            pExtendedFeatures = &featuresRobustness2;

            var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT()
            {
                SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt,
                PNext = pExtendedFeatures,
                ExtendedDynamicState = supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName)
            };

            pExtendedFeatures = &featuresExtendedDynamicState;

            var featuresVk11 = new PhysicalDeviceVulkan11Features()
            {
                SType = StructureType.PhysicalDeviceVulkan11Features,
                PNext = pExtendedFeatures,
                ShaderDrawParameters = true
            };

            pExtendedFeatures = &featuresVk11;

            var featuresVk12 = new PhysicalDeviceVulkan12Features()
            {
                SType = StructureType.PhysicalDeviceVulkan12Features,
                PNext = pExtendedFeatures,
                DescriptorIndexing = supportedExtensions.Contains("VK_EXT_descriptor_indexing"),
                DrawIndirectCount  = supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName)
            };

            pExtendedFeatures = &featuresVk12;

            PhysicalDeviceIndexTypeUint8FeaturesEXT featuresIndexU8;

            if (supportedExtensions.Contains("VK_EXT_index_type_uint8"))
            {
                featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT()
                {
                    SType          = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt,
                    PNext          = pExtendedFeatures,
                    IndexTypeUint8 = true
                };

                pExtendedFeatures = &featuresIndexU8;
            }

            PhysicalDeviceFragmentShaderInterlockFeaturesEXT featuresFragmentShaderInterlock;

            if (supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"))
            {
                featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT()
                {
                    SType = StructureType.PhysicalDeviceFragmentShaderInterlockFeaturesExt,
                    PNext = pExtendedFeatures,
                    FragmentShaderPixelInterlock = true
                };

                pExtendedFeatures = &featuresFragmentShaderInterlock;
            }

            PhysicalDeviceSubgroupSizeControlFeaturesEXT featuresSubgroupSizeControl;

            if (supportedExtensions.Contains("VK_EXT_subgroup_size_control"))
            {
                featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT()
                {
                    SType = StructureType.PhysicalDeviceSubgroupSizeControlFeaturesExt,
                    PNext = pExtendedFeatures,
                    SubgroupSizeControl = true
                };

                pExtendedFeatures = &featuresSubgroupSizeControl;
            }

            var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray();

            IntPtr *ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];

            for (int i = 0; i < enabledExtensions.Length; i++)
            {
                ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
            }

            var deviceCreateInfo = new DeviceCreateInfo()
            {
                SType = StructureType.DeviceCreateInfo,
                PNext = pExtendedFeatures,
                QueueCreateInfoCount    = 1,
                PQueueCreateInfos       = &queueCreateInfo,
                PpEnabledExtensionNames = (byte **)ppEnabledExtensions,
                EnabledExtensionCount   = (uint)enabledExtensions.Length,
                PEnabledFeatures        = &features
            };

            api.CreateDevice(physicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();

            for (int i = 0; i < enabledExtensions.Length; i++)
            {
                Marshal.FreeHGlobal(ppEnabledExtensions[i]);
            }

            return(device);
        }