comparison semiconginev2/old/vulkan/physicaldevice.nim @ 1218:56781cc0fc7c compiletime-tests

did: renamge main package
author sam <sam@basx.dev>
date Wed, 17 Jul 2024 21:01:37 +0700
parents semicongine/old/vulkan/physicaldevice.nim@a3eb305bcac2
children
comparison
equal deleted inserted replaced
1217:f819a874058f 1218:56781cc0fc7c
1 from std/enumerate import enumerate
2 import std/tables
3 import std/sequtils
4
5 import ../core
6 import ./instance
7
8 type
9 PhysicalDevice* = object
10 vk*: VkPhysicalDevice
11 name*: string
12 devicetype*: VkPhysicalDeviceType
13 surface*: VkSurfaceKHR
14 properties*: VkPhysicalDeviceProperties
15 features*: VkPhysicalDeviceFeatures2
16 QueueFamily* = object
17 device: PhysicalDevice
18 properties*: VkQueueFamilyProperties
19 index*: uint32
20 flags*: seq[VkQueueFlagBits]
21
22 func `$`*(device: PhysicalDevice): string =
23 "Physical device: vk=" & $device.vk & ", name=" & $device.name & ", devicetype=" & $device.devicetype
24
25 proc GetPhysicalDevices*(instance: Instance): seq[PhysicalDevice] =
26 assert instance.vk.Valid
27 assert instance.surface.Valid
28 var nDevices: uint32
29 checkVkResult vkEnumeratePhysicalDevices(instance.vk, addr(nDevices), nil)
30 var devices = newSeq[VkPhysicalDevice](nDevices)
31 checkVkResult vkEnumeratePhysicalDevices(instance.vk, addr(nDevices), devices.ToCPointer)
32 for i in 0 ..< nDevices:
33 var device = PhysicalDevice(vk: devices[i], surface: instance.surface)
34 device.vk.vkGetPhysicalDeviceProperties(addr device.properties)
35 device.features.stype = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2
36 device.vk.vkGetPhysicalDeviceFeatures2(addr device.features)
37 device.name = device.properties.deviceName.CleanString()
38 device.devicetype = device.properties.deviceType
39 result.add device
40
41 proc GetExtensions*(device: PhysicalDevice): seq[string] =
42 assert device.vk.Valid
43 var extensionCount: uint32
44 checkVkResult vkEnumerateDeviceExtensionProperties(device.vk, nil, addr(extensionCount), nil)
45 if extensionCount > 0:
46 var extensions = newSeq[VkExtensionProperties](extensionCount)
47 checkVkResult vkEnumerateDeviceExtensionProperties(device.vk, nil, addr(extensionCount), extensions.ToCPointer)
48 for extension in extensions:
49 result.add(CleanString(extension.extensionName))
50
51 proc GetSurfaceCapabilities*(device: PhysicalDevice): VkSurfaceCapabilitiesKHR =
52 assert device.vk.Valid
53 assert device.surface.Valid
54 checkVkResult device.vk.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device.surface, addr(result))
55
56 proc GetSurfaceFormats*(device: PhysicalDevice): seq[VkSurfaceFormatKHR] =
57 assert device.vk.Valid
58 assert device.surface.Valid
59 var n_formats: uint32
60 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device.vk, device.surface, addr(n_formats), nil)
61 result = newSeq[VkSurfaceFormatKHR](n_formats)
62 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device.vk, device.surface, addr(n_formats), result.ToCPointer)
63
64 func FilterSurfaceFormat*(
65 formats: seq[VkSurfaceFormatKHR],
66 imageFormat = VK_FORMAT_B8G8R8A8_SRGB,
67 colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
68 ): VkSurfaceFormatKHR =
69 for format in formats:
70 if format.format == imageFormat and format.colorSpace == colorSpace:
71 return format
72
73 proc FilterSurfaceFormat*(device: PhysicalDevice): VkSurfaceFormatKHR =
74 assert device.vk.Valid
75 assert device.surface.Valid
76 device.GetSurfaceFormats().FilterSurfaceFormat()
77
78 proc GetSurfacePresentModes*(device: PhysicalDevice): seq[VkPresentModeKHR] =
79 assert device.vk.Valid
80 assert device.surface.Valid
81 var n_modes: uint32
82 checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device.vk, device.surface, addr(n_modes), nil)
83 result = newSeq[VkPresentModeKHR](n_modes)
84 checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device.vk, device.surface, addr(n_modes), result.ToCPointer)
85
86 proc GetQueueFamilies*(device: PhysicalDevice): seq[QueueFamily] =
87 assert device.vk.Valid
88 var nQueuefamilies: uint32
89 vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies, nil)
90 var queuFamilies = newSeq[VkQueueFamilyProperties](nQueuefamilies)
91 vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies, queuFamilies.ToCPointer)
92 for i in 0 ..< nQueuefamilies:
93 result.add QueueFamily(
94 device: device,
95 properties: queuFamilies[i],
96 index: i,
97 flags: queuFamilies[i].queueFlags.toEnums,
98 )
99
100 proc CanDoGraphics*(family: QueueFamily): bool =
101 VK_QUEUE_GRAPHICS_BIT in family.flags
102
103 proc CanDoPresentation*(family: QueueFamily, surface: VkSurfaceKHR): bool =
104 assert surface.Valid
105 var presentation = VkBool32(false)
106 checkVkResult vkGetPhysicalDeviceSurfaceSupportKHR(family.device.vk, family.index, surface, addr presentation)
107 return bool(presentation)
108
109 proc CanDoTransfer*(family: QueueFamily): bool =
110 VK_QUEUE_TRANSFER_BIT in family.flags
111
112 proc FilterForGraphicsPresentationQueues*(device: PhysicalDevice): seq[QueueFamily] =
113 var canDoGraphics = false
114 var canDoPresentation = false
115 var queues: Table[uint32, QueueFamily]
116 for family in device.GetQueueFamilies():
117 if family.CanDoGraphics:
118 queues[family.index] = family
119 canDoGraphics = true
120 if family.CanDoPresentation(device.surface):
121 queues[family.index] = family
122 canDoPresentation = true
123 if canDoGraphics and canDoPresentation:
124 return queues.values.toSeq
125
126 proc filterGraphics(families: seq[QueueFamily]): seq[QueueFamily] =
127 for family in families:
128 if family.CanDoGraphics:
129 result.add family
130
131 proc filterPresentation(families: seq[QueueFamily], surface: VkSurfaceKHR): seq[QueueFamily] =
132 assert surface.Valid
133 for family in families:
134 if family.CanDoPresentation(surface):
135 result.add family
136
137 proc rateGraphics(device: PhysicalDevice): float =
138 assert device.vk.Valid
139 assert device.surface.Valid
140 if device.GetQueueFamilies().filterGraphics().filterPresentation(device.surface).len == 0:
141 return -1
142 if not ("VK_KHR_swapchain" in device.GetExtensions()):
143 return -1
144 const deviceTypeMap = [
145 VK_PHYSICAL_DEVICE_TYPE_OTHER,
146 VK_PHYSICAL_DEVICE_TYPE_CPU,
147 VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
148 VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
149 VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
150 ]
151 for (i, devicetype) in enumerate(deviceTypeMap):
152 if device.devicetype == devicetype:
153 result = float(i)
154
155 proc FilterBestGraphics*(devices: seq[PhysicalDevice]): PhysicalDevice =
156 var bestVal = -1'f
157 for device in devices:
158 assert device.vk.Valid
159 assert device.surface.Valid
160 let rating = device.rateGraphics()
161 if rating > bestVal:
162 bestVal = rating
163 result = device
164 assert bestVal >= 0