Beispiel #1
0
        private void FindQueueFamilies(PhysicalDevice device, out QueueFamilyIndices indices)
        {
            indices = new QueueFamilyIndices();

            var families = QuerryQueueFamilyProperties(device);

            for (int i = 0; i < families.Length; ++i)
            {
                ref QueueFamilyProperties queueFamily = ref families[i];

                const QueueFlags GraphicsQueueBits = QueueFlags.QueueGraphicsBit | QueueFlags.QueueTransferBit;

                if ((queueFamily.QueueFlags & GraphicsQueueBits) == GraphicsQueueBits)
                {
                    indices.GraphicsFamily = (uint)i;
                }

                var res = VkSurface.GetPhysicalDeviceSurfaceSupport(device, (uint)i, this.WindowSurface, out var presentSupport);

                if (res == Result.Success && presentSupport)
                {
                    indices.PresentFamily = (uint)i;
                }

                if (indices.IsComplete())
                {
                    break;
                }
            }
Beispiel #2
0
        public static uint FindSuitableQueueFamily(Vk api, PhysicalDevice physicalDevice, SurfaceKHR surface, out uint queueCount)
        {
            const QueueFlags RequiredFlags = QueueFlags.QueueGraphicsBit | QueueFlags.QueueComputeBit;

            var khrSurface = new KhrSurface(api.Context);

            uint propertiesCount;

            api.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &propertiesCount, null);

            QueueFamilyProperties[] properties = new QueueFamilyProperties[propertiesCount];

            fixed(QueueFamilyProperties *pProperties = properties)
            {
                api.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &propertiesCount, pProperties);
            }

            for (uint index = 0; index < propertiesCount; index++)
            {
                var queueFlags = properties[index].QueueFlags;

                khrSurface.GetPhysicalDeviceSurfaceSupport(physicalDevice, index, surface, out var surfaceSupported).ThrowOnError();

                if (queueFlags.HasFlag(RequiredFlags) && surfaceSupported)
                {
                    queueCount = properties[index].QueueCount;
                    return(index);
                }
            }

            queueCount = 0;
            return(InvalidIndex);
        }
Beispiel #3
0
        private static unsafe bool FindQueueFamilyIndices(PhysicalDevice physicalDevice, SurfaceKHR surface, out uint?graphicsQueueFamily, out uint?presentQueueFamily)
        {
            graphicsQueueFamily = presentQueueFamily = null;

            uint queueFamilyCount = 0;

            Vk.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyCount, null);
            Span <QueueFamilyProperties> props = stackalloc QueueFamilyProperties[(int)queueFamilyCount];

            Vk.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyCount, out props[0]);

            for (int i = 0; i < queueFamilyCount; i++)
            {
                QueueFamilyProperties prop = props[i];
                if (prop.QueueFlags.HasFlag(QueueFlags.QueueGraphicsBit) && !graphicsQueueFamily.HasValue)
                {
                    graphicsQueueFamily = (uint)i;
                }

                AssertVulkan(KhrSurface.GetPhysicalDeviceSurfaceSupport(physicalDevice, (uint)i, surface, out Bool32 supported));
                if (supported && !presentQueueFamily.HasValue)
                {
                    presentQueueFamily = (uint)i;
                }

                if (graphicsQueueFamily.HasValue && presentQueueFamily.HasValue)
                {
                    return(true);
                }
            }

            return(false);
        }
        private unsafe QueueFamilyIndices FindQueueFamilies(PhysicalDevice device)
        {
            var  indices          = new QueueFamilyIndices();
            uint queueFamilyCount = 0;

            _vk.GetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, (QueueFamilyProperties *)null);

            QueueFamilyProperties *queueFamilies = stackalloc QueueFamilyProperties[(int)queueFamilyCount];

            _vk.GetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies);

            for (uint i = 0; i < queueFamilyCount; i++)
            {
                QueueFamilyProperties queueFamily = queueFamilies[i];
                if (queueFamily.QueueFlags.HasFlag(QueueFlags.QueueGraphicsBit))
                {
                    indices.GraphicsFamily = i;
                }

                _vkSurface.GetPhysicalDeviceSurfaceSupport(device, i, _surface, out Bool32 presentSupport);

                if (presentSupport == Vk.True)
                {
                    indices.PresentFamily = i;
                }

                if (indices.IsComplete)
                {
                    break;
                }
            }

            return(indices);
        }
        private void CreateDevice()
        {
            QueueFamilyProperties[] queueProps = PhysicalDevice.GetQueueFamilyProperties();
            int computeFamilyIndex             = -1;
            int graphicsFamilyIndex            = -1;
            int sparseBindingFamilyIndex       = -1;
            int transferFamilyIndex            = -1;

            for (var i = 0; i < queueProps.Length; i++)
            {
                QueueFamilyProperties props = queueProps[i];

                if (computeFamilyIndex == -1 && props.QueueFlags.HasFlag(Queues.Compute))
                {
                    computeFamilyIndex = i;
                }

                if (graphicsFamilyIndex == -1 && props.QueueFlags.HasFlag(Queues.Graphics))
                {
                    graphicsFamilyIndex = i;
                }

                if (sparseBindingFamilyIndex == -1 && props.QueueFlags.HasFlag(Queues.SparseBinding))
                {
                    sparseBindingFamilyIndex = i;
                }

                if (transferFamilyIndex == -1 && props.QueueFlags.HasFlag(Queues.Transfer))
                {
                    transferFamilyIndex = i;
                }
            }

            var queueInfos = new[]
            {
                computeFamilyIndex,
                graphicsFamilyIndex,
                sparseBindingFamilyIndex,
                transferFamilyIndex
            }.Distinct().Select(i => new DeviceQueueCreateInfo(i, 1, 1.0f)).ToArray();

            string[] selectExtensions = new[] { Constant.DeviceExtension.ExtDebugMarker }
            .Where(AvailableDeviceExtensions.Contains)
            .ToArray();

            var createInfo = new DeviceCreateInfo(queueInfos, selectExtensions, PhysicalDeviceFeatures);

            Device = PhysicalDevice.CreateDevice(createInfo);

            ComputeQueue       = Device.GetQueue(computeFamilyIndex);
            GraphicsQueue      = Device.GetQueue(graphicsFamilyIndex);
            SparseBindingQueue = Device.GetQueue(sparseBindingFamilyIndex);
            TransferQueue      = Device.GetQueue(transferFamilyIndex);
        }
Beispiel #6
0
        void QueueFamilyProperties(QueueFamilyProperties queueFamilyProperties)
        {
            string flags = string.Empty;

            flags += queueFamilyProperties.QueueFlags.HasFlag(QueueFlags.Graphics) ? "G" : ".";
            flags += queueFamilyProperties.QueueFlags.HasFlag(QueueFlags.Compute) ? "C" : ".";
            flags += queueFamilyProperties.QueueFlags.HasFlag(QueueFlags.Transfer) ? "D" : ".";
            WriteLine($"QueueFlags         = {flags}");
            WriteLine($"QueueCount         = {queueFamilyProperties.QueueCount}");
            WriteLine($"TimestampValidBits = {queueFamilyProperties.TimestampValidBits}");
            WriteLine($"MinImageTransferGranularity = {Format(queueFamilyProperties.MinImageTransferGranularity)}");
        }
Beispiel #7
0
        public vksVulkanDevice(VkPhysicalDevice physicalDevice)
        {
            Debug.Assert(physicalDevice.Handle != IntPtr.Zero);
            PhysicalDevice = physicalDevice;

            // Store Properties features, limits and properties of the physical device for later use
            // Device properties also contain limits and sparse properties
            VkPhysicalDeviceProperties properties;

            vkGetPhysicalDeviceProperties(physicalDevice, out properties);
            Properties = properties;
            // Features should be checked by the examples before using them
            VkPhysicalDeviceFeatures features;

            vkGetPhysicalDeviceFeatures(physicalDevice, out features);
            Features = features;
            // Memory properties are used regularly for creating all kinds of buffers
            VkPhysicalDeviceMemoryProperties memoryProperties;

            vkGetPhysicalDeviceMemoryProperties(physicalDevice, out memoryProperties);
            MemoryProperties = memoryProperties;
            // Queue family properties, used for setting up requested queues upon device creation
            uint queueFamilyCount = 0;

            vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyCount, null);
            Debug.Assert(queueFamilyCount > 0);
            QueueFamilyProperties.Resize(queueFamilyCount);
            vkGetPhysicalDeviceQueueFamilyProperties(
                physicalDevice,
                &queueFamilyCount,
                (VkQueueFamilyProperties *)QueueFamilyProperties.Data.ToPointer());
            QueueFamilyProperties.Count = queueFamilyCount;

            // Get list of supported extensions
            uint extCount = 0;

            vkEnumerateDeviceExtensionProperties(physicalDevice, (byte *)null, ref extCount, null);
            if (extCount > 0)
            {
                VkExtensionProperties *extensions = stackalloc VkExtensionProperties[(int)extCount];
                if (vkEnumerateDeviceExtensionProperties(physicalDevice, (byte *)null, ref extCount, extensions) == VkResult.Success)
                {
                    for (uint i = 0; i < extCount; i++)
                    {
                        var ext = extensions[i];
                        // supportedExtensions.push_back(ext.extensionName);
                        // TODO: fixed-length char arrays are not being parsed correctly.
                    }
                }
            }
        }
Beispiel #8
0
        void AppGpuDumpQueuProps(AppGpu gpu, uint id, StreamWriter output)
        {
            QueueFamilyProperties props = gpu.QueueProps[id];

            output.WriteLine("VkQueueFamilyProperties[{0}]:", id);
            output.WriteLine("============================");
            output.WriteLine("\tqueueFlags         = {0}{1}{2}",
                             ((QueueFlags)props.QueueFlags & QueueFlags.Graphics) == QueueFlags.Graphics ? 'G' : '.',
                             ((QueueFlags)props.QueueFlags & QueueFlags.Compute) == QueueFlags.Compute ? 'C' : '.',
                             ((QueueFlags)props.QueueFlags & QueueFlags.Transfer) == QueueFlags.Transfer ? 'D' : '.');
            //((QueueFlags)props.QueueFlags & QueueFlags.SparseBinding) == QueueFlags.SparseBinding ? 'S' : '.'); // Add this option, not pressent in original
            output.WriteLine("\tqueueCount         = {0}", props.QueueCount);
            output.WriteLine("\ttimestampValidBits = {0}", props.TimestampValidBits);
            output.WriteLine("\tminImageTransferGranularity = ({0}, {1}, {2})",
                             props.MinImageTransferGranularity.Width,
                             props.MinImageTransferGranularity.Height,
                             props.MinImageTransferGranularity.Depth);
        }
Beispiel #9
0
        static int ScoreQueue(QueueFamilyProperties queueFamilyProperties, QueueFlags flags)
        {
            // Check if all flags are pressent
            if ((queueFamilyProperties.QueueFlags & flags) == flags)
            {
                int score = 256; // base score this was we can remove a lot and are still over 0

                int targetFlagCount = CountFlags((int)flags);
                int flagsCount      = CountFlags((int)queueFamilyProperties.QueueFlags);

                score -= flagsCount - targetFlagCount * 16;     // remove 16 for for overmaching the falgs
                score += (int)queueFamilyProperties.QueueCount; // add score for QueueCount;

                if (score <= 0)
                {
                    // always return minimum of 1 if it maches the flags
                    return(1);
                }
                return(score);
            }
            return(0);
        }
 public QueueFamilyPropertiesExt(QueueFamilyProperties child, uint queueIndex, PhysicalDevice physicalDevice)
 {
     QueueIndex     = queueIndex;
     Handle         = child;
     PhysicalDevice = physicalDevice;
 }
Beispiel #11
0
 /// <summary>
 /// Check if a queue family supports a queue type
 /// </summary>
 /// <param name="queueFamily"></param>
 /// <param name="type"></param>
 /// <returns></returns>
 public static bool Supports(QueueFamilyProperties queueFamily, Queues type)
 {
     return((queueFamily.QueueFlags & type) != 0);
 }
Beispiel #12
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);
        }
Beispiel #13
0
 internal unsafe void GetQueueFamilyProperties(ref uint queueFamilyPropertyCount, QueueFamilyProperties* queueFamilyProperties)
 {
     fixed (uint* __queueFamilyPropertyCount__ = &queueFamilyPropertyCount)
     {
         vkGetPhysicalDeviceQueueFamilyProperties(this, __queueFamilyPropertyCount__, queueFamilyProperties);
     }
 }
Beispiel #14
0
 internal static unsafe extern void vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice physicalDevice, uint* queueFamilyPropertyCount, QueueFamilyProperties* queueFamilyProperties);