Mercurial > games > semicongine
comparison svk/api.nim @ 1490:81da4be50663 default tip
did: some stuff
author | sam <sam@basx.dev> |
---|---|
date | Fri, 23 May 2025 23:42:19 +0700 |
parents | e6bd1f553c1b |
children |
comparison
equal
deleted
inserted
replaced
1489:e6bd1f553c1b | 1490:81da4be50663 |
---|---|
56 when defined(windows): | 56 when defined(windows): |
57 type NativeWindow* = object | 57 type NativeWindow* = object |
58 hinstance*: HINSTANCE | 58 hinstance*: HINSTANCE |
59 hwnd*: HWND | 59 hwnd*: HWND |
60 g_wpPrev*: WINDOWPLACEMENT | 60 g_wpPrev*: WINDOWPLACEMENT |
61 | |
61 else: | 62 else: |
62 type NativeWindow* = object | 63 type NativeWindow* = object |
63 display*: ptr Display | 64 display*: ptr Display |
64 window*: Window | 65 window*: Window |
65 emptyCursor*: Cursor | 66 emptyCursor*: Cursor |
66 ic*: XIC | 67 ic*: XIC |
67 | |
68 | |
69 | |
70 | 68 |
71 # ============================================================================= | 69 # ============================================================================= |
72 # VULKAN INSTANCE ============================================================= | 70 # VULKAN INSTANCE ============================================================= |
73 # ============================================================================= | 71 # ============================================================================= |
74 | 72 |
174 var allTypes: VkDebugUtilsMessageTypeFlagsEXT | 172 var allTypes: VkDebugUtilsMessageTypeFlagsEXT |
175 for t in VkDebugUtilsMessageTypeFlagBitsEXT: | 173 for t in VkDebugUtilsMessageTypeFlagBitsEXT: |
176 allTypes = allTypes or t | 174 allTypes = allTypes or t |
177 when not defined(release): | 175 when not defined(release): |
178 var debugMessengerCreateInfo = VkDebugUtilsMessengerCreateInfoEXT( | 176 var debugMessengerCreateInfo = VkDebugUtilsMessengerCreateInfoEXT( |
179 messageSeverity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT or VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT or VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT or VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, | 177 messageSeverity: |
180 messageType: VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT or VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT or VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, | 178 VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT or |
179 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT or | |
180 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT or | |
181 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, | |
182 messageType: | |
183 VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT or | |
184 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT or | |
185 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, | |
181 pfnUserCallback: debugCallback, | 186 pfnUserCallback: debugCallback, |
182 ) | 187 ) |
183 checkVkResult vkCreateDebugUtilsMessengerEXT( | 188 checkVkResult vkCreateDebugUtilsMessengerEXT( |
184 result.vkInstance, addr debugMessengerCreateInfo, nil, addr result.debugMessenger | 189 result.vkInstance, addr debugMessengerCreateInfo, nil, addr result.debugMessenger |
185 ) | 190 ) |
186 | 191 |
187 | |
188 result.window = createWindow(applicationName) | 192 result.window = createWindow(applicationName) |
189 when defined(windows): | 193 when defined(windows): |
190 var surfaceCreateInfo = VkWin32SurfaceCreateInfoKHR(hinstance: window.hinstance, hwnd: window.hwnd) | 194 var surfaceCreateInfo = |
191 checkVkResult vkCreateWin32SurfaceKHR(instance, addr surfaceCreateInfo, nil, addr result.vkSurface) | 195 VkWin32SurfaceCreateInfoKHR(hinstance: window.hinstance, hwnd: window.hwnd) |
196 checkVkResult vkCreateWin32SurfaceKHR( | |
197 instance, addr surfaceCreateInfo, nil, addr result.vkSurface | |
198 ) | |
192 else: | 199 else: |
193 var surfaceCreateInfo = VkXlibSurfaceCreateInfoKHR(dpy: result.window.display, window: result.window.window) | 200 var surfaceCreateInfo = VkXlibSurfaceCreateInfoKHR( |
194 checkVkResult result.vkInstance.vkCreateXlibSurfaceKHR(addr surfaceCreateInfo, nil, addr result.vkSurface) | 201 dpy: result.window.display, window: result.window.window |
195 | 202 ) |
196 | 203 checkVkResult result.vkInstance.vkCreateXlibSurfaceKHR( |
204 addr surfaceCreateInfo, nil, addr result.vkSurface | |
205 ) | |
197 | 206 |
198 # ============================================================================= | 207 # ============================================================================= |
199 # PHYSICAL DEVICES ============================================================ | 208 # PHYSICAL DEVICES ============================================================ |
200 # ============================================================================= | 209 # ============================================================================= |
201 | 210 |
203 SVkMemoryType* = object | 212 SVkMemoryType* = object |
204 size: uint64 | 213 size: uint64 |
205 deviceLocal: bool # fast for gpu access | 214 deviceLocal: bool # fast for gpu access |
206 hostCached: bool # fast for host access | 215 hostCached: bool # fast for host access |
207 hostVisible: bool # can use vkMapMemory | 216 hostVisible: bool # can use vkMapMemory |
208 hostCohorent: bool # does *not* require vkFlushMappedMemoryRanges and vkInvalidateMappedMemoryRanges | 217 hostCohorent: bool |
218 # does *not* require vkFlushMappedMemoryRanges and vkInvalidateMappedMemoryRanges | |
219 | |
209 SVkQueueFamilies* = object | 220 SVkQueueFamilies* = object |
210 count: int | 221 count: int |
211 hasGraphics: bool # implies "hasTransfer" | 222 hasGraphics: bool # implies "hasTransfer" |
212 hasCompute: bool # implies "hasTransfer" | 223 hasCompute: bool # implies "hasTransfer" |
213 | 224 |
214 SVkPhysicalDevice* = object | 225 SVkPhysicalDevice* = object |
215 name*: string | 226 name*: string |
227 discreteGPU*: bool | |
216 vkPhysicalDevice*: VkPhysicalDevice | 228 vkPhysicalDevice*: VkPhysicalDevice |
217 vkPhysicalDeviceFeatures*: VkPhysicalDeviceFeatures | 229 vkPhysicalDeviceFeatures*: VkPhysicalDeviceFeatures |
218 vkPhysicalDeviceProperties*: VkPhysicalDeviceProperties | 230 vkPhysicalDeviceProperties*: VkPhysicalDeviceProperties |
219 memoryTypes*: seq[SVkMemoryType] | 231 memoryTypes*: seq[SVkMemoryType] |
220 queueFamily*: uint32 | 232 queueFamily*: uint32 |
221 | 233 |
222 proc getUsablePhysicalDevices*(instance: SVkInstance): seq[SVkPhysicalDevice] = | 234 proc getUsablePhysicalDevices*(instance: SVkInstance): seq[SVkPhysicalDevice] = |
223 var nDevices: uint32 | 235 var nDevices: uint32 |
224 checkVkResult instance.vkInstance.vkEnumeratePhysicalDevices(addr nDevices, nil) | 236 checkVkResult instance.vkInstance.vkEnumeratePhysicalDevices(addr nDevices, nil) |
225 var devices = newSeq[VkPhysicalDevice](nDevices) | 237 var devices = newSeq[VkPhysicalDevice](nDevices) |
226 checkVkResult instance.vkInstance.vkEnumeratePhysicalDevices(addr nDevices, addr devices[0]) | 238 checkVkResult instance.vkInstance.vkEnumeratePhysicalDevices( |
239 addr nDevices, addr devices[0] | |
240 ) | |
227 for d in devices: | 241 for d in devices: |
228 var dev = SVkPhysicalDevice(vkPhysicalDevice: d) | 242 var dev = SVkPhysicalDevice(vkPhysicalDevice: d) |
229 d.vkGetPhysicalDeviceFeatures(addr dev.vkPhysicalDeviceFeatures) | 243 d.vkGetPhysicalDeviceFeatures(addr dev.vkPhysicalDeviceFeatures) |
230 d.vkGetPhysicalDeviceProperties(addr dev.vkPhysicalDeviceProperties) | 244 d.vkGetPhysicalDeviceProperties(addr dev.vkPhysicalDeviceProperties) |
231 | 245 |
232 if dev.vkPhysicalDeviceProperties.deviceType notin [VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU]: | 246 if dev.vkPhysicalDeviceProperties.deviceType notin |
247 [VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU]: | |
233 continue | 248 continue |
234 dev.name = $cast[cstring](addr dev.vkPhysicalDeviceProperties.deviceName[0]) | 249 dev.name = $cast[cstring](addr dev.vkPhysicalDeviceProperties.deviceName[0]) |
250 dev.discreteGPU = | |
251 dev.vkPhysicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU | |
235 | 252 |
236 var memoryProperties: VkPhysicalDeviceMemoryProperties | 253 var memoryProperties: VkPhysicalDeviceMemoryProperties |
237 d.vkGetPhysicalDeviceMemoryProperties(addr memoryProperties) | 254 d.vkGetPhysicalDeviceMemoryProperties(addr memoryProperties) |
238 for i in 0 ..< memoryProperties.memoryTypeCount: | 255 for i in 0 ..< memoryProperties.memoryTypeCount: |
239 let heapI = memoryProperties.memoryTypes[i].heapIndex | 256 let heapI = memoryProperties.memoryTypes[i].heapIndex |
240 dev.memoryTypes.add SVkMemoryType( | 257 dev.memoryTypes.add SVkMemoryType( |
241 size: memoryProperties.memoryHeaps[heapI].size.uint64, | 258 size: memoryProperties.memoryHeaps[heapI].size.uint64, |
242 deviceLocal: VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT in memoryProperties.memoryTypes[i].propertyFlags, | 259 deviceLocal: |
243 hostCached: VK_MEMORY_PROPERTY_HOST_CACHED_BIT in memoryProperties.memoryTypes[i].propertyFlags, | 260 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT in |
244 hostVisible: VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in memoryProperties.memoryTypes[i].propertyFlags, | 261 memoryProperties.memoryTypes[i].propertyFlags, |
245 hostCohorent: VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in memoryProperties.memoryTypes[i].propertyFlags, | 262 hostCached: |
263 VK_MEMORY_PROPERTY_HOST_CACHED_BIT in | |
264 memoryProperties.memoryTypes[i].propertyFlags, | |
265 hostVisible: | |
266 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in | |
267 memoryProperties.memoryTypes[i].propertyFlags, | |
268 hostCohorent: | |
269 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in | |
270 memoryProperties.memoryTypes[i].propertyFlags, | |
246 ) | 271 ) |
247 | |
248 | 272 |
249 var familyQueueCount: uint32 | 273 var familyQueueCount: uint32 |
250 var vkQueueFamilyProperties: seq[VkQueueFamilyProperties] | 274 var vkQueueFamilyProperties: seq[VkQueueFamilyProperties] |
251 d.vkGetPhysicalDeviceQueueFamilyProperties(addr familyQueueCount, nil) | 275 d.vkGetPhysicalDeviceQueueFamilyProperties(addr familyQueueCount, nil) |
252 vkQueueFamilyProperties.setLen(familyQueueCount) | 276 vkQueueFamilyProperties.setLen(familyQueueCount) |
253 d.vkGetPhysicalDeviceQueueFamilyProperties(addr familyQueueCount, addr vkQueueFamilyProperties[0]) | 277 d.vkGetPhysicalDeviceQueueFamilyProperties( |
278 addr familyQueueCount, addr vkQueueFamilyProperties[0] | |
279 ) | |
254 dev.queueFamily = high(uint32) | 280 dev.queueFamily = high(uint32) |
255 for i in 0 ..< familyQueueCount: | 281 for i in 0 ..< familyQueueCount: |
256 let hasGraphics = VK_QUEUE_GRAPHICS_BIT in vkQueueFamilyProperties[i].queueFlags | 282 let hasGraphics = VK_QUEUE_GRAPHICS_BIT in vkQueueFamilyProperties[i].queueFlags |
257 let hasCompute = VK_QUEUE_COMPUTE_BIT in vkQueueFamilyProperties[i].queueFlags | 283 let hasCompute = VK_QUEUE_COMPUTE_BIT in vkQueueFamilyProperties[i].queueFlags |
258 let hasPresentation = VK_FALSE | 284 let hasPresentation = VK_FALSE |
259 checkVkResult dev.vkPhysicalDevice.vkGetPhysicalDeviceSurfaceSupportKHR(i, instance.vkSurface, addr hasPresentation) | 285 checkVkResult dev.vkPhysicalDevice.vkGetPhysicalDeviceSurfaceSupportKHR( |
286 i, instance.vkSurface, addr hasPresentation | |
287 ) | |
260 | 288 |
261 if hasGraphics and hasCompute and bool(hasPresentation): | 289 if hasGraphics and hasCompute and bool(hasPresentation): |
262 dev.queueFamily = i | 290 dev.queueFamily = i |
263 break | 291 break |
264 if dev.queueFamily == high(uint32): | 292 if dev.queueFamily == high(uint32): |
265 raise newException(Exception, "Did not find queue family with graphics and compute support!") | 293 raise newException( |
294 Exception, | |
295 "Did not find queue family with graphics, compute and presentation support!", | |
296 ) | |
266 | 297 |
267 result.add dev | 298 result.add dev |
299 | |
300 # ============================================================================= | |
301 # DEVICES ===================================================================== | |
302 # ============================================================================= | |
303 | |
304 type SVkDevice* = object | |
305 vkDevice: VkDevice | |
306 vkQueue: VkQueue | |
307 | |
308 proc `=copy`(a: var SVkDevice, b: SVkDevice) {.error.} | |
309 | |
310 proc `=destroy`(a: SVkDevice) = | |
311 debugAssert a.vkDevice.pointer == nil | |
312 debugAssert a.vkQueue.pointer == nil | |
313 | |
314 proc destroy*(a: var SVkDevice) = | |
315 if a.vkDevice.pointer != nil: | |
316 vkDestroyDevice(a.vkDevice, nil) | |
317 a.vkDevice = VkDevice(nil) | |
318 a.vkQueue = VkQueue(nil) | |
319 | |
320 proc svkCreateDevice*( | |
321 instance: SVkInstance, physicalDevice: SVkPhysicalDevice | |
322 ): SVkDevice = | |
323 let | |
324 priority = cfloat(1) | |
325 queueInfo = VkDeviceQueueCreateInfo( | |
326 queueFamilyIndex: physicalDevice.queueFamily, | |
327 queueCount: 1, | |
328 pQueuePriorities: addr priority, | |
329 ) | |
330 deviceExtensions = @["VK_KHR_swapchain"] | |
331 deviceExtensionsC = allocCStringArray(deviceExtensions) | |
332 enabledFeatures = VkPhysicalDeviceFeatures( | |
333 fillModeNonSolid: VK_TRUE, | |
334 depthClamp: VK_TRUE, | |
335 wideLines: VK_TRUE, | |
336 largePoints: VK_TRUE, | |
337 ) | |
338 vk8bitExt = VkPhysicalDevice8BitStorageFeatures( | |
339 storageBuffer8BitAccess: VK_TRUE, | |
340 uniformAndStorageBuffer8BitAccess: VK_TRUE, | |
341 storagePushConstant8: VK_TRUE, | |
342 ) | |
343 vk16bitExt = VkPhysicalDevice16BitStorageFeatures( | |
344 storageBuffer16BitAccess: VK_TRUE, | |
345 uniformAndStorageBuffer16BitAccess: VK_TRUE, | |
346 storagePushConstant16: VK_TRUE, | |
347 storageInputOutput16: VK_FALSE, | |
348 pNext: addr vk8bitExt, | |
349 ) | |
350 createDeviceInfo = VkDeviceCreateInfo( | |
351 queueCreateInfoCount: 1, | |
352 pQueueCreateInfos: addr queueInfo, | |
353 enabledLayerCount: 0, | |
354 ppEnabledLayerNames: nil, | |
355 enabledExtensionCount: 1, | |
356 ppEnabledExtensionNames: deviceExtensionsC, | |
357 pEnabledFeatures: addr enabledFeatures, | |
358 pNext: addr vk16bitExt, | |
359 ) | |
360 checkVkResult vkCreateDevice( | |
361 physicalDevice = physicalDevice.vkPhysicalDevice, | |
362 pCreateInfo = addr createDeviceInfo, | |
363 pAllocator = nil, | |
364 pDevice = addr result.vkDevice, | |
365 ) | |
366 deviceExtensionsC.deallocCStringArray() | |
367 result.vkDevice.vkGetDeviceQueue(physicalDevice.queueFamily, 0, addr result.vkQueue) | |
368 | |
369 # ============================================================================= | |
370 # PLATFORM UTILS ============================================================== | |
371 # ============================================================================= | |
268 | 372 |
269 when defined(windows): | 373 when defined(windows): |
270 proc createWindow(title: string): NativeWindow = | 374 proc createWindow(title: string): NativeWindow = |
271 result.hInstance = HINSTANCE(GetModuleHandle(nil)) | 375 result.hInstance = HINSTANCE(GetModuleHandle(nil)) |
272 var | 376 var |
333 doAssert display.XGetWindowAttributes(rootWindow, addr(attribs)) != 0 | 437 doAssert display.XGetWindowAttributes(rootWindow, addr(attribs)) != 0 |
334 | 438 |
335 var attrs = XSetWindowAttributes( | 439 var attrs = XSetWindowAttributes( |
336 event_mask: | 440 event_mask: |
337 FocusChangeMask or KeyPressMask or KeyReleaseMask or ExposureMask or | 441 FocusChangeMask or KeyPressMask or KeyReleaseMask or ExposureMask or |
338 VisibilityChangeMask or StructureNotifyMask or ButtonMotionMask or ButtonPressMask or | 442 VisibilityChangeMask or StructureNotifyMask or ButtonMotionMask or |
339 ButtonReleaseMask | 443 ButtonPressMask or ButtonReleaseMask |
340 ) | 444 ) |
341 let window = display.XCreateWindow( | 445 let window = display.XCreateWindow( |
342 rootWindow, | 446 rootWindow, |
343 (attribs.width - cint(width)) div 2, | 447 (attribs.width - cint(width)) div 2, |
344 (attribs.height - cint(height)) div 2, | 448 (attribs.height - cint(height)) div 2, |
376 # wait until window is shown | 480 # wait until window is shown |
377 var ev: XEvent | 481 var ev: XEvent |
378 while ev.theType != MapNotify: | 482 while ev.theType != MapNotify: |
379 discard display.XNextEvent(addr(ev)) | 483 discard display.XNextEvent(addr(ev)) |
380 | 484 |
381 result = NativeWindow(display: display, window: window, emptyCursor: empty_cursor, ic: ic) | 485 result = |
486 NativeWindow(display: display, window: window, emptyCursor: empty_cursor, ic: ic) | |
382 | 487 |
383 proc destroyWindow*(window: NativeWindow) = | 488 proc destroyWindow*(window: NativeWindow) = |
384 doAssert XDestroyWindow(window.display, window.window) != 0 | 489 doAssert XDestroyWindow(window.display, window.window) != 0 |
385 |