summaryrefslogtreecommitdiffstats
path: root/tools/vk/vk_probe2.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/vk/vk_probe2.py')
-rw-r--r--tools/vk/vk_probe2.py141
1 files changed, 141 insertions, 0 deletions
diff --git a/tools/vk/vk_probe2.py b/tools/vk/vk_probe2.py
new file mode 100644
index 0000000..557b888
--- /dev/null
+++ b/tools/vk/vk_probe2.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python3
+# vk_probe2.py - Vulkan probe stage 2: create a logical device + queue on the
+# NVIDIA physical device. Prints the queue-family table and the create
+# result. ctypes only, no dev headers.
+import ctypes
+import sys
+
+VK_SUCCESS = 0
+VK_STRUCTURE_TYPE_APPLICATION_INFO = 0
+VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1
+VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2
+VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3
+VK_API_VERSION_1_2 = (1 << 22) | (2 << 12)
+
+vulkan = ctypes.CDLL("libvulkan.so.1")
+
+
+class VkApplicationInfo(ctypes.Structure):
+ _fields_ = [
+ ("sType", ctypes.c_int),
+ ("pNext", ctypes.c_void_p),
+ ("pApplicationName", ctypes.c_char_p),
+ ("applicationVersion", ctypes.c_uint32),
+ ("pEngineName", ctypes.c_char_p),
+ ("engineVersion", ctypes.c_uint32),
+ ("apiVersion", ctypes.c_uint32),
+ ]
+
+
+class VkInstanceCreateInfo(ctypes.Structure):
+ _fields_ = [
+ ("sType", ctypes.c_int),
+ ("pNext", ctypes.c_void_p),
+ ("flags", ctypes.c_uint32),
+ ("pApplicationInfo", ctypes.POINTER(VkApplicationInfo)),
+ ("enabledLayerCount", ctypes.c_uint32),
+ ("ppEnabledLayerNames", ctypes.c_void_p),
+ ("enabledExtensionCount", ctypes.c_uint32),
+ ("ppEnabledExtensionNames", ctypes.c_void_p),
+ ]
+
+
+class VkQueueFamilyProperties(ctypes.Structure):
+ _fields_ = [
+ ("queueFlags", ctypes.c_uint32),
+ ("queueCount", ctypes.c_uint32),
+ ("timestampValidBits", ctypes.c_uint32),
+ ("minImageTransferGranularity", ctypes.c_uint8 * 12),
+ ]
+
+
+class VkDeviceQueueCreateInfo(ctypes.Structure):
+ _fields_ = [
+ ("sType", ctypes.c_int),
+ ("pNext", ctypes.c_void_p),
+ ("flags", ctypes.c_uint32),
+ ("queueFamilyIndex", ctypes.c_uint32),
+ ("queueCount", ctypes.c_uint32),
+ ("pQueuePriorities", ctypes.POINTER(ctypes.c_float)),
+ ]
+
+
+class VkDeviceCreateInfo(ctypes.Structure):
+ _fields_ = [
+ ("sType", ctypes.c_int),
+ ("pNext", ctypes.c_void_p),
+ ("flags", ctypes.c_uint32),
+ ("queueCreateInfoCount", ctypes.c_uint32),
+ ("pQueueCreateInfos", ctypes.POINTER(VkDeviceQueueCreateInfo)),
+ ("enabledLayerCount", ctypes.c_uint32),
+ ("ppEnabledLayerNames", ctypes.c_void_p),
+ ("enabledExtensionCount", ctypes.c_uint32),
+ ("ppEnabledExtensionNames", ctypes.c_void_p),
+ ("pEnabledFeatures", ctypes.c_void_p),
+ ]
+
+
+app = VkApplicationInfo(VK_STRUCTURE_TYPE_APPLICATION_INFO, None, b"vk_probe2",
+ 1, b"vk_probe2", 1, VK_API_VERSION_1_2)
+ci = VkInstanceCreateInfo(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, None, 0,
+ ctypes.pointer(app), 0, None, 0, None)
+inst = ctypes.c_void_p()
+r = vulkan.vkCreateInstance(ctypes.byref(ci), None, ctypes.byref(inst))
+print("INSTANCE rc=%d" % r)
+if r != 0:
+ sys.exit(1)
+
+n = ctypes.c_uint32(0)
+vulkan.vkEnumeratePhysicalDevices(inst, ctypes.byref(n), None)
+devs = (ctypes.c_void_p * n.value)()
+vulkan.vkEnumeratePhysicalDevices(inst, ctypes.byref(n), devs)
+
+# pick the NVIDIA device by name
+best = None
+for i in range(n.value):
+ buf = ctypes.create_string_buffer(4096)
+ vulkan.vkGetPhysicalDeviceProperties(devs[i], buf)
+ raw = buf.raw
+ name = raw[20:276].split(b"\x00")[0].decode("utf-8", "replace")
+ print("PROPS dev=%d head=%s name=%r" % (i, raw[:40].hex(), name))
+ if "NVIDIA" in name or "llvmpipe" in name:
+ if "NVIDIA" in name:
+ best = devs[i]
+ print("PICK NVIDIA dev=%d name=%s" % (i, name))
+ break
+if best is None:
+ print("NO_NVIDIA")
+ sys.exit(2)
+
+nfam = ctypes.c_uint32(0)
+vulkan.vkGetPhysicalDeviceQueueFamilyProperties(best, ctypes.byref(nfam),
+ None)
+fams = (VkQueueFamilyProperties * nfam.value)()
+vulkan.vkGetPhysicalDeviceQueueFamilyProperties(best, ctypes.byref(nfam),
+ fams)
+gfam = None
+for j in range(nfam.value):
+ print("QFAM %d flags=0x%x count=%d" % (j, fams[j].queueFlags,
+ fams[j].queueCount))
+ if (fams[j].queueFlags & 0x1) and fams[j].queueCount > 0 and gfam is None:
+ gfam = j
+if gfam is None:
+ print("NO_GRAPHICS_QUEUE")
+ sys.exit(3)
+prio = ctypes.c_float(1.0)
+qci = VkDeviceQueueCreateInfo(VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+ None, 0, gfam, 1, ctypes.pointer(prio))
+dci = VkDeviceCreateInfo(VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, None, 0, 1,
+ ctypes.pointer(qci), 0, None, 0, None, None)
+dev = ctypes.c_void_p()
+r = vulkan.vkCreateDevice(best, ctypes.byref(dci), None, ctypes.byref(dev))
+print("vkCreateDevice rc=%d (0x%x)" % (r, r if r < 0 else 0))
+if r != 0:
+ sys.exit(4)
+queue = ctypes.c_void_p()
+vulkan.vkGetDeviceQueue(dev, gfam, 0, ctypes.byref(queue))
+print("QUEUE device=%s queue=%s" % (bool(dev), bool(queue)))
+# optional: wait-idle (exercises the queue)
+vulkan.vkDeviceWaitIdle(dev)
+print("VK2_DEVICE_OK")
+sys.exit(0) \ No newline at end of file