# HG changeset patch # User Sam # Date 1677517708 -25200 # Node ID e872cf35411023ecd2796a442051b36ceeb90e08 # Parent 2e9823f9193f9cb917a317fbbb518c1370a29916 add: more stuff for the vulkan API wrappers diff -r 2e9823f9193f -r e872cf354110 src/semicongine/engine.nim --- a/src/semicongine/engine.nim Mon Feb 27 00:05:26 2023 +0700 +++ b/src/semicongine/engine.nim Tue Feb 28 00:08:28 2023 +0700 @@ -111,7 +111,7 @@ proc getAllPhysicalDevices(instance: VkInstance, surface: VkSurfaceKHR): seq[ PhysicalDevice] = for vulkanPhysicalDevice in getVulkanPhysicalDevices(instance): - var device = PhysicalDevice(device: vulkanPhysicalDevice, extensions: getDeviceExtensions(vulkanPhysicalDevice)) + var device = PhysicalDevice(device: vulkanPhysicalDevice, extensions: vulkan.getDeviceExtensions(vulkanPhysicalDevice)) vkGetPhysicalDeviceProperties(vulkanPhysicalDevice, addr(device.properties)) vkGetPhysicalDeviceFeatures(vulkanPhysicalDevice, addr(device.features)) device.formats = vulkanPhysicalDevice.getDeviceSurfaceFormats(surface) @@ -886,20 +886,17 @@ engine.vulkan.framebuffers) for i in 0 ..< MAX_FRAMES_IN_FLIGHT: - engine.vulkan.device.device.vkDestroySemaphore( - engine.vulkan.imageAvailableSemaphores[i], nil) - engine.vulkan.device.device.vkDestroySemaphore( - engine.vulkan.renderFinishedSemaphores[i], nil) + engine.vulkan.device.device.vkDestroySemaphore(engine.vulkan.imageAvailableSemaphores[i], nil) + engine.vulkan.device.device.vkDestroySemaphore(engine.vulkan.renderFinishedSemaphores[i], nil) engine.vulkan.device.device.vkDestroyFence(engine.vulkan.inFlightFences[i], nil) engine.vulkan.device.device.vkDestroyRenderPass(engine.vulkan.renderPass, nil) - engine.vulkan.device.device.vkDestroyCommandPool( - engine.vulkan.device.commandPool, nil) + engine.vulkan.device.device.vkDestroyCommandPool(engine.vulkan.device.commandPool, nil) engine.vulkan.instance.vkDestroySurfaceKHR(engine.vulkan.surface, nil) engine.vulkan.device.device.vkDestroyDevice(nil) when DEBUG_LOG: engine.vulkan.instance.vkDestroyDebugUtilsMessengerEXT(engine.vulkan.debugMessenger, nil) engine.window.trash() - engine.vulkan.instance.vkDestroyInstance( - nil) # needs to happen after window is trashed as the driver might have a hook registered for the window destruction + # needs to happen after window is trashed as the driver might have a hook registered for the window destruction + engine.vulkan.instance.vkDestroyInstance(nil) diff -r 2e9823f9193f -r e872cf354110 src/semicongine/vulkan.nim --- a/src/semicongine/vulkan.nim Mon Feb 27 00:05:26 2023 +0700 +++ b/src/semicongine/vulkan.nim Tue Feb 28 00:08:28 2023 +0700 @@ -1,2 +1,14 @@ import ./vulkan/api export api + +import ./vulkan/instance +export instance + +import ./vulkan/device +export device + +import ./vulkan/buffer +export buffer + +import ./vulkan/memory +export memory diff -r 2e9823f9193f -r e872cf354110 src/semicongine/vulkan/api.nim --- a/src/semicongine/vulkan/api.nim Mon Feb 27 00:05:26 2023 +0700 +++ b/src/semicongine/vulkan/api.nim Tue Feb 28 00:08:28 2023 +0700 @@ -2,6 +2,7 @@ import std/tables import std/strutils import std/logging +import std/typetraits import std/macros import std/private/digitsutils from typetraits import HoleyEnum @@ -135,6 +136,150 @@ VkVideoSessionParametersKHR* = distinct VkNonDispatchableHandle VkSemaphoreSciSyncPoolNV* = distinct VkNonDispatchableHandle VkRemoteAddressNV* = pointer +proc `$`*(handle: VkInstance): string = "VkInstance(" & $(uint(handle)) & ")" +proc valid*(handle: VkInstance): bool = uint(handle) != 0 +proc reset*(handle: var VkInstance) = handle = VkInstance(0) +proc `$`*(handle: VkPhysicalDevice): string = "VkPhysicalDevice(" & $(uint(handle)) & ")" +proc valid*(handle: VkPhysicalDevice): bool = uint(handle) != 0 +proc reset*(handle: var VkPhysicalDevice) = handle = VkPhysicalDevice(0) +proc `$`*(handle: VkDevice): string = "VkDevice(" & $(uint(handle)) & ")" +proc valid*(handle: VkDevice): bool = uint(handle) != 0 +proc reset*(handle: var VkDevice) = handle = VkDevice(0) +proc `$`*(handle: VkQueue): string = "VkQueue(" & $(uint(handle)) & ")" +proc valid*(handle: VkQueue): bool = uint(handle) != 0 +proc reset*(handle: var VkQueue) = handle = VkQueue(0) +proc `$`*(handle: VkCommandBuffer): string = "VkCommandBuffer(" & $(uint(handle)) & ")" +proc valid*(handle: VkCommandBuffer): bool = uint(handle) != 0 +proc reset*(handle: var VkCommandBuffer) = handle = VkCommandBuffer(0) +proc `$`*(handle: VkDeviceMemory): string = "VkDeviceMemory(" & $(uint(handle)) & ")" +proc valid*(handle: VkDeviceMemory): bool = uint(handle) != 0 +proc reset*(handle: var VkDeviceMemory) = handle = VkDeviceMemory(0) +proc `$`*(handle: VkCommandPool): string = "VkCommandPool(" & $(uint(handle)) & ")" +proc valid*(handle: VkCommandPool): bool = uint(handle) != 0 +proc reset*(handle: var VkCommandPool) = handle = VkCommandPool(0) +proc `$`*(handle: VkBuffer): string = "VkBuffer(" & $(uint(handle)) & ")" +proc valid*(handle: VkBuffer): bool = uint(handle) != 0 +proc reset*(handle: var VkBuffer) = handle = VkBuffer(0) +proc `$`*(handle: VkBufferView): string = "VkBufferView(" & $(uint(handle)) & ")" +proc valid*(handle: VkBufferView): bool = uint(handle) != 0 +proc reset*(handle: var VkBufferView) = handle = VkBufferView(0) +proc `$`*(handle: VkImage): string = "VkImage(" & $(uint(handle)) & ")" +proc valid*(handle: VkImage): bool = uint(handle) != 0 +proc reset*(handle: var VkImage) = handle = VkImage(0) +proc `$`*(handle: VkImageView): string = "VkImageView(" & $(uint(handle)) & ")" +proc valid*(handle: VkImageView): bool = uint(handle) != 0 +proc reset*(handle: var VkImageView) = handle = VkImageView(0) +proc `$`*(handle: VkShaderModule): string = "VkShaderModule(" & $(uint(handle)) & ")" +proc valid*(handle: VkShaderModule): bool = uint(handle) != 0 +proc reset*(handle: var VkShaderModule) = handle = VkShaderModule(0) +proc `$`*(handle: VkPipeline): string = "VkPipeline(" & $(uint(handle)) & ")" +proc valid*(handle: VkPipeline): bool = uint(handle) != 0 +proc reset*(handle: var VkPipeline) = handle = VkPipeline(0) +proc `$`*(handle: VkPipelineLayout): string = "VkPipelineLayout(" & $(uint(handle)) & ")" +proc valid*(handle: VkPipelineLayout): bool = uint(handle) != 0 +proc reset*(handle: var VkPipelineLayout) = handle = VkPipelineLayout(0) +proc `$`*(handle: VkSampler): string = "VkSampler(" & $(uint(handle)) & ")" +proc valid*(handle: VkSampler): bool = uint(handle) != 0 +proc reset*(handle: var VkSampler) = handle = VkSampler(0) +proc `$`*(handle: VkDescriptorSet): string = "VkDescriptorSet(" & $(uint(handle)) & ")" +proc valid*(handle: VkDescriptorSet): bool = uint(handle) != 0 +proc reset*(handle: var VkDescriptorSet) = handle = VkDescriptorSet(0) +proc `$`*(handle: VkDescriptorSetLayout): string = "VkDescriptorSetLayout(" & $(uint(handle)) & ")" +proc valid*(handle: VkDescriptorSetLayout): bool = uint(handle) != 0 +proc reset*(handle: var VkDescriptorSetLayout) = handle = VkDescriptorSetLayout(0) +proc `$`*(handle: VkDescriptorPool): string = "VkDescriptorPool(" & $(uint(handle)) & ")" +proc valid*(handle: VkDescriptorPool): bool = uint(handle) != 0 +proc reset*(handle: var VkDescriptorPool) = handle = VkDescriptorPool(0) +proc `$`*(handle: VkFence): string = "VkFence(" & $(uint(handle)) & ")" +proc valid*(handle: VkFence): bool = uint(handle) != 0 +proc reset*(handle: var VkFence) = handle = VkFence(0) +proc `$`*(handle: VkSemaphore): string = "VkSemaphore(" & $(uint(handle)) & ")" +proc valid*(handle: VkSemaphore): bool = uint(handle) != 0 +proc reset*(handle: var VkSemaphore) = handle = VkSemaphore(0) +proc `$`*(handle: VkEvent): string = "VkEvent(" & $(uint(handle)) & ")" +proc valid*(handle: VkEvent): bool = uint(handle) != 0 +proc reset*(handle: var VkEvent) = handle = VkEvent(0) +proc `$`*(handle: VkQueryPool): string = "VkQueryPool(" & $(uint(handle)) & ")" +proc valid*(handle: VkQueryPool): bool = uint(handle) != 0 +proc reset*(handle: var VkQueryPool) = handle = VkQueryPool(0) +proc `$`*(handle: VkFramebuffer): string = "VkFramebuffer(" & $(uint(handle)) & ")" +proc valid*(handle: VkFramebuffer): bool = uint(handle) != 0 +proc reset*(handle: var VkFramebuffer) = handle = VkFramebuffer(0) +proc `$`*(handle: VkRenderPass): string = "VkRenderPass(" & $(uint(handle)) & ")" +proc valid*(handle: VkRenderPass): bool = uint(handle) != 0 +proc reset*(handle: var VkRenderPass) = handle = VkRenderPass(0) +proc `$`*(handle: VkPipelineCache): string = "VkPipelineCache(" & $(uint(handle)) & ")" +proc valid*(handle: VkPipelineCache): bool = uint(handle) != 0 +proc reset*(handle: var VkPipelineCache) = handle = VkPipelineCache(0) +proc `$`*(handle: VkIndirectCommandsLayoutNV): string = "VkIndirectCommandsLayoutNV(" & $(uint(handle)) & ")" +proc valid*(handle: VkIndirectCommandsLayoutNV): bool = uint(handle) != 0 +proc reset*(handle: var VkIndirectCommandsLayoutNV) = handle = VkIndirectCommandsLayoutNV(0) +proc `$`*(handle: VkDescriptorUpdateTemplate): string = "VkDescriptorUpdateTemplate(" & $(uint(handle)) & ")" +proc valid*(handle: VkDescriptorUpdateTemplate): bool = uint(handle) != 0 +proc reset*(handle: var VkDescriptorUpdateTemplate) = handle = VkDescriptorUpdateTemplate(0) +proc `$`*(handle: VkSamplerYcbcrConversion): string = "VkSamplerYcbcrConversion(" & $(uint(handle)) & ")" +proc valid*(handle: VkSamplerYcbcrConversion): bool = uint(handle) != 0 +proc reset*(handle: var VkSamplerYcbcrConversion) = handle = VkSamplerYcbcrConversion(0) +proc `$`*(handle: VkValidationCacheEXT): string = "VkValidationCacheEXT(" & $(uint(handle)) & ")" +proc valid*(handle: VkValidationCacheEXT): bool = uint(handle) != 0 +proc reset*(handle: var VkValidationCacheEXT) = handle = VkValidationCacheEXT(0) +proc `$`*(handle: VkAccelerationStructureKHR): string = "VkAccelerationStructureKHR(" & $(uint(handle)) & ")" +proc valid*(handle: VkAccelerationStructureKHR): bool = uint(handle) != 0 +proc reset*(handle: var VkAccelerationStructureKHR) = handle = VkAccelerationStructureKHR(0) +proc `$`*(handle: VkAccelerationStructureNV): string = "VkAccelerationStructureNV(" & $(uint(handle)) & ")" +proc valid*(handle: VkAccelerationStructureNV): bool = uint(handle) != 0 +proc reset*(handle: var VkAccelerationStructureNV) = handle = VkAccelerationStructureNV(0) +proc `$`*(handle: VkPerformanceConfigurationINTEL): string = "VkPerformanceConfigurationINTEL(" & $(uint(handle)) & ")" +proc valid*(handle: VkPerformanceConfigurationINTEL): bool = uint(handle) != 0 +proc reset*(handle: var VkPerformanceConfigurationINTEL) = handle = VkPerformanceConfigurationINTEL(0) +proc `$`*(handle: VkBufferCollectionFUCHSIA): string = "VkBufferCollectionFUCHSIA(" & $(uint(handle)) & ")" +proc valid*(handle: VkBufferCollectionFUCHSIA): bool = uint(handle) != 0 +proc reset*(handle: var VkBufferCollectionFUCHSIA) = handle = VkBufferCollectionFUCHSIA(0) +proc `$`*(handle: VkDeferredOperationKHR): string = "VkDeferredOperationKHR(" & $(uint(handle)) & ")" +proc valid*(handle: VkDeferredOperationKHR): bool = uint(handle) != 0 +proc reset*(handle: var VkDeferredOperationKHR) = handle = VkDeferredOperationKHR(0) +proc `$`*(handle: VkPrivateDataSlot): string = "VkPrivateDataSlot(" & $(uint(handle)) & ")" +proc valid*(handle: VkPrivateDataSlot): bool = uint(handle) != 0 +proc reset*(handle: var VkPrivateDataSlot) = handle = VkPrivateDataSlot(0) +proc `$`*(handle: VkCuModuleNVX): string = "VkCuModuleNVX(" & $(uint(handle)) & ")" +proc valid*(handle: VkCuModuleNVX): bool = uint(handle) != 0 +proc reset*(handle: var VkCuModuleNVX) = handle = VkCuModuleNVX(0) +proc `$`*(handle: VkCuFunctionNVX): string = "VkCuFunctionNVX(" & $(uint(handle)) & ")" +proc valid*(handle: VkCuFunctionNVX): bool = uint(handle) != 0 +proc reset*(handle: var VkCuFunctionNVX) = handle = VkCuFunctionNVX(0) +proc `$`*(handle: VkOpticalFlowSessionNV): string = "VkOpticalFlowSessionNV(" & $(uint(handle)) & ")" +proc valid*(handle: VkOpticalFlowSessionNV): bool = uint(handle) != 0 +proc reset*(handle: var VkOpticalFlowSessionNV) = handle = VkOpticalFlowSessionNV(0) +proc `$`*(handle: VkMicromapEXT): string = "VkMicromapEXT(" & $(uint(handle)) & ")" +proc valid*(handle: VkMicromapEXT): bool = uint(handle) != 0 +proc reset*(handle: var VkMicromapEXT) = handle = VkMicromapEXT(0) +proc `$`*(handle: VkDisplayKHR): string = "VkDisplayKHR(" & $(uint(handle)) & ")" +proc valid*(handle: VkDisplayKHR): bool = uint(handle) != 0 +proc reset*(handle: var VkDisplayKHR) = handle = VkDisplayKHR(0) +proc `$`*(handle: VkDisplayModeKHR): string = "VkDisplayModeKHR(" & $(uint(handle)) & ")" +proc valid*(handle: VkDisplayModeKHR): bool = uint(handle) != 0 +proc reset*(handle: var VkDisplayModeKHR) = handle = VkDisplayModeKHR(0) +proc `$`*(handle: VkSurfaceKHR): string = "VkSurfaceKHR(" & $(uint(handle)) & ")" +proc valid*(handle: VkSurfaceKHR): bool = uint(handle) != 0 +proc reset*(handle: var VkSurfaceKHR) = handle = VkSurfaceKHR(0) +proc `$`*(handle: VkSwapchainKHR): string = "VkSwapchainKHR(" & $(uint(handle)) & ")" +proc valid*(handle: VkSwapchainKHR): bool = uint(handle) != 0 +proc reset*(handle: var VkSwapchainKHR) = handle = VkSwapchainKHR(0) +proc `$`*(handle: VkDebugReportCallbackEXT): string = "VkDebugReportCallbackEXT(" & $(uint(handle)) & ")" +proc valid*(handle: VkDebugReportCallbackEXT): bool = uint(handle) != 0 +proc reset*(handle: var VkDebugReportCallbackEXT) = handle = VkDebugReportCallbackEXT(0) +proc `$`*(handle: VkDebugUtilsMessengerEXT): string = "VkDebugUtilsMessengerEXT(" & $(uint(handle)) & ")" +proc valid*(handle: VkDebugUtilsMessengerEXT): bool = uint(handle) != 0 +proc reset*(handle: var VkDebugUtilsMessengerEXT) = handle = VkDebugUtilsMessengerEXT(0) +proc `$`*(handle: VkVideoSessionKHR): string = "VkVideoSessionKHR(" & $(uint(handle)) & ")" +proc valid*(handle: VkVideoSessionKHR): bool = uint(handle) != 0 +proc reset*(handle: var VkVideoSessionKHR) = handle = VkVideoSessionKHR(0) +proc `$`*(handle: VkVideoSessionParametersKHR): string = "VkVideoSessionParametersKHR(" & $(uint(handle)) & ")" +proc valid*(handle: VkVideoSessionParametersKHR): bool = uint(handle) != 0 +proc reset*(handle: var VkVideoSessionParametersKHR) = handle = VkVideoSessionParametersKHR(0) +proc `$`*(handle: VkSemaphoreSciSyncPoolNV): string = "VkSemaphoreSciSyncPoolNV(" & $(uint(handle)) & ")" +proc valid*(handle: VkSemaphoreSciSyncPoolNV): bool = uint(handle) != 0 +proc reset*(handle: var VkSemaphoreSciSyncPoolNV) = handle = VkSemaphoreSciSyncPoolNV(0) type VkFramebufferCreateFlags* = distinct VkFlags VkQueryPoolCreateFlags* = distinct VkFlags @@ -3314,13 +3459,13 @@ VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2 VkMemoryDecompressionMethodFlagBitsNV* {.size: 8.} = enum VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_NV = 0b0000000000000000000000000000000000000000000000000000000000000001 -converter BitsetToNumber*(flags: openArray[VkMemoryDecompressionMethodFlagBitsNV]): VkMemoryDecompressionMethodFlagsNV = - for flag in flags: - result = VkMemoryDecompressionMethodFlagsNV(int64(result) or int64(flag)) -converter NumberToBitset*(number: VkMemoryDecompressionMethodFlagsNV): seq[VkMemoryDecompressionMethodFlagBitsNV] = - for value in VkMemoryDecompressionMethodFlagBitsNV.items: - if (value.ord and int64(number)) > 0: - result.add value +func toBits*(flags: openArray[VkMemoryDecompressionMethodFlagBitsNV]): VkMemoryDecompressionMethodFlagsNV = + for flag in flags: + result = VkMemoryDecompressionMethodFlagsNV(uint64(result) or uint64(flag)) +func toEnums*(number: VkMemoryDecompressionMethodFlagsNV): seq[VkMemoryDecompressionMethodFlagBitsNV] = + for value in VkMemoryDecompressionMethodFlagBitsNV.items: + if (cast[uint64](value) and uint64(number)) > 0: + result.add value type VkPerformanceCounterUnitKHR* {.size: sizeof(cint).} = enum VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR = 0 @@ -3496,13 +3641,13 @@ VK_ACCESS_2_MICROMAP_READ_BIT_EXT = 0b0000000000000000000100000000000000000000000000000000000000000000 VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT = 0b0000000000000000001000000000000000000000000000000000000000000000 VK_ACCESS_2_RESERVED_46_BIT_EXT = 0b0000000000000000010000000000000000000000000000000000000000000000 -converter BitsetToNumber*(flags: openArray[VkAccessFlagBits2]): VkAccessFlags2 = - for flag in flags: - result = VkAccessFlags2(int64(result) or int64(flag)) -converter NumberToBitset*(number: VkAccessFlags2): seq[VkAccessFlagBits2] = - for value in VkAccessFlagBits2.items: - if (value.ord and int64(number)) > 0: - result.add value +func toBits*(flags: openArray[VkAccessFlagBits2]): VkAccessFlags2 = + for flag in flags: + result = VkAccessFlags2(uint64(result) or uint64(flag)) +func toEnums*(number: VkAccessFlags2): seq[VkAccessFlagBits2] = + for value in VkAccessFlagBits2.items: + if (cast[uint64](value) and uint64(number)) > 0: + result.add value const VK_ACCESS_2_NONE* = 0 type @@ -3548,13 +3693,13 @@ VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0b0000000000000000000000001000000000000000000000000000000000000000 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0b0000000000000000000000010000000000000000000000000000000000000000 VK_PIPELINE_STAGE_2_CLUSTER_CULLING_SHADER_BIT_HUAWEI = 0b0000000000000000000000100000000000000000000000000000000000000000 -converter BitsetToNumber*(flags: openArray[VkPipelineStageFlagBits2]): VkPipelineStageFlags2 = - for flag in flags: - result = VkPipelineStageFlags2(int64(result) or int64(flag)) -converter NumberToBitset*(number: VkPipelineStageFlags2): seq[VkPipelineStageFlagBits2] = - for value in VkPipelineStageFlagBits2.items: - if (value.ord and int64(number)) > 0: - result.add value +func toBits*(flags: openArray[VkPipelineStageFlagBits2]): VkPipelineStageFlags2 = + for flag in flags: + result = VkPipelineStageFlags2(uint64(result) or uint64(flag)) +func toEnums*(number: VkPipelineStageFlags2): seq[VkPipelineStageFlagBits2] = + for value in VkPipelineStageFlagBits2.items: + if (cast[uint64](value) and uint64(number)) > 0: + result.add value const VK_PIPELINE_STAGE_2_NONE* = 0 type @@ -3974,13 +4119,13 @@ VK_FORMAT_FEATURE_2_OPTICAL_FLOW_COST_BIT_NV = 0b0000000000000000000001000000000000000000000000000000000000000000 VK_FORMAT_FEATURE_2_RESERVED_44_BIT_EXT = 0b0000000000000000000100000000000000000000000000000000000000000000 VK_FORMAT_FEATURE_2_RESERVED_45_BIT_EXT = 0b0000000000000000001000000000000000000000000000000000000000000000 -converter BitsetToNumber*(flags: openArray[VkFormatFeatureFlagBits2]): VkFormatFeatureFlags2 = - for flag in flags: - result = VkFormatFeatureFlags2(int64(result) or int64(flag)) -converter NumberToBitset*(number: VkFormatFeatureFlags2): seq[VkFormatFeatureFlagBits2] = - for value in VkFormatFeatureFlagBits2.items: - if (value.ord and int64(number)) > 0: - result.add value +func toBits*(flags: openArray[VkFormatFeatureFlagBits2]): VkFormatFeatureFlags2 = + for flag in flags: + result = VkFormatFeatureFlags2(uint64(result) or uint64(flag)) +func toEnums*(number: VkFormatFeatureFlags2): seq[VkFormatFeatureFlagBits2] = + for value in VkFormatFeatureFlagBits2.items: + if (cast[uint64](value) and uint64(number)) > 0: + result.add value type VkRenderingFlagBits* {.size: sizeof(cint).} = enum VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0b00000000000000000000000000000001 @@ -4286,6 +4431,130 @@ VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT = 6 VkDeviceFaultVendorBinaryHeaderVersionEXT* {.size: sizeof(cint).} = enum VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT_ENUM = 1 +proc `$`*(bitset: VkFramebufferCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkRenderPassCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkSamplerCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineCacheCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineShaderStageCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkDescriptorSetLayoutCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkInstanceCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkDeviceQueueCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkBufferCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkBufferUsageFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkColorComponentFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkCommandPoolCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkCommandPoolResetFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkCommandBufferResetFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkCommandBufferUsageFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkCullModeFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkFenceCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkFormatFeatureFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkImageAspectFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkImageCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkImageUsageFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkImageViewCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkMemoryHeapFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkAccessFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkMemoryPropertyFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkQueryControlFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkQueryPipelineStatisticFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkQueryResultFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkQueueFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkShaderStageFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkSparseMemoryBindFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkStencilFaceFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineStageFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkSparseImageFormatFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkSampleCountFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkAttachmentDescriptionFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkDescriptorPoolCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkDependencyFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkEventCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineLayoutCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkIndirectCommandsLayoutUsageFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkIndirectStateFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkPrivateDataSlotCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkSubpassDescriptionFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkResolveModeFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkDescriptorBindingFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkConditionalRenderingFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkGeometryFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkGeometryInstanceFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkBuildAccelerationStructureFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkAccelerationStructureCreateFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkDeviceDiagnosticsConfigFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineCreationFeedbackFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkPerformanceCounterDescriptionFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkSemaphoreWaitFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkToolPurposeFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkAccessFlags2): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineStageFlags2): string = $toEnums(bitset) +proc `$`*(bitset: VkImageConstraintsInfoFlagsFUCHSIA): string = $toEnums(bitset) +proc `$`*(bitset: VkFormatFeatureFlags2): string = $toEnums(bitset) +proc `$`*(bitset: VkRenderingFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineDepthStencilStateCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkPipelineColorBlendStateCreateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkImageCompressionFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkImageCompressionFixedRateFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkExportMetalObjectTypeFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkDeviceAddressBindingFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkBuildMicromapFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkMicromapCreateFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkMemoryDecompressionMethodFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkCompositeAlphaFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkDisplayPlaneAlphaFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkSurfaceTransformFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkDebugReportFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkExternalMemoryHandleTypeFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkExternalMemoryFeatureFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkExternalMemoryHandleTypeFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkExternalMemoryFeatureFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkExternalSemaphoreHandleTypeFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkExternalSemaphoreFeatureFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkSemaphoreImportFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkExternalFenceHandleTypeFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkExternalFenceFeatureFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkFenceImportFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkSurfaceCounterFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkPeerMemoryFeatureFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkMemoryAllocateFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkDeviceGroupPresentModeFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkSwapchainCreateFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkSubgroupFeatureFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkDebugUtilsMessageSeverityFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkDebugUtilsMessageTypeFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkSwapchainImageUsageFlagsANDROID): string = $toEnums(bitset) +proc `$`*(bitset: VkSubmitFlags): string = $toEnums(bitset) +proc `$`*(bitset: VkGraphicsPipelineLibraryFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkOpticalFlowGridSizeFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkOpticalFlowUsageFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkOpticalFlowSessionCreateFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkOpticalFlowExecuteFlagsNV): string = $toEnums(bitset) +proc `$`*(bitset: VkPresentScalingFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkPresentGravityFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoCodecOperationFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoChromaSubsamplingFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoComponentBitDepthFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoCapabilityFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoSessionCreateFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoCodingControlFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoDecodeUsageFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoDecodeCapabilityFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoDecodeH264PictureLayoutFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeUsageFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeContentFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeCapabilityFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeRateControlModeFlagsKHR): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeH264CapabilityFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeH264InputModeFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeH264OutputModeFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeH265CapabilityFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeH265InputModeFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeH265OutputModeFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeH265CtbSizeFlagsEXT): string = $toEnums(bitset) +proc `$`*(bitset: VkVideoEncodeH265TransformBlockSizeFlagsEXT): string = $toEnums(bitset) +type VkGeometryFlagsNV* = VkGeometryFlagsKHR VkGeometryInstanceFlagsNV* = VkGeometryInstanceFlagsKHR VkBuildAccelerationStructureFlagsNV* = VkBuildAccelerationStructureFlagsKHR @@ -11626,4 +11895,4 @@ converter VkBool2NimBool*(a: VkBool32): bool = a > 0 converter NimBool2VkBool*(a: bool): VkBool32 = VkBool32(a) -proc `$`*(x: uint32): string {.raises: [].} = addInt(result, x) +proc `$`*(x: uint32): string {.raises: [].} = addInt(result, x) \ No newline at end of file diff -r 2e9823f9193f -r e872cf354110 src/semicongine/vulkan/buffer.nim --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/semicongine/vulkan/buffer.nim Tue Feb 28 00:08:28 2023 +0700 @@ -0,0 +1,31 @@ +import ./api + +type + Buffer = object + device: VkDevice + vk: VkBuffer + size: uint64 + +# currently no support for extended structure and concurrent/shared use +# (shardingMode = VK_SHARING_MODE_CONCURRENT not supported) +proc createBuffer(device: VkDevice, size: uint64, flags: openArray[VkBufferCreateFlagBits], usage: openArray[VkBufferUsageFlagBits]): Buffer = + result.device = device + result.size = size + var createInfo = VkBufferCreateInfo( + sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + flags: toBits(flags), + size: size, + usage: toBits(usage), + sharingMode: VK_SHARING_MODE_EXCLUSIVE, + ) + + checkVkResult vkCreateBuffer( + device=device, + pCreateInfo=addr createInfo, + pAllocator=nil, + pBuffer=addr result.vk + ) + +proc destroy(buffer: Buffer) = + if uint(buffer.vk) != 0: + vkDestroyBuffer(buffer.device, buffer.vk, nil) diff -r 2e9823f9193f -r e872cf354110 src/semicongine/vulkan/buffers.nim --- a/src/semicongine/vulkan/buffers.nim Mon Feb 27 00:05:26 2023 +0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -import ./api - -type - Buffer = object - device: VkDevice - vk: VkBuffer - size: uint64 - -# currently no support for extended structure and concurrent/shared use -# (shardingMode = VK_SHARING_MODE_CONCURRENT not supported) -proc createBuffer(device: VkDevice, size: uint64, flags: openArray[VkBufferCreateFlagBits], usage: openArray[VkBufferUsageFlagBits]): Buffer = - result.device = device - result.size = size - var createInfo = VkBufferCreateInfo( - sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - flags: toBits(flags), - size: size, - usage: toBits(usage), - sharingMode: VK_SHARING_MODE_EXCLUSIVE, - ) - - checkVkResult vkCreateBuffer( - device=device, - pCreateInfo=addr createInfo, - pAllocator=nil, - pBuffer=addr result.vk - ) - -proc destroy(buffer: Buffer) = - if uint(buffer.vk) != 0: - vkDestroyBuffer(buffer.device, buffer.vk, nil) diff -r 2e9823f9193f -r e872cf354110 src/semicongine/vulkan/device.nim --- a/src/semicongine/vulkan/device.nim Mon Feb 27 00:05:26 2023 +0700 +++ b/src/semicongine/vulkan/device.nim Tue Feb 28 00:08:28 2023 +0700 @@ -3,48 +3,60 @@ import ./instance type - PhysicalDevice = object + PhysicalDevice* = object vk: VkPhysicalDevice - Device = object + Device* = object physicalDevice: PhysicalDevice vk: VkDevice - QueueFamily = object - vk: VkQueueFamilyProperties + QueueFamily* = object + properties: VkQueueFamilyProperties index: uint32 - Queue = object + Queue* = object vk: VkQueue -proc getDeviceExtensions*(device: VkPhysicalDevice): seq[string] = +proc getPhysicalDevices*(instance: Instance): seq[PhysicalDevice] = + assert instance.vk.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: + result.add PhysicalDevice(vk: devices[i]) + +proc getExtensions*(device: PhysicalDevice): seq[string] = + assert device.vk.valid var extensionCount: uint32 - checkVkResult vkEnumerateDeviceExtensionProperties(device, nil, addr(extensionCount), nil) + checkVkResult vkEnumerateDeviceExtensionProperties(device.vk, nil, addr(extensionCount), nil) if extensionCount > 0: var extensions = newSeq[VkExtensionProperties](extensionCount) - checkVkResult vkEnumerateDeviceExtensionProperties(device, nil, addr(extensionCount), addr extensions[0]) + checkVkResult vkEnumerateDeviceExtensionProperties(device.vk, nil, addr(extensionCount), extensions.toCPointer) for extension in extensions: result.add(cleanString(extension.extensionName)) -proc getVulkanPhysicalDevices*(instance: Instance): seq[PhysicalDevice] = - var nDevices: uint32 - checkVkResult vkEnumeratePhysicalDevices(instance.vk, addr(nDevices), nil) - var devices = newSeq[VkPhysicalDevice](nDevices) - checkVkResult vkEnumeratePhysicalDevices(instance.vk, addr(nDevices), addr devices[0]) - for i in 0 ..< nDevices: - result.add PhysicalDevice(vk: devices[i]) - 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 , addr queuFamilies[0]) + vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies , queuFamilies.toCPointer) for i in 0 ..< nQueuefamilies: - result.add QueueFamily(vk: queuFamilies[i], index: i) + result.add QueueFamily(properties: queuFamilies[i], index: i) -proc createDevice( +func canGraphics*(family: QueueFamily): bool = + VK_QUEUE_GRAPHICS_BIT in family.properties.queueFlags.toEnums +func canTransfer*(family: QueueFamily): bool = + VK_QUEUE_TRANSFER_BIT in family.properties.queueFlags.toEnums +func canCompute*(family: QueueFamily): bool = + VK_QUEUE_COMPUTE_BIT in family.properties.queueFlags.toEnums + +proc createDevice*( physicalDevice: PhysicalDevice, enabledLayers: openArray[string], enabledExtensions: openArray[string], queueFamilies: openArray[QueueFamily], ): Device = + assert physicalDevice.vk.valid + assert queueFamilies.len > 0 result.physicalDevice = physicalDevice var enabledLayersC = allocCStringArray(enabledLayers) @@ -62,7 +74,7 @@ var createInfo = VkDeviceCreateInfo( sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, queueCreateInfoCount: uint32(deviceQueues.len), - pQueueCreateInfos: addr deviceQueues[0], + pQueueCreateInfos: deviceQueues.toCPointer, enabledLayerCount: uint32(enabledLayers.len), ppEnabledLayerNames: enabledLayersC, enabledExtensionCount: uint32(enabledExtensions.len), @@ -78,3 +90,8 @@ ) deallocCStringArray(enabledLayersC) deallocCStringArray(enabledExtensionsC) + +proc destroy*(device: var Device) = + assert device.vk.valid + device.vk.vkDestroyDevice(nil) + device.vk.reset() diff -r 2e9823f9193f -r e872cf354110 src/semicongine/vulkan/instance.nim --- a/src/semicongine/vulkan/instance.nim Mon Feb 27 00:05:26 2023 +0700 +++ b/src/semicongine/vulkan/instance.nim Tue Feb 28 00:08:28 2023 +0700 @@ -6,10 +6,10 @@ type Instance* = object vk*: VkInstance - Debugger = object - instance: VkInstance + Debugger* = object + instance: Instance messenger: VkDebugUtilsMessengerEXT - DebugCallback = proc ( + DebugCallback* = proc ( messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT, messageTypes: VkDebugUtilsMessageTypeFlagsEXT, pCallbackData: ptr VkDebugUtilsMessengerCallbackDataEXT, @@ -18,10 +18,10 @@ proc getInstanceExtensions*(): seq[string] = var extensionCount: uint32 - checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr( extensionCount), nil) + checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), nil) if extensionCount > 0: var extensions = newSeq[VkExtensionProperties](extensionCount) - checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr( extensionCount), addr extensions[0]) + checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), extensions.toCPointer) for extension in extensions: result.add(cleanString(extension.extensionName)) @@ -30,14 +30,14 @@ checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), nil) if n_layers > 0: var layers = newSeq[VkLayerProperties](n_layers) - checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), addr layers[0]) + checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), layers.toCPointer) for layer in layers: result.add(cleanString(layer.layerName)) proc createInstance*( vulkanVersion: uint32, - instanceExtensions: seq[string], - layers: seq[string], + instanceExtensions: openArray[string], + layers: openArray[string], name = "defaultVulkanInstance", engine = "defaultEngine", ): Instance = @@ -61,14 +61,17 @@ ppEnabledExtensionNames: instanceExtensionsC ) checkVkResult vkCreateInstance(addr(createinfo), nil, addr(result.vk)) + result.vk.loadVulkan() deallocCStringArray(layersC) deallocCStringArray(instanceExtensionsC) for extension in instanceExtensions: result.vk.loadExtension($extension) -proc destroy(instance: Instance) = +proc destroy*(instance: var Instance) = + assert instance.vk.valid # needs to happen after window is trashed as the driver might have a hook registered for the window destruction instance.vk.vkDestroyInstance(nil) + instance.vk.reset() proc defaultDebugCallback( messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT, @@ -79,12 +82,13 @@ echo &"{messageSeverity}: {toEnums messageTypes}: {pCallbackData.pMessage}" return false -proc createDebugMessenger( - instance: VkInstance, +proc createDebugMessenger*( + instance: Instance, severityLevels: openArray[VkDebugUtilsMessageSeverityFlagBitsEXT] = @[], types: openArray[VkDebugUtilsMessageTypeFlagBitsEXT] = @[], callback: DebugCallback=defaultDebugCallback ): Debugger = + assert instance.vk.valid result.instance = instance var severityLevelBits = high(VkDebugUtilsMessageSeverityFlagsEXT) var typeBits = high(VkDebugUtilsMessageTypeFlagsEXT) @@ -99,7 +103,10 @@ pfnUserCallback: callback, pUserData: nil, ) - checkVkResult instance.vkCreateDebugUtilsMessengerEXT(addr(createInfo), nil, addr(result.messenger)) + checkVkResult instance.vk.vkCreateDebugUtilsMessengerEXT(addr(createInfo), nil, addr(result.messenger)) -proc destroy(debugger: Debugger) = - debugger.instance.vkDestroyDebugUtilsMessengerEXT(debugger.messenger, nil) +proc destroy*(debugger: var Debugger) = + assert debugger.messenger.valid + assert debugger.instance.vk.valid + debugger.instance.vk.vkDestroyDebugUtilsMessengerEXT(debugger.messenger, nil) + debugger.messenger.reset() diff -r 2e9823f9193f -r e872cf354110 src/semicongine/vulkan/utils.nim --- a/src/semicongine/vulkan/utils.nim Mon Feb 27 00:05:26 2023 +0700 +++ b/src/semicongine/vulkan/utils.nim Tue Feb 28 00:08:28 2023 +0700 @@ -6,3 +6,5 @@ result = join(str[0 ..< i]) break +func toCPointer*[T](list: var seq[T]): ptr T = + if list.len > 0: addr list[0] else: nil diff -r 2e9823f9193f -r e872cf354110 src/semicongine/vulkan_helpers.nim --- a/src/semicongine/vulkan_helpers.nim Mon Feb 27 00:05:26 2023 +0700 +++ b/src/semicongine/vulkan_helpers.nim Tue Feb 28 00:08:28 2023 +0700 @@ -81,8 +81,7 @@ var n_queuefamilies: uint32 vkGetPhysicalDeviceQueueFamilyProperties(device, addr(n_queuefamilies), nil) result = newSeq[VkQueueFamilyProperties](n_queuefamilies) - vkGetPhysicalDeviceQueueFamilyProperties(device, addr(n_queuefamilies), - addrOrNil(result)) + vkGetPhysicalDeviceQueueFamilyProperties(device, addr(n_queuefamilies), addrOrNil(result)) proc getDeviceSurfaceFormats*(device: VkPhysicalDevice, diff -r 2e9823f9193f -r e872cf354110 src/vulkan_api/vulkan_api_generator.nim --- a/src/vulkan_api/vulkan_api_generator.nim Mon Feb 27 00:05:26 2023 +0700 +++ b/src/vulkan_api/vulkan_api_generator.nim Tue Feb 28 00:08:28 2023 +0700 @@ -127,7 +127,8 @@ result = &"array[{arraylen}, {result}]" # serializers -func serializeEnum(node: XmlNode, api: XmlNode): seq[string] = +# return values and whether this is a bitfield +func serializeEnum(node: XmlNode, api: XmlNode): (seq[string], string) = let name = node.attr("name") if name == "": return result @@ -206,13 +207,13 @@ else: values[smartParseInt(value.attr("value"))] = value.attr("name") if values.len > 0: - result.add " " & name & "* {.size: sizeof(cint).} = enum" + result[0].add " " & name & "* {.size: sizeof(cint).} = enum" for (value, name) in tableSorted(values): var thename = name if name.replace("_", "").toLower() in reservedNames: thename = thename & "_ENUM" let enumEntry = &" {thename} = {value}" - result.add enumEntry + result[0].add enumEntry # generate bitsets (normal enums in the C API, but bitfield-enums in Nim) elif node.attr("type") == "bitmask": @@ -226,41 +227,42 @@ predefined_enum_sets.add &" {value.attr(\"name\")}* = {value.attr(\"value\")}" if values.len > 0: + let cApiName = name.replace("FlagBits", "Flags") + result[1] = cApiName if node.hasAttr("bitwidth"): - result.add " " & name & "* {.size: 8.} = enum" + result[0].add " " & name & "* {.size: 8.} = enum" else: - result.add " " & name & "* {.size: sizeof(cint).} = enum" + result[0].add " " & name & "* {.size: sizeof(cint).} = enum" for (bitpos, enumvalue) in tableSorted(values): var value = "00000000000000000000000000000000"# makes the bit mask nicely visible if node.hasAttr("bitwidth"): # assumes this is always 64 value = value & value value[^(bitpos + 1)] = '1' let enumEntry = &" {enumvalue} = 0b{value}" - if not (enumEntry in result): # the specs define duplicate entries for backwards compat - result.add enumEntry - let cApiName = name.replace("FlagBits", "Flags") + if not (enumEntry in result[0]): # the specs define duplicate entries for backwards compat + result[0].add enumEntry if node.hasAttr("bitwidth"): # assuming this attribute is always 64 if values.len > 0: - result.add &"""converter BitsetToNumber*(flags: openArray[{name}]): {cApiName} = + result[0].add &"""func toBits*(flags: openArray[{name}]): {cApiName} = for flag in flags: - result = {cApiName}(int64(result) or int64(flag))""" - result.add &"""converter NumberToBitset*(number: {cApiName}): seq[{name}] = - for value in {name}.items: - if (value.ord and int64(number)) > 0: - result.add value""" + result = {cApiName}(uint64(result) or uint64(flag))""" + result[0].add &"""func toEnums*(number: {cApiName}): seq[{name}] = + for value in {name}.items: + if (cast[uint64](value) and uint64(number)) > 0: + result.add value""" else: if values.len > 0: - result.add &"""func toBits*(flags: openArray[{name}]): {cApiName} = + result[0].add &"""func toBits*(flags: openArray[{name}]): {cApiName} = for flag in flags: result = {cApiName}(uint(result) or uint(flag))""" - result.add &"""func toEnums*(number: {cApiName}): seq[{name}] = + result[0].add &"""func toEnums*(number: {cApiName}): seq[{name}] = for value in {name}.items: if (value.ord and cint(number)) > 0: result.add value""" if predefined_enum_sets.len > 0: - result.add "const" - result.add predefined_enum_sets - result.add "type" + result[0].add "const" + result[0].add predefined_enum_sets + result[0].add "type" func serializeStruct(node: XmlNode): seq[string] = @@ -416,6 +418,7 @@ "import std/tables", "import std/strutils", "import std/logging", + "import std/typetraits", "import std/macros", "import std/private/digitsutils", "from typetraits import HoleyEnum", @@ -465,10 +468,24 @@ if thetype.attr("category") == "bitmask" and not thetype.hasAttr("alias") and (not thetype.hasAttr("api") or thetype.attr("api") == "vulkan"): let name = thetype.child("name")[0].text outputFiles["enums"].add &" {name}* = distinct VkFlags" + + var bitfields: Table[string, string] outputFiles["enums"].add "let vkGetInstanceProcAddr = cast[proc(instance: VkInstance, name: cstring): pointer {.stdcall.}](checkedSymAddr(vulkanLib, \"vkGetInstanceProcAddr\"))" outputFiles["enums"].add "type" for theenum in api.findAll("enums"): - outputFiles["enums"].add serializeEnum(theenum, api) + let (enums, bitFieldName) = serializeEnum(theenum, api) + outputFiles["enums"].add enums + if bitFieldName != "": + bitfields[theenum.attr("name")] = bitFieldName + + # bitmask-to-string functions + for thetype in api.findAll("type"): + if thetype.attr("name") in bitfields: + let name = bitfields[thetype.attr("name")] + let stringfunc = &"proc `$`*(bitset: {name}): string = $toEnums(bitset)" + if not (stringfunc in outputFiles["enums"]): + outputFiles["enums"].add stringfunc + outputFiles["enums"].add "type" # structs and function types need to be in same "type" block to avoid forward-declarations outputFiles["structs"].add serializeFunctiontypes(api) @@ -494,6 +511,15 @@ for thetype in typesgroup.findAll("type"): outputFiles.update serializeType(thetype, headerTypes) + for typesgroup in api.findAll("types"): + for node in typesgroup.findAll("type"): + if node.attr("category") == "handle": + if not node.hasAttr("alias"): + let name = node.child("name")[0].text + outputFiles["basetypes"].add &"proc `$`*(handle: {name}): string = \"{name}(\" & $(uint(handle)) & \")\"" + outputFiles["basetypes"].add &"proc valid*(handle: {name}): bool = uint(handle) != 0" + outputFiles["basetypes"].add &"proc reset*(handle: var {name}) = handle = {name}(0)" + # commands aka functions var varDecls: Table[string, string] var procLoads: Table[string, string] # procloads need to be packed into feature/extension loader procs