From b220c8989b0a8006360c6d2c7bd2a5cda9064e7c Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Thu, 27 Jan 2022 17:27:25 +0100 Subject: [PATCH] [d3d9] Only enable FETCH4 for single channel formats --- src/d3d9/d3d9_common_texture.cpp | 18 +++++++++++++++--- src/d3d9/d3d9_common_texture.h | 11 +++++++++++ src/d3d9/d3d9_device.cpp | 24 ++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 63943c62..8e5d237b 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -30,8 +30,9 @@ namespace dxvk { m_mapping = pDevice->LookupFormat(m_desc.Format); - m_mapMode = DetermineMapMode(); - m_shadow = DetermineShadowState(); + m_mapMode = DetermineMapMode(); + m_shadow = DetermineShadowState(); + m_supportsFetch4 = DetermineFetch4Compatibility(); if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED) { bool plainSurface = m_type == D3DRTYPE_SURFACE && @@ -316,7 +317,7 @@ namespace dxvk { BOOL D3D9CommonTexture::DetermineShadowState() const { - static std::array blacklist = { + constexpr std::array blacklist = { D3D9Format::INTZ, D3D9Format::DF16, D3D9Format::DF24 }; @@ -325,6 +326,17 @@ namespace dxvk { } + BOOL D3D9CommonTexture::DetermineFetch4Compatibility() const { + constexpr std::array singleChannelFormats = { + D3D9Format::INTZ, D3D9Format::DF16, D3D9Format::DF24, + D3D9Format::R16F, D3D9Format::R32F, D3D9Format::A8, + D3D9Format::L8, D3D9Format::L16 + }; + + return std::find(singleChannelFormats.begin(), singleChannelFormats.end(), m_desc.Format) != singleChannelFormats.end(); + } + + BOOL D3D9CommonTexture::CheckImageSupport( const DxvkImageCreateInfo* pImageInfo, VkImageTiling Tiling) const { diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index e3da26fd..f4d14115 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -190,6 +190,14 @@ namespace dxvk { return m_shadow; } + /** + * \brief FETCH4 compatibility + * \returns Whether the format of the texture supports the FETCH4 hack + */ + bool SupportsFetch4() const { + return m_supportsFetch4; + } + /** * \brief Null * \returns Whether the texture is D3DFMT_NULL or not @@ -444,6 +452,7 @@ namespace dxvk { D3D9_VK_FORMAT_MAPPING m_mapping; bool m_shadow; //< Depth Compare-ness + bool m_supportsFetch4; int64_t m_size = 0; @@ -483,6 +492,8 @@ namespace dxvk { BOOL DetermineShadowState() const; + BOOL DetermineFetch4Compatibility() const; + BOOL CheckImageSupport( const DxvkImageCreateInfo* pImageInfo, VkImageTiling Tiling) const; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 0699d8f3..ffba18d1 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3682,10 +3682,14 @@ namespace dxvk { constexpr DWORD Fetch4Disabled = MAKEFOURCC('G', 'E', 'T', '1'); if (unlikely(Type == D3DSAMP_MIPMAPLODBIAS)) { + auto texture = GetCommonTexture(m_state.textures[StateSampler]); + bool textureSupportsFetch4 = texture != nullptr && texture->SupportsFetch4(); + if (unlikely(Value == Fetch4Enabled)) { m_fetch4Enabled |= 1u << StateSampler; - if (state[StateSampler][D3DSAMP_MAGFILTER] == D3DTEXF_POINT) + if (textureSupportsFetch4 && state[StateSampler][D3DSAMP_MAGFILTER] == D3DTEXF_POINT) { m_fetch4 |= 1u << StateSampler; + } } else if (unlikely(Value == Fetch4Disabled)) { m_fetch4Enabled &= ~(1u << StateSampler); @@ -3694,7 +3698,10 @@ namespace dxvk { } if (unlikely(Type == D3DSAMP_MAGFILTER && (m_fetch4Enabled & (1u << StateSampler)))) { - if (Value == D3DTEXF_POINT) + auto texture = GetCommonTexture(m_state.textures[StateSampler]); + bool textureSupportsFetch4 = texture != nullptr && texture->SupportsFetch4(); + + if (Value == D3DTEXF_POINT && textureSupportsFetch4) m_fetch4 |= 1u << StateSampler; else m_fetch4 &= ~(1u << StateSampler); @@ -3748,6 +3755,19 @@ namespace dxvk { m_dirtySamplerStates |= 1u << StateSampler; } + + if (unlikely(m_fetch4Enabled & (1u << StateSampler) && !(m_fetch4 & (1u << StateSampler)))) { + bool textureSupportsFetch4 = newTexture->SupportsFetch4(); + if (textureSupportsFetch4 + && m_state.samplerStates[StateSampler][D3DSAMP_MAGFILTER] == D3DTEXF_POINT + && m_state.samplerStates[StateSampler][D3DSAMP_MINFILTER] == D3DTEXF_POINT) { + m_fetch4 |= 1u << StateSampler; + m_dirtySamplerStates |= 1u << StateSampler; + } + } + } else if (unlikely(m_fetch4 & (1u << StateSampler))) { + m_fetch4 &= ~(1u << StateSampler); + m_dirtySamplerStates |= 1u << StateSampler; } DWORD combinedUsage = oldUsage | newUsage;