Mercurial > games > semicongine
diff 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 |
line wrap: on
line diff
--- a/fuhtark_test/generate_vulkan_api.sh Wed Nov 26 21:36:48 2025 +0700 +++ b/fuhtark_test/generate_vulkan_api.sh Wed Nov 26 23:34:29 2025 +0700 @@ -1,21 +1,31 @@ #!/bin/sh -e # Variables -BASE_INCLUDE=$( realpath $( dirname $0 ) )"/include" -WIN_INCLUDE=$( realpath $( dirname $0 ) )"/include/winapi" +VULKAN_VERSION=1.4.334 +HOME_DIR=$( realpath $( dirname $0 ) ) +BASE_INCLUDE="$HOME_DIR/include" +WIN_INCLUDE="$HOME_DIR/include/winapi" +VULKAN_INCLUDE="$HOME_DIR/Vulkan-Headers-$VULKAN_VERSION/include/vulkan" OUT_BIN=vulkan OUTFILE=$OUT_BIN.nim OUTFILE_FUTHARK=$OUT_BIN".gen.nim" +# setup +# sudo apt install clang libclang-dev +# nimble install futhark +# rm -rf Vulkan-Headers-$VULKAN_VERSION +# curl -L https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/v$VULKAN_VERSION.tar.gz | tar -xzf - + # Convert C-headers to Nim using Futhark, if not existing yet NIM_GEN_CODE='import futhark, os importc: outputPath "'"$OUTFILE_FUTHARK"'" define VK_USE_PLATFORM_WIN32_KHR define VK_USE_PLATFORM_XLIB_KHR + define VK_ENABLE_BETA_EXTENSIONS sysPath "'"$BASE_INCLUDE"'" sysPath "'"$WIN_INCLUDE"'" - path "/usr/include/vulkan" + path "'"$VULKAN_INCLUDE"'" "vulkan.h"' if [ ! -f $OUTFILE_FUTHARK ] ; then @@ -36,14 +46,17 @@ # set default struct values for member "sType" # not very clean, as we "abuse" the fact that Nim does not differentiate between camel-case and snake-case for identifiers + +# VkStructureType_1124073999 = (when declared(VkStructureType): +TYPESTRUCTNAME=$( cat $OUTFILE | awk '/enum_VkStructureType\* =/ { print $3; }' ) awk -i inplace '{ - if ( $0 ~ /^ struct_Vk.* = object/ && ! $0 ~ /VkBaseInStructure/ ) { + if ( $0 ~ /^ struct_Vk.* = object/ && $0 !~ /VkBaseInStructure/ && $0 !~ /VkBaseOutStructure/ ) { split($0, arr, "_"); print $0; getline; if ( $0 ~ / sType\*:/ ) { split($0, arr2, "##"); - print arr2[1] "= VK_STRUCTURE_TYPE_" substr(arr[2], 3) " ##" arr2[2]; + print " sType*: '$TYPESTRUCTNAME' = '$TYPESTRUCTNAME'.VK_STRUCTURE_TYPE_" substr(arr[2], 3) " ##" arr2[2]; } else { print; } @@ -61,6 +74,7 @@ import std/dynlib import std/strutils import std/logging +import std/envvars var vkInstance*: VkInstance = VkInstance(nil) var vkPhysicalDevices: seq[VkPhysicalDevice] @@ -84,6 +98,19 @@ proc loadFunc[T](instance: VkInstance, f: var T, name: string) = f = cast[T](vkGetInstanceProcAddr(instance, name)) +proc hasValidationLayer*(): bool = + const val_layer = "VK_LAYER_KHRONOS_validation" + var n_layers: uint32 + checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), nil) + if n_layers > 0: + var layers = newSeq[VkLayerProperties](n_layers) + checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), addr layers[0]) + for layer in layers: + let layerName = \$(cast[cstring](addr layer.layerName[0])) + if layerName.startsWith(val_layer): + return true + return false + proc initVulkan*() = if vkGetInstanceProcAddr != nil: return @@ -100,14 +127,43 @@ # need to create an instance before loading other function points loadFunc(vkInstance, vkCreateInstance, "vkCreateInstance") + # and this one, to check which layers are available for instance creation + loadFunc(vkInstance, vkEnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties") + + # extensions + var extensions = @["VK_KHR_surface"] + when not defined(release): + extensions.add "VK_EXT_debug_utils" + when defined(windows): + extensions.add "VK_KHR_win32_surface" + when defined(linux): + extensions.add "VK_KHR_xlib_surface" + let extensionsC = allocCStringArray(extensions) + defer: deallocCStringArray(extensionsC) + + # layers + var layers: seq[string] + when not defined(release): + if hasValidationLayer(): + layers.add "VK_LAYER_KHRONOS_validation" + var layersC = allocCStringArray(layers) + defer: deallocCStringArray(layersC) + + putEnv( + "VK_LAYER_ENABLES", + "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", + ) + + echo "Use instance extensions: ", extensions + echo "Use layers: ", layers let createInfo = VkInstanceCreateInfo( pNext: nil, flags: 0, pApplicationInfo: nil, - enabledLayerCount: 0, - ppEnabledLayerNames: nil, - enabledExtensionCount: 0, - ppEnabledExtensionNames: nil, + enabledLayerCount: layers.len.uint32, + ppEnabledLayerNames: cast[ptr cstring](layersC), + enabledExtensionCount: extensions.len.uint32, + ppEnabledExtensionNames: cast[ptr cstring](extensionsC), ) checkVkResult vkCreateInstance(addr createInfo, nil, addr vkInstance)
