[PATCH 10/10] gdi32/tests: Add D3DKMTCheckOcclusion tests.
Zhiyi Zhang
zzhang at codeweavers.com
Wed May 15 08:44:46 CDT 2019
Mostly to show that D3DKMTCheckOcclusion is mainly composed of
ownership checks rather than actually window occlusion. Also
composition status doesn't affect its behavior despite MSDN
say so.
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/gdi32/tests/Makefile.in | 2 +-
dlls/gdi32/tests/driver.c | 382 +++++++++++++++++++++++++++++++++++
2 files changed, 383 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in
index 9d82c278e9..6c32f22c1d 100644
--- a/dlls/gdi32/tests/Makefile.in
+++ b/dlls/gdi32/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = gdi32.dll
-IMPORTS = user32 gdi32 advapi32
+IMPORTS = user32 gdi32 advapi32 d3d10_1 dxgi
C_SRCS = \
bitmap.c \
diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c
index 81c41a1454..b4564c58ee 100644
--- a/dlls/gdi32/tests/driver.c
+++ b/dlls/gdi32/tests/driver.c
@@ -27,12 +27,18 @@
#include "wingdi.h"
#include "winuser.h"
#include "winternl.h"
+#include "dwmapi.h"
+#define COBJMACROS
+#include "initguid.h"
+#include "dxgi1_6.h"
+#include <d3d11.h>
#include "ddk/d3dkmthk.h"
#include "wine/test.h"
static const WCHAR display1W[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
+static NTSTATUS (WINAPI *pD3DKMTCheckOcclusion)(const D3DKMT_CHECKOCCLUSION *);
static NTSTATUS (WINAPI *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *);
static NTSTATUS (WINAPI *pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *);
static NTSTATUS (WINAPI *pD3DKMTCreateDevice)(D3DKMT_CREATEDEVICE *);
@@ -40,6 +46,59 @@ static NTSTATUS (WINAPI *pD3DKMTDestroyDevice)(const D3DKMT_DESTROYDEVICE *);
static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromGdiDisplayName)(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *);
static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromHdc)(D3DKMT_OPENADAPTERFROMHDC *);
static NTSTATUS (WINAPI *pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *);
+static HRESULT (WINAPI *pDwmEnableComposition)(UINT);
+
+static IDXGIAdapter *create_adapter(void)
+{
+ IDXGIFactory *factory;
+ IDXGIAdapter *adapter;
+ HRESULT hr;
+
+ if (FAILED(hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory)))
+ {
+ trace("Failed to create IDXGIFactory, hr %#x.\n", hr);
+ return NULL;
+ }
+
+ adapter = NULL;
+ hr = IDXGIFactory_EnumAdapters(factory, 0, &adapter);
+ IDXGIFactory_Release(factory);
+ if (FAILED(hr))
+ trace("Failed to get adapter, hr %#x.\n", hr);
+ return adapter;
+}
+
+static IDXGIDevice *create_device(unsigned int flags)
+{
+ IDXGIDevice *dxgi_device;
+ ID3D10Device1 *device;
+ IDXGIAdapter *adapter;
+ HRESULT hr;
+
+ adapter = create_adapter();
+ hr = D3D10CreateDevice1(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_FEATURE_LEVEL_10_0,
+ D3D10_1_SDK_VERSION, &device);
+ if (adapter)
+ IDXGIAdapter_Release(adapter);
+ if (SUCCEEDED(hr))
+ goto success;
+
+ if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_WARP, NULL, flags, D3D10_FEATURE_LEVEL_10_0,
+ D3D10_1_SDK_VERSION, &device)))
+ goto success;
+ if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL, flags, D3D10_FEATURE_LEVEL_10_0,
+ D3D10_1_SDK_VERSION, &device)))
+ goto success;
+
+ return NULL;
+
+success:
+ hr = ID3D10Device1_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device);
+ ok(SUCCEEDED(hr), "Created device does not implement IDXGIDevice\n");
+ ID3D10Device1_Release(device);
+
+ return dxgi_device;
+}
static void test_D3DKMTOpenAdapterFromGdiDisplayName(void)
{
@@ -603,10 +662,328 @@ static void test_D3DKMTSetVidPnSourceOwner(void)
ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
}
+static void test_D3DKMTCheckOcclusion(void)
+{
+ static const DWORD timeout = 2000;
+ DISPLAY_DEVICEW display_device = {sizeof(display_device)};
+ D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
+ D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP check_owner_desc;
+ D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc;
+ D3DKMT_DESTROYDEVICE destroy_device_desc;
+ D3DKMT_VIDPNSOURCEOWNER_TYPE owner_type;
+ D3DKMT_CLOSEADAPTER close_adapter_desc;
+ D3DKMT_CREATEDEVICE create_device_desc;
+ D3DKMT_CHECKOCCLUSION occlusion_desc;
+ DXGI_SWAP_CHAIN_DESC swapchain_desc;
+ NTSTATUS expected_occlusion, status;
+ INT i, adapter_count = 0;
+ IDXGISwapChain *swapchain;
+ IDXGIFactory *factory;
+ IDXGIAdapter *adapter;
+ IDXGIDevice *device;
+ HWND hwnd, hwnd2;
+ HRESULT hr;
+
+ if (!pD3DKMTCheckOcclusion || pD3DKMTCheckOcclusion(NULL) == STATUS_PROCEDURE_NOT_FOUND)
+ {
+ skip("D3DKMTCheckOcclusion() is unavailable.\n");
+ return;
+ }
+
+ /* NULL parameter check */
+ status = pD3DKMTCheckOcclusion(NULL);
+ ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
+
+ occlusion_desc.hWnd = NULL;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
+
+ hwnd = CreateWindowA("static", "static1", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 200, 200, 0, 0, 0, 0);
+ ok(hwnd != NULL, "Failed to create window.\n");
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ /* Minimized state doesn't affect D3DKMTCheckOcclusion */
+ ShowWindow(hwnd, SW_MINIMIZE);
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+
+ /* Invisible state doesn't affect D3DKMTCheckOcclusion */
+ ShowWindow(hwnd, SW_HIDE);
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+ ShowWindow(hwnd, SW_SHOW);
+
+ /* hwnd2 covers hwnd */
+ hwnd2 = CreateWindowA("static", "static2", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 200, 200, 0, 0, 0, 0);
+ ok(hwnd2 != NULL, "Failed to create window.\n");
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ occlusion_desc.hWnd = hwnd2;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ /* Composition doesn't affect D3DKMTCheckOcclusion */
+ if (pDwmEnableComposition)
+ {
+ hr = pDwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
+ ok(hr == S_OK, "Failed to disable composition.\n");
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ /* This result means that D3DKMTCheckOcclusion doesn't check composition status despite MSDN says it will */
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ occlusion_desc.hWnd = hwnd2;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ ShowWindow(hwnd, SW_MINIMIZE);
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+
+ ShowWindow(hwnd, SW_HIDE);
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+ ShowWindow(hwnd, SW_SHOW);
+
+ hr = pDwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
+ ok(hr == S_OK, "Failed to enable composition.\n");
+ }
+ else
+ skip("Skip testing composition.\n");
+
+ DestroyWindow(hwnd2);
+
+ if (!(pD3DKMTCheckVidPnExclusiveOwnership && pD3DKMTCloseAdapter && pD3DKMTCreateDevice && pD3DKMTDestroyDevice
+ && pD3DKMTOpenAdapterFromGdiDisplayName && pD3DKMTSetVidPnSourceOwner))
+ {
+ skip("Required functions are unavailable.\n");
+ goto done;
+ }
+
+ lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
+ status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ memset(&create_device_desc, 0, sizeof(create_device_desc));
+ create_device_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ status = pD3DKMTCreateDevice(&create_device_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
+ status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ /* Test swapchain fullscreen mode relationship with D3DKMTCheckOcclusion */
+ if (!(device = create_device(0)))
+ {
+ skip("Failed to create device.\n");
+ goto done;
+ }
+
+ hr = IDXGIDevice_GetAdapter(device, &adapter);
+ ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
+
+ hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
+ ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
+
+ memset(&swapchain_desc, 0, sizeof(swapchain_desc));
+ swapchain_desc.BufferDesc.Width = 800;
+ swapchain_desc.BufferDesc.Height = 600;
+ swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
+ swapchain_desc.BufferDesc.RefreshRate.Denominator = 60;
+ swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+ swapchain_desc.SampleDesc.Count = 1;
+ swapchain_desc.SampleDesc.Quality = 0;
+ swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapchain_desc.BufferCount = 1;
+ swapchain_desc.OutputWindow = hwnd;
+ swapchain_desc.Windowed = TRUE;
+ swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+ swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+ hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
+ ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
+
+ for (i = 0; EnumDisplayDevicesW(NULL, i, &display_device, 0); ++i)
+ {
+ if ((display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
+ adapter_count++;
+ }
+ /* STATUS_GRAPHICS_PRESENT_OCCLUDED on single monitor system. STATUS_SUCCESS on multiple monitor system. */
+ expected_occlusion = adapter_count > 1 ? STATUS_SUCCESS : STATUS_GRAPHICS_PRESENT_OCCLUDED;
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+ ok(SUCCEEDED(hr), "Failed to SetFullscreenState.\n");
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
+
+ check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
+ status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
+ ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#x.\n", status);
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(SUCCEEDED(hr), "Failed to SetFullscreenState.\n");
+ /* Leaving fullscreen could take several seconds to complete, wait a while to get accurate results for
+ * D3DKMTCheckOcclusion and D3DKMTCheckVidPnExclusiveOwnership. */
+ Sleep(timeout);
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
+ status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+ ok(SUCCEEDED(hr), "Failed to SetFullscreenState.\n");
+
+ /* Invisible window, even HWND_TOP, doesn't break swapchain out of fullscreen, and doesn't change video present
+ * network ownership */
+ hwnd2 = CreateWindowA("static", "static2", WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, 0, 0);
+ ok(hwnd2 != NULL, "Failed to create window.\n");
+ SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
+
+ check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
+ status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
+ ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#x.\n", status);
+
+ /* Visible window, even with HWND_BOTTOM, breaks swapchain out of fullscreen */
+ SetWindowPos(hwnd2, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ ShowWindow(hwnd2, SW_SHOW);
+ Sleep(timeout);
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
+ status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(SUCCEEDED(hr), "Failed to SetFullscreenState.\n");
+ Sleep(timeout);
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
+ status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ IDXGISwapChain_Release(swapchain);
+ IDXGIAdapter_Release(adapter);
+ IDXGIDevice_Release(device);
+ IDXGIFactory_Release(factory);
+
+ /* Test D3DKMTCheckOcclusion relationship with video present source owner */
+ set_owner_desc.hDevice = create_device_desc.hDevice;
+ owner_type = D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE;
+ set_owner_desc.pType = &owner_type;
+ set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
+ set_owner_desc.VidPnSourceCount = 1;
+ status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
+
+ /* Note hwnd2 is not actually occluded but D3DKMTCheckOcclusion reports STATUS_GRAPHICS_PRESENT_OCCLUDED as well */
+ SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ ShowWindow(hwnd2, SW_SHOW);
+ occlusion_desc.hWnd = hwnd2;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
+
+ /* Now hwnd is HWND_TOPMOST. Still reports STATUS_GRAPHICS_PRESENT_OCCLUDED */
+ ok(SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE), "Failed to SetWindowPos.\n");
+ ok(GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "No WS_EX_TOPMOST style.\n");
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
+
+ DestroyWindow(hwnd2);
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
+
+ check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
+ status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
+ ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#x.\n", status);
+
+ /* Unset video present source owner */
+ set_owner_desc.hDevice = create_device_desc.hDevice;
+ set_owner_desc.pType = NULL;
+ set_owner_desc.pVidPnSourceId = NULL;
+ set_owner_desc.VidPnSourceCount = 0;
+ status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ occlusion_desc.hWnd = hwnd;
+ status = pD3DKMTCheckOcclusion(&occlusion_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+ check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
+ status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
+ /* D3DKMTCheckVidPnExclusiveOwnership gets STATUS_GRAPHICS_PRESENT_UNOCCLUDED sometimes and with some delay,
+ * it will always return STATUS_SUCCESS. So there are some timing issues here. */
+ ok(status == STATUS_SUCCESS || status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED, "Got unexpected return code %#x.\n", status);
+
+ destroy_device_desc.hDevice = create_device_desc.hDevice;
+ status = pD3DKMTDestroyDevice(&destroy_device_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+
+done:
+ if (pD3DKMTCloseAdapter)
+ {
+ close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
+ status = pD3DKMTCloseAdapter(&close_adapter_desc);
+ ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
+ }
+ DestroyWindow(hwnd);
+}
+
START_TEST(driver)
{
HMODULE gdi32 = LoadLibraryA("gdi32.dll");
+ HMODULE dwmapi = LoadLibraryA("dwmapi.dll");
+ pD3DKMTCheckOcclusion = (void *)GetProcAddress(gdi32, "D3DKMTCheckOcclusion");
pD3DKMTCheckVidPnExclusiveOwnership = (void *)GetProcAddress(gdi32, "D3DKMTCheckVidPnExclusiveOwnership");
pD3DKMTCloseAdapter = (void *)GetProcAddress(gdi32, "D3DKMTCloseAdapter");
pD3DKMTCreateDevice = (void *)GetProcAddress(gdi32, "D3DKMTCreateDevice");
@@ -615,6 +992,10 @@ START_TEST(driver)
pD3DKMTOpenAdapterFromHdc = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromHdc");
pD3DKMTSetVidPnSourceOwner = (void *)GetProcAddress(gdi32, "D3DKMTSetVidPnSourceOwner");
+ if (dwmapi)
+ pDwmEnableComposition = (void *)GetProcAddress(dwmapi, "DwmEnableComposition");
+
+ test_D3DKMTCheckOcclusion();
test_D3DKMTCheckVidPnExclusiveOwnership();
test_D3DKMTCloseAdapter();
test_D3DKMTCreateDevice();
@@ -624,4 +1005,5 @@ START_TEST(driver)
test_D3DKMTSetVidPnSourceOwner();
FreeLibrary(gdi32);
+ FreeLibrary(dwmapi);
}
--
2.20.1
More information about the wine-devel
mailing list