GS/DX11: Fix possible use-after-free on cached RT/DS

This commit is contained in:
Connor McLaughlin 2022-04-24 21:31:55 +10:00 committed by refractionpcsx2
parent 6b1e483d28
commit 3359b3c7ab
2 changed files with 25 additions and 9 deletions

View File

@ -58,6 +58,14 @@ GSDevice11::GSDevice11()
m_features.stencil_buffer = true; m_features.stencil_buffer = true;
} }
GSDevice11::~GSDevice11()
{
if (m_state.rt_view)
m_state.rt_view->Release();
if (m_state.dsv)
m_state.dsv->Release();
}
bool GSDevice11::Create(HostDisplay* display) bool GSDevice11::Create(HostDisplay* display)
{ {
if (!__super::Create(display)) if (!__super::Create(display))
@ -1153,15 +1161,25 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
if (rt) rtv = *(GSTexture11*)rt; if (rt) rtv = *(GSTexture11*)rt;
if (ds) dsv = *(GSTexture11*)ds; if (ds) dsv = *(GSTexture11*)ds;
if (m_state.rt_view != rtv || m_state.dsv != dsv) const bool changed = (m_state.rt_view != rtv || m_state.dsv != dsv);
if (m_state.rt_view != rtv)
{ {
if (m_state.rt_view)
m_state.rt_view->Release();
if (rtv)
rtv->AddRef();
m_state.rt_view = rtv; m_state.rt_view = rtv;
m_state.rt_texture = static_cast<GSTexture11*>(rt);
m_state.dsv = dsv;
m_state.rt_ds = static_cast<GSTexture11*>(ds);
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
} }
if (m_state.dsv != dsv)
{
if (m_state.dsv)
m_state.dsv->Release();
if (dsv)
dsv->AddRef();
m_state.dsv = dsv;
}
if (changed)
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
const GSVector2i size = rt ? rt->GetSize() : ds->GetSize(); const GSVector2i size = rt ? rt->GetSize() : ds->GetSize();
if (m_state.viewport != size) if (m_state.viewport != size)

View File

@ -154,8 +154,6 @@ private:
ID3D11BlendState* bs; ID3D11BlendState* bs;
float bf; float bf;
ID3D11RenderTargetView* rt_view; ID3D11RenderTargetView* rt_view;
GSTexture11* rt_texture;
GSTexture11* rt_ds;
ID3D11DepthStencilView* dsv; ID3D11DepthStencilView* dsv;
} m_state; } m_state;
@ -228,7 +226,7 @@ private:
public: public:
GSDevice11(); GSDevice11();
virtual ~GSDevice11() {} ~GSDevice11() override;
__fi static GSDevice11* GetInstance() { return static_cast<GSDevice11*>(g_gs_device.get()); } __fi static GSDevice11* GetInstance() { return static_cast<GSDevice11*>(g_gs_device.get()); }
__fi ID3D11Device* GetD3DDevice() const { return m_dev.get(); } __fi ID3D11Device* GetD3DDevice() const { return m_dev.get(); }