Mercurial > games > semicongine
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 |