feat(vk): load NVIDIA Streamline's interposer as the Vulkan loader on request
vk_sl_prefer(1) before Vk.open() makes the Windows loader try sl.interposer.dll beside the executable and fall back to vulkan-1.dll. Thunks for the sl* exports and for calling feature functions from slGetFeatureFunction; macOS stubs. Verified on an RTX 3070 Ti: slInit eOk, DLSS, DLSS-RR, Reflex and PCL supported, DLSS-G reports no supported adapter (needs RTX 40). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
fd750f3588
commit
ad8f44b78a
3 changed files with 362 additions and 0 deletions
|
|
@ -27,6 +27,22 @@ entry:
|
|||
%open = icmp ne ptr %have, null
|
||||
br i1 %open, label %ok, label %load
|
||||
load:
|
||||
; Streamline: when the renderer asked for it (lvk_sl_prefer) and sl.interposer.dll is found, the
|
||||
; interposer IS the loader - it proxies every Vulkan command, and intercepts the few its DLSS and
|
||||
; Reflex plugins need. Without it, vulkan-1.dll as always.
|
||||
%want = load i32, ptr @lvk_sl_want
|
||||
%try = icmp ne i32 %want, 0
|
||||
br i1 %try, label %sl, label %plain
|
||||
sl:
|
||||
%sll = call ptr @LoadLibraryA(ptr @.lsl_dll)
|
||||
%slmiss = icmp eq ptr %sll, null
|
||||
br i1 %slmiss, label %plain, label %slok
|
||||
slok:
|
||||
store i32 1, ptr @lvk_sl_on
|
||||
store ptr %sll, ptr @lvk_lib
|
||||
%sln = call i32 @lvk_bind()
|
||||
br label %ok
|
||||
plain:
|
||||
%lib = call ptr @LoadLibraryA(ptr @.lvk_dll)
|
||||
%none = icmp eq ptr %lib, null
|
||||
br i1 %none, label %fail, label %bind
|
||||
|
|
@ -59,3 +75,251 @@ entry:
|
|||
%r = zext i1 %there to i32
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
; ---- Streamline (NVIDIA DLSS, Reflex) -----------------------------------------------------------
|
||||
; lvk_sl_prefer(1) before lvk_open makes the loader try sl.interposer.dll first; lvk_sl_active says
|
||||
; whether it did. The sl* thunks resolve their exports from the opened library once and return -1
|
||||
; (not sl::Result::eOk) when it has none - vulkan-1.dll, or no library at all.
|
||||
@.lsl_dll = private unnamed_addr constant [18 x i8] c"sl.interposer.dll\00"
|
||||
@lvk_sl_want = internal global i32 0
|
||||
@lvk_sl_on = internal global i32 0
|
||||
define void @lvk_sl_prefer(i32 %on) {
|
||||
entry:
|
||||
store i32 %on, ptr @lvk_sl_want
|
||||
ret void
|
||||
}
|
||||
define i32 @lvk_sl_active() {
|
||||
entry:
|
||||
%v = load i32, ptr @lvk_sl_on
|
||||
ret i32 %v
|
||||
}
|
||||
@.lsl_n_slInit = private unnamed_addr constant [7 x i8] c"slInit\00"
|
||||
@lsl_p_slInit = internal global ptr null
|
||||
define i32 @lsl_slInit(ptr %a0, i64 %a1) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slInit
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slInit)
|
||||
store ptr %found, ptr @lsl_p_slInit
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slInit
|
||||
%r = call i32 %fp(ptr %a0, i64 %a1)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slShutdown = private unnamed_addr constant [11 x i8] c"slShutdown\00"
|
||||
@lsl_p_slShutdown = internal global ptr null
|
||||
define i32 @lsl_slShutdown() {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slShutdown
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slShutdown)
|
||||
store ptr %found, ptr @lsl_p_slShutdown
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slShutdown
|
||||
%r = call i32 %fp()
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slIsFeatureSupported = private unnamed_addr constant [21 x i8] c"slIsFeatureSupported\00"
|
||||
@lsl_p_slIsFeatureSupported = internal global ptr null
|
||||
define i32 @lsl_slIsFeatureSupported(i32 %a0, ptr %a1) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slIsFeatureSupported
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slIsFeatureSupported)
|
||||
store ptr %found, ptr @lsl_p_slIsFeatureSupported
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slIsFeatureSupported
|
||||
%r = call i32 %fp(i32 %a0, ptr %a1)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slIsFeatureLoaded = private unnamed_addr constant [18 x i8] c"slIsFeatureLoaded\00"
|
||||
@lsl_p_slIsFeatureLoaded = internal global ptr null
|
||||
define i32 @lsl_slIsFeatureLoaded(i32 %a0, ptr %a1) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slIsFeatureLoaded
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slIsFeatureLoaded)
|
||||
store ptr %found, ptr @lsl_p_slIsFeatureLoaded
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slIsFeatureLoaded
|
||||
%r = call i32 %fp(i32 %a0, ptr %a1)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slGetFeatureRequirements = private unnamed_addr constant [25 x i8] c"slGetFeatureRequirements\00"
|
||||
@lsl_p_slGetFeatureRequirements = internal global ptr null
|
||||
define i32 @lsl_slGetFeatureRequirements(i32 %a0, ptr %a1) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slGetFeatureRequirements
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slGetFeatureRequirements)
|
||||
store ptr %found, ptr @lsl_p_slGetFeatureRequirements
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slGetFeatureRequirements
|
||||
%r = call i32 %fp(i32 %a0, ptr %a1)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slGetFeatureFunction = private unnamed_addr constant [21 x i8] c"slGetFeatureFunction\00"
|
||||
@lsl_p_slGetFeatureFunction = internal global ptr null
|
||||
define i32 @lsl_slGetFeatureFunction(i32 %a0, ptr %a1, ptr %a2) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slGetFeatureFunction
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slGetFeatureFunction)
|
||||
store ptr %found, ptr @lsl_p_slGetFeatureFunction
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slGetFeatureFunction
|
||||
%r = call i32 %fp(i32 %a0, ptr %a1, ptr %a2)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slGetNewFrameToken = private unnamed_addr constant [19 x i8] c"slGetNewFrameToken\00"
|
||||
@lsl_p_slGetNewFrameToken = internal global ptr null
|
||||
define i32 @lsl_slGetNewFrameToken(ptr %a0, ptr %a1) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slGetNewFrameToken
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slGetNewFrameToken)
|
||||
store ptr %found, ptr @lsl_p_slGetNewFrameToken
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slGetNewFrameToken
|
||||
%r = call i32 %fp(ptr %a0, ptr %a1)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slSetTagForFrame = private unnamed_addr constant [17 x i8] c"slSetTagForFrame\00"
|
||||
@lsl_p_slSetTagForFrame = internal global ptr null
|
||||
define i32 @lsl_slSetTagForFrame(ptr %a0, ptr %a1, ptr %a2, i32 %a3, ptr %a4) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slSetTagForFrame
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slSetTagForFrame)
|
||||
store ptr %found, ptr @lsl_p_slSetTagForFrame
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slSetTagForFrame
|
||||
%r = call i32 %fp(ptr %a0, ptr %a1, ptr %a2, i32 %a3, ptr %a4)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slSetConstants = private unnamed_addr constant [15 x i8] c"slSetConstants\00"
|
||||
@lsl_p_slSetConstants = internal global ptr null
|
||||
define i32 @lsl_slSetConstants(ptr %a0, ptr %a1, ptr %a2) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slSetConstants
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slSetConstants)
|
||||
store ptr %found, ptr @lsl_p_slSetConstants
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slSetConstants
|
||||
%r = call i32 %fp(ptr %a0, ptr %a1, ptr %a2)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slEvaluateFeature = private unnamed_addr constant [18 x i8] c"slEvaluateFeature\00"
|
||||
@lsl_p_slEvaluateFeature = internal global ptr null
|
||||
define i32 @lsl_slEvaluateFeature(i32 %a0, ptr %a1, ptr %a2, i32 %a3, ptr %a4) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slEvaluateFeature
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slEvaluateFeature)
|
||||
store ptr %found, ptr @lsl_p_slEvaluateFeature
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slEvaluateFeature
|
||||
%r = call i32 %fp(i32 %a0, ptr %a1, ptr %a2, i32 %a3, ptr %a4)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
@.lsl_n_slFreeResources = private unnamed_addr constant [16 x i8] c"slFreeResources\00"
|
||||
@lsl_p_slFreeResources = internal global ptr null
|
||||
define i32 @lsl_slFreeResources(i32 %a0, ptr %a1) {
|
||||
entry:
|
||||
%have = load ptr, ptr @lsl_p_slFreeResources
|
||||
%known = icmp ne ptr %have, null
|
||||
br i1 %known, label %call, label %look
|
||||
look:
|
||||
%found = call ptr @lvk_sym(ptr @.lsl_n_slFreeResources)
|
||||
store ptr %found, ptr @lsl_p_slFreeResources
|
||||
%none = icmp eq ptr %found, null
|
||||
br i1 %none, label %absent, label %call
|
||||
call:
|
||||
%fp = load ptr, ptr @lsl_p_slFreeResources
|
||||
%r = call i32 %fp(i32 %a0, ptr %a1)
|
||||
ret i32 %r
|
||||
absent:
|
||||
ret i32 -1
|
||||
}
|
||||
; a feature's own functions (slDLSSSetOptions, slReflexSleep ...) come from slGetFeatureFunction
|
||||
define i32 @lsl_call_p(ptr %fn, ptr %a0) {
|
||||
entry:
|
||||
%r = call i32 %fn(ptr %a0)
|
||||
ret i32 %r
|
||||
}
|
||||
define i32 @lsl_call_pp(ptr %fn, ptr %a0, ptr %a1) {
|
||||
entry:
|
||||
%r = call i32 %fn(ptr %a0, ptr %a1)
|
||||
ret i32 %r
|
||||
}
|
||||
define i32 @lsl_call_ppp(ptr %fn, ptr %a0, ptr %a1, ptr %a2) {
|
||||
entry:
|
||||
%r = call i32 %fn(ptr %a0, ptr %a1, ptr %a2)
|
||||
ret i32 %r
|
||||
}
|
||||
define i32 @lsl_call_ip(ptr %fn, i32 %a0, ptr %a1) {
|
||||
entry:
|
||||
%r = call i32 %fn(i32 %a0, ptr %a1)
|
||||
ret i32 %r
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue