Mercurial > games > semicongine
comparison svk/api.nim @ 1490:81da4be50663
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 |
