1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[d3d9] Track and defer mipmap generations

Turns out we need to track this crap and generate at draw time and handle a bunch of other wacky cases for it...

Bah.

Fixes #1642
(The funky water.)
This commit is contained in:
Joshua Ashton 2020-05-26 18:42:46 +01:00
parent b958473cc9
commit e57aea5749
4 changed files with 72 additions and 8 deletions

View File

@ -354,6 +354,9 @@ namespace dxvk {
bool NeedsAnyUpload() { return m_needsUpload.any(); }
void ClearNeedsUpload() { return m_needsUpload.clearAll(); }
void SetNeedsMipGen(bool value) { m_needsMipGen = value; }
bool NeedsMipGen() const { return m_needsMipGen; }
DWORD ExposedMipLevels() { return m_exposedMipLevels; }
private:
@ -395,6 +398,8 @@ namespace dxvk {
DWORD m_exposedMipLevels = 0;
bool m_needsMipGen = false;
/**
* \brief Mip level
* \returns Size of packed mip level in bytes

View File

@ -702,7 +702,7 @@ namespace dxvk {
dstTextureInfo->SetDirty(dst->GetSubresource(), true);
if (dstTextureInfo->IsAutomaticMip())
GenerateMips(dstTextureInfo);
MarkTextureMipsDirty(dstTextureInfo);
return D3D_OK;
}
@ -748,9 +748,14 @@ namespace dxvk {
}
}
dstTexInfo->MarkAllDirty();
if (dstTexInfo->IsAutomaticMip()) {
for (uint32_t i = 0; i < dstTexInfo->Desc()->ArraySize; i++)
dstTexInfo->SetDirty(dstTexInfo->CalcSubresource(i, 0), true);
pDestinationTexture->GenerateMipSubLevels();
MarkTextureMipsDirty(dstTexInfo);
}
else
dstTexInfo->MarkAllDirty();
FlushImplicit(false);
@ -1018,6 +1023,9 @@ namespace dxvk {
dstTextureInfo->SetDirty(dst->GetSubresource(), true);
if (dstTextureInfo->IsAutomaticMip())
MarkTextureMipsDirty(dstTextureInfo);
return D3D_OK;
}
@ -1093,6 +1101,9 @@ namespace dxvk {
dstTextureInfo->SetDirty(dst->GetSubresource(), true);
if (dstTextureInfo->IsAutomaticMip())
MarkTextureMipsDirty(dstTextureInfo);
return D3D_OK;
}
@ -4133,9 +4144,6 @@ namespace dxvk {
pResource->SetDirty(Subresource, true);
}
if (pResource->IsAutomaticMip())
GenerateMips(pResource);
return D3D_OK;
}
@ -4184,6 +4192,9 @@ namespace dxvk {
copyBuffer);
}
if (pResource->IsAutomaticMip())
MarkTextureMipsDirty(pResource);
return D3D_OK;
}
@ -4195,6 +4206,8 @@ namespace dxvk {
] (DxvkContext* ctx) {
ctx->generateMipmaps(cImageView);
});
pResource->SetNeedsMipGen(false);
}
@ -4770,6 +4783,7 @@ namespace dxvk {
m_activeDSTextures &= ~bit;
m_activeTextures &= ~bit;
m_activeTexturesToUpload &= ~bit;
m_activeTexturesToGen &= ~bit;
auto tex = GetCommonTexture(m_state.textures[index]);
if (tex != nullptr) {
@ -4783,6 +4797,9 @@ namespace dxvk {
if (unlikely(tex->NeedsAnyUpload()))
m_activeTexturesToUpload |= bit;
if (unlikely(tex->NeedsMipGen()))
m_activeTexturesToGen |= bit;
}
if (unlikely(combinedUsage & D3DUSAGE_RENDERTARGET))
@ -4873,6 +4890,35 @@ namespace dxvk {
}
void D3D9DeviceEx::GenerateTextureMips(uint32_t mask) {
for (uint32_t tex = mask; tex; tex &= tex - 1) {
// Guaranteed to not be nullptr...
auto texInfo = GetCommonTexture(m_state.textures[bit::tzcnt(tex)]);
this->GenerateMips(texInfo);
}
m_activeTexturesToGen &= ~mask;
}
void D3D9DeviceEx::MarkTextureMipsDirty(D3D9CommonTexture* pResource) {
pResource->SetNeedsMipGen(true);
for (uint32_t tex = m_activeTextures; tex; tex &= tex - 1) {
// Guaranteed to not be nullptr...
const uint32_t i = bit::tzcnt(tex);
auto texInfo = GetCommonTexture(m_state.textures[i]);
if (texInfo == pResource) {
m_activeTexturesToGen |= 1 << i;
// We can early out here, no need to add another index for this.
break;
}
}
}
template <bool Points>
void D3D9DeviceEx::UpdatePointMode() {
if constexpr (!Points) {
@ -5550,6 +5596,12 @@ namespace dxvk {
if (unlikely(texturesToUpload != 0))
UploadManagedTextures(texturesToUpload);
uint32_t texturesToGen = m_activeTexturesToGen;
texturesToGen &= m_psShaderMasks.samplerMask | m_vsShaderMasks.samplerMask;
if (unlikely(texturesToGen != 0))
GenerateTextureMips(texturesToGen);
auto* ibo = GetCommonBuffer(m_state.indices);
if (ibo != nullptr && ibo->NeedsUpload())
FlushBuffer(ibo);

View File

@ -750,6 +750,10 @@ namespace dxvk {
void UploadManagedTextures(uint32_t mask);
void GenerateTextureMips(uint32_t mask);
void MarkTextureMipsDirty(D3D9CommonTexture* pResource);
template <bool Points>
void UpdatePointMode();
@ -1035,6 +1039,7 @@ namespace dxvk {
uint32_t m_alphaSwizzleRTs = 0;
uint32_t m_activeTextures = 0;
uint32_t m_activeTexturesToUpload = 0;
uint32_t m_activeTexturesToGen = 0;
uint32_t m_fetch4Enabled = 0;
uint32_t m_lastFetch4 = 0;

View File

@ -84,8 +84,10 @@ namespace dxvk {
}
void STDMETHODCALLTYPE GenerateMipSubLevels() final {
if (m_texture.IsAutomaticMip())
this->m_parent->GenerateMips(&m_texture);
if (!m_texture.NeedsMipGen())
return;
this->m_parent->GenerateMips(&m_texture);
}
D3D9CommonTexture* GetCommonTexture() {