From fd72999bd68065a890a496b076a421841f92f778 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 22 Jun 2020 13:45:29 +0300 Subject: [PATCH] dxva2: Add device manager stub. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- configure | 1 + configure.ac | 1 + dlls/dxva2/Makefile.in | 4 +- dlls/dxva2/main.c | 147 +++++++++++++++++++++++++++- dlls/dxva2/tests/Makefile.in | 5 + dlls/dxva2/tests/dxva2.c | 181 +++++++++++++++++++++++++++++++++++ 6 files changed, 334 insertions(+), 5 deletions(-) create mode 100644 dlls/dxva2/tests/Makefile.in create mode 100644 dlls/dxva2/tests/dxva2.c diff --git a/configure b/configure index dd23b5ab13b..106ce1625b1 100755 --- a/configure +++ b/configure @@ -20683,6 +20683,7 @@ wine_fn_config_makefile dlls/dxgi enable_dxgi wine_fn_config_makefile dlls/dxgi/tests enable_tests wine_fn_config_makefile dlls/dxguid enable_dxguid wine_fn_config_makefile dlls/dxva2 enable_dxva2 +wine_fn_config_makefile dlls/dxva2/tests enable_tests wine_fn_config_makefile dlls/esent enable_esent wine_fn_config_makefile dlls/evr enable_evr wine_fn_config_makefile dlls/evr/tests enable_tests diff --git a/configure.ac b/configure.ac index 9c5f76669df..a78610c6490 100644 --- a/configure.ac +++ b/configure.ac @@ -3269,6 +3269,7 @@ WINE_CONFIG_MAKEFILE(dlls/dxgi) WINE_CONFIG_MAKEFILE(dlls/dxgi/tests) WINE_CONFIG_MAKEFILE(dlls/dxguid) WINE_CONFIG_MAKEFILE(dlls/dxva2) +WINE_CONFIG_MAKEFILE(dlls/dxva2/tests) WINE_CONFIG_MAKEFILE(dlls/esent) WINE_CONFIG_MAKEFILE(dlls/evr) WINE_CONFIG_MAKEFILE(dlls/evr/tests) diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in index 44e125e9b5f..e3fc2fd6c3a 100644 --- a/dlls/dxva2/Makefile.in +++ b/dlls/dxva2/Makefile.in @@ -1,4 +1,6 @@ -MODULE = dxva2.dll +MODULE = dxva2.dll +IMPORTS = uuid +IMPORTLIB = dxva2 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/dxva2/main.c b/dlls/dxva2/main.c index 782f0dfa3d4..e1eb2128439 100644 --- a/dlls/dxva2/main.c +++ b/dlls/dxva2/main.c @@ -16,19 +16,144 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + #include #include "windef.h" #include "winbase.h" #include "d3d9.h" -#include "dxva2api.h" #include "physicalmonitorenumerationapi.h" #include "lowlevelmonitorconfigurationapi.h" #include "highlevelmonitorconfigurationapi.h" +#include "initguid.h" +#include "dxva2api.h" #include "wine/debug.h" +#include "wine/heap.h" WINE_DEFAULT_DEBUG_CHANNEL(dxva2); +struct device_manager +{ + IDirect3DDeviceManager9 IDirect3DDeviceManager9_iface; + LONG refcount; + + UINT token; +}; + +static struct device_manager *impl_from_IDirect3DDeviceManager9(IDirect3DDeviceManager9 *iface) +{ + return CONTAINING_RECORD(iface, struct device_manager, IDirect3DDeviceManager9_iface); +} + +static HRESULT WINAPI device_manager_QueryInterface(IDirect3DDeviceManager9 *iface, REFIID riid, void **obj) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + if (IsEqualIID(&IID_IDirect3DDeviceManager9, riid) || + IsEqualIID(&IID_IUnknown, riid)) + { + *obj = iface; + IDirect3DDeviceManager9_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI device_manager_AddRef(IDirect3DDeviceManager9 *iface) +{ + struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface); + ULONG refcount = InterlockedIncrement(&manager->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI device_manager_Release(IDirect3DDeviceManager9 *iface) +{ + struct device_manager *manager = impl_from_IDirect3DDeviceManager9(iface); + ULONG refcount = InterlockedDecrement(&manager->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(manager); + } + + return refcount; +} + +static HRESULT WINAPI device_manager_ResetDevice(IDirect3DDeviceManager9 *iface, IDirect3DDevice9 *device, + UINT token) +{ + FIXME("%p, %p, %#x.\n", iface, device, token); + + return E_NOTIMPL; +} + +static HRESULT WINAPI device_manager_OpenDeviceHandle(IDirect3DDeviceManager9 *iface, HANDLE *hdevice) +{ + FIXME("%p, %p.\n", iface, hdevice); + + return E_NOTIMPL; +} + +static HRESULT WINAPI device_manager_CloseDeviceHandle(IDirect3DDeviceManager9 *iface, HANDLE hdevice) +{ + FIXME("%p, %p.\n", iface, hdevice); + + return E_NOTIMPL; +} + +static HRESULT WINAPI device_manager_TestDevice(IDirect3DDeviceManager9 *iface, HANDLE hdevice) +{ + FIXME("%p, %p.\n", iface, hdevice); + + return E_NOTIMPL; +} + +static HRESULT WINAPI device_manager_LockDevice(IDirect3DDeviceManager9 *iface, HANDLE hdevice, + IDirect3DDevice9 **device, BOOL block) +{ + FIXME("%p, %p, %p, %d.\n", iface, hdevice, device, block); + + return E_NOTIMPL; +} + +static HRESULT WINAPI device_manager_UnlockDevice(IDirect3DDeviceManager9 *iface, HANDLE hdevice, BOOL savestate) +{ + FIXME("%p, %p, %d.\n", iface, hdevice, savestate); + + return E_NOTIMPL; +} + +static HRESULT WINAPI device_manager_GetVideoService(IDirect3DDeviceManager9 *iface, HANDLE hdevice, REFIID riid, + void **obj) +{ + FIXME("%p, %p, %s, %p.\n", iface, hdevice, debugstr_guid(riid), obj); + + return E_NOTIMPL; +} + +static const IDirect3DDeviceManager9Vtbl device_manager_vtbl = +{ + device_manager_QueryInterface, + device_manager_AddRef, + device_manager_Release, + device_manager_ResetDevice, + device_manager_OpenDeviceHandle, + device_manager_CloseDeviceHandle, + device_manager_TestDevice, + device_manager_LockDevice, + device_manager_UnlockDevice, + device_manager_GetVideoService, +}; + BOOL WINAPI CapabilitiesRequestAndCapabilitiesReply( HMONITOR monitor, LPSTR buffer, DWORD length ) { FIXME("(%p, %p, %d): stub\n", monitor, buffer, length); @@ -37,11 +162,25 @@ BOOL WINAPI CapabilitiesRequestAndCapabilitiesReply( HMONITOR monitor, LPSTR buf return FALSE; } -HRESULT WINAPI DXVA2CreateDirect3DDeviceManager9( UINT *resetToken, IDirect3DDeviceManager9 **dxvManager ) +HRESULT WINAPI DXVA2CreateDirect3DDeviceManager9(UINT *token, IDirect3DDeviceManager9 **manager) { - FIXME("(%p, %p): stub\n", resetToken, dxvManager); + struct device_manager *object; - return E_NOTIMPL; + TRACE("%p, %p.\n", token, manager); + + *manager = NULL; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IDirect3DDeviceManager9_iface.lpVtbl = &device_manager_vtbl; + object->refcount = 1; + object->token = GetTickCount(); + + *token = object->token; + *manager = &object->IDirect3DDeviceManager9_iface; + + return S_OK; } HRESULT WINAPI DXVA2CreateVideoService( IDirect3DDevice9 *device, REFIID riid, void **ppv ) diff --git a/dlls/dxva2/tests/Makefile.in b/dlls/dxva2/tests/Makefile.in new file mode 100644 index 00000000000..c86c5ab42fc --- /dev/null +++ b/dlls/dxva2/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = dxva2.dll +IMPORTS = dxva2 user32 d3d9 + +C_SRCS = \ + dxva2.c diff --git a/dlls/dxva2/tests/dxva2.c b/dlls/dxva2/tests/dxva2.c new file mode 100644 index 00000000000..cbcad40ca59 --- /dev/null +++ b/dlls/dxva2/tests/dxva2.c @@ -0,0 +1,181 @@ +/* + * Copyright 2020 Nikolay Sivov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS +#include "wine/test.h" +#include "d3d9.h" + +#include "initguid.h" +#include "dxva2api.h" + +static int get_refcount(IUnknown *object) +{ + IUnknown_AddRef(object); + return IUnknown_Release(object); +} + +static HWND create_window(void) +{ + RECT r = {0, 0, 640, 480}; + + AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); + + return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); +} + +static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window) +{ + D3DPRESENT_PARAMETERS present_parameters = {0}; + IDirect3DDevice9 *device = NULL; + + present_parameters.BackBufferWidth = 640; + present_parameters.BackBufferHeight = 480; + present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.hDeviceWindow = focus_window; + present_parameters.Windowed = TRUE; + present_parameters.EnableAutoDepthStencil = TRUE; + present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; + + IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device); + + return device; +} + +static void test_device_manager(void) +{ + IDirectXVideoProcessorService *processor_service; + IDirect3DDevice9 *device, *device2; + IDirect3DDeviceManager9 *manager; + int refcount, refcount2; + HANDLE handle, handle1; + IDirect3D9 *d3d; + HWND window; + UINT token; + HRESULT hr; + + window = create_window(); + d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + if (!(device = create_device(d3d, window))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + goto done; + } + + hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle); +todo_wine + ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr); + + /* Invalid token. */ + hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token + 1); +todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + refcount = get_refcount((IUnknown *)device); + + handle1 = NULL; + hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle1); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + refcount2 = get_refcount((IUnknown *)device); + ok(refcount2 == refcount, "Unexpected refcount %d.\n", refcount); + + handle = NULL; + hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(handle != handle1, "Unexpected handle.\n"); +} + hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* Already closed. */ + hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle); +todo_wine + ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr); + + handle = NULL; + hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle1); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDirect3DDeviceManager9_TestDevice(manager, handle1); +todo_wine + ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr); + + handle = NULL; + hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + handle1 = NULL; + hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle1); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, &IID_IDirectXVideoProcessorService, + (void **)&processor_service); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + if (SUCCEEDED(hr)) + IDirectXVideoProcessorService_Release(processor_service); + + device2 = create_device(d3d, window); + hr = IDirect3DDeviceManager9_ResetDevice(manager, device2, token); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, &IID_IDirectXVideoProcessorService, + (void **)&processor_service); +todo_wine + ok(hr == DXVA2_E_NEW_VIDEO_DEVICE, "Unexpected hr %#x.\n", hr); + + hr = IDirect3DDeviceManager9_TestDevice(manager, handle); +todo_wine + ok(hr == DXVA2_E_NEW_VIDEO_DEVICE, "Unexpected hr %#x.\n", hr); + + IDirect3DDevice9_Release(device); + IDirect3DDevice9_Release(device2); + + IDirect3DDeviceManager9_Release(manager); + +done: + IDirect3D9_Release(d3d); + DestroyWindow(window); +} + +START_TEST(dxva2) +{ + test_device_manager(); +}