D3D: Fixed D3D validation error during EFB to texture copy
Texture was being bound as a render target while still being set as a shader resource. D3D automatically unbinds the SRV in this case and generates a validation error. The fix is to manually unbind SRV, render into it and then re-bind to old slots.
This commit is contained in:
parent
971a95aece
commit
764aee6995
|
@ -199,6 +199,22 @@ void StateManager::Apply()
|
|||
m_dirtyFlags = 0;
|
||||
}
|
||||
|
||||
u32 StateManager::UnsetTexture(ID3D11ShaderResourceView* srv)
|
||||
{
|
||||
u32 mask = 0;
|
||||
|
||||
for (u32 index = 0; index < 8; ++index)
|
||||
{
|
||||
if (m_current.textures[index] == srv)
|
||||
{
|
||||
SetTexture(index, nullptr);
|
||||
mask |= 1 << index;
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
} // namespace D3D
|
||||
|
||||
ID3D11SamplerState* StateCache::Get(SamplerState state)
|
||||
|
|
|
@ -234,6 +234,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// removes currently set texture from all slots, returns mask of previously bound slots
|
||||
u32 StateManager::UnsetTexture(ID3D11ShaderResourceView* srv);
|
||||
|
||||
// call this immediately before any drawing operation or to explicitly apply pending resource state changes
|
||||
void Apply();
|
||||
|
||||
|
|
|
@ -156,6 +156,10 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
|||
else
|
||||
D3D::SetPointCopySampler();
|
||||
|
||||
// if texture is currently in use, it needs to be temporarily unset
|
||||
u32 textureSlotMask = D3D::stateman->UnsetTexture(texture->GetSRV());
|
||||
D3D::stateman->Apply();
|
||||
|
||||
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr);
|
||||
|
||||
// Create texture copy
|
||||
|
@ -168,6 +172,15 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
|||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||
|
||||
g_renderer->RestoreAPIState();
|
||||
|
||||
// Restore old texture in all previously used slots, if any
|
||||
while (textureSlotMask)
|
||||
{
|
||||
unsigned long index;
|
||||
_BitScanForward(&index, textureSlotMask);
|
||||
D3D::stateman->SetTexture(index, texture->GetSRV());
|
||||
textureSlotMask &= ~(1 << index);
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_ActiveConfig.bCopyEFBToTexture)
|
||||
|
|
Loading…
Reference in New Issue