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

[d3d8] Improve handling of failed d3d9 calls

This commit is contained in:
WinterSnowfall 2024-08-24 15:37:01 +03:00 committed by Philip Rebohle
parent f3fa4b102a
commit 9f8832dd14
9 changed files with 304 additions and 140 deletions

View File

@ -42,12 +42,16 @@ namespace dxvk {
} }
HRESULT STDMETHODCALLTYPE GetDesc(D3DVERTEXBUFFER_DESC* pDesc) { HRESULT STDMETHODCALLTYPE GetDesc(D3DVERTEXBUFFER_DESC* pDesc) {
if (unlikely(pDesc == nullptr))
return D3DERR_INVALIDCALL;
pDesc->Format = D3DFMT_VERTEXDATA; pDesc->Format = D3DFMT_VERTEXDATA;
pDesc->Type = D3DRTYPE_VERTEXBUFFER; pDesc->Type = D3DRTYPE_VERTEXBUFFER;
pDesc->Usage = m_usage; pDesc->Usage = m_usage;
pDesc->Pool = m_pool; pDesc->Pool = m_pool;
pDesc->Size = m_data.size(); pDesc->Size = m_data.size();
pDesc->FVF = m_fvf; pDesc->FVF = m_fvf;
return D3D_OK; return D3D_OK;
} }

View File

@ -41,9 +41,7 @@ namespace dxvk {
} }
protected: protected:
// This is the D3D8 pool, not necessarily what's given to D3D9.
const D3DPOOL m_pool; const D3DPOOL m_pool;
// This is the D3D8 usage, not necessarily what's given to D3D9.
const DWORD m_usage; const DWORD m_usage;
}; };
@ -64,12 +62,7 @@ namespace dxvk {
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_VERTEXBUFFER; } D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_VERTEXBUFFER; }
HRESULT STDMETHODCALLTYPE GetDesc(D3DVERTEXBUFFER_DESC* pDesc) { HRESULT STDMETHODCALLTYPE GetDesc(D3DVERTEXBUFFER_DESC* pDesc) {
HRESULT hr = GetD3D9()->GetDesc(reinterpret_cast<d3d9::D3DVERTEXBUFFER_DESC*>(pDesc)); return GetD3D9()->GetDesc(reinterpret_cast<d3d9::D3DVERTEXBUFFER_DESC*>(pDesc));
if (!FAILED(hr)) {
pDesc->Pool = m_pool;
pDesc->Usage = m_usage;
}
return hr;
} }
}; };
@ -90,12 +83,7 @@ namespace dxvk {
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_INDEXBUFFER; } D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_INDEXBUFFER; }
HRESULT STDMETHODCALLTYPE GetDesc(D3DINDEXBUFFER_DESC* pDesc) final { HRESULT STDMETHODCALLTYPE GetDesc(D3DINDEXBUFFER_DESC* pDesc) final {
HRESULT hr = GetD3D9()->GetDesc(reinterpret_cast<d3d9::D3DINDEXBUFFER_DESC*>(pDesc)); return GetD3D9()->GetDesc(reinterpret_cast<d3d9::D3DINDEXBUFFER_DESC*>(pDesc));
if (!FAILED(hr)) {
pDesc->Pool = m_pool;
pDesc->Usage = m_usage;
}
return hr;
} }
}; };

View File

@ -96,7 +96,7 @@ namespace dxvk {
DWORD MagicNumber; DWORD MagicNumber;
}; };
if(FAILED(res)) { if (FAILED(res)) {
if (DevInfoStructSize != sizeof(D3DDEVINFO_VCACHE)) if (DevInfoStructSize != sizeof(D3DDEVINFO_VCACHE))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
@ -170,7 +170,10 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::GetDeviceCaps(D3DCAPS8* pCaps) { HRESULT STDMETHODCALLTYPE D3D8Device::GetDeviceCaps(D3DCAPS8* pCaps) {
d3d9::D3DCAPS9 caps9; d3d9::D3DCAPS9 caps9;
HRESULT res = GetD3D9()->GetDeviceCaps(&caps9); HRESULT res = GetD3D9()->GetDeviceCaps(&caps9);
dxvk::ConvertCaps8(caps9, pCaps);
if (likely(SUCCEEDED(res)))
dxvk::ConvertCaps8(caps9, pCaps);
return res; return res;
} }
@ -207,6 +210,10 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::CreateAdditionalSwapChain( HRESULT STDMETHODCALLTYPE D3D8Device::CreateAdditionalSwapChain(
D3DPRESENT_PARAMETERS* pPresentationParameters, D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DSwapChain8** ppSwapChain) { IDirect3DSwapChain8** ppSwapChain) {
InitReturnPtr(ppSwapChain);
if (unlikely(pPresentationParameters == nullptr || ppSwapChain == nullptr))
return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DSwapChain9> pSwapChain9; Com<d3d9::IDirect3DSwapChain9> pSwapChain9;
d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters); d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters);
@ -214,26 +221,27 @@ namespace dxvk {
&params, &params,
&pSwapChain9 &pSwapChain9
); );
*ppSwapChain = ref(new D3D8SwapChain(this, std::move(pSwapChain9))); if (likely(SUCCEEDED(res)))
*ppSwapChain = ref(new D3D8SwapChain(this, std::move(pSwapChain9)));
return res; return res;
} }
HRESULT STDMETHODCALLTYPE D3D8Device::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) { HRESULT STDMETHODCALLTYPE D3D8Device::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) {
StateChange(); StateChange();
if (unlikely(pPresentationParameters == nullptr))
return D3DERR_INVALIDCALL;
m_presentParams = *pPresentationParameters; m_presentParams = *pPresentationParameters;
ResetState(); ResetState();
d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters); d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters);
HRESULT res = GetD3D9()->Reset(&params); HRESULT res = GetD3D9()->Reset(&params);
if (FAILED(res)) if (likely(SUCCEEDED(res)))
return res; RecreateBackBuffersAndAutoDepthStencil();
RecreateBackBuffersAndAutoDepthStencil();
return res; return res;
} }
@ -253,15 +261,18 @@ namespace dxvk {
D3DBACKBUFFER_TYPE Type, D3DBACKBUFFER_TYPE Type,
IDirect3DSurface8** ppBackBuffer) { IDirect3DSurface8** ppBackBuffer) {
InitReturnPtr(ppBackBuffer); InitReturnPtr(ppBackBuffer);
if (unlikely(ppBackBuffer == nullptr))
return D3DERR_INVALIDCALL;
if (iBackBuffer >= m_backBuffers.size() || m_backBuffers[iBackBuffer] == nullptr) { if (iBackBuffer >= m_backBuffers.size() || m_backBuffers[iBackBuffer] == nullptr) {
Com<d3d9::IDirect3DSurface9> pSurface9; Com<d3d9::IDirect3DSurface9> pSurface9;
HRESULT res = GetD3D9()->GetBackBuffer(0, iBackBuffer, (d3d9::D3DBACKBUFFER_TYPE)Type, &pSurface9); HRESULT res = GetD3D9()->GetBackBuffer(0, iBackBuffer, (d3d9::D3DBACKBUFFER_TYPE)Type, &pSurface9);
if (FAILED(res)) return res; if (likely(SUCCEEDED(res))) {
m_backBuffers[iBackBuffer] = new D3D8Surface(this, std::move(pSurface9));
m_backBuffers[iBackBuffer] = new D3D8Surface(this, std::move(pSurface9)); *ppBackBuffer = m_backBuffers[iBackBuffer].ref();
*ppBackBuffer = m_backBuffers[iBackBuffer].ref(); }
return res; return res;
} }
@ -271,7 +282,7 @@ namespace dxvk {
} }
HRESULT STDMETHODCALLTYPE D3D8Device::GetRasterStatus(D3DRASTER_STATUS* pRasterStatus) { HRESULT STDMETHODCALLTYPE D3D8Device::GetRasterStatus(D3DRASTER_STATUS* pRasterStatus) {
return GetD3D9()->GetRasterStatus(0, (d3d9::D3DRASTER_STATUS*)pRasterStatus); return GetD3D9()->GetRasterStatus(0, reinterpret_cast<d3d9::D3DRASTER_STATUS*>(pRasterStatus));
} }
void STDMETHODCALLTYPE D3D8Device::SetGammaRamp(DWORD Flags, const D3DGAMMARAMP* pRamp) { void STDMETHODCALLTYPE D3D8Device::SetGammaRamp(DWORD Flags, const D3DGAMMARAMP* pRamp) {
@ -295,6 +306,9 @@ namespace dxvk {
IDirect3DTexture8** ppTexture) { IDirect3DTexture8** ppTexture) {
InitReturnPtr(ppTexture); InitReturnPtr(ppTexture);
if (unlikely(ppTexture == nullptr))
return D3DERR_INVALIDCALL;
// Nvidia & Intel workaround for The Lord of the Rings: The Fellowship of the Ring // Nvidia & Intel workaround for The Lord of the Rings: The Fellowship of the Ring
if (m_d3d8Options.placeP8InScratch && Format == D3DFMT_P8) if (m_d3d8Options.placeP8InScratch && Format == D3DFMT_P8)
Pool = D3DPOOL_SCRATCH; Pool = D3DPOOL_SCRATCH;
@ -310,10 +324,8 @@ namespace dxvk {
&pTex9, &pTex9,
NULL); NULL);
if (FAILED(res)) if (likely(SUCCEEDED(res)))
return res; *ppTexture = ref(new D3D8Texture2D(this, std::move(pTex9)));
*ppTexture = ref(new D3D8Texture2D(this, std::move(pTex9)));
return res; return res;
} }
@ -327,6 +339,11 @@ namespace dxvk {
D3DFORMAT Format, D3DFORMAT Format,
D3DPOOL Pool, D3DPOOL Pool,
IDirect3DVolumeTexture8** ppVolumeTexture) { IDirect3DVolumeTexture8** ppVolumeTexture) {
InitReturnPtr(ppVolumeTexture);
if (unlikely(ppVolumeTexture == nullptr))
return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DVolumeTexture9> pVolume9 = nullptr; Com<d3d9::IDirect3DVolumeTexture9> pVolume9 = nullptr;
HRESULT res = GetD3D9()->CreateVolumeTexture( HRESULT res = GetD3D9()->CreateVolumeTexture(
Width, Height, Depth, Levels, Width, Height, Depth, Levels,
@ -336,10 +353,10 @@ namespace dxvk {
&pVolume9, &pVolume9,
NULL); NULL);
*ppVolumeTexture = ref(new D3D8Texture3D(this, std::move(pVolume9))); if (likely(SUCCEEDED(res)))
*ppVolumeTexture = ref(new D3D8Texture3D(this, std::move(pVolume9)));
return res; return res;
} }
HRESULT STDMETHODCALLTYPE D3D8Device::CreateCubeTexture( HRESULT STDMETHODCALLTYPE D3D8Device::CreateCubeTexture(
@ -349,6 +366,11 @@ namespace dxvk {
D3DFORMAT Format, D3DFORMAT Format,
D3DPOOL Pool, D3DPOOL Pool,
IDirect3DCubeTexture8** ppCubeTexture) { IDirect3DCubeTexture8** ppCubeTexture) {
InitReturnPtr(ppCubeTexture);
if (unlikely(ppCubeTexture == nullptr))
return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DCubeTexture9> pCube9 = nullptr; Com<d3d9::IDirect3DCubeTexture9> pCube9 = nullptr;
HRESULT res = GetD3D9()->CreateCubeTexture( HRESULT res = GetD3D9()->CreateCubeTexture(
EdgeLength, EdgeLength,
@ -359,7 +381,8 @@ namespace dxvk {
&pCube9, &pCube9,
NULL); NULL);
*ppCubeTexture = ref(new D3D8TextureCube(this, std::move(pCube9))); if (likely(SUCCEEDED(res)))
*ppCubeTexture = ref(new D3D8TextureCube(this, std::move(pCube9)));
return res; return res;
} }
@ -372,16 +395,18 @@ namespace dxvk {
IDirect3DVertexBuffer8** ppVertexBuffer) { IDirect3DVertexBuffer8** ppVertexBuffer) {
InitReturnPtr(ppVertexBuffer); InitReturnPtr(ppVertexBuffer);
if (unlikely(ppVertexBuffer == nullptr))
return D3DERR_INVALIDCALL;
if (ShouldBatch()) { if (ShouldBatch()) {
*ppVertexBuffer = m_batcher->CreateVertexBuffer(Length, Usage, FVF, Pool); *ppVertexBuffer = m_batcher->CreateVertexBuffer(Length, Usage, FVF, Pool);
return D3D_OK; return D3D_OK;
} }
Com<d3d9::IDirect3DVertexBuffer9> pVertexBuffer9 = nullptr; Com<d3d9::IDirect3DVertexBuffer9> pVertexBuffer9 = nullptr;
HRESULT res = GetD3D9()->CreateVertexBuffer(Length, Usage, FVF, d3d9::D3DPOOL(Pool), &pVertexBuffer9, NULL); HRESULT res = GetD3D9()->CreateVertexBuffer(Length, Usage, FVF, d3d9::D3DPOOL(Pool), &pVertexBuffer9, NULL);
if (!FAILED(res)) if (likely(SUCCEEDED(res)))
*ppVertexBuffer = ref(new D3D8VertexBuffer(this, std::move(pVertexBuffer9), Pool, Usage)); *ppVertexBuffer = ref(new D3D8VertexBuffer(this, std::move(pVertexBuffer9), Pool, Usage));
return res; return res;
@ -394,11 +419,14 @@ namespace dxvk {
D3DPOOL Pool, D3DPOOL Pool,
IDirect3DIndexBuffer8** ppIndexBuffer) { IDirect3DIndexBuffer8** ppIndexBuffer) {
InitReturnPtr(ppIndexBuffer); InitReturnPtr(ppIndexBuffer);
if (unlikely(ppIndexBuffer == nullptr))
return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DIndexBuffer9> pIndexBuffer9 = nullptr; Com<d3d9::IDirect3DIndexBuffer9> pIndexBuffer9 = nullptr;
HRESULT res = GetD3D9()->CreateIndexBuffer(Length, Usage, d3d9::D3DFORMAT(Format), d3d9::D3DPOOL(Pool), &pIndexBuffer9, NULL); HRESULT res = GetD3D9()->CreateIndexBuffer(Length, Usage, d3d9::D3DFORMAT(Format), d3d9::D3DPOOL(Pool), &pIndexBuffer9, NULL);
if (!FAILED(res)) if (likely(SUCCEEDED(res)))
*ppIndexBuffer = ref(new D3D8IndexBuffer(this, std::move(pIndexBuffer9), Pool, Usage)); *ppIndexBuffer = ref(new D3D8IndexBuffer(this, std::move(pIndexBuffer9), Pool, Usage));
return res; return res;
@ -411,6 +439,11 @@ namespace dxvk {
D3DMULTISAMPLE_TYPE MultiSample, D3DMULTISAMPLE_TYPE MultiSample,
BOOL Lockable, BOOL Lockable,
IDirect3DSurface8** ppSurface) { IDirect3DSurface8** ppSurface) {
InitReturnPtr(ppSurface);
if (unlikely(ppSurface == nullptr))
return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DSurface9> pSurf9 = nullptr; Com<d3d9::IDirect3DSurface9> pSurf9 = nullptr;
HRESULT res = GetD3D9()->CreateRenderTarget( HRESULT res = GetD3D9()->CreateRenderTarget(
Width, Width,
@ -422,7 +455,8 @@ namespace dxvk {
&pSurf9, &pSurf9,
NULL); NULL);
*ppSurface = ref(new D3D8Surface(this, std::move(pSurf9))); if (likely(SUCCEEDED(res)))
*ppSurface = ref(new D3D8Surface(this, std::move(pSurf9)));
return res; return res;
} }
@ -433,6 +467,11 @@ namespace dxvk {
D3DFORMAT Format, D3DFORMAT Format,
D3DMULTISAMPLE_TYPE MultiSample, D3DMULTISAMPLE_TYPE MultiSample,
IDirect3DSurface8** ppSurface) { IDirect3DSurface8** ppSurface) {
InitReturnPtr(ppSurface);
if (unlikely(ppSurface == nullptr))
return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DSurface9> pSurf9 = nullptr; Com<d3d9::IDirect3DSurface9> pSurf9 = nullptr;
HRESULT res = GetD3D9()->CreateDepthStencilSurface( HRESULT res = GetD3D9()->CreateDepthStencilSurface(
Width, Width,
@ -444,7 +483,8 @@ namespace dxvk {
&pSurf9, &pSurf9,
NULL); NULL);
*ppSurface = ref(new D3D8Surface(this, std::move(pSurf9))); if (likely(SUCCEEDED(res)))
*ppSurface = ref(new D3D8Surface(this, std::move(pSurf9)));
return res; return res;
} }
@ -454,6 +494,11 @@ namespace dxvk {
UINT Height, UINT Height,
D3DFORMAT Format, D3DFORMAT Format,
IDirect3DSurface8** ppSurface) { IDirect3DSurface8** ppSurface) {
InitReturnPtr(ppSurface);
if (unlikely(ppSurface == nullptr))
return D3DERR_INVALIDCALL;
// FIXME: Handle D3DPOOL_SCRATCH in CopyRects // FIXME: Handle D3DPOOL_SCRATCH in CopyRects
D3DPOOL pool = isUnsupportedSurfaceFormat(Format) ? D3DPOOL_SCRATCH : D3DPOOL_SYSTEMMEM; D3DPOOL pool = isUnsupportedSurfaceFormat(Format) ? D3DPOOL_SCRATCH : D3DPOOL_SYSTEMMEM;
@ -466,7 +511,8 @@ namespace dxvk {
&pSurf, &pSurf,
NULL); NULL);
*ppSurface = ref(new D3D8Surface(this, std::move(pSurf))); if (likely(SUCCEEDED(res)))
*ppSurface = ref(new D3D8Surface(this, std::move(pSurf)));
return res; return res;
} }
@ -577,11 +623,14 @@ namespace dxvk {
UINT cRects, UINT cRects,
IDirect3DSurface8* pDestinationSurface, IDirect3DSurface8* pDestinationSurface,
const POINT* pDestPointsArray) { const POINT* pDestPointsArray) {
if (pSourceSurface == NULL || pDestinationSurface == NULL) { // The source and destination surfaces can not be identical.
if (unlikely(pSourceSurface == nullptr ||
pDestinationSurface == nullptr ||
pSourceSurface == pDestinationSurface)) {
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
// TODO: No format conversion, no stretching, no clipping. // TODO: No stretching or clipping of either source or destination rectangles.
// All src/dest rectangles must fit within the dest surface. // All src/dest rectangles must fit within the dest surface.
Com<D3D8Surface> src = static_cast<D3D8Surface*>(pSourceSurface); Com<D3D8Surface> src = static_cast<D3D8Surface*>(pSourceSurface);
@ -591,6 +640,10 @@ namespace dxvk {
src->GetD3D9()->GetDesc(&srcDesc); src->GetD3D9()->GetDesc(&srcDesc);
dst->GetD3D9()->GetDesc(&dstDesc); dst->GetD3D9()->GetDesc(&dstDesc);
// This method does not support format conversion.
if (unlikely(srcDesc.Format != dstDesc.Format))
return D3DERR_INVALIDCALL;
// This method cannot be applied to surfaces whose formats // This method cannot be applied to surfaces whose formats
// are classified as depth stencil formats. // are classified as depth stencil formats.
if (unlikely(isDepthStencilFormat(D3DFORMAT(srcDesc.Format)) || if (unlikely(isDepthStencilFormat(D3DFORMAT(srcDesc.Format)) ||
@ -807,6 +860,9 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::UpdateTexture( HRESULT STDMETHODCALLTYPE D3D8Device::UpdateTexture(
IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pSourceTexture,
IDirect3DBaseTexture8* pDestinationTexture) { IDirect3DBaseTexture8* pDestinationTexture) {
if (unlikely(pSourceTexture == nullptr || pDestinationTexture == nullptr))
return D3DERR_INVALIDCALL;
D3D8Texture2D* src = static_cast<D3D8Texture2D*>(pSourceTexture); D3D8Texture2D* src = static_cast<D3D8Texture2D*>(pSourceTexture);
D3D8Texture2D* dst = static_cast<D3D8Texture2D*>(pDestinationTexture); D3D8Texture2D* dst = static_cast<D3D8Texture2D*>(pDestinationTexture);
@ -828,14 +884,14 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::SetRenderTarget(IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) { HRESULT STDMETHODCALLTYPE D3D8Device::SetRenderTarget(IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) {
HRESULT res; HRESULT res;
if (pRenderTarget != NULL) { if (pRenderTarget != nullptr) {
D3D8Surface* surf = static_cast<D3D8Surface*>(pRenderTarget); D3D8Surface* surf = static_cast<D3D8Surface*>(pRenderTarget);
if(likely(m_renderTarget.ptr() != surf)) { if (likely(m_renderTarget.ptr() != surf)) {
StateChange(); StateChange();
res = GetD3D9()->SetRenderTarget(0, surf->GetD3D9()); res = GetD3D9()->SetRenderTarget(0, surf->GetD3D9());
if (FAILED(res)) return res; if (unlikely(FAILED(res))) return res;
if (likely(m_renderTarget != surf)) if (likely(m_renderTarget != surf))
m_renderTarget = surf; m_renderTarget = surf;
@ -845,14 +901,14 @@ namespace dxvk {
// SetDepthStencilSurface is a separate call // SetDepthStencilSurface is a separate call
D3D8Surface* zStencil = static_cast<D3D8Surface*>(pNewZStencil); D3D8Surface* zStencil = static_cast<D3D8Surface*>(pNewZStencil);
if(likely(m_depthStencil.ptr() != zStencil)) { if (likely(m_depthStencil.ptr() != zStencil)) {
StateChange(); StateChange();
res = GetD3D9()->SetDepthStencilSurface(D3D8Surface::GetD3D9Nullable(zStencil)); res = GetD3D9()->SetDepthStencilSurface(D3D8Surface::GetD3D9Nullable(zStencil));
if (FAILED(res)) return res; if (unlikely(FAILED(res))) return res;
if (likely(m_depthStencil != zStencil)) if (likely(m_depthStencil != zStencil))
m_depthStencil = zStencil; m_depthStencil = zStencil;
} }
return D3D_OK; return D3D_OK;
@ -861,15 +917,18 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::GetRenderTarget(IDirect3DSurface8** ppRenderTarget) { HRESULT STDMETHODCALLTYPE D3D8Device::GetRenderTarget(IDirect3DSurface8** ppRenderTarget) {
InitReturnPtr(ppRenderTarget); InitReturnPtr(ppRenderTarget);
if (unlikely(ppRenderTarget == nullptr))
return D3DERR_INVALIDCALL;
if (unlikely(m_renderTarget == nullptr)) { if (unlikely(m_renderTarget == nullptr)) {
Com<d3d9::IDirect3DSurface9> pRT9 = nullptr; Com<d3d9::IDirect3DSurface9> pRT9 = nullptr;
HRESULT res = GetD3D9()->GetRenderTarget(0, &pRT9); // use RT index 0 HRESULT res = GetD3D9()->GetRenderTarget(0, &pRT9); // use RT index 0
if(FAILED(res)) return res; if (likely(SUCCEEDED(res))) {
m_renderTarget = new D3D8Surface(this, std::move(pRT9));
*ppRenderTarget = m_renderTarget.ref();
}
m_renderTarget = new D3D8Surface(this, std::move(pRT9));
*ppRenderTarget = m_renderTarget.ref();
return res; return res;
} }
@ -879,16 +938,19 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::GetDepthStencilSurface(IDirect3DSurface8** ppZStencilSurface) { HRESULT STDMETHODCALLTYPE D3D8Device::GetDepthStencilSurface(IDirect3DSurface8** ppZStencilSurface) {
InitReturnPtr(ppZStencilSurface); InitReturnPtr(ppZStencilSurface);
if (unlikely(ppZStencilSurface == nullptr))
return D3DERR_INVALIDCALL;
if (unlikely(m_depthStencil == nullptr)) { if (unlikely(m_depthStencil == nullptr)) {
Com<d3d9::IDirect3DSurface9> pStencil9 = nullptr; Com<d3d9::IDirect3DSurface9> pStencil9 = nullptr;
HRESULT res = GetD3D9()->GetDepthStencilSurface(&pStencil9); HRESULT res = GetD3D9()->GetDepthStencilSurface(&pStencil9);
if(FAILED(res)) return res; if (likely(SUCCEEDED(res))) {
m_depthStencil = new D3D8Surface(this, std::move(pStencil9));
*ppZStencilSurface = m_depthStencil.ref();
}
m_depthStencil = new D3D8Surface(this, std::move(pStencil9));
*ppZStencilSurface = m_depthStencil.ref();
return res; return res;
} }
@ -929,7 +991,7 @@ namespace dxvk {
if (likely(pViewport != nullptr)) { if (likely(pViewport != nullptr)) {
// we need a valid render target to validate the viewport // we need a valid render target to validate the viewport
if (unlikely(m_renderTarget == nullptr)) if (unlikely(m_renderTarget == nullptr))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
D3DSURFACE_DESC rtDesc; D3DSURFACE_DESC rtDesc;
HRESULT res = m_renderTarget->GetDesc(&rtDesc); HRESULT res = m_renderTarget->GetDesc(&rtDesc);
@ -989,14 +1051,19 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::CreateStateBlock( HRESULT STDMETHODCALLTYPE D3D8Device::CreateStateBlock(
D3DSTATEBLOCKTYPE Type, D3DSTATEBLOCKTYPE Type,
DWORD* pToken) { DWORD* pToken) {
if (unlikely(pToken == nullptr))
return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DStateBlock9> pStateBlock9; Com<d3d9::IDirect3DStateBlock9> pStateBlock9;
HRESULT res = GetD3D9()->CreateStateBlock(d3d9::D3DSTATEBLOCKTYPE(Type), &pStateBlock9); HRESULT res = GetD3D9()->CreateStateBlock(d3d9::D3DSTATEBLOCKTYPE(Type), &pStateBlock9);
m_token++; if (likely(SUCCEEDED(res))) {
m_stateBlocks.emplace(std::piecewise_construct, m_token++;
std::forward_as_tuple(m_token), m_stateBlocks.emplace(std::piecewise_construct,
std::forward_as_tuple(this, Type, pStateBlock9.ref())); std::forward_as_tuple(m_token),
*pToken = m_token; std::forward_as_tuple(this, Type, pStateBlock9.ref()));
*pToken = m_token;
}
return res; return res;
} }
@ -1052,14 +1119,18 @@ namespace dxvk {
if (unlikely(m_recorder != nullptr)) if (unlikely(m_recorder != nullptr))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
m_token++; HRESULT res = GetD3D9()->BeginStateBlock();
auto stateBlockIterPair = m_stateBlocks.emplace(std::piecewise_construct,
std::forward_as_tuple(m_token),
std::forward_as_tuple(this));
m_recorder = &stateBlockIterPair.first->second;
m_recorderToken = m_token;
return GetD3D9()->BeginStateBlock(); if (likely(SUCCEEDED(res))) {
m_token++;
auto stateBlockIterPair = m_stateBlocks.emplace(std::piecewise_construct,
std::forward_as_tuple(m_token),
std::forward_as_tuple(this));
m_recorder = &stateBlockIterPair.first->second;
m_recorderToken = m_token;
}
return res;
} }
HRESULT STDMETHODCALLTYPE D3D8Device::EndStateBlock(DWORD* pToken) { HRESULT STDMETHODCALLTYPE D3D8Device::EndStateBlock(DWORD* pToken) {
@ -1069,12 +1140,14 @@ namespace dxvk {
Com<d3d9::IDirect3DStateBlock9> pStateBlock; Com<d3d9::IDirect3DStateBlock9> pStateBlock;
HRESULT res = GetD3D9()->EndStateBlock(&pStateBlock); HRESULT res = GetD3D9()->EndStateBlock(&pStateBlock);
m_recorder->SetD3D9(std::move(pStateBlock)); if (likely(SUCCEEDED(res))) {
m_recorder->SetD3D9(std::move(pStateBlock));
*pToken = m_recorderToken; *pToken = m_recorderToken;
m_recorder = nullptr; m_recorder = nullptr;
m_recorderToken = 0; m_recorderToken = 0;
}
return res; return res;
} }
@ -1091,6 +1164,9 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::GetTexture(DWORD Stage, IDirect3DBaseTexture8** ppTexture) { HRESULT STDMETHODCALLTYPE D3D8Device::GetTexture(DWORD Stage, IDirect3DBaseTexture8** ppTexture) {
InitReturnPtr(ppTexture); InitReturnPtr(ppTexture);
if (unlikely(ppTexture == nullptr))
return D3DERR_INVALIDCALL;
*ppTexture = m_textures[Stage].ref(); *ppTexture = m_textures[Stage].ref();
return D3D_OK; return D3D_OK;
@ -1105,14 +1181,16 @@ namespace dxvk {
D3D8Texture2D* tex = static_cast<D3D8Texture2D*>(pTexture); D3D8Texture2D* tex = static_cast<D3D8Texture2D*>(pTexture);
if(unlikely(m_textures[Stage].ptr() == tex)) if (unlikely(m_textures[Stage].ptr() == tex))
return D3D_OK; return D3D_OK;
StateChange(); StateChange();
HRESULT res = GetD3D9()->SetTexture(Stage, D3D8Texture2D::GetD3D9Nullable(tex));
m_textures[Stage] = tex; if (likely(SUCCEEDED(res)))
m_textures[Stage] = tex;
return GetD3D9()->SetTexture(Stage, D3D8Texture2D::GetD3D9Nullable(tex)); return res;
} }
HRESULT STDMETHODCALLTYPE D3D8Device::GetTextureStageState( HRESULT STDMETHODCALLTYPE D3D8Device::GetTextureStageState(
@ -1237,14 +1315,12 @@ namespace dxvk {
UINT VertexCount, UINT VertexCount,
IDirect3DVertexBuffer8* pDestBuffer, IDirect3DVertexBuffer8* pDestBuffer,
DWORD Flags) { DWORD Flags) {
if (unlikely(!pDestBuffer))
return D3DERR_INVALIDCALL;
D3D8VertexBuffer* buffer = static_cast<D3D8VertexBuffer*>(pDestBuffer); D3D8VertexBuffer* buffer = static_cast<D3D8VertexBuffer*>(pDestBuffer);
return GetD3D9()->ProcessVertices( return GetD3D9()->ProcessVertices(
SrcStartIndex, SrcStartIndex,
DestIndex, DestIndex,
VertexCount, VertexCount,
buffer->GetD3D9(), D3D8VertexBuffer::GetD3D9Nullable(buffer),
nullptr, nullptr,
Flags Flags
); );
@ -1271,14 +1347,16 @@ namespace dxvk {
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
D3D8VertexBuffer* buffer = static_cast<D3D8VertexBuffer*>(pStreamData); D3D8VertexBuffer* buffer = static_cast<D3D8VertexBuffer*>(pStreamData);
HRESULT res = GetD3D9()->SetStreamSource(StreamNumber, D3D8VertexBuffer::GetD3D9Nullable(buffer), 0, Stride);
if (ShouldBatch()) if (likely(SUCCEEDED(res))) {
m_batcher->SetStream(StreamNumber, buffer, Stride); if (ShouldBatch())
m_batcher->SetStream(StreamNumber, buffer, Stride);
m_streams[StreamNumber] = D3D8VBO {buffer, Stride}; m_streams[StreamNumber] = D3D8VBO {buffer, Stride};
}
// DXVK: Never fails return res;
return GetD3D9()->SetStreamSource(StreamNumber, D3D8VertexBuffer::GetD3D9Nullable(buffer), 0, Stride);
} }
HRESULT STDMETHODCALLTYPE D3D8Device::GetStreamSource( HRESULT STDMETHODCALLTYPE D3D8Device::GetStreamSource(
@ -1315,14 +1393,16 @@ namespace dxvk {
m_baseVertexIndex = BaseVertexIndex; m_baseVertexIndex = BaseVertexIndex;
D3D8IndexBuffer* buffer = static_cast<D3D8IndexBuffer*>(pIndexData); D3D8IndexBuffer* buffer = static_cast<D3D8IndexBuffer*>(pIndexData);
HRESULT res = GetD3D9()->SetIndices(D3D8IndexBuffer::GetD3D9Nullable(buffer));
if (ShouldBatch()) if (likely(SUCCEEDED(res))) {
m_batcher->SetIndices(buffer, m_baseVertexIndex); if (ShouldBatch())
m_batcher->SetIndices(buffer, m_baseVertexIndex);
m_indices = buffer; m_indices = buffer;
}
// DXVK: Never fails return res;
return GetD3D9()->SetIndices(D3D8IndexBuffer::GetD3D9Nullable(buffer));
} }
HRESULT STDMETHODCALLTYPE D3D8Device::GetIndices( HRESULT STDMETHODCALLTYPE D3D8Device::GetIndices(
@ -1330,6 +1410,9 @@ namespace dxvk {
UINT* pBaseVertexIndex) { UINT* pBaseVertexIndex) {
InitReturnPtr(ppIndexData); InitReturnPtr(ppIndexData);
if (unlikely(ppIndexData == nullptr || pBaseVertexIndex == nullptr))
return D3DERR_INVALIDCALL;
*ppIndexData = m_indices.ref(); *ppIndexData = m_indices.ref();
*pBaseVertexIndex = m_baseVertexIndex; *pBaseVertexIndex = m_baseVertexIndex;
@ -1367,7 +1450,6 @@ namespace dxvk {
return GetD3D9()->DeletePatch(Handle); return GetD3D9()->DeletePatch(Handle);
} }
// Render States // // Render States //
// ZBIAS can be an integer from 0 to 1 and needs to be remapped to float // ZBIAS can be an integer from 0 to 1 and needs to be remapped to float
@ -1429,10 +1511,14 @@ namespace dxvk {
StateChange(); StateChange();
} }
// This call will never fail
return GetD3D9()->SetRenderState(State9, Value); return GetD3D9()->SetRenderState(State9, Value);
} }
HRESULT STDMETHODCALLTYPE D3D8Device::GetRenderState(D3DRENDERSTATETYPE State, DWORD* pValue) { HRESULT STDMETHODCALLTYPE D3D8Device::GetRenderState(D3DRENDERSTATETYPE State, DWORD* pValue) {
if (unlikely(pValue == nullptr))
return D3DERR_INVALIDCALL;
d3d9::D3DRENDERSTATETYPE State9 = (d3d9::D3DRENDERSTATETYPE)State; d3d9::D3DRENDERSTATETYPE State9 = (d3d9::D3DRENDERSTATETYPE)State;
switch (State) { switch (State) {
@ -1467,6 +1553,7 @@ namespace dxvk {
break; break;
} }
// This call will never fail
return GetD3D9()->GetRenderState(State9, pValue); return GetD3D9()->GetRenderState(State9, pValue);
} }
@ -1477,6 +1564,9 @@ namespace dxvk {
const DWORD* pFunction, const DWORD* pFunction,
DWORD* pHandle, DWORD* pHandle,
DWORD Usage ) { DWORD Usage ) {
if (unlikely(pDeclaration == nullptr || pHandle == nullptr))
return D3DERR_INVALIDCALL;
D3D8VertexShaderInfo& info = m_vertexShaders.emplace_back(); D3D8VertexShaderInfo& info = m_vertexShaders.emplace_back();
// Store D3D8 bytecodes in the shader info // Store D3D8 bytecodes in the shader info
@ -1492,7 +1582,7 @@ namespace dxvk {
// Create vertex declaration // Create vertex declaration
HRESULT res = GetD3D9()->CreateVertexDeclaration(result.declaration, &(info.pVertexDecl)); HRESULT res = GetD3D9()->CreateVertexDeclaration(result.declaration, &(info.pVertexDecl));
if (FAILED(res)) if (unlikely(FAILED(res)))
return res; return res;
if (pFunction != nullptr) { if (pFunction != nullptr) {
@ -1502,8 +1592,10 @@ namespace dxvk {
info.pVertexShader = nullptr; info.pVertexShader = nullptr;
} }
// Set bit to indicate this is not an FVF if (likely(SUCCEEDED(res))) {
*pHandle = getShaderHandle(m_vertexShaders.size() - 1); // Set bit to indicate this is not an FVF
*pHandle = getShaderHandle(m_vertexShaders.size() - 1);
}
return res; return res;
} }
@ -1527,7 +1619,9 @@ namespace dxvk {
return &info; return &info;
} }
HRESULT STDMETHODCALLTYPE D3D8Device::SetVertexShader( DWORD Handle ) { HRESULT STDMETHODCALLTYPE D3D8Device::SetVertexShader(DWORD Handle) {
HRESULT res;
if (unlikely(ShouldRecord())) { if (unlikely(ShouldRecord())) {
return m_recorder->SetVertexShader(Handle); return m_recorder->SetVertexShader(Handle);
} }
@ -1542,26 +1636,38 @@ namespace dxvk {
StateChange(); StateChange();
// Cache current shader
m_currentVertexShader = Handle;
GetD3D9()->SetVertexDeclaration(info->pVertexDecl); GetD3D9()->SetVertexDeclaration(info->pVertexDecl);
return GetD3D9()->SetVertexShader(info->pVertexShader); res = GetD3D9()->SetVertexShader(info->pVertexShader);
if (likely(SUCCEEDED(res))) {
// Cache current shader
m_currentVertexShader = Handle;
}
return res;
} else if (m_currentVertexShader != Handle) { } else if (m_currentVertexShader != Handle) {
StateChange(); StateChange();
// Cache current FVF
m_currentVertexShader = Handle;
//GetD3D9()->SetVertexDeclaration(nullptr); //GetD3D9()->SetVertexDeclaration(nullptr);
GetD3D9()->SetVertexShader(nullptr); GetD3D9()->SetVertexShader(nullptr);
return GetD3D9()->SetFVF( Handle ); res = GetD3D9()->SetFVF(Handle);
if (likely(SUCCEEDED(res))) {
// Cache current FVF
m_currentVertexShader = Handle;
}
return res;
} }
return D3D_OK; return D3D_OK;
} }
HRESULT STDMETHODCALLTYPE D3D8Device::GetVertexShader(DWORD* pHandle) { HRESULT STDMETHODCALLTYPE D3D8Device::GetVertexShader(DWORD* pHandle) {
if (unlikely(pHandle == nullptr))
return D3DERR_INVALIDCALL;
// Return cached shader // Return cached shader
*pHandle = m_currentVertexShader; *pHandle = m_currentVertexShader;
@ -1667,14 +1773,18 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::CreatePixelShader( HRESULT STDMETHODCALLTYPE D3D8Device::CreatePixelShader(
const DWORD* pFunction, const DWORD* pFunction,
DWORD* pHandle) { DWORD* pHandle) {
if (unlikely(pFunction == nullptr || pHandle == nullptr))
return D3DERR_INVALIDCALL;
d3d9::IDirect3DPixelShader9* pPixelShader; d3d9::IDirect3DPixelShader9* pPixelShader;
HRESULT res = GetD3D9()->CreatePixelShader(pFunction, &pPixelShader); HRESULT res = GetD3D9()->CreatePixelShader(pFunction, &pPixelShader);
m_pixelShaders.push_back(pPixelShader); if (likely(SUCCEEDED(res))) {
m_pixelShaders.push_back(pPixelShader);
// Still set the shader bit, to prevent conflicts with NULL. // Still set the shader bit, to prevent conflicts with NULL.
*pHandle = getShaderHandle(m_pixelShaders.size() - 1); *pHandle = getShaderHandle(m_pixelShaders.size() - 1);
}
return res; return res;
} }
@ -1715,14 +1825,20 @@ namespace dxvk {
} }
StateChange(); StateChange();
HRESULT res = GetD3D9()->SetPixelShader(pPixelShader);
// Cache current pixel shader if (likely(SUCCEEDED(res))) {
m_currentPixelShader = Handle; // Cache current pixel shader
m_currentPixelShader = Handle;
}
return GetD3D9()->SetPixelShader(pPixelShader); return res;
} }
HRESULT STDMETHODCALLTYPE D3D8Device::GetPixelShader(DWORD* pHandle) { HRESULT STDMETHODCALLTYPE D3D8Device::GetPixelShader(DWORD* pHandle) {
if (unlikely(pHandle == nullptr))
return D3DERR_INVALIDCALL;
// Return cached shader // Return cached shader
*pHandle = m_currentPixelShader; *pHandle = m_currentPixelShader;

View File

@ -61,6 +61,9 @@ namespace dxvk
UINT Adapter, UINT Adapter,
DWORD Flags, DWORD Flags,
D3DADAPTER_IDENTIFIER8* pIdentifier) { D3DADAPTER_IDENTIFIER8* pIdentifier) {
if (unlikely(pIdentifier == nullptr))
return D3DERR_INVALIDCALL;
// This flag now has the opposite effect. // This flag now has the opposite effect.
// Either way, WHQLevel will be 1 with Direct3D9Ex // Either way, WHQLevel will be 1 with Direct3D9Ex
if (Flags & D3DENUM_NO_WHQL_LEVEL) if (Flags & D3DENUM_NO_WHQL_LEVEL)
@ -71,17 +74,19 @@ namespace dxvk
d3d9::D3DADAPTER_IDENTIFIER9 identifier9; d3d9::D3DADAPTER_IDENTIFIER9 identifier9;
HRESULT res = m_d3d9->GetAdapterIdentifier(Adapter, Flags, &identifier9); HRESULT res = m_d3d9->GetAdapterIdentifier(Adapter, Flags, &identifier9);
strncpy(pIdentifier->Driver, identifier9.Driver, MAX_DEVICE_IDENTIFIER_STRING); if (likely(SUCCEEDED(res))) {
strncpy(pIdentifier->Description, identifier9.Description, MAX_DEVICE_IDENTIFIER_STRING); strncpy(pIdentifier->Driver, identifier9.Driver, MAX_DEVICE_IDENTIFIER_STRING);
strncpy(pIdentifier->Description, identifier9.Description, MAX_DEVICE_IDENTIFIER_STRING);
pIdentifier->DriverVersion = identifier9.DriverVersion; pIdentifier->DriverVersion = identifier9.DriverVersion;
pIdentifier->VendorId = identifier9.VendorId; pIdentifier->VendorId = identifier9.VendorId;
pIdentifier->DeviceId = identifier9.DeviceId; pIdentifier->DeviceId = identifier9.DeviceId;
pIdentifier->SubSysId = identifier9.SubSysId; pIdentifier->SubSysId = identifier9.SubSysId;
pIdentifier->Revision = identifier9.Revision; pIdentifier->Revision = identifier9.Revision;
pIdentifier->DeviceIdentifier = identifier9.DeviceIdentifier; pIdentifier->DeviceIdentifier = identifier9.DeviceIdentifier;
pIdentifier->WHQLLevel = identifier9.WHQLLevel; pIdentifier->WHQLLevel = identifier9.WHQLLevel;
}
return res; return res;
} }
@ -98,6 +103,7 @@ namespace dxvk
pMode->Height = m_adapterModes[Adapter][Mode].Height; pMode->Height = m_adapterModes[Adapter][Mode].Height;
pMode->RefreshRate = m_adapterModes[Adapter][Mode].RefreshRate; pMode->RefreshRate = m_adapterModes[Adapter][Mode].RefreshRate;
pMode->Format = D3DFORMAT(m_adapterModes[Adapter][Mode].Format); pMode->Format = D3DFORMAT(m_adapterModes[Adapter][Mode].Format);
return D3D_OK; return D3D_OK;
} }
@ -108,6 +114,12 @@ namespace dxvk
DWORD BehaviorFlags, DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS* pPresentationParameters, D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice8** ppReturnedDeviceInterface) { IDirect3DDevice8** ppReturnedDeviceInterface) {
InitReturnPtr(ppReturnedDeviceInterface);
if (unlikely(pPresentationParameters == nullptr ||
ppReturnedDeviceInterface == nullptr))
return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DDevice9> pDevice9 = nullptr; Com<d3d9::IDirect3DDevice9> pDevice9 = nullptr;
d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters); d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters);
HRESULT res = m_d3d9->CreateDevice( HRESULT res = m_d3d9->CreateDevice(
@ -119,18 +131,14 @@ namespace dxvk
&pDevice9 &pDevice9
); );
if (FAILED(res)) { if (likely(SUCCEEDED(res)))
return res; *ppReturnedDeviceInterface = ref(new D3D8Device(
} this, std::move(pDevice9),
DeviceType, hFocusWindow, BehaviorFlags,
*ppReturnedDeviceInterface = ref(new D3D8Device( pPresentationParameters
this, std::move(pDevice9), ));
DeviceType, hFocusWindow, BehaviorFlags,
pPresentationParameters
));
return res; return res;
} }
} }

View File

@ -128,9 +128,15 @@ namespace dxvk {
UINT Adapter, UINT Adapter,
D3DDEVTYPE DeviceType, D3DDEVTYPE DeviceType,
D3DCAPS8* pCaps) { D3DCAPS8* pCaps) {
if (unlikely(pCaps == nullptr))
return D3DERR_INVALIDCALL;
d3d9::D3DCAPS9 caps9; d3d9::D3DCAPS9 caps9;
HRESULT res = m_d3d9->GetDeviceCaps(Adapter, (d3d9::D3DDEVTYPE)DeviceType, &caps9); HRESULT res = m_d3d9->GetDeviceCaps(Adapter, (d3d9::D3DDEVTYPE)DeviceType, &caps9);
dxvk::ConvertCaps8(caps9, pCaps);
if (likely(SUCCEEDED(res)))
dxvk::ConvertCaps8(caps9, pCaps);
return res; return res;
} }

View File

@ -32,9 +32,15 @@ namespace dxvk {
} }
HRESULT STDMETHODCALLTYPE GetDesc(D3DSURFACE_DESC* pDesc) { HRESULT STDMETHODCALLTYPE GetDesc(D3DSURFACE_DESC* pDesc) {
if (unlikely(pDesc == nullptr))
return D3DERR_INVALIDCALL;
d3d9::D3DSURFACE_DESC desc; d3d9::D3DSURFACE_DESC desc;
HRESULT res = GetD3D9()->GetDesc(&desc); HRESULT res = GetD3D9()->GetDesc(&desc);
ConvertSurfaceDesc8(&desc, pDesc);
if (likely(SUCCEEDED(res)))
ConvertSurfaceDesc8(&desc, pDesc);
return res; return res;
} }

View File

@ -21,19 +21,28 @@ namespace dxvk {
} }
HRESULT STDMETHODCALLTYPE GetBackBuffer(UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) final { HRESULT STDMETHODCALLTYPE GetBackBuffer(UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) final {
InitReturnPtr(ppBackBuffer);
if (unlikely(ppBackBuffer == nullptr))
return D3DERR_INVALIDCALL;
// Same logic as in D3D8Device::GetBackBuffer // Same logic as in D3D8Device::GetBackBuffer
if (unlikely(m_backBuffer == nullptr)) { if (unlikely(m_backBuffer == nullptr)) {
Com<d3d9::IDirect3DSurface9> pSurface9; Com<d3d9::IDirect3DSurface9> pSurface9;
HRESULT res = GetD3D9()->GetBackBuffer(BackBuffer, (d3d9::D3DBACKBUFFER_TYPE)Type, &pSurface9); HRESULT res = GetD3D9()->GetBackBuffer(BackBuffer, (d3d9::D3DBACKBUFFER_TYPE)Type, &pSurface9);
m_backBuffer = new D3D8Surface(GetParent(), std::move(pSurface9)); if (likely(SUCCEEDED(res))) {
*ppBackBuffer = m_backBuffer.ref(); m_backBuffer = new D3D8Surface(GetParent(), std::move(pSurface9));
*ppBackBuffer = m_backBuffer.ref();
}
return res; return res;
} }
*ppBackBuffer = m_backBuffer.ref(); *ppBackBuffer = m_backBuffer.ref();
return D3D_OK; return D3D_OK;
} }
private: private:
Com<D3D8Surface> m_backBuffer = nullptr; Com<D3D8Surface> m_backBuffer = nullptr;

View File

@ -65,6 +65,9 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE GetSubresource(UINT Index, SubresourceType8** ppSubresource) { HRESULT STDMETHODCALLTYPE GetSubresource(UINT Index, SubresourceType8** ppSubresource) {
InitReturnPtr(ppSubresource); InitReturnPtr(ppSubresource);
if (unlikely(ppSubresource == nullptr))
return D3DERR_INVALIDCALL;
if (unlikely(Index >= m_subresources.size())) if (unlikely(Index >= m_subresources.size()))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
@ -118,9 +121,15 @@ namespace dxvk {
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_TEXTURE; } D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_TEXTURE; }
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) { HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) {
if (unlikely(pDesc == nullptr))
return D3DERR_INVALIDCALL;
d3d9::D3DSURFACE_DESC surf; d3d9::D3DSURFACE_DESC surf;
HRESULT res = GetD3D9()->GetLevelDesc(Level, &surf); HRESULT res = GetD3D9()->GetLevelDesc(Level, &surf);
ConvertSurfaceDesc8(&surf, pDesc);
if (likely(SUCCEEDED(res)))
ConvertSurfaceDesc8(&surf, pDesc);
return res; return res;
} }
@ -155,9 +164,15 @@ namespace dxvk {
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_VOLUMETEXTURE; } D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_VOLUMETEXTURE; }
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DVOLUME_DESC *pDesc) { HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DVOLUME_DESC *pDesc) {
if (unlikely(pDesc == nullptr))
return D3DERR_INVALIDCALL;
d3d9::D3DVOLUME_DESC vol; d3d9::D3DVOLUME_DESC vol;
HRESULT res = GetD3D9()->GetLevelDesc(Level, &vol); HRESULT res = GetD3D9()->GetLevelDesc(Level, &vol);
ConvertVolumeDesc8(&vol, pDesc);
if (likely(SUCCEEDED(res)))
ConvertVolumeDesc8(&vol, pDesc);
return res; return res;
} }
@ -198,9 +213,15 @@ namespace dxvk {
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_CUBETEXTURE; } D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_CUBETEXTURE; }
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) { HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) {
if (unlikely(pDesc == nullptr))
return D3DERR_INVALIDCALL;
d3d9::D3DSURFACE_DESC surf; d3d9::D3DSURFACE_DESC surf;
HRESULT res = GetD3D9()->GetLevelDesc(Level, &surf); HRESULT res = GetD3D9()->GetLevelDesc(Level, &surf);
ConvertSurfaceDesc8(&surf, pDesc);
if (likely(SUCCEEDED(res)))
ConvertSurfaceDesc8(&surf, pDesc);
return res; return res;
} }

View File

@ -17,9 +17,15 @@ namespace dxvk {
: D3D8VolumeBase(pDevice, std::move(pVolume), pTexture) {} : D3D8VolumeBase(pDevice, std::move(pVolume), pTexture) {}
HRESULT STDMETHODCALLTYPE GetDesc(D3DVOLUME_DESC* pDesc) { HRESULT STDMETHODCALLTYPE GetDesc(D3DVOLUME_DESC* pDesc) {
if (unlikely(pDesc == nullptr))
return D3DERR_INVALIDCALL;
d3d9::D3DVOLUME_DESC desc; d3d9::D3DVOLUME_DESC desc;
HRESULT res = GetD3D9()->GetDesc(&desc); HRESULT res = GetD3D9()->GetDesc(&desc);
ConvertVolumeDesc8(&desc, pDesc);
if (likely(SUCCEEDED(res)))
ConvertVolumeDesc8(&desc, pDesc);
return res; return res;
} }