2025-01-09 03:09:45 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "d3d8_include.h"
|
|
|
|
#include "../d3d9/d3d9_bridge.h"
|
|
|
|
#include "../util/config/config.h"
|
|
|
|
|
|
|
|
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
|
|
|
|
std::vector<std::pair<D3DVSDE_REGISTER, D3DVSDT_TYPE>> 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;
|
|
|
|
|
|
|
|
/// 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;
|
|
|
|
|
|
|
|
/// 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;
|
|
|
|
|
|
|
|
D3D8Options() {}
|
|
|
|
D3D8Options(const Config& config) {
|
|
|
|
auto forceVsDeclStr = config.getOption<std::string>("d3d8.forceVsDecl", "");
|
|
|
|
batching = config.getOption<bool> ("d3d8.batching", batching);
|
|
|
|
placeP8InScratch = config.getOption<bool> ("d3d8.placeP8InScratch", placeP8InScratch);
|
|
|
|
forceLegacyDiscard = config.getOption<bool> ("d3d8.forceLegacyDiscard", forceLegacyDiscard);
|
|
|
|
|
|
|
|
parseVsDecl(forceVsDeclStr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void parseVsDecl(const std::string& decl);
|
|
|
|
};
|
|
|
|
}
|