1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[d3d9] Fix ref-counting for swapchain surfaces

This commit is contained in:
Joshua Ashton 2020-04-18 20:40:49 +01:00
parent 97cd91885d
commit 42089d73c5
4 changed files with 26 additions and 13 deletions

View File

@ -30,7 +30,7 @@ namespace dxvk {
pBaseTexture, pBaseTexture,
pBaseTexture) { } pBaseTexture) { }
void D3D9Surface::AddRefPrivate() { void D3D9Surface::AddRefPrivate(bool swapchain) {
IDirect3DBaseTexture9* pBaseTexture = this->m_baseTexture; IDirect3DBaseTexture9* pBaseTexture = this->m_baseTexture;
IUnknown* pSwapChain = this->m_container; IUnknown* pSwapChain = this->m_container;
@ -43,7 +43,7 @@ namespace dxvk {
return; return;
} }
else if (pSwapChain != nullptr) { else if (pSwapChain != nullptr && !swapchain) {
// Container must be a swapchain if it isn't a base texture. // Container must be a swapchain if it isn't a base texture.
reinterpret_cast<D3D9SwapChainEx*>(pSwapChain)->AddRefPrivate(); reinterpret_cast<D3D9SwapChainEx*>(pSwapChain)->AddRefPrivate();
@ -53,7 +53,7 @@ namespace dxvk {
D3D9SurfaceBase::AddRefPrivate(); D3D9SurfaceBase::AddRefPrivate();
} }
void D3D9Surface::ReleasePrivate() { void D3D9Surface::ReleasePrivate(bool swapchain) {
IDirect3DBaseTexture9* pBaseTexture = this->m_baseTexture; IDirect3DBaseTexture9* pBaseTexture = this->m_baseTexture;
IUnknown* pSwapChain = this->m_container; IUnknown* pSwapChain = this->m_container;
@ -66,7 +66,7 @@ namespace dxvk {
return; return;
} }
else if (pSwapChain != nullptr) { else if (pSwapChain != nullptr && !swapchain) {
// Container must be a swapchain if it isn't a base texture. // Container must be a swapchain if it isn't a base texture.
reinterpret_cast<D3D9SwapChainEx*>(pSwapChain)->ReleasePrivate(); reinterpret_cast<D3D9SwapChainEx*>(pSwapChain)->ReleasePrivate();

View File

@ -29,9 +29,9 @@ namespace dxvk {
UINT MipLevel, UINT MipLevel,
IDirect3DBaseTexture9* pBaseTexture); IDirect3DBaseTexture9* pBaseTexture);
void AddRefPrivate(); void AddRefPrivate(bool swapchain = false);
void ReleasePrivate(); void ReleasePrivate(bool swapchain = false);
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);

View File

@ -463,7 +463,7 @@ namespace dxvk {
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
*ppBackBuffer = ref(m_backBuffers[iBackBuffer].get()); *ppBackBuffer = ref(m_backBuffers[iBackBuffer]);
return D3D_OK; return D3D_OK;
} }
@ -712,7 +712,7 @@ namespace dxvk {
if (iBackBuffer >= m_presentParams.BackBufferCount) if (iBackBuffer >= m_presentParams.BackBufferCount)
return nullptr; return nullptr;
return m_backBuffers[iBackBuffer].get(); return m_backBuffers[iBackBuffer];
} }
@ -876,7 +876,7 @@ namespace dxvk {
// Rotate swap chain buffers so that the back // Rotate swap chain buffers so that the back
// buffer at index 0 becomes the front buffer. // buffer at index 0 becomes the front buffer.
for (uint32_t i = 1; i < m_backBuffers.size(); i++) for (uint32_t i = 1; i < m_backBuffers.size(); i++)
m_backBuffers[i]->Swap(m_backBuffers[i - 1].get()); m_backBuffers[i]->Swap(m_backBuffers[i - 1]);
m_parent->m_flags.set(D3D9DeviceFlag::DirtyFramebuffer); m_parent->m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
} }
@ -1010,14 +1010,23 @@ namespace dxvk {
} }
void D3D9SwapChainEx::DestroyBackBuffers() {
for (auto* backBuffer : m_backBuffers)
backBuffer->ReleasePrivate(true);
m_backBuffers.clear();
}
void D3D9SwapChainEx::CreateBackBuffers(uint32_t NumBackBuffers) { void D3D9SwapChainEx::CreateBackBuffers(uint32_t NumBackBuffers) {
// Explicitly destroy current swap image before // Explicitly destroy current swap image before
// creating a new one to free up resources // creating a new one to free up resources
m_resolveImage = nullptr; m_resolveImage = nullptr;
m_resolveImageView = nullptr; m_resolveImageView = nullptr;
DestroyBackBuffers();
int NumFrontBuffer = m_parent->GetOptions()->noExplicitFrontBuffer ? 0 : 1; int NumFrontBuffer = m_parent->GetOptions()->noExplicitFrontBuffer ? 0 : 1;
m_backBuffers.clear();
m_backBuffers.resize(NumBackBuffers + NumFrontBuffer); m_backBuffers.resize(NumBackBuffers + NumFrontBuffer);
// Create new back buffer // Create new back buffer
@ -1034,8 +1043,10 @@ namespace dxvk {
desc.Usage = D3DUSAGE_RENDERTARGET; desc.Usage = D3DUSAGE_RENDERTARGET;
desc.Discard = FALSE; desc.Discard = FALSE;
for (uint32_t i = 0; i < m_backBuffers.size(); i++) for (uint32_t i = 0; i < m_backBuffers.size(); i++) {
m_backBuffers[i] = std::make_unique<D3D9Surface>(m_parent, &desc, this); m_backBuffers[i] = new D3D9Surface(m_parent, &desc, this);
m_backBuffers[i]->AddRefPrivate(true);
}
auto swapImage = m_backBuffers[0]->GetCommonTexture()->GetImage(); auto swapImage = m_backBuffers[0]->GetCommonTexture()->GetImage();

View File

@ -129,7 +129,7 @@ namespace dxvk {
DxvkLogicOpState m_loState; DxvkLogicOpState m_loState;
DxvkBlendMode m_blendMode; DxvkBlendMode m_blendMode;
std::vector<std::unique_ptr<D3D9Surface>> m_backBuffers; std::vector<D3D9Surface*> m_backBuffers;
RECT m_srcRect; RECT m_srcRect;
RECT m_dstRect; RECT m_dstRect;
@ -167,6 +167,8 @@ namespace dxvk {
void CreateRenderTargetViews(); void CreateRenderTargetViews();
void DestroyBackBuffers();
void CreateBackBuffers( void CreateBackBuffers(
uint32_t NumBackBuffers); uint32_t NumBackBuffers);