Skip to content

Commit 9ee679a

Browse files
feat(compat.vulkan): 1.4.357.3 ships the Vulkan loader on Windows
A Windows program that links `vulkan-1.lib` needs `vulkan-1.dll` at process start, and that DLL is not part of Windows. It arrives with a GPU driver, with LunarG's Vulkan Runtime redistributable, or beside an application. A machine without a driver has none, and the program dies before `main` with 0xC0000135 (STATUS_DLL_NOT_FOUND). Measured on GitHub's `windows-2022` image (#387 probe, run 34569282837): `vulkan`, `eui-neo-vulkan` and `vulkan-hpp-module` all fail that way, while images that happen to carry a driver pass. WHAT CHANGES compat.vulkan 1.4.357.3 windows artifact adds bin/vulkan-1.dll and LICENSE.txt; mcpp.windows.runtime gains library_dirs = { "bin" } khronos.vulkan-hpp 1.4.357.1 same headers, pin -> compat.vulkan 1.4.357.3 compat.eui-neo 0.5.9.1 upstream 0.5.9 unchanged, `vulkan` feature pin -> compat.vulkan 1.4.357.3 members vulkan 1.4.357.3, vulkan-hpp-module 1.4.357.1, eui-neo-vulkan 0.5.9.1 tests/examples/vulkan on Windows, asserts the mapped vulkan-1.dll lives in the executable's own directory THE MECHANISM ALREADY EXISTS AND IS NOT NEW HERE. mcpp copies every *.dll under a dependency's `runtime.library_dirs` beside the executable it builds (mcpp #185, v0.0.73); `compat.openblas` has shipped `bin/libopenblas.dll` this way on Windows CI since mcpp-index #55. Two properties this change leans on were measured locally with mcpp 2026.9.11.2 rather than assumed: * transitive -- app -> mid -> dep(bin/vulkan-1.dll): the DLL lands beside `app`. `vulkan-hpp-module` and `eui-neo-vulkan` reach compat.vulkan only transitively. * test binaries -- `mcpp test` places it beside the test executable too. `mcpp pack` needs nothing further: its PE closure always searches the executable's own directory ("whatever the build staged beside it ... is by definition part of what it runs with"), and `vulkan-1.dll` is not in its system-DLL allow-list, so the deployed copy is what a packed program carries. THE ARTIFACT (xlings-res/vulkan-import 1.4.357.3, sha256 8118f1bd...12f5) lib/vulkan-1.lib byte-identical to 1.4.357.1's vulkan-1.def upstream `loader/vulkan-1.def`, tag vulkan-sdk-1.4.357.0 bin/vulkan-1.dll built from vulkan-sdk-1.4.357.0 by xlings-res/vulkan-loader's windows workflow, which loads the DLL and resolves vkEnumerateInstanceVersion, vkCreateInstance and vkGetInstanceProcAddr before publishing (run 34608619850) LICENSE.txt Vulkan-Loader's Apache-2.0 -- a redistributed binary carries its license README.md how each file was produced Packed deterministically (sorted, fixed mtime, numeric owner, gzip -n); the sha was computed twice, read back from GitHub, and the gitcode mirror (mcpp-res/vulkan-import 1.4.357.3) is byte-identical. COMPATIBILITY, MEASURED. The DLL exports exactly the 265 names in the .def -- no additions, no omissions -- so every import `vulkan-1.lib` can produce resolves, and no consumer can hit "entry point not found". The loader version the earlier xim payload carried (1.4.313) exports the same 265; the build is at 1.4.357 anyway so the loader matches the headers it is consumed with. On a machine that ALREADY has a GPU driver nothing is lost: the copy beside the executable is found first (the application directory precedes System32), and the loader still reads HKLM\SOFTWARE\Khronos\Vulkan\Drivers, so the driver the machine has is the ICD it uses. The ICD is deliberately not supplied -- a software fallback would hide a missing driver behind a slow device. WHY NEW VERSIONS INSTEAD OF MOVING PINS. An installed copy records the pins it resolved with. Moving a pin inside a published version does not reach a warm store, which is not hypothetical here: with #391's first approach, a warm CI store kept `compat.vulkan@1.4.357.0`, never re-evaluated its closure, and the loader never arrived. That is the same rule as compat.vulkan 1.4.357.1. Versions before 1.4.357.3 have no bin/; mcpp skips a declared runtime directory that does not exist, so `library_dirs` is inert for them. WHY THE TEST ASSERTION IS A REAL CHECK. On Windows the test now requires the mapped vulkan-1.dll to sit in the executable's directory. With an older compat.vulkan that fails on a machine with a driver (the loader comes from System32) and never runs on one without (the process dies first). The `windows-2022` leg of this PR has no system loader at all, so it can only pass if the deployment works. This is also why #391 -- which put the DLL in System32 on the runner -- is superseded rather than merged: it would make that leg pass whether or not the package works. Co-authored-by: sunrisepeak <x.d2learn.org@gmail.com>
1 parent a7e9711 commit 9ee679a

7 files changed

Lines changed: 182 additions & 17 deletions

File tree

‎pkgs/c/compat.vulkan.lua‎

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,15 @@
3333
-- this through `APPLE_STATIC_LOADER` + pthread_once; Linux through
3434
-- `__attribute__((constructor))`. Windows has neither.
3535
--
36-
-- The supported Windows arrangement is the ordinary one every Vulkan
37-
-- application uses: link `vulkan-1.lib` and let the system `vulkan-1.dll`,
38-
-- installed by any GPU driver, do the ICD loading. The windows xpm entry is
39-
-- therefore a small artifact carrying that import library — symbol stubs, no
40-
-- code — generated from Khronos' own `loader/vulkan-1.def` (shipped in this
41-
-- very loader tarball) with a single reproducible command:
36+
-- The supported Windows arrangement is the ordinary one: link `vulkan-1.lib`
37+
-- and load `vulkan-1.dll` at process start. Through 1.4.357.2 that DLL was
38+
-- assumed to come from the machine's GPU driver, which a driverless machine
39+
-- does not have (0xC0000135 before `main`, measured on `windows-2022`). From
40+
-- 1.4.357.3 the artifact also carries the DLL, built from the same tag, and
41+
-- `runtime.library_dirs` has mcpp place it beside every consuming executable;
42+
-- see the windows xpm entry. The import library in that artifact — symbol
43+
-- stubs, no code — is generated from Khronos' own `loader/vulkan-1.def`
44+
-- (shipped in this very loader tarball) with a single reproducible command:
4245
--
4346
-- llvm-dlltool -d vulkan-1.def -l lib/vulkan-1.lib -m i386:x86-64
4447
--
@@ -89,6 +92,16 @@ package = {
8992
-- version -- and where a consumer also names the farm directly, the
9093
-- two disagree and the build stops. Measured on a CI runner with a
9194
-- warm ~/.mcpp; see the note on compat.vulkan 1.4.357.1.
95+
-- 1.4.357.3: the same loader source. A new version on every platform
96+
-- because the WINDOWS artifact changed -- it now carries the loader DLL
97+
-- (see the windows entry) -- and a version is one key across platforms.
98+
["1.4.357.3"] = {
99+
url = {
100+
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Loader/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
101+
CN = "https://gitcode.com/mcpp-res/vulkan/releases/download/1.4.357.0/vulkan-1.4.357.0.tar.gz",
102+
},
103+
sha256 = "54f2537df22313768da0317dda2abdaaab7711b4081c48c869a79db343d0ae70",
104+
},
92105
["1.4.357.2"] = {
93106
url = {
94107
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Loader/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
@@ -136,6 +149,16 @@ package = {
136149
-- version -- and where a consumer also names the farm directly, the
137150
-- two disagree and the build stops. Measured on a CI runner with a
138151
-- warm ~/.mcpp; see the note on compat.vulkan 1.4.357.1.
152+
-- 1.4.357.3: the same loader source. A new version on every platform
153+
-- because the WINDOWS artifact changed -- it now carries the loader DLL
154+
-- (see the windows entry) -- and a version is one key across platforms.
155+
["1.4.357.3"] = {
156+
url = {
157+
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Loader/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
158+
CN = "https://gitcode.com/mcpp-res/vulkan/releases/download/1.4.357.0/vulkan-1.4.357.0.tar.gz",
159+
},
160+
sha256 = "54f2537df22313768da0317dda2abdaaab7711b4081c48c869a79db343d0ae70",
161+
},
139162
["1.4.357.2"] = {
140163
url = {
141164
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Loader/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
@@ -183,6 +206,37 @@ package = {
183206
-- version -- and where a consumer also names the farm directly, the
184207
-- two disagree and the build stops. Measured on a CI runner with a
185208
-- warm ~/.mcpp; see the note on compat.vulkan 1.4.357.1.
209+
-- 1.4.357.3: THE LOADER DLL SHIPS WITH THE IMPORT LIBRARY.
210+
--
211+
-- `vulkan-1.dll` is not a Windows component: it arrives with a GPU
212+
-- driver, with LunarG's Vulkan Runtime redistributable, or beside an
213+
-- application. So a machine without a driver has no loader, and a
214+
-- program linking `vulkan-1.lib` dies before `main` with 0xC0000135
215+
-- (STATUS_DLL_NOT_FOUND). Measured on GitHub's `windows-2022` image
216+
-- (mcpp-index #387 probe; `vulkan`, `eui-neo-vulkan` and
217+
-- `vulkan-hpp-module` all failed that way).
218+
--
219+
-- The artifact adds `bin/vulkan-1.dll`, built from
220+
-- `vulkan-sdk-1.4.357.0` -- the same tag as the headers and the .def --
221+
-- by xlings-res/vulkan-loader's windows workflow, which loads the DLL
222+
-- and resolves its entry points before publishing. `lib/vulkan-1.lib`
223+
-- is byte-identical to 1.4.357.1's, and the DLL exports exactly the
224+
-- 265 names in `vulkan-1.def`: every import that library can produce
225+
-- resolves, so no consumer can hit "entry point not found".
226+
--
227+
-- ON A MACHINE THAT ALREADY HAS A DRIVER nothing is lost. The copy
228+
-- beside the executable is found first (the application directory
229+
-- precedes System32), and the loader still reads
230+
-- HKLM\SOFTWARE\Khronos\Vulkan\Drivers, so the GPU driver the
231+
-- machine has is the ICD it uses. This is the ordinary arrangement for
232+
-- an application that redistributes the loader.
233+
["1.4.357.3"] = {
234+
url = {
235+
GLOBAL = "https://github.com/xlings-res/vulkan-import/releases/download/1.4.357.3/vulkan-import-1.4.357.3.tar.gz",
236+
CN = "https://gitcode.com/mcpp-res/vulkan-import/releases/download/1.4.357.3/vulkan-import-1.4.357.3.tar.gz",
237+
},
238+
sha256 = "8118f1bd897e553baffabf484a14db980ce1f0a6cfdb5a6222c0a236ecdf12f5",
239+
},
186240
["1.4.357.2"] = {
187241
url = {
188242
GLOBAL = "https://github.com/xlings-res/vulkan-import/releases/download/1.4.357.1/vulkan-import-1.4.357.1.tar.gz",
@@ -359,15 +413,26 @@ package = {
359413
-- .def it came from. The anchor keeps a buildable target, the same
360414
-- shape `compat.opengl` uses for a headers-only package.
361415
--
362-
-- The artifact is packed FLAT — lib/ at the archive root, no wrap
363-
-- directory — because `-L` is not glob-expanded the way
416+
-- The artifact is packed FLAT — lib/ and bin/ at the archive root, no
417+
-- wrap directory — because `-L` is not glob-expanded the way
364418
-- include_dirs and sources are. With a wrap layer the relative
365419
-- `-Llib` below misses and the link fails with
366420
-- "LNK1181: cannot open input file 'vulkan-1.lib'".
367421
sources = { "mcpp_generated/vulkan_import_anchor.c" },
368422
ldflags = { "-Llib", "-lvulkan-1" },
369423
runtime = {
370-
-- vulkan-1.dll ships with the GPU driver, not with us.
424+
-- THE LOADER TRAVELS WITH THE PROGRAM (1.4.357.3+). mcpp copies
425+
-- every *.dll under a dependency's runtime library_dirs beside the
426+
-- executable it builds -- for transitive dependencies too -- and
427+
-- `mcpp pack` always searches the executable's own directory, so
428+
-- the same file reaches a packed distribution. Versions before
429+
-- 1.4.357.3 have no bin/ in their artifact; mcpp skips a declared
430+
-- directory that does not exist, so for them this is inert.
431+
--
432+
-- The ICD is deliberately NOT supplied: on a machine with a GPU
433+
-- driver the driver's ICD is the right one, and a software
434+
-- fallback would hide a missing driver behind a slow device.
435+
library_dirs = { "bin" },
371436
dlopen_libs = { "vulkan-1.dll" },
372437
capabilities = { "vulkan.icd.driver" },
373438
},

‎pkgs/e/compat.eui-neo.lua‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ package = {
148148
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.9.tar.gz",
149149
sha256 = "370d1da706d94bbbb144fa1634e1d9796a8a1ffd58b696fbb801296aef15703d",
150150
},
151+
-- 0.5.9.1: upstream 0.5.9 unchanged. Exists because the `vulkan`
152+
-- feature now pins compat.vulkan 1.4.357.3, whose Windows artifact
153+
-- carries the loader DLL; an installed 0.5.9 records the old pin.
154+
["0.5.9.1"] = {
155+
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.9.tar.gz",
156+
sha256 = "370d1da706d94bbbb144fa1634e1d9796a8a1ffd58b696fbb801296aef15703d",
157+
},
151158
},
152159
macosx = {
153160
["0.5.3"] = {
@@ -183,6 +190,13 @@ package = {
183190
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.9.tar.gz",
184191
sha256 = "370d1da706d94bbbb144fa1634e1d9796a8a1ffd58b696fbb801296aef15703d",
185192
},
193+
-- 0.5.9.1: upstream 0.5.9 unchanged. Exists because the `vulkan`
194+
-- feature now pins compat.vulkan 1.4.357.3, whose Windows artifact
195+
-- carries the loader DLL; an installed 0.5.9 records the old pin.
196+
["0.5.9.1"] = {
197+
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.9.tar.gz",
198+
sha256 = "370d1da706d94bbbb144fa1634e1d9796a8a1ffd58b696fbb801296aef15703d",
199+
},
186200
},
187201
windows = {
188202
["0.5.3"] = {
@@ -218,6 +232,13 @@ package = {
218232
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.9.tar.gz",
219233
sha256 = "370d1da706d94bbbb144fa1634e1d9796a8a1ffd58b696fbb801296aef15703d",
220234
},
235+
-- 0.5.9.1: upstream 0.5.9 unchanged. Exists because the `vulkan`
236+
-- feature now pins compat.vulkan 1.4.357.3, whose Windows artifact
237+
-- carries the loader DLL; an installed 0.5.9 records the old pin.
238+
["0.5.9.1"] = {
239+
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.9.tar.gz",
240+
sha256 = "370d1da706d94bbbb144fa1634e1d9796a8a1ffd58b696fbb801296aef15703d",
241+
},
221242
},
222243
},
223244

@@ -420,7 +441,7 @@ package = {
420441
"*/core/render/vulkan/vulkan_shadertoy.cpp",
421442
"*/core/render/vulkan/vulkan_text.cpp",
422443
},
423-
deps = { ["compat.vulkan"] = "1.4.357.0" },
444+
deps = { ["compat.vulkan"] = "1.4.357.3" },
424445
},
425446
-- ── Window backend ────────────────────────────────────────────
426447
-- Exclusive in the same way and for the same reason as the render

‎pkgs/k/khronos.vulkan-hpp.lua‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ package = {
159159
-- header, loader and bindings repositories together.
160160
xpm = {
161161
linux = {
162+
-- 1.4.357.1: the same headers, pinned to compat.vulkan 1.4.357.3, whose
163+
-- Windows artifact carries the loader DLL. A new version rather than a
164+
-- moved pin, because an installed copy records the pin it resolved
165+
-- with (see compat.vulkan 1.4.357.1).
166+
["1.4.357.1"] = {
167+
url = {
168+
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
169+
CN = "https://gitcode.com/mcpp-res/vulkan-headers/releases/download/1.4.357.0/vulkan-headers-1.4.357.0.tar.gz",
170+
},
171+
sha256 = "e87dce08116151f6b6d7de6b6faf41498e87e6cf848ff16fa3bd5402190ad4a3",
172+
},
162173
["1.4.357.0"] = {
163174
url = {
164175
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
@@ -168,6 +179,17 @@ package = {
168179
},
169180
},
170181
macosx = {
182+
-- 1.4.357.1: the same headers, pinned to compat.vulkan 1.4.357.3, whose
183+
-- Windows artifact carries the loader DLL. A new version rather than a
184+
-- moved pin, because an installed copy records the pin it resolved
185+
-- with (see compat.vulkan 1.4.357.1).
186+
["1.4.357.1"] = {
187+
url = {
188+
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
189+
CN = "https://gitcode.com/mcpp-res/vulkan-headers/releases/download/1.4.357.0/vulkan-headers-1.4.357.0.tar.gz",
190+
},
191+
sha256 = "e87dce08116151f6b6d7de6b6faf41498e87e6cf848ff16fa3bd5402190ad4a3",
192+
},
171193
["1.4.357.0"] = {
172194
url = {
173195
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
@@ -177,6 +199,17 @@ package = {
177199
},
178200
},
179201
windows = {
202+
-- 1.4.357.1: the same headers, pinned to compat.vulkan 1.4.357.3, whose
203+
-- Windows artifact carries the loader DLL. A new version rather than a
204+
-- moved pin, because an installed copy records the pin it resolved
205+
-- with (see compat.vulkan 1.4.357.1).
206+
["1.4.357.1"] = {
207+
url = {
208+
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
209+
CN = "https://gitcode.com/mcpp-res/vulkan-headers/releases/download/1.4.357.0/vulkan-headers-1.4.357.0.tar.gz",
210+
},
211+
sha256 = "e87dce08116151f6b6d7de6b6faf41498e87e6cf848ff16fa3bd5402190ad4a3",
212+
},
180213
["1.4.357.0"] = {
181214
url = {
182215
GLOBAL = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.tar.gz",
@@ -207,6 +240,6 @@ package = {
207240
targets = { ["vulkan_hpp"] = { kind = "lib" } },
208241
-- The loader, for the static dispatcher's direct calls — and, through
209242
-- it, `compat.vulkan-headers` for the includes these units open.
210-
deps = { ["compat.vulkan"] = "1.4.357.0" },
243+
deps = { ["compat.vulkan"] = "1.4.357.3" },
211244
},
212245
}

‎tests/examples/eui-neo-vulkan/mcpp.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ version = "0.1.0"
66
# package resolves the exclusive choice in its own preprocessor from the
77
# MCPP_FEATURE_* flags. The window backend stays GLFW, unnamed.
88
[dependencies.compat]
9-
eui-neo = { version = "0.5.9", features = ["vulkan"] }
9+
eui-neo = { version = "0.5.9.1", features = ["vulkan"] }
1010

1111
[build]
1212
cxxflags = ["-DHAVE_EUI_VULKAN=1"]

‎tests/examples/vulkan-hpp-module/mcpp.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ name = "vulkan-hpp-module-tests"
2121
version = "0.1.0"
2222

2323
[dependencies.khronos]
24-
vulkan-hpp = "1.4.357.0"
24+
vulkan-hpp = "1.4.357.1"
2525

2626
# No [build] section, and no per-platform gating: unlike tests/examples/vulkan,
2727
# which had to publish its own HAVE_VULKAN_LOADER switch, nothing here is

‎tests/examples/vulkan/mcpp.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "vulkan-tests"
33
version = "0.1.0"
44

55
[dependencies.compat]
6-
vulkan = "1.4.357.0"
6+
vulkan = "1.4.357.3"
77

88
# All three platforms now carry compat.vulkan — linux/macOS build the loader
99
# from source, windows links the import library. HAVE_VULKAN_LOADER stays as the

‎tests/examples/vulkan/tests/loader.cpp‎

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,22 @@
88
// legitimately ABSENT on a driverless machine and asserting on it would just be
99
// testing the runner's hardware.
1010
//
11-
// HAVE_VULKAN_LOADER is set by THIS project's own [target.'cfg(...)'.build]
12-
// cxxflags, because compat.vulkan has no windows entry. A consumer that keys
13-
// its source off a dependency's presence has to declare that itself.
11+
// HAVE_VULKAN_LOADER is set by THIS project's own [build] cxxflags. A consumer
12+
// that keys its source off a dependency's presence has to declare that itself.
1413
#if defined(HAVE_VULKAN_LOADER)
1514
#include <vulkan/vulkan.h>
1615
#endif
1716
import std;
1817

18+
#if defined(HAVE_VULKAN_LOADER) && defined(_WIN32)
19+
// Declared rather than taken from <windows.h>: two functions are needed, and
20+
// the header's macros and min/max collide with `import std`. Both live in
21+
// kernel32, which every Windows program already links.
22+
extern "C" __declspec(dllimport) void* GetModuleHandleW(const wchar_t* name);
23+
extern "C" __declspec(dllimport) unsigned long GetModuleFileNameW(void* module, wchar_t* path,
24+
unsigned long size);
25+
#endif
26+
1927
#if !defined(HAVE_VULKAN_LOADER)
2028
int main() {
2129
std::println("compat.vulkan: skipped (no windows build — static loader unsupported upstream)");
@@ -36,6 +44,44 @@ int main() {
3644
return 2;
3745
}
3846

47+
#if defined(_WIN32)
48+
// WHERE THE LOADER CAME FROM is the point of compat.vulkan 1.4.357.3 on
49+
// Windows: the package now ships vulkan-1.dll and mcpp places it beside the
50+
// executable, so a machine with no GPU driver can still start this program.
51+
// The loader has just answered, so the DLL is mapped; its directory must be
52+
// this executable's. That holds on a machine WITH a driver too (the
53+
// application directory precedes System32), which is what makes this a real
54+
// check: with an older compat.vulkan the loader came from System32 there,
55+
// and on a driverless machine the process never reached main.
56+
{
57+
std::vector<wchar_t> dll(32768), exe(32768);
58+
void* module = GetModuleHandleW(L"vulkan-1.dll");
59+
if (module == nullptr) {
60+
std::println("vulkan-1.dll answered but is not mapped in this process");
61+
return 7;
62+
}
63+
const auto dllLen = GetModuleFileNameW(module, dll.data(), 32768);
64+
const auto exeLen = GetModuleFileNameW(nullptr, exe.data(), 32768);
65+
auto dirOf = [](std::wstring_view p) {
66+
std::wstring d(p.substr(0, p.find_last_of(L"\\/")));
67+
for (auto& c : d) c = static_cast<wchar_t>(std::towlower(c));
68+
return d;
69+
};
70+
auto narrow = [](std::wstring_view p) {
71+
std::string out;
72+
for (wchar_t c : p) out.push_back(c < 128 ? static_cast<char>(c) : '?');
73+
return out;
74+
};
75+
const std::wstring_view dllPath(dll.data(), dllLen), exePath(exe.data(), exeLen);
76+
if (dirOf(dllPath) != dirOf(exePath)) {
77+
std::println("vulkan-1.dll was loaded from {}, not beside {}",
78+
narrow(dllPath), narrow(exePath));
79+
return 8;
80+
}
81+
std::println("compat.vulkan: loader deployed beside the executable ({})", narrow(dllPath));
82+
}
83+
#endif
84+
3985
std::uint32_t extensionCount = 0;
4086
if (vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr) != VK_SUCCESS) {
4187
std::println("vkEnumerateInstanceExtensionProperties failed");

0 commit comments

Comments
 (0)