[PATCH 2/6] mfplat: Implement IMFDXGIDeviceManager::ResetDevice().
Jactry Zeng
jzeng at codeweavers.com
Wed Aug 28 08:37:18 CDT 2019
Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
dlls/mfplat/main.c | 29 ++++++++++-
dlls/mfplat/tests/Makefile.in | 2 +-
dlls/mfplat/tests/mfplat.c | 92 +++++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+), 3 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index c2293cfd8b..1b0f6b5e9d 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -28,7 +28,10 @@
#include "winuser.h"
#include "winreg.h"
+#define D3D11_INIT_GUID
#include "initguid.h"
+#include "d3d11_4.h"
+#include "d3d12.h"
#include "ole2.h"
#include "propsys.h"
@@ -7623,6 +7626,7 @@ struct mfdxgi_dev_mgr
IMFDXGIDeviceManager IMFDXGIDeviceManager_iface;
LONG ref;
UINT token;
+ IUnknown *d3d_device;
};
static struct mfdxgi_dev_mgr *impl_from_IMFDXGIDeviceManager(IMFDXGIDeviceManager *iface)
@@ -7666,6 +7670,8 @@ static ULONG WINAPI mfdxgi_dev_mgr_Release(IMFDXGIDeviceManager *iface)
if (!refcount)
{
+ if (manager->d3d_device)
+ IUnknown_Release(manager->d3d_device);
heap_free(manager);
}
@@ -7713,10 +7719,28 @@ static HRESULT WINAPI mfdxgi_dev_mgr_OpenDeviceHandle(IMFDXGIDeviceManager *ifac
static HRESULT WINAPI mfdxgi_dev_mgr_ResetDevice(IMFDXGIDeviceManager *iface, IUnknown *device, UINT token)
{
struct mfdxgi_dev_mgr *This = impl_from_IMFDXGIDeviceManager(iface);
+ IUnknown *d3d_device;
+ HRESULT hr;
- FIXME("(%p)->(%p, %u): stub.\n", This, device, token);
+ TRACE("(%p)->(%p, %u).\n", This, device, token);
- return E_NOTIMPL;
+ if (!device || token != This->token)
+ return E_INVALIDARG;
+
+ hr = IUnknown_QueryInterface(device, &IID_ID3D11Device, (void **)&d3d_device);
+ if (FAILED(hr))
+ hr = IUnknown_QueryInterface(device, &IID_ID3D12Device, (void **)&d3d_device);
+
+ if (SUCCEEDED(hr))
+ {
+ if (This->d3d_device)
+ IUnknown_Release(This->d3d_device);
+ This->d3d_device = d3d_device;
+ }
+ else
+ hr = E_INVALIDARG;
+
+ return hr;
}
static HRESULT WINAPI mfdxgi_dev_mgr_TestDevice(IMFDXGIDeviceManager *iface, HANDLE device)
@@ -7767,6 +7791,7 @@ HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **man
dev_mgr->IMFDXGIDeviceManager_iface.lpVtbl = &mfdxgi_dev_mgr_vtbl;
dev_mgr->ref = 1;
dev_mgr->token = MFGetSystemTime();
+ dev_mgr->d3d_device = NULL;
TRACE("Created device manager: %p, token: %u.\n", dev_mgr, dev_mgr->token);
diff --git a/dlls/mfplat/tests/Makefile.in b/dlls/mfplat/tests/Makefile.in
index c58a0463e5..dafb429142 100644
--- a/dlls/mfplat/tests/Makefile.in
+++ b/dlls/mfplat/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = mfplat.dll
-IMPORTS = ole32 mfplat mfuuid propsys uuid
+IMPORTS = ole32 mfplat mfuuid propsys uuid d3d11
C_SRCS = \
mfplat.c
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 312f8b3bb2..7f29793982 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -38,7 +38,11 @@
#include "wine/test.h"
#include "wine/heap.h"
+#define D3D11_INIT_GUID
#include "initguid.h"
+#include "d3d11_4.h"
+#include "d3d12.h"
+
DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
@@ -56,6 +60,7 @@ static void _expect_ref(IUnknown *obj, ULONG ref, int line)
ok_(__FILE__,line)(rc == ref, "Unexpected refcount %d, expected %d.\n", rc, ref);
}
+PFN_D3D12_CREATE_DEVICE pD3D12CreateDevice;
static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
DWORD width, DWORD lines);
static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
@@ -506,6 +511,7 @@ todo_wine
static void init_functions(void)
{
HMODULE mod = GetModuleHandleA("mfplat.dll");
+ HMODULE d3d12_mod = LoadLibraryA("d3d12.dll");
#define X(f) p##f = (void*)GetProcAddress(mod, #f)
X(MFAddPeriodicCallback);
@@ -522,6 +528,10 @@ static void init_functions(void)
X(MFRemovePeriodicCallback);
#undef X
+#define X(f) p##f = (void*)GetProcAddress(d3d12_mod, #f)
+ X(D3D12CreateDevice);
+#undef X
+
is_win8_plus = pMFPutWaitingWorkItem != NULL;
}
@@ -3778,6 +3788,87 @@ static void test_create_dxgi_device_manager(void)
IMFDXGIDeviceManager_Release(ret2.dev_mgr);
}
+static void test_reset_device(void)
+{
+ ID3D11Device *d3d11_dev, *d3d11_dev2;
+ IMFDXGIDeviceManager *manager;
+ ID3D12Device *d3d12_dev;
+ HRESULT hr;
+ UINT token;
+
+ token = 0;
+ hr = pMFCreateDXGIDeviceManager(&token, &manager);
+ ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
+ EXPECT_REF(manager, 1);
+ ok(!!token, "got wrong token: %u.\n", token);
+
+ hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
+ NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
+ ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
+ EXPECT_REF(d3d11_dev, 1);
+
+ hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
+ ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
+ EXPECT_REF(d3d11_dev, 1);
+
+ hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
+ ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
+
+ hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
+ ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
+ EXPECT_REF(manager, 1);
+ EXPECT_REF(d3d11_dev, 2);
+
+ hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager, token);
+ ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
+ EXPECT_REF(manager, 1);
+ EXPECT_REF(d3d11_dev, 2);
+
+ hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
+ ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
+ EXPECT_REF(manager, 1);
+ EXPECT_REF(d3d11_dev, 2);
+
+ hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
+ NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
+ ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
+ EXPECT_REF(d3d11_dev2, 1);
+ hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
+ ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
+ EXPECT_REF(manager, 1);
+ EXPECT_REF(d3d11_dev2, 2);
+ EXPECT_REF(d3d11_dev, 1);
+
+ IMFDXGIDeviceManager_Release(manager);
+ EXPECT_REF(d3d11_dev2, 1);
+ ID3D11Device_Release(d3d11_dev);
+ ID3D11Device_Release(d3d11_dev2);
+
+ if (!pD3D12CreateDevice)
+ {
+ win_skip("D3D12CreateDevice() not found.\n");
+ return;
+ }
+
+ token = 0;
+ hr = pMFCreateDXGIDeviceManager(&token, &manager);
+ ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
+ EXPECT_REF(manager, 1);
+ ok(!!token, "got wrong token: %u.\n", token);
+
+ hr = pD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&d3d12_dev);
+ ok(hr == S_OK, "D3D12CreateDevice failed: %#x.\n", hr);
+ EXPECT_REF(d3d12_dev, 1);
+
+ hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d12_dev, token);
+ ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
+ EXPECT_REF(manager, 1);
+ EXPECT_REF(d3d12_dev, 2);
+
+ ID3D12Device_Release(d3d12_dev);
+ IMFDXGIDeviceManager_Release(manager);
+}
+
START_TEST(mfplat)
{
CoInitialize(NULL);
@@ -3816,6 +3907,7 @@ START_TEST(mfplat)
test_local_handlers();
test_create_property_store();
test_create_dxgi_device_manager();
+ test_reset_device();
CoUninitialize();
}
--
2.23.0.rc1
More information about the wine-devel
mailing list