diff --git a/src/d3d9/d3d9_config.h b/src/d3d9/d3d9_config.h new file mode 100644 index 00000000..7c9c9cb4 --- /dev/null +++ b/src/d3d9/d3d9_config.h @@ -0,0 +1,12 @@ +#pragma once + +namespace dxvk::config { + + constexpr bool FloatEmulationByDefault = false; + constexpr bool FixedFunctionEnabled = true; + constexpr bool HazardTrackingEnabled = false; + constexpr bool ManagedUploadTrackingEnabled = true; + constexpr bool MipGenTrackingEnabled = false; + constexpr bool SWVPEnabled = false; + +} \ No newline at end of file diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 241d18b9..bb4a92c7 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4877,6 +4877,9 @@ namespace dxvk { inline void D3D9DeviceEx::UpdateActiveRTs(uint32_t index) { + if (!config::HazardTrackingEnabled) + return; + const uint32_t bit = 1 << index; m_activeRTs &= ~bit; @@ -4891,40 +4894,52 @@ namespace dxvk { inline void D3D9DeviceEx::UpdateActiveTextures(uint32_t index, DWORD combinedUsage) { + if (!config::ManagedUploadTrackingEnabled && !config::HazardTrackingEnabled && !config::MipGenTrackingEnabled) + return; + const uint32_t bit = 1 << index; - m_activeRTTextures &= ~bit; - m_activeDSTextures &= ~bit; + if (config::HazardTrackingEnabled) { + m_activeRTTextures &= ~bit; + m_activeDSTextures &= ~bit; + } m_activeTextures &= ~bit; - m_activeTexturesToUpload &= ~bit; - m_activeTexturesToGen &= ~bit; + if (config::ManagedUploadTrackingEnabled) + m_activeTexturesToUpload &= ~bit; + if (config::MipGenTrackingEnabled) + m_activeTexturesToGen &= ~bit; auto tex = GetCommonTexture(m_state.textures[index]); if (tex != nullptr) { m_activeTextures |= bit; - if (unlikely(tex->IsRenderTarget())) + if (unlikely(config::HazardTrackingEnabled && tex->IsRenderTarget())) m_activeRTTextures |= bit; - if (unlikely(tex->IsDepthStencil())) + if (unlikely(config::HazardTrackingEnabled && tex->IsDepthStencil())) m_activeDSTextures |= bit; - if (unlikely(tex->NeedsAnyUpload())) + if (unlikely(config::ManagedUploadTrackingEnabled && tex->NeedsAnyUpload())) m_activeTexturesToUpload |= bit; - if (unlikely(tex->NeedsMipGen())) + if (unlikely(config::MipGenTrackingEnabled && tex->NeedsMipGen())) m_activeTexturesToGen |= bit; } - if (unlikely(combinedUsage & D3DUSAGE_RENDERTARGET)) - UpdateActiveHazardsRT(UINT32_MAX); + if (config::HazardTrackingEnabled) { + if (unlikely(combinedUsage & D3DUSAGE_RENDERTARGET)) + UpdateActiveHazardsRT(UINT32_MAX); - if (unlikely(combinedUsage & D3DUSAGE_DEPTHSTENCIL)) - UpdateActiveHazardsDS(bit); + if (unlikely(combinedUsage & D3DUSAGE_DEPTHSTENCIL)) + UpdateActiveHazardsDS(bit); + } } inline void D3D9DeviceEx::UpdateActiveHazardsRT(uint32_t rtMask) { + if (!config::HazardTrackingEnabled) + return; + auto masks = m_psShaderMasks; masks.rtMask &= m_activeRTs & rtMask; masks.samplerMask &= m_activeRTTextures; @@ -4953,6 +4968,9 @@ namespace dxvk { inline void D3D9DeviceEx::UpdateActiveHazardsDS(uint32_t texMask) { + if (!config::HazardTrackingEnabled) + return; + m_activeHazardsDS = m_activeHazardsDS & (~texMask); if (m_state.depthStencil != nullptr && m_state.depthStencil->GetBaseTexture() != nullptr) { @@ -4973,6 +4991,9 @@ namespace dxvk { void D3D9DeviceEx::MarkRenderHazards() { + if (!config::HazardTrackingEnabled) + return; + for (uint32_t rt = m_activeHazardsRT; rt; rt &= rt - 1) { // Guaranteed to not be nullptr... auto tex = m_state.renderTargets[bit::tzcnt(rt)]->GetCommonTexture(); @@ -4997,6 +5018,9 @@ namespace dxvk { void D3D9DeviceEx::UploadManagedTextures(uint32_t mask) { + if (!config::ManagedUploadTrackingEnabled) + return; + // Guaranteed to not be nullptr... for (uint32_t tex = mask; tex; tex &= tex - 1) UploadManagedTexture(GetCommonTexture(m_state.textures[bit::tzcnt(tex)])); @@ -5021,6 +5045,9 @@ namespace dxvk { void D3D9DeviceEx::MarkTextureMipsDirty(D3D9CommonTexture* pResource) { + if (!config::MipGenTrackingEnabled) + return; + pResource->SetNeedsMipGen(true); pResource->MarkAllDirty(); @@ -5039,6 +5066,9 @@ namespace dxvk { void D3D9DeviceEx::MarkTextureMipsUnDirty(D3D9CommonTexture* pResource) { + if (!config::MipGenTrackingEnabled) + return; + pResource->SetNeedsMipGen(false); for (uint32_t tex = m_activeTextures; tex; tex &= tex - 1) { @@ -5053,6 +5083,8 @@ namespace dxvk { void D3D9DeviceEx::MarkTextureUploaded(D3D9CommonTexture* pResource) { + if (!config::ManagedUploadTrackingEnabled) + return; for (uint32_t tex = m_activeTextures; tex; tex &= tex - 1) { // Guaranteed to not be nullptr... const uint32_t i = bit::tzcnt(tex); @@ -5712,18 +5744,20 @@ namespace dxvk { void D3D9DeviceEx::PrepareDraw(D3DPRIMITIVETYPE PrimitiveType) { - if (unlikely(m_activeHazardsRT != 0)) { - EmitCs([](DxvkContext* ctx) { - ctx->emitRenderTargetReadbackBarrier(); - }); + if (config::HazardTrackingEnabled) { + if (unlikely(m_activeHazardsRT != 0)) { + EmitCs([](DxvkContext* ctx) { + ctx->emitRenderTargetReadbackBarrier(); + }); - if (m_d3d9Options.generalHazards) - MarkRenderHazards(); - } + if (m_d3d9Options.generalHazards) + MarkRenderHazards(); + } - if (unlikely((m_lastHazardsDS == 0) != (m_activeHazardsDS == 0))) { - m_flags.set(D3D9DeviceFlag::DirtyFramebuffer); - m_lastHazardsDS = m_activeHazardsDS; + if (unlikely((m_lastHazardsDS == 0) != (m_activeHazardsDS == 0))) { + m_flags.set(D3D9DeviceFlag::DirtyFramebuffer); + m_lastHazardsDS = m_activeHazardsDS; + } } for (uint32_t i = 0; i < caps::MaxStreams; i++) { @@ -5732,17 +5766,21 @@ namespace dxvk { FlushBuffer(vbo); } - uint32_t texturesToUpload = m_activeTexturesToUpload; - texturesToUpload &= m_psShaderMasks.samplerMask | m_vsShaderMasks.samplerMask; + if (config::ManagedUploadTrackingEnabled) { + uint32_t texturesToUpload = m_activeTexturesToUpload; + texturesToUpload &= m_psShaderMasks.samplerMask | m_vsShaderMasks.samplerMask; - if (unlikely(texturesToUpload != 0)) - UploadManagedTextures(texturesToUpload); + if (unlikely(texturesToUpload != 0)) + UploadManagedTextures(texturesToUpload); + } - uint32_t texturesToGen = m_activeTexturesToGen; - texturesToGen &= m_psShaderMasks.samplerMask | m_vsShaderMasks.samplerMask; + if (config::MipGenTrackingEnabled) { + uint32_t texturesToGen = m_activeTexturesToGen; + texturesToGen &= m_psShaderMasks.samplerMask | m_vsShaderMasks.samplerMask; - if (unlikely(texturesToGen != 0)) - GenerateTextureMips(texturesToGen); + if (unlikely(texturesToGen != 0)) + GenerateTextureMips(texturesToGen); + } auto* ibo = GetCommonBuffer(m_state.indices); if (ibo != nullptr && ibo->NeedsUpload()) @@ -5845,7 +5883,7 @@ namespace dxvk { UpdateFixedFunctionPS(); } - if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData)) { + if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData) && config::FixedFunctionEnabled) { m_flags.clr(D3D9DeviceFlag::DirtySharedPixelShaderData); DxvkBufferSliceHandle slice = m_psShared->allocSlice(); @@ -6480,6 +6518,9 @@ namespace dxvk { bool D3D9DeviceEx::UseProgrammableVS() { + if (!config::FixedFunctionEnabled) + return true; + return m_state.vertexShader != nullptr && m_state.vertexDecl != nullptr && !m_state.vertexDecl->TestFlag(D3D9VertexDeclFlag::HasPositionT); @@ -6487,6 +6528,9 @@ namespace dxvk { bool D3D9DeviceEx::UseProgrammablePS() { + if (!config::FixedFunctionEnabled) + return true; + return m_state.pixelShader != nullptr; } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index ccc7e494..24f7d6c7 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -22,6 +22,7 @@ #include "d3d9_sampler.h" #include "d3d9_fixed_function.h" #include "d3d9_swvp_emu.h" +#include "d3d9_config.h" #include "d3d9_shader_permutations.h" @@ -965,6 +966,9 @@ namespace dxvk { } bool CanSWVP() { + if (!config::SWVPEnabled) + return false; + return m_behaviorFlags & (D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING); } diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index ef5e56a2..1c1e61cb 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -1,6 +1,7 @@ #include "d3d9_options.h" #include "d3d9_caps.h" +#include "d3d9_config.h" namespace dxvk { @@ -79,7 +80,7 @@ namespace dxvk { this->generalHazards = adapter == nullptr || !adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0); applyTristate(this->generalHazards, config.getOption("d3d9.generalHazards", Tristate::Auto)); - this->d3d9FloatEmulation = true; // <-- Future Extension? + this->d3d9FloatEmulation = config::FloatEmulationByDefault; // <-- Future Extension? applyTristate(this->d3d9FloatEmulation, config.getOption("d3d9.floatEmulation", Tristate::Auto)); }