Merge pull request #1689 from kayru/d3d_efb_copy_fix

D3D: Fixed D3D validation error during EFB to texture copy
This commit is contained in:
shuffle2 2014-12-18 02:59:51 -08:00
commit 717e155ce1
3 changed files with 38 additions and 0 deletions

View File

@ -199,6 +199,33 @@ void StateManager::Apply()
m_dirtyFlags = 0; 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;
}
void StateManager::SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceView* srv)
{
while (textureSlotMask)
{
unsigned long index;
_BitScanForward(&index, textureSlotMask);
SetTexture(index, srv);
textureSlotMask &= ~(1 << index);
}
}
} // namespace D3D } // namespace D3D
ID3D11SamplerState* StateCache::Get(SamplerState state) ID3D11SamplerState* StateCache::Get(SamplerState state)

View File

@ -218,6 +218,10 @@ public:
m_pending.geometryShader = shader; m_pending.geometryShader = shader;
} }
// removes currently set texture from all slots, returns mask of previously bound slots
u32 UnsetTexture(ID3D11ShaderResourceView* srv);
void SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceView* srv);
// call this immediately before any drawing operation or to explicitly apply pending resource state changes // call this immediately before any drawing operation or to explicitly apply pending resource state changes
void Apply(); void Apply();

View File

@ -157,6 +157,10 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
else else
D3D::SetPointCopySampler(); 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); D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr);
// Create texture copy // Create texture copy
@ -170,6 +174,9 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
g_renderer->RestoreAPIState(); g_renderer->RestoreAPIState();
// Restore old texture in all previously used slots, if any
D3D::stateman->SetTextureByMask(textureSlotMask, texture->GetSRV());
} }
if (!g_ActiveConfig.bCopyEFBToTexture) if (!g_ActiveConfig.bCopyEFBToTexture)