From 4a83a16aae241cad1a2734e6b804c0492dd4281b Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Wed, 5 Mar 2025 12:25:52 +0200 Subject: [PATCH] [d3d8] Move D3D8 options description into dxvk.conf --- dxvk.conf | 80 +++++++++++++++++++++++++++++++++++++++++ src/d3d8/d3d8_options.h | 50 +++++++------------------- 2 files changed, 93 insertions(+), 37 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 603e3132b..2bf0d23eb 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -764,3 +764,83 @@ # - True/False # d3d9.countLosableResources = True + +# Dref scaling for DXS0/FVF +# +# Some early D3D8 games expect Dref (depth texcoord Z) to be on the range of +# [0..2^bitDepth - 1]. This option allows DXSO and fixed vertex function to +# scale it back down to [0..1]. +# +# Supported values: Any number representing bitDepth (typically 24). + +# d3d8.drefScaling = 0 + +# Shadow perspective divide +# +# Older applications designed for Nvidia hardware (or ported from XBox) +# expect shadow map texture coordinates to be perspective divided, even +# though D3DTTFF_PROJECTED is never set for any texture coordinates. +# Older Nvidia cards (GeForce 3, GeForce 4 series) performed this +# projection directly in hardware. +# +# This option forces the D3DTTFF_PROJECTED flag for the necessary stages +# when a depth texture is bound to slot 0, in order to emulate older +# Nvidia hardware behavior. +# +# Supported values: +# - True/False + +# d3d8.shadowPerspectiveDivide = False + +# Force vertex shader declaration +# +# Some games rely on undefined behavior by using undeclared vertex shader inputs. +# The simplest way to fix them is to modify their vertex shader decl. +# +# This option takes a comma-separated list of colon-separated number pairs, where +# the first number is a D3DVSDE_REGISTER value, the second is a D3DVSDT_TYPE value. +# +# Supported values: +# - e.g. "0:2,3:2,7:1" for float3 position : v0, float3 normal : v3, float2 uv : v7. + +# d3d8.forceVsDecl = "" + +# Draw call batching +# +# Specialized drawcall batcher, typically for games that draw a lot of similar +# geometry in separate drawcalls (sometimes even one triangle at a time). +# +# May hurt performance or introduce graphical artifacts outside of +# specific games that are known to benefit from it. +# +# Supported values: +# - True/False + +# d3d8.batching = False + +# P8 texture support workaround +# +# 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. ATI/AMD drivers and hardware were most likely in a similar situation. +# +# This option will ensure all P8 textures are placed in D3DPOOL_SCRATCH, so that +# their creation is guaranteed to succeed even if the format is unsupported. +# Can help older titles that don't properly handle the lack of P8 support. +# +# Supported values: +# - True/False + +# d3d8.placeP8InScratch = False + +# Legacy discard buffer behavior +# +# Older applications may rely on D3DLOCK_DISCARD being ignored for everything +# except D3DUSAGE_DYNAMIC + D3DUSAGE_WRITEONLY buffers, however this approach +# incurs a performance penalty. +# +# Supported values: +# - True/False + +# d3d8.forceLegacyDiscard = False + diff --git a/src/d3d8/d3d8_options.h b/src/d3d8/d3d8_options.h index 17604d41a..09f448cc8 100644 --- a/src/d3d8/d3d8_options.h +++ b/src/d3d8/d3d8_options.h @@ -8,53 +8,29 @@ namespace dxvk { struct D3D8Options { - /// Some games rely on undefined behavior by using undeclared vertex shader inputs. - /// The simplest way to fix them is to simply modify their vertex shader decl. - /// - /// This option takes a comma-separated list of colon-separated number pairs, where - /// the first number is a D3DVSDE_REGISTER value, the second is a D3DVSDT_TYPE value. - /// e.g. "0:2,3:2,7:1" for float3 position : v0, float3 normal : v3, float2 uv : v7 + /// Override application vertex shader declarations. std::vector> forceVsDecl; - /// Specialized drawcall batcher, typically for games that draw a lot of similar - /// geometry in separate drawcalls (sometimes even one triangle at a time). - /// - /// May hurt performance outside of specifc games that benefit from it. - bool batching = false; + /// Enable/disable the drawcall batcher. + bool batching; - /// 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; + /// Place all P8 textures in D3DPOOL_SCRATCH. + bool placeP8InScratch; - /// Rayman 3 relies on D3DLOCK_DISCARD being ignored for everything except D3DUSAGE_DYNAMIC + - /// D3DUSAGE_WRITEONLY buffers, however this approach incurs a performance penalty. - /// - /// Some titles might abuse this early D3D8 quirk, however at some point in its history - /// it was brought in line with standard D3D9 behavior. - bool forceLegacyDiscard = false; + /// Ignore D3DLOCK_DISCARD for everything except D3DUSAGE_DYNAMIC + D3DUSAGE_WRITEONLY buffers. + bool forceLegacyDiscard; - /// 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; + /// Force D3DTTFF_PROJECTED for the necessary stages when a depth texture is bound to slot 0. + bool shadowPerspectiveDivide; D3D8Options() {} D3D8Options(const Config& config) { auto forceVsDeclStr = config.getOption("d3d8.forceVsDecl", ""); - batching = config.getOption ("d3d8.batching", batching); - placeP8InScratch = config.getOption ("d3d8.placeP8InScratch", placeP8InScratch); - forceLegacyDiscard = config.getOption ("d3d8.forceLegacyDiscard", forceLegacyDiscard); - shadowPerspectiveDivide = config.getOption ("d3d8.shadowPerspectiveDivide", shadowPerspectiveDivide); + batching = config.getOption ("d3d8.batching", false); + placeP8InScratch = config.getOption ("d3d8.placeP8InScratch", false); + forceLegacyDiscard = config.getOption ("d3d8.forceLegacyDiscard", false); + shadowPerspectiveDivide = config.getOption ("d3d8.shadowPerspectiveDivide", false); parseVsDecl(forceVsDeclStr); }