Fix early vulkan calls on Linux

This commit is contained in:
FakeMichau
2026-03-19 01:49:44 +01:00
parent 0c43f74ce0
commit ca8b4bb690
4 changed files with 53 additions and 33 deletions
+2 -2
View File
@@ -1217,7 +1217,7 @@ static void CheckQuirks()
auto quirks = getQuirksForExe(exePathFilename);
auto state = &State::Instance();
auto primaryGpu = IdentifyGpu::getPrimaryGpuNoDxgi();
auto primaryGpu = IdentifyGpu::getPrimaryGpuVulkan();
// Apply config-level quirks
if (quirks & GameQuirk::DisableHudfix && Config::Instance()->FGInput.value_or_default() == FGInput::Upscaler)
@@ -1609,7 +1609,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
spdlog::info("");
State::Instance().isRunningOnLinux = IsRunningOnWine();
auto primaryGpu = IdentifyGpu::getPrimaryGpuNoDxgi();
auto primaryGpu = IdentifyGpu::getPrimaryGpuVulkan();
// Check if real DLSS available
if (Config::Instance()->DLSSEnabled.value_or_default())
+1 -15
View File
@@ -2315,7 +2315,7 @@ bool MenuCommon::RenderMenu()
ImGui::PushItemWidth(180.0f * menuResScale);
auto primaryGpuVulkan = IdentifyGpu::getPrimaryGpuNoDxgi();
auto primaryGpuVulkan = IdentifyGpu::getPrimaryGpuVulkan();
switch (state.api)
{
@@ -4382,20 +4382,6 @@ bool MenuCommon::RenderMenu()
config->FramerateLimit = _limitFps;
}
if (ImGui::Button("S"))
ImGui::InsertNotification(
{ ImGuiToastType::Success, 10000, "Test Success Test Success Test Success Test Success" });
ImGui::SameLine(0.0f, 16.0f);
if (ImGui::Button("W"))
ImGui::InsertNotification(
{ ImGuiToastType::Warning, 10000, "Test warning Test warning Test warning" });
ImGui::SameLine(0.0f, 16.0f);
if (ImGui::Button("E"))
ImGui::InsertNotification({ ImGuiToastType::Error, 10000, "Test error Test error" });
ImGui::SameLine(0.0f, 16.0f);
if (ImGui::Button("I"))
ImGui::InsertNotification({ ImGuiToastType::Info, 10000, "Test info" });
ImGui::Spacing();
if (auto ch = ScopedCollapsingHeader("VRR Frame Cap Calculator"); ch.IsHeaderOpen())
{
+47 -13
View File
@@ -30,6 +30,9 @@ void sortGpus(std::vector<GpuInformation>& gpus)
return aIsPreferred;
}
if (a.softwareAdapter)
return false;
// Fallback on VRAM amount
return a.dedicatedVramInBytes > b.dedicatedVramInBytes;
});
@@ -205,7 +208,7 @@ std::vector<GpuInformation> IdentifyGpu::checkGpuInfo()
// !!! Doesn't fill out FSR 4 capability and dxvk/vkd3d-proton usages !!!
// We are using Vulkan inside DLL_PROCESS_ATTACH which unlike dxgi technically works™
// Not ideal + requires a GPU that supports Vulkan but every GPU we care about should
std::vector<GpuInformation> IdentifyGpu::checkGpuInfoNoDxgi()
std::vector<GpuInformation> IdentifyGpu::checkGpuInfoVulkan()
{
auto localCachedInfo = std::vector<GpuInformation> {};
@@ -221,15 +224,46 @@ std::vector<GpuInformation> IdentifyGpu::checkGpuInfoNoDxgi()
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
// while (!IsDebuggerPresent())
// Sleep(100);
auto winevulkan = LoadLibraryA("winevulkan.dll");
auto o_vkCreateInstance = vkCreateInstance;
auto o_vkGetInstanceProcAddr = vkGetInstanceProcAddr;
if (State::Instance().isRunningOnLinux && winevulkan)
{
o_vkCreateInstance = (PFN_vkCreateInstance) KernelBaseProxy::GetProcAddress_()(winevulkan, "vkCreateInstance");
o_vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr) KernelBaseProxy::GetProcAddress_()(winevulkan, "vkGetInstanceProcAddr");
}
VkInstance instance = VK_NULL_HANDLE;
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
if (o_vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
{
LOG_ERROR("Couldn't create a Vulkan instance");
return localCachedInfo;
}
auto o_vkEnumeratePhysicalDevices = vkEnumeratePhysicalDevices;
auto o_vkGetPhysicalDeviceProperties2 = vkGetPhysicalDeviceProperties2;
auto o_vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties;
auto o_vkDestroyInstance = vkDestroyInstance;
if (State::Instance().isRunningOnLinux && winevulkan && instance)
{
o_vkEnumeratePhysicalDevices =
(PFN_vkEnumeratePhysicalDevices) o_vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDevices");
o_vkGetPhysicalDeviceProperties2 =
(PFN_vkGetPhysicalDeviceProperties2) o_vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2");
o_vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) o_vkGetInstanceProcAddr(
instance, "vkGetPhysicalDeviceMemoryProperties");
o_vkDestroyInstance = (PFN_vkDestroyInstance) o_vkGetInstanceProcAddr(instance, "vkDestroyInstance");
}
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
o_vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
if (deviceCount == 0)
{
@@ -241,7 +275,7 @@ std::vector<GpuInformation> IdentifyGpu::checkGpuInfoNoDxgi()
// ScopedSkipSpoofing skipSpoofing {};
std::vector<VkPhysicalDevice> physicalDevices(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, physicalDevices.data());
o_vkEnumeratePhysicalDevices(instance, &deviceCount, physicalDevices.data());
for (auto physicalDevice : physicalDevices)
{
@@ -252,10 +286,10 @@ std::vector<GpuInformation> IdentifyGpu::checkGpuInfoNoDxgi()
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
props2.pNext = &idProps;
vkGetPhysicalDeviceProperties2(physicalDevice, &props2);
o_vkGetPhysicalDeviceProperties2(physicalDevice, &props2);
VkPhysicalDeviceMemoryProperties memProps {};
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProps);
o_vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProps);
GpuInformation gpuInfo;
for (uint32_t i = 0; i < memProps.memoryHeapCount; ++i)
@@ -275,7 +309,7 @@ std::vector<GpuInformation> IdentifyGpu::checkGpuInfoNoDxgi()
localCachedInfo.push_back(std::move(gpuInfo));
}
vkDestroyInstance(instance, nullptr);
o_vkDestroyInstance(instance, nullptr);
sortGpus(localCachedInfo);
for (auto& gpuInfo : localCachedInfo)
@@ -423,17 +457,17 @@ GpuInformation IdentifyGpu::getPrimaryGpu()
return allGpus.size() > 0 ? allGpus[0] : GpuInformation {};
}
// !!! Use the NoDxgi variants only inside DLL_PROCESS_ATTACH as they provide incomplete data !!!
std::vector<GpuInformation> IdentifyGpu::getAllGpusNoDxgi()
// !!! Use the Vulkan variants only inside DLL_PROCESS_ATTACH as they provide incomplete data !!!
std::vector<GpuInformation> IdentifyGpu::getAllGpusVulkan()
{
static std::vector<GpuInformation> cache = []() { return checkGpuInfoNoDxgi(); }();
static std::vector<GpuInformation> cache = []() { return checkGpuInfoVulkan(); }();
return cache;
}
// !!! Use the NoDxgi variants only inside DLL_PROCESS_ATTACH as they provide incomplete data !!!
GpuInformation IdentifyGpu::getPrimaryGpuNoDxgi()
// !!! Use the Vulkan variants only inside DLL_PROCESS_ATTACH as they provide incomplete data !!!
GpuInformation IdentifyGpu::getPrimaryGpuVulkan()
{
// return GpuInformation {};
auto allGpus = getAllGpusNoDxgi();
auto allGpus = getAllGpusVulkan();
return allGpus.size() > 0 ? allGpus[0] : GpuInformation {};
}
+3 -3
View File
@@ -83,7 +83,7 @@ inline constexpr bool IsEqualLUID(LUID luid1, LUID luid2)
class IdentifyGpu
{
static std::vector<GpuInformation> checkGpuInfo();
static std::vector<GpuInformation> checkGpuInfoNoDxgi();
static std::vector<GpuInformation> checkGpuInfoVulkan();
static void queryNvapi(GpuInformation& gpuInfo);
public:
@@ -93,6 +93,6 @@ class IdentifyGpu
// Sorted by priority, the first one should be treated as the primary one
static std::vector<GpuInformation> getAllGpus();
static GpuInformation getPrimaryGpu();
static std::vector<GpuInformation> getAllGpusNoDxgi();
static GpuInformation getPrimaryGpuNoDxgi();
static std::vector<GpuInformation> getAllGpusVulkan();
static GpuInformation getPrimaryGpuVulkan();
};