mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
[d3d9] Implement swapchain containers for surfaces
Fixes a crash in L.A. Noire. Closes #1564
This commit is contained in:
parent
4d8940957c
commit
4699d4162a
@ -3318,7 +3318,7 @@ namespace dxvk {
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
try {
|
||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc);
|
||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc, nullptr);
|
||||
m_initializer->InitTexture(surface->GetCommonTexture());
|
||||
*ppSurface = surface.ref();
|
||||
return D3D_OK;
|
||||
@ -3361,7 +3361,7 @@ namespace dxvk {
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
try {
|
||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc);
|
||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc, nullptr);
|
||||
m_initializer->InitTexture(surface->GetCommonTexture());
|
||||
*ppSurface = surface.ref();
|
||||
return D3D_OK;
|
||||
@ -3406,7 +3406,7 @@ namespace dxvk {
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
try {
|
||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc);
|
||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc, nullptr);
|
||||
m_initializer->InitTexture(surface->GetCommonTexture());
|
||||
*ppSurface = surface.ref();
|
||||
return D3D_OK;
|
||||
@ -6695,7 +6695,7 @@ namespace dxvk {
|
||||
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc)))
|
||||
return D3DERR_NOTAVAILABLE;
|
||||
|
||||
m_autoDepthStencil = new D3D9Surface(this, &desc);
|
||||
m_autoDepthStencil = new D3D9Surface(this, &desc, nullptr);
|
||||
m_initializer->InitTexture(m_autoDepthStencil->GetCommonTexture());
|
||||
SetDepthStencilSurface(m_autoDepthStencil.ptr());
|
||||
}
|
||||
|
@ -15,8 +15,10 @@ namespace dxvk {
|
||||
D3D9CommonTexture* pTexture,
|
||||
UINT Face,
|
||||
UINT MipLevel,
|
||||
IDirect3DBaseTexture9* pContainer)
|
||||
IDirect3DBaseTexture9* pBaseTexture,
|
||||
IUnknown* pContainer)
|
||||
: D3D9Resource<Type...> ( pDevice )
|
||||
, m_baseTexture ( pBaseTexture )
|
||||
, m_container ( pContainer )
|
||||
, m_texture ( pTexture )
|
||||
, m_face ( Face )
|
||||
@ -25,7 +27,7 @@ namespace dxvk {
|
||||
|
||||
~D3D9Subresource() {
|
||||
// We own the texture!
|
||||
if (m_container == nullptr)
|
||||
if (m_baseTexture == nullptr)
|
||||
delete m_texture;
|
||||
}
|
||||
|
||||
@ -108,7 +110,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
IDirect3DBaseTexture9* GetBaseTexture() {
|
||||
return m_container;
|
||||
return m_baseTexture;
|
||||
}
|
||||
|
||||
void Swap(D3D9Subresource* Other) {
|
||||
@ -121,7 +123,8 @@ namespace dxvk {
|
||||
|
||||
protected:
|
||||
|
||||
IDirect3DBaseTexture9* m_container;
|
||||
IUnknown* m_container;
|
||||
IDirect3DBaseTexture9* m_baseTexture;
|
||||
|
||||
D3D9CommonTexture* m_texture;
|
||||
UINT m_face;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "d3d9_surface.h"
|
||||
#include "d3d9_texture.h"
|
||||
#include "d3d9_swapchain.h"
|
||||
|
||||
#include "d3d9_device.h"
|
||||
|
||||
@ -7,34 +8,44 @@ namespace dxvk {
|
||||
|
||||
D3D9Surface::D3D9Surface(
|
||||
D3D9DeviceEx* pDevice,
|
||||
const D3D9_COMMON_TEXTURE_DESC* pDesc)
|
||||
const D3D9_COMMON_TEXTURE_DESC* pDesc,
|
||||
IUnknown* pContainer)
|
||||
: D3D9SurfaceBase(
|
||||
pDevice,
|
||||
new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_TEXTURE),
|
||||
0, 0,
|
||||
nullptr) { }
|
||||
nullptr,
|
||||
pContainer) { }
|
||||
|
||||
D3D9Surface::D3D9Surface(
|
||||
D3D9DeviceEx* pDevice,
|
||||
D3D9CommonTexture* pTexture,
|
||||
UINT Face,
|
||||
UINT MipLevel,
|
||||
IDirect3DBaseTexture9* pContainer)
|
||||
IDirect3DBaseTexture9* pBaseTexture)
|
||||
: D3D9SurfaceBase(
|
||||
pDevice,
|
||||
pTexture,
|
||||
Face, MipLevel,
|
||||
pContainer) { }
|
||||
pBaseTexture,
|
||||
pBaseTexture) { }
|
||||
|
||||
void D3D9Surface::AddRefPrivate() {
|
||||
IDirect3DBaseTexture9* pContainer = this->m_container;
|
||||
IDirect3DBaseTexture9* pBaseTexture = this->m_baseTexture;
|
||||
IUnknown* pSwapChain = this->m_container;
|
||||
|
||||
if (pContainer != nullptr) {
|
||||
D3DRESOURCETYPE type = pContainer->GetType();
|
||||
if (pBaseTexture != nullptr) {
|
||||
D3DRESOURCETYPE type = pBaseTexture->GetType();
|
||||
if (type == D3DRTYPE_TEXTURE)
|
||||
reinterpret_cast<D3D9Texture2D*> (pContainer)->AddRefPrivate();
|
||||
reinterpret_cast<D3D9Texture2D*> (pBaseTexture)->AddRefPrivate();
|
||||
else //if (type == D3DRTYPE_CUBETEXTURE)
|
||||
reinterpret_cast<D3D9TextureCube*>(pContainer)->AddRefPrivate();
|
||||
reinterpret_cast<D3D9TextureCube*>(pBaseTexture)->AddRefPrivate();
|
||||
|
||||
return;
|
||||
}
|
||||
else if (pSwapChain != nullptr) {
|
||||
// Container must be a swapchain if it isn't a base texture.
|
||||
reinterpret_cast<D3D9SwapChainEx*>(pSwapChain)->AddRefPrivate();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -43,14 +54,21 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
void D3D9Surface::ReleasePrivate() {
|
||||
IDirect3DBaseTexture9* pContainer = this->m_container;
|
||||
IDirect3DBaseTexture9* pBaseTexture = this->m_baseTexture;
|
||||
IUnknown* pSwapChain = this->m_container;
|
||||
|
||||
if (pContainer != nullptr) {
|
||||
D3DRESOURCETYPE type = pContainer->GetType();
|
||||
if (pBaseTexture != nullptr) {
|
||||
D3DRESOURCETYPE type = pBaseTexture->GetType();
|
||||
if (type == D3DRTYPE_TEXTURE)
|
||||
reinterpret_cast<D3D9Texture2D*> (pContainer)->ReleasePrivate();
|
||||
reinterpret_cast<D3D9Texture2D*> (pBaseTexture)->ReleasePrivate();
|
||||
else //if (type == D3DRTYPE_CUBETEXTURE)
|
||||
reinterpret_cast<D3D9TextureCube*>(pContainer)->ReleasePrivate();
|
||||
reinterpret_cast<D3D9TextureCube*>(pBaseTexture)->ReleasePrivate();
|
||||
|
||||
return;
|
||||
}
|
||||
else if (pSwapChain != nullptr) {
|
||||
// Container must be a swapchain if it isn't a base texture.
|
||||
reinterpret_cast<D3D9SwapChainEx*>(pSwapChain)->ReleasePrivate();
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -19,14 +19,15 @@ namespace dxvk {
|
||||
|
||||
D3D9Surface(
|
||||
D3D9DeviceEx* pDevice,
|
||||
const D3D9_COMMON_TEXTURE_DESC* pDesc);
|
||||
const D3D9_COMMON_TEXTURE_DESC* pDesc,
|
||||
IUnknown* pContainer);
|
||||
|
||||
D3D9Surface(
|
||||
D3D9DeviceEx* pDevice,
|
||||
D3D9CommonTexture* pTexture,
|
||||
UINT Face,
|
||||
UINT MipLevel,
|
||||
IDirect3DBaseTexture9* pContainer);
|
||||
IDirect3DBaseTexture9* pBaseTexture);
|
||||
|
||||
void AddRefPrivate();
|
||||
|
||||
|
@ -463,7 +463,7 @@ namespace dxvk {
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
*ppBackBuffer = m_backBuffers[iBackBuffer].ref();
|
||||
*ppBackBuffer = ref(m_backBuffers[iBackBuffer].get());
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
@ -712,7 +712,7 @@ namespace dxvk {
|
||||
if (iBackBuffer >= m_presentParams.BackBufferCount)
|
||||
return nullptr;
|
||||
|
||||
return m_backBuffers[iBackBuffer].ptr();
|
||||
return m_backBuffers[iBackBuffer].get();
|
||||
}
|
||||
|
||||
|
||||
@ -876,7 +876,7 @@ namespace dxvk {
|
||||
// Rotate swap chain buffers so that the back
|
||||
// buffer at index 0 becomes the front buffer.
|
||||
for (uint32_t i = 1; i < m_backBuffers.size(); i++)
|
||||
m_backBuffers[i]->Swap(m_backBuffers[i - 1].ptr());
|
||||
m_backBuffers[i]->Swap(m_backBuffers[i - 1].get());
|
||||
|
||||
m_parent->m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
|
||||
}
|
||||
@ -1035,7 +1035,7 @@ namespace dxvk {
|
||||
desc.Discard = FALSE;
|
||||
|
||||
for (uint32_t i = 0; i < m_backBuffers.size(); i++)
|
||||
m_backBuffers[i] = new D3D9Surface(m_parent, &desc);
|
||||
m_backBuffers[i] = std::make_unique<D3D9Surface>(m_parent, &desc, this);
|
||||
|
||||
auto swapImage = m_backBuffers[0]->GetCommonTexture()->GetImage();
|
||||
|
||||
|
@ -129,7 +129,7 @@ namespace dxvk {
|
||||
DxvkLogicOpState m_loState;
|
||||
DxvkBlendMode m_blendMode;
|
||||
|
||||
std::vector<Com<D3D9Surface, false>> m_backBuffers;
|
||||
std::vector<std::unique_ptr<D3D9Surface>> m_backBuffers;
|
||||
|
||||
RECT m_srcRect;
|
||||
RECT m_dstRect;
|
||||
|
@ -12,6 +12,7 @@ namespace dxvk {
|
||||
pDevice,
|
||||
new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_VOLUMETEXTURE ),
|
||||
0, 0,
|
||||
nullptr,
|
||||
nullptr) { }
|
||||
|
||||
|
||||
@ -25,11 +26,14 @@ namespace dxvk {
|
||||
pDevice,
|
||||
pTexture,
|
||||
Face, MipLevel,
|
||||
pContainer,
|
||||
pContainer) { }
|
||||
|
||||
|
||||
void D3D9Volume::AddRefPrivate() {
|
||||
IDirect3DBaseTexture9* pContainer = this->m_container;
|
||||
IDirect3DBaseTexture9* pContainer = this->m_baseTexture;
|
||||
|
||||
// Can't have a swapchain container for a volume.
|
||||
|
||||
if (pContainer != nullptr) {
|
||||
reinterpret_cast<D3D9Texture3D*> (pContainer)->AddRefPrivate();
|
||||
@ -41,7 +45,9 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D9Volume::ReleasePrivate() {
|
||||
IDirect3DBaseTexture9* pContainer = this->m_container;
|
||||
IDirect3DBaseTexture9* pContainer = this->m_baseTexture;
|
||||
|
||||
// Can't have a swapchain container for a volume.
|
||||
|
||||
if (pContainer != nullptr) {
|
||||
reinterpret_cast<D3D9Texture3D*> (pContainer)->ReleasePrivate();
|
||||
|
Loading…
Reference in New Issue
Block a user