コード例 #1
0
        AppGpu AppGpuInit(uint id, PhysicalDevice obj)
        {
            // TODO : Limits

            AppGpu gpu = new AppGpu
            {
                Id          = id,
                Obj         = obj,
                Props       = obj.GetProperties(),
                QueueProps  = obj.GetQueueFamilyProperties(),
                MemoryProps = obj.GetMemoryProperties(),
                Features    = obj.GetFeatures(),
                Limits      = null,
            };

            gpu.QueueReqs = new DeviceQueueCreateInfo[gpu.QueueProps.Length];
            for (uint i = 0; i < gpu.QueueProps.Length; i++)
            {
                uint queueCount = gpu.QueueProps[i].QueueCount;
                DeviceQueueCreateInfo queueReq = new DeviceQueueCreateInfo
                {
                    QueueFamilyIndex = i,
                    QueueCount       = queueCount,
                    QueuePriorities  = new float[queueCount],
                };
                gpu.QueueReqs[i] = queueReq;
            }

            gpu.Device = AppDevInit(gpu);
            AppDevInitFormats(gpu.Device);

            return(gpu);
        }
コード例 #2
0
        public static bool TrySelectQueue(PhysicalDevice physicalDevice, QueueFlags flags, bool present, out uint selectedIndex)
        {
            if (QueueFamilyPropertiesCachePhysicalDevice != physicalDevice)
            {
                QueueFamilyPropertiesCachePhysicalDevice = physicalDevice;
                QueueFamilyPropertiesCache = physicalDevice.GetQueueFamilyProperties();
            }

            selectedIndex = 0;
            int  score = 0;
            uint i     = 0;

            foreach (QueueFamilyProperties test in QueueFamilyPropertiesCache)
            {
                /*foreach(SurfaceFormatKhr format in physicalDevice.GetSurfaceFormatsKHR())
                 * {
                 *
                 * }
                 * physicalDevice.GetSurfaceSupportKHR(i);*/

                int checkScore = ScoreQueue(test, flags);
                if (checkScore > score)
                {
                    selectedIndex = i;
                    score         = checkScore;
                }
                i++;
            }
            return(score > 0);
        }
コード例 #3
0
        private (uint, uint) FindQueueFamilies()
        {
            var queueFamilyProperties = PhysicalDevice.GetQueueFamilyProperties();

            var graphicsFamily = queueFamilyProperties
                                 .Select((properties, index) => new { properties, index })
                                 .SkipWhile(pair => !pair.properties.QueueFlags.HasFlag(QueueFlags.Graphics))
                                 .FirstOrDefault();

            if (graphicsFamily == null)
            {
                throw new Exception("Unable to find graphics queue");
            }

            uint?presentFamily = default;

            for (uint i = 0; i < queueFamilyProperties.Length; ++i)
            {
                if (PhysicalDevice.GetSurfaceSupport(i, Surface))
                {
                    presentFamily = i;
                }
            }

            if (!presentFamily.HasValue)
            {
                throw new Exception("Unable to find present queue");
            }

            return((uint)graphicsFamily.index, presentFamily.Value);
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: CloneDeath/Illustrate
        private static void PrintDeviceInformation(PhysicalDevice physicalDevice)
        {
            var properties = physicalDevice.GetProperties();

            Console.WriteLine($"Driver Version: {properties.DriverVersion}");
            Console.WriteLine($"Device Name:    {properties.DeviceName}");
            Console.WriteLine($"Device Type:    {properties.DeviceType}");
            Console.WriteLine($"Api Version:    {Version.ToString(properties.ApiVersion)}");

            foreach (var queueFamilyProperties in physicalDevice.GetQueueFamilyProperties())
            {
                Console.WriteLine($"Count of Queues: {queueFamilyProperties.QueueCount}");
                Console.WriteLine("Supported operations on this queue: ");
                if (queueFamilyProperties.QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    Console.WriteLine("\t\tGraphics");
                }
                if (queueFamilyProperties.QueueFlags.HasFlag(QueueFlags.Compute))
                {
                    Console.WriteLine("\t\tCompute");
                }
                if (queueFamilyProperties.QueueFlags.HasFlag(QueueFlags.Transfer))
                {
                    Console.WriteLine("\t\tTransfer");
                }
                if (queueFamilyProperties.QueueFlags.HasFlag(QueueFlags.SparseBinding))
                {
                    Console.WriteLine("\t\tSparse Binding");
                }
            }
        }
コード例 #5
0
        public QueueFamilyIndices(PhysicalDevice device, SurfaceKhr surface)
        {
            int graphicsIndex = -1;
            int presentIndex  = -1;

            int i      = 0;
            var queues = device.GetQueueFamilyProperties();

            foreach (var f in queues)
            {
                if (graphicsIndex < 0 && f.QueueCount > 0 && (f.QueueFlags & QueueFlags.Graphics) != 0)
                {
                    graphicsIndex = i;
                }

                if (presentIndex < 0 && f.QueueCount > 0 && device.GetSurfaceSupportKHR((uint)i, surface))
                {
                    presentIndex = i;
                }

                ++i;
            }

            GraphicsFamily = graphicsIndex;
            PresentFamily  = presentIndex;
        }
コード例 #6
0
        static void CreateDevice()
        {
            var queueCreateInfo = new DeviceQueueCreateInfo
            {
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = 0,
            };

            var deviceEnabledExtensions = new[]
            {
                "VK_KHR_swapchain",
            };

            var deviceCreateInfo = new DeviceCreateInfo
            {
                QueueCreateInfoCount  = 1,
                QueueCreateInfos      = queueCreateInfo,
                EnabledExtensionNames = deviceEnabledExtensions,
            };

            device = physicalDevice.CreateDevice(deviceCreateInfo, null);
            Console.WriteLine("[ OK ] Device");

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

            queue = device.GetQueue(0, (uint)queueNodeIndex);
            Console.WriteLine("[ OK ] Queue");
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: yongweisun/SharpVk-Samples
        private QueueFamilyIndices FindQueueFamilies(PhysicalDevice device)
        {
            QueueFamilyIndices indices = new QueueFamilyIndices();

            var queueFamilies = device.GetQueueFamilyProperties();

            for (uint index = 0; index < queueFamilies.Length && !indices.IsComplete; index++)
            {
                if (queueFamilies[index].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    indices.GraphicsFamily = index;
                }

                if (device.GetSurfaceSupport(index, this.surface))
                {
                    indices.PresentFamily = index;
                }

                if (queueFamilies[index].QueueFlags.HasFlag(QueueFlags.Transfer) && !queueFamilies[index].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    indices.TransferFamily = index;
                }
            }

            if (!indices.TransferFamily.HasValue)
            {
                indices.TransferFamily = indices.GraphicsFamily;
            }

            return(indices);
        }
コード例 #8
0
ファイル: VulkanInfo.cs プロジェクト: jcoder58/Tanagra
        public void Write(PhysicalDevice physicalDevice)
        {
            WriteLine("PhysicalDeviceProperties:");
            WriteLine("=========================");
            var properties = physicalDevice.GetProperties();

            _tabs++;
            PhysicalDeviceProperties(properties);

            WriteLine("PhysicalDeviceLimits:");
            WriteLine("---------------------");
            var limits = properties.Limits;

            _tabs++;
            PhysicalDeviceLimits(limits);

            _tabs--;
            WriteLine("PhysicalDeviceSparseProperties:");
            WriteLine("-------------------------------");
            var sparse = properties.SparseProperties;

            _tabs++;
            PhysicalDeviceSparseProperties(sparse);

            _tabs = 0;
            WriteLine("");
            var queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();

            for (int x = 0; x < queueFamilyProperties.Length; x++)
            {
                WriteLine($"QueueFamilyProperties[{x}]:");
                WriteLine("==========================");
                _tabs++;
                QueueFamilyProperties(queueFamilyProperties[x]);
                _tabs--;
                WriteLine("");
            }

            _tabs = 0;
            WriteLine("PhysicalDeviceMemoryProperties");
            WriteLine("==============================");
            var physicalDeviceMemoryProperties = physicalDevice.GetMemoryProperties();

            _tabs++;
            PhysicalDeviceMemoryProperties(physicalDeviceMemoryProperties);
            WriteLine("");

            _tabs = 0;
            WriteLine("PhysicalDeviceFeatures:");
            WriteLine("=======================");
            var features = physicalDevice.GetFeatures();

            _tabs++;
            PhysicalDeviceFeatures(features);

            Console.WriteLine(_sb.ToString());
        }
コード例 #9
0
        Queue GetQueue(PhysicalDevice physicalDevice, uint queueFamily)
        {
            var queueNodeIndex = physicalDevice.GetQueueFamilyProperties()
                                 .Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0)
                                 .Select((properties, index) => index)
                                 .First();

            return(device.GetQueue(queueFamily, (uint)queueNodeIndex));
        }
コード例 #10
0
        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);
        }
コード例 #11
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));
        }
コード例 #12
0
        public void CreateDevice()
        {
            // Required in order to keep the validation layer happy :)
            PhysicalDevice.GetQueueFamilyProperties();

            var createInfo = new DeviceCreateInfo(new[]
            {
                new DeviceQueueCreateInfo(0, 1, 1.0f)
            });

            using (PhysicalDevice.CreateDevice(createInfo)) { }
            using (PhysicalDevice.CreateDevice(createInfo, CustomAllocator)) { }
        }
コード例 #13
0
ファイル: GraphicsManager.cs プロジェクト: Ciastex/Prisma
        private void InitializeVulkan(PhysicalDevice physDev, SurfaceKhr surface)
        {
            var  queueFamilyProperties = physDev.GetQueueFamilyProperties();
            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physDev.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }
                if (queueFamilyProperties[queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo
            {
                QueuePriorities  = new[] { 1.0f },
                QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo
            {
                EnabledExtensionNames = new[]
                {
                    "VK_KHR_swapchain",
                },
                QueueCreateInfos = new[] { queueInfo }
            };

            _device = physDev.CreateDevice(deviceInfo);

            _queue = _device.GetQueue(0, 0);
            _surfaceCapabilities = physDev.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectSurfaceFormat(physDev, surface);

            _swapchainKhr = CreateSwapchainKhr(surface, surfaceFormat);
            _images       = _device.GetSwapchainImagesKHR(_swapchainKhr);
            _renderPass   = CreateRenderPass(surfaceFormat);
            _framebuffers = CreateFramebuffers(_images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            _fence = _device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            _semaphore      = _device.CreateSemaphore(semaphoreInfo);
            _commandBuffers = CreateCommandBuffers(_images, _framebuffers, _renderPass, _surfaceCapabilities);
        }
コード例 #14
0
        public static uint GetIndexOfFirstAvailablePresentQueueFamily(this PhysicalDevice @this, SurfaceKhr surface)
        {
            var queueFamilies = @this.GetQueueFamilyProperties();

            for (uint i = 0; i < queueFamilies.Length; i++)
            {
                if (@this.GetSurfaceSupportKHR(i, surface))
                {
                    return(i);
                }
            }

            throw new VulkanException($"Could not find a queue family on device {@this.GetName()} that can present to given surface");
        }
コード例 #15
0
        public static uint GetIndexOfFirstAvailableGraphicsQueueFamily(this PhysicalDevice @this)
        {
            var queueFamilies = @this.GetQueueFamilyProperties();

            for (uint i = 0; i < queueFamilies.Length; i++)
            {
                if (queueFamilies[i].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    return(i);
                }
            }

            throw new VulkanException("Could not find a graphics queue family for device " + @this.GetName());
        }
コード例 #16
0
        static public uint FindBestComputeQueue(PhysicalDevice physicalDevice)
        {
            uint i = 0;

            foreach (var queueFamily in physicalDevice.GetQueueFamilyProperties())
            {
                var maskedFlages = (QueueFlags.Transfer | QueueFlags.Compute) & queueFamily.QueueFlags;

                if (maskedFlages == QueueFlags.Compute)
                {
                    return(i);
                }
                i++;
            }

            return(~0U);
        }
コード例 #17
0
        public virtual void Initialize(PhysicalDevice physicalDevice, SurfaceKhr surface)
        {
            var queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();

            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physicalDevice.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }

                if (queueFamilyProperties [queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo {
                QueuePriorities = new float [] { 1.0f }, QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo {
                EnabledExtensionNames = new string [] { "VK_KHR_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectFormat(physicalDevice, surface);

            swapchain    = CreateSwapchain(surface, surfaceFormat);
            images       = device.GetSwapchainImagesKHR(swapchain);
            renderPass   = CreateRenderPass(surfaceFormat);
            framebuffers = CreateFramebuffers(images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            fence = device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
コード例 #18
0
        public static void PrintQueueFamilies(this PhysicalDevice @this)
        {
            var queueFamilyProperties = @this.GetQueueFamilyProperties();

            _logger.LogInfo($"Queue families from device {@this.GetName()}:");

            for (int i = 0; i < queueFamilyProperties.Length; i++)
            {
                var family = queueFamilyProperties[i];
                _logger.LogInfo("\tFamily " + i + ":");
                _logger.LogInfo("\t\tCount: " + family.QueueCount);
                _logger.LogInfo("\t\tFlags: " + family.QueueFlags);
                _logger.LogInfo("\t\tTimestampValidBits: " + family.TimestampValidBits);
                _logger.LogInfo("\t\tMinImageTransferGranularity:");
                _logger.LogInfo($"\t\t\tWidth: {family.MinImageTransferGranularity.Width}");
                _logger.LogInfo($"\t\t\tHeight: {family.MinImageTransferGranularity.Height}");
                _logger.LogInfo($"\t\t\tDepth: {family.MinImageTransferGranularity.Depth}");
            }
        }
コード例 #19
0
ファイル: QueueTest.cs プロジェクト: yongweisun/VulkanCore
        public void PropertiesSet()
        {
            QueueFamilyProperties[] props = PhysicalDevice.GetQueueFamilyProperties();
            int queueFamilyIndex          = props.Length - 1;
            int queueCount       = props[props.Length - 1].QueueCount;
            int queueIndex       = queueCount - 1;
            var deviceCreateInfo = new DeviceCreateInfo(new[]
            {
                new DeviceQueueCreateInfo(queueFamilyIndex, queueCount, Enumerable.Range(0, queueCount).Select(_ => 1.0f).ToArray())
            });

            using (Device device = PhysicalDevice.CreateDevice(deviceCreateInfo))
            {
                Queue queue = device.GetQueue(queueFamilyIndex, queueIndex);

                Assert.Equal(device, queue.Parent);
                Assert.Equal(queueFamilyIndex, queue.FamilyIndex);
                Assert.Equal(queueIndex, queue.Index);
            }
        }
コード例 #20
0
ファイル: MeteoraWindow.cs プロジェクト: Amatsugu/Meteora
        private QueueFamilyIndices FindQueueFamilies(PhysicalDevice device)
        {
            var queueFamilyProperties = device.GetQueueFamilyProperties();
            var queueFamilyIndices    = new QueueFamilyIndices();

            for (int queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; queueFamilyUsedIndex++)
            {
                //Check Present Support
                if (device.GetSurfaceSupportKHR((uint)queueFamilyUsedIndex, data.surface))
                {
                    queueFamilyIndices.PresentFamily = queueFamilyUsedIndex;
                }
                //Check Graphics Support
                if (queueFamilyProperties[queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    queueFamilyIndices.GraphicsFamily = queueFamilyUsedIndex;
                }
            }
            return(queueFamilyIndices);
        }
コード例 #21
0
        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);
        }
コード例 #22
0
        public static QueueFamilyIndices _FindQueueFamilies(PhysicalDevice device, Surface surface)
        {
            QueueFamilyIndices indices = new QueueFamilyIndices();

            var queueFamilies = device.GetQueueFamilyProperties();

            for (uint index = 0; index < queueFamilies.Length && !indices.IsComplete; index++)
            {
                if (queueFamilies[index].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    indices.GraphicsFamily = index;
                }

                if (device.GetSurfaceSupport(index, surface))
                {
                    indices.PresentFamily = index;
                }
            }

            return(indices);
        }
コード例 #23
0
        public static QueueFamilyPropertiesExt[] GetQueueFamilyPropertiesExt(this PhysicalDevice self)
        {
            var queueProperties = self.GetQueueFamilyProperties();

            return(queueProperties.Select((q, i) => new QueueFamilyPropertiesExt(q, (uint)i, self)).ToArray());
        }
コード例 #24
0
 public void GetQueueFamilyProperties()
 {
     QueueFamilyProperties[] properties = PhysicalDevice.GetQueueFamilyProperties();
     Assert.True(properties.Length > 0);
 }
コード例 #25
0
 /// <summary>
 /// Get whether a physical device meets requirement features and capabilities
 /// </summary>
 /// <param name="device"></param>
 /// <returns></returns>
 private static bool GetDeviceMeetsRequirements(PhysicalDevice device, SurfaceKhr surface)
 {
     // Argument checks
     if (device is null)
     {
         throw new ArgumentNullException(nameof(device));
     }
     if (surface is null)
     {
         throw new ArgumentNullException(nameof(surface));
     }
     // Check device features
     {
         var features = device.GetFeatures();
         if (!features.SamplerAnisotropy)
         {
             return(false);
         }
         var limits = device.GetProperties().Limits;
         if (limits.MaxVertexInputAttributes < 16)
         {
             return(false);
         }
         if (limits.MaxUniformBufferRange < sizeof(float) * 4 * 254)
         {
             return(false);
         }
         if (limits.MaxVertexInputBindings < 2)
         {
             return(false);
         }
         if (limits.MaxPointSize <= 1)
         {
             return(false);
         }
     }
     // Check queue families
     {
         var families = device.GetQueueFamilyProperties();
         // Graphics, compute, transfer
         {
             if (families.Count(family => QueueFamily.Supports(family, Queues.Graphics)) == 0 ||
                 families.Count(family => QueueFamily.Supports(family, Queues.Compute)) == 0 ||
                 families.Count(family => QueueFamily.Supports(family, Queues.Transfer)) == 0)
             {
                 return(false);
             }
         }
         // Present
         {
             var foundPresent = false;
             for (var i = 0; i < families.Length; i++)
             {
                 if (QueueFamily.SupportsPresenting(i, device, surface))
                 {
                     foundPresent = true;
                     break;
                 }
             }
             if (!foundPresent)
             {
                 return(false);
             }
         }
     }
     return(true);
 }