Signed-off-by: Jactry Zeng jzeng@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(); }