mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / gdi32 / tests / driver.c
blobeb0da18b32e9004ae1698964c706475bc11ccd77
1 /*
2 * Unit test suite for kernel mode graphics driver
4 * Copyright 2019 Zhiyi Zhang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winternl.h"
30 #include "dwmapi.h"
31 #include "ddk/d3dkmthk.h"
33 #include "wine/test.h"
35 static const WCHAR display1W[] = L"\\\\.\\DISPLAY1";
37 static NTSTATUS (WINAPI *pD3DKMTCheckOcclusion)(const D3DKMT_CHECKOCCLUSION *);
38 static NTSTATUS (WINAPI *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *);
39 static NTSTATUS (WINAPI *pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *);
40 static NTSTATUS (WINAPI *pD3DKMTCreateDevice)(D3DKMT_CREATEDEVICE *);
41 static NTSTATUS (WINAPI *pD3DKMTDestroyDevice)(const D3DKMT_DESTROYDEVICE *);
42 static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromGdiDisplayName)(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *);
43 static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromHdc)(D3DKMT_OPENADAPTERFROMHDC *);
44 static NTSTATUS (WINAPI *pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *);
45 static HRESULT (WINAPI *pDwmEnableComposition)(UINT);
47 static void test_D3DKMTOpenAdapterFromGdiDisplayName(void)
49 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
50 D3DKMT_CLOSEADAPTER close_adapter_desc;
51 DISPLAY_DEVICEW display_device = {sizeof(display_device)};
52 NTSTATUS status;
53 DWORD i;
55 lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
56 if (!pD3DKMTOpenAdapterFromGdiDisplayName
57 || pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc) == STATUS_PROCEDURE_NOT_FOUND)
59 win_skip("D3DKMTOpenAdapterFromGdiDisplayName() is unavailable.\n");
60 return;
63 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
64 status = pD3DKMTCloseAdapter(&close_adapter_desc);
65 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
67 /* Invalid parameters */
68 status = pD3DKMTOpenAdapterFromGdiDisplayName(NULL);
69 ok(status == STATUS_UNSUCCESSFUL, "Got unexpected return code %#x.\n", status);
71 memset(&open_adapter_gdi_desc, 0, sizeof(open_adapter_gdi_desc));
72 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
73 ok(status == STATUS_UNSUCCESSFUL, "Got unexpected return code %#x.\n", status);
75 /* Open adapter */
76 for (i = 0; EnumDisplayDevicesW(NULL, i, &display_device, 0); ++i)
78 lstrcpyW(open_adapter_gdi_desc.DeviceName, display_device.DeviceName);
79 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
80 if (display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
81 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
82 else
84 ok(status == STATUS_UNSUCCESSFUL, "Got unexpected return code %#x.\n", status);
85 continue;
88 ok(open_adapter_gdi_desc.hAdapter, "Expect not null.\n");
89 ok(open_adapter_gdi_desc.AdapterLuid.LowPart || open_adapter_gdi_desc.AdapterLuid.HighPart,
90 "Expect LUID not zero.\n");
92 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
93 status = pD3DKMTCloseAdapter(&close_adapter_desc);
94 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
98 static void test_D3DKMTOpenAdapterFromHdc(void)
100 DISPLAY_DEVICEW display_device = {sizeof(display_device)};
101 D3DKMT_OPENADAPTERFROMHDC open_adapter_hdc_desc;
102 D3DKMT_CLOSEADAPTER close_adapter_desc;
103 INT adapter_count = 0;
104 NTSTATUS status;
105 HDC hdc;
106 DWORD i;
108 if (!pD3DKMTOpenAdapterFromHdc)
110 win_skip("D3DKMTOpenAdapterFromHdc() is missing.\n");
111 return;
114 /* Invalid parameters */
115 /* Passing a NULL pointer crashes on Windows 10 >= 2004 */
116 if (0) status = pD3DKMTOpenAdapterFromHdc(NULL);
118 memset(&open_adapter_hdc_desc, 0, sizeof(open_adapter_hdc_desc));
119 status = pD3DKMTOpenAdapterFromHdc(&open_adapter_hdc_desc);
120 if (status == STATUS_PROCEDURE_NOT_FOUND)
122 win_skip("D3DKMTOpenAdapterFromHdc() is not supported.\n");
123 return;
125 todo_wine ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
127 /* Open adapter */
128 for (i = 0; EnumDisplayDevicesW(NULL, i, &display_device, 0); ++i)
130 if (!(display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
131 continue;
133 adapter_count++;
135 hdc = CreateDCW(0, display_device.DeviceName, 0, NULL);
136 open_adapter_hdc_desc.hDc = hdc;
137 status = pD3DKMTOpenAdapterFromHdc(&open_adapter_hdc_desc);
138 todo_wine ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
139 todo_wine ok(open_adapter_hdc_desc.hAdapter, "Expect not null.\n");
140 DeleteDC(hdc);
142 if (status == STATUS_SUCCESS)
144 close_adapter_desc.hAdapter = open_adapter_hdc_desc.hAdapter;
145 status = pD3DKMTCloseAdapter(&close_adapter_desc);
146 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
150 /* HDC covering more than two adapters is invalid for D3DKMTOpenAdapterFromHdc */
151 hdc = GetDC(0);
152 open_adapter_hdc_desc.hDc = hdc;
153 status = pD3DKMTOpenAdapterFromHdc(&open_adapter_hdc_desc);
154 ReleaseDC(0, hdc);
155 todo_wine ok(status == (adapter_count > 1 ? STATUS_INVALID_PARAMETER : STATUS_SUCCESS),
156 "Got unexpected return code %#x.\n", status);
157 if (status == STATUS_SUCCESS)
159 close_adapter_desc.hAdapter = open_adapter_hdc_desc.hAdapter;
160 status = pD3DKMTCloseAdapter(&close_adapter_desc);
161 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
165 static void test_D3DKMTCloseAdapter(void)
167 D3DKMT_CLOSEADAPTER close_adapter_desc;
168 NTSTATUS status;
170 if (!pD3DKMTCloseAdapter || pD3DKMTCloseAdapter(NULL) == STATUS_PROCEDURE_NOT_FOUND)
172 win_skip("D3DKMTCloseAdapter() is unavailable.\n");
173 return;
176 /* Invalid parameters */
177 status = pD3DKMTCloseAdapter(NULL);
178 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
180 memset(&close_adapter_desc, 0, sizeof(close_adapter_desc));
181 status = pD3DKMTCloseAdapter(&close_adapter_desc);
182 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
185 static void test_D3DKMTCreateDevice(void)
187 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
188 D3DKMT_CREATEDEVICE create_device_desc;
189 D3DKMT_CLOSEADAPTER close_adapter_desc;
190 D3DKMT_DESTROYDEVICE destroy_device_desc;
191 NTSTATUS status;
193 if (!pD3DKMTCreateDevice || pD3DKMTCreateDevice(NULL) == STATUS_PROCEDURE_NOT_FOUND)
195 win_skip("D3DKMTCreateDevice() is unavailable.\n");
196 return;
199 /* Invalid parameters */
200 status = pD3DKMTCreateDevice(NULL);
201 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
203 memset(&create_device_desc, 0, sizeof(create_device_desc));
204 status = pD3DKMTCreateDevice(&create_device_desc);
205 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
207 lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
208 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
209 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
211 /* Create device */
212 create_device_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
213 status = pD3DKMTCreateDevice(&create_device_desc);
214 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
215 ok(create_device_desc.hDevice, "Expect not null.\n");
216 ok(create_device_desc.pCommandBuffer == NULL, "Expect null.\n");
217 ok(create_device_desc.CommandBufferSize == 0, "Got wrong value %#x.\n", create_device_desc.CommandBufferSize);
218 ok(create_device_desc.pAllocationList == NULL, "Expect null.\n");
219 ok(create_device_desc.AllocationListSize == 0, "Got wrong value %#x.\n", create_device_desc.AllocationListSize);
220 ok(create_device_desc.pPatchLocationList == NULL, "Expect null.\n");
221 ok(create_device_desc.PatchLocationListSize == 0, "Got wrong value %#x.\n", create_device_desc.PatchLocationListSize);
223 destroy_device_desc.hDevice = create_device_desc.hDevice;
224 status = pD3DKMTDestroyDevice(&destroy_device_desc);
225 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
227 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
228 status = pD3DKMTCloseAdapter(&close_adapter_desc);
229 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
232 static void test_D3DKMTDestroyDevice(void)
234 D3DKMT_DESTROYDEVICE destroy_device_desc;
235 NTSTATUS status;
237 if (!pD3DKMTDestroyDevice || pD3DKMTDestroyDevice(NULL) == STATUS_PROCEDURE_NOT_FOUND)
239 win_skip("D3DKMTDestroyDevice() is unavailable.\n");
240 return;
243 /* Invalid parameters */
244 status = pD3DKMTDestroyDevice(NULL);
245 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
247 memset(&destroy_device_desc, 0, sizeof(destroy_device_desc));
248 status = pD3DKMTDestroyDevice(&destroy_device_desc);
249 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
252 static void test_D3DKMTCheckVidPnExclusiveOwnership(void)
254 static const DWORD timeout = 1000;
255 static const DWORD wait_step = 100;
256 D3DKMT_CREATEDEVICE create_device_desc, create_device_desc2;
257 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
258 D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP check_owner_desc;
259 D3DKMT_DESTROYDEVICE destroy_device_desc;
260 D3DKMT_CLOSEADAPTER close_adapter_desc;
261 D3DKMT_VIDPNSOURCEOWNER_TYPE owner_type;
262 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc;
263 DWORD total_time;
264 NTSTATUS status;
265 INT i;
267 /* Test cases using single device */
268 static const struct test_data1
270 D3DKMT_VIDPNSOURCEOWNER_TYPE owner_type;
271 NTSTATUS expected_set_status;
272 NTSTATUS expected_check_status;
273 } tests1[] = {
274 /* 0 */
275 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
276 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
277 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
278 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
279 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
280 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
281 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
282 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVEGDI, STATUS_INVALID_PARAMETER, STATUS_SUCCESS},
283 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
284 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS},
285 /* 10 */
286 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
287 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
288 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
289 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
290 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
291 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
292 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
293 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
294 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
295 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
296 /* 20 */
297 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
298 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS},
299 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
300 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
301 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
302 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
303 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
304 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
305 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
306 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
307 /* 30 */
308 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
309 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
310 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
311 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS},
312 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
313 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
314 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
315 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
316 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
317 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_INVALID_PARAMETER, STATUS_GRAPHICS_PRESENT_OCCLUDED},
318 /* 40 */
319 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
320 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
321 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
322 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
323 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
324 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_INVALID_PARAMETER, STATUS_GRAPHICS_PRESENT_OCCLUDED},
325 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
326 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS},
327 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS},
328 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
329 /* 50 */
330 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS},
331 {D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
332 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
333 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS},
334 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_INVALID_PARAMETER, STATUS_SUCCESS},
335 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
336 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS},
337 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS},
338 {-1, STATUS_SUCCESS, STATUS_SUCCESS},
339 {D3DKMT_VIDPNSOURCEOWNER_EMULATED + 1, STATUS_INVALID_PARAMETER, STATUS_SUCCESS},
342 /* Test cases using two devices consecutively */
343 static const struct test_data2
345 D3DKMT_VIDPNSOURCEOWNER_TYPE set_owner_type1;
346 D3DKMT_VIDPNSOURCEOWNER_TYPE set_owner_type2;
347 NTSTATUS expected_set_status1;
348 NTSTATUS expected_set_status2;
349 NTSTATUS expected_check_status;
350 } tests2[] = {
351 /* 0 */
352 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS, STATUS_SUCCESS},
353 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_SUCCESS, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
354 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
355 {D3DKMT_VIDPNSOURCEOWNER_UNOWNED, D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_SUCCESS, STATUS_SUCCESS},
356 {D3DKMT_VIDPNSOURCEOWNER_SHARED, D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS, STATUS_SUCCESS},
357 {D3DKMT_VIDPNSOURCEOWNER_SHARED, D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
358 {D3DKMT_VIDPNSOURCEOWNER_SHARED, D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
359 {D3DKMT_VIDPNSOURCEOWNER_SHARED, D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS, STATUS_SUCCESS},
360 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
361 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_SUCCESS, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_GRAPHICS_PRESENT_OCCLUDED},
362 /* 10 */
363 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_GRAPHICS_PRESENT_OCCLUDED},
364 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_GRAPHICS_PRESENT_OCCLUDED},
365 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, D3DKMT_VIDPNSOURCEOWNER_UNOWNED, STATUS_SUCCESS, STATUS_SUCCESS, STATUS_SUCCESS},
366 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, D3DKMT_VIDPNSOURCEOWNER_SHARED, STATUS_SUCCESS, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
367 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, STATUS_SUCCESS, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
368 {D3DKMT_VIDPNSOURCEOWNER_EMULATED, D3DKMT_VIDPNSOURCEOWNER_EMULATED, STATUS_SUCCESS, STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE, STATUS_SUCCESS},
369 {-1, D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, -1, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
370 {D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE, -1, STATUS_SUCCESS, STATUS_SUCCESS, STATUS_GRAPHICS_PRESENT_OCCLUDED},
373 if (!pD3DKMTCheckVidPnExclusiveOwnership || pD3DKMTCheckVidPnExclusiveOwnership(NULL) == STATUS_PROCEDURE_NOT_FOUND)
375 skip("D3DKMTCheckVidPnExclusiveOwnership() is unavailable.\n");
376 return;
379 /* Invalid parameters */
380 status = pD3DKMTCheckVidPnExclusiveOwnership(NULL);
381 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
383 memset(&check_owner_desc, 0, sizeof(check_owner_desc));
384 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
385 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
387 /* Test cases */
388 lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
389 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
390 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
392 memset(&create_device_desc, 0, sizeof(create_device_desc));
393 create_device_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
394 status = pD3DKMTCreateDevice(&create_device_desc);
395 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
397 check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
398 check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
399 for (i = 0; i < ARRAY_SIZE(tests1); ++i)
401 set_owner_desc.hDevice = create_device_desc.hDevice;
402 if (tests1[i].owner_type != -1)
404 owner_type = tests1[i].owner_type;
405 set_owner_desc.pType = &owner_type;
406 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
407 set_owner_desc.VidPnSourceCount = 1;
409 else
411 set_owner_desc.pType = NULL;
412 set_owner_desc.pVidPnSourceId = NULL;
413 set_owner_desc.VidPnSourceCount = 0;
415 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
416 ok(status == tests1[i].expected_set_status ||
417 /* win8 doesn't support D3DKMT_VIDPNSOURCEOWNER_EMULATED */
418 (status == STATUS_INVALID_PARAMETER && tests1[i].owner_type == D3DKMT_VIDPNSOURCEOWNER_EMULATED)
419 || (status == STATUS_SUCCESS && tests1[i].owner_type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
420 && tests1[i - 1].owner_type == D3DKMT_VIDPNSOURCEOWNER_EMULATED),
421 "Got unexpected return code %#x at test %d.\n", status, i);
423 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
424 /* If don't sleep, D3DKMTCheckVidPnExclusiveOwnership may get STATUS_GRAPHICS_PRESENT_UNOCCLUDED instead
425 * of STATUS_SUCCESS */
426 if ((tests1[i].expected_check_status == STATUS_SUCCESS && status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED))
428 total_time = 0;
431 Sleep(wait_step);
432 total_time += wait_step;
433 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
434 } while (status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED && total_time < timeout);
436 ok(status == tests1[i].expected_check_status
437 || (status == STATUS_GRAPHICS_PRESENT_OCCLUDED /* win8 */
438 && tests1[i].owner_type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
439 && tests1[i - 1].owner_type == D3DKMT_VIDPNSOURCEOWNER_EMULATED),
440 "Got unexpected return code %#x at test %d.\n", status, i);
443 /* Set owner and unset owner using different devices */
444 memset(&create_device_desc2, 0, sizeof(create_device_desc2));
445 create_device_desc2.hAdapter = open_adapter_gdi_desc.hAdapter;
446 status = pD3DKMTCreateDevice(&create_device_desc2);
447 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
449 /* Set owner with the first device */
450 set_owner_desc.hDevice = create_device_desc.hDevice;
451 owner_type = D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE;
452 set_owner_desc.pType = &owner_type;
453 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
454 set_owner_desc.VidPnSourceCount = 1;
455 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
456 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
457 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
458 ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#x.\n", status);
460 /* Unset owner with the second device */
461 set_owner_desc.hDevice = create_device_desc2.hDevice;
462 set_owner_desc.pType = NULL;
463 set_owner_desc.pVidPnSourceId = NULL;
464 set_owner_desc.VidPnSourceCount = 0;
465 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
466 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
467 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
468 /* No effect */
469 ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#x.\n", status);
471 /* Unset owner with the first device */
472 set_owner_desc.hDevice = create_device_desc.hDevice;
473 set_owner_desc.pType = NULL;
474 set_owner_desc.pVidPnSourceId = NULL;
475 set_owner_desc.VidPnSourceCount = 0;
476 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
477 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
478 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
479 /* Proves that the correct device is needed to unset owner */
480 ok(status == STATUS_SUCCESS || status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED, "Got unexpected return code %#x.\n",
481 status);
483 /* Set owner with the first device, set owner again with the second device */
484 for (i = 0; i < ARRAY_SIZE(tests2); ++i)
486 if (tests2[i].set_owner_type1 != -1)
488 set_owner_desc.hDevice = create_device_desc.hDevice;
489 owner_type = tests2[i].set_owner_type1;
490 set_owner_desc.pType = &owner_type;
491 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
492 set_owner_desc.VidPnSourceCount = 1;
493 /* If don't sleep, D3DKMTSetVidPnSourceOwner may return STATUS_OK for D3DKMT_VIDPNSOURCEOWNER_SHARED.
494 * Other owner type doesn't seems to be affected. */
495 if (tests2[i].set_owner_type1 == D3DKMT_VIDPNSOURCEOWNER_SHARED)
496 Sleep(timeout);
497 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
498 ok(status == tests2[i].expected_set_status1
499 || (status == STATUS_INVALID_PARAMETER /* win8 */
500 && tests2[i].set_owner_type1 == D3DKMT_VIDPNSOURCEOWNER_EMULATED),
501 "Got unexpected return code %#x at test %d.\n", status, i);
504 if (tests2[i].set_owner_type2 != -1)
506 set_owner_desc.hDevice = create_device_desc2.hDevice;
507 owner_type = tests2[i].set_owner_type2;
508 set_owner_desc.pType = &owner_type;
509 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
510 set_owner_desc.VidPnSourceCount = 1;
511 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
512 ok(status == tests2[i].expected_set_status2
513 || (status == STATUS_INVALID_PARAMETER /* win8 */
514 && tests2[i].set_owner_type2 == D3DKMT_VIDPNSOURCEOWNER_EMULATED)
515 || (status == STATUS_SUCCESS && tests2[i].set_owner_type1 == D3DKMT_VIDPNSOURCEOWNER_EMULATED
516 && tests2[i].set_owner_type2 == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE),
517 "Got unexpected return code %#x at test %d.\n", status, i);
520 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
521 if ((tests2[i].expected_check_status == STATUS_SUCCESS && status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED))
523 total_time = 0;
526 Sleep(wait_step);
527 total_time += wait_step;
528 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
529 } while (status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED && total_time < timeout);
531 ok(status == tests2[i].expected_check_status
532 || (status == STATUS_GRAPHICS_PRESENT_OCCLUDED /* win8 */
533 && tests2[i].set_owner_type2 == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
534 && tests2[i].set_owner_type1 == D3DKMT_VIDPNSOURCEOWNER_EMULATED),
535 "Got unexpected return code %#x at test %d.\n", status, i);
537 /* Unset owner with first device */
538 if (tests2[i].set_owner_type1 != -1)
540 set_owner_desc.hDevice = create_device_desc.hDevice;
541 set_owner_desc.pType = NULL;
542 set_owner_desc.pVidPnSourceId = NULL;
543 set_owner_desc.VidPnSourceCount = 0;
544 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
545 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x at test %d.\n", status, i);
548 /* Unset owner with second device */
549 if (tests2[i].set_owner_type2 != -1)
551 set_owner_desc.hDevice = create_device_desc2.hDevice;
552 set_owner_desc.pType = NULL;
553 set_owner_desc.pVidPnSourceId = NULL;
554 set_owner_desc.VidPnSourceCount = 0;
555 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
556 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x at test %d.\n", status, i);
560 /* Destroy devices holding ownership */
561 set_owner_desc.hDevice = create_device_desc.hDevice;
562 owner_type = D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE;
563 set_owner_desc.pType = &owner_type;
564 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
565 set_owner_desc.VidPnSourceCount = 1;
566 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
567 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
569 destroy_device_desc.hDevice = create_device_desc.hDevice;
570 status = pD3DKMTDestroyDevice(&destroy_device_desc);
571 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
573 set_owner_desc.hDevice = create_device_desc2.hDevice;
574 owner_type = D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE;
575 set_owner_desc.pType = &owner_type;
576 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
577 set_owner_desc.VidPnSourceCount = 1;
578 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
579 /* So ownership is released when device is destroyed. otherwise the return code should be
580 * STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE */
581 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
583 destroy_device_desc.hDevice = create_device_desc2.hDevice;
584 status = pD3DKMTDestroyDevice(&destroy_device_desc);
585 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
587 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
588 status = pD3DKMTCloseAdapter(&close_adapter_desc);
589 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
592 static void test_D3DKMTSetVidPnSourceOwner(void)
594 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc = {0};
595 NTSTATUS status;
597 if (!pD3DKMTSetVidPnSourceOwner || pD3DKMTSetVidPnSourceOwner(&set_owner_desc) == STATUS_PROCEDURE_NOT_FOUND)
599 skip("D3DKMTSetVidPnSourceOwner() is unavailable.\n");
600 return;
603 /* Invalid parameters */
604 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
605 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
608 static void test_D3DKMTCheckOcclusion(void)
610 DISPLAY_DEVICEW display_device = {sizeof(display_device)};
611 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
612 D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP check_owner_desc;
613 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc;
614 D3DKMT_DESTROYDEVICE destroy_device_desc;
615 D3DKMT_VIDPNSOURCEOWNER_TYPE owner_type;
616 D3DKMT_CLOSEADAPTER close_adapter_desc;
617 D3DKMT_CREATEDEVICE create_device_desc;
618 D3DKMT_CHECKOCCLUSION occlusion_desc;
619 NTSTATUS expected_occlusion, status;
620 INT i, adapter_count = 0;
621 HWND hwnd, hwnd2;
622 HRESULT hr;
624 if (!pD3DKMTCheckOcclusion || pD3DKMTCheckOcclusion(NULL) == STATUS_PROCEDURE_NOT_FOUND)
626 skip("D3DKMTCheckOcclusion() is unavailable.\n");
627 return;
630 /* NULL parameter check */
631 status = pD3DKMTCheckOcclusion(NULL);
632 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
634 occlusion_desc.hWnd = NULL;
635 status = pD3DKMTCheckOcclusion(&occlusion_desc);
636 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#x.\n", status);
638 hwnd = CreateWindowA("static", "static1", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 200, 200, 0, 0, 0, 0);
639 ok(hwnd != NULL, "Failed to create window.\n");
641 occlusion_desc.hWnd = hwnd;
642 status = pD3DKMTCheckOcclusion(&occlusion_desc);
643 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
645 /* Minimized state doesn't affect D3DKMTCheckOcclusion */
646 ShowWindow(hwnd, SW_MINIMIZE);
647 occlusion_desc.hWnd = hwnd;
648 status = pD3DKMTCheckOcclusion(&occlusion_desc);
649 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
650 ShowWindow(hwnd, SW_SHOWNORMAL);
652 /* Invisible state doesn't affect D3DKMTCheckOcclusion */
653 ShowWindow(hwnd, SW_HIDE);
654 occlusion_desc.hWnd = hwnd;
655 status = pD3DKMTCheckOcclusion(&occlusion_desc);
656 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
657 ShowWindow(hwnd, SW_SHOW);
659 /* hwnd2 covers hwnd */
660 hwnd2 = CreateWindowA("static", "static2", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 200, 200, 0, 0, 0, 0);
661 ok(hwnd2 != NULL, "Failed to create window.\n");
663 occlusion_desc.hWnd = hwnd;
664 status = pD3DKMTCheckOcclusion(&occlusion_desc);
665 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
667 occlusion_desc.hWnd = hwnd2;
668 status = pD3DKMTCheckOcclusion(&occlusion_desc);
669 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
671 /* Composition doesn't affect D3DKMTCheckOcclusion */
672 if (pDwmEnableComposition)
674 hr = pDwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
675 ok(hr == S_OK, "Failed to disable composition.\n");
677 occlusion_desc.hWnd = hwnd;
678 status = pD3DKMTCheckOcclusion(&occlusion_desc);
679 /* This result means that D3DKMTCheckOcclusion doesn't check composition status despite MSDN says it will */
680 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
682 occlusion_desc.hWnd = hwnd2;
683 status = pD3DKMTCheckOcclusion(&occlusion_desc);
684 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
686 ShowWindow(hwnd, SW_MINIMIZE);
687 occlusion_desc.hWnd = hwnd;
688 status = pD3DKMTCheckOcclusion(&occlusion_desc);
689 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
690 ShowWindow(hwnd, SW_SHOWNORMAL);
692 ShowWindow(hwnd, SW_HIDE);
693 occlusion_desc.hWnd = hwnd;
694 status = pD3DKMTCheckOcclusion(&occlusion_desc);
695 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
696 ShowWindow(hwnd, SW_SHOW);
698 hr = pDwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
699 ok(hr == S_OK, "Failed to enable composition.\n");
701 else
702 skip("Skip testing composition.\n");
704 lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
705 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
706 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
708 memset(&create_device_desc, 0, sizeof(create_device_desc));
709 create_device_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
710 status = pD3DKMTCreateDevice(&create_device_desc);
711 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
713 check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
714 check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
715 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
716 /* D3DKMTCheckVidPnExclusiveOwnership gets STATUS_GRAPHICS_PRESENT_UNOCCLUDED sometimes and with some delay,
717 * it will always return STATUS_SUCCESS. So there are some timing issues here. */
718 ok(status == STATUS_SUCCESS || status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED, "Got unexpected return code %#x.\n", status);
720 /* Test D3DKMTCheckOcclusion relationship with video present source owner */
721 set_owner_desc.hDevice = create_device_desc.hDevice;
722 owner_type = D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE;
723 set_owner_desc.pType = &owner_type;
724 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
725 set_owner_desc.VidPnSourceCount = 1;
726 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
727 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
729 for (i = 0; EnumDisplayDevicesW(NULL, i, &display_device, 0); ++i)
731 if ((display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
732 adapter_count++;
734 /* STATUS_GRAPHICS_PRESENT_OCCLUDED on single monitor system. STATUS_SUCCESS on multiple monitor system. */
735 expected_occlusion = adapter_count > 1 ? STATUS_SUCCESS : STATUS_GRAPHICS_PRESENT_OCCLUDED;
737 occlusion_desc.hWnd = hwnd;
738 status = pD3DKMTCheckOcclusion(&occlusion_desc);
739 ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
741 /* Note hwnd2 is not actually occluded but D3DKMTCheckOcclusion reports STATUS_GRAPHICS_PRESENT_OCCLUDED as well */
742 SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
743 ShowWindow(hwnd2, SW_SHOW);
744 occlusion_desc.hWnd = hwnd2;
745 status = pD3DKMTCheckOcclusion(&occlusion_desc);
746 ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
748 /* Now hwnd is HWND_TOPMOST. Still reports STATUS_GRAPHICS_PRESENT_OCCLUDED */
749 ok(SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE), "Failed to SetWindowPos.\n");
750 ok(GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "No WS_EX_TOPMOST style.\n");
751 occlusion_desc.hWnd = hwnd;
752 status = pD3DKMTCheckOcclusion(&occlusion_desc);
753 ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
755 DestroyWindow(hwnd2);
756 occlusion_desc.hWnd = hwnd;
757 status = pD3DKMTCheckOcclusion(&occlusion_desc);
758 ok(status == expected_occlusion, "Got unexpected return code %#x.\n", status);
760 check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
761 check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
762 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
763 ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#x.\n", status);
765 /* Unset video present source owner */
766 set_owner_desc.hDevice = create_device_desc.hDevice;
767 set_owner_desc.pType = NULL;
768 set_owner_desc.pVidPnSourceId = NULL;
769 set_owner_desc.VidPnSourceCount = 0;
770 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
771 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
773 occlusion_desc.hWnd = hwnd;
774 status = pD3DKMTCheckOcclusion(&occlusion_desc);
775 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
777 check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
778 check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
779 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
780 ok(status == STATUS_SUCCESS || status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED, "Got unexpected return code %#x.\n", status);
782 destroy_device_desc.hDevice = create_device_desc.hDevice;
783 status = pD3DKMTDestroyDevice(&destroy_device_desc);
784 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
786 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
787 status = pD3DKMTCloseAdapter(&close_adapter_desc);
788 ok(status == STATUS_SUCCESS, "Got unexpected return code %#x.\n", status);
789 DestroyWindow(hwnd);
792 START_TEST(driver)
794 HMODULE gdi32 = GetModuleHandleA("gdi32.dll");
795 HMODULE dwmapi = LoadLibraryA("dwmapi.dll");
797 pD3DKMTCheckOcclusion = (void *)GetProcAddress(gdi32, "D3DKMTCheckOcclusion");
798 pD3DKMTCheckVidPnExclusiveOwnership = (void *)GetProcAddress(gdi32, "D3DKMTCheckVidPnExclusiveOwnership");
799 pD3DKMTCloseAdapter = (void *)GetProcAddress(gdi32, "D3DKMTCloseAdapter");
800 pD3DKMTCreateDevice = (void *)GetProcAddress(gdi32, "D3DKMTCreateDevice");
801 pD3DKMTDestroyDevice = (void *)GetProcAddress(gdi32, "D3DKMTDestroyDevice");
802 pD3DKMTOpenAdapterFromGdiDisplayName = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromGdiDisplayName");
803 pD3DKMTOpenAdapterFromHdc = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromHdc");
804 pD3DKMTSetVidPnSourceOwner = (void *)GetProcAddress(gdi32, "D3DKMTSetVidPnSourceOwner");
806 if (dwmapi)
807 pDwmEnableComposition = (void *)GetProcAddress(dwmapi, "DwmEnableComposition");
809 test_D3DKMTOpenAdapterFromGdiDisplayName();
810 test_D3DKMTOpenAdapterFromHdc();
811 test_D3DKMTCloseAdapter();
812 test_D3DKMTCreateDevice();
813 test_D3DKMTDestroyDevice();
814 test_D3DKMTCheckVidPnExclusiveOwnership();
815 test_D3DKMTSetVidPnSourceOwner();
816 test_D3DKMTCheckOcclusion();
818 FreeLibrary(dwmapi);