internal Queue(Device device, uint family, uint index) { Device = device; Handle = device.Handle.GetDeviceQueue(family, index); FamilyIndex = family; FamilyProperties = Device.PhysicalDevice.Handle.GetQueueFamilyProperties()[(int)family]; }
private void GetQueueFamilyIndices() { uint queueFamilyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(_physicalDevice, ref queueFamilyCount, null); VkQueueFamilyProperties[] qfp = new VkQueueFamilyProperties[queueFamilyCount]; vkGetPhysicalDeviceQueueFamilyProperties(_physicalDevice, ref queueFamilyCount, out qfp[0]); bool foundGraphics = false; bool foundPresent = false; for (uint i = 0; i < qfp.Length; i++) { if ((qfp[i].queueFlags & VkQueueFlags.Graphics) != 0) { _graphicsQueueIndex = i; foundGraphics = true; } vkGetPhysicalDeviceSurfaceSupportKHR(_physicalDevice, i, _surface, out VkBool32 presentSupported); if (presentSupported) { _presentQueueIndex = i; foundPresent = true; } if (foundGraphics && foundPresent) { break; } } }
public SoftwarePhysicalDevice(SoftwareInstance instance) { m_Instance = instance; m_QueueFamilyProperties.Add(VkQueueFamilyProperties.Create(1, VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT)); m_QueueFamilyProperties.Add(VkQueueFamilyProperties.Create(1, VkQueueFlagBits.VK_QUEUE_COMPUTE_BIT)); m_ExtensionProperties.Add(VkExtensionProperties.Create(VkExtensionNames.VK_KHR_SWAPCHAIN_EXTENSION_NAME, 1)); m_PhysicalDeviceMemoryProperties = new VkPhysicalDeviceMemoryProperties(); m_PhysicalDeviceMemoryProperties.memoryTypeCount = 1; m_PhysicalDeviceMemoryProperties.memoryTypes = new VkMemoryType[] { new VkMemoryType() { heapIndex = 0, propertyFlags = VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT } }; m_PhysicalDeviceMemoryProperties.memoryHeapCount = 1; m_PhysicalDeviceMemoryProperties.memoryHeaps = new VkMemoryHeap[] { new VkMemoryHeap() { flags = VkMemoryHeapFlagBits.VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, size = 64 * 1024 * 1024 } }; }
public DummyPhysicalDevice(SoftwareInstance instance) { m_Instance = instance; m_QueueFamilyProperties.Add(VkQueueFamilyProperties.Create(1, VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT)); m_QueueFamilyProperties.Add(VkQueueFamilyProperties.Create(1, VkQueueFlagBits.VK_QUEUE_COMPUTE_BIT)); m_ExtensionProperties.Add(VkExtensionProperties.Create(VkExtensionNames.VK_KHR_SWAPCHAIN_EXTENSION_NAME, 1)); }
internal QueueFamily(VkQueueFamilyProperties prop, PhysicalDevice pDevice, uint index) { this.pDevice = pDevice; this.index = index; Flags = prop.queueFlags; QueueCount = prop.queueCount; TimestampValidBits = prop.timestampValidBits; MinImageTransferGranularity = prop.minImageTransferGranularity; }
public static ReadOnlySpan <VkQueueFamilyProperties> vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice) { uint queueFamilyPropertyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertyCount, null); ReadOnlySpan <VkQueueFamilyProperties> queueFamilyProperties = new VkQueueFamilyProperties[queueFamilyPropertyCount]; fixed(VkQueueFamilyProperties *queueFamilyPropertiesPtr = queueFamilyProperties) { vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertyCount, queueFamilyPropertiesPtr); } return(queueFamilyProperties); }
/// <summary> /// To query properties of queues available on a physical device, call: /// </summary> /// <returns>array of <see cref="VkQueueFamilyProperties"/> structures</returns> public VkQueueFamilyProperties[] GetQueueFamilyProperties() { unsafe { VkQueueFamilyProperties[] props; uint count = 0; do { props = new VkQueueFamilyProperties[count]; fixed(VkQueueFamilyProperties *pptr = props) vkGetPhysicalDeviceQueueFamilyProperties(this, &count, pptr); } while (props.Length != count); return(props); } }
unsafe void init() { // Gather physical Device memory properties IntPtr tmp = Marshal.AllocHGlobal(Marshal.SizeOf <VkPhysicalDeviceMemoryProperties>()); vkGetPhysicalDeviceMemoryProperties(phy, tmp); memoryProperties = Marshal.PtrToStructure <VkPhysicalDeviceMemoryProperties> (tmp); uint queueFamilyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, IntPtr.Zero); QueueFamilies = new VkQueueFamilyProperties[queueFamilyCount]; if (queueFamilyCount <= 0) { throw new Exception("No queues found for physical device"); } vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, QueueFamilies.Pin()); QueueFamilies.Unpin(); uint propCount = 0; vkEnumerateDeviceExtensionProperties(phy, IntPtr.Zero, out propCount, IntPtr.Zero); VkExtensionProperties[] extProps = new VkExtensionProperties[propCount]; vkEnumerateDeviceExtensionProperties(phy, IntPtr.Zero, out propCount, extProps.Pin()); extProps.Unpin(); for (int i = 0; i < extProps.Length; i++) { fixed(VkExtensionProperties *ep = extProps) { IntPtr n = (IntPtr)ep[i].extensionName; switch (Marshal.PtrToStringAnsi(n)) { case "VK_KHR_swapchain": HasSwapChainSupport = true; break; } } } }
/// <summary> /// Gets the queue families available on the passed device. /// </summary> /// <param name="device">The device to get the queue families on.</param> public static VkQueueFamilyProperties[] GetQueueFamilies(VkPhysicalDevice device) { if (!device) { throw new ArgumentNullException(nameof(device), "Cannot pass null device or device handle"); } uint famCount; device.GetPhysicalDeviceQueueFamilyProperties(&famCount, null); var fams = new VkQueueFamilyProperties[famCount]; fixed(VkQueueFamilyProperties *famPtr = fams) { device.GetPhysicalDeviceQueueFamilyProperties(&famCount, famPtr); } return(fams); }
private QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) { QueueFamilyIndices indices = new QueueFamilyIndices(); int queueFamilyCount = 0; Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(device, ref queueFamilyCount, null); VkQueueFamilyProperties[] queueFamilies = new VkQueueFamilyProperties[queueFamilyCount]; Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(device, ref queueFamilyCount, queueFamilies); int i = 0; foreach (var queueFamily in queueFamilies) { if (queueFamily.queueCount > 0 && (queueFamily.queueFlags & VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT) > 0) { indices.graphicsFamily = i; } bool presentSupport = false; Vulkan.vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, out presentSupport); if (queueFamily.queueCount > 0 && presentSupport) { indices.presentFamily = i; } if (indices.isComplete()) { break; } i++; } return(indices); }
internal PhysicalDevice(IntPtr vkPhy) { phy = vkPhy; // Gather physical Device memory properties IntPtr tmp = Marshal.AllocHGlobal(Marshal.SizeOf <VkPhysicalDeviceMemoryProperties> ()); vkGetPhysicalDeviceMemoryProperties(phy, tmp); memoryProperties = Marshal.PtrToStructure <VkPhysicalDeviceMemoryProperties> (tmp); Marshal.FreeHGlobal(tmp); vkGetPhysicalDeviceQueueFamilyProperties(phy, out uint queueFamilyCount, IntPtr.Zero); QueueFamilies = new VkQueueFamilyProperties [queueFamilyCount]; if (queueFamilyCount <= 0) { throw new Exception("No queues found for physical device"); } vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, QueueFamilies.Pin()); QueueFamilies.Unpin(); HasSwapChainSupport = GetDeviceExtensionSupported(Ext.D.VK_KHR_swapchain); }
static VkPhysicalDevice PickPhysicalDevice(VkInstance instance, VkSurfaceKHR surface, out uint queueFamilyIndex) { queueFamilyIndex = 0; uint deviceCount = 0; vkEnumeratePhysicalDevices(instance, &deviceCount, null); Console.WriteLine($"There are {deviceCount} devices available."); VkPhysicalDevice[] devices = new VkPhysicalDevice[deviceCount]; if (deviceCount <= 0) return(VkPhysicalDevice.Null); fixed(VkPhysicalDevice *ptr = &devices[0]) vkEnumeratePhysicalDevices(instance, &deviceCount, ptr); VkPhysicalDeviceProperties props = new VkPhysicalDeviceProperties(); for (int i = 0; i < deviceCount; i++) { bool badGpu = true; bool onlyPickDiscrete = true; vkGetPhysicalDeviceProperties(devices[i], &props); uint familyQueueCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &familyQueueCount, null); VkQueueFamilyProperties[] famProps = new VkQueueFamilyProperties[familyQueueCount]; fixed(VkQueueFamilyProperties *ptr = famProps) vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &familyQueueCount, ptr); VkPhysicalDeviceFeatures deviceFeatures; vkGetPhysicalDeviceFeatures(devices[i], &deviceFeatures); if (deviceFeatures.samplerAnisotropy == VkBool32.False) { continue; } for (uint k = 0; k < familyQueueCount; k++) { if ((int)(famProps[k].queueFlags & VkQueueFlags.Graphics) <= 0) { continue; } VkBool32 supported = VkBool32.False; Assert(vkGetPhysicalDeviceSurfaceSupportKHR(devices[i], k, surface, &supported)); if (supported == VkBool32.False) { continue; } /*fixed (VkPhysicalDevice* ptr = &(devices[i])) * if (!GLFW.Vulkan.GetPhysicalDevicePresentationSupport((IntPtr)(&instance), (IntPtr)ptr, k))//Throws exception * { * continue; * }*/ if (onlyPickDiscrete && !(props.deviceType == VkPhysicalDeviceType.DiscreteGpu)) { continue; } queueFamilyIndex = k; badGpu = false; } //Here we pick if its acceptable if (badGpu) { continue; } Console.WriteLine($"Picking GPU: {Marshal.PtrToStringUTF8((IntPtr)props.deviceName)}"); return(devices[i]); } throw new System.Exception("There was no GPU that filled our needs."); }
public unsafe void InitSurface(IntPtr sdlWindow) { VkResult err; // Create the os-specific Surface VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR(); surfaceCreateInfo.sType = Win32SurfaceCreateInfoKHR; var processHandle = Process.GetCurrentProcess().Handle;//.SafeHandle.DangerousGetHandle(); surfaceCreateInfo.hinstance = processHandle; surfaceCreateInfo.hwnd = sdlWindow; VkSurfaceKHR surface; err = vkCreateWin32SurfaceKHR(Instance, &surfaceCreateInfo, null, &surface); Surface = surface; // Get available queue family properties uint queueCount; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null); Debug.Assert(queueCount >= 1); var queueProps = new VkQueueFamilyProperties[queueCount]; fixed(VkQueueFamilyProperties *pointer = queueProps) { vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, pointer); } // Iterate over each queue to learn whether it supports presenting: // Find a queue with present support // Will be used to present the swap chain Images to the windowing system VkBool32 *supportsPresent = stackalloc VkBool32[(int)queueCount]; for (uint i = 0; i < queueCount; i++) { vkGetPhysicalDeviceSurfaceSupportKHR(PhysicalDevice, i, Surface, &supportsPresent[i]); } // Search for a graphics and a present queue in the array of queue // families, try to find one that supports both uint graphicsQueueNodeIndex = uint.MaxValue; uint presentQueueNodeIndex = uint.MaxValue; for (uint i = 0; i < queueCount; i++) { if ((queueProps[i].queueFlags & VkQueueFlagBits.Graphics) != 0) { if (graphicsQueueNodeIndex == uint.MaxValue) { graphicsQueueNodeIndex = i; } if (supportsPresent[i] == true) { graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; } } } if (presentQueueNodeIndex == uint.MaxValue) { // If there's no queue that supports both present and graphics // try to find a separate present queue for (uint i = 0; i < queueCount; ++i) { if (supportsPresent[i] == true) { presentQueueNodeIndex = i; break; } } } // Exit if either a graphics or a presenting queue hasn't been found if (graphicsQueueNodeIndex == uint.MaxValue || presentQueueNodeIndex == uint.MaxValue) { throw new InvalidOperationException("Could not find a graphics and/or presenting queue!"); } // todo : Add support for separate graphics and presenting queue if (graphicsQueueNodeIndex != presentQueueNodeIndex) { throw new InvalidOperationException("Separate graphics and presenting queues are not supported yet!"); } QueueNodeIndex = graphicsQueueNodeIndex; // Get list of supported Surface formats uint formatCount; err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, null); Debug.Assert(err == VkResult.Success); Debug.Assert(formatCount > 0); var surfaceFormats = new VkSurfaceFormatKHR[formatCount]; fixed(VkSurfaceFormatKHR *pointer = surfaceFormats) { err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, pointer); Debug.Assert(err == VkResult.Success); } // If the Surface format list only includes one entry with VK_FORMAT_UNDEFINED, // there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM if ((formatCount == 1) && (surfaceFormats[0].format == VkFormat.Undefined)) { ColorFormat = VkFormat.B8g8r8a8Unorm; ColorSpace = surfaceFormats[0].colorSpace; } else { // iterate over the list of available Surface format and // check for the presence of VK_FORMAT_B8G8R8A8_UNORM bool found_B8G8R8A8_UNORM = false; foreach (var surfaceFormat in surfaceFormats) { if (surfaceFormat.format == VkFormat.B8g8r8a8Unorm) { ColorFormat = surfaceFormat.format; ColorSpace = surfaceFormat.colorSpace; found_B8G8R8A8_UNORM = true; break; } } // in case VK_FORMAT_B8G8R8A8_UNORM is not available // select the first available color format if (!found_B8G8R8A8_UNORM) { ColorFormat = surfaceFormats[0].format; ColorSpace = surfaceFormats[0].colorSpace; } } }
static void Main(string[] args) { VkInstance inst; using (VkApplicationInfo ai = new VkApplicationInfo()) { using (VkInstanceCreateInfo ci = new VkInstanceCreateInfo { pApplicationInfo = ai }){ CheckResult(vkCreateInstance(ci, IntPtr.Zero, out inst)); } } Vk.LoadInstanceFunctionPointers(inst); if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.DiscreteGpu, out VkPhysicalDevice phy)) { if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.IntegratedGpu, out phy)) { if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.Cpu, out phy)) { throw new Exception("no suitable physical device found"); } } } foreach (VkPhysicalDeviceToolPropertiesEXT toolProp in GetToolProperties(phy)) { Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine($"Enabled Tool: {toolProp.name}({toolProp.version})"); Console.ResetColor(); } vkGetPhysicalDeviceQueueFamilyProperties(phy, out uint queueFamilyCount, IntPtr.Zero); VkQueueFamilyProperties[] qFamProps = new VkQueueFamilyProperties[queueFamilyCount]; vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, qFamProps.Pin()); qFamProps.Unpin(); Console.WriteLine($"Queues:"); for (int i = 0; i < queueFamilyCount; i++) { Console.WriteLine($"\t{i}: {qFamProps[i].queueFlags,-60} ({qFamProps[i].queueCount})"); } uint qFamIndex = (uint)qFamProps.Select((qFam, index) => (qFam, index)) .First(qfp => qfp.qFam.queueFlags.HasFlag(VkQueueFlags.Graphics)).index; VkDevice dev = default; float[] priorities = { 0 }; using (VkDeviceQueueCreateInfo qInfo = new VkDeviceQueueCreateInfo(qFamIndex, 1, priorities)) { using (VkDeviceCreateInfo deviceCreateInfo = new VkDeviceCreateInfo() { pQueueCreateInfos = qInfo }) { CheckResult(vkCreateDevice(phy, deviceCreateInfo, IntPtr.Zero, out dev)); } } vkGetDeviceQueue(dev, qFamIndex, 0, out VkQueue gQ); vkDestroyDevice(dev, IntPtr.Zero); vkDestroyInstance(inst, IntPtr.Zero); }