Skip to content

Commit

Permalink
[d3d9] Skip some validations when hDeviceWindow is NULL
Browse files Browse the repository at this point in the history
  • Loading branch information
WinterSnowfall authored and doitsujin committed Nov 7, 2024
1 parent c466dec commit eb98047
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 45 deletions.
9 changes: 6 additions & 3 deletions src/d3d9/d3d9_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8309,9 +8309,12 @@ namespace dxvk {
" - Windowed: ", pPresentationParameters->Windowed ? "true" : "false", "\n",
" - Swap effect: ", pPresentationParameters->SwapEffect, "\n"));

if (!pPresentationParameters->Windowed &&
(pPresentationParameters->BackBufferWidth == 0
|| pPresentationParameters->BackBufferHeight == 0)) {
// Black Desert creates a device with a NULL hDeviceWindow and
// seemingly expects this validation to not prevent a swapchain reset.
if (pPresentationParameters->hDeviceWindow != nullptr &&
!pPresentationParameters->Windowed &&
(pPresentationParameters->BackBufferWidth == 0
|| pPresentationParameters->BackBufferHeight == 0)) {
return D3DERR_INVALIDCALL;
}

Expand Down
47 changes: 47 additions & 0 deletions src/d3d9/d3d9_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,4 +406,51 @@ namespace dxvk {
return D3DERR_INVALIDCALL;
}


HRESULT D3D9InterfaceEx::ValidatePresentationParameters(D3DPRESENT_PARAMETERS* pPresentationParameters) {
if (m_extended) {
// The swap effect value on a D3D9Ex device
// can not be higher than D3DSWAPEFFECT_FLIPEX.
if (unlikely(pPresentationParameters->SwapEffect > D3DSWAPEFFECT_FLIPEX))
return D3DERR_INVALIDCALL;
} else {
// The swap effect value on a non-Ex D3D9 device
// can not be higher than D3DSWAPEFFECT_COPY.
if (unlikely(pPresentationParameters->SwapEffect > D3DSWAPEFFECT_COPY))
return D3DERR_INVALIDCALL;
}

// The swap effect value can not be 0.
// Black Desert sets this to 0 with a NULL hDeviceWindow
// and expects device creation to succeed.
if (unlikely(pPresentationParameters->hDeviceWindow != nullptr
&& !pPresentationParameters->SwapEffect))
return D3DERR_INVALIDCALL;

// D3DSWAPEFFECT_COPY can not be used with more than one back buffer.
// Allow D3DSWAPEFFECT_COPY to bypass this restriction in D3D8 compatibility
// mode, since it may be a remapping of D3DSWAPEFFECT_COPY_VSYNC and RC Cars
// depends on it not being validated.
if (unlikely(!IsD3D8Compatible()
&& pPresentationParameters->SwapEffect == D3DSWAPEFFECT_COPY
&& pPresentationParameters->BackBufferCount > 1))
return D3DERR_INVALIDCALL;

// 3 is the highest supported back buffer count.
if (unlikely(pPresentationParameters->BackBufferCount > 3))
return D3DERR_INVALIDCALL;

// Valid fullscreen presentation intervals must be known values.
if (unlikely(!pPresentationParameters->Windowed
&& !(pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_DEFAULT
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_ONE
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_TWO
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_THREE
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_FOUR
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE)))
return D3DERR_INVALIDCALL;

return D3D_OK;
}

}
43 changes: 1 addition & 42 deletions src/d3d9/d3d9_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,48 +121,7 @@ namespace dxvk {

HRESULT STDMETHODCALLTYPE GetAdapterLUID(UINT Adapter, LUID* pLUID);

HRESULT ValidatePresentationParameters(D3DPRESENT_PARAMETERS* pPresentationParameters) {
if (m_extended) {
// The swap effect value on a D3D9Ex device
// can not be higher than D3DSWAPEFFECT_FLIPEX.
if (unlikely(pPresentationParameters->SwapEffect > D3DSWAPEFFECT_FLIPEX))
return D3DERR_INVALIDCALL;
} else {
// The swap effect value on a non-Ex D3D9 device
// can not be higher than D3DSWAPEFFECT_COPY.
if (unlikely(pPresentationParameters->SwapEffect > D3DSWAPEFFECT_COPY))
return D3DERR_INVALIDCALL;
}

// The swap effect value can not be 0.
if (unlikely(!pPresentationParameters->SwapEffect))
return D3DERR_INVALIDCALL;

// D3DSWAPEFFECT_COPY can not be used with more than one back buffer.
// Allow D3DSWAPEFFECT_COPY to bypass this restriction in D3D8 compatibility
// mode, since it may be a remapping of D3DSWAPEFFECT_COPY_VSYNC and RC Cars
// depends on it not being validated.
if (unlikely(!IsD3D8Compatible()
&& pPresentationParameters->SwapEffect == D3DSWAPEFFECT_COPY
&& pPresentationParameters->BackBufferCount > 1))
return D3DERR_INVALIDCALL;

// 3 is the highest supported back buffer count.
if (unlikely(pPresentationParameters->BackBufferCount > 3))
return D3DERR_INVALIDCALL;

// Valid fullscreen presentation intervals must be known values.
if (unlikely(!pPresentationParameters->Windowed
&& !(pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_DEFAULT
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_ONE
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_TWO
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_THREE
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_FOUR
|| pPresentationParameters->PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE)))
return D3DERR_INVALIDCALL;

return D3D_OK;
}
HRESULT ValidatePresentationParameters(D3DPRESENT_PARAMETERS* pPresentationParameters);

const D3D9Options& GetOptions() { return m_d3d9Options; }

Expand Down

0 comments on commit eb98047

Please sign in to comment.