1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-24 04:54:14 +01:00

[d3d8] Add shadow perspective divide hack for Splinter Cell

This commit is contained in:
Jeff 2025-01-31 19:01:02 +00:00 committed by Philip Rebohle
parent f2802dd2ff
commit 0aebedae16
4 changed files with 43 additions and 4 deletions

View File

@ -1368,6 +1368,27 @@ namespace dxvk {
D3D8Texture2D* tex = static_cast<D3D8Texture2D*>(pTexture); D3D8Texture2D* tex = static_cast<D3D8Texture2D*>(pTexture);
// Splinter Cell: Force perspective divide when a shadow map is bound to slot 0
if (unlikely(m_d3d8Options.shadowPerspectiveDivide && Stage == 0)) {
if (tex) {
D3DSURFACE_DESC surf;
tex->GetLevelDesc(0, &surf);
if (isDepthStencilFormat(surf.Format)) {
// If we bound a depth texture to stage 0 then we need to set the projected flag for stage 0 and 1
// Stage 1 is a non-depth light cookie texture but still requires perspective divide to work
GetD3D9()->SetTextureStageState(0, d3d9::D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_PROJECTED);
GetD3D9()->SetTextureStageState(1, d3d9::D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_PROJECTED);
m_shadowPerspectiveDivide = true;
} else if (m_shadowPerspectiveDivide) {
// Non-depth texture bound. Game will reset the transform flags to 0 on its own
m_shadowPerspectiveDivide = false;
}
} else if (m_shadowPerspectiveDivide) {
// Texture unbound. Game will reset the transform flags to 0 on its own
m_shadowPerspectiveDivide = false;
}
}
if (unlikely(m_textures[Stage] == tex)) if (unlikely(m_textures[Stage] == tex))
return D3D_OK; return D3D_OK;
@ -1401,6 +1422,13 @@ namespace dxvk {
DWORD Value) { DWORD Value) {
d3d9::D3DSAMPLERSTATETYPE stateType = GetSamplerStateType9(Type); d3d9::D3DSAMPLERSTATETYPE stateType = GetSamplerStateType9(Type);
if (unlikely(m_d3d8Options.shadowPerspectiveDivide && Type == D3DTSS_TEXTURETRANSFORMFLAGS)) {
// Splinter Cell: Ignore requests to change texture transform flags
// to 0 while shadow mapping perspective divide mode is enabled
if (m_shadowPerspectiveDivide && (Stage == 0 || Stage == 1))
return D3D_OK;
}
StateChange(); StateChange();
if (stateType != -1u) { if (stateType != -1u) {
// if the type has been remapped to a sampler state type: // if the type has been remapped to a sampler state type:

View File

@ -393,6 +393,8 @@ namespace dxvk {
m_backBuffers.resize(m_presentParams.BackBufferCount); m_backBuffers.resize(m_presentParams.BackBufferCount);
m_autoDepthStencil = nullptr; m_autoDepthStencil = nullptr;
m_shadowPerspectiveDivide = false;
} }
inline void RecreateBackBuffersAndAutoDepthStencil() { inline void RecreateBackBuffersAndAutoDepthStencil() {
@ -434,6 +436,8 @@ namespace dxvk {
// Controls fixed-function exclusive mode (no PS support) // Controls fixed-function exclusive mode (no PS support)
bool m_isFixedFunctionOnly = false; bool m_isFixedFunctionOnly = false;
bool m_shadowPerspectiveDivide = false;
D3D8StateBlock* m_recorder = nullptr; D3D8StateBlock* m_recorder = nullptr;
DWORD m_recorderToken = 0; DWORD m_recorderToken = 0;
DWORD m_token = 0; DWORD m_token = 0;

View File

@ -42,6 +42,11 @@ namespace dxvk {
/// it was brought in line with standard D3D9 behavior. /// it was brought in line with standard D3D9 behavior.
bool forceLegacyDiscard = false; bool forceLegacyDiscard = false;
/// Splinter Cell expects shadow map texture coordinates to be perspective divided
/// even though D3DTTFF_PROJECTED is never set for any texture coordinates. This flag
/// forces that flag for the necessary stages when a depth texture is bound to slot 0
bool shadowPerspectiveDivide = false;
D3D8Options() {} D3D8Options() {}
D3D8Options(const Config& config) { D3D8Options(const Config& config) {
@ -49,6 +54,7 @@ namespace dxvk {
batching = config.getOption<bool> ("d3d8.batching", batching); batching = config.getOption<bool> ("d3d8.batching", batching);
placeP8InScratch = config.getOption<bool> ("d3d8.placeP8InScratch", placeP8InScratch); placeP8InScratch = config.getOption<bool> ("d3d8.placeP8InScratch", placeP8InScratch);
forceLegacyDiscard = config.getOption<bool> ("d3d8.forceLegacyDiscard", forceLegacyDiscard); forceLegacyDiscard = config.getOption<bool> ("d3d8.forceLegacyDiscard", forceLegacyDiscard);
shadowPerspectiveDivide = config.getOption<bool> ("d3d8.shadowPerspectiveDivide", shadowPerspectiveDivide);
parseVsDecl(forceVsDeclStr); parseVsDecl(forceVsDeclStr);
} }

View File

@ -1199,6 +1199,7 @@ namespace dxvk {
* Fixes shadow buffers and alt-tab */ * Fixes shadow buffers and alt-tab */
{ R"(\\splintercell\.exe$)", {{ { R"(\\splintercell\.exe$)", {{
{ "d3d8.scaleDref", "24" }, { "d3d8.scaleDref", "24" },
{ "d3d8.shadowPerspectiveDivide", "True" },
{ "d3d9.deviceLossOnFocusLoss", "True" }, { "d3d9.deviceLossOnFocusLoss", "True" },
}} }, }} },
/* Trainz v1.3 (2001) * /* Trainz v1.3 (2001) *