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
24 #define WIN32_NO_STATUS
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
)};
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");
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
);
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
);
84 ok(status
== STATUS_UNSUCCESSFUL
, "Got unexpected return code %#x.\n", status
);
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;
108 if (!pD3DKMTOpenAdapterFromHdc
)
110 win_skip("D3DKMTOpenAdapterFromHdc() is missing.\n");
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");
125 todo_wine
ok(status
== STATUS_INVALID_PARAMETER
, "Got unexpected return code %#x.\n", status
);
128 for (i
= 0; EnumDisplayDevicesW(NULL
, i
, &display_device
, 0); ++i
)
130 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
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");
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 */
152 open_adapter_hdc_desc
.hDc
= hdc
;
153 status
= pD3DKMTOpenAdapterFromHdc(&open_adapter_hdc_desc
);
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
;
170 if (!pD3DKMTCloseAdapter
|| pD3DKMTCloseAdapter(NULL
) == STATUS_PROCEDURE_NOT_FOUND
)
172 win_skip("D3DKMTCloseAdapter() is unavailable.\n");
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
;
193 if (!pD3DKMTCreateDevice
|| pD3DKMTCreateDevice(NULL
) == STATUS_PROCEDURE_NOT_FOUND
)
195 win_skip("D3DKMTCreateDevice() is unavailable.\n");
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
);
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
;
237 if (!pD3DKMTDestroyDevice
|| pD3DKMTDestroyDevice(NULL
) == STATUS_PROCEDURE_NOT_FOUND
)
239 win_skip("D3DKMTDestroyDevice() is unavailable.\n");
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
;
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
;
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
},
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
},
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
},
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
},
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
},
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
;
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
},
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");
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
);
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;
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
))
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
);
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",
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
)
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
))
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};
597 if (!pD3DKMTSetVidPnSourceOwner
|| pD3DKMTSetVidPnSourceOwner(&set_owner_desc
) == STATUS_PROCEDURE_NOT_FOUND
)
599 skip("D3DKMTSetVidPnSourceOwner() is unavailable.\n");
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;
624 if (!pD3DKMTCheckOcclusion
|| pD3DKMTCheckOcclusion(NULL
) == STATUS_PROCEDURE_NOT_FOUND
)
626 skip("D3DKMTCheckOcclusion() is unavailable.\n");
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");
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
))
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
);
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");
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();