feat(vk): Vk.* - Vulkan 1.0-1.4 generated from the registry, loaded at run time
ludic-dev vkgen reads vk.xml into runtime/native/vk_api.ludic (constants, every struct's <Struct>_sizeof and <Struct>_<field> offsets, one extern per command) and vk_thunks.ll. Every size and offset was compiled against the SDK's C headers; `ludic-dev test` checks the tracked files against the registry wherever the Vulkan SDK is installed. vk_win.ll (vulkan-1.dll) and vk_mac.ll (libvulkan.1.dylib, MoltenVK) open the loader at run time, so a program built with Vk.* starts on a machine without Vulkan. ludicc and ludic build link both for any program that uses Vk.*. The seeds are regenerated for the new compiler. vk_probe reports what a machine's Vulkan can do; vk_compute dispatches a Slang compute shader and reads the picture back, clean under the validation layer on an RTX 3070 Ti and on an M4 Pro through MoltenVK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
043d8d81a2
commit
208cad7ca1
18 changed files with 52468 additions and 40972 deletions
61
runtime/native/vk_win.ll
Normal file
61
runtime/native/vk_win.ll
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
; ============================================================================
|
||||
; vk_win.ll — the Vulkan loader, for Windows, written in LLVM IR.
|
||||
;
|
||||
; vulkan-1.dll ships with every GPU driver on Windows 10 and 11, but it is not
|
||||
; guaranteed, so it is opened AT RUN TIME and never linked: a program that asks for
|
||||
; Vulkan on a machine without it gets 0 from vk_open and falls back to OpenGL
|
||||
; rather than failing to start.
|
||||
;
|
||||
; lvk_open() -> 1 | 0 open the loader and bind every command (vk_thunks.ll)
|
||||
; lvk_sym(name) -> ptr one entry point by name, null when the loader lacks it
|
||||
; lvk_has(name) -> 1 | 0 whether a command is there (an extension's, say)
|
||||
;
|
||||
; The commands themselves, their struct layouts and constants are generated from
|
||||
; the Vulkan registry by `ludic-dev vkgen` into vk_api.ludic and vk_thunks.ll.
|
||||
; ============================================================================
|
||||
|
||||
declare ptr @LoadLibraryA(ptr)
|
||||
declare ptr @GetProcAddress(ptr, ptr)
|
||||
declare i32 @lvk_bind()
|
||||
|
||||
@.lvk_dll = private unnamed_addr constant [13 x i8] c"vulkan-1.dll\00"
|
||||
@lvk_lib = internal global ptr null
|
||||
|
||||
define i32 @lvk_open() {
|
||||
entry:
|
||||
%have = load ptr, ptr @lvk_lib
|
||||
%open = icmp ne ptr %have, null
|
||||
br i1 %open, label %ok, label %load
|
||||
load:
|
||||
%lib = call ptr @LoadLibraryA(ptr @.lvk_dll)
|
||||
%none = icmp eq ptr %lib, null
|
||||
br i1 %none, label %fail, label %bind
|
||||
bind:
|
||||
store ptr %lib, ptr @lvk_lib
|
||||
%n = call i32 @lvk_bind()
|
||||
br label %ok
|
||||
ok:
|
||||
ret i32 1
|
||||
fail:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define ptr @lvk_sym(ptr %name) {
|
||||
entry:
|
||||
%lib = load ptr, ptr @lvk_lib
|
||||
%none = icmp eq ptr %lib, null
|
||||
br i1 %none, label %no, label %look
|
||||
look:
|
||||
%p = call ptr @GetProcAddress(ptr %lib, ptr %name)
|
||||
ret ptr %p
|
||||
no:
|
||||
ret ptr null
|
||||
}
|
||||
|
||||
define i32 @lvk_has(ptr %name) {
|
||||
entry:
|
||||
%p = call ptr @lvk_sym(ptr %name)
|
||||
%there = icmp ne ptr %p, null
|
||||
%r = zext i1 %there to i32
|
||||
ret i32 %r
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue