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;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc);
|
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc, nullptr);
|
||||||
m_initializer->InitTexture(surface->GetCommonTexture());
|
m_initializer->InitTexture(surface->GetCommonTexture());
|
||||||
*ppSurface = surface.ref();
|
*ppSurface = surface.ref();
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
@ -3361,7 +3361,7 @@ namespace dxvk {
|
|||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc);
|
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc, nullptr);
|
||||||
m_initializer->InitTexture(surface->GetCommonTexture());
|
m_initializer->InitTexture(surface->GetCommonTexture());
|
||||||
*ppSurface = surface.ref();
|
*ppSurface = surface.ref();
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
@ -3406,7 +3406,7 @@ namespace dxvk {
|
|||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc);
|
const Com<D3D9Surface> surface = new D3D9Surface(this, &desc, nullptr);
|
||||||
m_initializer->InitTexture(surface->GetCommonTexture());
|
m_initializer->InitTexture(surface->GetCommonTexture());
|
||||||
*ppSurface = surface.ref();
|
*ppSurface = surface.ref();
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
@ -6695,7 +6695,7 @@ namespace dxvk {
|
|||||||
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc)))
|
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc)))
|
||||||
return D3DERR_NOTAVAILABLE;
|
return D3DERR_NOTAVAILABLE;
|
||||||
|
|
||||||
m_autoDepthStencil = new D3D9Surface(this, &desc);
|
m_autoDepthStencil = new D3D9Surface(this, &desc, nullptr);
|
||||||
m_initializer->InitTexture(m_autoDepthStencil->GetCommonTexture());
|
m_initializer->InitTexture(m_autoDepthStencil->GetCommonTexture());
|
||||||
SetDepthStencilSurface(m_autoDepthStencil.ptr());
|
SetDepthStencilSurface(m_autoDepthStencil.ptr());
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,10 @@ namespace dxvk {
|
|||||||
D3D9CommonTexture* pTexture,
|
D3D9CommonTexture* pTexture,
|
||||||
UINT Face,
|
UINT Face,
|
||||||
UINT MipLevel,
|
UINT MipLevel,
|
||||||
IDirect3DBaseTexture9* pContainer)
|
IDirect3DBaseTexture9* pBaseTexture,
|
||||||
|
IUnknown* pContainer)
|
||||||
: D3D9Resource<Type...> ( pDevice )
|
: D3D9Resource<Type...> ( pDevice )
|
||||||
|
, m_baseTexture ( pBaseTexture )
|
||||||
, m_container ( pContainer )
|
, m_container ( pContainer )
|
||||||
, m_texture ( pTexture )
|
, m_texture ( pTexture )
|
||||||
, m_face ( Face )
|
, m_face ( Face )
|
||||||
@ -25,7 +27,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
~D3D9Subresource() {
|
~D3D9Subresource() {
|
||||||
// We own the texture!
|
// We own the texture!
|
||||||
if (m_container == nullptr)
|
if (m_baseTexture == nullptr)
|
||||||
delete m_texture;
|
delete m_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +110,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IDirect3DBaseTexture9* GetBaseTexture() {
|
IDirect3DBaseTexture9* GetBaseTexture() {
|
||||||
return m_container;
|
return m_baseTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swap(D3D9Subresource* Other) {
|
void Swap(D3D9Subresource* Other) {
|
||||||
@ -121,7 +123,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
IDirect3DBaseTexture9* m_container;
|
IUnknown* m_container;
|
||||||
|
IDirect3DBaseTexture9* m_baseTexture;
|
||||||
|
|
||||||
D3D9CommonTexture* m_texture;
|
D3D9CommonTexture* m_texture;
|
||||||
UINT m_face;
|
UINT m_face;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "d3d9_surface.h"
|
#include "d3d9_surface.h"
|
||||||
#include "d3d9_texture.h"
|
#include "d3d9_texture.h"
|
||||||
|
#include "d3d9_swapchain.h"
|
||||||
|
|
||||||
#include "d3d9_device.h"
|
#include "d3d9_device.h"
|
||||||
|
|
||||||
@ -7,34 +8,44 @@ namespace dxvk {
|
|||||||
|
|
||||||
D3D9Surface::D3D9Surface(
|
D3D9Surface::D3D9Surface(
|
||||||
D3D9DeviceEx* pDevice,
|
D3D9DeviceEx* pDevice,
|
||||||
const D3D9_COMMON_TEXTURE_DESC* pDesc)
|
const D3D9_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
IUnknown* pContainer)
|
||||||
: D3D9SurfaceBase(
|
: D3D9SurfaceBase(
|
||||||
pDevice,
|
pDevice,
|
||||||
new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_TEXTURE),
|
new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_TEXTURE),
|
||||||
0, 0,
|
0, 0,
|
||||||
nullptr) { }
|
nullptr,
|
||||||
|
pContainer) { }
|
||||||
|
|
||||||
D3D9Surface::D3D9Surface(
|
D3D9Surface::D3D9Surface(
|
||||||
D3D9DeviceEx* pDevice,
|
D3D9DeviceEx* pDevice,
|
||||||
D3D9CommonTexture* pTexture,
|
D3D9CommonTexture* pTexture,
|
||||||
UINT Face,
|
UINT Face,
|
||||||
UINT MipLevel,
|
UINT MipLevel,
|
||||||
IDirect3DBaseTexture9* pContainer)
|
IDirect3DBaseTexture9* pBaseTexture)
|
||||||
: D3D9SurfaceBase(
|
: D3D9SurfaceBase(
|
||||||
pDevice,
|
pDevice,
|
||||||
pTexture,
|
pTexture,
|
||||||
Face, MipLevel,
|
Face, MipLevel,
|
||||||
pContainer) { }
|
pBaseTexture,
|
||||||
|
pBaseTexture) { }
|
||||||
|
|
||||||
void D3D9Surface::AddRefPrivate() {
|
void D3D9Surface::AddRefPrivate() {
|
||||||
IDirect3DBaseTexture9* pContainer = this->m_container;
|
IDirect3DBaseTexture9* pBaseTexture = this->m_baseTexture;
|
||||||
|
IUnknown* pSwapChain = this->m_container;
|
||||||
|
|
||||||
if (pContainer != nullptr) {
|
if (pBaseTexture != nullptr) {
|
||||||
D3DRESOURCETYPE type = pContainer->GetType();
|
D3DRESOURCETYPE type = pBaseTexture->GetType();
|
||||||
if (type == D3DRTYPE_TEXTURE)
|
if (type == D3DRTYPE_TEXTURE)
|
||||||
reinterpret_cast<D3D9Texture2D*> (pContainer)->AddRefPrivate();
|
reinterpret_cast<D3D9Texture2D*> (pBaseTexture)->AddRefPrivate();
|
||||||
else //if (type == D3DRTYPE_CUBETEXTURE)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@ -43,14 +54,21 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void D3D9Surface::ReleasePrivate() {
|
void D3D9Surface::ReleasePrivate() {
|
||||||
IDirect3DBaseTexture9* pContainer = this->m_container;
|
IDirect3DBaseTexture9* pBaseTexture = this->m_baseTexture;
|
||||||
|
IUnknown* pSwapChain = this->m_container;
|
||||||
|
|
||||||
if (pContainer != nullptr) {
|
if (pBaseTexture != nullptr) {
|
||||||
D3DRESOURCETYPE type = pContainer->GetType();
|
D3DRESOURCETYPE type = pBaseTexture->GetType();
|
||||||
if (type == D3DRTYPE_TEXTURE)
|
if (type == D3DRTYPE_TEXTURE)
|
||||||
reinterpret_cast<D3D9Texture2D*> (pContainer)->ReleasePrivate();
|
reinterpret_cast<D3D9Texture2D*> (pBaseTexture)->ReleasePrivate();
|
||||||
else //if (type == D3DRTYPE_CUBETEXTURE)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,15 @@ namespace dxvk {
|
|||||||
|
|
||||||
D3D9Surface(
|
D3D9Surface(
|
||||||
D3D9DeviceEx* pDevice,
|
D3D9DeviceEx* pDevice,
|
||||||
const D3D9_COMMON_TEXTURE_DESC* pDesc);
|
const D3D9_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
IUnknown* pContainer);
|
||||||
|
|
||||||
D3D9Surface(
|
D3D9Surface(
|
||||||
D3D9DeviceEx* pDevice,
|
D3D9DeviceEx* pDevice,
|
||||||
D3D9CommonTexture* pTexture,
|
D3D9CommonTexture* pTexture,
|
||||||
UINT Face,
|
UINT Face,
|
||||||
UINT MipLevel,
|
UINT MipLevel,
|
||||||
IDirect3DBaseTexture9* pContainer);
|
IDirect3DBaseTexture9* pBaseTexture);
|
||||||
|
|
||||||
void AddRefPrivate();
|
void AddRefPrivate();
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ namespace dxvk {
|
|||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppBackBuffer = m_backBuffers[iBackBuffer].ref();
|
*ppBackBuffer = ref(m_backBuffers[iBackBuffer].get());
|
||||||
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].ptr();
|
return m_backBuffers[iBackBuffer].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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].ptr());
|
m_backBuffers[i]->Swap(m_backBuffers[i - 1].get());
|
||||||
|
|
||||||
m_parent->m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
|
m_parent->m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
|
||||||
}
|
}
|
||||||
@ -1035,7 +1035,7 @@ namespace dxvk {
|
|||||||
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] = new D3D9Surface(m_parent, &desc);
|
m_backBuffers[i] = std::make_unique<D3D9Surface>(m_parent, &desc, this);
|
||||||
|
|
||||||
auto swapImage = m_backBuffers[0]->GetCommonTexture()->GetImage();
|
auto swapImage = m_backBuffers[0]->GetCommonTexture()->GetImage();
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ namespace dxvk {
|
|||||||
DxvkLogicOpState m_loState;
|
DxvkLogicOpState m_loState;
|
||||||
DxvkBlendMode m_blendMode;
|
DxvkBlendMode m_blendMode;
|
||||||
|
|
||||||
std::vector<Com<D3D9Surface, false>> m_backBuffers;
|
std::vector<std::unique_ptr<D3D9Surface>> m_backBuffers;
|
||||||
|
|
||||||
RECT m_srcRect;
|
RECT m_srcRect;
|
||||||
RECT m_dstRect;
|
RECT m_dstRect;
|
||||||
|
@ -12,6 +12,7 @@ namespace dxvk {
|
|||||||
pDevice,
|
pDevice,
|
||||||
new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_VOLUMETEXTURE ),
|
new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_VOLUMETEXTURE ),
|
||||||
0, 0,
|
0, 0,
|
||||||
|
nullptr,
|
||||||
nullptr) { }
|
nullptr) { }
|
||||||
|
|
||||||
|
|
||||||
@ -25,11 +26,14 @@ namespace dxvk {
|
|||||||
pDevice,
|
pDevice,
|
||||||
pTexture,
|
pTexture,
|
||||||
Face, MipLevel,
|
Face, MipLevel,
|
||||||
|
pContainer,
|
||||||
pContainer) { }
|
pContainer) { }
|
||||||
|
|
||||||
|
|
||||||
void D3D9Volume::AddRefPrivate() {
|
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) {
|
if (pContainer != nullptr) {
|
||||||
reinterpret_cast<D3D9Texture3D*> (pContainer)->AddRefPrivate();
|
reinterpret_cast<D3D9Texture3D*> (pContainer)->AddRefPrivate();
|
||||||
@ -41,7 +45,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void D3D9Volume::ReleasePrivate() {
|
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) {
|
if (pContainer != nullptr) {
|
||||||
reinterpret_cast<D3D9Texture3D*> (pContainer)->ReleasePrivate();
|
reinterpret_cast<D3D9Texture3D*> (pContainer)->ReleasePrivate();
|
||||||
|
Loading…
Reference in New Issue
Block a user