mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-09-23 13:56:19 +00:00
Add dxvk and vkd3d-proton checks
This commit is contained in:
@@ -194,7 +194,6 @@ class State
|
||||
|
||||
// Linux checks
|
||||
bool isRunningOnLinux = false;
|
||||
bool isRunningOnDXVK = false;
|
||||
|
||||
// Other checks
|
||||
bool isRunningOnNvidia = false;
|
||||
|
||||
+7
-37
@@ -587,45 +587,17 @@ static void CheckWorkingMode()
|
||||
// dxgi.dll
|
||||
if (lCaseFilename == "dxgi.dll")
|
||||
{
|
||||
do
|
||||
{
|
||||
auto pluginFilePath = pluginPath / L"dxgi.dll";
|
||||
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
|
||||
// Init will try to load the specifc path itself
|
||||
// It's to allow dxgi usage before this point
|
||||
DxgiProxy::Init(nullptr, _passThruMode);
|
||||
|
||||
if (originalModule != nullptr)
|
||||
{
|
||||
if (!_passThruMode)
|
||||
LOG_INFO("OptiScaler working as dxgi.dll, original dll loaded from plugin folder");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"dxgi-original.dll", NULL, 0);
|
||||
|
||||
if (originalModule != nullptr)
|
||||
{
|
||||
if (!_passThruMode)
|
||||
LOG_INFO("OptiScaler working as dxgi.dll, dxgi-original.dll loaded");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
auto sysFilePath = sysPath / L"dxgi.dll";
|
||||
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
|
||||
|
||||
if (originalModule != nullptr && !_passThruMode)
|
||||
LOG_INFO("OptiScaler working as dxgi.dll, system dll loaded");
|
||||
|
||||
} while (false);
|
||||
|
||||
if (originalModule != nullptr)
|
||||
if (DxgiProxy::Module() != nullptr)
|
||||
{
|
||||
dllNames.push_back("dxgi.dll");
|
||||
dllNames.push_back("dxgi");
|
||||
dllNamesW.push_back(L"dxgi.dll");
|
||||
dllNamesW.push_back(L"dxgi");
|
||||
|
||||
DxgiProxy::Init(originalModule);
|
||||
dxgi.LoadOriginalLibrary(originalModule);
|
||||
|
||||
State::Instance().isDxgiMode = true;
|
||||
@@ -839,7 +811,7 @@ static void CheckWorkingMode()
|
||||
}
|
||||
|
||||
// Vulkan
|
||||
if (State::Instance().isRunningOnDXVK || State::Instance().isRunningOnLinux ||
|
||||
if (IdentifyGpu::getPrimaryGpu().usesDxvk || State::Instance().isRunningOnLinux ||
|
||||
(State::Instance().gameQuirks & GameQuirk::LoadVulkanManually))
|
||||
{
|
||||
vulkanModule = NtdllProxy::LoadLibraryExW_Ldr(L"vulkan-1.dll", NULL, 0);
|
||||
@@ -1770,7 +1742,8 @@ DWORD WINAPI InitThread(LPVOID hModuleVoid)
|
||||
// Check for Wine
|
||||
spdlog::info("");
|
||||
State::Instance().isRunningOnLinux = IsRunningOnWine();
|
||||
State::Instance().isRunningOnDXVK = State::Instance().isRunningOnLinux;
|
||||
|
||||
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
|
||||
|
||||
// Check if real DLSS available
|
||||
if (Config::Instance()->DLSSEnabled.value_or_default())
|
||||
@@ -1827,10 +1800,7 @@ DWORD WINAPI InitThread(LPVOID hModuleVoid)
|
||||
spdlog::info("");
|
||||
CheckWorkingMode();
|
||||
|
||||
auto d = IdentifyGpu::getGpuInfo();
|
||||
|
||||
// OptiFG & Overlay Checks
|
||||
// TODO: Either FGInput == FGInput::Upscaler or FGOutput == FGOutput::FSRFG
|
||||
if ((Config::Instance()->FGInput.value_or_default() == FGInput::Upscaler) &&
|
||||
!Config::Instance()->DisableOverlays.has_value())
|
||||
Config::Instance()->DisableOverlays.set_volatile_value(true);
|
||||
|
||||
@@ -27,6 +27,7 @@ void CheckForGPU();
|
||||
std::vector<std::filesystem::path> GetDriverStore();
|
||||
HMODULE GetFSR4Module();
|
||||
|
||||
// Based on the PDBs provided with FFX 2.1.0
|
||||
enum AmdExtWaveMatrixPropertiesType : int32_t
|
||||
{
|
||||
float16 = 0x0,
|
||||
|
||||
@@ -20,28 +20,6 @@
|
||||
#include <magic_enum.hpp>
|
||||
#endif
|
||||
|
||||
void DxgiFactoryHooks::CheckAdapter(IUnknown* unkAdapter)
|
||||
{
|
||||
if (State::Instance().isRunningOnDXVK)
|
||||
return;
|
||||
|
||||
// DXVK VkInterface GUID
|
||||
const GUID guid = { 0x907bf281, 0xea3c, 0x43b4, { 0xa8, 0xe4, 0x9f, 0x23, 0x11, 0x07, 0xb4, 0xff } };
|
||||
|
||||
IDXGIAdapter* adapter = nullptr;
|
||||
bool adapterOk = unkAdapter->QueryInterface(IID_PPV_ARGS(&adapter)) == S_OK;
|
||||
|
||||
void* dxvkAdapter = nullptr;
|
||||
if (adapterOk && adapter->QueryInterface(guid, &dxvkAdapter) == S_OK)
|
||||
{
|
||||
State::Instance().isRunningOnDXVK = dxvkAdapter != nullptr;
|
||||
((IDXGIAdapter*) dxvkAdapter)->Release();
|
||||
}
|
||||
|
||||
if (adapterOk)
|
||||
adapter->Release();
|
||||
}
|
||||
|
||||
void DxgiFactoryHooks::HookToFactory(IDXGIFactory* pFactory)
|
||||
{
|
||||
if (pFactory == nullptr)
|
||||
@@ -920,10 +898,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters(IDXGIFactory* realFactory, UINT Adapter,
|
||||
}
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
CheckAdapter(*ppAdapter);
|
||||
DxgiSpoofing::AttachToAdapter(*ppAdapter);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppAdapter);
|
||||
@@ -997,10 +972,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters1(IDXGIFactory1* realFactory, UINT Adapter
|
||||
}
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
CheckAdapter(*ppAdapter);
|
||||
DxgiSpoofing::AttachToAdapter(*ppAdapter);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppAdapter);
|
||||
@@ -1019,10 +991,7 @@ HRESULT DxgiFactoryHooks::EnumAdapterByLuid(IDXGIFactory4* realFactory, LUID Ada
|
||||
}
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
CheckAdapter((IUnknown*) *ppvAdapter);
|
||||
DxgiSpoofing::AttachToAdapter((IUnknown*) *ppvAdapter);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
LOG_TRACE("result: {:X}, pAdapter: {:X}", (UINT) result, (uintptr_t) *ppvAdapter);
|
||||
@@ -1042,10 +1011,7 @@ HRESULT DxgiFactoryHooks::EnumAdapterByGpuPreference(IDXGIFactory6* realFactory,
|
||||
}
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
CheckAdapter((IUnknown*) *ppvAdapter);
|
||||
DxgiSpoofing::AttachToAdapter((IUnknown*) *ppvAdapter);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppvAdapter);
|
||||
|
||||
@@ -53,8 +53,6 @@ class DxgiFactoryHooks
|
||||
inline static bool _skipFGSwapChainCreation = false;
|
||||
inline static bool _skipHighPerfCheck = false;
|
||||
|
||||
static void CheckAdapter(IUnknown* unkAdapter);
|
||||
|
||||
class ScopedSkipFGSCCreation
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -18,28 +18,6 @@
|
||||
#include <magic_enum.hpp>
|
||||
#endif
|
||||
|
||||
void DxgiFactoryWrappedCalls::CheckAdapter(IUnknown* unkAdapter)
|
||||
{
|
||||
if (State::Instance().isRunningOnDXVK)
|
||||
return;
|
||||
|
||||
// DXVK VkInterface GUID
|
||||
const GUID guid = { 0x907bf281, 0xea3c, 0x43b4, { 0xa8, 0xe4, 0x9f, 0x23, 0x11, 0x07, 0xb4, 0xff } };
|
||||
|
||||
IDXGIAdapter* adapter = nullptr;
|
||||
bool adapterOk = unkAdapter->QueryInterface(IID_PPV_ARGS(&adapter)) == S_OK;
|
||||
|
||||
void* dxvkAdapter = nullptr;
|
||||
if (adapterOk && adapter->QueryInterface(guid, &dxvkAdapter) == S_OK)
|
||||
{
|
||||
State::Instance().isRunningOnDXVK = dxvkAdapter != nullptr;
|
||||
((IDXGIAdapter*) dxvkAdapter)->Release();
|
||||
}
|
||||
|
||||
if (adapterOk)
|
||||
adapter->Release();
|
||||
}
|
||||
|
||||
HRESULT DxgiFactoryWrappedCalls::CreateSwapChain(IDXGIFactory* realFactory, WrappedIDXGIFactory7* wrappedFactory,
|
||||
IUnknown* pDevice, const DXGI_SWAP_CHAIN_DESC* pDesc,
|
||||
IDXGISwapChain** ppSwapChain)
|
||||
@@ -810,10 +788,7 @@ HRESULT DxgiFactoryWrappedCalls::EnumAdapters(IDXGIFactory* realFactory, UINT Ad
|
||||
}
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
CheckAdapter(*ppAdapter);
|
||||
DxgiSpoofing::AttachToAdapter(*ppAdapter);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppAdapter);
|
||||
@@ -886,10 +861,7 @@ HRESULT DxgiFactoryWrappedCalls::EnumAdapters1(IDXGIFactory1* realFactory, UINT
|
||||
}
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
CheckAdapter(*ppAdapter);
|
||||
DxgiSpoofing::AttachToAdapter(*ppAdapter);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppAdapter);
|
||||
@@ -909,10 +881,7 @@ HRESULT DxgiFactoryWrappedCalls::EnumAdapterByLuid(IDXGIFactory4* realFactory, L
|
||||
}
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
CheckAdapter((IUnknown*) *ppvAdapter);
|
||||
DxgiSpoofing::AttachToAdapter((IUnknown*) *ppvAdapter);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
LOG_TRACE("result: {:X}, pAdapter: {:X}", (UINT) result, (uintptr_t) *ppvAdapter);
|
||||
@@ -933,10 +902,7 @@ HRESULT DxgiFactoryWrappedCalls::EnumAdapterByGpuPreference(IDXGIFactory6* realF
|
||||
}
|
||||
|
||||
if (result == S_OK)
|
||||
{
|
||||
CheckAdapter((IUnknown*) *ppvAdapter);
|
||||
DxgiSpoofing::AttachToAdapter((IUnknown*) *ppvAdapter);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppvAdapter);
|
||||
|
||||
@@ -29,8 +29,6 @@ class DxgiFactoryWrappedCalls
|
||||
inline static bool _skipFGSwapChainCreation = false;
|
||||
inline static bool _skipHighPerfCheck = false;
|
||||
|
||||
static void CheckAdapter(IUnknown* unkAdapter);
|
||||
|
||||
class ScopedSkipFGSCCreation
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include <detours/detours.h>
|
||||
#include <misc/IdentifyGpu.h>
|
||||
|
||||
// for menu rendering
|
||||
static VkDevice _device = VK_NULL_HANDLE;
|
||||
@@ -183,7 +184,9 @@ static VkResult hkvkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPres
|
||||
// get upscaler time
|
||||
UpscalerTimeVk::ReadUpscalingTime(_device);
|
||||
|
||||
if (!State::Instance().isRunningOnDXVK)
|
||||
// ??? TODO: if we are hooking dxvk's vulkan calls then this present call could be either coming from dxvk or from a
|
||||
// native vk game
|
||||
if (!IdentifyGpu::getPrimaryGpu().usesDxvk)
|
||||
State::Instance().swapchainApi = Vulkan;
|
||||
|
||||
// Tick feature to let it know if it's frozen
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <misc/IdentifyGpu.h>
|
||||
|
||||
#define MARK_ALL_BACKENDS_CHANGED() \
|
||||
for (auto& singleChangeBackend : State::Instance().changeBackend) \
|
||||
@@ -1872,7 +1873,11 @@ bool MenuCommon::RenderMenu()
|
||||
ImGuiWindowFlags_NoNav))
|
||||
{
|
||||
std::string api;
|
||||
if (state.isRunningOnDXVK || state.isRunningOnLinux)
|
||||
if (IdentifyGpu::getPrimaryGpu().usesDxvk && state.api == DX11)
|
||||
{
|
||||
api = "DXVK";
|
||||
}
|
||||
else if (IdentifyGpu::getPrimaryGpu().usesVkd3dProton && state.api == DX12)
|
||||
{
|
||||
api = "VKD3D";
|
||||
}
|
||||
@@ -2390,7 +2395,7 @@ bool MenuCommon::RenderMenu()
|
||||
else if (state.DeviceAdapterNames.contains(state.currentD3D12Device))
|
||||
ImGui::Text(state.DeviceAdapterNames[state.currentD3D12Device].c_str());
|
||||
|
||||
ImGui::Text("D3D11 %s| %s %d.%d.%d", state.isRunningOnDXVK ? "(DXVK) " : "",
|
||||
ImGui::Text("D3D11 %s| %s %d.%d.%d", IdentifyGpu::getPrimaryGpu().usesDxvk ? "(DXVK) " : "",
|
||||
currentFeature->Name().c_str(), currentFeature->Version().major,
|
||||
currentFeature->Version().minor, currentFeature->Version().patch);
|
||||
ImGui::SameLine(0.0f, 6.0f);
|
||||
@@ -2409,7 +2414,7 @@ bool MenuCommon::RenderMenu()
|
||||
if (state.DeviceAdapterNames.contains(state.currentD3D12Device))
|
||||
ImGui::Text(state.DeviceAdapterNames[state.currentD3D12Device].c_str());
|
||||
|
||||
ImGui::Text("D3D12 %s| %s %d.%d.%d", state.isRunningOnDXVK ? "(DXVK) " : "",
|
||||
ImGui::Text("D3D12 %s| %s %d.%d.%d", IdentifyGpu::getPrimaryGpu().usesDxvk ? "(DXVK) " : "",
|
||||
currentFeature->Name().c_str(), currentFeature->Version().major,
|
||||
currentFeature->Version().minor, currentFeature->Version().patch);
|
||||
ImGui::SameLine(0.0f, 6.0f);
|
||||
@@ -2428,7 +2433,7 @@ bool MenuCommon::RenderMenu()
|
||||
if (state.DeviceAdapterNames.contains(state.currentVkDevice))
|
||||
ImGui::Text(state.DeviceAdapterNames[state.currentVkDevice].c_str());
|
||||
|
||||
ImGui::Text("Vulkan %s| %s %d.%d.%d", state.isRunningOnDXVK ? "(DXVK) " : "",
|
||||
ImGui::Text("Vulkan %s| %s %d.%d.%d", IdentifyGpu::getPrimaryGpu().usesDxvk ? "(DXVK) " : "",
|
||||
currentFeature->Name().c_str(), currentFeature->Version().major,
|
||||
currentFeature->Version().minor, currentFeature->Version().patch);
|
||||
ImGui::SameLine(0.0f, 6.0f);
|
||||
|
||||
@@ -10,7 +10,7 @@ std::optional<std::vector<GpuInformation>> IdentifyGpu::cachedInfo;
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
// Maybe take into account some other GPU ordering, DxgiFactoryWrappedCalls::EnumAdapters?
|
||||
// TODO: Maybe take into account some other GPU ordering, DxgiFactoryWrappedCalls::EnumAdapters?
|
||||
constexpr int vendorPriority(VendorId::Value v)
|
||||
{
|
||||
switch (v)
|
||||
@@ -75,7 +75,13 @@ void IdentifyGpu::checkGpuInfo()
|
||||
std::wstring szName(adapterDesc.Description);
|
||||
gpuInfo.name = wstring_to_string(szName);
|
||||
|
||||
if (gpuInfo.vendorId == VendorId::AMD)
|
||||
// TODO: check if an invalid guid still return S_OK but nullptr
|
||||
ComPtr<IDXGIVkInteropDevice> dxgiInterop;
|
||||
if (SUCCEEDED(adapter->QueryInterface(IID_PPV_ARGS(&dxgiInterop))))
|
||||
gpuInfo.usesDxvk = true;
|
||||
|
||||
// Needed to be able to query amdxc and check for vkd3d-proton
|
||||
if (gpuInfo.vendorId == VendorId::AMD || gpuInfo.usesDxvk)
|
||||
{
|
||||
auto result =
|
||||
D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(&gpuInfo.d3d12device));
|
||||
@@ -96,6 +102,10 @@ void IdentifyGpu::checkGpuInfo()
|
||||
|
||||
for (auto& gpuInfo : localCachedInfo)
|
||||
{
|
||||
ComPtr<ID3D12DXVKInteropDevice> vkd3dInterop;
|
||||
if (gpuInfo.usesDxvk && SUCCEEDED(gpuInfo.d3d12device->QueryInterface(IID_PPV_ARGS(&vkd3dInterop))))
|
||||
gpuInfo.usesVkd3dProton = true;
|
||||
|
||||
if (gpuInfo.vendorId == VendorId::AMD && gpuInfo.d3d12device)
|
||||
{
|
||||
auto moduleAmdxc64 = KernelBaseProxy::GetModuleHandleW_()(L"amdxc64.dll");
|
||||
@@ -119,32 +129,27 @@ void IdentifyGpu::checkGpuInfo()
|
||||
{
|
||||
HRESULT float8support =
|
||||
amdExtD3DShaderIntrinsics->CheckSupport(AmdExtD3DShaderIntrinsicsSupport_Float8Conversion);
|
||||
gpuInfo.fsr4capable = float8support == S_OK;
|
||||
gpuInfo.fsr4Capable = float8support == S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gpuInfo.fsr4capable /*&& State::Instance().isRunningOnLinux*/)
|
||||
if (!gpuInfo.fsr4Capable && gpuInfo.usesVkd3dProton)
|
||||
{
|
||||
ComPtr<ID3D12DXVKInteropDevice> interop;
|
||||
UINT extensionCount = 0;
|
||||
|
||||
if (SUCCEEDED(gpuInfo.d3d12device->QueryInterface(IID_PPV_ARGS(&interop))))
|
||||
if (SUCCEEDED(vkd3dInterop->GetDeviceExtensions(&extensionCount, nullptr)) && extensionCount > 0)
|
||||
{
|
||||
UINT extensionCount = 0;
|
||||
std::vector<const char*> exts(extensionCount);
|
||||
|
||||
if (SUCCEEDED(interop->GetDeviceExtensions(&extensionCount, nullptr)) && extensionCount > 0)
|
||||
if (SUCCEEDED(vkd3dInterop->GetDeviceExtensions(&extensionCount, exts.data())))
|
||||
{
|
||||
std::vector<const char*> exts(extensionCount);
|
||||
|
||||
if (SUCCEEDED(interop->GetDeviceExtensions(&extensionCount, exts.data())))
|
||||
for (UINT i = 0; i < extensionCount; i++)
|
||||
{
|
||||
for (UINT i = 0; i < extensionCount; i++)
|
||||
// Only RDNA4+
|
||||
if (!strcmp("VK_EXT_shader_float8", exts[i]))
|
||||
{
|
||||
// Only RDNA4+
|
||||
if (!strcmp("VK_EXT_shader_float8", exts[i]))
|
||||
{
|
||||
gpuInfo.fsr4capable = true;
|
||||
break;
|
||||
}
|
||||
gpuInfo.fsr4Capable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,10 +241,16 @@ void IdentifyGpu::checkGpuInfo()
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<GpuInformation> IdentifyGpu::getGpuInfo()
|
||||
std::vector<GpuInformation> IdentifyGpu::getAllGpus()
|
||||
{
|
||||
if (!cachedInfo.has_value())
|
||||
checkGpuInfo();
|
||||
|
||||
return cachedInfo.value();
|
||||
}
|
||||
|
||||
GpuInformation IdentifyGpu::getPrimaryGpu()
|
||||
{
|
||||
auto allGpus = getAllGpus();
|
||||
return allGpus.size() > 0 ? allGpus[0] : GpuInformation {};
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <nvapi.h>
|
||||
|
||||
// vkd3d-proton
|
||||
MIDL_INTERFACE("39da4e09-bd1c-4198-9fae-86bbe3be41fd")
|
||||
ID3D12DXVKInteropDevice : public IUnknown
|
||||
{
|
||||
@@ -29,14 +30,24 @@ ID3D12DXVKInteropDevice : public IUnknown
|
||||
virtual HRESULT STDMETHODCALLTYPE UnlockCommandQueue(ID3D12CommandQueue * pCommandQueue) = 0;
|
||||
};
|
||||
|
||||
// dxvk
|
||||
MIDL_INTERFACE("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")
|
||||
IDXGIVkInteropDevice : public IUnknown
|
||||
{
|
||||
virtual void STDMETHODCALLTYPE GetVulkanHandles(VkInstance * pInstance, VkPhysicalDevice * pPhysDev,
|
||||
VkDevice * pDevice) = 0;
|
||||
};
|
||||
|
||||
struct GpuInformation
|
||||
{
|
||||
LUID luid {}; // Unique id to be able to reference the exact GPU, VkPhysicalDeviceIDProperties
|
||||
std::string name {};
|
||||
VendorId::Value vendorId = VendorId::Invalid;
|
||||
size_t dedicatedVramInBytes = 0;
|
||||
bool usesDxvk = false;
|
||||
bool usesVkd3dProton = false;
|
||||
|
||||
bool fsr4capable = false;
|
||||
bool fsr4Capable = false;
|
||||
ID3D12Device* d3d12device = nullptr;
|
||||
|
||||
bool dlssCapable = false;
|
||||
@@ -47,11 +58,15 @@ struct GpuInformation
|
||||
// vulkan caps
|
||||
// - Check Nvidia Arch, watch out for fakenvapi
|
||||
// - Check vram amount
|
||||
// - Check if dxgi uses dxvk, some dxvk specific call?
|
||||
//
|
||||
// - Check hags support? watch out for linux
|
||||
// - Check if dxgi uses dxvk, some dxvk specific call?
|
||||
// - Check if vkd3d-proton is being used? Could be helpful to display in menu
|
||||
// - Check vulkan driver? radv vs amdvlk etc
|
||||
// - Opti in many spots assumes a single GPU and that all handles are coming from that gpu,
|
||||
// might need to always check if LUID of the held device matches the one provided by this class
|
||||
// before trying to use any info from here. Could also create a method to query GpuInformation based on LUID
|
||||
// - Look at removing state.DeviceAdapterNames
|
||||
|
||||
class IdentifyGpu
|
||||
{
|
||||
@@ -61,5 +76,6 @@ class IdentifyGpu
|
||||
|
||||
public:
|
||||
// Sorted by priority, the first one should be treated as the primary one
|
||||
static std::vector<GpuInformation> getGpuInfo();
|
||||
static std::vector<GpuInformation> getAllGpus();
|
||||
static GpuInformation getPrimaryGpu();
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ class DxgiProxy
|
||||
typedef HRESULT (*PFN_DeclareAdepterRemovalSupport)();
|
||||
typedef HRESULT (*PFN_GetDebugInterface)(UINT Flags, REFIID riid, void** ppDebug);
|
||||
|
||||
static void Init(HMODULE module = nullptr)
|
||||
static void Init(HMODULE module = nullptr, bool passThruMode = false)
|
||||
{
|
||||
if (_dll != nullptr)
|
||||
return;
|
||||
@@ -29,6 +29,47 @@ class DxgiProxy
|
||||
{
|
||||
_dll = GetModuleHandle(L"dxgi.dll");
|
||||
|
||||
if (_dll == dllModule)
|
||||
{
|
||||
wchar_t sysFolder[MAX_PATH];
|
||||
GetSystemDirectory(sysFolder, MAX_PATH);
|
||||
std::filesystem::path sysPath(sysFolder);
|
||||
std::filesystem::path pluginPath(Config::Instance()->PluginPath.value_or_default());
|
||||
|
||||
do
|
||||
{
|
||||
auto pluginFilePath = pluginPath / L"dxgi.dll";
|
||||
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
|
||||
|
||||
if (originalModule != nullptr)
|
||||
{
|
||||
if (!passThruMode)
|
||||
LOG_INFO("OptiScaler working as dxgi.dll, original dll loaded from plugin folder");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"dxgi-original.dll", NULL, 0);
|
||||
|
||||
if (originalModule != nullptr)
|
||||
{
|
||||
if (!passThruMode)
|
||||
LOG_INFO("OptiScaler working as dxgi.dll, dxgi-original.dll loaded");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
auto sysFilePath = sysPath / L"dxgi.dll";
|
||||
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
|
||||
|
||||
if (originalModule != nullptr && !passThruMode)
|
||||
LOG_INFO("OptiScaler working as dxgi.dll, system dll loaded");
|
||||
|
||||
_dll = originalModule;
|
||||
|
||||
} while (false);
|
||||
}
|
||||
|
||||
if (_dll == nullptr)
|
||||
_dll = NtdllProxy::LoadLibraryExW_Ldr(L"dxgi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <d3d12.h>
|
||||
#include <misc/IdentifyGpu.h>
|
||||
|
||||
#pragma intrinsic(_ReturnAddress)
|
||||
|
||||
@@ -214,7 +215,7 @@ static HRESULT LocalPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT
|
||||
}
|
||||
|
||||
// DXVK check, it's here because of upscaler time calculations
|
||||
if (State::Instance().isRunningOnDXVK)
|
||||
if (IdentifyGpu::getPrimaryGpu().usesDxvk)
|
||||
{
|
||||
if (pPresentParameters == nullptr)
|
||||
presentResult = pSwapChain->Present(SyncInterval, Flags);
|
||||
|
||||
Reference in New Issue
Block a user