Mercurial > games > semicongine
annotate src/semicongine/vulkan/physicaldevice.nim @ 207:81fab407a479
add: some adjustment to the last refactoring :P
author | Sam <sam@basx.dev> |
---|---|
date | Tue, 09 May 2023 01:18:01 +0700 |
parents | 7f921d7d0a2b |
children | ddfc54036e00 |
rev | line source |
---|---|
97
110ed3ee5df8
add: swapchain, images, fix some destroctors
Sam <sam@basx.dev>
parents:
96
diff
changeset
|
1 from std/enumerate import enumerate |
96 | 2 import std/tables |
3 import std/sequtils | |
4 | |
206
7f921d7d0a2b
did: small refactoring of module structure
Sam <sam@basx.dev>
parents:
189
diff
changeset
|
5 import ../core |
96 | 6 import ./instance |
7 | |
8 type | |
9 PhysicalDevice* = object | |
10 vk*: VkPhysicalDevice | |
11 name*: string | |
12 devicetype*: VkPhysicalDeviceType | |
13 surface*: VkSurfaceKHR | |
188
de9dff24c422
add: image/texture creation, refactoring of some unclean parts
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
14 properties*: VkPhysicalDeviceProperties |
de9dff24c422
add: image/texture creation, refactoring of some unclean parts
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
15 features*: VkPhysicalDeviceFeatures |
96 | 16 QueueFamily* = object |
17 device: PhysicalDevice | |
18 properties*: VkQueueFamilyProperties | |
19 index*: uint32 | |
20 flags*: seq[VkQueueFlagBits] | |
21 | |
189
df92519d4d68
add: initial code for texture support, not finished, had to completely refactor how to handle material-data (ie scene-wide data, sorry if you ever read this
Sam <sam@basx.dev>
parents:
188
diff
changeset
|
22 func `$`*(device: PhysicalDevice): string = |
df92519d4d68
add: initial code for texture support, not finished, had to completely refactor how to handle material-data (ie scene-wide data, sorry if you ever read this
Sam <sam@basx.dev>
parents:
188
diff
changeset
|
23 "Physical device: vk=" & $device.vk & ", name=" & $device.name & ", devicetype=" & $device.devicetype |
df92519d4d68
add: initial code for texture support, not finished, had to completely refactor how to handle material-data (ie scene-wide data, sorry if you ever read this
Sam <sam@basx.dev>
parents:
188
diff
changeset
|
24 |
96 | 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) | |
188
de9dff24c422
add: image/texture creation, refactoring of some unclean parts
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
34 device.vk.vkGetPhysicalDeviceProperties(addr device.properties) |
de9dff24c422
add: image/texture creation, refactoring of some unclean parts
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
35 device.vk.vkGetPhysicalDeviceFeatures(addr device.features) |
de9dff24c422
add: image/texture creation, refactoring of some unclean parts
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
36 device.name = device.properties.deviceName.cleanString() |
de9dff24c422
add: image/texture creation, refactoring of some unclean parts
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
37 device.devicetype = device.properties.deviceType |
96 | 38 result.add device |
39 | |
40 proc getExtensions*(device: PhysicalDevice): seq[string] = | |
41 assert device.vk.valid | |
42 var extensionCount: uint32 | |
43 checkVkResult vkEnumerateDeviceExtensionProperties(device.vk, nil, addr(extensionCount), nil) | |
44 if extensionCount > 0: | |
45 var extensions = newSeq[VkExtensionProperties](extensionCount) | |
46 checkVkResult vkEnumerateDeviceExtensionProperties(device.vk, nil, addr(extensionCount), extensions.toCPointer) | |
47 for extension in extensions: | |
48 result.add(cleanString(extension.extensionName)) | |
49 | |
50 proc getSurfaceCapabilities*(device: PhysicalDevice): VkSurfaceCapabilitiesKHR = | |
51 assert device.vk.valid | |
52 assert device.surface.valid | |
53 checkVkResult device.vk.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device.surface, addr(result)) | |
54 | |
55 proc getSurfaceFormats*(device: PhysicalDevice): seq[VkSurfaceFormatKHR] = | |
56 assert device.vk.valid | |
57 assert device.surface.valid | |
58 var n_formats: uint32 | |
59 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device.vk, device.surface, addr(n_formats), nil) | |
60 result = newSeq[VkSurfaceFormatKHR](n_formats) | |
61 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device.vk, device.surface, addr(n_formats), result.toCPointer) | |
62 | |
63 func filterSurfaceFormat*( | |
64 formats: seq[VkSurfaceFormatKHR], | |
65 imageFormat = VK_FORMAT_B8G8R8A8_SRGB, | |
66 colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR | |
67 ): VkSurfaceFormatKHR = | |
68 for format in formats: | |
69 if format.format == imageFormat and format.colorSpace == colorSpace: | |
70 return format | |
71 | |
72 proc filterSurfaceFormat*(device: PhysicalDevice): VkSurfaceFormatKHR = | |
73 assert device.vk.valid | |
74 assert device.surface.valid | |
75 device.getSurfaceFormats().filterSurfaceFormat() | |
76 | |
77 proc getSurfacePresentModes*(device: PhysicalDevice): seq[VkPresentModeKHR] = | |
78 assert device.vk.valid | |
79 assert device.surface.valid | |
80 var n_modes: uint32 | |
81 checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device.vk, device.surface, addr(n_modes), nil) | |
82 result = newSeq[VkPresentModeKHR](n_modes) | |
83 checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device.vk, device.surface, addr(n_modes), result.toCPointer) | |
84 | |
85 proc getQueueFamilies*(device: PhysicalDevice): seq[QueueFamily] = | |
86 assert device.vk.valid | |
87 var nQueuefamilies: uint32 | |
88 vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies, nil) | |
89 var queuFamilies = newSeq[VkQueueFamilyProperties](nQueuefamilies) | |
90 vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies , queuFamilies.toCPointer) | |
91 for i in 0 ..< nQueuefamilies: | |
92 result.add QueueFamily( | |
93 device: device, | |
94 properties: queuFamilies[i], | |
95 index: i, | |
96 flags: queuFamilies[i].queueFlags.toEnums, | |
97 ) | |
98 | |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
99 proc canDoGraphics*(family: QueueFamily): bool = |
96 | 100 VK_QUEUE_GRAPHICS_BIT in family.flags |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
101 |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
102 proc canDoPresentation*(family: QueueFamily, surface: VkSurfaceKHR): bool = |
96 | 103 assert surface.valid |
104 var presentation = VkBool32(false) | |
105 checkVkResult vkGetPhysicalDeviceSurfaceSupportKHR(family.device.vk, family.index, surface, addr presentation) | |
106 return presentation | |
107 | |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
108 proc canDoTransfer*(family: QueueFamily): bool = |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
109 VK_QUEUE_TRANSFER_BIT in family.flags |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
110 |
96 | 111 proc filterForGraphicsPresentationQueues*(device: PhysicalDevice): seq[QueueFamily] = |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
112 var canDoGraphics = false |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
113 var canDoPresentation = false |
96 | 114 var queues: Table[uint32, QueueFamily] |
115 for family in device.getQueueFamilies(): | |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
116 if family.canDoGraphics: |
96 | 117 queues[family.index] = family |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
118 canDoGraphics = true |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
119 if family.canDoPresentation(device.surface): |
96 | 120 queues[family.index] = family |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
121 canDoPresentation = true |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
122 if canDoGraphics and canDoPresentation: |
96 | 123 return queues.values.toSeq |
124 | |
125 proc filterGraphics(families: seq[QueueFamily]): seq[QueueFamily] = | |
126 for family in families: | |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
127 if family.canDoGraphics: |
96 | 128 result.add family |
129 | |
130 proc filterPresentation(families: seq[QueueFamily], surface: VkSurfaceKHR): seq[QueueFamily] = | |
131 assert surface.valid | |
132 for family in families: | |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
133 if family.canDoPresentation(surface): |
96 | 134 result.add family |
135 | |
136 proc rateGraphics*(device: PhysicalDevice): float = | |
137 assert device.vk.valid | |
138 assert device.surface.valid | |
139 if device.getQueueFamilies().filterGraphics().filterPresentation(device.surface).len == 0: | |
140 return -1 | |
141 if not ("VK_KHR_swapchain" in device.getExtensions()): | |
142 return -1 | |
143 const deviceTypeMap = [ | |
144 VK_PHYSICAL_DEVICE_TYPE_OTHER, | |
145 VK_PHYSICAL_DEVICE_TYPE_CPU, | |
146 VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, | |
147 VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, | |
148 VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, | |
149 ] | |
150 for (i, devicetype) in enumerate(deviceTypeMap): | |
151 if device.devicetype == devicetype: | |
152 result = float(i) | |
153 | |
154 proc filterBestGraphics*(devices: seq[PhysicalDevice]): PhysicalDevice = | |
155 var bestVal = -1'f | |
156 for device in devices: | |
157 assert device.vk.valid | |
158 assert device.surface.valid | |
159 let rating = device.rateGraphics() | |
160 if rating > bestVal: | |
161 bestVal = rating | |
162 result = device | |
163 assert bestVal >= 0 |