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; } }
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); }
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); }
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)}"); }
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. } } } }
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); }
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; }
/// <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); }
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); }
internal unsafe void GetQueueFamilyProperties(ref uint queueFamilyPropertyCount, QueueFamilyProperties* queueFamilyProperties) { fixed (uint* __queueFamilyPropertyCount__ = &queueFamilyPropertyCount) { vkGetPhysicalDeviceQueueFamilyProperties(this, __queueFamilyPropertyCount__, queueFamilyProperties); } }
internal static unsafe extern void vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice physicalDevice, uint* queueFamilyPropertyCount, QueueFamilyProperties* queueFamilyProperties);