changeset 1485:6e062a84c157 default tip

add: more api-starting
author sam <sam@basx.dev>
date Sat, 03 May 2025 01:03:01 +0700
parents a2af327f19df
children
files svk/api.nim svk/generate.nim svk/test.nim
diffstat 3 files changed, 92 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svk/api.nim	Sat May 03 01:03:01 2025 +0700
@@ -0,0 +1,56 @@
+import std/strutils
+import std/logging
+
+include ./vkapi
+
+template checkVkResult*(call: untyped) =
+  when defined(release):
+    discard call
+  else:
+    # yes, a bit cheap, but this is only for nice debug output
+    var callstr = astToStr(call).replace("\n", "")
+    while callstr.find("  ") >= 0:
+      callstr = callstr.replace("  ", " ")
+    debug "Calling vulkan: ", callstr
+    let value = call
+    if value != VK_SUCCESS:
+      error "Vulkan error: ", astToStr(call), " returned ", $value
+      raise newException(
+        Exception, "Vulkan error: " & astToStr(call) & " returned " & $value
+      )
+
+type SVkInstance* = object
+  vkInstance: VkInstance
+
+proc `=copy`(a: var SVkInstance, b: SVkInstance) {.error.}
+
+proc `=destroy`(a: SVkInstance) =
+  if a.vkInstance.pointer != nil:
+    a.vkInstance.vkDestroyInstance(nil)
+
+proc svkCreateInstance*(
+    applicationName: string,
+    enabledLayers: openArray[string] = [],
+    enabledExtensions: openArray[string] = [],
+    engineName = "semicongine",
+    majorVersion = 1'u32,
+    minorVersion = 3'u32,
+): SVkInstance =
+  let
+    appinfo = VkApplicationInfo(
+      pApplicationName: applicationName,
+      pEngineName: engineName,
+      apiVersion: VK_MAKE_API_VERSION(0, majorVersion, minorVersion, 0),
+    )
+    layersC = enabledLayers.allocCStringArray()
+    extensionsC = enabledLayers.allocCStringArray()
+    createinfo = VkInstanceCreateInfo(
+      pApplicationInfo: addr appinfo,
+      enabledLayerCount: enabledLayers.len.uint32,
+      ppEnabledLayerNames: layersC,
+      enabledExtensionCount: enabledExtensions.len.uint32,
+      ppEnabledExtensionNames: extensionsC,
+    )
+  checkVkResult vkCreateInstance(addr createinfo, nil, addr result.vkInstance)
+  layersC.deallocCStringArray()
+  extensionsC.deallocCStringArray()
--- a/svk/generate.nim	Thu May 01 00:59:40 2025 +0700
+++ b/svk/generate.nim	Sat May 03 01:03:01 2025 +0700
@@ -100,10 +100,16 @@
     if typename == "void":
       result = "pointer"
     elif typename == "char":
-      result = "cstring"
+      if pointerType == 1:
+        result = "cstring"
+      elif pointerType == 2:
+        result = "cstringArray"
+      else:
+        assert false, "Unsupported char pointer type"
     else:
       result = "ptr " & result
-  if pointerType == 2:
+
+  if pointerType == 2 and typename != "char":
     result = "ptr " & result
 
 func doIdentifier(typename: string): string =
@@ -165,11 +171,12 @@
       assert n[0].text.strip() == "const" # can be ignored
       assert n[1].tag == "type"
       assert n[2].text.strip() in ["*", "* const *", "* const*"]
-        # can be ignored, basically every type is a pointer
       assert n[3].tag == "name"
       assert n[1].len == 1
       assert n[3].len == 1
-      return doMember(n[3][0].text, n[1][0].text, 1, n.attr("values"))
+      return doMember(
+        n[3][0].text, n[1][0].text, n[2].text.strip().count("*"), n.attr("values")
+      )
   elif n.len in [5, 6]:
     # array definition, using const-value for array length
     # <type>uint8_t</type>,<name>pipelineCacheUUID</name>[<enum>VK_UUID_SIZE</enum>]
@@ -231,7 +238,7 @@
 
 func VK_MAKE_API_VERSION*(
     variant: uint32, major: uint32, minor: uint32, patch: uint32
-): uint32 {.compileTime.} =
+): uint32 =
   (variant shl 29) or (major shl 22) or (minor shl 12) or patch
 """
 
@@ -392,14 +399,13 @@
     doAssert category in ["", "basetype", "enum"], "unknown type category: " & category
 outFile.writeLine ""
 
-outFile.write &"var\n"
 for command in commands:
   if command.attr("api") == "vulkansc":
     continue
   if command.attr("alias") != "":
     let funcName = command.attr("name")
     let funcAlias = command.attr("alias")
-    outFile.write &"  {funcName}* = {funcAlias}\n"
+    outFile.write &"var {funcName}* = {funcAlias}\n"
     continue
 
   let proto = command.findAll("proto")[0]
@@ -409,7 +415,7 @@
   if "Video" in funcName: # Video API not supported at this time
     continue
 
-  outFile.write &"  {funcName}*: proc("
+  outFile.write &"var {funcName}*: proc("
   for param in command:
     if param.tag != "param":
       continue
@@ -453,7 +459,25 @@
   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))
+
+"""
+
+for f in features:
+  let name = f.attr("name").replace(",", "_")
+  if f.attr("struct") != "":
+    continue
+  outFile.writeLine &"proc loadFeature_{name}(instance: VkInstance) ="
+  var hasEntries = false
+  for cmd in f.findAll("command"):
+    hasEntries = true
+    let cName = cmd.attr("name")
+    outFile.writeLine &"  loadFunc(instance, {cName}, \"{cName}\")"
+  if not hasEntries:
+    outFile.writeLine "  discard"
+  outFile.writeLine ""
 
 outFile.close()
 
--- a/svk/test.nim	Thu May 01 00:59:40 2025 +0700
+++ b/svk/test.nim	Sat May 03 01:03:01 2025 +0700
@@ -1,17 +1,4 @@
-import ./vkapi
+import ./api
 
-var
-  appinfo = VkApplicationInfo(
-    pApplicationName: appName,
-    pEngineName: "semicongine",
-    apiVersion: VK_MAKE_API_VERSION(0, 1, 3, 0),
-  )
-  createinfo = VkInstanceCreateInfo(
-    pApplicationInfo: addr appinfo,
-    enabledLayerCount: layers.len.uint32,
-    ppEnabledLayerNames: layersC,
-    enabledExtensionCount: requiredExtensions.len.uint32,
-    ppEnabledExtensionNames: instanceExtensionsC,
-  )
-checkVkResult vkCreateInstance(addr(createinfo), nil, addr(result.instance))
-loadVulkan(result.instance)
+let vk = svkCreateInstance("test")
+echo vk