Mercurial > games > semicongine
comparison fuhtark_test/generate_vulkan_api.sh @ 1501:f40d9d814c08 default tip
did: correct vulkan-api generator
| author | sam <sam@basx.dev> |
|---|---|
| date | Wed, 26 Nov 2025 23:34:29 +0700 |
| parents | 91c8c3b7cbf0 |
| children |
comparison
equal
deleted
inserted
replaced
| 1500:91c8c3b7cbf0 | 1501:f40d9d814c08 |
|---|---|
| 1 #!/bin/sh -e | 1 #!/bin/sh -e |
| 2 | 2 |
| 3 # Variables | 3 # Variables |
| 4 BASE_INCLUDE=$( realpath $( dirname $0 ) )"/include" | 4 VULKAN_VERSION=1.4.334 |
| 5 WIN_INCLUDE=$( realpath $( dirname $0 ) )"/include/winapi" | 5 HOME_DIR=$( realpath $( dirname $0 ) ) |
| 6 BASE_INCLUDE="$HOME_DIR/include" | |
| 7 WIN_INCLUDE="$HOME_DIR/include/winapi" | |
| 8 VULKAN_INCLUDE="$HOME_DIR/Vulkan-Headers-$VULKAN_VERSION/include/vulkan" | |
| 6 OUT_BIN=vulkan | 9 OUT_BIN=vulkan |
| 7 OUTFILE=$OUT_BIN.nim | 10 OUTFILE=$OUT_BIN.nim |
| 8 OUTFILE_FUTHARK=$OUT_BIN".gen.nim" | 11 OUTFILE_FUTHARK=$OUT_BIN".gen.nim" |
| 12 | |
| 13 # setup | |
| 14 # sudo apt install clang libclang-dev | |
| 15 # nimble install futhark | |
| 16 # rm -rf Vulkan-Headers-$VULKAN_VERSION | |
| 17 # curl -L https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/v$VULKAN_VERSION.tar.gz | tar -xzf - | |
| 9 | 18 |
| 10 # Convert C-headers to Nim using Futhark, if not existing yet | 19 # Convert C-headers to Nim using Futhark, if not existing yet |
| 11 NIM_GEN_CODE='import futhark, os | 20 NIM_GEN_CODE='import futhark, os |
| 12 importc: | 21 importc: |
| 13 outputPath "'"$OUTFILE_FUTHARK"'" | 22 outputPath "'"$OUTFILE_FUTHARK"'" |
| 14 define VK_USE_PLATFORM_WIN32_KHR | 23 define VK_USE_PLATFORM_WIN32_KHR |
| 15 define VK_USE_PLATFORM_XLIB_KHR | 24 define VK_USE_PLATFORM_XLIB_KHR |
| 25 define VK_ENABLE_BETA_EXTENSIONS | |
| 16 sysPath "'"$BASE_INCLUDE"'" | 26 sysPath "'"$BASE_INCLUDE"'" |
| 17 sysPath "'"$WIN_INCLUDE"'" | 27 sysPath "'"$WIN_INCLUDE"'" |
| 18 path "/usr/include/vulkan" | 28 path "'"$VULKAN_INCLUDE"'" |
| 19 "vulkan.h"' | 29 "vulkan.h"' |
| 20 | 30 |
| 21 if [ ! -f $OUTFILE_FUTHARK ] ; then | 31 if [ ! -f $OUTFILE_FUTHARK ] ; then |
| 22 nim c --maxLoopIterationsVM:1000000000 --eval:"$NIM_GEN_CODE" | 32 nim c --maxLoopIterationsVM:1000000000 --eval:"$NIM_GEN_CODE" |
| 23 fi | 33 fi |
| 34 sed -i '/struct_Vk.*pure,$/{N;s/\n/ /}' $OUTFILE | 44 sed -i '/struct_Vk.*pure,$/{N;s/\n/ /}' $OUTFILE |
| 35 sed -i '/struct_Vk.* {\.$/{N;s/\n/ /}' $OUTFILE | 45 sed -i '/struct_Vk.* {\.$/{N;s/\n/ /}' $OUTFILE |
| 36 | 46 |
| 37 # set default struct values for member "sType" | 47 # set default struct values for member "sType" |
| 38 # not very clean, as we "abuse" the fact that Nim does not differentiate between camel-case and snake-case for identifiers | 48 # not very clean, as we "abuse" the fact that Nim does not differentiate between camel-case and snake-case for identifiers |
| 49 | |
| 50 # VkStructureType_1124073999 = (when declared(VkStructureType): | |
| 51 TYPESTRUCTNAME=$( cat $OUTFILE | awk '/enum_VkStructureType\* =/ { print $3; }' ) | |
| 39 awk -i inplace '{ | 52 awk -i inplace '{ |
| 40 if ( $0 ~ /^ struct_Vk.* = object/ && ! $0 ~ /VkBaseInStructure/ ) { | 53 if ( $0 ~ /^ struct_Vk.* = object/ && $0 !~ /VkBaseInStructure/ && $0 !~ /VkBaseOutStructure/ ) { |
| 41 split($0, arr, "_"); | 54 split($0, arr, "_"); |
| 42 print $0; | 55 print $0; |
| 43 getline; | 56 getline; |
| 44 if ( $0 ~ / sType\*:/ ) { | 57 if ( $0 ~ / sType\*:/ ) { |
| 45 split($0, arr2, "##"); | 58 split($0, arr2, "##"); |
| 46 print arr2[1] "= VK_STRUCTURE_TYPE_" substr(arr[2], 3) " ##" arr2[2]; | 59 print " sType*: '$TYPESTRUCTNAME' = '$TYPESTRUCTNAME'.VK_STRUCTURE_TYPE_" substr(arr[2], 3) " ##" arr2[2]; |
| 47 } else { | 60 } else { |
| 48 print; | 61 print; |
| 49 } | 62 } |
| 50 } else { | 63 } else { |
| 51 print; | 64 print; |
| 59 cat <<EOF >> $OUTFILE | 72 cat <<EOF >> $OUTFILE |
| 60 | 73 |
| 61 import std/dynlib | 74 import std/dynlib |
| 62 import std/strutils | 75 import std/strutils |
| 63 import std/logging | 76 import std/logging |
| 77 import std/envvars | |
| 64 | 78 |
| 65 var vkInstance*: VkInstance = VkInstance(nil) | 79 var vkInstance*: VkInstance = VkInstance(nil) |
| 66 var vkPhysicalDevices: seq[VkPhysicalDevice] | 80 var vkPhysicalDevices: seq[VkPhysicalDevice] |
| 67 | 81 |
| 68 template checkVkResult*(call: untyped) = | 82 template checkVkResult*(call: untyped) = |
| 82 ) | 96 ) |
| 83 | 97 |
| 84 proc loadFunc[T](instance: VkInstance, f: var T, name: string) = | 98 proc loadFunc[T](instance: VkInstance, f: var T, name: string) = |
| 85 f = cast[T](vkGetInstanceProcAddr(instance, name)) | 99 f = cast[T](vkGetInstanceProcAddr(instance, name)) |
| 86 | 100 |
| 101 proc hasValidationLayer*(): bool = | |
| 102 const val_layer = "VK_LAYER_KHRONOS_validation" | |
| 103 var n_layers: uint32 | |
| 104 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), nil) | |
| 105 if n_layers > 0: | |
| 106 var layers = newSeq[VkLayerProperties](n_layers) | |
| 107 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), addr layers[0]) | |
| 108 for layer in layers: | |
| 109 let layerName = \$(cast[cstring](addr layer.layerName[0])) | |
| 110 if layerName.startsWith(val_layer): | |
| 111 return true | |
| 112 return false | |
| 113 | |
| 87 proc initVulkan*() = | 114 proc initVulkan*() = |
| 88 if vkGetInstanceProcAddr != nil: | 115 if vkGetInstanceProcAddr != nil: |
| 89 return | 116 return |
| 90 | 117 |
| 91 when defined(linux): | 118 when defined(linux): |
| 98 # load function-pointer resolver function | 125 # load function-pointer resolver function |
| 99 vkGetInstanceProcAddr = cast[typeof(vkGetInstanceProcAddr)](checkedSymAddr(vulkanLib, "vkGetInstanceProcAddr")) | 126 vkGetInstanceProcAddr = cast[typeof(vkGetInstanceProcAddr)](checkedSymAddr(vulkanLib, "vkGetInstanceProcAddr")) |
| 100 | 127 |
| 101 # need to create an instance before loading other function points | 128 # need to create an instance before loading other function points |
| 102 loadFunc(vkInstance, vkCreateInstance, "vkCreateInstance") | 129 loadFunc(vkInstance, vkCreateInstance, "vkCreateInstance") |
| 130 # and this one, to check which layers are available for instance creation | |
| 131 loadFunc(vkInstance, vkEnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties") | |
| 132 | |
| 133 # extensions | |
| 134 var extensions = @["VK_KHR_surface"] | |
| 135 when not defined(release): | |
| 136 extensions.add "VK_EXT_debug_utils" | |
| 137 when defined(windows): | |
| 138 extensions.add "VK_KHR_win32_surface" | |
| 139 when defined(linux): | |
| 140 extensions.add "VK_KHR_xlib_surface" | |
| 141 let extensionsC = allocCStringArray(extensions) | |
| 142 defer: deallocCStringArray(extensionsC) | |
| 143 | |
| 144 # layers | |
| 145 var layers: seq[string] | |
| 146 when not defined(release): | |
| 147 if hasValidationLayer(): | |
| 148 layers.add "VK_LAYER_KHRONOS_validation" | |
| 149 var layersC = allocCStringArray(layers) | |
| 150 defer: deallocCStringArray(layersC) | |
| 151 | |
| 152 putEnv( | |
| 153 "VK_LAYER_ENABLES", | |
| 154 "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD,VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXTVK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT", | |
| 155 ) | |
| 156 | |
| 157 echo "Use instance extensions: ", extensions | |
| 158 echo "Use layers: ", layers | |
| 103 let createInfo = VkInstanceCreateInfo( | 159 let createInfo = VkInstanceCreateInfo( |
| 104 pNext: nil, | 160 pNext: nil, |
| 105 flags: 0, | 161 flags: 0, |
| 106 pApplicationInfo: nil, | 162 pApplicationInfo: nil, |
| 107 enabledLayerCount: 0, | 163 enabledLayerCount: layers.len.uint32, |
| 108 ppEnabledLayerNames: nil, | 164 ppEnabledLayerNames: cast[ptr cstring](layersC), |
| 109 enabledExtensionCount: 0, | 165 enabledExtensionCount: extensions.len.uint32, |
| 110 ppEnabledExtensionNames: nil, | 166 ppEnabledExtensionNames: cast[ptr cstring](extensionsC), |
| 111 ) | 167 ) |
| 112 checkVkResult vkCreateInstance(addr createInfo, nil, addr vkInstance) | 168 checkVkResult vkCreateInstance(addr createInfo, nil, addr vkInstance) |
| 113 | 169 |
| 114 # load all functions (some might be null, not checking here) | 170 # load all functions (some might be null, not checking here) |
| 115 EOF | 171 EOF |
