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:
parent
b958473cc9
commit
e57aea5749
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user