Skip to content

Commit

Permalink
[d3d9] Add device creation and reset SwapEffect validations
Browse files Browse the repository at this point in the history
  • Loading branch information
WinterSnowfall committed Oct 13, 2024
1 parent 90f50f5 commit 7bd062c
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 14 deletions.
9 changes: 7 additions & 2 deletions src/d3d9/d3d9_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,11 @@ namespace dxvk {
Logger::info("Device reset");
m_deviceLostState = D3D9DeviceLostState::Ok;

HRESULT hr = m_parent->ValidatePresentationParameters(pPresentationParameters, IsExtended());

if (unlikely(FAILED(hr)))
return hr;

if (!IsExtended()) {
// The internal references are always cleared, regardless of whether the Reset call succeeds.
ResetState(pPresentationParameters);
Expand Down Expand Up @@ -499,8 +504,8 @@ namespace dxvk {
return D3DERR_DEVICELOST;
}

HRESULT hr = ResetSwapChain(pPresentationParameters, nullptr);
if (FAILED(hr)) {
hr = ResetSwapChain(pPresentationParameters, nullptr);
if (unlikely(FAILED(hr))) {
if (!IsExtended()) {
Logger::warn("Device reset failed: Device not reset");
m_deviceLostState = D3D9DeviceLostState::NotReset;
Expand Down
55 changes: 47 additions & 8 deletions src/d3d9/d3d9_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,11 @@ namespace dxvk {
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface) {
HRESULT hr = ValidatePresentationParameters(pPresentationParameters, false);

if (unlikely(FAILED(hr)))
return hr;

return this->CreateDeviceEx(
Adapter,
DeviceType,
Expand Down Expand Up @@ -350,16 +355,21 @@ namespace dxvk {
IDirect3DDevice9Ex** ppReturnedDeviceInterface) {
InitReturnPtr(ppReturnedDeviceInterface);

if (ppReturnedDeviceInterface == nullptr
|| pPresentationParameters == nullptr)
if (unlikely(ppReturnedDeviceInterface == nullptr
|| pPresentationParameters == nullptr))
return D3DERR_INVALIDCALL;

// creating a device with D3DCREATE_PUREDEVICE only works in conjunction
// with D3DCREATE_HARDWARE_VERTEXPROCESSING on native drivers
if (BehaviorFlags & D3DCREATE_PUREDEVICE &&
!(BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING))
// Creating a device with D3DCREATE_PUREDEVICE only works in conjunction
// with D3DCREATE_HARDWARE_VERTEXPROCESSING on native drivers.
if (unlikely(BehaviorFlags & D3DCREATE_PUREDEVICE &&
!(BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)))
return D3DERR_INVALIDCALL;

HRESULT hr = ValidatePresentationParameters(pPresentationParameters, true);

if (unlikely(FAILED(hr)))
return hr;

auto* adapter = GetAdapter(Adapter);

if (adapter == nullptr)
Expand All @@ -378,9 +388,9 @@ namespace dxvk {
BehaviorFlags,
dxvkDevice);

HRESULT hr = device->InitialReset(pPresentationParameters, pFullscreenDisplayMode);
hr = device->InitialReset(pPresentationParameters, pFullscreenDisplayMode);

if (FAILED(hr))
if (unlikely(FAILED(hr)))
return hr;

*ppReturnedDeviceInterface = ref(device);
Expand All @@ -401,4 +411,33 @@ namespace dxvk {
return D3DERR_INVALIDCALL;
}


HRESULT D3D9InterfaceEx::ValidatePresentationParameters(D3DPRESENT_PARAMETERS* params, bool isExDevice) {
if (isExDevice) {
// The swap effect value on a D3D9Ex device
// can not be higher than D3DSWAPEFFECT_FLIPEX.
if (unlikely(params->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(params->SwapEffect > D3DSWAPEFFECT_COPY))
return D3DERR_INVALIDCALL;
}

// The swap effect value can not be 0, and D3DSWAPEFFECT_COPY
// can not have more than one back buffer.
if (unlikely(!params->SwapEffect
|| (params->SwapEffect == D3DSWAPEFFECT_COPY
&& params->BackBufferCount > 1)))
return D3DERR_INVALIDCALL;

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

return D3D_OK;
}

}
6 changes: 2 additions & 4 deletions src/d3d9/d3d9_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,9 @@ namespace dxvk {

Rc<DxvkInstance> GetInstance() { return m_instance; }

private:

void CacheModes(D3D9Format Format);
HRESULT ValidatePresentationParameters(D3DPRESENT_PARAMETERS* params, bool isExDevice);

static const char* GetDriverDllName(DxvkGpuVendor vendor);
private:

Rc<DxvkInstance> m_instance;

Expand Down

0 comments on commit 7bd062c

Please sign in to comment.