Skip to content

Commit

Permalink
Merge pull request #1689 from kayru/d3d_efb_copy_fix
Browse files Browse the repository at this point in the history
D3D: Fixed D3D validation error during EFB to texture copy
  • Loading branch information
shuffle2 committed Dec 18, 2014
2 parents 418e006 + 5688c27 commit 717e155
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
27 changes: 27 additions & 0 deletions Source/Core/VideoBackends/D3D/D3DState.cpp
Expand Up @@ -199,6 +199,33 @@ 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;
}

void StateManager::SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceView* srv)
{
while (textureSlotMask)
{
unsigned long index;
_BitScanForward(&index, textureSlotMask);
SetTexture(index, srv);
textureSlotMask &= ~(1 << index);
}
}

} // namespace D3D

ID3D11SamplerState* StateCache::Get(SamplerState state)
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/VideoBackends/D3D/D3DState.h
Expand Up @@ -218,6 +218,10 @@ class StateManager
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
void Apply();

Expand Down
7 changes: 7 additions & 0 deletions Source/Core/VideoBackends/D3D/TextureCache.cpp
Expand Up @@ -157,6 +157,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
Expand All @@ -170,6 +174,9 @@ 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
D3D::stateman->SetTextureByMask(textureSlotMask, texture->GetSRV());
}

if (!g_ActiveConfig.bCopyEFBToTexture)
Expand Down

0 comments on commit 717e155

Please sign in to comment.