Пример #1
0
        public void CreateDevice()
        {
            /*
             * We create the logical device in this function.
             */

            /*
             * When creating the device, we also specify what queues it has.
             */
            // Store memory properties of the physical device.
            PhysicalDeviceMemoryProperties MemoryProperties = physicalDevice.GetMemoryProperties();
            PhysicalDeviceFeatures         Features         = physicalDevice.GetFeatures();
            PhysicalDeviceProperties       Properties       = physicalDevice.GetProperties();

            // Create a logical device.
            var queueCreateInfos = new DeviceQueueCreateInfo[1];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(computeQueueFamilyIndex, 1, 1.0f);

            var deviceCreateInfo = new DeviceCreateInfo(
                queueCreateInfos,
                new[] { Constant.DeviceExtension.NVExternalMemory },
                Features);

            device = physicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            queue = device.GetQueue(computeQueueFamilyIndex);

            // Create command pool(s).
            //commandPool = device.CreateCommandPool(new CommandPoolCreateInfo(computeQueueFamilyIndex));
        }
Пример #2
0
        Device CreateDevice(PhysicalDevice physicalDevice, uint queueFamily)
        {
            // Device objects represent logical connections to physical devices. Each device exposes
            // a number of queue families each having one or more queues. All queues in a queue family
            // support the same operations.
            //
            // As described above, a Vulkan application will first query for all physical
            // devices in a system. Each physical device can then be queried for its capabilities,
            // including its queue and queue family properties. Once an acceptable physical device is
            // identified, an application will create a corresponding logical device. An application
            // must create a separate logical device for each physical device it will use. The created
            // logical device is then the primary interface to the physical device.

            String[] enabledLayers = new string[]
            {
                "VK_LAYER_LUNARG_standard_validation"
            };

            var features = new PhysicalDeviceFeatures();

            features.ShaderClipDistance = true;
            features.ShaderCullDistance = true;

            var queueCreateInfo  = new DeviceQueueCreateInfo(queueFamily, new[] { 0f });
            var deviceCreateInfo = new DeviceCreateInfo(new[] { queueCreateInfo }, enabledLayers, null);

            deviceCreateInfo.EnabledFeatures = features;
            return(physicalDevice.CreateDevice(deviceCreateInfo));
        }
Пример #3
0
        private Device CreateLogicalDevice(out Queue GraphicsQueue, out Queue PresentQueue)
        {
            var   queueInfos    = stackalloc DeviceQueueCreateInfo[2];
            uint  infoCount     = 1;
            float queuePriority = 1f;

            queueInfos[0] = new DeviceQueueCreateInfo(queueFamilyIndex: (uint)this.QueueIndices.GraphicsFamily, queueCount: 1, pQueuePriorities: &queuePriority);

            if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily)
            {
                infoCount = 2;

                queueInfos[1] = new DeviceQueueCreateInfo(queueFamilyIndex: (uint)this.QueueIndices.PresentFamily, queueCount: 1, pQueuePriorities: &queuePriority);
            }

            PhysicalDeviceFeatures features = default;

            using var extensionNames = SilkMarshal.StringArrayToMemory(RequiredDeviceExtensions);

            PhysicalDeviceSeparateDepthStencilLayoutsFeatures depthStencilFeature = new PhysicalDeviceSeparateDepthStencilLayoutsFeatures
            {
                SType = StructureType.PhysicalDeviceSeparateDepthStencilLayoutsFeatures,
                SeparateDepthStencilLayouts = true
            };

            DeviceCreateInfo createInfo = new DeviceCreateInfo
            {
                SType = StructureType.DeviceCreateInfo,
                //PNext = &depthStencilFeature,
                QueueCreateInfoCount    = infoCount,
                PQueueCreateInfos       = queueInfos,
                EnabledExtensionCount   = (uint)RequiredDeviceExtensions.Length,
                PpEnabledExtensionNames = (byte **)extensionNames,
                PEnabledFeatures        = &features
            };

            Device device;
            var    res = VkApi.CreateDevice(this.PhysicalDevice, &createInfo, null, &device);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Logical Device Creation Failed!", res);
            }

            Queue queue = default;

            VkApi.GetDeviceQueue(device, (uint)this.QueueIndices.GraphicsFamily, 0, &queue);

            GraphicsQueue = queue;

            if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily)
            {
                queue = default;
                VkApi.GetDeviceQueue(device, (uint)this.QueueIndices.PresentFamily, 0, &queue);
            }

            PresentQueue = queue;

            return(device);
        }
Пример #4
0
 public static PhysicalDeviceFeaturesNative ToNative(this PhysicalDeviceFeatures features) =>
 new PhysicalDeviceFeaturesNative
 {
     RobustBufferAccess                      = features.RobustBufferAccess,
     FullDrawIndexUint32                     = features.FullDrawIndexUint32,
     ImageCubeArray                          = features.ImageCubeArray,
     IndependentBlend                        = features.IndependentBlend,
     GeometryShader                          = features.GeometryShader,
     TessellationShader                      = features.TessellationShader,
     SampleRateShading                       = features.SampleRateShading,
     DualSourceBlend                         = features.DualSourceBlend,
     LogicOp                                 = features.LogicOp,
     MultiDrawIndirect                       = features.MultiDrawIndirect,
     DrawIndirectFirstInstance               = features.DrawIndirectFirstInstance,
     DepthClamp                              = features.DepthClamp,
     DepthBiasClamp                          = features.DepthBiasClamp,
     FillModeNonSolid                        = features.FillModeNonSolid,
     DepthBounds                             = features.DepthBounds,
     WideLines                               = features.WideLines,
     LargePoints                             = features.LargePoints,
     AlphaToOne                              = features.AlphaToOne,
     MultiViewport                           = features.MultiViewport,
     SamplerAnisotropy                       = features.SamplerAnisotropy,
     TextureCompressionETC2                  = features.TextureCompressionETC2,
     TexturecompressionastcLdr               = features.TexturecompressionastcLdr,
     TextureCompressionBC                    = features.TextureCompressionBC,
     OcclusionQueryPrecise                   = features.OcclusionQueryPrecise,
     PipelineStatisticsQuery                 = features.PipelineStatisticsQuery,
     VertexPipelineStoresAndAtomics          = features.VertexPipelineStoresAndAtomics,
     FragmentStoresAndAtomics                = features.FragmentStoresAndAtomics,
     ShaderTessellationAndGeometryPointSize  = features.ShaderTessellationAndGeometryPointSize,
     ShaderImageGatherExtended               = features.ShaderImageGatherExtended,
     ShaderStorageImageExtendedFormats       = features.ShaderStorageImageExtendedFormats,
     ShaderStorageImageMultisample           = features.ShaderStorageImageMultisample,
     ShaderStorageImageReadWithoutFormat     = features.ShaderStorageImageReadWithoutFormat,
     ShaderStorageImageWriteWithoutFormat    = features.ShaderStorageImageWriteWithoutFormat,
     ShaderUniformBufferArrayDynamicIndexing = features.ShaderUniformBufferArrayDynamicIndexing,
     ShaderSampledImageArrayDynamicIndexing  = features.ShaderSampledImageArrayDynamicIndexing,
     ShaderStorageBufferArrayDynamicIndexing = features.ShaderStorageBufferArrayDynamicIndexing,
     ShaderStorageImageArrayDynamicIndexing  = features.ShaderStorageImageArrayDynamicIndexing,
     ShaderClipDistance                      = features.ShaderClipDistance,
     ShaderCullDistance                      = features.ShaderCullDistance,
     ShaderFloat64                           = features.ShaderFloat64,
     ShaderInt64                             = features.ShaderInt64,
     ShaderInt16                             = features.ShaderInt16,
     ShaderResourceResidency                 = features.ShaderResourceResidency,
     ShaderResourceMinLod                    = features.ShaderResourceMinLod,
     SparseBinding                           = features.SparseBinding,
     SparseResidencyBuffer                   = features.SparseResidencyBuffer,
     SparseResidencyImage2D                  = features.SparseResidencyImage2D,
     SparseResidencyImage3D                  = features.SparseResidencyImage3D,
     SparseResidency2Samples                 = features.SparseResidency2Samples,
     SparseResidency4Samples                 = features.SparseResidency4Samples,
     SparseResidency8Samples                 = features.SparseResidency8Samples,
     SparseResidency16Samples                = features.SparseResidency16Samples,
     SparseResidencyAliased                  = features.SparseResidencyAliased,
     VariableMultisampleRate                 = features.VariableMultisampleRate,
     InheritedQueries                        = features.InheritedQueries,
 };
Пример #5
0
        void PhysicalDeviceFeatures(PhysicalDeviceFeatures physicalDeviceFeatures)
        {
            var type    = physicalDeviceFeatures.GetType();
            var members = type.GetFields();

            foreach (var member in members)
            {
                WriteLine($"{member.Name,-39} = {member.GetValue(physicalDeviceFeatures)}");
            }
        }
Пример #6
0
        public unsafe ReturnSet <bool> InitializeLogicalDevice(VulkanDevice physicalDevice, Logger logger)
        {
            uint queuePriorities = 0;

            var deviceQueueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType    = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new IntPtr(&queuePriorities)
            };

            var physicalDeviceFeatures = new PhysicalDeviceFeatures
            {
                ShaderClipDistance = true,
            };

            var enabledLayerNames = new[]
            {
                ExtensionNames.VK_LAYER_LUNARG_standard_validation.ToIntPtr()
            };

            var enabledExtensionNames = new[]
            {
                ExtensionNames.VK_KHR_swapchain.ToIntPtr()
            };

            fixed(void *enabledLayerNamesPointer = &enabledLayerNames[0])
            fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
            {
                var deviceCreateInfo = new DeviceCreateInfo
                {
                    StructureType         = StructureType.DeviceCreateInfo,
                    QueueCreateInfoCount  = 1,
                    QueueCreateInfos      = new IntPtr(&deviceQueueCreateInfo),
                    EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                    EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                    EnabledFeatures       = new IntPtr(&physicalDeviceFeatures),
                    EnabledLayerCount     = (uint)enabledLayerNames.Length,
                    EnabledLayerNames     = new IntPtr(enabledLayerNamesPointer)
                };

                physicalDevice.CreateLogicalDevice(deviceCreateInfo);

                logger.AddMessage("Logical Device created successfully");

                _queue = physicalDevice.CreateQueue(_surface);

                logger.AddMessage($"Queue created on {physicalDevice.Name}");

                _form.Show();

                return(new ReturnSet <bool>(true));
            }
        }
Пример #7
0
        public PhysicalDeviceInfo(PhysicalDevice physicalDevice)
        {
            PhysicalDevice        = physicalDevice;
            Properties            = PhysicalDevice.GetProperties();
            QueueFamilyProperties = PhysicalDevice.GetQueueFamilyProperties();
            MemoryProperties      = PhysicalDevice.GetMemoryProperties();
            Features = PhysicalDevice.GetFeatures();

            GraphicsQFamilies      = Array.AsReadOnly(QueueFamiliesWithFlag(QueueFlags.Graphics));
            ComputeQFamilies       = Array.AsReadOnly(QueueFamiliesWithFlag(QueueFlags.Compute));
            TransferQFamilies      = Array.AsReadOnly(QueueFamiliesWithFlag(QueueFlags.Transfer));
            SparseBindingQFamilies = Array.AsReadOnly(QueueFamiliesWithFlag(QueueFlags.SparseBinding));
        }
Пример #8
0
        public static bool SupportsFeatures(this PhysicalDevice @this, PhysicalDeviceFeatures desiredFeatures)
        {
            var deviceFeatures = @this.GetFeatures().GetEnabledFeatures();

            foreach (var desiredFeature in desiredFeatures.GetEnabledFeatures())
            {
                if (deviceFeatures.Contains(desiredFeature) == false)
                {
                    return(false);
                }
            }

            return(true);
        }
        public static IEnumerable <string> GetEnabledFeatures(this PhysicalDeviceFeatures @this)
        {
            var enabledFeatures = new List <string>();

            foreach (var field in @this.GetType().GetFields())
            {
                if ((Bool32)field.GetValue(@this))
                {
                    enabledFeatures.Add(field.Name);
                }
            }

            return(enabledFeatures);
        }
        internal HostDevice(
            PhysicalDevice vulkanPhysicaldevice,
            SurfaceType surfaceType,
            Logger logger = null)
        {
            if (vulkanPhysicaldevice == null)
            {
                throw new ArgumentNullException(nameof(vulkanPhysicaldevice));
            }
            this.physicalDevice         = vulkanPhysicaldevice;
            this.surfaceType            = surfaceType;
            this.logger                 = logger;
            this.properties             = vulkanPhysicaldevice.GetProperties();
            this.deviceMemoryProperties = vulkanPhysicaldevice.GetMemoryProperties();
            this.supportedFeatures      = vulkanPhysicaldevice.GetFeatures();
            this.availableExtensions    = vulkanPhysicaldevice.EnumerateExtensionProperties();
            this.queueFamilies          = vulkanPhysicaldevice.GetQueueFamilyProperties();

            logger?.Log(nameof(HostDevice), $"Found device: {Name}");
            logger?.LogList(nameof(HostDevice), $"{Name} available extensions:", availableExtensions);
        }
Пример #11
0
        protected Device CreateDevice(PhysicalDevice physicalDevice, uint queueFamily)
        {
            String[] enabledLayers = new string[]
            {
                "VK_LAYER_LUNARG_standard_validation"
            };

            var enabledExtensions = new[]
            {
                VulkanConstant.KhrSwapchainExtensionName,
            };

            var features = new PhysicalDeviceFeatures();

            features.ShaderClipDistance = true;
            features.ShaderCullDistance = true;

            var queueCreateInfo  = new DeviceQueueCreateInfo(queueFamily, new[] { 0f });
            var deviceCreateInfo = new DeviceCreateInfo(new[] { queueCreateInfo }, enabledLayers, enabledExtensions);

            deviceCreateInfo.EnabledFeatures = features;
            return(physicalDevice.CreateDevice(deviceCreateInfo));
        }
Пример #12
0
        public unsafe VulkanRenderer(UserSettings userSettings, Window window, IScene scene, CameraInitialState cameraInitialState, ILogger logger, bool enableDebugLogging)
        {
            _userSettings = userSettings;
            _window       = window;

            _api = new Api(enableDebugLogging, logger);

            _presentMode = _userSettings.VSync ? PresentModeKHR.PresentModeFifoKhr : PresentModeKHR.PresentModeImmediateKhr;

            _api.Instance = new Instance(_api, _window, new Version32(1, 2, 0));
            _surface      = new Surface(_api, _window, _api.Instance);

            // Find the vulkan device we want
            var physicalDevice = _api.Instance.PhysicalDevices.Where(d =>
            {
                _api.Vk.GetPhysicalDeviceFeatures(d, out var deviceFeatures);

                if (deviceFeatures.GeometryShader == false)
                {
                    return(false);
                }

                var queueFamilies = Enumerate.Get <PhysicalDevice, QueueFamilyProperties>(d, (device, count, values) =>
                                                                                          _api.Vk.GetPhysicalDeviceQueueFamilyProperties(device, (uint *)count, (QueueFamilyProperties *)values));

                for (var i = 0; i < queueFamilies.Count; i++)
                {
                    if (queueFamilies[i].QueueCount > 0 && queueFamilies[i].QueueFlags.HasFlag(QueueFlags.QueueGraphicsBit))
                    {
                        return(true);
                    }
                }

                return(false);
            }).FirstOrDefault();

            if (physicalDevice.Handle == 0)
            {
                throw new Exception($"{nameof(VulkanRenderer)}: Could not find a suitable graphics device.");
            }

            var deviceProps = new PhysicalDeviceProperties2();

            deviceProps.SType = StructureType.PhysicalDeviceProperties2;

            _api.Vk.GetPhysicalDeviceProperties2(physicalDevice, &deviceProps);

            _api.Logger.Debug($"{nameof(VulkanRenderer)}: Setting physical device: {deviceProps.Properties.DeviceID} ({Marshal.PtrToStringAnsi((nint)deviceProps.Properties.DeviceName)})");

            // Opt-in into mandatory device features.
            var shaderClockFeatures = new PhysicalDeviceShaderClockFeaturesKHR();

            shaderClockFeatures.SType = StructureType.PhysicalDeviceShaderClockFeaturesKhr;
            shaderClockFeatures.PNext = null;
            shaderClockFeatures.ShaderSubgroupClock = true;

            var deviceFeatures = new PhysicalDeviceFeatures();

            deviceFeatures.FillModeNonSolid  = true;
            deviceFeatures.SamplerAnisotropy = true;
            deviceFeatures.ShaderInt64       = true;

            // Required device features.
            var bufferDeviceAddressFeatures = new PhysicalDeviceBufferDeviceAddressFeatures();

            bufferDeviceAddressFeatures.SType = StructureType.PhysicalDeviceBufferDeviceAddressFeatures;
            bufferDeviceAddressFeatures.PNext = &shaderClockFeatures;
            bufferDeviceAddressFeatures.BufferDeviceAddress = true;

            var indexingFeatures = new PhysicalDeviceDescriptorIndexingFeatures();

            indexingFeatures.SType = StructureType.PhysicalDeviceDescriptorIndexingFeatures;
            indexingFeatures.PNext = &bufferDeviceAddressFeatures;
            indexingFeatures.RuntimeDescriptorArray = true;
            indexingFeatures.ShaderSampledImageArrayNonUniformIndexing = true;

            var accelerationStructureFeatures = new PhysicalDeviceAccelerationStructureFeaturesKHR();

            accelerationStructureFeatures.SType = StructureType.PhysicalDeviceAccelerationStructureFeaturesKhr;
            accelerationStructureFeatures.PNext = &indexingFeatures;
            accelerationStructureFeatures.AccelerationStructure = true;

            var rayTracingFeatures = new PhysicalDeviceRayTracingPipelineFeaturesKHR();

            rayTracingFeatures.SType = StructureType.PhysicalDeviceRayTracingPipelineFeaturesKhr;
            rayTracingFeatures.PNext = &accelerationStructureFeatures;
            rayTracingFeatures.RayTracingPipeline = true;

            _api.Device = new Device(_api, physicalDevice, _surface, deviceFeatures, Unsafe.AsPointer(ref rayTracingFeatures));

            // Now that we have an instance and a device, load all of the extentions we need.
            _api.InitializeExtensions();

            _commandPool = new CommandPool(_api, _api.Device.GraphicsFamilyIndex, true);

            _rayTracingProperties = new RayTracingProperties(_api);

            // Load the scene, and create the swap chain / command buffers
            LoadScene(scene, cameraInitialState);

            _currentFrame = 0;

            _api.Device.WaitIdle();
        }
Пример #13
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);
        }
Пример #14
0
        private unsafe void CreateLogicalDevice()
        {
            QueueFamilyIndices indices = FindQueueFamilies(_physicalDevice);

            uint[] uniqueQueueFamilies = new[] { indices.GraphicsFamily.Value, indices.PresentFamily.Value };
            var    queueCreateInfos    = stackalloc DeviceQueueCreateInfo[uniqueQueueFamilies.Length];

            float queuePriority = 1.0f;

            for (int i = 0; i < uniqueQueueFamilies.Length; i++)
            {
                uint queueFamily     = uniqueQueueFamilies[i];
                var  queueCreateInfo = new DeviceQueueCreateInfo
                {
                    SType            = StructureType.DeviceQueueCreateInfo,
                    QueueFamilyIndex = queueFamily,
                    QueueCount       = 1,
                    PQueuePriorities = &queuePriority
                };
                queueCreateInfos[i] = queueCreateInfo;
            }

            var deviceFeatures = new PhysicalDeviceFeatures();

            var createInfo = new DeviceCreateInfo
            {
                SType                 = StructureType.DeviceCreateInfo,
                PQueueCreateInfos     = queueCreateInfos,
                QueueCreateInfoCount  = (uint)uniqueQueueFamilies.Length,
                PEnabledFeatures      = &deviceFeatures,
                EnabledExtensionCount = 0
            };

            if (EnableValidationLayers)
            {
                createInfo.EnabledLayerCount   = (uint)_validationLayers.Length;
                createInfo.PpEnabledLayerNames = (byte **)SilkMarshal.MarshalStringArrayToPtr(_validationLayers);
            }
            else
            {
                createInfo.EnabledLayerCount = 0;
            }

            fixed(Device *device = &_device)
            {
                Result result = _vk.CreateDevice(_physicalDevice, &createInfo, (AllocationCallbacks *)null, device);

                if (result != Result.Success)
                {
                    throw new Exception("Failed to create logical device!");
                }
            }

            fixed(Queue *graphicsQueue = &_graphicsQueue)
            {
                _vk.GetDeviceQueue(_device, indices.GraphicsFamily.Value, 0, graphicsQueue);
            }

            fixed(Queue *presentQueue = &_presentQueue)
            {
                _vk.GetDeviceQueue(_device, indices.PresentFamily.Value, 0, presentQueue);
            }
        }
Пример #15
0
        /// <summary>
        ///     Initializes the specified device.
        /// </summary>
        /// <param name="graphicsProfiles">The graphics profiles.</param>
        /// <param name="deviceCreationFlags">The device creation flags.</param>
        /// <param name="windowHandle">The window handle.</param>
        private unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle)
        {
            if (nativeDevice != Device.Null)
            {
                // Destroy previous device
                ReleaseDevice();
            }

            rendererName = Adapter.Description;

            PhysicalDeviceProperties physicalDeviceProperties;

            NativePhysicalDevice.GetProperties(out physicalDeviceProperties);
            ConstantBufferDataPlacementAlignment = (int)physicalDeviceProperties.Limits.MinUniformBufferOffsetAlignment;

            RequestedProfile = graphicsProfiles.Last();

            var queueProperties = NativePhysicalDevice.QueueFamilyProperties;

            // Command lists are thread-safe and execute deferred
            IsDeferred = true;

            // TODO VULKAN
            // Create Vulkan device based on profile
            uint queuePriorities = 0;
            var  queueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType    = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new IntPtr(&queuePriorities)
            };

            var enabledFeature = new PhysicalDeviceFeatures
            {
                FillModeNonSolid   = true,
                ShaderClipDistance = true,
                ShaderCullDistance = true,
                SamplerAnisotropy  = true,
                DepthClamp         = true,
            };

            var extensionProperties     = NativePhysicalDevice.GetDeviceExtensionProperties();
            var availableExtensionNames = new List <string>();
            var desiredExtensionNames   = new List <string>();

            for (int index = 0; index < extensionProperties.Length; index++)
            {
                var namePointer = new IntPtr(Interop.Fixed(ref extensionProperties[index].ExtensionName));
                var name        = Marshal.PtrToStringAnsi(namePointer);
                availableExtensionNames.Add(name);
            }

            desiredExtensionNames.Add("VK_KHR_swapchain");
            if (!availableExtensionNames.Contains("VK_KHR_swapchain"))
            {
                throw new InvalidOperationException();
            }

            if (availableExtensionNames.Contains("VK_EXT_debug_marker") && IsDebugMode)
            {
                desiredExtensionNames.Add("VK_EXT_debug_marker");
                IsProfilingSupported = true;
            }

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

            try
            {
                var deviceCreateInfo = new DeviceCreateInfo
                {
                    StructureType         = StructureType.DeviceCreateInfo,
                    QueueCreateInfoCount  = 1,
                    QueueCreateInfos      = new IntPtr(&queueCreateInfo),
                    EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                    EnabledExtensionNames = enabledExtensionNames.Length > 0 ? new IntPtr(Interop.Fixed(enabledExtensionNames)) : IntPtr.Zero,
                    EnabledFeatures       = new IntPtr(&enabledFeature)
                };

                nativeDevice = NativePhysicalDevice.CreateDevice(ref deviceCreateInfo);
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }
            }

            NativeCommandQueue = nativeDevice.GetQueue(0, 0);

            //// Prepare copy command list (start it closed, so that every new use start with a Reset)
            var commandPoolCreateInfo = new CommandPoolCreateInfo
            {
                StructureType    = StructureType.CommandPoolCreateInfo,
                QueueFamilyIndex = 0, //device.NativeCommandQueue.FamilyIndex
                Flags            = CommandPoolCreateFlags.ResetCommandBuffer
            };

            NativeCopyCommandPool = NativeDevice.CreateCommandPool(ref commandPoolCreateInfo);

            var commandBufferAllocationInfo = new CommandBufferAllocateInfo
            {
                StructureType      = StructureType.CommandBufferAllocateInfo,
                Level              = CommandBufferLevel.Primary,
                CommandPool        = NativeCopyCommandPool,
                CommandBufferCount = 1
            };
            CommandBuffer nativeCommandBuffer;

            NativeDevice.AllocateCommandBuffers(ref commandBufferAllocationInfo, &nativeCommandBuffer);
            NativeCopyCommandBuffer = nativeCommandBuffer;

            DescriptorPools = new HeapPool(this);

            nativeResourceCollector       = new NativeResourceCollector(this);
            graphicsResourceLinkCollector = new GraphicsResourceLinkCollector(this);

            EmptyTexelBuffer = Buffer.Typed.New(this, 1, PixelFormat.R32G32B32A32_Float);
        }
Пример #16
0
        private void InitializeVulkan(string applicationName, uint applicationVersion)
        {
            Console.WriteLine("Initializing Vulkan");
#if VALIDITION
            DebugUtilsMessengerCreateInfoEXT GetDebugMessenger(void *pNext)
            {
                return(new DebugUtilsMessengerCreateInfoEXT(
                           messageSeverity: DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityVerboseBitExt |
                           DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityInfoBitExt |
                           DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt |
                           DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt,
                           messageType: DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeGeneralBitExt |
                           DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt |
                           DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt,
                           pfnUserCallback: new PfnDebugUtilsMessengerCallbackEXT(DebugCallback), pNext: pNext));
            }
#endif

            _vk = Vk.GetApi();

            const uint   engineVersion = 1;
            const string engineName    = "Videre";

            var instanceLayers     = new List <string>();
            var instanceExtensions = new List <string>();

            var pApplicationName = SilkMarshal.StringToPtr(applicationName);
            var pEngineName      = SilkMarshal.StringToPtr(engineName);
            var applicationInfo  = new ApplicationInfo(pApplicationName: (byte *)pApplicationName,
                                                       applicationVersion: applicationVersion, pEngineName: (byte *)pEngineName, engineVersion: engineVersion,
                                                       apiVersion: new Version32(1, 1, 0));

            Version32 apiVersion = default;
            _vk.EnumerateInstanceVersion((uint *)&apiVersion);
            Console.WriteLine($"Instance Version: {apiVersion.Major}.{apiVersion.Minor}.{apiVersion.Patch}");

            void *instancepNext = default;

            // instanceExtensions.Add(KhrSurface.ExtensionName);
            instanceExtensions.AddRange(SilkMarshal.PtrToStringArray((nint)View.VkSurface.GetRequiredExtensions(out var requiredExtensionsCount), (int)requiredExtensionsCount));
            instanceExtensions.Add(ExtDebugUtils.ExtensionName);

            Console.WriteLine($"Creating Instance with {instanceExtensions.Count} extensions");
            VerifyInstanceExtensionsAvailable(_vk, instanceExtensions);

            var ppEnabledLayers     = instanceLayers.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(instanceLayers) : null;
            var ppEnabledExtensions = instanceExtensions.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(instanceExtensions) : null;

            _vk.CreateInstance(
                new InstanceCreateInfo(pApplicationInfo: &applicationInfo,
                                       enabledLayerCount: (uint)instanceLayers.Count, ppEnabledLayerNames: ppEnabledLayers,
                                       enabledExtensionCount: (uint)instanceExtensions.Count,
                                       ppEnabledExtensionNames: ppEnabledExtensions, pNext: instancepNext), _allocationCallbacks.AllocationCallbacks, out _instance)
            .ThrowCode();
            SilkMarshal.Free((nint)ppEnabledLayers);
            SilkMarshal.Free((nint)ppEnabledExtensions);

            _vk.CurrentInstance = _instance;

            if (!_vk.TryGetInstanceExtension(_instance, out _khrSurface))
            {
                Console.WriteLine($"Could not load {KhrSurface.ExtensionName}");
            }

            _vk.TryGetInstanceExtension(_instance, out _debugUtils);

            Console.WriteLine("Creating Surface");
            _surface = View.VkSurface.Create(_instance.ToHandle(), (AllocationCallbacks *)null).ToSurface();

            uint deviceCount = 0;
            _vk.EnumeratePhysicalDevices(_instance, ref deviceCount, null).ThrowCode();
            var devices = (PhysicalDevice *)SilkMarshal.Allocate((int)(deviceCount * sizeof(PhysicalDevice)));
            _vk.EnumeratePhysicalDevices(_instance, ref deviceCount, devices).ThrowCode();
            Console.WriteLine($"Found {deviceCount} devices");

            Console.WriteLine("Creating Device");
            // TODO: actually somehow reasonably find the best device.
            for (int i = 0; i < deviceCount; i++)
            {
                var physicalDevice = devices[i];
                _physicalDeviceFeatures = _vk.GetPhysicalDeviceFeature(physicalDevice);

                uint presentModeCount = 0;
                _khrSurface.GetPhysicalDeviceSurfacePresentModes(physicalDevice, _surface, ref presentModeCount, null).ThrowCode();
                if (presentModeCount <= 0)
                {
                    continue;
                }

                var presentModes = (PresentModeKHR *)SilkMarshal.Allocate((int)(presentModeCount * sizeof(PresentModeKHR)));
                _khrSurface.GetPhysicalDeviceSurfacePresentModes(physicalDevice, _surface, ref presentModeCount, presentModes).ThrowCode();

                _presentMode         = PresentModeKHR.PresentModeFifoKhr;
                View.FramesPerSecond = -1;
                for (int j = 0; j < presentModeCount; j++)
                {
                    if (presentModes[j] == PresentModeKHR.PresentModeMailboxKhr)
                    {
                        _presentMode         = PresentModeKHR.PresentModeMailboxKhr;
                        View.FramesPerSecond = -1;
                        break;
                    }
                }

                SilkMarshal.Free((nint)presentModes);

                uint surfaceFormatCount = 0;
                _khrSurface.GetPhysicalDeviceSurfaceFormats(physicalDevice, _surface, ref surfaceFormatCount, null).ThrowCode();
                var surfaceFormats = (SurfaceFormatKHR *)SilkMarshal.Allocate((int)(surfaceFormatCount * sizeof(SurfaceFormatKHR)));
                _khrSurface.GetPhysicalDeviceSurfaceFormats(physicalDevice, _surface, ref surfaceFormatCount, surfaceFormats).ThrowCode();
                int max = int.MinValue;
                SurfaceFormatKHR maxFormat = surfaceFormats[0];
                for (int j = 0; j < surfaceFormatCount; j++)
                {
                    var score = FormatRater.Rate(surfaceFormats[j].Format) + ColorSpaceRater.Rate(surfaceFormats[j].ColorSpace);
                    if (score > max)
                    {
                        max       = score;
                        maxFormat = surfaceFormats[j];
                    }
                }
                SilkMarshal.Free((nint)surfaceFormats);

                _swapchainFormat     = maxFormat.Format;
                _swapchainColorSpace = maxFormat.ColorSpace;
                Console.WriteLine($"Chose Swapchain Properties: {Enum.GetName(typeof(PresentModeKHR), _presentMode)} {Enum.GetName(typeof(Format), _swapchainFormat)} {Enum.GetName(typeof(ColorSpaceKHR), _swapchainColorSpace)}");

                _khrSurface.GetPhysicalDeviceSurfaceCapabilities(physicalDevice, _surface, out var surfaceCapabilities).ThrowCode();

                uint queueFamilyPropertyCount = 0;
                _vk.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyPropertyCount, null);
                var deviceQueueFamilyProperties = (QueueFamilyProperties *)SilkMarshal.Allocate((int)(queueFamilyPropertyCount * sizeof(QueueFamilyProperties)));
                _vk.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyPropertyCount, deviceQueueFamilyProperties);

                var queueCreateInfoList = new List <DeviceQueueCreateInfo>();
                var deviceExtensions    = new List <string>();
                var deviceLayers        = new List <string>();

                for (int j = 0; j < queueFamilyPropertyCount; j++)
                {
                    var    queueCount       = deviceQueueFamilyProperties[j].QueueCount;
                    float *pQueuePriorities = stackalloc float[(int)queueCount]; // queue count should generally be 1
                    for (int k = 0; k < queueCount; k++)
                    {
                        pQueuePriorities[k] = 1.0f;
                    }

                    queueCreateInfoList.Add(new DeviceQueueCreateInfo(queueFamilyIndex: (uint)j, queueCount: queueCount, pQueuePriorities: pQueuePriorities));
                }

                deviceExtensions.Add(KhrSwapchain.ExtensionName);
                // deviceExtensions.Add(KhrSynchronization2.ExtensionName);
                // deviceExtensions.Add(ExtBufferDeviceAddress.ExtensionName);

                var features = new PhysicalDeviceFeatures();
                features.ShaderInt64 = true;

                void *devicePNext = null;

//                 var physicalDeviceDescriptorIndexingFeaturesExt = new PhysicalDeviceDescriptorIndexingFeaturesEXT(
//                     descriptorBindingSampledImageUpdateAfterBind: true,
//                     descriptorBindingStorageBufferUpdateAfterBind: true,
//                     descriptorBindingStorageImageUpdateAfterBind: true,
//                     descriptorBindingUniformBufferUpdateAfterBind: true,
//                     descriptorBindingStorageTexelBufferUpdateAfterBind: true,
//                     descriptorBindingUniformTexelBufferUpdateAfterBind: true,
//                     descriptorBindingUpdateUnusedWhilePending: true,
//                     runtimeDescriptorArray: true,
//                     pNext: devicePNext);
//                 devicePNext = &physicalDeviceDescriptorIndexingFeaturesExt;
//
                var physicalDeviceBufferDeviceAddressFeatures = new PhysicalDeviceBufferDeviceAddressFeatures(bufferDeviceAddress: true,
#if DEBUG
                                                                                                              bufferDeviceAddressCaptureReplay: true,
#endif
                                                                                                              pNext: devicePNext);
                devicePNext = &physicalDeviceBufferDeviceAddressFeatures;

//                 var version12 = new PhysicalDeviceVulkan12Features(bufferDeviceAddress: true,
// #if DEBUG
//                     bufferDeviceAddressCaptureReplay: true,
// #endif
//                    descriptorBindingSampledImageUpdateAfterBind: true,
//                    descriptorBindingStorageBufferUpdateAfterBind: true,
//                    descriptorBindingStorageImageUpdateAfterBind: true,
//                    descriptorBindingUniformBufferUpdateAfterBind: true,
//                    descriptorBindingStorageTexelBufferUpdateAfterBind: true,
//                    descriptorBindingUniformTexelBufferUpdateAfterBind: true,
//                    descriptorBindingUpdateUnusedWhilePending: true,
//                    runtimeDescriptorArray: true,
//                     pNext: devicePNext);
//                 devicePNext = &version12;

                var queueCreateInfos = queueCreateInfoList.Distinct().ToArray();
                queueCreateInfoList = null;

                VerifyDeviceExtensionsAvailable(_vk, devices[i], deviceExtensions, ref deviceLayers);

                _physicalDevice = devices[i];

                Console.WriteLine("Creating Logical Device");
                var ppDeviceExtensions = deviceExtensions.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(deviceExtensions) : null;
                var ppDeviceLayers     = deviceLayers.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(deviceLayers) : null;

                fixed(DeviceQueueCreateInfo *pQueueCreateInfos = queueCreateInfos)
                _vk.CreateDevice(physicalDevice,
                                 new DeviceCreateInfo(queueCreateInfoCount: (uint)queueCreateInfos.Length,
                                                      pQueueCreateInfos: pQueueCreateInfos,
                                                      enabledExtensionCount: (uint)deviceExtensions.Count,
                                                      enabledLayerCount: (uint)deviceLayers.Count,
                                                      ppEnabledExtensionNames: ppDeviceExtensions,
                                                      ppEnabledLayerNames: ppDeviceLayers, pEnabledFeatures: &features, pNext: devicePNext), null,
                                 out _logicalDevice)
                .ThrowCode();

                _vk.CurrentDevice = _logicalDevice;

                if (!_vk.TryGetDeviceExtension(_instance, _logicalDevice, out _khrSwapchain))
                {
                    Console.WriteLine($"Could not load {KhrSwapchain.ExtensionName}!");
                }

                _queueManager = new(_vk, _khrSurface, _instance, _physicalDevice, _logicalDevice, _surface, new Span <QueueFamilyProperties>(deviceQueueFamilyProperties, (int)queueFamilyPropertyCount));
                Console.WriteLine($"{_queueManager.QueueCount} queues found");

                SilkMarshal.Free((nint)ppDeviceExtensions);
                SilkMarshal.Free((nint)ppDeviceLayers);
                SilkMarshal.Free((nint)deviceQueueFamilyProperties);
                break;
            }
            SilkMarshal.Free((nint)devices);
            Console.WriteLine("Initialized Vulkan");
        }
Пример #17
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);
        }
Пример #18
0
        public static IEnumerable <PhysicalDevice> GetSuitablePhysicalDevices(this Instance @this, string[] requiredPhysicalDeviceExtensions, PhysicalDeviceFeatures requiredPhysicalDeviceFeatures, QueueFlags requiredQueueFlags, SurfaceKhr surface)
        {
            var suitablePhysicalDevices = new List <PhysicalDevice>();

            foreach (var physicalDevice in @this.EnumeratePhysicalDevices())
            {
                // Make sure device supports required extensions
                if (physicalDevice.SupportsExtensions(requiredPhysicalDeviceExtensions) == false)
                {
                    continue;
                }

                // Make sure device supports required features
                if (physicalDevice.SupportsFeatures(requiredPhysicalDeviceFeatures) == false)
                {
                    continue;
                }

                // Make sure device has a queue family with required flags
                if (physicalDevice.GetIndexOfFirstAvailableGraphicsQueueFamily() < 0)
                {
                    continue;
                }

                // Make sure device has a queue family with required flags
                if (physicalDevice.GetIndexOfFirstAvailablePresentQueueFamily(surface) < 0)
                {
                    continue;
                }

                suitablePhysicalDevices.Add(physicalDevice);
            }

            if (suitablePhysicalDevices.Count() == 0)
            {
                throw new VulkanException("No suitable physical device found");
            }

            return(suitablePhysicalDevices);
        }
Пример #19
0
 internal static unsafe extern void vkGetPhysicalDeviceFeatures(PhysicalDevice physicalDevice, PhysicalDeviceFeatures* features);
Пример #20
0
        public Context(GameWindow window)
        {
            Window              = window;
            Instance            = ToDispose(VKHelper.CreateInstance());
            DebugReportCallback = ToDispose(VKHelper.CreateDebugReportCallback(Instance));
            Surface             = ToDispose(VKHelper.CreateSurface(Instance, Window.Handle));

            foreach (PhysicalDevice physicalDevice in Instance.EnumeratePhysicalDevices())
            {
                QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();
                for (int i = 0; i < queueFamilyProperties.Length; i++)
                {
                    if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics))
                    {
                        if (GraphicsQueueFamilyIndex == -1)
                        {
                            GraphicsQueueFamilyIndex = i;
                        }
                        if (ComputeQueueFamilyIndex == -1)
                        {
                            ComputeQueueFamilyIndex = i;
                        }

                        if (physicalDevice.GetSurfaceSupportKhr(i, Surface) &&
                            VKHelper.GetPresentationSupport(physicalDevice, i))
                        {
                            PresentQueueFamilyIndex = i;
                        }

                        if (GraphicsQueueFamilyIndex != -1 &&
                            ComputeQueueFamilyIndex != -1 &&
                            PresentQueueFamilyIndex != -1)
                        {
                            PhysicalDevice = physicalDevice;
                            break;
                        }
                    }
                }
                if (PhysicalDevice != null)
                {
                    break;
                }
            }

            if (PhysicalDevice == null)
            {
                throw new InvalidOperationException("No suitable physical device found.");
            }

            GenerateDepthStencilFormat();

            // Store memory properties of the physical device.
            MemoryProperties = PhysicalDevice.GetMemoryProperties();
            Features         = PhysicalDevice.GetFeatures();
            Properties       = PhysicalDevice.GetProperties();

            // Create a logical device.
            bool sameGraphicsAndPresent = GraphicsQueueFamilyIndex == PresentQueueFamilyIndex;
            var  queueCreateInfos       = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(GraphicsQueueFamilyIndex, 1, 1.0f);
            if (!sameGraphicsAndPresent)
            {
                queueCreateInfos[1] = new DeviceQueueCreateInfo(PresentQueueFamilyIndex, 1, 1.0f);
            }

            var deviceCreateInfo = new DeviceCreateInfo(
                queueCreateInfos,
                new[] { Constant.DeviceExtension.KhrSwapchain, Constant.DeviceExtension.KhrMaintenance1 },
                Features);

            Device = PhysicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            GraphicsQueue = Device.GetQueue(GraphicsQueueFamilyIndex);
            ComputeQueue  = ComputeQueueFamilyIndex == GraphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(ComputeQueueFamilyIndex);
            PresentQueue = PresentQueueFamilyIndex == GraphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(PresentQueueFamilyIndex);

            Content = new Content(this);

            GraphicsCommandPool = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(GraphicsQueueFamilyIndex, CommandPoolCreateFlags.ResetCommandBuffer)));
            ComputeCommandPool  = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(ComputeQueueFamilyIndex)));

            Graphics = ToDispose(new Graphics(this));

            Build();
        }
Пример #21
0
        protected virtual void CreateDevice()
        {
            uint queuePriorities = 0;
            var  queueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType    = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new IntPtr(&queuePriorities)
            };

            var enabledLayerNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_LAYER_LUNARG_standard_validation"),
            };

            var enabledExtensionNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_KHR_swapchain"),
            };

            try
            {
                fixed(void *enabledLayerNamesPointer = &enabledLayerNames[0])
                fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var enabledFeatures = new PhysicalDeviceFeatures
                    {
                        ShaderClipDistance = true,
                    };

                    var deviceCreateInfo = new DeviceCreateInfo
                    {
                        StructureType         = StructureType.DeviceCreateInfo,
                        QueueCreateInfoCount  = 1,
                        QueueCreateInfos      = new IntPtr(&queueCreateInfo),
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                        EnabledFeatures       = new IntPtr(&enabledFeatures)
                    };

                    if (validate)
                    {
                        deviceCreateInfo.EnabledLayerCount = (uint)enabledLayerNames.Length;
                        deviceCreateInfo.EnabledLayerNames = new IntPtr(enabledLayerNamesPointer);
                    }

                    device = physicalDevice.CreateDevice(ref deviceCreateInfo);
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }

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

            var queueNodeIndex = physicalDevice.QueueFamilyProperties.
                                 Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0 && physicalDevice.GetSurfaceSupport((uint)index, surface)).
                                 Select((properties, index) => index).First();

            queue = device.GetQueue(0, (uint)queueNodeIndex);
        }
Пример #22
0
        protected virtual void CreateDevice()
        {
            uint queuePriorities = 0;
            var queueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount = 1,
                QueuePriorities = new IntPtr(&queuePriorities)
            };

            var enabledLayerNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_LAYER_LUNARG_standard_validation"),
            };

            var enabledExtensionNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_KHR_swapchain"),
            };

            try
            {
                fixed (void* enabledLayerNamesPointer = &enabledLayerNames[0])
                fixed (void* enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var enabledFeatures = new PhysicalDeviceFeatures
                    {
                        ShaderClipDistance = true,
                    };

                    var deviceCreateInfo = new DeviceCreateInfo
                    {
                        StructureType = StructureType.DeviceCreateInfo,
                        QueueCreateInfoCount = 1,
                        QueueCreateInfos = new IntPtr(&queueCreateInfo),
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                        EnabledFeatures = new IntPtr(&enabledFeatures)
                    };

                    if (validate)
                    {
                        deviceCreateInfo.EnabledLayerCount = (uint)enabledLayerNames.Length;
                        deviceCreateInfo.EnabledLayerNames = new IntPtr(enabledLayerNamesPointer);
                    }

                    device = physicalDevice.CreateDevice(ref deviceCreateInfo);
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                    Marshal.FreeHGlobal(enabledExtensionName);

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

            var queueNodeIndex = physicalDevice.QueueFamilyProperties.
                Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0 && physicalDevice.GetSurfaceSupport((uint)index, surface)).
                Select((properties, index) => index).First();

            queue = device.GetQueue(0, (uint)queueNodeIndex);
        }
Пример #23
0
        void AppGpuDumpFeatures(AppGpu gpu, StreamWriter output)
        {
            PhysicalDeviceFeatures features = gpu.Features;

            output.WriteLine("VkPhysicalDeviceFeatures:");
            output.WriteLine("=========================");

            output.WriteLine("\trobustBufferAccess                      = {0}", features.RobustBufferAccess);
            output.WriteLine("\tfullDrawIndexUint32                     = {0}", features.FullDrawIndexUint32);
            output.WriteLine("\timageCubeArray                          = {0}", features.ImageCubeArray);
            output.WriteLine("\tindependentBlend                        = {0}", features.IndependentBlend);
            output.WriteLine("\tgeometryShader                          = {0}", features.GeometryShader);
            output.WriteLine("\ttessellationShader                      = {0}", features.TessellationShader);
            output.WriteLine("\tsampleRateShading                       = {0}", features.SampleRateShading);
            output.WriteLine("\tdualSrcBlend                            = {0}", features.DualSrcBlend);
            output.WriteLine("\tlogicOp                                 = {0}", features.LogicOp);
            output.WriteLine("\tmultiDrawIndirect                       = {0}", features.MultiDrawIndirect);
            output.WriteLine("\tdrawIndirectFirstInstance               = {0}", features.DrawIndirectFirstInstance);
            output.WriteLine("\tdepthClamp                              = {0}", features.DepthClamp);
            output.WriteLine("\tdepthBiasClamp                          = {0}", features.DepthBiasClamp);
            output.WriteLine("\tfillModeNonSolid                        = {0}", features.FillModeNonSolid);
            output.WriteLine("\tdepthBounds                             = {0}", features.DepthBounds);
            output.WriteLine("\twideLines                               = {0}", features.WideLines);
            output.WriteLine("\tlargePoints                             = {0}", features.LargePoints);
            output.WriteLine("\ttextureCompressionETC2                  = {0}", features.TextureCompressionETC2);
            output.WriteLine("\ttextureCompressionASTC_LDR              = {0}", features.TextureCompressionASTCLdr);
            output.WriteLine("\ttextureCompressionBC                    = {0}", features.TextureCompressionBC);
            output.WriteLine("\tocclusionQueryPrecise                   = {0}", features.OcclusionQueryPrecise);
            output.WriteLine("\tpipelineStatisticsQuery                 = {0}", features.PipelineStatisticsQuery);
            output.WriteLine("\tvertexSideEffects                       = {0}", features.VertexPipelineStoresAndAtomics);
            output.WriteLine("\ttessellationSideEffects                 = {0}", features.FragmentStoresAndAtomics);
            output.WriteLine("\tgeometrySideEffects                     = {0}", features.ShaderTessellationAndGeometryPointSize);
            output.WriteLine("\tshaderImageGatherExtended               = {0}", features.ShaderImageGatherExtended);
            output.WriteLine("\tshaderStorageImageExtendedFormats       = {0}", features.ShaderStorageImageExtendedFormats);
            output.WriteLine("\tshaderStorageImageMultisample           = {0}", features.ShaderStorageImageMultisample);
            output.WriteLine("\tshaderStorageImageReadWithoutFormat     = {0}", features.ShaderStorageImageReadWithoutFormat);
            output.WriteLine("\tshaderStorageImageWriteWithoutFormat    = {0}", features.ShaderStorageImageWriteWithoutFormat);
            output.WriteLine("\tshaderUniformBufferArrayDynamicIndexing = {0}", features.ShaderUniformBufferArrayDynamicIndexing);
            output.WriteLine("\tshaderSampledImageArrayDynamicIndexing  = {0}", features.ShaderSampledImageArrayDynamicIndexing);
            output.WriteLine("\tshaderStorageBufferArrayDynamicIndexing = {0}", features.ShaderStorageBufferArrayDynamicIndexing);
            output.WriteLine("\tshaderStorageImageArrayDynamicIndexing  = {0}", features.ShaderStorageImageArrayDynamicIndexing);
            output.WriteLine("\tshaderClipDistance                      = {0}", features.ShaderClipDistance);
            output.WriteLine("\tshaderCullDistance                      = {0}", features.ShaderCullDistance);
            output.WriteLine("\tshaderFloat64                           = {0}", features.ShaderFloat64);
            output.WriteLine("\tshaderInt64                             = {0}", features.ShaderInt64);
            output.WriteLine("\tshaderInt16                             = {0}", features.ShaderInt16);
            output.WriteLine("\tshaderResourceResidency                 = {0}", features.ShaderResourceResidency);
            output.WriteLine("\tshaderResourceMinLod                    = {0}", features.ShaderResourceMinLod);
            output.WriteLine("\talphaToOne                              = {0}", features.AlphaToOne);
            output.WriteLine("\tsparseBinding                           = {0}", features.SparseBinding);
            output.WriteLine("\tsparseResidencyBuffer                   = {0}", features.SparseResidencyBuffer);
            output.WriteLine("\tsparseResidencyImage2D                  = {0}", features.SparseResidencyImage2D);
            output.WriteLine("\tsparseResidencyImage3D                  = {0}", features.SparseResidencyImage3D);
            output.WriteLine("\tsparseResidency2Samples                 = {0}", features.SparseResidency2Samples);
            output.WriteLine("\tsparseResidency4Samples                 = {0}", features.SparseResidency4Samples);
            output.WriteLine("\tsparseResidency8Samples                 = {0}", features.SparseResidency8Samples);
            output.WriteLine("\tsparseResidency16Samples                = {0}", features.SparseResidency16Samples);
            output.WriteLine("\tsparseResidencyAliased                  = {0}", features.SparseResidencyAliased);
            output.WriteLine("\tvariableMultisampleRate                 = {0}", features.VariableMultisampleRate);
            output.WriteLine("\tiheritedQueries                         = {0}", features.InheritedQueries);
        }
 internal bool DoesSupportRequirements(PhysicalDeviceFeatures features) =>
 features.SamplerAnisotropy &&
 features.DepthBiasClamp &&
 features.DepthClamp;
Пример #25
0
 public unsafe void GetFeatures(out PhysicalDeviceFeatures features)
 {
     fixed (PhysicalDeviceFeatures* __features__ = &features)
     {
         vkGetPhysicalDeviceFeatures(this, __features__);
     }
 }