[d3d9] Add strict option to float emulation setting

This commit is contained in:
Robin Kertels 2021-09-02 22:46:35 +02:00 committed by Joshie
parent eb9dfcedbd
commit 6c17b8801c
6 changed files with 30 additions and 15 deletions

View File

@ -334,13 +334,16 @@
# Force enable/disable floating point quirk emulation # Force enable/disable floating point quirk emulation
# #
# Force toggle anything * 0 emulation # Force toggle anything * 0 emulation
# Tristate # Setting it to True will use a faster but less accurate approach that works for most games.
# Supported values: # Supported values:
# - True/False # - True: Use a faster but less accurate approach. Good enough for most games
# - False: Disable float emulation completely
# - Strict: Use a slower but more correct approach. Necessary for some games
# - Auto: DXVK will pick automatically
# d3d9.floatEmulation = # d3d9.floatEmulation = True
# Enable dialog box mode # Enable dialog box mode

View File

@ -6479,7 +6479,7 @@ namespace dxvk {
StartRegister, StartRegister,
pConstantData, pConstantData,
Count, Count,
m_d3d9Options.d3d9FloatEmulation); m_d3d9Options.d3d9FloatEmulation == D3D9FloatEmulation::Enabled);
return D3D_OK; return D3D_OK;
} }

View File

@ -81,8 +81,14 @@ namespace dxvk {
0, 0); 0, 0);
applyTristate(this->generalHazards, config.getOption<Tristate>("d3d9.generalHazards", Tristate::Auto)); applyTristate(this->generalHazards, config.getOption<Tristate>("d3d9.generalHazards", Tristate::Auto));
this->d3d9FloatEmulation = true; // <-- Future Extension? std::string floatEmulation = Config::toLower(config.getOption<std::string>("d3d9.floatEmulation", "true"));
applyTristate(this->d3d9FloatEmulation, config.getOption<Tristate>("d3d9.floatEmulation", Tristate::Auto)); if (floatEmulation == "strict") {
d3d9FloatEmulation = D3D9FloatEmulation::Strict;
} else if (floatEmulation == "false") {
d3d9FloatEmulation = D3D9FloatEmulation::Disabled;
} else {
d3d9FloatEmulation = D3D9FloatEmulation::Enabled;
}
} }
} }

View File

@ -7,6 +7,12 @@
namespace dxvk { namespace dxvk {
enum class D3D9FloatEmulation {
Disabled,
Enabled,
Strict
};
struct D3D9Options { struct D3D9Options {
D3D9Options(const Rc<DxvkDevice>& device, const Config& config); D3D9Options(const Rc<DxvkDevice>& device, const Config& config);
@ -83,7 +89,7 @@ namespace dxvk {
uint32_t maxAvailableMemory; uint32_t maxAvailableMemory;
/// D3D9 Floating Point Emulation (anything * 0 = 0) /// D3D9 Floating Point Emulation (anything * 0 = 0)
bool d3d9FloatEmulation; D3D9FloatEmulation d3d9FloatEmulation;
/// Support the DF16 & DF24 texture format /// Support the DF16 & DF24 texture format
bool supportDFFormats; bool supportDFFormats;

View File

@ -1439,7 +1439,7 @@ namespace dxvk {
DxsoRegisterValue DxsoCompiler::emitMulOperand( DxsoRegisterValue DxsoCompiler::emitMulOperand(
DxsoRegisterValue operand, DxsoRegisterValue operand,
DxsoRegisterValue other) { DxsoRegisterValue other) {
if (!m_moduleInfo.options.d3d9FloatEmulation) if (m_moduleInfo.options.d3d9FloatEmulation != D3D9FloatEmulation::Strict)
return operand; return operand;
uint32_t boolId = getVectorTypeId({ DxsoScalarType::Bool, other.type.ccount }); uint32_t boolId = getVectorTypeId({ DxsoScalarType::Bool, other.type.ccount });
@ -1966,7 +1966,7 @@ namespace dxvk {
m_module.constfReplicant(1.0f, result.type.ccount), m_module.constfReplicant(1.0f, result.type.ccount),
emitRegisterLoad(src[0], mask).id); emitRegisterLoad(src[0], mask).id);
if (m_moduleInfo.options.d3d9FloatEmulation) { if (m_moduleInfo.options.d3d9FloatEmulation == D3D9FloatEmulation::Enabled) {
result.id = m_module.opNMin(typeId, result.id, result.id = m_module.opNMin(typeId, result.id,
m_module.constfReplicant(FLT_MAX, result.type.ccount)); m_module.constfReplicant(FLT_MAX, result.type.ccount));
} }
@ -1978,7 +1978,7 @@ namespace dxvk {
result.id = m_module.opInverseSqrt(typeId, result.id = m_module.opInverseSqrt(typeId,
result.id); result.id);
if (m_moduleInfo.options.d3d9FloatEmulation) { if (m_moduleInfo.options.d3d9FloatEmulation == D3D9FloatEmulation::Enabled) {
result.id = m_module.opNMin(typeId, result.id, result.id = m_module.opNMin(typeId, result.id,
m_module.constfReplicant(FLT_MAX, result.type.ccount)); m_module.constfReplicant(FLT_MAX, result.type.ccount));
} }
@ -2052,7 +2052,7 @@ namespace dxvk {
result.id = m_module.opPow(typeId, base, exponent); result.id = m_module.opPow(typeId, base, exponent);
if (m_moduleInfo.options.strictPow && m_moduleInfo.options.d3d9FloatEmulation) { if (m_moduleInfo.options.strictPow && m_moduleInfo.options.d3d9FloatEmulation != D3D9FloatEmulation::Disabled) {
DxsoRegisterValue cmp; DxsoRegisterValue cmp;
cmp.type = { DxsoScalarType::Bool, result.type.ccount }; cmp.type = { DxsoScalarType::Bool, result.type.ccount };
cmp.id = m_module.opFOrdEqual(getVectorTypeId(cmp.type), cmp.id = m_module.opFOrdEqual(getVectorTypeId(cmp.type),
@ -2097,7 +2097,7 @@ namespace dxvk {
DxsoRegisterValue dot = emitDot(vec3, vec3); DxsoRegisterValue dot = emitDot(vec3, vec3);
dot.id = m_module.opInverseSqrt (scalarTypeId, dot.id); dot.id = m_module.opInverseSqrt (scalarTypeId, dot.id);
if (m_moduleInfo.options.d3d9FloatEmulation) { if (m_moduleInfo.options.d3d9FloatEmulation == D3D9FloatEmulation::Enabled) {
dot.id = m_module.opNMin (scalarTypeId, dot.id, dot.id = m_module.opNMin (scalarTypeId, dot.id,
m_module.constf32(FLT_MAX)); m_module.constf32(FLT_MAX));
} }
@ -2214,7 +2214,7 @@ namespace dxvk {
case DxsoOpcode::Log: case DxsoOpcode::Log:
result.id = m_module.opFAbs(typeId, emitRegisterLoad(src[0], mask).id); result.id = m_module.opFAbs(typeId, emitRegisterLoad(src[0], mask).id);
result.id = m_module.opLog2(typeId, result.id); result.id = m_module.opLog2(typeId, result.id);
if (m_moduleInfo.options.d3d9FloatEmulation) { if (m_moduleInfo.options.d3d9FloatEmulation == D3D9FloatEmulation::Enabled) {
result.id = m_module.opNMax(typeId, result.id, result.id = m_module.opNMax(typeId, result.id,
m_module.constfReplicant(-FLT_MAX, result.type.ccount)); m_module.constfReplicant(-FLT_MAX, result.type.ccount));
} }

View File

@ -27,7 +27,7 @@ namespace dxvk {
/// Whether to emulate d3d9 float behaviour using clampps /// Whether to emulate d3d9 float behaviour using clampps
/// True: Perform emulation to emulate behaviour (ie. anything * 0 = 0) /// True: Perform emulation to emulate behaviour (ie. anything * 0 = 0)
/// False: Don't do anything. /// False: Don't do anything.
bool d3d9FloatEmulation; D3D9FloatEmulation d3d9FloatEmulation;
/// Whether or not we should care about pow(0, 0) = 1 /// Whether or not we should care about pow(0, 0) = 1
bool strictPow; bool strictPow;