mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-20 08:52:22 +01:00
[d3d9] Add present params validations on device creation and reset
This commit is contained in:
parent
35352b9c52
commit
a7c2eb140e
@ -228,6 +228,13 @@ namespace dxvk {
|
||||
if (unlikely(pPresentationParameters == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
// D3DSWAPEFFECT_COPY can not be used with more than one back buffer.
|
||||
// This is also technically true for D3DSWAPEFFECT_COPY_VSYNC, however
|
||||
// RC Cars depends on it not being rejected.
|
||||
if (unlikely(pPresentationParameters->SwapEffect == D3DSWAPEFFECT_COPY
|
||||
&& pPresentationParameters->BackBufferCount > 1))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
m_presentParams = *pPresentationParameters;
|
||||
ResetState();
|
||||
|
||||
|
@ -122,6 +122,13 @@ namespace dxvk
|
||||
ppReturnedDeviceInterface == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
// D3DSWAPEFFECT_COPY can not be used with more than one back buffer.
|
||||
// This is also technically true for D3DSWAPEFFECT_COPY_VSYNC, however
|
||||
// RC Cars depends on it not being rejected.
|
||||
if (unlikely(pPresentationParameters->SwapEffect == D3DSWAPEFFECT_COPY
|
||||
&& pPresentationParameters->BackBufferCount > 1))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
Com<d3d9::IDirect3DDevice9> pDevice9 = nullptr;
|
||||
d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters);
|
||||
HRESULT res = m_d3d9->CreateDevice(
|
||||
|
@ -476,6 +476,11 @@ namespace dxvk {
|
||||
Logger::info("Device reset");
|
||||
m_deviceLostState = D3D9DeviceLostState::Ok;
|
||||
|
||||
HRESULT hr = m_parent->ValidatePresentationParameters(pPresentationParameters);
|
||||
|
||||
if (unlikely(FAILED(hr)))
|
||||
return hr;
|
||||
|
||||
if (!IsExtended()) {
|
||||
// The internal references are always cleared, regardless of whether the Reset call succeeds.
|
||||
ResetState(pPresentationParameters);
|
||||
@ -507,8 +512,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;
|
||||
|
@ -350,16 +350,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);
|
||||
|
||||
if (unlikely(FAILED(hr)))
|
||||
return hr;
|
||||
|
||||
auto* adapter = GetAdapter(Adapter);
|
||||
|
||||
if (adapter == nullptr)
|
||||
@ -378,9 +383,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);
|
||||
|
@ -121,6 +121,49 @@ 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;
|
||||
}
|
||||
|
||||
const D3D9Options& GetOptions() { return m_d3d9Options; }
|
||||
|
||||
D3D9Adapter* GetAdapter(UINT Ordinal) {
|
||||
@ -146,10 +189,6 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
void CacheModes(D3D9Format Format);
|
||||
|
||||
static const char* GetDriverDllName(DxvkGpuVendor vendor);
|
||||
|
||||
Rc<DxvkInstance> m_instance;
|
||||
|
||||
DxvkD3D8InterfaceBridge m_d3d8Bridge;
|
||||
|
Loading…
x
Reference in New Issue
Block a user