Mercurial > games > semicongine
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/semiconginev2/old/vulkan/physicaldevice.nim Wed Jul 17 21:01:37 2024 +0700 @@ -0,0 +1,164 @@ +from std/enumerate import enumerate +import std/tables +import std/sequtils + +import ../core +import ./instance + +type + PhysicalDevice* = object + vk*: VkPhysicalDevice + name*: string + devicetype*: VkPhysicalDeviceType + surface*: VkSurfaceKHR + properties*: VkPhysicalDeviceProperties + features*: VkPhysicalDeviceFeatures2 + QueueFamily* = object + device: PhysicalDevice + properties*: VkQueueFamilyProperties + index*: uint32 + flags*: seq[VkQueueFlagBits] + +func `$`*(device: PhysicalDevice): string = + "Physical device: vk=" & $device.vk & ", name=" & $device.name & ", devicetype=" & $device.devicetype + +proc GetPhysicalDevices*(instance: Instance): seq[PhysicalDevice] = + assert instance.vk.Valid + assert instance.surface.Valid + var nDevices: uint32 + checkVkResult vkEnumeratePhysicalDevices(instance.vk, addr(nDevices), nil) + var devices = newSeq[VkPhysicalDevice](nDevices) + checkVkResult vkEnumeratePhysicalDevices(instance.vk, addr(nDevices), devices.ToCPointer) + for i in 0 ..< nDevices: + var device = PhysicalDevice(vk: devices[i], surface: instance.surface) + device.vk.vkGetPhysicalDeviceProperties(addr device.properties) + device.features.stype = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 + device.vk.vkGetPhysicalDeviceFeatures2(addr device.features) + device.name = device.properties.deviceName.CleanString() + device.devicetype = device.properties.deviceType + result.add device + +proc GetExtensions*(device: PhysicalDevice): seq[string] = + assert device.vk.Valid + var extensionCount: uint32 + checkVkResult vkEnumerateDeviceExtensionProperties(device.vk, nil, addr(extensionCount), nil) + if extensionCount > 0: + var extensions = newSeq[VkExtensionProperties](extensionCount) + checkVkResult vkEnumerateDeviceExtensionProperties(device.vk, nil, addr(extensionCount), extensions.ToCPointer) + for extension in extensions: + result.add(CleanString(extension.extensionName)) + +proc GetSurfaceCapabilities*(device: PhysicalDevice): VkSurfaceCapabilitiesKHR = + assert device.vk.Valid + assert device.surface.Valid + checkVkResult device.vk.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device.surface, addr(result)) + +proc GetSurfaceFormats*(device: PhysicalDevice): seq[VkSurfaceFormatKHR] = + assert device.vk.Valid + assert device.surface.Valid + var n_formats: uint32 + checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device.vk, device.surface, addr(n_formats), nil) + result = newSeq[VkSurfaceFormatKHR](n_formats) + checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device.vk, device.surface, addr(n_formats), result.ToCPointer) + +func FilterSurfaceFormat*( + formats: seq[VkSurfaceFormatKHR], + imageFormat = VK_FORMAT_B8G8R8A8_SRGB, + colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR +): VkSurfaceFormatKHR = + for format in formats: + if format.format == imageFormat and format.colorSpace == colorSpace: + return format + +proc FilterSurfaceFormat*(device: PhysicalDevice): VkSurfaceFormatKHR = + assert device.vk.Valid + assert device.surface.Valid + device.GetSurfaceFormats().FilterSurfaceFormat() + +proc GetSurfacePresentModes*(device: PhysicalDevice): seq[VkPresentModeKHR] = + assert device.vk.Valid + assert device.surface.Valid + var n_modes: uint32 + checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device.vk, device.surface, addr(n_modes), nil) + result = newSeq[VkPresentModeKHR](n_modes) + checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device.vk, device.surface, addr(n_modes), result.ToCPointer) + +proc GetQueueFamilies*(device: PhysicalDevice): seq[QueueFamily] = + assert device.vk.Valid + var nQueuefamilies: uint32 + vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies, nil) + var queuFamilies = newSeq[VkQueueFamilyProperties](nQueuefamilies) + vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies, queuFamilies.ToCPointer) + for i in 0 ..< nQueuefamilies: + result.add QueueFamily( + device: device, + properties: queuFamilies[i], + index: i, + flags: queuFamilies[i].queueFlags.toEnums, + ) + +proc CanDoGraphics*(family: QueueFamily): bool = + VK_QUEUE_GRAPHICS_BIT in family.flags + +proc CanDoPresentation*(family: QueueFamily, surface: VkSurfaceKHR): bool = + assert surface.Valid + var presentation = VkBool32(false) + checkVkResult vkGetPhysicalDeviceSurfaceSupportKHR(family.device.vk, family.index, surface, addr presentation) + return bool(presentation) + +proc CanDoTransfer*(family: QueueFamily): bool = + VK_QUEUE_TRANSFER_BIT in family.flags + +proc FilterForGraphicsPresentationQueues*(device: PhysicalDevice): seq[QueueFamily] = + var canDoGraphics = false + var canDoPresentation = false + var queues: Table[uint32, QueueFamily] + for family in device.GetQueueFamilies(): + if family.CanDoGraphics: + queues[family.index] = family + canDoGraphics = true + if family.CanDoPresentation(device.surface): + queues[family.index] = family + canDoPresentation = true + if canDoGraphics and canDoPresentation: + return queues.values.toSeq + +proc filterGraphics(families: seq[QueueFamily]): seq[QueueFamily] = + for family in families: + if family.CanDoGraphics: + result.add family + +proc filterPresentation(families: seq[QueueFamily], surface: VkSurfaceKHR): seq[QueueFamily] = + assert surface.Valid + for family in families: + if family.CanDoPresentation(surface): + result.add family + +proc rateGraphics(device: PhysicalDevice): float = + assert device.vk.Valid + assert device.surface.Valid + if device.GetQueueFamilies().filterGraphics().filterPresentation(device.surface).len == 0: + return -1 + if not ("VK_KHR_swapchain" in device.GetExtensions()): + return -1 + const deviceTypeMap = [ + VK_PHYSICAL_DEVICE_TYPE_OTHER, + VK_PHYSICAL_DEVICE_TYPE_CPU, + VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, + VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, + ] + for (i, devicetype) in enumerate(deviceTypeMap): + if device.devicetype == devicetype: + result = float(i) + +proc FilterBestGraphics*(devices: seq[PhysicalDevice]): PhysicalDevice = + var bestVal = -1'f + for device in devices: + assert device.vk.Valid + assert device.surface.Valid + let rating = device.rateGraphics() + if rating > bestVal: + bestVal = rating + result = device + assert bestVal >= 0