ReactOS 0.4.17-dev-116-ga4b6fe9
driver.c
Go to the documentation of this file.
1/*
2 * Unit test suite for kernel mode graphics driver
3 *
4 * Copyright 2019 Zhiyi Zhang
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include <stdarg.h>
22
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"
32#include "initguid.h"
33#include "setupapi.h"
34#include "ntddvdeo.h"
35#include "devpkey.h"
36#include "cfgmgr32.h"
37
38#include "wine/test.h"
39
40static const WCHAR display1W[] = L"\\\\.\\DISPLAY1";
41
42DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2);
43
44static NTSTATUS (WINAPI *pD3DKMTCheckOcclusion)(const D3DKMT_CHECKOCCLUSION *);
45static NTSTATUS (WINAPI *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *);
46static NTSTATUS (WINAPI *pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *);
47static NTSTATUS (WINAPI *pD3DKMTCreateDevice)(D3DKMT_CREATEDEVICE *);
48static NTSTATUS (WINAPI *pD3DKMTDestroyDevice)(const D3DKMT_DESTROYDEVICE *);
49static NTSTATUS (WINAPI *pD3DKMTEnumAdapters2)(D3DKMT_ENUMADAPTERS2 *);
50static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromDeviceName)(D3DKMT_OPENADAPTERFROMDEVICENAME *);
51static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromGdiDisplayName)(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *);
52static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromHdc)(D3DKMT_OPENADAPTERFROMHDC *);
53static NTSTATUS (WINAPI *pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *);
54static NTSTATUS (WINAPI *pD3DKMTQueryVideoMemoryInfo)(D3DKMT_QUERYVIDEOMEMORYINFO *);
55static HRESULT (WINAPI *pDwmEnableComposition)(UINT);
56
58{
60 DWORD adapter_idx;
61
62 dd.cb = sizeof(dd);
63 for (adapter_idx = 0; EnumDisplayDevicesW(NULL, adapter_idx, &dd, 0); ++adapter_idx)
64 {
66 {
68 return TRUE;
69 }
70 }
71
72 return FALSE;
73}
74
76{
77 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
78 D3DKMT_CLOSEADAPTER close_adapter_desc;
79 DISPLAY_DEVICEW display_device = {sizeof(display_device)};
81 DWORD i;
82
83 lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
84 if (!pD3DKMTOpenAdapterFromGdiDisplayName
85 || pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc) == STATUS_PROCEDURE_NOT_FOUND)
86 {
87 win_skip("D3DKMTOpenAdapterFromGdiDisplayName() is unavailable.\n");
88 return;
89 }
90
91 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
92 status = pD3DKMTCloseAdapter(&close_adapter_desc);
93 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
94
95 /* Invalid parameters */
96 status = pD3DKMTOpenAdapterFromGdiDisplayName(NULL);
97 ok(status == STATUS_UNSUCCESSFUL, "Got unexpected return code %#lx.\n", status);
98
99 memset(&open_adapter_gdi_desc, 0, sizeof(open_adapter_gdi_desc));
100 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
101 ok(status == STATUS_UNSUCCESSFUL, "Got unexpected return code %#lx.\n", status);
102
103 /* Open adapter */
104 for (i = 0; EnumDisplayDevicesW(NULL, i, &display_device, 0); ++i)
105 {
106 lstrcpyW(open_adapter_gdi_desc.DeviceName, display_device.DeviceName);
107 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
109 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
110 else
111 {
112 ok(status == STATUS_UNSUCCESSFUL, "Got unexpected return code %#lx.\n", status);
113 continue;
114 }
115
116 ok(open_adapter_gdi_desc.hAdapter, "Expect not null.\n");
117 ok(open_adapter_gdi_desc.AdapterLuid.LowPart || open_adapter_gdi_desc.AdapterLuid.HighPart,
118 "Expect LUID not zero.\n");
119
120 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
121 status = pD3DKMTCloseAdapter(&close_adapter_desc);
122 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
123 }
124}
125
127{
128 DISPLAY_DEVICEW display_device = {sizeof(display_device)};
129 D3DKMT_OPENADAPTERFROMHDC open_adapter_hdc_desc;
130 D3DKMT_CLOSEADAPTER close_adapter_desc;
131 INT adapter_count = 0;
133 HDC hdc;
134 DWORD i;
135
136 if (!pD3DKMTOpenAdapterFromHdc)
137 {
138 win_skip("D3DKMTOpenAdapterFromHdc() is missing.\n");
139 return;
140 }
141
142 /* Invalid parameters */
143 /* Passing a NULL pointer crashes on Windows 10 >= 2004 */
144 if (0) status = pD3DKMTOpenAdapterFromHdc(NULL);
145
146 memset(&open_adapter_hdc_desc, 0, sizeof(open_adapter_hdc_desc));
147 status = pD3DKMTOpenAdapterFromHdc(&open_adapter_hdc_desc);
149 {
150 win_skip("D3DKMTOpenAdapterFromHdc() is not supported.\n");
151 return;
152 }
153 todo_wine ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
154
155 /* Open adapter */
156 for (i = 0; EnumDisplayDevicesW(NULL, i, &display_device, 0); ++i)
157 {
158 if (!(display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
159 continue;
160
162
163 hdc = CreateDCW(0, display_device.DeviceName, 0, NULL);
164 open_adapter_hdc_desc.hDc = hdc;
165 status = pD3DKMTOpenAdapterFromHdc(&open_adapter_hdc_desc);
166 todo_wine ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
167 todo_wine ok(open_adapter_hdc_desc.hAdapter, "Expect not null.\n");
168 DeleteDC(hdc);
169
170 if (status == STATUS_SUCCESS)
171 {
172 close_adapter_desc.hAdapter = open_adapter_hdc_desc.hAdapter;
173 status = pD3DKMTCloseAdapter(&close_adapter_desc);
174 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
175 }
176 }
177
178 /* HDC covering more than two adapters is invalid for D3DKMTOpenAdapterFromHdc */
179 hdc = GetDC(0);
180 open_adapter_hdc_desc.hDc = hdc;
181 status = pD3DKMTOpenAdapterFromHdc(&open_adapter_hdc_desc);
182 ReleaseDC(0, hdc);
184 "Got unexpected return code %#lx.\n", status);
185 if (status == STATUS_SUCCESS)
186 {
187 close_adapter_desc.hAdapter = open_adapter_hdc_desc.hAdapter;
188 status = pD3DKMTCloseAdapter(&close_adapter_desc);
189 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
190 }
191}
192
194{
195 D3DKMT_ENUMADAPTERS2 enum_adapters_2_desc = {0};
196 D3DKMT_CLOSEADAPTER close_adapter_desc;
198 UINT i;
199
200 if (!pD3DKMTEnumAdapters2 || pD3DKMTEnumAdapters2(&enum_adapters_2_desc) == STATUS_PROCEDURE_NOT_FOUND)
201 {
202 win_skip("D3DKMTEnumAdapters2() is unavailable.\n");
203 return;
204 }
205
206 /* Invalid parameters */
207 status = pD3DKMTEnumAdapters2(NULL);
208 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
209
210 /* Query the array to allocate */
211 memset(&enum_adapters_2_desc, 0, sizeof(enum_adapters_2_desc));
212 status = pD3DKMTEnumAdapters2(&enum_adapters_2_desc);
213 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
214 ok(enum_adapters_2_desc.NumAdapters == 32 /* win10 and older */ || enum_adapters_2_desc.NumAdapters == 34 /* win11 */,
215 "Got unexpected value %lu.\n", enum_adapters_2_desc.NumAdapters);
216
217 /* Allocate the array */
218 enum_adapters_2_desc.pAdapters = calloc(enum_adapters_2_desc.NumAdapters, sizeof(D3DKMT_ADAPTERINFO));
219 ok(!!enum_adapters_2_desc.pAdapters, "Expect not null.\n");
220
221 /* Enumerate adapters */
222 status = pD3DKMTEnumAdapters2(&enum_adapters_2_desc);
223 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
224 ok(enum_adapters_2_desc.NumAdapters, "Expect not zero.\n");
225
226 for (i = 0; i < enum_adapters_2_desc.NumAdapters; ++i)
227 {
228 ok(enum_adapters_2_desc.pAdapters[i].hAdapter, "Expect not null.\n");
229 ok(enum_adapters_2_desc.pAdapters[i].AdapterLuid.LowPart || enum_adapters_2_desc.pAdapters[i].AdapterLuid.HighPart,
230 "Expect LUID not zero.\n");
231
232 close_adapter_desc.hAdapter = enum_adapters_2_desc.pAdapters[i].hAdapter;
233 status = pD3DKMTCloseAdapter(&close_adapter_desc);
234 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
235 }
236
237 /* Check for insufficient buffer */
238 enum_adapters_2_desc.NumAdapters = 0;
239 status = pD3DKMTEnumAdapters2(&enum_adapters_2_desc);
240 ok(status == STATUS_BUFFER_TOO_SMALL, "Got unexpected return code %#lx.\n", status);
241
242 free(enum_adapters_2_desc.pAdapters);
243}
244
245static void test_D3DKMTCloseAdapter(void)
246{
247 D3DKMT_CLOSEADAPTER close_adapter_desc;
249
250 if (!pD3DKMTCloseAdapter || pD3DKMTCloseAdapter(NULL) == STATUS_PROCEDURE_NOT_FOUND)
251 {
252 win_skip("D3DKMTCloseAdapter() is unavailable.\n");
253 return;
254 }
255
256 /* Invalid parameters */
257 status = pD3DKMTCloseAdapter(NULL);
258 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
259
260 memset(&close_adapter_desc, 0, sizeof(close_adapter_desc));
261 status = pD3DKMTCloseAdapter(&close_adapter_desc);
262 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
263}
264
265static void test_D3DKMTCreateDevice(void)
266{
267 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
268 D3DKMT_CREATEDEVICE create_device_desc;
269 D3DKMT_CLOSEADAPTER close_adapter_desc;
270 D3DKMT_DESTROYDEVICE destroy_device_desc;
272
273 if (!pD3DKMTCreateDevice || pD3DKMTCreateDevice(NULL) == STATUS_PROCEDURE_NOT_FOUND)
274 {
275 win_skip("D3DKMTCreateDevice() is unavailable.\n");
276 return;
277 }
278
279 /* Invalid parameters */
280 status = pD3DKMTCreateDevice(NULL);
281 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
282
283 memset(&create_device_desc, 0, sizeof(create_device_desc));
284 status = pD3DKMTCreateDevice(&create_device_desc);
285 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
286
287 lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
288 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
289 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
290
291 /* Create device */
292 create_device_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
293 status = pD3DKMTCreateDevice(&create_device_desc);
294 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
295 ok(create_device_desc.hDevice, "Expect not null.\n");
296 ok(create_device_desc.pCommandBuffer == NULL, "Expect null.\n");
297 ok(create_device_desc.CommandBufferSize == 0, "Got wrong value %#x.\n", create_device_desc.CommandBufferSize);
298 ok(create_device_desc.pAllocationList == NULL, "Expect null.\n");
299 ok(create_device_desc.AllocationListSize == 0, "Got wrong value %#x.\n", create_device_desc.AllocationListSize);
300 ok(create_device_desc.pPatchLocationList == NULL, "Expect null.\n");
301 ok(create_device_desc.PatchLocationListSize == 0, "Got wrong value %#x.\n", create_device_desc.PatchLocationListSize);
302
303 destroy_device_desc.hDevice = create_device_desc.hDevice;
304 status = pD3DKMTDestroyDevice(&destroy_device_desc);
305 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
306
307 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
308 status = pD3DKMTCloseAdapter(&close_adapter_desc);
309 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
310}
311
313{
314 D3DKMT_DESTROYDEVICE destroy_device_desc;
316
317 if (!pD3DKMTDestroyDevice || pD3DKMTDestroyDevice(NULL) == STATUS_PROCEDURE_NOT_FOUND)
318 {
319 win_skip("D3DKMTDestroyDevice() is unavailable.\n");
320 return;
321 }
322
323 /* Invalid parameters */
324 status = pD3DKMTDestroyDevice(NULL);
325 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
326
327 memset(&destroy_device_desc, 0, sizeof(destroy_device_desc));
328 status = pD3DKMTDestroyDevice(&destroy_device_desc);
329 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
330}
331
333{
334 static const DWORD timeout = 1000;
335 static const DWORD wait_step = 100;
336 D3DKMT_CREATEDEVICE create_device_desc, create_device_desc2;
337 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
339 D3DKMT_DESTROYDEVICE destroy_device_desc;
340 D3DKMT_CLOSEADAPTER close_adapter_desc;
342 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc;
343 DWORD total_time;
345 INT i;
346
347 /* Test cases using single device */
348 static const struct test_data1
349 {
351 NTSTATUS expected_set_status;
352 NTSTATUS expected_check_status;
353 } tests1[] = {
354 /* 0 */
365 /* 10 */
376 /* 20 */
387 /* 30 */
398 /* 40 */
409 /* 50 */
420 };
421
422 /* Test cases using two devices consecutively */
423 static const struct test_data2
424 {
425 D3DKMT_VIDPNSOURCEOWNER_TYPE set_owner_type1;
426 D3DKMT_VIDPNSOURCEOWNER_TYPE set_owner_type2;
427 NTSTATUS expected_set_status1;
428 NTSTATUS expected_set_status2;
429 NTSTATUS expected_check_status;
430 } tests2[] = {
431 /* 0 */
442 /* 10 */
451 };
452
453 if (!pD3DKMTCheckVidPnExclusiveOwnership || pD3DKMTCheckVidPnExclusiveOwnership(NULL) == STATUS_PROCEDURE_NOT_FOUND)
454 {
455 /* This is a stub in some drivers (e.g. nulldrv) */
456 skip("D3DKMTCheckVidPnExclusiveOwnership() is unavailable.\n");
457 return;
458 }
459
460 /* Invalid parameters */
461 status = pD3DKMTCheckVidPnExclusiveOwnership(NULL);
462 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
463
464 memset(&check_owner_desc, 0, sizeof(check_owner_desc));
465 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
466 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
467
468 /* Test cases */
469 lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
470 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
471 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
472
473 memset(&create_device_desc, 0, sizeof(create_device_desc));
474 create_device_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
475 status = pD3DKMTCreateDevice(&create_device_desc);
476 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
477
478 check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
479 check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
480 for (i = 0; i < ARRAY_SIZE(tests1); ++i)
481 {
482 set_owner_desc.hDevice = create_device_desc.hDevice;
483 if (tests1[i].owner_type != -1)
484 {
485 owner_type = tests1[i].owner_type;
486 set_owner_desc.pType = &owner_type;
487 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
488 set_owner_desc.VidPnSourceCount = 1;
489 }
490 else
491 {
492 set_owner_desc.pType = NULL;
493 set_owner_desc.pVidPnSourceId = NULL;
494 set_owner_desc.VidPnSourceCount = 0;
495 }
496 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
497 ok(status == tests1[i].expected_set_status ||
498 /* win8 doesn't support D3DKMT_VIDPNSOURCEOWNER_EMULATED */
500 || (status == STATUS_SUCCESS && tests1[i].owner_type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
501 && tests1[i - 1].owner_type == D3DKMT_VIDPNSOURCEOWNER_EMULATED),
502 "Got unexpected return code %#lx at test %d.\n", status, i);
503
504 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
505 /* If don't sleep, D3DKMTCheckVidPnExclusiveOwnership may get STATUS_GRAPHICS_PRESENT_UNOCCLUDED instead
506 * of STATUS_SUCCESS */
507 if ((tests1[i].expected_check_status == STATUS_SUCCESS && status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED))
508 {
509 total_time = 0;
510 do
511 {
512 Sleep(wait_step);
513 total_time += wait_step;
514 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
515 } while (status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED && total_time < timeout);
516 }
517 ok(status == tests1[i].expected_check_status
519 && tests1[i].owner_type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
520 && tests1[i - 1].owner_type == D3DKMT_VIDPNSOURCEOWNER_EMULATED),
521 "Got unexpected return code %#lx at test %d.\n", status, i);
522 }
523
524 /* Set owner and unset owner using different devices */
525 memset(&create_device_desc2, 0, sizeof(create_device_desc2));
526 create_device_desc2.hAdapter = open_adapter_gdi_desc.hAdapter;
527 status = pD3DKMTCreateDevice(&create_device_desc2);
528 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
529
530 /* Set owner with the first device */
531 set_owner_desc.hDevice = create_device_desc.hDevice;
533 set_owner_desc.pType = &owner_type;
534 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
535 set_owner_desc.VidPnSourceCount = 1;
536 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
537 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
538 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
539 ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#lx.\n", status);
540
541 /* Unset owner with the second device */
542 set_owner_desc.hDevice = create_device_desc2.hDevice;
543 set_owner_desc.pType = NULL;
544 set_owner_desc.pVidPnSourceId = NULL;
545 set_owner_desc.VidPnSourceCount = 0;
546 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
547 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
548 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
549 /* No effect */
550 ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#lx.\n", status);
551
552 /* Unset owner with the first device */
553 set_owner_desc.hDevice = create_device_desc.hDevice;
554 set_owner_desc.pType = NULL;
555 set_owner_desc.pVidPnSourceId = NULL;
556 set_owner_desc.VidPnSourceCount = 0;
557 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
558 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
559 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
560 /* Proves that the correct device is needed to unset owner */
561 ok(status == STATUS_SUCCESS || status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED, "Got unexpected return code %#lx.\n",
562 status);
563
564 /* Set owner with the first device, set owner again with the second device */
565 for (i = 0; i < ARRAY_SIZE(tests2); ++i)
566 {
567 if (tests2[i].set_owner_type1 != -1)
568 {
569 set_owner_desc.hDevice = create_device_desc.hDevice;
570 owner_type = tests2[i].set_owner_type1;
571 set_owner_desc.pType = &owner_type;
572 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
573 set_owner_desc.VidPnSourceCount = 1;
574 /* If don't sleep, D3DKMTSetVidPnSourceOwner may return STATUS_OK for D3DKMT_VIDPNSOURCEOWNER_SHARED.
575 * Other owner type doesn't seems to be affected. */
576 if (tests2[i].set_owner_type1 == D3DKMT_VIDPNSOURCEOWNER_SHARED)
577 Sleep(timeout);
578 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
579 ok(status == tests2[i].expected_set_status1
580 || (status == STATUS_INVALID_PARAMETER /* win8 */
581 && tests2[i].set_owner_type1 == D3DKMT_VIDPNSOURCEOWNER_EMULATED),
582 "Got unexpected return code %#lx at test %d.\n", status, i);
583 }
584
585 if (tests2[i].set_owner_type2 != -1)
586 {
587 set_owner_desc.hDevice = create_device_desc2.hDevice;
588 owner_type = tests2[i].set_owner_type2;
589 set_owner_desc.pType = &owner_type;
590 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
591 set_owner_desc.VidPnSourceCount = 1;
592 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
593 ok(status == tests2[i].expected_set_status2
594 || (status == STATUS_INVALID_PARAMETER /* win8 */
595 && tests2[i].set_owner_type2 == D3DKMT_VIDPNSOURCEOWNER_EMULATED)
596 || (status == STATUS_SUCCESS && tests2[i].set_owner_type1 == D3DKMT_VIDPNSOURCEOWNER_EMULATED
597 && tests2[i].set_owner_type2 == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE),
598 "Got unexpected return code %#lx at test %d.\n", status, i);
599 }
600
601 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
602 if ((tests2[i].expected_check_status == STATUS_SUCCESS && status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED))
603 {
604 total_time = 0;
605 do
606 {
607 Sleep(wait_step);
608 total_time += wait_step;
609 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
610 } while (status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED && total_time < timeout);
611 }
612 ok(status == tests2[i].expected_check_status
614 && tests2[i].set_owner_type2 == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
615 && tests2[i].set_owner_type1 == D3DKMT_VIDPNSOURCEOWNER_EMULATED),
616 "Got unexpected return code %#lx at test %d.\n", status, i);
617
618 /* Unset owner with first device */
619 if (tests2[i].set_owner_type1 != -1)
620 {
621 set_owner_desc.hDevice = create_device_desc.hDevice;
622 set_owner_desc.pType = NULL;
623 set_owner_desc.pVidPnSourceId = NULL;
624 set_owner_desc.VidPnSourceCount = 0;
625 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
626 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx at test %d.\n", status, i);
627 }
628
629 /* Unset owner with second device */
630 if (tests2[i].set_owner_type2 != -1)
631 {
632 set_owner_desc.hDevice = create_device_desc2.hDevice;
633 set_owner_desc.pType = NULL;
634 set_owner_desc.pVidPnSourceId = NULL;
635 set_owner_desc.VidPnSourceCount = 0;
636 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
637 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx at test %d.\n", status, i);
638 }
639 }
640
641 /* Destroy devices holding ownership */
642 set_owner_desc.hDevice = create_device_desc.hDevice;
644 set_owner_desc.pType = &owner_type;
645 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
646 set_owner_desc.VidPnSourceCount = 1;
647 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
648 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
649
650 destroy_device_desc.hDevice = create_device_desc.hDevice;
651 status = pD3DKMTDestroyDevice(&destroy_device_desc);
652 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
653
654 set_owner_desc.hDevice = create_device_desc2.hDevice;
656 set_owner_desc.pType = &owner_type;
657 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
658 set_owner_desc.VidPnSourceCount = 1;
659 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
660 /* So ownership is released when device is destroyed. otherwise the return code should be
661 * STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE */
662 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
663
664 destroy_device_desc.hDevice = create_device_desc2.hDevice;
665 status = pD3DKMTDestroyDevice(&destroy_device_desc);
666 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
667
668 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
669 status = pD3DKMTCloseAdapter(&close_adapter_desc);
670 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
671}
672
674{
675 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc = {0};
677
678 if (!pD3DKMTSetVidPnSourceOwner || pD3DKMTSetVidPnSourceOwner(&set_owner_desc) == STATUS_PROCEDURE_NOT_FOUND)
679 {
680 /* This is a stub in some drivers (e.g. nulldrv) */
681 skip("D3DKMTSetVidPnSourceOwner() is unavailable.\n");
682 return;
683 }
684
685 /* Invalid parameters */
686 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
687 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
688}
689
691{
692 DISPLAY_DEVICEW display_device = {sizeof(display_device)};
693 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_gdi_desc;
695 D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc;
696 D3DKMT_DESTROYDEVICE destroy_device_desc;
698 D3DKMT_CLOSEADAPTER close_adapter_desc;
699 D3DKMT_CREATEDEVICE create_device_desc;
700 D3DKMT_CHECKOCCLUSION occlusion_desc;
701 NTSTATUS expected_occlusion, status;
702 INT i, adapter_count = 0;
703 HWND hwnd, hwnd2;
704 HRESULT hr;
705
706 if (!pD3DKMTCheckOcclusion || pD3DKMTCheckOcclusion(NULL) == STATUS_PROCEDURE_NOT_FOUND)
707 {
708 todo_wine win_skip("D3DKMTCheckOcclusion() is unavailable.\n");
709 return;
710 }
711
712 /* NULL parameter check */
713 status = pD3DKMTCheckOcclusion(NULL);
714 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
715
716 occlusion_desc.hWnd = NULL;
717 status = pD3DKMTCheckOcclusion(&occlusion_desc);
718 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
719
720 hwnd = CreateWindowA("static", "static1", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 200, 200, 0, 0, 0, 0);
721 ok(hwnd != NULL, "Failed to create window.\n");
722
723 occlusion_desc.hWnd = hwnd;
724 status = pD3DKMTCheckOcclusion(&occlusion_desc);
725 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
726
727 /* Minimized state doesn't affect D3DKMTCheckOcclusion */
729 occlusion_desc.hWnd = hwnd;
730 status = pD3DKMTCheckOcclusion(&occlusion_desc);
731 flaky
732 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
734
735 /* Invisible state doesn't affect D3DKMTCheckOcclusion */
737 occlusion_desc.hWnd = hwnd;
738 status = pD3DKMTCheckOcclusion(&occlusion_desc);
739 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
741
742 /* hwnd2 covers hwnd */
743 hwnd2 = CreateWindowA("static", "static2", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 200, 200, 0, 0, 0, 0);
744 ok(hwnd2 != NULL, "Failed to create window.\n");
745
746 occlusion_desc.hWnd = hwnd;
747 status = pD3DKMTCheckOcclusion(&occlusion_desc);
748 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
749
750 occlusion_desc.hWnd = hwnd2;
751 status = pD3DKMTCheckOcclusion(&occlusion_desc);
752 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
753
754 /* Composition doesn't affect D3DKMTCheckOcclusion */
755 if (pDwmEnableComposition)
756 {
757 hr = pDwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
758 ok(hr == S_OK, "Failed to disable composition.\n");
759
760 occlusion_desc.hWnd = hwnd;
761 status = pD3DKMTCheckOcclusion(&occlusion_desc);
762 /* This result means that D3DKMTCheckOcclusion doesn't check composition status despite MSDN says it will */
763 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
764
765 occlusion_desc.hWnd = hwnd2;
766 status = pD3DKMTCheckOcclusion(&occlusion_desc);
767 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
768
770 occlusion_desc.hWnd = hwnd;
771 status = pD3DKMTCheckOcclusion(&occlusion_desc);
772 flaky
773 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
775
777 occlusion_desc.hWnd = hwnd;
778 status = pD3DKMTCheckOcclusion(&occlusion_desc);
779 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
781
782 hr = pDwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
783 ok(hr == S_OK, "Failed to enable composition.\n");
784 }
785 else
786 skip("Skip testing composition.\n");
787
788 lstrcpyW(open_adapter_gdi_desc.DeviceName, display1W);
789 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_gdi_desc);
790 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
791
792 memset(&create_device_desc, 0, sizeof(create_device_desc));
793 create_device_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
794 status = pD3DKMTCreateDevice(&create_device_desc);
795 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
796
797 check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
798 check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
799 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
800 /* D3DKMTCheckVidPnExclusiveOwnership gets STATUS_GRAPHICS_PRESENT_UNOCCLUDED sometimes and with some delay,
801 * it will always return STATUS_SUCCESS. So there are some timing issues here. */
802 ok(status == STATUS_SUCCESS || status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED, "Got unexpected return code %#lx.\n", status);
803
804 /* Test D3DKMTCheckOcclusion relationship with video present source owner */
805 set_owner_desc.hDevice = create_device_desc.hDevice;
807 set_owner_desc.pType = &owner_type;
808 set_owner_desc.pVidPnSourceId = &open_adapter_gdi_desc.VidPnSourceId;
809 set_owner_desc.VidPnSourceCount = 1;
810 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
811 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
812
813 for (i = 0; EnumDisplayDevicesW(NULL, i, &display_device, 0); ++i)
814 {
815 if ((display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
817 }
818 /* STATUS_GRAPHICS_PRESENT_OCCLUDED on single monitor system. STATUS_SUCCESS on multiple monitor system. */
820
821 occlusion_desc.hWnd = hwnd;
822 status = pD3DKMTCheckOcclusion(&occlusion_desc);
823 ok(status == expected_occlusion, "Got unexpected return code %#lx.\n", status);
824
825 /* Note hwnd2 is not actually occluded but D3DKMTCheckOcclusion reports STATUS_GRAPHICS_PRESENT_OCCLUDED as well */
826 SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
827 ShowWindow(hwnd2, SW_SHOW);
828 occlusion_desc.hWnd = hwnd2;
829 status = pD3DKMTCheckOcclusion(&occlusion_desc);
830 ok(status == expected_occlusion, "Got unexpected return code %#lx.\n", status);
831
832 /* Now hwnd is HWND_TOPMOST. Still reports STATUS_GRAPHICS_PRESENT_OCCLUDED */
833 ok(SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE), "Failed to SetWindowPos.\n");
834 ok(GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "No WS_EX_TOPMOST style.\n");
835 occlusion_desc.hWnd = hwnd;
836 status = pD3DKMTCheckOcclusion(&occlusion_desc);
837 ok(status == expected_occlusion, "Got unexpected return code %#lx.\n", status);
838
839 DestroyWindow(hwnd2);
840 occlusion_desc.hWnd = hwnd;
841 status = pD3DKMTCheckOcclusion(&occlusion_desc);
842 ok(status == expected_occlusion, "Got unexpected return code %#lx.\n", status);
843
844 check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
845 check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
846 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
847 ok(status == STATUS_GRAPHICS_PRESENT_OCCLUDED, "Got unexpected return code %#lx.\n", status);
848
849 /* Unset video present source owner */
850 set_owner_desc.hDevice = create_device_desc.hDevice;
851 set_owner_desc.pType = NULL;
852 set_owner_desc.pVidPnSourceId = NULL;
853 set_owner_desc.VidPnSourceCount = 0;
854 status = pD3DKMTSetVidPnSourceOwner(&set_owner_desc);
855 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
856
857 occlusion_desc.hWnd = hwnd;
858 status = pD3DKMTCheckOcclusion(&occlusion_desc);
859 flaky
860 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
861
862 check_owner_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
863 check_owner_desc.VidPnSourceId = open_adapter_gdi_desc.VidPnSourceId;
864 status = pD3DKMTCheckVidPnExclusiveOwnership(&check_owner_desc);
865 flaky
866 ok(status == STATUS_SUCCESS || status == STATUS_GRAPHICS_PRESENT_UNOCCLUDED, "Got unexpected return code %#lx.\n", status);
867
868 destroy_device_desc.hDevice = create_device_desc.hDevice;
869 status = pD3DKMTDestroyDevice(&destroy_device_desc);
870 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
871
872 close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
873 status = pD3DKMTCloseAdapter(&close_adapter_desc);
874 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
876}
877
878#if (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
879static void test_D3DKMTOpenAdapterFromDeviceName_deviface(const GUID *devinterface_guid,
880 NTSTATUS expected_status, BOOL todo)
881{
882 BYTE iface_detail_buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + 256 * sizeof(WCHAR)];
883 SP_DEVINFO_DATA device_data = {sizeof(device_data)};
884 SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
887 D3DKMT_CLOSEADAPTER close_adapter_desc;
890 unsigned int i;
892 LUID luid;
893 BOOL ret;
894
896 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed, error %lu.\n", GetLastError());
897
898 iface_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer;
899 iface_data->cbSize = sizeof(*iface_data);
900 device_name.pDeviceName = iface_data->DevicePath;
901
902 i = 0;
903 while (SetupDiEnumDeviceInterfaces(set, NULL, devinterface_guid, i, &iface))
904 {
905 ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, iface_data,
906 sizeof(iface_detail_buffer), NULL, &device_data );
907 ok(ret, "Got unexpected ret %d, GetLastError() %lu.\n", ret, GetLastError());
908
909 status = pD3DKMTOpenAdapterFromDeviceName(&device_name);
910 todo_wine_if(todo) ok(status == expected_status, "Got status %#lx, expected %#lx.\n", status, expected_status);
911
912 if (!status)
913 {
914 ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPROPKEY_GPU_LUID, &type,
915 (BYTE *)&luid, sizeof(luid), NULL, 0);
916 ok(ret || GetLastError() == ERROR_NOT_FOUND, "Got unexpected ret %d, GetLastError() %lu.\n",
917 ret, GetLastError());
918
919 if (ret)
920 {
921 ret = RtlEqualLuid( &luid, &device_name.AdapterLuid);
922 todo_wine ok(ret, "Luid does not match.\n");
923 }
924 else
925 {
926 skip("Luid not found.\n");
927 }
928
929 close_adapter_desc.hAdapter = device_name.hAdapter;
930 status = pD3DKMTCloseAdapter(&close_adapter_desc);
931 ok(!status, "Got unexpected status %#lx.\n", status);
932 }
933 ++i;
934 }
935 if (!i)
936 win_skip("No devices found.\n");
937
939}
940
942{
945
946 /* Make sure display devices are initialized. */
948
949 status = pD3DKMTOpenAdapterFromDeviceName(NULL);
951 {
952 win_skip("D3DKMTOpenAdapterFromDeviceName() is not supported.\n");
953 return;
954 }
955 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", status);
956
957 memset(&device_name, 0, sizeof(device_name));
958 status = pD3DKMTOpenAdapterFromDeviceName(&device_name);
959 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", status);
960
961 winetest_push_context("GUID_DEVINTERFACE_DISPLAY_ADAPTER");
964
965 winetest_push_context("GUID_DISPLAY_DEVICE_ARRIVAL");
968}
969#endif
970
972{
975 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_desc;
976 D3DKMT_QUERYVIDEOMEMORYINFO query_memory_info;
977 D3DKMT_CLOSEADAPTER close_adapter_desc;
979 unsigned int i;
980 BOOL ret;
981
982 if (!pD3DKMTQueryVideoMemoryInfo)
983 {
984 win_skip("D3DKMTQueryVideoMemoryInfo() is unavailable.\n");
985 return;
986 }
987
988 ret = get_primary_adapter_name(open_adapter_desc.DeviceName);
989 ok(ret, "Failed to get primary adapter name.\n");
990 status = pD3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_desc);
991 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
992
993 /* Normal query */
994 for (i = 0; i < ARRAY_SIZE(groups); ++i)
995 {
996 winetest_push_context("group %d", groups[i]);
997
998 query_memory_info.hProcess = NULL;
999 query_memory_info.hAdapter = open_adapter_desc.hAdapter;
1000 query_memory_info.PhysicalAdapterIndex = 0;
1001 query_memory_info.MemorySegmentGroup = groups[i];
1002 status = pD3DKMTQueryVideoMemoryInfo(&query_memory_info);
1003 todo_wine_if (status == STATUS_INVALID_PARAMETER) /* fails on Wine without a Vulkan adapter */
1004 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
1005 ok(query_memory_info.Budget >= query_memory_info.AvailableForReservation,
1006 "Unexpected budget %I64u and reservation %I64u.\n", query_memory_info.Budget,
1007 query_memory_info.AvailableForReservation);
1008 ok(query_memory_info.CurrentUsage <= query_memory_info.Budget,
1009 "Unexpected current usage %I64u.\n", query_memory_info.CurrentUsage);
1010 ok(query_memory_info.CurrentReservation == 0,
1011 "Unexpected current reservation %I64u.\n", query_memory_info.CurrentReservation);
1012
1014 }
1015
1016 /* Query using the current process handle */
1017 query_memory_info.hProcess = GetCurrentProcess();
1018 status = pD3DKMTQueryVideoMemoryInfo(&query_memory_info);
1019 todo_wine_if (status == STATUS_INVALID_PARAMETER) /* fails on Wine without a Vulkan adapter */
1020 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
1021
1022 /* Query using a process handle without PROCESS_QUERY_INFORMATION privilege */
1024 ok(!!query_memory_info.hProcess, "OpenProcess failed, error %ld.\n", GetLastError());
1025 status = pD3DKMTQueryVideoMemoryInfo(&query_memory_info);
1026 ok(status == STATUS_ACCESS_DENIED, "Got unexpected return code %#lx.\n", status);
1027 CloseHandle(query_memory_info.hProcess);
1028 query_memory_info.hProcess = NULL;
1029
1030 /* Query using an invalid process handle */
1031 query_memory_info.hProcess = (HANDLE)0xdeadbeef;
1032 status = pD3DKMTQueryVideoMemoryInfo(&query_memory_info);
1033 ok(status == STATUS_INVALID_HANDLE, "Got unexpected return code %#lx.\n", status);
1034 query_memory_info.hProcess = NULL;
1035
1036 /* Query using an invalid adapter handle */
1037 query_memory_info.hAdapter = (D3DKMT_HANDLE)0xdeadbeef;
1038 status = pD3DKMTQueryVideoMemoryInfo(&query_memory_info);
1039 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
1040 query_memory_info.hAdapter = open_adapter_desc.hAdapter;
1041
1042 /* Query using an invalid adapter index */
1043 query_memory_info.PhysicalAdapterIndex = 99;
1044 status = pD3DKMTQueryVideoMemoryInfo(&query_memory_info);
1045 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
1046 query_memory_info.PhysicalAdapterIndex = 0;
1047
1048 /* Query using an invalid memory segment group */
1050 status = pD3DKMTQueryVideoMemoryInfo(&query_memory_info);
1051 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected return code %#lx.\n", status);
1052
1053 close_adapter_desc.hAdapter = open_adapter_desc.hAdapter;
1054 status = pD3DKMTCloseAdapter(&close_adapter_desc);
1055 ok(status == STATUS_SUCCESS, "Got unexpected return code %#lx.\n", status);
1056}
1057
1058#if (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
1059static void test_gpu_device_properties_guid(const GUID *devinterface_guid)
1060{
1061 BYTE iface_detail_buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + 256 * sizeof(WCHAR)];
1062 SP_DEVINFO_DATA device_data = {sizeof(device_data)};
1063 SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
1065 WCHAR device_id[256];
1067 unsigned int i;
1068 UINT32 value;
1069 HDEVINFO set;
1070 BOOL ret;
1071
1072 /* Make sure display devices are initialized. */
1074
1076 ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed, error %lu.\n", GetLastError());
1077
1078 iface_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer;
1079 iface_data->cbSize = sizeof(*iface_data);
1080
1081 i = 0;
1082 while (SetupDiEnumDeviceInterfaces(set, NULL, devinterface_guid, i, &iface))
1083 {
1084 ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, iface_data,
1085 sizeof(iface_detail_buffer), NULL, &device_data );
1086 ok(ret, "Got unexpected ret %d, GetLastError() %lu.\n", ret, GetLastError());
1087
1088 ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_MatchingDeviceId, &type,
1089 (BYTE *)device_id, sizeof(device_id), NULL, 0);
1090 ok(ret, "Got unexpected ret %d, GetLastError() %lu.\n", ret, GetLastError());
1091 ok(type == DEVPROP_TYPE_STRING, "Got type %ld.\n", type);
1092
1093 ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_BusNumber, &type,
1094 (BYTE *)&value, sizeof(value), NULL, 0);
1095 if (!wcsicmp(device_id, L"root\\basicrender") || !wcsicmp(device_id, L"root\\basicdisplay"))
1096 {
1097 ok(!ret, "Found Bus Id.\n");
1098 }
1099 else
1100 {
1101 ok(ret, "Got unexpected ret %d, GetLastError() %lu, %s.\n", ret, GetLastError(), debugstr_w(device_id));
1102 ok(type == DEVPROP_TYPE_UINT32, "Got type %ld.\n", type);
1103 }
1104
1105 ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_RemovalPolicy, &type,
1106 (BYTE *)&value, sizeof(value), NULL, 0);
1107 ok(ret, "Got unexpected ret %d, GetLastError() %lu, %s.\n", ret, GetLastError(), debugstr_w(device_id));
1109 || value == CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL, "Got value %d.\n", value);
1110 ok(type == DEVPROP_TYPE_UINT32, "Got type %ld.\n", type);
1111 ++i;
1112 }
1114}
1115
1117{
1118 winetest_push_context("GUID_DEVINTERFACE_DISPLAY_ADAPTER");
1119 test_gpu_device_properties_guid(&GUID_DEVINTERFACE_DISPLAY_ADAPTER);
1121 winetest_push_context("GUID_DISPLAY_DEVICE_ARRIVAL");
1122 test_gpu_device_properties_guid(&GUID_DISPLAY_DEVICE_ARRIVAL);
1124}
1125#endif
1126
1128{
1129 HMODULE gdi32 = GetModuleHandleA("gdi32.dll");
1130 HMODULE dwmapi = LoadLibraryA("dwmapi.dll");
1131
1132 pD3DKMTCheckOcclusion = (void *)GetProcAddress(gdi32, "D3DKMTCheckOcclusion");
1133 pD3DKMTCheckVidPnExclusiveOwnership = (void *)GetProcAddress(gdi32, "D3DKMTCheckVidPnExclusiveOwnership");
1134 pD3DKMTCloseAdapter = (void *)GetProcAddress(gdi32, "D3DKMTCloseAdapter");
1135 pD3DKMTCreateDevice = (void *)GetProcAddress(gdi32, "D3DKMTCreateDevice");
1136 pD3DKMTDestroyDevice = (void *)GetProcAddress(gdi32, "D3DKMTDestroyDevice");
1137 pD3DKMTEnumAdapters2 = (void *)GetProcAddress(gdi32, "D3DKMTEnumAdapters2");
1138 pD3DKMTOpenAdapterFromDeviceName = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromDeviceName");
1139 pD3DKMTOpenAdapterFromGdiDisplayName = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromGdiDisplayName");
1140 pD3DKMTOpenAdapterFromHdc = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromHdc");
1141 pD3DKMTSetVidPnSourceOwner = (void *)GetProcAddress(gdi32, "D3DKMTSetVidPnSourceOwner");
1142 pD3DKMTQueryVideoMemoryInfo = (void *)GetProcAddress(gdi32, "D3DKMTQueryVideoMemoryInfo");
1143
1144 if (dwmapi)
1145 pDwmEnableComposition = (void *)GetProcAddress(dwmapi, "DwmEnableComposition");
1146
1156#if (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
1158#endif
1160#if (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
1162#endif
1163
1164 FreeLibrary(dwmapi);
1165}
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
#define CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL
Definition: cfgmgr32.h:750
#define CM_REMOVAL_POLICY_EXPECT_ORDERLY_REMOVAL
Definition: cfgmgr32.h:749
#define CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL
Definition: cfgmgr32.h:748
Definition: _set.h:50
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:573
ULONG DEVPROPTYPE
Definition: devpropdef.h:24
#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid)
Definition: devpropdef.h:103
#define DEVPROP_TYPE_UINT32
Definition: devpropdef.h:36
#define DEVPROP_TYPE_STRING
Definition: devpropdef.h:47
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:19
#define CloseHandle
Definition: compat.h:739
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define GetCurrentProcess()
Definition: compat.h:759
#define lstrcpyW
Definition: compat.h:749
#define wcsicmp
Definition: compat.h:15
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1225
BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, CONST GUID *InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:2824
HDEVINFO WINAPI SetupDiGetClassDevsW(CONST GUID *class, LPCWSTR enumstr, HWND parent, DWORD flags)
Definition: devinst.c:2292
BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:3055
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:2937
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
static const WCHAR device_name[]
Definition: btrfs.c:60
#define DWM_EC_ENABLECOMPOSITION
Definition: dwmapi.h:144
#define DWM_EC_DISABLECOMPOSITION
Definition: dwmapi.h:143
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizei GLuint * groups
Definition: glext.h:11113
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define PROCESS_SET_INFORMATION
Definition: pstypes.h:161
#define S_OK
Definition: intsafe.h:52
#define debugstr_w
Definition: kernel32.h:32
#define win_skip
Definition: minitest.h:67
#define todo_wine_if(is_todo)
Definition: minitest.h:81
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
BOOL todo
Definition: filedlg.c:313
static void test_D3DKMTQueryVideoMemoryInfo(void)
Definition: driver.c:971
static void test_D3DKMTCheckOcclusion(void)
Definition: driver.c:690
static BOOL get_primary_adapter_name(WCHAR *name)
Definition: driver.c:57
static void test_D3DKMTOpenAdapterFromDeviceName_deviface(const GUID *devinterface_guid, NTSTATUS expected_status, BOOL todo)
Definition: driver.c:879
static void test_D3DKMTEnumAdapters2(void)
Definition: driver.c:193
static void test_D3DKMTOpenAdapterFromGdiDisplayName(void)
Definition: driver.c:75
static void test_gpu_device_properties_guid(const GUID *devinterface_guid)
Definition: driver.c:1059
static void test_D3DKMTCloseAdapter(void)
Definition: driver.c:245
static void test_gpu_device_properties(void)
Definition: driver.c:1116
static const WCHAR display1W[]
Definition: driver.c:40
static void test_D3DKMTOpenAdapterFromDeviceName(void)
Definition: driver.c:941
static void test_D3DKMTOpenAdapterFromHdc(void)
Definition: driver.c:126
static void test_D3DKMTCreateDevice(void)
Definition: driver.c:265
static void test_D3DKMTCheckVidPnExclusiveOwnership(void)
Definition: driver.c:332
static void test_D3DKMTDestroyDevice(void)
Definition: driver.c:312
static void test_D3DKMTSetVidPnSourceOwner(void)
Definition: driver.c:673
static int adapter_count
Definition: monitor.c:148
struct @1813::@1814 driver
unsigned int UINT
Definition: ndis.h:50
#define STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE
Definition: ntstatus.h:2094
#define STATUS_GRAPHICS_PRESENT_OCCLUDED
Definition: ntstatus.h:1996
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:452
#define STATUS_GRAPHICS_PRESENT_UNOCCLUDED
Definition: ntstatus.h:2002
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
short WCHAR
Definition: pedump.c:58
#define WS_VISIBLE
Definition: pedump.c:620
#define WS_EX_TOPMOST
Definition: pedump.c:647
#define calloc
Definition: rosglue.h:14
#define flaky
Definition: test.h:164
#define memset(x, y, z)
Definition: compat.h:39
#define DIGCF_DEVICEINTERFACE
Definition: setupapi.h:177
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_DEVICE_INTERFACE_DETAIL_DATA_W
#define DIGCF_PRESENT
Definition: setupapi.h:174
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
D3DKMT_HANDLE hAdapter
Definition: d3dkmthk.h:765
D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId
Definition: d3dkmthk.h:149
D3DKMT_HANDLE hAdapter
Definition: d3dkmthk.h:156
D3DDDI_PATCHLOCATIONLIST * pPatchLocationList
Definition: d3dkmthk.h:105
D3DKMT_HANDLE hDevice
Definition: d3dkmthk.h:100
D3DKMT_HANDLE hAdapter
Definition: d3dkmthk.h:96
D3DDDI_ALLOCATIONLIST * pAllocationList
Definition: d3dkmthk.h:103
UINT PatchLocationListSize
Definition: d3dkmthk.h:106
D3DKMT_HANDLE hDevice
Definition: d3dkmthk.h:84
D3DKMT_ADAPTERINFO * pAdapters
Definition: d3dkmthk.h:782
D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId
Definition: d3dkmthk.h:129
D3DKMT_HANDLE hAdapter
Definition: d3dkmthk.h:112
D3DKMT_MEMORY_SEGMENT_GROUP MemorySegmentGroup
Definition: d3dkmthk.h:709
const D3DKMT_VIDPNSOURCEOWNER_TYPE * pType
Definition: d3dkmthk.h:141
const D3DDDI_VIDEO_PRESENT_SOURCE_ID * pVidPnSourceId
Definition: d3dkmthk.h:142
WCHAR DeviceName[32]
Definition: wingdi.h:3264
DWORD StateFlags
Definition: wingdi.h:3266
LONG HighPart
DWORD LowPart
WCHAR DevicePath[ANYSIZE_ARRAY]
Definition: setupapi.h:858
Definition: name.c:39
Definition: ps.c:97
Definition: dhcpd.h:248
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
PVOID HANDLE
Definition: typedefs.h:73
int32_t INT
Definition: typedefs.h:58
uint32_t UINT32
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Definition: pdh_main.c:96
BOOL WINAPI EnumDisplayDevicesW(LPCWSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICEW lpDisplayDevice, DWORD dwFlags)
Definition: display.c:78
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
UINT D3DKMT_HANDLE
Definition: d3dukmdt.h:28
@ D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL
Definition: d3dkmthk.h:36
@ D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL
Definition: d3dkmthk.h:37
enum _D3DKMT_MEMORY_SEGMENT_GROUP D3DKMT_MEMORY_SEGMENT_GROUP
enum _D3DKMT_VIDPNSOURCEOWNER_TYPE D3DKMT_VIDPNSOURCEOWNER_TYPE
@ D3DKMT_VIDPNSOURCEOWNER_EMULATED
Definition: d3dkmthk.h:31
@ D3DKMT_VIDPNSOURCEOWNER_UNOWNED
Definition: d3dkmthk.h:27
@ D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVEGDI
Definition: d3dkmthk.h:30
@ D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
Definition: d3dkmthk.h:29
@ D3DKMT_VIDPNSOURCEOWNER_SHARED
Definition: d3dkmthk.h:28
#define ERROR_NOT_FOUND
Definition: winerror.h:1014
#define DISPLAY_DEVICE_PRIMARY_DEVICE
Definition: wingdi.h:1398
#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
Definition: wingdi.h:1396
BOOL WINAPI DeleteDC(_In_ HDC)
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
#define SW_SHOWNORMAL
Definition: winuser.h:781
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define SW_HIDE
Definition: winuser.h:779
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define HWND_TOPMOST
Definition: winuser.h:1219
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4469
#define SW_MINIMIZE
Definition: winuser.h:787
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define SWP_NOMOVE
Definition: winuser.h:1255
#define SWP_NOSIZE
Definition: winuser.h:1256
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
#define HWND_TOP
Definition: winuser.h:1218
#define WM_NULL
Definition: winuser.h:1635
HDC WINAPI GetDC(_In_opt_ HWND)
#define SW_SHOW
Definition: winuser.h:786
BOOL WINAPI DestroyWindow(_In_ HWND)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define GWL_EXSTYLE
Definition: winuser.h:862
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:304
unsigned char BYTE
Definition: xxhash.c:193