mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 23:52:20 +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))
|
if (unlikely(pPresentationParameters == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
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;
|
m_presentParams = *pPresentationParameters;
|
||||||
ResetState();
|
ResetState();
|
||||||
|
|
||||||
|
@ -122,6 +122,13 @@ namespace dxvk
|
|||||||
ppReturnedDeviceInterface == nullptr))
|
ppReturnedDeviceInterface == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
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;
|
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(
|
||||||
|
@ -476,6 +476,11 @@ namespace dxvk {
|
|||||||
Logger::info("Device reset");
|
Logger::info("Device reset");
|
||||||
m_deviceLostState = D3D9DeviceLostState::Ok;
|
m_deviceLostState = D3D9DeviceLostState::Ok;
|
||||||
|
|
||||||
|
HRESULT hr = m_parent->ValidatePresentationParameters(pPresentationParameters);
|
||||||
|
|
||||||
|
if (unlikely(FAILED(hr)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
if (!IsExtended()) {
|
if (!IsExtended()) {
|
||||||
// The internal references are always cleared, regardless of whether the Reset call succeeds.
|
// The internal references are always cleared, regardless of whether the Reset call succeeds.
|
||||||
ResetState(pPresentationParameters);
|
ResetState(pPresentationParameters);
|
||||||
@ -507,8 +512,8 @@ namespace dxvk {
|
|||||||
return D3DERR_DEVICELOST;
|
return D3DERR_DEVICELOST;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = ResetSwapChain(pPresentationParameters, nullptr);
|
hr = ResetSwapChain(pPresentationParameters, nullptr);
|
||||||
if (FAILED(hr)) {
|
if (unlikely(FAILED(hr))) {
|
||||||
if (!IsExtended()) {
|
if (!IsExtended()) {
|
||||||
Logger::warn("Device reset failed: Device not reset");
|
Logger::warn("Device reset failed: Device not reset");
|
||||||
m_deviceLostState = D3D9DeviceLostState::NotReset;
|
m_deviceLostState = D3D9DeviceLostState::NotReset;
|
||||||
|
@ -350,16 +350,21 @@ namespace dxvk {
|
|||||||
IDirect3DDevice9Ex** ppReturnedDeviceInterface) {
|
IDirect3DDevice9Ex** ppReturnedDeviceInterface) {
|
||||||
InitReturnPtr(ppReturnedDeviceInterface);
|
InitReturnPtr(ppReturnedDeviceInterface);
|
||||||
|
|
||||||
if (ppReturnedDeviceInterface == nullptr
|
if (unlikely(ppReturnedDeviceInterface == nullptr
|
||||||
|| pPresentationParameters == nullptr)
|
|| pPresentationParameters == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
// creating a device with D3DCREATE_PUREDEVICE only works in conjunction
|
// Creating a device with D3DCREATE_PUREDEVICE only works in conjunction
|
||||||
// with D3DCREATE_HARDWARE_VERTEXPROCESSING on native drivers
|
// with D3DCREATE_HARDWARE_VERTEXPROCESSING on native drivers.
|
||||||
if (BehaviorFlags & D3DCREATE_PUREDEVICE &&
|
if (unlikely(BehaviorFlags & D3DCREATE_PUREDEVICE &&
|
||||||
!(BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING))
|
!(BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
|
HRESULT hr = ValidatePresentationParameters(pPresentationParameters);
|
||||||
|
|
||||||
|
if (unlikely(FAILED(hr)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
auto* adapter = GetAdapter(Adapter);
|
auto* adapter = GetAdapter(Adapter);
|
||||||
|
|
||||||
if (adapter == nullptr)
|
if (adapter == nullptr)
|
||||||
@ -378,9 +383,9 @@ namespace dxvk {
|
|||||||
BehaviorFlags,
|
BehaviorFlags,
|
||||||
dxvkDevice);
|
dxvkDevice);
|
||||||
|
|
||||||
HRESULT hr = device->InitialReset(pPresentationParameters, pFullscreenDisplayMode);
|
hr = device->InitialReset(pPresentationParameters, pFullscreenDisplayMode);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (unlikely(FAILED(hr)))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
*ppReturnedDeviceInterface = ref(device);
|
*ppReturnedDeviceInterface = ref(device);
|
||||||
|
@ -121,6 +121,49 @@ namespace dxvk {
|
|||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetAdapterLUID(UINT Adapter, LUID* pLUID);
|
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; }
|
const D3D9Options& GetOptions() { return m_d3d9Options; }
|
||||||
|
|
||||||
D3D9Adapter* GetAdapter(UINT Ordinal) {
|
D3D9Adapter* GetAdapter(UINT Ordinal) {
|
||||||
@ -146,10 +189,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void CacheModes(D3D9Format Format);
|
|
||||||
|
|
||||||
static const char* GetDriverDllName(DxvkGpuVendor vendor);
|
|
||||||
|
|
||||||
Rc<DxvkInstance> m_instance;
|
Rc<DxvkInstance> m_instance;
|
||||||
|
|
||||||
DxvkD3D8InterfaceBridge m_d3d8Bridge;
|
DxvkD3D8InterfaceBridge m_d3d8Bridge;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user