From cb2a2b587943f58766b392171aee0fe1edb13b74 Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Mon, 6 May 2024 19:31:48 +0300 Subject: [PATCH] [d3d8] Add a workaround for LotR: Fellowship of the Ring --- src/d3d8/d3d8_device.cpp | 4 ++++ src/d3d8/d3d8_options.h | 16 +++++++++++++++- src/util/config/config.cpp | 6 ++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/d3d8/d3d8_device.cpp b/src/d3d8/d3d8_device.cpp index e11634c9e8a..6ead84792d9 100644 --- a/src/d3d8/d3d8_device.cpp +++ b/src/d3d8/d3d8_device.cpp @@ -300,6 +300,10 @@ namespace dxvk { IDirect3DTexture8** ppTexture) { InitReturnPtr(ppTexture); + // Nvidia & Intel workaround for The Lord of the Rings: The Fellowship of the Ring + if (m_d3d8Options.placeP8InScratch && Format == D3DFMT_P8) + Pool = D3DPOOL_SCRATCH; + Com pTex9 = nullptr; HRESULT res = GetD3D9()->CreateTexture( Width, diff --git a/src/d3d8/d3d8_options.h b/src/d3d8/d3d8_options.h index 8193e2ae54e..67bdf35927c 100644 --- a/src/d3d8/d3d8_options.h +++ b/src/d3d8/d3d8_options.h @@ -21,10 +21,24 @@ namespace dxvk { /// May hurt performance outside of specifc games that benefit from it. bool batching = false; + /// The Lord of the Rings: The Fellowship of the Ring tries to create a P8 texture + /// in D3DPOOL_MANAGED on Nvidia and Intel, which fails, but has a separate code + /// path for ATI/AMD that creates it in D3DPOOL_SCRATCH instead, which works. + /// + /// The internal logic determining this path doesn't seem to be d3d-related, but + /// the game works universally if we mimic its own ATI/AMD workaround during P8 + /// texture creation. + /// + /// Early Nvidia GPUs, such as the GeForce 4 generation cards, included and exposed + /// P8 texture support. However, it was no longer advertised with cards in the FX series + /// and above. Most likely ATI/AMD drivers never supported P8 in the first place. + bool placeP8InScratch = false; + D3D8Options() {} D3D8Options(const Config& config) { - auto forceVsDeclStr = config.getOption("d3d8.forceVsDecl", ""); + auto forceVsDeclStr = config.getOption("d3d8.forceVsDecl", ""); batching = config.getOption ("d3d8.batching", batching); + placeP8InScratch = config.getOption ("d3d8.placeP8InScratch", placeP8InScratch); parseVsDecl(forceVsDeclStr); } diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index b88f495f7c7..34d88b68297 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -1109,6 +1109,12 @@ namespace dxvk { { R"(\\X2\.exe$)", {{ { "d3d9.cachedDynamicBuffers", "True" }, }} }, + /* The Lord of the Rings: * + * The Fellowship of the Ring */ + { R"(\\Fellowship\.exe$)", {{ + { "d3d9.maxFrameRate", "60" }, + { "d3d8.placeP8InScratch", "True" }, + }} }, }};