M2(Vulkan layer): registry register/unregister + opt-in Injection-panel checkbox

Host helper register_vk_layer/unregister_vk_layer registers coop_vk_layer's
manifest as a per-user (HKCU, no admin) implicit Vulkan layer and writes the
scoping file (%TEMP%\coop_vk_target.txt) naming the target game's exe, so the
layer captures only that game and stays inert for every other Vulkan app. The
Injection panel gains an opt-in "Set up Vulkan layer" checkbox (next to Auto
re-attach, which the too-late banner points at); it registers on tick,
unregisters on untick, and the panel destructor unregisters on host exit so no
stale registration is left behind.

Verified live: a registry-registered layer is loaded by the loader for a fresh
vk launch (no env vars) and the scoping matches (active=1), then cleans up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 13:29:14 +02:00
parent 2532ffed56
commit 23a6408e52
5 changed files with 132 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
// Host-side setup for the opt-in Vulkan capture layer (coop_vk_layer). Registering it as a
// per-user implicit Vulkan layer makes the Vulkan loader insert it at vkCreateInstance -- so it's
// in the chain before a game (that caches its present pointer at init) can resolve
// vkQueuePresentKHR, the reliable early-presence path the inject-after-launch hook can't get.
//
// An implicit layer loads into *every* Vulkan app, so the layer itself only captures the process
// whose image basename matches the scoping file this writes -- keeping it inert for everything but
// the host's target. Registration is HKCU-only (no admin) and fully reversible.
#pragma once
#include <string>
namespace coop
{
// Register the implicit layer (HKCU) and scope it to `target_image` (the game's exe basename,
// e.g. "game.exe"). Returns true on success. Idempotent.
bool register_vk_layer(const std::wstring& target_image);
// Remove the registry registration and the scoping file. Safe to call when not registered (e.g.
// on host shutdown as a belt-and-suspenders cleanup).
void unregister_vk_layer();
} // namespace coop