Mercurial > games > semicongine
diff svk/generate.nim @ 1486:0ba3f0b2be2e default tip main
did: more
author | sam <sam@basx.dev> |
---|---|
date | Sat, 03 May 2025 20:16:04 +0700 |
parents | 6e062a84c157 |
children |
line wrap: on
line diff
--- a/svk/generate.nim Sat May 03 01:03:01 2025 +0700 +++ b/svk/generate.nim Sat May 03 20:16:04 2025 +0700 @@ -213,8 +213,15 @@ if extendenum.attr("extends") != "": enums[extendenum.attr("extends")].addValue(extendenum) +var extensionLoaders: seq[(string, seq[string])] + for extension in extensions.findAll("extension"): let extNum = extension.attr("number") + extensionLoaders.add (extension.attr("name"), newSeq[string]()) + for c in extension.findAll("command"): + if "Video" notin c.attr("name"): + extensionLoaders[^1][1].add c.attr("name") + for extendenum in extension.findAll("enum"): if extendenum.attr("extends") != "": if extendenum.attr("extnumber") == "": @@ -229,6 +236,8 @@ outFile.writeLine """ import std/dynlib +import std/strutils +import std/tables import ../semicongine/thirdparty/winim/winim/inc/winbase import ../semicongine/thirdparty/winim/winim/inc/windef @@ -311,7 +320,10 @@ value = value[0 ..^ 4] & "'u64" if value[0] == '~': value = "not " & value[1 ..^ 1] - outFile.writeLine &" {c.name}*: {c.datatype} = {value}" + if c.name in ["VK_TRUE", "VK_FALSE"]: + outFile.writeLine &" {c.name}*: VkBool32 = VkBool32({value})" + else: + outFile.writeLine &" {c.name}*: {c.datatype} = {value}" outFile.writeLine "" # generate enums =============================================================================== @@ -335,6 +347,7 @@ outFile.writeLine "" # generate types =============================================================================== +var stringConverters: seq[string] for t in types: let category = t.attr("category") let tName = t.attr("name") @@ -357,13 +370,14 @@ outFile.writeLine &" {tName}* = {a}" elif category == "bitmask": if t.len > 0 and t[0].text.startsWith("typedef"): - outFile.writeLine &" {t[2][0].text}* = distinct {t[1][0].text}" + outFile.writeLine &" {t[2][0].text.strip()}* = distinct {t[1][0].text.strip()}" elif category == "union": outFile.writeLine &" {tName}* {{.union.}} = object" for member in t.findAll("member"): outFile.writeLine &" {member.memberDecl()}" elif category == "handle": - outFile.writeLine &" {t[2][0].text} = distinct pointer" + outFile.writeLine &" {t[2][0].text.strip()} = distinct pointer" + stringConverters.add t[2][0].text.strip() elif category == "struct": outFile.writeLine &" {tName}* = object" for member in t.findAll("member"): @@ -451,27 +465,37 @@ outFile.write " {.stdcall.}\n" outFile.write """ -when defined(linux): - let vulkanLib = loadLib("libvulkan.so.1") -when defined(windows): - let vulkanLib = loadLib("vulkan-1.dll") -if vulkanLib == nil: - raise newException(Exception, "Unable to load vulkan library") - -vkGetInstanceProcAddr = cast[proc(instance: VkInstance, pName: cstring, ): PFN_vkVoidFunction {.stdcall.}](checkedSymAddr(vulkanLib, "vkGetInstanceProcAddr")) proc loadFunc[T](instance: VkInstance, f: var T, name: string) = f = cast[T](vkGetInstanceProcAddr(instance, name)) +proc initVulkanLoader*() = + if vkGetInstanceProcAddr != nil: + return + + when defined(linux): + let vulkanLib = loadLib("libvulkan.so.1") + when defined(windows): + let vulkanLib = loadLib("vulkan-1.dll") + if vulkanLib == nil: + raise newException(Exception, "Unable to load vulkan library") + + # init two global functions + vkGetInstanceProcAddr = cast[proc(instance: VkInstance, pName: cstring, ): PFN_vkVoidFunction {.stdcall.}](checkedSymAddr(vulkanLib, "vkGetInstanceProcAddr")) + + loadFunc(VkInstance(nil), vkCreateInstance, "vkCreateInstance") + """ for f in features: let name = f.attr("name").replace(",", "_") if f.attr("struct") != "": continue - outFile.writeLine &"proc loadFeature_{name}(instance: VkInstance) =" + outFile.writeLine &"proc load_{name}(instance: VkInstance) =" var hasEntries = false for cmd in f.findAll("command"): + if cmd.attr("name") == "vkCreateInstance": + continue hasEntries = true let cName = cmd.attr("name") outFile.writeLine &" loadFunc(instance, {cName}, \"{cName}\")" @@ -479,6 +503,32 @@ outFile.writeLine " discard" outFile.writeLine "" +for (extName, commands) in extensionLoaders: + outFile.writeLine &"proc load_{extName}(instance: VkInstance) =" + for c in commands: + outFile.writeLine &" loadFunc(instance, {c}, \"{c}\")" + if commands.len == 0: + outFile.writeLine &" discard" +outFile.writeLine "" + +outFile.writeLine "const EXTENSION_LOADERS = {" +for (extName, commands) in extensionLoaders: + outFile.writeLine &" \"{extName}\": load_{extName}," +outFile.writeLine "}.toTable" +outFile.writeLine "" + +outFile.writeLine "proc loadExtension*(instance: VkInstance, name: string) =" +outFile.writeLine " assert name in EXTENSION_LOADERS" +outFile.writeLine " EXTENSION_LOADERS[name](instance)" +outFile.writeLine "" + +for strCon in stringConverters: + outFile.writeLine &"""proc `$`*(v: {strCon}): string = "0x" & cast[uint](v).toHex()""" +outFile.writeLine "" + +# we preload the vkCreateInstance function, so we can create an instance +outFile.writeLine "" + outFile.close() assert execCmd("nim c " & outPath) == 0