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(); }
On 8/28/19 4:37 PM, Jactry Zeng wrote:
- hr = IUnknown_QueryInterface(device, &IID_ID3D11Device, (void **)&d3d_device);
- if (FAILED(hr))
hr = IUnknown_QueryInterface(device, &IID_ID3D12Device, (void **)&d3d_device);
Can we query for IDXGIDevice instead?
test_create_dxgi_device_manager();
- test_reset_device();
Please use existing function for that.
Also, what's a point of d3d12 device case?
On 28/8/2019 10:00 pm, Nikolay Sivov wrote:
+ hr = IUnknown_QueryInterface(device, &IID_ID3D11Device, (void **)&d3d_device); + if (FAILED(hr)) + hr = IUnknown_QueryInterface(device, &IID_ID3D12Device, (void **)&d3d_device);
Can we query for IDXGIDevice instead?
Yes, I will use IDXGIDevice instead.
test_create_dxgi_device_manager(); + test_reset_device();
Please use existing function for that.
Also, what's a point of d3d12 device case?
OK, I just found that it also support d3d12 device when writing tests. But it seems that debian testbot didn't support d3d12. And since we will use IDXGIDevice in the device manager struct instead, this will become not so important. I will drop these tests in next try.
Thanks.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=55923
Your paranoid android.
=== wvistau64 (32 bit report) ===
mfplat: 02d8:mfplat: unhandled exception c0000005 at 00000000
=== wvistau64_zh_CN (32 bit report) ===
mfplat: 0a60:mfplat: unhandled exception c0000005 at 00000000
=== wvistau64_fr (32 bit report) ===
mfplat: 0b9c:mfplat: unhandled exception c0000005 at 00000000
=== wvistau64_he (32 bit report) ===
mfplat: 0a64:mfplat: unhandled exception c0000005 at 00000000
=== w7u (32 bit report) ===
mfplat: 0d64:mfplat: unhandled exception c0000005 at 00000000
=== w7pro64 (32 bit report) ===
mfplat: 0a8c:mfplat: unhandled exception c0000005 at 00000000
=== w1064v1507 (32 bit report) ===
mfplat: mfplat.c:3860: Test failed: D3D12CreateDevice failed: 0x887a0004. 027c:mfplat: unhandled exception c0000005 at 004017DF
=== wvistau64 (64 bit report) ===
mfplat: 02d8:mfplat: unhandled exception c0000005 at 0000000000000000
=== w7pro64 (64 bit report) ===
mfplat: 0a70:mfplat: unhandled exception c0000005 at 0000000000000000
=== w1064v1507 (64 bit report) ===
mfplat: mfplat.c:3860: Test failed: D3D12CreateDevice failed: 0x887a0004. 0250:mfplat: unhandled exception c0000005 at 00000000004017D7
=== debian10 (32 bit report) ===
mfplat: mfplat.c:3860: Test failed: D3D12CreateDevice failed: 0x80004005. Unhandled exception: page fault on execute access to 0x11002400 in 32-bit code (0x11002400).
Report errors: mfplat:mfplat crashed (c0000005)
=== debian10 (32 bit French report) ===
mfplat: mfplat.c:3860: Test failed: D3D12CreateDevice failed: 0x80004005. Unhandled exception: page fault on execute access to 0x11002400 in 32-bit code (0x11002400).
Report errors: mfplat:mfplat crashed (c0000005)
=== debian10 (32 bit Japanese:Japan report) ===
mfplat: mfplat.c:3860: Test failed: D3D12CreateDevice failed: 0x80004005. Unhandled exception: page fault on execute access to 0x11002400 in 32-bit code (0x11002400).
Report errors: mfplat:mfplat crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
mfplat: mfplat.c:3860: Test failed: D3D12CreateDevice failed: 0x80004005. Unhandled exception: page fault on execute access to 0x11002400 in 32-bit code (0x11002400).
Report errors: mfplat:mfplat crashed (c0000005)
=== debian10 (32 bit WoW report) ===
mfplat: mfplat.c:3860: Test failed: D3D12CreateDevice failed: 0x80004005. Unhandled exception: page fault on execute access to 0x11002400 in 32-bit code (0x11002400).
Report errors: mfplat:mfplat crashed (c0000005)
=== debian10 (64 bit WoW report) ===
mfplat: mfplat.c:3860: Test failed: D3D12CreateDevice failed: 0x80004005. Unhandled exception: page fault on execute access to 0x11002400 in 32-bit code (0x11002400).
Report errors: mfplat:mfplat crashed (c0000005)