mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-04-26 12:21:43 +00:00
fix: layer: support multiple instances
Some checks failed
(CI) lsfg-vk / build (push) Has been cancelled
(CI/Flatpak) lsfg-vk / flatpak-extensions (23.08) (push) Has been cancelled
(CI/Flatpak) lsfg-vk / flatpak-extensions (24.08) (push) Has been cancelled
(CI/Flatpak) lsfg-vk / flatpak-extensions (25.08) (push) Has been cancelled
(CI/Flatpak) lsfg-vk / flatpak-ui (push) Has been cancelled
Some checks failed
(CI) lsfg-vk / build (push) Has been cancelled
(CI/Flatpak) lsfg-vk / flatpak-extensions (23.08) (push) Has been cancelled
(CI/Flatpak) lsfg-vk / flatpak-extensions (24.08) (push) Has been cancelled
(CI/Flatpak) lsfg-vk / flatpak-extensions (25.08) (push) Has been cancelled
(CI/Flatpak) lsfg-vk / flatpak-ui (push) Has been cancelled
i- it turns out some games *do* use multiple Vulkan instances
This commit is contained in:
parent
94d243bc2d
commit
9943153918
1 changed files with 30 additions and 22 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include "lsfg-vk-common/vulkan/vulkan.hpp"
|
||||
#include "swapchain.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
|
|
@ -29,9 +30,9 @@ namespace {
|
|||
Root root;
|
||||
}* layer_info;
|
||||
|
||||
// instance-wide info initialized at instance creation
|
||||
// instance-wide info initialized at instance creation(s)
|
||||
struct InstanceInfo {
|
||||
VkInstance handle;
|
||||
std::vector<VkInstance> handles; // there may be several instances
|
||||
vk::VulkanInstanceFuncs funcs;
|
||||
|
||||
std::unordered_map<VkDevice, vk::Vulkan> devices;
|
||||
|
|
@ -91,11 +92,13 @@ namespace {
|
|||
}
|
||||
);
|
||||
|
||||
instance_info = new InstanceInfo{
|
||||
.handle = *instance,
|
||||
.funcs = vk::initVulkanInstanceFuncs(*instance, layer_info->GetInstanceProcAddr, true),
|
||||
.devices = {}
|
||||
};
|
||||
if (!instance_info)
|
||||
instance_info = new InstanceInfo{
|
||||
.funcs = vk::initVulkanInstanceFuncs(*instance,
|
||||
layer_info->GetInstanceProcAddr, true),
|
||||
};
|
||||
|
||||
instance_info->handles.push_back(*instance);
|
||||
|
||||
return VK_SUCCESS;
|
||||
} catch (const ls::vulkan_error& e) {
|
||||
|
|
@ -179,7 +182,7 @@ namespace {
|
|||
instance_info->devices.emplace(
|
||||
*device,
|
||||
vk::Vulkan(
|
||||
instance_info->handle, *device, physdev,
|
||||
instance_info->handles.front(), *device, physdev,
|
||||
instance_info->funcs, vk::initVulkanDeviceFuncs(instance_info->funcs, *device,
|
||||
true),
|
||||
true, setLoaderData
|
||||
|
|
@ -214,9 +217,16 @@ namespace {
|
|||
|
||||
// destroy instance
|
||||
void myvkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* alloc) {
|
||||
// destroy instance info
|
||||
delete instance_info;
|
||||
instance_info = nullptr;
|
||||
// remove instance handle
|
||||
auto it = std::ranges::find(instance_info->handles, instance);
|
||||
if (it != instance_info->handles.end())
|
||||
instance_info->handles.erase(it);
|
||||
|
||||
// destroy instance info if no handles remain
|
||||
if (instance_info->handles.empty()) {
|
||||
delete instance_info;
|
||||
instance_info = nullptr;
|
||||
}
|
||||
|
||||
// destroy instance
|
||||
auto vkDestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
|
||||
|
|
@ -228,14 +238,6 @@ namespace {
|
|||
}
|
||||
|
||||
vkDestroyInstance(instance, alloc);
|
||||
|
||||
// destroy layer info
|
||||
// NOTE: there's no real way of unloading the layer without a deconstructor.
|
||||
// multiple instances just aren't common enough to worry about it.
|
||||
// NOTE2: this IS a memory leak, because the VkInstance inside of root->backend
|
||||
// cannot be destroyed, due to a Vulkan-Loader limitation/bug.
|
||||
delete layer_info;
|
||||
layer_info = nullptr;
|
||||
}
|
||||
|
||||
// get optional function pointer override
|
||||
|
|
@ -250,9 +252,6 @@ namespace {
|
|||
PFN_vkVoidFunction myvkGetInstanceProcAddr(VkInstance instance, const char* name) {
|
||||
if (!name) return nullptr;
|
||||
|
||||
if (std::string(name) == "vkCreateInstance") // pre-instance function
|
||||
return reinterpret_cast<PFN_vkVoidFunction>(myvkCreateInstance);
|
||||
|
||||
auto func = getProcAddr(name);
|
||||
if (func) return func;
|
||||
|
||||
|
|
@ -453,6 +452,15 @@ VkResult vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface* pVers
|
|||
|| pVersionStruct->loaderLayerInterfaceVersion < 2)
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
|
||||
// if the layer has already been initialized, skip
|
||||
if (layer_info) {
|
||||
pVersionStruct->loaderLayerInterfaceVersion = 2;
|
||||
pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
|
||||
pVersionStruct->pfnGetDeviceProcAddr = myvkGetDeviceProcAddr;
|
||||
pVersionStruct->pfnGetInstanceProcAddr = myvkGetInstanceProcAddr;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
// load the layer configuration
|
||||
try {
|
||||
layer_info = new LayerInfo {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue