wow64: In wow64_NtSetInformationToken forward TokenIntegrityLevel.
[wine.git] / dlls / d3d9 / tests / device.c
blob53dc9ee55edc6f16aa52230fb71f3e9a72b02643
1 /*
2 * Copyright (C) 2006 Ivan Gyurdiev
3 * Copyright (C) 2006 Vitaliy Margolen
4 * Copyright (C) 2006 Chris Robinson
5 * Copyright 2006-2008, 2010-2011, 2013 Stefan Dösinger for CodeWeavers
6 * Copyright 2005, 2006, 2007 Henri Verbeet
7 * Copyright 2013-2014 Henri Verbeet for CodeWeavers
8 * Copyright (C) 2008 Rico Schüller
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define COBJMACROS
26 #include <d3d9.h>
27 #include "utils.h"
29 struct vec3
31 float x, y, z;
34 #define CREATE_DEVICE_FULLSCREEN 0x01
35 #define CREATE_DEVICE_NOWINDOWCHANGES 0x02
36 #define CREATE_DEVICE_FPU_PRESERVE 0x04
37 #define CREATE_DEVICE_SWVP_ONLY 0x08
38 #define CREATE_DEVICE_MIXED_ONLY 0x10
39 #define CREATE_DEVICE_UNKNOWN_BACKBUFFER_FORMAT 0x20
40 #define CREATE_DEVICE_LOCKABLE_BACKBUFFER 0x40
42 struct device_desc
44 unsigned int adapter_ordinal;
45 HWND device_window;
46 unsigned int width;
47 unsigned int height;
48 DWORD flags;
51 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
52 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
54 static DEVMODEW registry_mode;
56 static void *(WINAPI *Direct3DShaderValidatorCreate9)(void);
58 static const DWORD simple_vs[] =
60 0xfffe0101, /* vs_1_1 */
61 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
62 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
63 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
64 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
65 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
66 0x0000ffff, /* end */
69 static const DWORD simple_ps[] =
71 0xffff0101, /* ps_1_1 */
72 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
73 0x00000042, 0xb00f0000, /* tex t0 */
74 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
75 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
76 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
77 0x0000ffff, /* end */
80 static int get_refcount(IUnknown *object)
82 IUnknown_AddRef( object );
83 return IUnknown_Release( object );
86 static BOOL compare_elements(IDirect3DVertexDeclaration9 *declaration, const D3DVERTEXELEMENT9 *expected_elements)
88 unsigned int element_count, i;
89 D3DVERTEXELEMENT9 *elements;
90 BOOL equal = TRUE;
91 HRESULT hr;
93 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
94 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#lx.\n", hr);
95 elements = malloc(element_count * sizeof(*elements));
96 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
97 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#lx.\n", hr);
99 for (i = 0; i < element_count; ++i)
101 if (memcmp(&elements[i], &expected_elements[i], sizeof(*elements)))
103 equal = FALSE;
104 break;
108 if (!equal)
110 for (i = 0; i < element_count; ++i)
112 trace("[Element %u] stream %u, offset %u, type %#x, method %#x, usage %#x, usage index %u.\n",
113 i, elements[i].Stream, elements[i].Offset, elements[i].Type,
114 elements[i].Method, elements[i].Usage, elements[i].UsageIndex);
118 free(elements);
119 return equal;
122 static void get_virtual_rect(RECT *rect)
124 rect->left = GetSystemMetrics(SM_XVIRTUALSCREEN);
125 rect->top = GetSystemMetrics(SM_YVIRTUALSCREEN);
126 rect->right = rect->left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
127 rect->bottom = rect->top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
130 static HWND create_window(void)
132 RECT r = {0, 0, 640, 480};
134 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
136 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
137 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
140 /* try to make sure pending X events have been processed before continuing */
141 static void flush_events(void)
143 MSG msg;
144 int diff = 200;
145 int min_timeout = 100;
146 DWORD time = GetTickCount() + diff;
148 while (diff > 0)
150 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
151 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
152 diff = time - GetTickCount();
156 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
158 return !strcmp(identifier->Driver, "d3d10warp.dll");
161 static BOOL equal_mode_rect(const DEVMODEW *mode1, const DEVMODEW *mode2)
163 return mode1->dmPosition.x == mode2->dmPosition.x
164 && mode1->dmPosition.y == mode2->dmPosition.y
165 && mode1->dmPelsWidth == mode2->dmPelsWidth
166 && mode1->dmPelsHeight == mode2->dmPelsHeight;
169 /* Free original_modes after finished using it */
170 static BOOL save_display_modes(DEVMODEW **original_modes, unsigned int *display_count)
172 unsigned int number, size = 2, count = 0, index = 0;
173 DISPLAY_DEVICEW display_device;
174 DEVMODEW *modes, *tmp;
176 if (!(modes = malloc(size * sizeof(*modes))))
177 return FALSE;
179 display_device.cb = sizeof(display_device);
180 while (EnumDisplayDevicesW(NULL, index++, &display_device, 0))
182 /* Skip software devices */
183 if (swscanf(display_device.DeviceName, L"\\\\.\\DISPLAY%u", &number) != 1)
184 continue;
186 if (!(display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
187 continue;
189 if (count >= size)
191 size *= 2;
192 if (!(tmp = realloc(modes, size * sizeof(*modes))))
194 free(modes);
195 return FALSE;
197 modes = tmp;
200 memset(&modes[count], 0, sizeof(modes[count]));
201 modes[count].dmSize = sizeof(modes[count]);
202 if (!EnumDisplaySettingsW(display_device.DeviceName, ENUM_CURRENT_SETTINGS, &modes[count]))
204 free(modes);
205 return FALSE;
208 lstrcpyW(modes[count++].dmDeviceName, display_device.DeviceName);
211 *original_modes = modes;
212 *display_count = count;
213 return TRUE;
216 static BOOL restore_display_modes(DEVMODEW *modes, unsigned int count)
218 unsigned int index;
219 LONG ret;
221 for (index = 0; index < count; ++index)
223 ret = ChangeDisplaySettingsExW(modes[index].dmDeviceName, &modes[index], NULL,
224 CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
225 if (ret != DISP_CHANGE_SUCCESSFUL)
226 return FALSE;
228 ret = ChangeDisplaySettingsExW(NULL, NULL, NULL, 0, NULL);
229 return ret == DISP_CHANGE_SUCCESSFUL;
232 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window, const struct device_desc *desc)
234 D3DPRESENT_PARAMETERS present_parameters = {0};
235 unsigned int adapter_ordinal;
236 IDirect3DDevice9 *device;
237 DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
239 adapter_ordinal = D3DADAPTER_DEFAULT;
240 present_parameters.BackBufferWidth = 640;
241 present_parameters.BackBufferHeight = 480;
242 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
243 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
244 present_parameters.hDeviceWindow = focus_window;
245 present_parameters.Windowed = TRUE;
246 present_parameters.EnableAutoDepthStencil = TRUE;
247 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
249 if (desc)
251 adapter_ordinal = desc->adapter_ordinal;
252 present_parameters.BackBufferWidth = desc->width;
253 present_parameters.BackBufferHeight = desc->height;
254 if (desc->flags & CREATE_DEVICE_UNKNOWN_BACKBUFFER_FORMAT)
255 present_parameters.BackBufferFormat = D3DFMT_UNKNOWN;
256 present_parameters.hDeviceWindow = desc->device_window;
257 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
258 if (desc->flags & CREATE_DEVICE_LOCKABLE_BACKBUFFER)
259 present_parameters.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
260 if (desc->flags & CREATE_DEVICE_SWVP_ONLY)
261 behavior_flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
262 else if (desc->flags & CREATE_DEVICE_MIXED_ONLY)
263 behavior_flags = D3DCREATE_MIXED_VERTEXPROCESSING;
264 if (desc->flags & CREATE_DEVICE_NOWINDOWCHANGES)
265 behavior_flags |= D3DCREATE_NOWINDOWCHANGES;
266 if (desc->flags & CREATE_DEVICE_FPU_PRESERVE)
267 behavior_flags |= D3DCREATE_FPU_PRESERVE;
270 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, adapter_ordinal, D3DDEVTYPE_HAL, focus_window,
271 behavior_flags, &present_parameters, &device)))
272 return device;
274 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
275 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, adapter_ordinal, D3DDEVTYPE_HAL, focus_window,
276 behavior_flags, &present_parameters, &device)))
277 return device;
279 if (desc && (desc->flags & (CREATE_DEVICE_SWVP_ONLY | CREATE_DEVICE_MIXED_ONLY)))
280 return NULL;
281 behavior_flags = (behavior_flags
282 & ~(D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING))
283 | D3DCREATE_HARDWARE_VERTEXPROCESSING;
285 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, adapter_ordinal, D3DDEVTYPE_HAL, focus_window,
286 behavior_flags, &present_parameters, &device)))
287 return device;
289 return NULL;
292 static HRESULT reset_device(IDirect3DDevice9 *device, const struct device_desc *desc)
294 D3DPRESENT_PARAMETERS present_parameters = {0};
296 present_parameters.BackBufferWidth = 640;
297 present_parameters.BackBufferHeight = 480;
298 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
299 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
300 present_parameters.hDeviceWindow = NULL;
301 present_parameters.Windowed = TRUE;
302 present_parameters.EnableAutoDepthStencil = TRUE;
303 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
305 if (desc)
307 present_parameters.BackBufferWidth = desc->width;
308 present_parameters.BackBufferHeight = desc->height;
309 present_parameters.hDeviceWindow = desc->device_window;
310 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
313 return IDirect3DDevice9_Reset(device, &present_parameters);
316 #define CHECK_CALL(r,c,d,rc) \
317 if (SUCCEEDED(r)) {\
318 int tmp1 = get_refcount( (IUnknown *)d ); \
319 int rc_new = rc; \
320 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
321 } else {\
322 trace("%s failed: %08lx\n", c, r); \
325 #define CHECK_RELEASE(obj,d,rc) \
326 if (obj) { \
327 int tmp1, rc_new = rc; \
328 IUnknown_Release( (IUnknown*)obj ); \
329 tmp1 = get_refcount( (IUnknown *)d ); \
330 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
333 #define CHECK_REFCOUNT(obj,rc) \
335 int rc_new = rc; \
336 int count = get_refcount( (IUnknown *)obj ); \
337 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
340 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
342 int rc_new = rc; \
343 int count = IUnknown_Release( (IUnknown *)obj ); \
344 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
347 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
349 int rc_new = rc; \
350 int count = IUnknown_AddRef( (IUnknown *)obj ); \
351 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
354 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
356 void *container_ptr = (void *)0x1337c0d3; \
357 hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
358 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#lx, container_ptr %p. " \
359 "Expected hr %#lx, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
360 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
363 static void test_get_set_vertex_declaration(void)
365 IDirect3DVertexDeclaration9 *declaration, *tmp;
366 ULONG refcount, expected_refcount;
367 IDirect3DDevice9 *device;
368 IDirect3D9 *d3d;
369 HWND window;
370 HRESULT hr;
372 static const D3DVERTEXELEMENT9 simple_decl[] =
374 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
375 D3DDECL_END()
378 window = create_window();
379 d3d = Direct3DCreate9(D3D_SDK_VERSION);
380 ok(!!d3d, "Failed to create a D3D object.\n");
381 if (!(device = create_device(d3d, window, NULL)))
383 skip("Failed to create a D3D device, skipping tests.\n");
384 goto done;
387 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
388 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
390 /* SetVertexDeclaration() should not touch the declaration's refcount. */
391 expected_refcount = get_refcount((IUnknown *)declaration);
392 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
393 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
394 refcount = get_refcount((IUnknown *)declaration);
395 ok(refcount == expected_refcount, "Got unexpected refcount %lu, expected %lu.\n", refcount, expected_refcount);
397 /* GetVertexDeclaration() should increase the declaration's refcount by one. */
398 tmp = NULL;
399 expected_refcount = refcount + 1;
400 hr = IDirect3DDevice9_GetVertexDeclaration(device, &tmp);
401 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#lx.\n", hr);
402 ok(tmp == declaration, "Got unexpected declaration %p, expected %p.\n", tmp, declaration);
403 refcount = get_refcount((IUnknown *)declaration);
404 ok(refcount == expected_refcount, "Got unexpected refcount %lu, expected %lu.\n", refcount, expected_refcount);
405 IDirect3DVertexDeclaration9_Release(tmp);
407 IDirect3DVertexDeclaration9_Release(declaration);
408 refcount = IDirect3DDevice9_Release(device);
409 ok(!refcount, "Device has %lu references left.\n", refcount);
410 done:
411 IDirect3D9_Release(d3d);
412 DestroyWindow(window);
415 static void test_get_declaration(void)
417 unsigned int element_count, expected_element_count;
418 IDirect3DVertexDeclaration9 *declaration;
419 D3DVERTEXELEMENT9 *elements;
420 IDirect3DDevice9 *device;
421 IDirect3D9 *d3d;
422 ULONG refcount;
423 HWND window;
424 HRESULT hr;
426 static const D3DVERTEXELEMENT9 simple_decl[] =
428 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
429 D3DDECL_END()
432 window = create_window();
433 d3d = Direct3DCreate9(D3D_SDK_VERSION);
434 ok(!!d3d, "Failed to create a D3D object.\n");
435 if (!(device = create_device(d3d, window, NULL)))
437 skip("Failed to create a D3D device, skipping tests.\n");
438 goto done;
441 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
442 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
444 /* First test only getting the number of elements. */
445 element_count = 0x1337c0de;
446 expected_element_count = ARRAY_SIZE(simple_decl);
447 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
448 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#lx.\n", hr);
449 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
450 element_count, expected_element_count);
452 element_count = 0;
453 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
454 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#lx.\n", hr);
455 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
456 element_count, expected_element_count);
458 /* Also test the returned data. */
459 elements = calloc(1, sizeof(simple_decl));
461 element_count = 0x1337c0de;
462 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
463 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#lx.\n", hr);
464 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
465 element_count, expected_element_count);
466 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
467 "Original and returned vertexdeclarations are not the same.\n");
469 memset(elements, 0, sizeof(simple_decl));
471 element_count = 0;
472 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
473 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#lx.\n", hr);
474 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
475 element_count, expected_element_count);
476 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
477 "Original and returned vertexdeclarations are not the same.\n");
479 free(elements);
480 IDirect3DVertexDeclaration9_Release(declaration);
481 refcount = IDirect3DDevice9_Release(device);
482 ok(!refcount, "Device has %lu references left.\n", refcount);
483 done:
484 IDirect3D9_Release(d3d);
485 DestroyWindow(window);
488 static void test_fvf_decl_conversion(void)
490 IDirect3DVertexDeclaration9 *default_decl;
491 IDirect3DVertexDeclaration9 *declaration;
492 IDirect3DDevice9 *device;
493 IDirect3D9 *d3d;
494 ULONG refcount;
495 unsigned int i;
496 HWND window;
497 HRESULT hr;
499 static const D3DVERTEXELEMENT9 default_elements[] =
501 {0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
502 {0, 4, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
503 D3DDECL_END()
505 /* Test conversions from vertex declaration to an FVF. For some reason
506 * those seem to occur only for POSITION/POSITIONT, otherwise the FVF is
507 * forced to 0 - maybe this is configuration specific. */
508 static const struct
510 D3DVERTEXELEMENT9 elements[7];
511 DWORD fvf;
512 BOOL todo;
514 decl_to_fvf_tests[] =
516 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}, D3DFVF_XYZ, TRUE },
517 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}, D3DFVF_XYZRHW, TRUE },
518 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
519 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
520 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
521 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
522 {{{0, 0, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0}, D3DDECL_END()}, 0, FALSE},
523 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}, 0, FALSE},
524 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}, 0, FALSE},
525 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}, 0, FALSE},
526 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}, 0, FALSE},
527 /* No FVF mapping available. */
528 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 1}, D3DDECL_END()}, 0, FALSE},
529 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 1}, D3DDECL_END()}, 0, FALSE},
530 /* Try empty declaration. */
531 {{ D3DDECL_END()}, 0, FALSE},
532 /* Make sure textures of different sizes work. */
533 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
534 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
535 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
536 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
537 /* Make sure the TEXCOORD index works correctly - try several textures. */
540 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
541 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
542 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
543 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
544 D3DDECL_END(),
545 }, 0, FALSE,
547 /* Now try a combination test. */
550 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITIONT, 0},
551 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
552 {0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0},
553 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
554 {0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
555 {0, 44, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1},
556 D3DDECL_END(),
557 }, 0, FALSE,
560 /* Test conversions from FVF to a vertex declaration. These seem to always
561 * occur internally. A new declaration object is created if necessary. */
562 static const struct
564 DWORD fvf;
565 D3DVERTEXELEMENT9 elements[7];
567 fvf_to_decl_tests[] =
569 {D3DFVF_XYZ, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
570 {D3DFVF_XYZW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
571 {D3DFVF_XYZRHW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}},
573 D3DFVF_XYZB5,
575 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
576 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
577 {0, 28, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDINDICES, 0},
578 D3DDECL_END(),
582 D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4,
584 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
585 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
586 {0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
587 D3DDECL_END(),
591 D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR,
593 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
594 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
595 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
596 D3DDECL_END(),
600 D3DFVF_XYZB1,
602 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
603 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
604 D3DDECL_END(),
608 D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4,
610 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
611 {0, 12, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
612 D3DDECL_END(),
616 D3DFVF_XYZB1 | D3DFVF_LASTBETA_D3DCOLOR,
618 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
619 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
620 D3DDECL_END(),
624 D3DFVF_XYZB2,
626 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
627 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
628 D3DDECL_END(),
632 D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4,
634 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
635 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
636 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
637 D3DDECL_END(),
641 D3DFVF_XYZB2 | D3DFVF_LASTBETA_D3DCOLOR,
643 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
644 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
645 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
646 D3DDECL_END(),
650 D3DFVF_XYZB3,
652 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
653 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
654 D3DDECL_END(),
658 D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4,
660 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
661 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
662 {0, 20, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
663 D3DDECL_END(),
667 D3DFVF_XYZB3 | D3DFVF_LASTBETA_D3DCOLOR,
669 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
670 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
671 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
672 D3DDECL_END(),
676 D3DFVF_XYZB4,
678 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
679 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
680 D3DDECL_END(),
684 D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4,
686 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
687 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
688 {0, 24, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
689 D3DDECL_END(),
693 D3DFVF_XYZB4 | D3DFVF_LASTBETA_D3DCOLOR,
695 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
696 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
697 {0, 24, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
698 D3DDECL_END(),
701 {D3DFVF_NORMAL, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}},
702 {D3DFVF_PSIZE, {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}},
703 {D3DFVF_DIFFUSE, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}},
704 {D3DFVF_SPECULAR, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}},
705 /* Make sure textures of different sizes work. */
707 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1,
708 {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
711 D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1,
712 {{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
715 D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1,
716 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
719 D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1,
720 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
722 /* Make sure the TEXCOORD index works correctly - try several textures. */
724 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE2(2)
725 | D3DFVF_TEXCOORDSIZE4(3) | D3DFVF_TEX4,
727 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
728 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
729 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
730 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
731 D3DDECL_END(),
734 /* Now try a combination test. */
736 D3DFVF_XYZB4 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEXCOORDSIZE2(0)
737 | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEX2,
739 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
740 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
741 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
742 {0, 32, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
743 {0, 36, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0},
744 {0, 44, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
745 D3DDECL_END(),
750 window = create_window();
751 d3d = Direct3DCreate9(D3D_SDK_VERSION);
752 ok(!!d3d, "Failed to create a D3D object.\n");
753 if (!(device = create_device(d3d, window, NULL)))
755 skip("Failed to create a D3D device, skipping tests.\n");
756 goto done;
759 for (i = 0; i < ARRAY_SIZE(decl_to_fvf_tests); ++i)
761 DWORD fvf = 0xdeadbeef;
762 HRESULT hr;
764 /* Set a default FVF of SPECULAR and DIFFUSE to make sure it is changed
765 * back to 0. */
766 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
767 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#lx.\n", i, hr);
769 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_to_fvf_tests[i].elements, &declaration);
770 ok(SUCCEEDED(hr), "Test %u: Failed to create vertex declaration, hr %#lx.\n", i, hr);
771 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
772 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#lx.\n", i, hr);
774 /* Check the FVF. */
775 hr = IDirect3DDevice9_GetFVF(device, &fvf);
776 ok(SUCCEEDED(hr), "Test %u: Failed to get FVF, hr %#lx.\n", i, hr);
778 todo_wine_if (decl_to_fvf_tests[i].todo)
779 ok(fvf == decl_to_fvf_tests[i].fvf,
780 "Test %u: Got unexpected FVF %#lx, expected %#lx.\n",
781 i, fvf, decl_to_fvf_tests[i].fvf);
783 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
784 IDirect3DVertexDeclaration9_Release(declaration);
787 /* Create a default declaration and FVF that does not match any of the
788 * tests. */
789 hr = IDirect3DDevice9_CreateVertexDeclaration(device, default_elements, &default_decl);
790 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#lx.\n", hr);
792 for (i = 0; i < ARRAY_SIZE(fvf_to_decl_tests); ++i)
794 /* Set a default declaration to make sure it is changed. */
795 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
796 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#lx.\n", i, hr);
798 hr = IDirect3DDevice9_SetFVF(device, fvf_to_decl_tests[i].fvf);
799 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#lx.\n", i, hr);
801 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
802 ok(SUCCEEDED(hr), "Test %u: Failed to get vertex declaration, hr %#lx.\n", i, hr);
803 ok(!!declaration && declaration != default_decl,
804 "Test %u: Got unexpected declaration %p.\n", i, declaration);
805 ok(compare_elements(declaration, fvf_to_decl_tests[i].elements),
806 "Test %u: Declaration does not match.\n", i);
807 IDirect3DVertexDeclaration9_Release(declaration);
810 /* Setting the FVF to 0 should result in no change to the default decl. */
811 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
812 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
813 hr = IDirect3DDevice9_SetFVF(device, 0);
814 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
815 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
816 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#lx.\n", hr);
817 ok(declaration == default_decl, "Got unexpected declaration %p, expected %p.\n", declaration, default_decl);
818 IDirect3DVertexDeclaration9_Release(declaration);
820 IDirect3DVertexDeclaration9_Release(default_decl);
821 refcount = IDirect3DDevice9_Release(device);
822 ok(!refcount, "Device has %lu references left.\n", refcount);
823 done:
824 IDirect3D9_Release(d3d);
825 DestroyWindow(window);
828 /* Check whether a declaration converted from FVF is shared.
829 * Check whether refcounts behave as expected. */
830 static void test_fvf_decl_management(void)
832 IDirect3DVertexDeclaration9 *declaration1;
833 IDirect3DVertexDeclaration9 *declaration2;
834 IDirect3DVertexDeclaration9 *declaration3;
835 IDirect3DVertexDeclaration9 *declaration4;
836 IDirect3DDevice9 *device;
837 IDirect3D9 *d3d;
838 ULONG refcount;
839 HWND window;
840 HRESULT hr;
842 static const D3DVERTEXELEMENT9 test_elements1[] =
843 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()};
844 static const D3DVERTEXELEMENT9 test_elements2[] =
845 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()};
847 window = create_window();
848 d3d = Direct3DCreate9(D3D_SDK_VERSION);
849 ok(!!d3d, "Failed to create a D3D object.\n");
850 if (!(device = create_device(d3d, window, NULL)))
852 skip("Failed to create a D3D device, skipping tests.\n");
853 goto done;
856 /* Clear down any current vertex declaration. */
857 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
858 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
859 /* Conversion. */
860 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
861 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
862 /* Get converted decl (#1). */
863 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration1);
864 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#lx.\n", hr);
865 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
866 /* Get converted decl again (#2). */
867 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration2);
868 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#lx.\n", hr);
869 ok(declaration2 == declaration1, "Got unexpected declaration2 %p, expected %p.\n", declaration2, declaration1);
871 /* Conversion. */
872 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_NORMAL);
873 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
874 /* Get converted decl (#3). */
875 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration3);
876 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#lx.\n", hr);
877 ok(declaration3 != declaration2, "Got unexpected declaration3 %p.\n", declaration3);
878 /* The contents should correspond to the second conversion. */
879 ok(compare_elements(declaration3, test_elements2), "Declaration does not match.\n");
880 /* Re-Check if the first decl was overwritten by the new Get(). */
881 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
883 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
884 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
885 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration4);
886 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#lx.\n", hr);
887 ok(declaration4 == declaration1, "Got unexpected declaration4 %p, expected %p.\n", declaration4, declaration1);
889 refcount = get_refcount((IUnknown*)declaration1);
890 ok(refcount == 3, "Got unexpected refcount %lu.\n", refcount);
891 refcount = get_refcount((IUnknown*)declaration2);
892 ok(refcount == 3, "Got unexpected refcount %lu.\n", refcount);
893 refcount = get_refcount((IUnknown*)declaration3);
894 ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount);
895 refcount = get_refcount((IUnknown*)declaration4);
896 ok(refcount == 3, "Got unexpected refcount %lu.\n", refcount);
898 IDirect3DVertexDeclaration9_Release(declaration4);
899 IDirect3DVertexDeclaration9_Release(declaration3);
900 IDirect3DVertexDeclaration9_Release(declaration2);
901 IDirect3DVertexDeclaration9_Release(declaration1);
903 refcount = IDirect3DDevice9_Release(device);
904 ok(!refcount, "Device has %lu references left.\n", refcount);
905 done:
906 IDirect3D9_Release(d3d);
907 DestroyWindow(window);
910 static void test_vertex_declaration_alignment(void)
912 IDirect3DVertexDeclaration9 *declaration;
913 IDirect3DDevice9 *device;
914 IDirect3D9 *d3d;
915 unsigned int i;
916 ULONG refcount;
917 HWND window;
918 HRESULT hr;
920 static const struct
922 D3DVERTEXELEMENT9 elements[3];
923 HRESULT hr;
925 test_data[] =
929 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
930 {0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
931 D3DDECL_END(),
932 }, D3D_OK,
936 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
937 {0, 17, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
938 D3DDECL_END(),
939 }, E_FAIL,
943 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
944 {0, 18, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
945 D3DDECL_END(),
946 }, E_FAIL,
950 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
951 {0, 19, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
952 D3DDECL_END(),
953 }, E_FAIL,
957 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
958 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
959 D3DDECL_END(),
960 }, D3D_OK,
964 window = create_window();
965 d3d = Direct3DCreate9(D3D_SDK_VERSION);
966 ok(!!d3d, "Failed to create a D3D object.\n");
967 if (!(device = create_device(d3d, window, NULL)))
969 skip("Failed to create a D3D device, skipping tests.\n");
970 goto done;
973 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
975 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_data[i].elements, &declaration);
976 ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i, hr, test_data[i].hr);
977 if (SUCCEEDED(hr))
978 IDirect3DVertexDeclaration9_Release(declaration);
981 refcount = IDirect3DDevice9_Release(device);
982 ok(!refcount, "Device has %lu references left.\n", refcount);
983 done:
984 IDirect3D9_Release(d3d);
985 DestroyWindow(window);
988 static void test_unused_declaration_type(void)
990 IDirect3DVertexDeclaration9 *declaration;
991 IDirect3DDevice9 *device;
992 IDirect3D9 *d3d;
993 unsigned int i;
994 ULONG refcount;
995 HWND window;
996 HRESULT hr;
998 static const D3DVERTEXELEMENT9 test_elements[][3] =
1001 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
1002 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_COLOR , 0 },
1003 D3DDECL_END(),
1006 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
1007 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 0 },
1008 D3DDECL_END(),
1011 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
1012 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 1 },
1013 D3DDECL_END(),
1016 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
1017 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
1018 D3DDECL_END(),
1021 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
1022 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
1023 D3DDECL_END(),
1026 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
1027 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
1028 D3DDECL_END(),
1031 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
1032 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
1033 D3DDECL_END(),
1037 window = create_window();
1038 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1039 ok(!!d3d, "Failed to create a D3D object.\n");
1040 if (!(device = create_device(d3d, window, NULL)))
1042 skip("Failed to create a D3D device, skipping tests.\n");
1043 goto done;
1046 for (i = 0; i < ARRAY_SIZE(test_elements); ++i)
1048 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &declaration);
1049 ok(hr == E_FAIL, "Test %u: Got unexpected hr %#lx.\n", i, hr);
1052 refcount = IDirect3DDevice9_Release(device);
1053 ok(!refcount, "Device has %lu references left.\n", refcount);
1054 done:
1055 IDirect3D9_Release(d3d);
1056 DestroyWindow(window);
1059 static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count)
1061 IDirect3DBaseTexture9* texture = NULL;
1062 HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0,
1063 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
1065 if (SUCCEEDED(hr)) {
1066 DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
1067 ok(levels == count, "Invalid level count. Expected %d got %lu\n", count, levels);
1068 } else
1069 trace("CreateTexture failed: %08lx\n", hr);
1071 if (texture) IDirect3DBaseTexture9_Release( texture );
1074 static void test_mipmap_levels(void)
1076 IDirect3DDevice9 *device;
1077 IDirect3D9 *d3d;
1078 ULONG refcount;
1079 HWND window;
1081 window = create_window();
1082 ok(!!window, "Failed to create a window.\n");
1083 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1084 ok(!!d3d, "Failed to create a D3D object.\n");
1085 if (!(device = create_device(d3d, window, NULL)))
1087 skip("Failed to create a 3D device, skipping test.\n");
1088 goto cleanup;
1091 check_mipmap_levels(device, 32, 32, 6);
1092 check_mipmap_levels(device, 256, 1, 9);
1093 check_mipmap_levels(device, 1, 256, 9);
1094 check_mipmap_levels(device, 1, 1, 1);
1096 refcount = IDirect3DDevice9_Release(device);
1097 ok(!refcount, "Device has %lu references left.\n", refcount);
1098 cleanup:
1099 IDirect3D9_Release(d3d);
1100 DestroyWindow(window);
1103 static void test_checkdevicemultisampletype(void)
1105 DWORD quality_levels;
1106 IDirect3D9 *d3d;
1107 HWND window;
1108 HRESULT hr;
1110 window = create_window();
1111 ok(!!window, "Failed to create a window.\n");
1112 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1113 ok(!!d3d, "Failed to create a D3D object.\n");
1115 if (IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1116 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL) == D3DERR_NOTAVAILABLE)
1118 skip("Multisampling not supported for D3DFMT_X8R8G8B8, skipping test.\n");
1119 goto cleanup;
1122 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1123 D3DFMT_UNKNOWN, TRUE, D3DMULTISAMPLE_NONE, NULL);
1124 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1125 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1126 65536, TRUE, D3DMULTISAMPLE_NONE, NULL);
1127 todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1129 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1130 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, NULL);
1131 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1133 quality_levels = 0;
1134 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1135 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality_levels);
1136 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1137 ok(quality_levels == 1, "Got unexpected quality_levels %lu.\n", quality_levels);
1138 quality_levels = 0;
1139 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1140 D3DFMT_X8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality_levels);
1141 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1142 ok(quality_levels == 1, "Got unexpected quality_levels %lu.\n", quality_levels);
1144 quality_levels = 0;
1145 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1146 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, NULL);
1147 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1148 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1149 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, &quality_levels);
1150 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1151 ok(quality_levels, "Got unexpected quality_levels %lu.\n", quality_levels);
1153 quality_levels = 0;
1154 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1155 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
1156 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1157 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1158 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels);
1159 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1160 ok(quality_levels, "Got unexpected quality_levels %lu.\n", quality_levels);
1162 /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */
1163 quality_levels = 0;
1164 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1165 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, NULL);
1166 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
1167 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1168 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, &quality_levels);
1169 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
1170 ok(quality_levels == 1, "Got unexpected quality_levels %lu.\n", quality_levels);
1172 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1173 D3DFMT_X8R8G8B8, TRUE, 65536, NULL);
1174 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1176 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1177 D3DFMT_DXT5, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
1178 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
1180 cleanup:
1181 IDirect3D9_Release(d3d);
1182 DestroyWindow(window);
1185 static void test_invalid_multisample(void)
1187 IDirect3DDevice9 *device;
1188 IDirect3DSurface9 *rt;
1189 DWORD quality_levels;
1190 IDirect3D9 *d3d;
1191 BOOL available;
1192 ULONG refcount;
1193 HWND window;
1194 HRESULT hr;
1196 window = create_window();
1197 ok(!!window, "Failed to create a window.\n");
1198 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1199 ok(!!d3d, "Failed to create a D3D object.\n");
1201 if (!(device = create_device(d3d, window, NULL)))
1203 skip("Failed to create a 3D device, skipping test.\n");
1204 goto cleanup;
1207 available = SUCCEEDED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1208 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, &quality_levels));
1209 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1210 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONMASKABLE, 0, FALSE, &rt, NULL);
1211 if (available)
1213 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1214 IDirect3DSurface9_Release(rt);
1215 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1216 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONMASKABLE, quality_levels, FALSE, &rt, NULL);
1217 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1219 else
1221 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1224 available = SUCCEEDED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1225 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels));
1226 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1227 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
1228 if (available)
1230 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
1231 IDirect3DSurface9_Release(rt);
1232 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1233 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, quality_levels, FALSE, &rt, NULL);
1234 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1236 else
1238 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1241 /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */
1242 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1243 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, NULL);
1244 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
1245 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1246 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_15_SAMPLES, 0, FALSE, &rt, NULL);
1247 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1249 refcount = IDirect3DDevice9_Release(device);
1250 ok(!refcount, "Device has %lu references left.\n", refcount);
1251 cleanup:
1252 IDirect3D9_Release(d3d);
1253 DestroyWindow(window);
1256 static void test_swapchain(void)
1258 IDirect3DSwapChain9 *swapchain0;
1259 IDirect3DSwapChain9 *swapchain1;
1260 IDirect3DSwapChain9 *swapchain2;
1261 IDirect3DSwapChain9 *swapchain3;
1262 IDirect3DSwapChain9 *swapchainX;
1263 IDirect3DSurface9 *backbuffer, *stereo_buffer;
1264 D3DPRESENT_PARAMETERS d3dpp;
1265 IDirect3DDevice9 *device;
1266 RECT client_rect;
1267 IDirect3D9 *d3d;
1268 ULONG refcount;
1269 HWND window, window2;
1270 HRESULT hr;
1271 struct device_desc device_desc;
1273 window = create_window();
1274 ok(!!window, "Failed to create a window.\n");
1275 window2 = create_window();
1276 ok(!!window2, "Failed to create a window.\n");
1277 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1278 ok(!!d3d, "Failed to create a D3D object.\n");
1279 if (!(device = create_device(d3d, window, NULL)))
1281 skip("Failed to create a 3D device, skipping test.\n");
1282 goto cleanup;
1285 /* Get the implicit swapchain */
1286 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain0);
1287 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1288 /* Check if the back buffer count was modified */
1289 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain0, &d3dpp);
1290 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#lx.\n", hr);
1291 ok(d3dpp.BackBufferCount == 1, "Got unexpected back buffer count %u.\n", d3dpp.BackBufferCount);
1292 IDirect3DSwapChain9_Release(swapchain0);
1294 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, NULL);
1295 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1296 /* IDirect3DDevice9::GetBackBuffer crashes if a NULL output pointer is passed. */
1297 backbuffer = (void *)0xdeadbeef;
1298 hr = IDirect3DDevice9_GetBackBuffer(device, 1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1299 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1300 ok(!backbuffer, "The back buffer pointer is %p, expected NULL.\n", backbuffer);
1301 backbuffer = (void *)0xdeadbeef;
1302 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 1, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1303 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1304 ok(!backbuffer, "The back buffer pointer is %p, expected NULL.\n", backbuffer);
1306 /* Check if there is a back buffer */
1307 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1308 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1309 ok(backbuffer != NULL, "The back buffer is NULL\n");
1310 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1312 /* The back buffer type value is ignored. */
1313 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_LEFT, &stereo_buffer);
1314 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#lx.\n", hr);
1315 ok(stereo_buffer == backbuffer, "Expected left back buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1316 IDirect3DSurface9_Release(stereo_buffer);
1317 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_RIGHT, &stereo_buffer);
1318 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#lx.\n", hr);
1319 ok(stereo_buffer == backbuffer, "Expected right back buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1320 IDirect3DSurface9_Release(stereo_buffer);
1321 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, (D3DBACKBUFFER_TYPE)0xdeadbeef, &stereo_buffer);
1322 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#lx.\n", hr);
1323 ok(stereo_buffer == backbuffer, "Expected unknown buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1324 IDirect3DSurface9_Release(stereo_buffer);
1326 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_LEFT, &stereo_buffer);
1327 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#lx.\n", hr);
1328 ok(stereo_buffer == backbuffer, "Expected left back buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1329 IDirect3DSurface9_Release(stereo_buffer);
1330 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_RIGHT, &stereo_buffer);
1331 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#lx.\n", hr);
1332 ok(stereo_buffer == backbuffer, "Expected right back buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1333 IDirect3DSurface9_Release(stereo_buffer);
1334 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, (D3DBACKBUFFER_TYPE)0xdeadbeef, &stereo_buffer);
1335 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#lx.\n", hr);
1336 ok(stereo_buffer == backbuffer, "Expected unknown buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1337 IDirect3DSurface9_Release(stereo_buffer);
1339 /* Try to get a nonexistent swapchain */
1340 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1341 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1342 ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
1343 if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
1345 memset(&d3dpp, 0, sizeof(d3dpp));
1346 d3dpp.Windowed = TRUE;
1347 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1348 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1349 GetClientRect(window, &client_rect);
1351 /* Create a bunch of swapchains */
1352 d3dpp.BackBufferCount = 0;
1353 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1354 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1355 ok(d3dpp.BackBufferWidth == client_rect.right, "Got unexpected BackBufferWidth %u, expected %ld.\n",
1356 d3dpp.BackBufferWidth, client_rect.right);
1357 ok(d3dpp.BackBufferHeight == client_rect.bottom, "Got unexpected BackBufferHeight %u, expected %ld.\n",
1358 d3dpp.BackBufferHeight, client_rect.bottom);
1359 ok(d3dpp.BackBufferFormat == D3DFMT_A8R8G8B8, "Got unexpected BackBufferFormat %#x.\n", d3dpp.BackBufferFormat);
1360 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
1361 ok(!d3dpp.hDeviceWindow, "Got unexpected hDeviceWindow %p.\n", d3dpp.hDeviceWindow);
1363 d3dpp.hDeviceWindow = NULL;
1364 d3dpp.BackBufferCount = 1;
1365 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain2);
1366 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1367 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain2, &d3dpp);
1368 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1369 ok(d3dpp.hDeviceWindow == window, "Got window %p, expected %p.\n", d3dpp.hDeviceWindow, window);
1371 d3dpp.BackBufferCount = 2;
1372 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain3);
1373 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1374 if(SUCCEEDED(hr)) {
1375 /* Swapchain 3, created with backbuffercount 2 */
1376 backbuffer = (void *) 0xdeadbeef;
1377 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
1378 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1379 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1380 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1382 backbuffer = (void *) 0xdeadbeef;
1383 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
1384 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1385 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1386 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1388 backbuffer = (void *) 0xdeadbeef;
1389 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
1390 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1391 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1392 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1394 backbuffer = (void *) 0xdeadbeef;
1395 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
1396 ok(FAILED(hr), "Got hr %#lx.\n", hr);
1397 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1398 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1401 /* Check the back buffers of the swapchains */
1402 /* Swapchain 1, created with backbuffercount 0 */
1403 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1404 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1405 ok(backbuffer != NULL, "Got hr %#lx.\n", hr);
1406 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1408 backbuffer = (void *) 0xdeadbeef;
1409 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
1410 ok(FAILED(hr), "Got hr %#lx.\n", hr);
1411 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1412 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1414 /* Swapchain 2 - created with backbuffercount 1 */
1415 backbuffer = (void *) 0xdeadbeef;
1416 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
1417 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1418 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1419 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1421 backbuffer = (void *) 0xdeadbeef;
1422 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
1423 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1424 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1425 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1427 backbuffer = (void *) 0xdeadbeef;
1428 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
1429 ok(FAILED(hr), "Got hr %#lx.\n", hr);
1430 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1431 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1433 /* Try getSwapChain on a manually created swapchain
1434 * it should fail, apparently GetSwapChain only returns implicit swapchains
1436 swapchainX = (void *) 0xdeadbeef;
1437 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1438 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1439 ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
1440 if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
1442 IDirect3DSwapChain9_Release(swapchain3);
1443 IDirect3DSwapChain9_Release(swapchain2);
1444 IDirect3DSwapChain9_Release(swapchain1);
1446 d3dpp.Windowed = FALSE;
1447 d3dpp.hDeviceWindow = window;
1448 d3dpp.BackBufferCount = 1;
1449 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1450 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx\n", hr);
1451 d3dpp.hDeviceWindow = window2;
1452 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1453 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx\n", hr);
1455 device_desc.width = registry_mode.dmPelsWidth;
1456 device_desc.height = registry_mode.dmPelsHeight;
1457 device_desc.device_window = window;
1458 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
1459 hr = reset_device(device, &device_desc);
1460 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
1462 d3dpp.hDeviceWindow = window;
1463 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1464 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx\n", hr);
1465 d3dpp.hDeviceWindow = window2;
1466 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1467 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx\n", hr);
1468 d3dpp.Windowed = TRUE;
1469 d3dpp.hDeviceWindow = window;
1470 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1471 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx\n", hr);
1472 d3dpp.hDeviceWindow = window2;
1473 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1474 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx\n", hr);
1476 refcount = IDirect3DDevice9_Release(device);
1477 ok(!refcount, "Device has %lu references left.\n", refcount);
1478 cleanup:
1479 IDirect3D9_Release(d3d);
1480 DestroyWindow(window2);
1481 DestroyWindow(window);
1484 static void test_refcount(void)
1486 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
1487 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
1488 IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
1489 IDirect3DVertexShader9 *pVertexShader = NULL;
1490 IDirect3DPixelShader9 *pPixelShader = NULL;
1491 IDirect3DCubeTexture9 *pCubeTexture = NULL;
1492 IDirect3DTexture9 *pTexture = NULL;
1493 IDirect3DVolumeTexture9 *pVolumeTexture = NULL;
1494 IDirect3DVolume9 *pVolumeLevel = NULL;
1495 IDirect3DSurface9 *pStencilSurface = NULL;
1496 IDirect3DSurface9 *pOffscreenSurface = NULL;
1497 IDirect3DSurface9 *pRenderTarget = NULL;
1498 IDirect3DSurface9 *pRenderTarget2 = NULL;
1499 IDirect3DSurface9 *pRenderTarget3 = NULL;
1500 IDirect3DSurface9 *pTextureLevel = NULL;
1501 IDirect3DSurface9 *pBackBuffer = NULL;
1502 IDirect3DStateBlock9 *pStateBlock = NULL;
1503 IDirect3DStateBlock9 *pStateBlock1 = NULL;
1504 IDirect3DSwapChain9 *pSwapChain = NULL;
1505 IDirect3DQuery9 *pQuery = NULL;
1506 D3DPRESENT_PARAMETERS d3dpp;
1507 IDirect3DDevice9 *device;
1508 ULONG refcount = 0, tmp;
1509 IDirect3D9 *d3d, *d3d2;
1510 HWND window;
1511 HRESULT hr;
1513 D3DVERTEXELEMENT9 decl[] =
1515 D3DDECL_END()
1518 window = create_window();
1519 ok(!!window, "Failed to create a window.\n");
1520 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1521 ok(!!d3d, "Failed to create a D3D object.\n");
1523 CHECK_REFCOUNT(d3d, 1);
1525 if (!(device = create_device(d3d, window, NULL)))
1527 skip("Failed to create a 3D device, skipping test.\n");
1528 goto cleanup;
1531 refcount = get_refcount((IUnknown *)device);
1532 ok(refcount == 1, "Unexpected refcount %lu.\n", refcount);
1534 CHECK_REFCOUNT(d3d, 2);
1536 hr = IDirect3DDevice9_GetDirect3D(device, &d3d2);
1537 CHECK_CALL(hr, "GetDirect3D", device, refcount);
1539 ok(d3d2 == d3d, "Expected IDirect3D9 pointers to be equal.\n");
1540 CHECK_REFCOUNT(d3d, 3);
1541 CHECK_RELEASE_REFCOUNT(d3d, 2);
1544 * Check refcount of implicit surfaces and implicit swapchain. Findings:
1545 * - the container is the device OR swapchain
1546 * - they hold a reference to the device
1547 * - they are created with a refcount of 0 (Get/Release returns original refcount)
1548 * - they are not freed if refcount reaches 0.
1549 * - the refcount is not forwarded to the container.
1551 hr = IDirect3DDevice9_GetSwapChain(device, 0, &pSwapChain);
1552 CHECK_CALL(hr, "GetSwapChain", device, ++refcount);
1553 if (pSwapChain)
1555 CHECK_REFCOUNT(pSwapChain, 1);
1557 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1558 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1559 CHECK_REFCOUNT(pSwapChain, 1);
1560 if (pRenderTarget)
1562 CHECK_SURFACE_CONTAINER(pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
1563 CHECK_REFCOUNT(pRenderTarget, 1);
1565 CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
1566 CHECK_REFCOUNT(device, refcount);
1567 CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
1568 CHECK_REFCOUNT(device, refcount);
1570 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1571 CHECK_CALL(hr, "GetRenderTarget", device, refcount);
1572 CHECK_REFCOUNT(pRenderTarget, 2);
1573 CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
1574 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
1575 CHECK_REFCOUNT(device, --refcount);
1577 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
1578 CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
1579 CHECK_REFCOUNT(device, ++refcount);
1580 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
1581 CHECK_REFCOUNT(device, --refcount);
1582 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
1583 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
1586 /* Render target and back buffer are identical. */
1587 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, 0, &pBackBuffer);
1588 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1589 if (pBackBuffer)
1591 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1592 ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
1593 pRenderTarget, pBackBuffer);
1594 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1595 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1596 pBackBuffer = NULL;
1598 CHECK_REFCOUNT(device, --refcount);
1600 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &pStencilSurface);
1601 CHECK_CALL(hr, "GetDepthStencilSurface", device, ++refcount);
1602 CHECK_REFCOUNT(pSwapChain, 1);
1603 if (pStencilSurface)
1605 CHECK_SURFACE_CONTAINER(pStencilSurface, IID_IDirect3DDevice9, device);
1606 CHECK_REFCOUNT( pStencilSurface, 1);
1608 CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
1609 CHECK_REFCOUNT(device, refcount);
1610 CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
1611 CHECK_REFCOUNT(device, refcount);
1613 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
1614 CHECK_REFCOUNT(device, --refcount);
1616 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
1617 CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
1618 CHECK_REFCOUNT(device, ++refcount);
1619 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
1620 CHECK_REFCOUNT(device, --refcount);
1621 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
1622 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
1623 pStencilSurface = NULL;
1626 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1627 CHECK_REFCOUNT(device, --refcount);
1628 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1629 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1631 /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
1632 CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
1633 CHECK_REFCOUNT(device, ++refcount);
1634 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1635 CHECK_REFCOUNT(device, --refcount);
1636 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1637 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1638 pSwapChain = NULL;
1641 /* Buffers */
1642 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL);
1643 CHECK_CALL(hr, "CreateIndexBuffer", device, ++refcount );
1644 if(pIndexBuffer)
1646 tmp = get_refcount((IUnknown *)pIndexBuffer);
1648 hr = IDirect3DDevice9_SetIndices(device, pIndexBuffer);
1649 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1650 hr = IDirect3DDevice9_SetIndices(device, NULL);
1651 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1654 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL);
1655 CHECK_CALL(hr, "CreateVertexBuffer", device, ++refcount);
1656 if(pVertexBuffer)
1658 IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
1659 UINT offset = ~0;
1660 UINT stride = ~0;
1662 tmp = get_refcount( (IUnknown *)pVertexBuffer );
1664 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 3 * sizeof(float));
1665 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1666 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1667 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1669 hr = IDirect3DDevice9_GetStreamSource(device, 0, &pVBuf, &offset, &stride);
1670 ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
1671 ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
1672 ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
1673 ok(offset==0, "offset not 0 (got %u)!\n", offset);
1675 /* Shaders */
1676 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pVertexDeclaration);
1677 CHECK_CALL(hr, "CreateVertexDeclaration", device, ++refcount);
1678 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &pVertexShader);
1679 CHECK_CALL(hr, "CreateVertexShader", device, ++refcount);
1680 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &pPixelShader);
1681 CHECK_CALL(hr, "CreatePixelShader", device, ++refcount);
1682 /* Textures */
1683 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL);
1684 CHECK_CALL(hr, "CreateTexture", device, ++refcount);
1685 if (pTexture)
1687 tmp = get_refcount( (IUnknown *)pTexture );
1689 /* SetTexture should not increase refcounts */
1690 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)pTexture);
1691 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1692 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1693 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1695 /* This should not increment device refcount */
1696 hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
1697 CHECK_CALL(hr, "GetSurfaceLevel", device, refcount);
1698 /* But should increment texture's refcount */
1699 CHECK_REFCOUNT( pTexture, tmp+1 );
1700 /* Because the texture and surface refcount are identical */
1701 if (pTextureLevel)
1703 CHECK_REFCOUNT ( pTextureLevel, tmp+1 );
1704 CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
1705 CHECK_REFCOUNT ( pTexture , tmp+2 );
1706 CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
1707 CHECK_REFCOUNT ( pTexture , tmp+1 );
1708 CHECK_RELEASE_REFCOUNT( pTexture , tmp );
1709 CHECK_REFCOUNT ( pTextureLevel, tmp );
1712 hr = IDirect3DDevice9_CreateCubeTexture(device, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL);
1713 CHECK_CALL(hr, "CreateCubeTexture", device, ++refcount);
1714 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 2, 0, 0,
1715 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL);
1716 CHECK_CALL(hr, "CreateVolumeTexture", device, ++refcount);
1717 if (pVolumeTexture)
1719 tmp = get_refcount( (IUnknown *)pVolumeTexture );
1721 /* This should not increment device refcount */
1722 hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
1723 CHECK_CALL(hr, "GetVolumeLevel", device, refcount);
1724 /* But should increment volume texture's refcount */
1725 CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
1726 /* Because the volume texture and volume refcount are identical */
1727 if (pVolumeLevel)
1729 CHECK_REFCOUNT ( pVolumeLevel , tmp+1 );
1730 CHECK_ADDREF_REFCOUNT ( pVolumeLevel , tmp+2 );
1731 CHECK_REFCOUNT ( pVolumeTexture, tmp+2 );
1732 CHECK_RELEASE_REFCOUNT( pVolumeLevel , tmp+1 );
1733 CHECK_REFCOUNT ( pVolumeTexture, tmp+1 );
1734 CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp );
1735 CHECK_REFCOUNT ( pVolumeLevel , tmp );
1738 /* Surfaces */
1739 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32,
1740 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL);
1741 CHECK_CALL(hr, "CreateDepthStencilSurface", device, ++refcount);
1742 CHECK_REFCOUNT( pStencilSurface, 1 );
1743 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1744 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL);
1745 CHECK_CALL(hr, "CreateOffscreenPlainSurface", device, ++refcount);
1746 CHECK_REFCOUNT( pOffscreenSurface, 1 );
1747 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
1748 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL);
1749 CHECK_CALL(hr, "CreateRenderTarget", device, ++refcount);
1750 CHECK_REFCOUNT( pRenderTarget3, 1 );
1751 /* Misc */
1752 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &pStateBlock);
1753 CHECK_CALL(hr, "CreateStateBlock", device, ++refcount);
1755 memset(&d3dpp, 0, sizeof(d3dpp));
1756 d3dpp.Windowed = TRUE;
1757 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1758 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1759 d3dpp.EnableAutoDepthStencil = TRUE;
1760 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1761 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &pSwapChain);
1762 CHECK_CALL(hr, "CreateAdditionalSwapChain", device, ++refcount);
1763 if (pSwapChain)
1765 /* check implicit back buffer */
1766 hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
1767 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1768 CHECK_REFCOUNT(pSwapChain, 1);
1769 if (pBackBuffer)
1771 CHECK_SURFACE_CONTAINER(pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
1772 CHECK_REFCOUNT(pBackBuffer, 1);
1773 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1774 CHECK_REFCOUNT(device, --refcount);
1776 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
1777 CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
1778 CHECK_REFCOUNT(device, ++refcount);
1779 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1780 CHECK_REFCOUNT(device, --refcount);
1781 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1782 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1783 pBackBuffer = NULL;
1785 CHECK_REFCOUNT(pSwapChain, 1);
1787 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &pQuery);
1788 CHECK_CALL(hr, "CreateQuery", device, ++refcount);
1790 hr = IDirect3DDevice9_BeginStateBlock(device);
1791 CHECK_CALL(hr, "BeginStateBlock", device, refcount);
1792 hr = IDirect3DDevice9_EndStateBlock(device, &pStateBlock1);
1793 CHECK_CALL(hr, "EndStateBlock", device, ++refcount);
1795 /* The implicit render target is not freed if refcount reaches 0.
1796 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
1797 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget2);
1798 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1799 if (pRenderTarget2)
1801 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
1802 ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
1803 pRenderTarget, pRenderTarget2);
1804 CHECK_REFCOUNT(device, --refcount);
1805 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
1806 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
1807 pRenderTarget2 = NULL;
1809 pRenderTarget = NULL;
1811 cleanup:
1812 CHECK_RELEASE(device, device, --refcount);
1814 /* Buffers */
1815 CHECK_RELEASE(pVertexBuffer, device, --refcount);
1816 CHECK_RELEASE(pIndexBuffer, device, --refcount);
1817 /* Shaders */
1818 CHECK_RELEASE(pVertexDeclaration, device, --refcount);
1819 CHECK_RELEASE(pVertexShader, device, --refcount);
1820 CHECK_RELEASE(pPixelShader, device, --refcount);
1821 /* Textures */
1822 CHECK_RELEASE(pTextureLevel, device, --refcount);
1823 CHECK_RELEASE(pCubeTexture, device, --refcount);
1824 CHECK_RELEASE(pVolumeTexture, device, --refcount);
1825 /* Surfaces */
1826 CHECK_RELEASE(pStencilSurface, device, --refcount);
1827 CHECK_RELEASE(pOffscreenSurface, device, --refcount);
1828 CHECK_RELEASE(pRenderTarget3, device, --refcount);
1829 /* Misc */
1830 CHECK_RELEASE(pStateBlock, device, --refcount);
1831 CHECK_RELEASE(pSwapChain, device, --refcount);
1832 CHECK_RELEASE(pQuery, device, --refcount);
1833 /* This will destroy device - cannot check the refcount here */
1834 if (pStateBlock1) CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
1835 CHECK_RELEASE_REFCOUNT(d3d, 0);
1836 DestroyWindow(window);
1839 static void test_cursor(void)
1841 unsigned int adapter_idx, adapter_count, test_idx;
1842 IDirect3DSurface9 *cursor = NULL;
1843 struct device_desc device_desc;
1844 unsigned int width, height;
1845 IDirect3DDevice9 *device;
1846 HRESULT expected_hr, hr;
1847 D3DDISPLAYMODE mode;
1848 CURSORINFO info;
1849 IDirect3D9 *d3d;
1850 ULONG refcount;
1851 HCURSOR cur;
1852 HWND window;
1853 BOOL ret;
1855 static const DWORD device_flags[] = {0, CREATE_DEVICE_FULLSCREEN};
1856 static const SIZE cursor_sizes[] =
1858 {1, 1},
1859 {2, 4},
1860 {3, 2},
1861 {2, 3},
1862 {6, 6},
1865 window = create_window();
1866 ok(!!window, "Failed to create a window.\n");
1868 ret = SetCursorPos(50, 50);
1869 ok(ret, "Failed to set cursor position.\n");
1870 flush_events();
1871 memset(&info, 0, sizeof(info));
1872 info.cbSize = sizeof(info);
1873 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1874 cur = info.hCursor;
1876 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1877 ok(!!d3d, "Failed to create a D3D object.\n");
1878 if (!(device = create_device(d3d, window, NULL)))
1880 skip("Failed to create a 3D device, skipping test.\n");
1881 goto cleanup;
1884 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1885 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
1886 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#lx.\n", hr);
1888 /* Initially hidden */
1889 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
1890 ok(!ret, "IDirect3DDevice9_ShowCursor returned %d\n", ret);
1892 /* Not enabled without a surface*/
1893 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
1894 ok(!ret, "IDirect3DDevice9_ShowCursor returned %d\n", ret);
1896 /* Fails */
1897 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, NULL);
1898 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1900 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
1901 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1903 IDirect3DSurface9_Release(cursor);
1905 /* On the testbot the cursor handle does not behave as expected in rare situations,
1906 * leading to random test failures. Either the cursor handle changes before we expect
1907 * it to, or it doesn't change afterwards (or already changed before we read the
1908 * initial handle?). I was not able to reproduce this on my own machines. Moving the
1909 * mouse outside the window results in similar behavior. However, I tested various
1910 * obvious failure causes: Was the mouse moved? Was the window hidden or moved? Is
1911 * the window in the background? Neither of those applies. Making the window topmost
1912 * or using a fullscreen device doesn't improve the test's reliability either. */
1913 memset(&info, 0, sizeof(info));
1914 info.cbSize = sizeof(info);
1915 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1916 ok(info.flags & (CURSOR_SHOWING | CURSOR_SUPPRESSED), "Got cursor flags %#lx.\n", info.flags);
1917 ok(info.hCursor == cur || broken(1), "The cursor handle is %p\n", info.hCursor); /* unchanged */
1919 /* Still hidden */
1920 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
1921 ok(!ret, "IDirect3DDevice9_ShowCursor returned %d\n", ret);
1923 /* Enabled now*/
1924 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
1925 ok(ret, "IDirect3DDevice9_ShowCursor returned %d\n", ret);
1927 memset(&info, 0, sizeof(info));
1928 info.cbSize = sizeof(info);
1929 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1930 ok(info.flags & (CURSOR_SHOWING | CURSOR_SUPPRESSED), "Got cursor flags %#lx.\n", info.flags);
1931 ok(info.hCursor != cur || broken(1), "The cursor handle is %p\n", info.hCursor);
1933 /* Cursor dimensions must all be powers of two */
1934 for (test_idx = 0; test_idx < ARRAY_SIZE(cursor_sizes); ++test_idx)
1936 width = cursor_sizes[test_idx].cx;
1937 height = cursor_sizes[test_idx].cy;
1938 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, D3DFMT_A8R8G8B8,
1939 D3DPOOL_DEFAULT, &cursor, NULL);
1940 ok(hr == D3D_OK, "Test %u: CreateOffscreenPlainSurface failed, hr %#lx.\n", test_idx, hr);
1941 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
1942 if (width && !(width & (width - 1)) && height && !(height & (height - 1)))
1943 expected_hr = D3D_OK;
1944 else
1945 expected_hr = D3DERR_INVALIDCALL;
1946 ok(hr == expected_hr, "Test %u: Expect SetCursorProperties return %#lx, got %#lx.\n",
1947 test_idx, expected_hr, hr);
1948 IDirect3DSurface9_Release(cursor);
1951 refcount = IDirect3DDevice9_Release(device);
1952 ok(!refcount, "Device has %lu references left.\n", refcount);
1954 /* Cursor dimensions must not exceed adapter display mode */
1955 device_desc.device_window = window;
1956 device_desc.width = 640;
1957 device_desc.height = 480;
1959 adapter_count = IDirect3D9_GetAdapterCount(d3d);
1960 for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx)
1962 for (test_idx = 0; test_idx < ARRAY_SIZE(device_flags); ++test_idx)
1964 device_desc.adapter_ordinal = adapter_idx;
1965 device_desc.flags = device_flags[test_idx];
1966 if (!(device = create_device(d3d, window, &device_desc)))
1968 skip("Adapter %u test %u: Failed to create a D3D device.\n", adapter_idx, test_idx);
1969 break;
1972 hr = IDirect3D9_GetAdapterDisplayMode(d3d, adapter_idx, &mode);
1973 ok(hr == D3D_OK, "Adapter %u test %u: GetAdapterDisplayMode failed, hr %#lx.\n",
1974 adapter_idx, test_idx, hr);
1976 /* Find the largest width and height that are powers of two and less than the display mode */
1977 width = 1;
1978 height = 1;
1979 while (width * 2 <= mode.Width)
1980 width *= 2;
1981 while (height * 2 <= mode.Height)
1982 height *= 2;
1984 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height,
1985 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &cursor, NULL);
1986 ok(hr == D3D_OK, "Adapter %u test %u: CreateOffscreenPlainSurface failed, hr %#lx.\n",
1987 adapter_idx, test_idx, hr);
1988 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
1989 ok(hr == D3D_OK, "Adapter %u test %u: SetCursorProperties failed, hr %#lx.\n",
1990 adapter_idx, test_idx, hr);
1991 IDirect3DSurface9_Release(cursor);
1993 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width * 2, height,
1994 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &cursor, NULL);
1995 ok(hr == D3D_OK, "Adapter %u test %u: CreateOffscreenPlainSurface failed, hr %#lx.\n",
1996 adapter_idx, test_idx, hr);
1997 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
1998 ok(hr == D3DERR_INVALIDCALL, "Adapter %u test %u: Got hr %#lx.\n", adapter_idx, test_idx, hr);
1999 IDirect3DSurface9_Release(cursor);
2001 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height * 2,
2002 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &cursor, NULL);
2003 ok(hr == D3D_OK, "Adapter %u test %u: CreateOffscreenPlainSurface failed, hr %#lx.\n",
2004 adapter_idx, test_idx, hr);
2005 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
2006 ok(hr == D3DERR_INVALIDCALL, "Adapter %u test %u: Got hr %#lx.\n", adapter_idx, test_idx, hr);
2007 IDirect3DSurface9_Release(cursor);
2009 refcount = IDirect3DDevice9_Release(device);
2010 ok(!refcount, "Adapter %u: Device has %lu references left.\n", adapter_idx, refcount);
2013 cleanup:
2014 IDirect3D9_Release(d3d);
2015 DestroyWindow(window);
2018 static void test_reset(void)
2020 HRESULT hr;
2021 RECT winrect, client_rect;
2022 D3DPRESENT_PARAMETERS d3dpp;
2023 D3DDISPLAYMODE d3ddm, d3ddm2;
2024 D3DVIEWPORT9 vp;
2025 IDirect3DSurface9 *surface;
2026 IDirect3DTexture9 *texture;
2027 IDirect3DVertexShader9 *shader;
2028 D3DLOCKED_RECT lockrect;
2029 const DWORD orig_width = GetSystemMetrics(SM_CXSCREEN), orig_height = GetSystemMetrics(SM_CYSCREEN);
2030 unsigned int mode_count = 0, adapter_mode_count, width, height, i;
2031 IDirect3DDevice9 *device1 = NULL;
2032 IDirect3DDevice9 *device2 = NULL;
2033 IDirect3DSwapChain9 *swapchain;
2034 struct device_desc device_desc;
2035 IDirect3DVertexBuffer9 *vb;
2036 IDirect3DIndexBuffer9 *ib;
2037 DEVMODEW devmode;
2038 IDirect3D9 *d3d;
2039 D3DCAPS9 caps;
2040 DWORD value;
2041 HWND hwnd;
2042 LONG ret;
2043 struct
2045 UINT w;
2046 UINT h;
2047 } *modes = NULL;
2049 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2050 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2051 ok(!!hwnd, "Failed to create a window.\n");
2052 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2053 ok(!!d3d, "Failed to create a D3D object.\n");
2055 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2056 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, d3ddm.Format);
2057 modes = malloc(sizeof(*modes) * adapter_mode_count);
2058 for(i = 0; i < adapter_mode_count; ++i)
2060 UINT j;
2061 ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
2062 hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
2063 ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#lx\n", hr);
2065 for (j = 0; j < mode_count; ++j)
2067 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
2068 break;
2070 if (j == mode_count)
2072 modes[j].w = d3ddm2.Width;
2073 modes[j].h = d3ddm2.Height;
2074 ++mode_count;
2077 /* We use them as invalid modes */
2078 if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
2079 (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
2080 skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
2081 d3ddm2.Width, d3ddm2.Height);
2082 goto cleanup;
2086 if (mode_count < 2)
2088 skip("Less than 2 modes supported, skipping mode tests\n");
2089 goto cleanup;
2092 i = 0;
2093 if (modes[i].w == orig_width && modes[i].h == orig_height) ++i;
2095 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
2096 device_desc.width = modes[i].w;
2097 device_desc.height = modes[i].h;
2098 device_desc.device_window = hwnd;
2099 device_desc.flags = CREATE_DEVICE_FULLSCREEN | CREATE_DEVICE_SWVP_ONLY;
2100 if (!(device1 = create_device(d3d, hwnd, &device_desc)))
2102 skip("Failed to create a D3D device, skipping tests.\n");
2103 goto cleanup;
2105 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2106 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#lx\n", hr);
2108 hr = IDirect3DDevice9_GetDeviceCaps(device1, &caps);
2109 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
2111 width = GetSystemMetrics(SM_CXSCREEN);
2112 height = GetSystemMetrics(SM_CYSCREEN);
2113 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
2114 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
2116 hr = IDirect3DDevice9_GetViewport(device1, &vp);
2117 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2118 ok(vp.X == 0, "D3DVIEWPORT->X = %ld\n", vp.X);
2119 ok(vp.Y == 0, "D3DVIEWPORT->Y = %ld\n", vp.Y);
2120 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %lu, expected %u\n", vp.Width, modes[i].w);
2121 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %lu, expected %u\n", vp.Height, modes[i].h);
2122 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
2123 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
2125 i = 1;
2126 vp.X = 10;
2127 vp.Y = 20;
2128 vp.MinZ = 2;
2129 vp.MaxZ = 3;
2130 hr = IDirect3DDevice9_SetViewport(device1, &vp);
2131 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2133 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
2134 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
2135 ok(!!value, "Got unexpected value %#lx for D3DRS_LIGHTING.\n", value);
2136 hr = IDirect3DDevice9_SetRenderState(device1, D3DRS_LIGHTING, FALSE);
2137 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2139 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2140 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2141 d3dpp.Windowed = FALSE;
2142 d3dpp.BackBufferWidth = modes[i].w;
2143 d3dpp.BackBufferHeight = modes[i].h;
2144 d3dpp.BackBufferFormat = d3ddm.Format;
2145 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2147 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2150 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
2151 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
2152 ok(!!value, "Got unexpected value %#lx for D3DRS_LIGHTING.\n", value);
2154 ZeroMemory(&vp, sizeof(vp));
2155 hr = IDirect3DDevice9_GetViewport(device1, &vp);
2156 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2157 ok(vp.X == 0, "D3DVIEWPORT->X = %ld\n", vp.X);
2158 ok(vp.Y == 0, "D3DVIEWPORT->Y = %ld\n", vp.Y);
2159 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %lu, expected %u\n", vp.Width, modes[i].w);
2160 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %lu, expected %u\n", vp.Height, modes[i].h);
2161 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
2162 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
2164 width = GetSystemMetrics(SM_CXSCREEN);
2165 height = GetSystemMetrics(SM_CYSCREEN);
2166 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
2167 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
2169 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &swapchain);
2170 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#lx.\n", hr);
2171 memset(&d3dpp, 0, sizeof(d3dpp));
2172 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
2173 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#lx.\n", hr);
2174 ok(d3dpp.BackBufferWidth == modes[i].w, "Got unexpected BackBufferWidth %u, expected %u.\n",
2175 d3dpp.BackBufferWidth, modes[i].w);
2176 ok(d3dpp.BackBufferHeight == modes[i].h, "Got unexpected BackBufferHeight %u, expected %u.\n",
2177 d3dpp.BackBufferHeight, modes[i].h);
2178 IDirect3DSwapChain9_Release(swapchain);
2180 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2181 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2182 d3dpp.Windowed = TRUE;
2183 d3dpp.BackBufferWidth = 400;
2184 d3dpp.BackBufferHeight = 300;
2185 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
2186 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2187 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2188 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2189 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2191 width = GetSystemMetrics(SM_CXSCREEN);
2192 height = GetSystemMetrics(SM_CYSCREEN);
2193 ok(width == orig_width, "Screen width is %d\n", width);
2194 ok(height == orig_height, "Screen height is %d\n", height);
2196 ZeroMemory(&vp, sizeof(vp));
2197 hr = IDirect3DDevice9_GetViewport(device1, &vp);
2198 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2199 ok(vp.X == 0, "D3DVIEWPORT->X = %ld\n", vp.X);
2200 ok(vp.Y == 0, "D3DVIEWPORT->Y = %ld\n", vp.Y);
2201 ok(vp.Width == 400, "D3DVIEWPORT->Width = %ld\n", vp.Width);
2202 ok(vp.Height == 300, "D3DVIEWPORT->Height = %ld\n", vp.Height);
2203 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
2204 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
2206 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &swapchain);
2207 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#lx.\n", hr);
2208 memset(&d3dpp, 0, sizeof(d3dpp));
2209 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
2210 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#lx.\n", hr);
2211 ok(d3dpp.BackBufferWidth == 400, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
2212 ok(d3dpp.BackBufferHeight == 300, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
2213 IDirect3DSwapChain9_Release(swapchain);
2215 memset(&devmode, 0, sizeof(devmode));
2216 devmode.dmSize = sizeof(devmode);
2217 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2218 devmode.dmPelsWidth = modes[1].w;
2219 devmode.dmPelsHeight = modes[1].h;
2220 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2221 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx.\n", ret);
2222 width = GetSystemMetrics(SM_CXSCREEN);
2223 height = GetSystemMetrics(SM_CYSCREEN);
2224 ok(width == modes[1].w, "Screen width is %u, expected %u.\n", width, modes[1].w);
2225 ok(height == modes[1].h, "Screen height is %u, expected %u.\n", height, modes[1].h);
2227 d3dpp.BackBufferWidth = 500;
2228 d3dpp.BackBufferHeight = 400;
2229 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
2230 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2231 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2232 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2233 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2235 width = GetSystemMetrics(SM_CXSCREEN);
2236 height = GetSystemMetrics(SM_CYSCREEN);
2237 ok(width == modes[1].w, "Screen width is %u, expected %u.\n", width, modes[1].w);
2238 ok(height == modes[1].h, "Screen height is %u, expected %u.\n", height, modes[1].h);
2240 ZeroMemory(&vp, sizeof(vp));
2241 hr = IDirect3DDevice9_GetViewport(device1, &vp);
2242 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed, hr %#lx.\n", hr);
2243 ok(vp.X == 0, "D3DVIEWPORT->X = %ld.\n", vp.X);
2244 ok(vp.Y == 0, "D3DVIEWPORT->Y = %ld.\n", vp.Y);
2245 ok(vp.Width == 500, "D3DVIEWPORT->Width = %ld.\n", vp.Width);
2246 ok(vp.Height == 400, "D3DVIEWPORT->Height = %ld.\n", vp.Height);
2247 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f.\n", vp.MinZ);
2248 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f.\n", vp.MaxZ);
2250 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &swapchain);
2251 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#lx.\n", hr);
2252 memset(&d3dpp, 0, sizeof(d3dpp));
2253 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
2254 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#lx.\n", hr);
2255 ok(d3dpp.BackBufferWidth == 500, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
2256 ok(d3dpp.BackBufferHeight == 400, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
2257 IDirect3DSwapChain9_Release(swapchain);
2259 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
2260 devmode.dmPelsWidth = orig_width;
2261 devmode.dmPelsHeight = orig_height;
2262 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
2263 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx.\n", ret);
2264 width = GetSystemMetrics(SM_CXSCREEN);
2265 height = GetSystemMetrics(SM_CYSCREEN);
2266 ok(width == orig_width, "Got screen width %u, expected %lu.\n", width, orig_width);
2267 ok(height == orig_height, "Got screen height %u, expected %lu.\n", height, orig_height);
2269 SetRect(&winrect, 0, 0, 200, 150);
2270 ok(AdjustWindowRect(&winrect, WS_OVERLAPPEDWINDOW, FALSE), "AdjustWindowRect failed\n");
2271 ok(SetWindowPos(hwnd, NULL, 0, 0,
2272 winrect.right-winrect.left,
2273 winrect.bottom-winrect.top,
2274 SWP_NOMOVE|SWP_NOZORDER),
2275 "SetWindowPos failed\n");
2277 /* Windows 10 gives us a different size than we requested with some DPI scaling settings (e.g. 172%). */
2278 GetClientRect(hwnd, &client_rect);
2280 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2281 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2282 d3dpp.Windowed = TRUE;
2283 d3dpp.BackBufferWidth = 0;
2284 d3dpp.BackBufferHeight = 0;
2285 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
2286 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2287 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2288 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2289 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2291 ok(d3dpp.BackBufferWidth == client_rect.right, "Got unexpected BackBufferWidth %u, expected %ld.\n",
2292 d3dpp.BackBufferWidth, client_rect.right);
2293 ok(d3dpp.BackBufferHeight == client_rect.bottom, "Got unexpected BackBufferHeight %u, expected %ld.\n",
2294 d3dpp.BackBufferHeight, client_rect.bottom);
2295 ok(d3dpp.BackBufferFormat == d3ddm.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
2296 d3dpp.BackBufferFormat, d3ddm.Format);
2297 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
2298 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
2299 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %lu.\n", d3dpp.MultiSampleQuality);
2300 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
2301 ok(!d3dpp.hDeviceWindow, "Got unexpected hDeviceWindow %p.\n", d3dpp.hDeviceWindow);
2302 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
2303 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
2304 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
2305 ok(!d3dpp.Flags, "Got unexpected Flags %#lx.\n", d3dpp.Flags);
2306 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
2307 d3dpp.FullScreen_RefreshRateInHz);
2308 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
2310 ZeroMemory(&vp, sizeof(vp));
2311 hr = IDirect3DDevice9_GetViewport(device1, &vp);
2312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2313 ok(vp.X == 0, "D3DVIEWPORT->X = %ld\n", vp.X);
2314 ok(vp.Y == 0, "D3DVIEWPORT->Y = %ld\n", vp.Y);
2315 ok(vp.Width == client_rect.right, "D3DVIEWPORT->Width = %ld, expected %ld\n",
2316 vp.Width, client_rect.right);
2317 ok(vp.Height == client_rect.bottom, "D3DVIEWPORT->Height = %ld, expected %ld\n",
2318 vp.Height, client_rect.bottom);
2319 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
2320 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
2322 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &swapchain);
2323 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#lx.\n", hr);
2324 memset(&d3dpp, 0, sizeof(d3dpp));
2325 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
2326 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#lx.\n", hr);
2327 ok(d3dpp.BackBufferWidth == client_rect.right,
2328 "Got unexpected BackBufferWidth %u, expected %ld.\n", d3dpp.BackBufferWidth, client_rect.right);
2329 ok(d3dpp.BackBufferHeight == client_rect.bottom,
2330 "Got unexpected BackBufferHeight %u, expected %ld.\n", d3dpp.BackBufferHeight, client_rect.bottom);
2331 ok(d3dpp.BackBufferFormat == d3ddm.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
2332 d3dpp.BackBufferFormat, d3ddm.Format);
2333 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
2334 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
2335 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %lu.\n", d3dpp.MultiSampleQuality);
2336 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
2337 ok(d3dpp.hDeviceWindow == hwnd, "Got unexpected hDeviceWindow %p, expected %p.\n", d3dpp.hDeviceWindow, hwnd);
2338 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
2339 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
2340 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
2341 ok(!d3dpp.Flags, "Got unexpected Flags %#lx.\n", d3dpp.Flags);
2342 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
2343 d3dpp.FullScreen_RefreshRateInHz);
2344 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
2345 IDirect3DSwapChain9_Release(swapchain);
2347 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2348 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2349 d3dpp.Windowed = TRUE;
2350 d3dpp.BackBufferWidth = 400;
2351 d3dpp.BackBufferHeight = 300;
2353 /* _Reset fails if there is a resource in the default pool */
2354 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
2355 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2356 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2357 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2358 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2359 ok(hr == D3DERR_DEVICENOTRESET, "Got hr %#lx.\n", hr);
2360 IDirect3DSurface9_Release(surface);
2361 /* Reset again to get the device out of the lost state */
2362 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2363 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2364 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2365 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2367 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
2369 IDirect3DVolumeTexture9 *volume_texture;
2371 hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
2372 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
2373 ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#lx.\n", hr);
2374 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2375 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2376 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2377 ok(hr == D3DERR_DEVICENOTRESET, "Got hr %#lx.\n", hr);
2378 IDirect3DVolumeTexture9_Release(volume_texture);
2379 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2380 ok(SUCCEEDED(hr), "Reset failed, hr %#lx.\n", hr);
2381 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2382 ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#lx.\n", hr);
2384 else
2386 skip("Volume textures not supported.\n");
2389 /* Scratch, sysmem and managed pools are fine */
2390 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
2391 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2392 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2393 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2394 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2396 IDirect3DSurface9_Release(surface);
2398 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
2399 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
2400 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2401 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2402 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2403 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2405 IDirect3DSurface9_Release(surface);
2407 hr = IDirect3DDevice9_CreateVertexBuffer(device1, 16, 0,
2408 D3DFVF_XYZ, D3DPOOL_SYSTEMMEM, &vb, NULL);
2409 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#lx.\n", hr);
2410 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2411 ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr);
2412 IDirect3DVertexBuffer9_Release(vb);
2414 hr = IDirect3DDevice9_CreateIndexBuffer(device1, 16, 0,
2415 D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &ib, NULL);
2416 ok(hr == D3D_OK, "Failed to create index buffer, hr %#lx.\n", hr);
2417 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2418 ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr);
2419 IDirect3DIndexBuffer9_Release(ib);
2421 /* The depth stencil should get reset to the auto depth stencil when present. */
2422 hr = IDirect3DDevice9_SetDepthStencilSurface(device1, NULL);
2423 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2425 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
2426 ok(hr == D3DERR_NOTFOUND, "Got hr %#lx.\n", hr);
2427 ok(surface == NULL, "Depth stencil should be NULL\n");
2429 d3dpp.EnableAutoDepthStencil = TRUE;
2430 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2431 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2432 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2434 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
2435 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2436 ok(surface != NULL, "Depth stencil should not be NULL\n");
2437 if (surface) IDirect3DSurface9_Release(surface);
2439 d3dpp.EnableAutoDepthStencil = FALSE;
2440 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2441 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2443 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
2444 ok(hr == D3DERR_NOTFOUND, "Got hr %#lx.\n", hr);
2445 ok(surface == NULL, "Depth stencil should be NULL\n");
2447 /* Will a sysmem or scratch survive while locked */
2448 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
2449 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
2450 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2451 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
2452 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2453 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2454 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2455 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2457 IDirect3DSurface9_UnlockRect(surface);
2458 IDirect3DSurface9_Release(surface);
2460 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
2461 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2462 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
2463 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2464 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2465 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2466 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2467 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2468 IDirect3DSurface9_UnlockRect(surface);
2469 IDirect3DSurface9_Release(surface);
2471 hr = IDirect3DDevice9_CreateTexture(device1, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
2472 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2473 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2474 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2475 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2476 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2477 IDirect3DTexture9_Release(texture);
2479 /* A reference held to an implicit surface causes failures as well */
2480 hr = IDirect3DDevice9_GetBackBuffer(device1, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
2481 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2482 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2483 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2484 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2485 ok(hr == D3DERR_DEVICENOTRESET, "Got hr %#lx.\n", hr);
2486 IDirect3DSurface9_Release(surface);
2487 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2488 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2489 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2490 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2492 /* Shaders are fine as well */
2493 hr = IDirect3DDevice9_CreateVertexShader(device1, simple_vs, &shader);
2494 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2495 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2496 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2497 IDirect3DVertexShader9_Release(shader);
2499 /* Try setting invalid modes */
2500 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2501 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2502 d3dpp.Windowed = FALSE;
2503 d3dpp.BackBufferWidth = 32;
2504 d3dpp.BackBufferHeight = 32;
2505 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2506 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2507 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2508 ok(hr == D3DERR_DEVICENOTRESET, "Got hr %#lx.\n", hr);
2510 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2511 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2512 d3dpp.Windowed = FALSE;
2513 d3dpp.BackBufferWidth = 801;
2514 d3dpp.BackBufferHeight = 600;
2515 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2516 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2517 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2518 ok(hr == D3DERR_DEVICENOTRESET, "Got hr %#lx.\n", hr);
2520 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2521 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2522 d3dpp.Windowed = FALSE;
2523 d3dpp.BackBufferWidth = 0;
2524 d3dpp.BackBufferHeight = 0;
2525 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2526 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2527 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2528 ok(hr == D3DERR_DEVICENOTRESET, "Got hr %#lx.\n", hr);
2530 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2532 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2533 d3dpp.Windowed = TRUE;
2534 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2535 d3dpp.BackBufferFormat = d3ddm.Format;
2536 d3dpp.EnableAutoDepthStencil = FALSE;
2537 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2539 if (FAILED(hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2540 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2)))
2542 skip("Failed to create device, hr %#lx.\n", hr);
2543 goto cleanup;
2546 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
2547 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2549 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2550 d3dpp.Windowed = TRUE;
2551 d3dpp.BackBufferWidth = 400;
2552 d3dpp.BackBufferHeight = 300;
2553 d3dpp.EnableAutoDepthStencil = TRUE;
2554 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2556 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
2557 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2559 if (FAILED(hr)) goto cleanup;
2561 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
2562 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2563 ok(surface != NULL, "Depth stencil should not be NULL\n");
2564 if (surface) IDirect3DSurface9_Release(surface);
2566 cleanup:
2567 free(modes);
2568 if (device2)
2570 ULONG refcount = IDirect3DDevice9_Release(device2);
2571 ok(!refcount, "Device has %lu references left.\n", refcount);
2573 if (device1)
2575 ULONG refcount = IDirect3DDevice9_Release(device1);
2576 ok(!refcount, "Device has %lu references left.\n", refcount);
2578 IDirect3D9_Release(d3d);
2579 DestroyWindow(hwnd);
2582 /* Test adapter display modes */
2583 static void test_display_modes(void)
2585 D3DDISPLAYMODE dmode;
2586 IDirect3D9 *d3d;
2588 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2589 ok(!!d3d, "Failed to create a D3D object.\n");
2591 #define TEST_FMT(x,r) do { \
2592 HRESULT res = IDirect3D9_EnumAdapterModes(d3d, 0, (x), 0, &dmode); \
2593 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08lx)!\n", res); \
2594 } while(0)
2596 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
2597 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
2598 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2599 /* D3DFMT_R5G6B5 */
2600 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
2601 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
2602 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
2603 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
2604 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
2605 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
2606 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
2607 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
2608 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
2609 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2610 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
2611 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
2613 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
2614 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
2616 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
2617 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
2618 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
2620 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
2621 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
2622 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
2623 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
2624 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
2625 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
2627 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
2628 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
2629 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
2630 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
2631 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
2632 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
2633 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
2634 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
2635 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
2636 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
2638 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
2639 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
2640 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
2641 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
2642 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
2643 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
2644 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
2645 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
2646 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
2647 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
2649 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
2650 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
2651 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
2652 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
2653 /* Floating point formats */
2654 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
2655 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
2656 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
2658 /* IEEE formats */
2659 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
2660 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
2661 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
2663 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
2665 TEST_FMT(0, D3DERR_INVALIDCALL);
2667 IDirect3D9_Release(d3d);
2670 static void test_scene(void)
2672 IDirect3DSurface9 *surface1, *surface2, *surface3;
2673 IDirect3DSurface9 *backBuffer, *rt, *ds;
2674 RECT rect = {0, 0, 128, 128};
2675 IDirect3DDevice9 *device;
2676 IDirect3D9 *d3d;
2677 ULONG refcount;
2678 D3DCAPS9 caps;
2679 HWND window;
2680 HRESULT hr;
2682 window = create_window();
2683 ok(!!window, "Failed to create a window.\n");
2684 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2685 ok(!!d3d, "Failed to create a D3D object.\n");
2686 if (!(device = create_device(d3d, window, NULL)))
2688 skip("Failed to create a 3D device, skipping test.\n");
2689 goto cleanup;
2692 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
2693 memset(&caps, 0, sizeof(caps));
2694 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2695 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2697 /* Test an EndScene without BeginScene. Should return an error */
2698 hr = IDirect3DDevice9_EndScene(device);
2699 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2701 /* Test a normal BeginScene / EndScene pair, this should work */
2702 hr = IDirect3DDevice9_BeginScene(device);
2703 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2704 hr = IDirect3DDevice9_EndScene(device);
2705 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2707 /* Test another EndScene without having begun a new scene. Should return an error */
2708 hr = IDirect3DDevice9_EndScene(device);
2709 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2711 /* Two nested BeginScene and EndScene calls */
2712 hr = IDirect3DDevice9_BeginScene(device);
2713 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2714 hr = IDirect3DDevice9_BeginScene(device);
2715 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2716 hr = IDirect3DDevice9_EndScene(device);
2717 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2718 hr = IDirect3DDevice9_EndScene(device);
2719 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2721 /* Create some surfaces to test stretchrect between the scenes */
2722 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2723 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface1, NULL);
2724 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2725 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2726 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface2, NULL);
2727 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2728 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 800, 600,
2729 D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &surface3, NULL);
2730 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2731 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
2732 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
2733 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2735 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
2736 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2737 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
2738 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2740 /* First make sure a simple StretchRect call works */
2741 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2742 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2743 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2744 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2745 if (0) /* Disabled for now because it crashes in wine */
2747 HRESULT expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
2748 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2749 ok(hr == expected, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected);
2752 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a
2753 * BeginScene - Endscene pair with normal surfaces and render targets, but
2754 * not depth stencil surfaces. */
2755 hr = IDirect3DDevice9_BeginScene(device);
2756 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2758 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2760 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2761 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2762 /* This is supposed to fail inside a BeginScene - EndScene pair. */
2763 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2764 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2766 hr = IDirect3DDevice9_EndScene(device);
2767 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2769 /* Does a SetRenderTarget influence BeginScene / EndScene ?
2770 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
2771 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
2773 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
2774 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2775 hr = IDirect3DDevice9_BeginScene(device);
2776 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2777 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backBuffer);
2778 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2779 hr = IDirect3DDevice9_EndScene(device);
2780 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2782 IDirect3DSurface9_Release(rt);
2783 IDirect3DSurface9_Release(ds);
2784 IDirect3DSurface9_Release(backBuffer);
2785 IDirect3DSurface9_Release(surface1);
2786 IDirect3DSurface9_Release(surface2);
2787 IDirect3DSurface9_Release(surface3);
2788 refcount = IDirect3DDevice9_Release(device);
2789 ok(!refcount, "Device has %lu references left.\n", refcount);
2790 cleanup:
2791 IDirect3D9_Release(d3d);
2792 DestroyWindow(window);
2795 static void test_limits(void)
2797 IDirect3DTexture9 *texture;
2798 IDirect3DDevice9 *device;
2799 IDirect3D9 *d3d;
2800 unsigned int i;
2801 ULONG refcount;
2802 HWND window;
2803 HRESULT hr;
2805 window = create_window();
2806 ok(!!window, "Failed to create a window.\n");
2807 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2808 ok(!!d3d, "Failed to create a D3D object.\n");
2809 if (!(device = create_device(d3d, window, NULL)))
2811 skip("Failed to create a 3D device, skipping test.\n");
2812 goto cleanup;
2815 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
2816 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2818 /* There are 16 pixel samplers. We should be able to access all of them */
2819 for (i = 0; i < 16; ++i)
2821 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture);
2822 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2823 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2824 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2825 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_SRGBTEXTURE, TRUE);
2826 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2829 /* Now test all 8 textures stage states */
2830 for (i = 0; i < 8; ++i)
2832 hr = IDirect3DDevice9_SetTextureStageState(device, i, D3DTSS_COLOROP, D3DTOP_ADD);
2833 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2836 /* Investigations show that accessing higher samplers / textures stage
2837 * states does not return an error either. Writing to too high samplers
2838 * (approximately sampler 40) causes memory corruption in Windows, so
2839 * there is no bounds checking. */
2840 IDirect3DTexture9_Release(texture);
2841 refcount = IDirect3D9_Release(device);
2842 ok(!refcount, "Device has %lu references left.\n", refcount);
2843 cleanup:
2844 IDirect3D9_Release(d3d);
2845 DestroyWindow(window);
2848 static void test_depthstenciltest(void)
2850 HRESULT hr;
2851 IDirect3DDevice9 *pDevice = NULL;
2852 D3DPRESENT_PARAMETERS d3dpp;
2853 D3DDISPLAYMODE d3ddm;
2854 IDirect3DSurface9 *pDepthStencil = NULL;
2855 IDirect3DSurface9 *pDepthStencil2 = NULL;
2856 IDirect3D9 *d3d;
2857 DWORD state;
2858 HWND hwnd;
2860 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2861 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2862 ok(!!hwnd, "Failed to create a window.\n");
2863 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2864 ok(!!d3d, "Failed to create a D3D object.\n");
2866 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2867 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2868 d3dpp.Windowed = TRUE;
2869 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2870 d3dpp.BackBufferWidth = 800;
2871 d3dpp.BackBufferHeight = 600;
2872 d3dpp.BackBufferFormat = d3ddm.Format;
2873 d3dpp.EnableAutoDepthStencil = TRUE;
2874 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2876 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2877 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2878 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || broken(hr == D3DERR_INVALIDCALL), "Got hr %#lx.\n", hr);
2879 if(!pDevice)
2881 skip("Failed to create a d3d device\n");
2882 goto cleanup;
2885 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2886 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2887 ok(!!pDepthStencil, "Got surface %p.\n", pDepthStencil);
2889 /* Try to clear */
2890 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2891 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2893 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
2894 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2896 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
2897 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
2898 ok(hr == D3DERR_NOTFOUND, "Got hr %#lx.\n", hr);
2899 ok(!pDepthStencil2, "Got surface %p.\n", pDepthStencil2);
2900 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
2902 /* This left the render states untouched! */
2903 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2904 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2905 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2906 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
2907 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2908 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
2909 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
2910 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2911 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
2912 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
2913 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2914 ok(state == 0xffffffff, "Got state %#lx.\n", state);
2916 /* This is supposed to fail now */
2917 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2918 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2920 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
2921 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2923 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
2924 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2926 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2927 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2928 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2930 /* Now it works again */
2931 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2932 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2934 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2935 IDirect3D9_Release(pDevice);
2937 /* Now see if autodepthstencil disable is honored. First, without a format set */
2938 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2939 d3dpp.Windowed = TRUE;
2940 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2941 d3dpp.BackBufferWidth = 800;
2942 d3dpp.BackBufferHeight = 600;
2943 d3dpp.BackBufferFormat = d3ddm.Format;
2944 d3dpp.EnableAutoDepthStencil = FALSE;
2945 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2947 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2948 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2949 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got hr %#lx.\n", hr);
2950 if(!pDevice)
2952 skip("Failed to create a d3d device\n");
2953 goto cleanup;
2956 pDepthStencil = NULL;
2957 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2958 ok(hr == D3DERR_NOTFOUND, "Got hr %#lx.\n", hr);
2959 ok(!pDepthStencil, "Got surface %p.\n", pDepthStencil);
2960 if(pDepthStencil) {
2961 IDirect3DSurface9_Release(pDepthStencil);
2962 pDepthStencil = NULL;
2965 /* Check the depth test state */
2966 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2967 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2968 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2970 IDirect3D9_Release(pDevice);
2972 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
2973 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2974 d3dpp.Windowed = TRUE;
2975 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2976 d3dpp.BackBufferWidth = 800;
2977 d3dpp.BackBufferHeight = 600;
2978 d3dpp.BackBufferFormat = d3ddm.Format;
2979 d3dpp.EnableAutoDepthStencil = FALSE;
2980 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2982 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2983 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2984 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got hr %#lx.\n", hr);
2985 if(!pDevice)
2987 skip("Failed to create a d3d device\n");
2988 goto cleanup;
2991 pDepthStencil = NULL;
2992 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2993 ok(hr == D3DERR_NOTFOUND, "Got hr %#lx.\n", hr);
2994 ok(!pDepthStencil, "Got surface %p.\n", pDepthStencil);
2995 if(pDepthStencil) {
2996 IDirect3DSurface9_Release(pDepthStencil);
2997 pDepthStencil = NULL;
3000 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
3001 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3002 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
3004 cleanup:
3005 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
3006 if (pDevice)
3008 ULONG refcount = IDirect3D9_Release(pDevice);
3009 ok(!refcount, "Device has %lu references left.\n", refcount);
3011 IDirect3D9_Release(d3d);
3012 DestroyWindow(hwnd);
3015 static void test_get_rt(void)
3017 IDirect3DSurface9 *backbuffer, *rt;
3018 IDirect3DDevice9 *device;
3019 IDirect3D9 *d3d9;
3020 D3DCAPS9 caps;
3021 HWND window;
3022 HRESULT hr;
3023 ULONG ref;
3024 UINT i;
3026 window = create_window();
3027 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3028 ok(!!d3d9, "Failed to create a D3D object.\n");
3029 device = create_device(d3d9, window, NULL);
3030 if (!device)
3032 skip("Failed to create a D3D device, skipping tests.\n");
3033 goto done;
3036 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
3037 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
3038 ok(!!backbuffer, "Got a NULL backbuffer.\n");
3040 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3041 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
3043 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
3045 rt = backbuffer;
3046 hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
3047 ok(hr == D3DERR_NOTFOUND, "Got hr %#lx.\n", hr);
3048 ok(!rt, "Got rt %p.\n", rt);
3051 IDirect3DSurface9_Release(backbuffer);
3053 ref = IDirect3DDevice9_Release(device);
3054 ok(!ref, "Unexpected refcount %lu.\n", ref);
3055 done:
3056 IDirect3D9_Release(d3d9);
3057 DestroyWindow(window);
3060 static void test_draw_primitive(void)
3062 static const struct
3064 float position[3];
3065 DWORD color;
3067 quad[] =
3069 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
3070 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
3071 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
3072 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
3074 static const WORD indices[] = {0, 1, 2, 3, 0, 2};
3075 static const D3DVERTEXELEMENT9 decl_elements[] =
3077 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3078 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3079 D3DDECL_END()
3082 IDirect3DVertexBuffer9 *vertex_buffer, *current_vb;
3083 IDirect3DIndexBuffer9 *index_buffer, *current_ib;
3084 IDirect3DVertexDeclaration9 *vertex_declaration;
3085 IDirect3DStateBlock9 *stateblock;
3086 IDirect3DDevice9 *device;
3087 UINT offset, stride;
3088 IDirect3D9 *d3d9;
3089 ULONG refcount;
3090 HWND window;
3091 HRESULT hr;
3092 void *ptr;
3094 window = create_window();
3095 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3096 ok(!!d3d9, "Failed to create a D3D object.\n");
3097 if (!(device = create_device(d3d9, window, NULL)))
3099 skip("Failed to create a D3D device.\n");
3100 IDirect3D9_Release(d3d9);
3101 DestroyWindow(window);
3102 return;
3105 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
3106 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#lx.\n", hr);
3108 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
3109 D3DPOOL_DEFAULT, &vertex_buffer, NULL);
3110 ok(SUCCEEDED(hr), "CreateVertexBuffer failed, hr %#lx.\n", hr);
3111 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
3112 ok(SUCCEEDED(hr), "Lock failed, hr %#lx.\n", hr);
3113 memcpy(ptr, quad, sizeof(quad));
3114 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
3115 ok(SUCCEEDED(hr), "Unlock failed, hr %#lx.\n", hr);
3116 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
3117 ok(SUCCEEDED(hr), "SetStreamSource failed, hr %#lx.\n", hr);
3119 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16,
3120 D3DPOOL_DEFAULT, &index_buffer, NULL);
3121 ok(SUCCEEDED(hr), "CreateIndexBuffer failed, hr %#lx.\n", hr);
3122 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
3123 ok(SUCCEEDED(hr), "Lock failed, hr %#lx.\n", hr);
3124 memcpy(ptr, indices, sizeof(indices));
3125 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
3126 ok(SUCCEEDED(hr), "Unlock failed, hr %#lx.\n", hr);
3128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3129 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed, hr %#lx.\n", hr);
3131 hr = IDirect3DDevice9_BeginScene(device);
3132 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3134 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3135 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
3137 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
3138 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3140 hr = IDirect3DDevice9_GetStreamSource(device, 0, &current_vb, &offset, &stride);
3141 ok(SUCCEEDED(hr), "GetStreamSource failed, hr %#lx.\n", hr);
3142 ok(current_vb == vertex_buffer, "Unexpected vb %p.\n", current_vb);
3143 ok(!offset, "Unexpected offset %u.\n", offset);
3144 ok(stride == sizeof(*quad), "Unexpected stride %u.\n", stride);
3145 IDirect3DVertexBuffer9_Release(current_vb);
3147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 2, quad, sizeof(*quad));
3148 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3150 hr = IDirect3DDevice9_GetStreamSource(device, 0, &current_vb, &offset, &stride);
3151 ok(SUCCEEDED(hr), "GetStreamSource failed, hr %#lx.\n", hr);
3152 todo_wine ok(!current_vb, "Unexpected vb %p.\n", current_vb);
3153 ok(!offset, "Unexpected offset %u.\n", offset);
3154 ok(stride == sizeof(*quad), "Unexpected stride %u.\n", stride);
3155 if (current_vb)
3156 IDirect3DVertexBuffer9_Release(current_vb);
3158 hr = IDirect3DDevice9_SetIndices(device, NULL);
3159 ok(SUCCEEDED(hr), "SetIndices failed, hr %#lx.\n", hr);
3160 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */,
3161 0 /* MinIndex */, 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
3162 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3164 /* Valid index buffer, NULL vertex declaration. */
3165 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
3166 ok(SUCCEEDED(hr), "SetIndices failed, hr %#lx.\n", hr);
3167 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */,
3168 0 /* MinIndex */, 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
3169 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3171 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4, 2,
3172 indices, D3DFMT_INDEX16, quad, sizeof(*quad));
3173 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3175 hr = IDirect3DDevice9_GetIndices(device, &current_ib);
3176 ok(SUCCEEDED(hr), "GetIndices failed, hr %#lx.\n", hr);
3177 todo_wine ok(!current_ib, "Unexpected index buffer %p.\n", current_vb);
3178 if (current_ib)
3179 IDirect3DIndexBuffer9_Release(current_ib);
3181 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3182 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
3184 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
3185 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#lx.\n", hr);
3187 /* Crashes on r200, Windows XP with STATUS_INTEGER_DIVIDE_BY_ZERO. */
3188 if (0)
3190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 2, quad, 0);
3191 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3192 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, quad, 0);
3193 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 2, quad, sizeof(*quad));
3197 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3199 hr = IDirect3DDevice9_GetStreamSource(device, 0, &current_vb, &offset, &stride);
3200 ok(SUCCEEDED(hr), "GetStreamSource failed, hr %#lx.\n", hr);
3201 ok(!current_vb, "Unexpected vb %p.\n", current_vb);
3202 ok(!offset, "Unexpected offset %u.\n", offset);
3203 ok(!stride, "Unexpected stride %u.\n", stride);
3205 /* NULL index buffer, valid vertex declaration, NULL stream source. */
3206 hr = IDirect3DDevice9_SetIndices(device, NULL);
3207 ok(SUCCEEDED(hr), "SetIndices failed, hr %#lx.\n", hr);
3208 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */,
3209 0 /* MinIndex */, 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
3210 todo_wine ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed, hr %#lx.\n", hr);
3212 /* Valid index buffer and vertex declaration, NULL stream source. */
3213 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
3214 ok(SUCCEEDED(hr), "SetIndices failed, hr %#lx.\n", hr);
3215 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */,
3216 0 /* MinIndex */, 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
3217 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed, hr %#lx.\n", hr);
3219 hr = IDirect3DDevice9_GetIndices(device, &current_ib);
3220 ok(SUCCEEDED(hr), "GetIndices failed, hr %#lx.\n", hr);
3221 ok(current_ib == index_buffer, "Unexpected index buffer %p.\n", current_ib);
3222 IDirect3DIndexBuffer9_Release(current_ib);
3224 /* Crashes on r200, Windows XP with STATUS_INTEGER_DIVIDE_BY_ZERO. */
3225 if (0)
3227 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4, 2,
3228 indices, D3DFMT_INDEX16, quad, 0);
3229 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3230 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4, 0,
3231 indices, D3DFMT_INDEX16, quad, 0);
3232 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
3235 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4, 2,
3236 indices, D3DFMT_INDEX16, quad, sizeof(*quad));
3237 ok(SUCCEEDED(hr), "DrawIndexedPrimitiveUP failed, hr %#lx.\n", hr);
3239 hr = IDirect3DDevice9_GetIndices(device, &current_ib);
3240 ok(SUCCEEDED(hr), "GetIndices failed, hr %#lx.\n", hr);
3241 ok(!current_ib, "Unexpected index buffer %p.\n", current_ib);
3243 /* Resetting of stream source and index buffer is not recorded in stateblocks. */
3245 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
3246 ok(SUCCEEDED(hr), "SetStreamSource failed, hr %#lx.\n", hr);
3247 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
3248 ok(SUCCEEDED(hr), "SetIndices failed, hr %#lx.\n", hr);
3250 hr = IDirect3DDevice9_BeginStateBlock(device);
3251 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#lx.\n", hr);
3253 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4, 2,
3254 indices, D3DFMT_INDEX16, quad, sizeof(*quad));
3255 ok(SUCCEEDED(hr), "DrawIndexedPrimitiveUP failed, hr %#lx.\n", hr);
3257 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
3258 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#lx.\n", hr);
3260 hr = IDirect3DDevice9_GetStreamSource(device, 0, &current_vb, &offset, &stride);
3261 ok(SUCCEEDED(hr), "GetStreamSource failed, hr %#lx.\n", hr);
3262 ok(!current_vb, "Unexpected vb %p.\n", current_vb);
3263 ok(!offset, "Unexpected offset %u.\n", offset);
3264 ok(!stride, "Unexpected stride %u.\n", stride);
3265 hr = IDirect3DDevice9_GetIndices(device, &current_ib);
3266 ok(SUCCEEDED(hr), "GetIndices failed, hr %#lx.\n", hr);
3267 ok(!current_ib, "Unexpected index buffer %p.\n", current_ib);
3269 hr = IDirect3DStateBlock9_Capture(stateblock);
3270 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
3272 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
3273 ok(SUCCEEDED(hr), "SetStreamSource failed, hr %#lx.\n", hr);
3274 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
3275 ok(SUCCEEDED(hr), "SetIndices failed, hr %#lx.\n", hr);
3277 hr = IDirect3DStateBlock9_Apply(stateblock);
3278 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
3280 hr = IDirect3DDevice9_GetStreamSource(device, 0, &current_vb, &offset, &stride);
3281 ok(SUCCEEDED(hr), "GetStreamSource failed, hr %#lx.\n", hr);
3282 ok(current_vb == vertex_buffer, "Unexpected vb %p.\n", current_vb);
3283 ok(!offset, "Unexpected offset %u.\n", offset);
3284 ok(stride == sizeof(*quad), "Unexpected stride %u.\n", stride);
3285 IDirect3DVertexBuffer9_Release(current_vb);
3286 hr = IDirect3DDevice9_GetIndices(device, &current_ib);
3287 ok(SUCCEEDED(hr), "GetIndices failed, hr %#lx.\n", hr);
3288 ok(current_ib == index_buffer, "Unexpected index buffer %p.\n", current_ib);
3289 IDirect3DIndexBuffer9_Release(current_ib);
3291 hr = IDirect3DDevice9_EndScene(device);
3292 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3294 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3295 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
3297 IDirect3DStateBlock9_Release(stateblock);
3298 IDirect3DVertexBuffer9_Release(vertex_buffer);
3299 IDirect3DIndexBuffer9_Release(index_buffer);
3300 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3301 refcount = IDirect3DDevice9_Release(device);
3302 ok(!refcount, "Device has %lu references left.\n", refcount);
3303 IDirect3D9_Release(d3d9);
3304 DestroyWindow(window);
3307 static void test_null_stream(void)
3309 IDirect3DVertexBuffer9 *buffer = NULL;
3310 IDirect3DDevice9 *device;
3311 IDirect3D9 *d3d9;
3312 ULONG refcount;
3313 HWND window;
3314 HRESULT hr;
3315 IDirect3DVertexShader9 *shader = NULL;
3316 IDirect3DVertexDeclaration9 *decl = NULL;
3317 static const DWORD shader_code[] =
3319 0xfffe0101, /* vs_1_1 */
3320 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3321 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3322 0x0000ffff /* end */
3324 static const D3DVERTEXELEMENT9 decl_elements[] = {
3325 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3326 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3327 D3DDECL_END()
3330 window = create_window();
3331 ok(!!window, "Failed to create a window.\n");
3332 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3333 ok(!!d3d9, "Failed to create a D3D object.\n");
3334 if (!(device = create_device(d3d9, window, NULL)))
3336 skip("Failed to create a 3D device, skipping test.\n");
3337 goto cleanup;
3340 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3341 if(FAILED(hr)) {
3342 skip("No vertex shader support\n");
3343 goto cleanup;
3345 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3346 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3347 if (FAILED(hr)) {
3348 skip("Vertex declaration handling not possible.\n");
3349 goto cleanup;
3351 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
3352 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3353 if (FAILED(hr)) {
3354 skip("Vertex buffer handling not possible.\n");
3355 goto cleanup;
3358 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
3359 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3360 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
3361 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3362 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3363 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3364 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3365 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3367 hr = IDirect3DDevice9_BeginScene(device);
3368 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3369 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
3370 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3371 hr = IDirect3DDevice9_EndScene(device);
3372 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3374 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3375 IDirect3DDevice9_SetVertexShader(device, NULL);
3376 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3378 cleanup:
3379 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
3380 if (decl) IDirect3DVertexDeclaration9_Release(decl);
3381 if (shader) IDirect3DVertexShader9_Release(shader);
3382 if (device)
3384 refcount = IDirect3DDevice9_Release(device);
3385 ok(!refcount, "Device has %lu references left.\n", refcount);
3387 IDirect3D9_Release(d3d9);
3388 DestroyWindow(window);
3391 static void test_lights(void)
3393 IDirect3DDevice9 *device;
3394 IDirect3D9 *d3d9;
3395 ULONG refcount;
3396 HWND window;
3397 HRESULT hr;
3398 unsigned int i;
3399 BOOL enabled;
3400 D3DCAPS9 caps;
3402 window = create_window();
3403 ok(!!window, "Failed to create a window.\n");
3404 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3405 ok(!!d3d9, "Failed to create a D3D object.\n");
3406 if (!(device = create_device(d3d9, window, NULL)))
3408 skip("Failed to create a 3D device, skipping test.\n");
3409 goto cleanup;
3412 memset(&caps, 0, sizeof(caps));
3413 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3414 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3416 for(i = 1; i <= caps.MaxActiveLights; i++) {
3417 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
3418 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3419 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
3420 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3421 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
3424 /* TODO: Test the rendering results in this situation */
3425 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
3426 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3427 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
3428 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3429 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
3430 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
3431 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3433 for(i = 1; i <= caps.MaxActiveLights; i++) {
3434 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
3435 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3438 refcount = IDirect3DDevice9_Release(device);
3439 ok(!refcount, "Device has %lu references left.\n", refcount);
3440 cleanup:
3441 IDirect3D9_Release(d3d9);
3442 DestroyWindow(window);
3445 static void test_set_stream_source(void)
3447 IDirect3DVertexBuffer9 *vb, *current_vb;
3448 unsigned int offset, stride;
3449 IDirect3DDevice9 *device;
3450 IDirect3D9 *d3d9;
3451 ULONG refcount;
3452 HWND window;
3453 HRESULT hr;
3455 window = create_window();
3456 ok(!!window, "Failed to create a window.\n");
3457 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3458 ok(!!d3d9, "Failed to create a D3D object.\n");
3459 if (!(device = create_device(d3d9, window, NULL)))
3461 skip("Failed to create a 3D device, skipping test.\n");
3462 goto cleanup;
3465 hr = IDirect3DDevice9_CreateVertexBuffer(device, 512, 0, 0, D3DPOOL_DEFAULT, &vb, NULL);
3466 ok(SUCCEEDED(hr), "Failed to create a vertex buffer, hr %#lx.\n", hr);
3468 /* Some cards (GeForce 7400 at least) accept non-aligned offsets, others
3469 * (Radeon 9000 verified) reject them, so accept both results. Wine
3470 * currently rejects this to be able to optimize the vbo conversion, but
3471 * writes a WARN. */
3472 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, 32);
3473 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#lx.\n", hr);
3474 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 1, 32);
3475 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3476 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 2, 32);
3477 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3478 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 3, 32);
3479 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3480 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 4, 32);
3481 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3483 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3484 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3485 hr = IDirect3DDevice9_GetStreamSource(device, 0, &current_vb, &offset, &stride);
3486 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3487 ok(!current_vb, "Got unexpected vb %p.\n", current_vb);
3488 ok(offset == 4, "Got unexpected offset %u.\n", offset);
3489 ok(stride == 32, "Got unexpected stride %u.\n", stride);
3491 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, 0);
3492 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3493 hr = IDirect3DDevice9_GetStreamSource(device, 0, &current_vb, &offset, &stride);
3494 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3495 ok(current_vb == vb, "Got unexpected vb %p.\n", current_vb);
3496 IDirect3DVertexBuffer9_Release(current_vb);
3497 ok(!offset, "Got unexpected offset %u.\n", offset);
3498 ok(!stride, "Got unexpected stride %u.\n", stride);
3500 /* Try to set the NULL buffer with an offset and stride 0 */
3501 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3502 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#lx.\n", hr);
3503 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
3504 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3505 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
3506 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3507 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
3508 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
3509 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
3510 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#lx.\n", hr);
3512 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3513 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#lx.\n", hr);
3515 IDirect3DVertexBuffer9_Release(vb);
3516 refcount = IDirect3DDevice9_Release(device);
3517 ok(!refcount, "Device has %lu references left.\n", refcount);
3518 cleanup:
3519 IDirect3D9_Release(d3d9);
3520 DestroyWindow(window);
3523 /* Direct3D9 offers 4 display formats: R5G6B5, X1R5G5B5, X8R8G8B8 and
3524 * A2R10G10B10. Next to these there are 6 different back buffer formats. Only
3525 * a fixed number of combinations are possible in fullscreen mode. In windowed
3526 * mode more combinations are allowed due to format conversion and this is
3527 * likely driver dependent. */
3528 static void test_display_formats(void)
3530 D3DDEVTYPE device_type = D3DDEVTYPE_HAL;
3531 unsigned int backbuffer, display;
3532 unsigned int windowed;
3533 IDirect3D9 *d3d9;
3534 BOOL should_pass;
3535 BOOL has_modes;
3536 HRESULT hr;
3538 static const struct
3540 const char *name;
3541 D3DFORMAT format;
3542 D3DFORMAT alpha_format;
3543 BOOL display;
3544 BOOL windowed;
3546 formats[] =
3548 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, 0, TRUE, TRUE},
3549 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE, TRUE},
3550 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE, FALSE},
3551 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE, TRUE},
3552 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, FALSE},
3553 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, 0, TRUE, FALSE},
3554 {"D3DFMT_UNKNOWN", D3DFMT_UNKNOWN, 0, FALSE, FALSE},
3557 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3558 ok(!!d3d9, "Failed to create a D3D object.\n");
3560 for (display = 0; display < ARRAY_SIZE(formats); ++display)
3562 has_modes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, formats[display].format);
3564 for (windowed = 0; windowed <= 1; ++windowed)
3566 for (backbuffer = 0; backbuffer < ARRAY_SIZE(formats); ++backbuffer)
3568 should_pass = FALSE;
3570 if (formats[display].display && (formats[display].windowed || !windowed) && (has_modes || windowed))
3572 D3DFORMAT backbuffer_format;
3574 if (windowed && formats[backbuffer].format == D3DFMT_UNKNOWN)
3575 backbuffer_format = formats[display].format;
3576 else
3577 backbuffer_format = formats[backbuffer].format;
3579 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, device_type, formats[display].format,
3580 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, backbuffer_format);
3581 if (hr == D3D_OK)
3583 if (windowed)
3585 hr = IDirect3D9_CheckDeviceFormatConversion(d3d9, D3DADAPTER_DEFAULT, device_type,
3586 backbuffer_format, formats[display].format);
3587 should_pass = (hr == D3D_OK);
3589 else
3590 should_pass = (formats[display].format == formats[backbuffer].format
3591 || (formats[display].alpha_format
3592 && formats[display].alpha_format == formats[backbuffer].alpha_format));
3596 hr = IDirect3D9_CheckDeviceType(d3d9, D3DADAPTER_DEFAULT, device_type,
3597 formats[display].format, formats[backbuffer].format, windowed);
3598 ok(SUCCEEDED(hr) == should_pass || broken(SUCCEEDED(hr) && !has_modes) /* Win8 64-bit */,
3599 "Got unexpected hr %#lx for %s / %s, windowed %#x, should_pass %#x.\n",
3600 hr, formats[display].name, formats[backbuffer].name, windowed, should_pass);
3605 IDirect3D9_Release(d3d9);
3608 static void test_scissor_size(void)
3610 struct device_desc device_desc;
3611 IDirect3D9 *d3d9_ptr;
3612 unsigned int i;
3613 static struct {
3614 int winx; int winy; int backx; int backy; DWORD flags;
3615 } scts[] = { /* scissor tests */
3616 {800, 600, 640, 480, 0},
3617 {800, 600, 640, 480, CREATE_DEVICE_FULLSCREEN},
3618 {640, 480, 800, 600, 0},
3619 {640, 480, 800, 600, CREATE_DEVICE_FULLSCREEN},
3622 d3d9_ptr = Direct3DCreate9(D3D_SDK_VERSION);
3623 ok(!!d3d9_ptr, "Failed to create a D3D object.\n");
3625 for (i = 0; i < ARRAY_SIZE(scts); i++)
3627 IDirect3DDevice9 *device_ptr = 0;
3628 RECT scissorrect, expect;
3629 HRESULT hr;
3630 HWND hwnd = 0;
3632 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
3633 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
3635 if (scts[i].flags & CREATE_DEVICE_FULLSCREEN)
3637 scts[i].backx = registry_mode.dmPelsWidth;
3638 scts[i].backy = registry_mode.dmPelsHeight;
3641 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
3642 device_desc.device_window = hwnd;
3643 device_desc.width = scts[i].backx;
3644 device_desc.height = scts[i].backy;
3645 device_desc.flags = scts[i].flags;
3646 if (!(device_ptr = create_device(d3d9_ptr, hwnd, &device_desc)))
3648 skip("Failed to create a 3D device, skipping test.\n");
3649 DestroyWindow(hwnd);
3650 goto err_out;
3653 /* Check for the default scissor rect size */
3654 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
3655 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3656 SetRect(&expect, 0, 0, scts[i].backx, scts[i].backy);
3657 ok(EqualRect(&scissorrect, &expect), "Expected rect %s, got %s.\n",
3658 wine_dbgstr_rect(&expect), wine_dbgstr_rect(&scissorrect));
3660 /* check the scissorrect values after a reset */
3661 device_desc.width = registry_mode.dmPelsWidth;
3662 device_desc.height = registry_mode.dmPelsHeight;
3663 device_desc.flags = scts[i].flags;
3664 hr = reset_device(device_ptr, &device_desc);
3665 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3666 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
3667 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3669 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
3670 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3671 SetRect(&expect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
3672 ok(EqualRect(&scissorrect, &expect), "Expected rect %s, got %s.\n",
3673 wine_dbgstr_rect(&expect), wine_dbgstr_rect(&scissorrect));
3675 if (device_ptr)
3677 ULONG ref;
3679 ref = IDirect3DDevice9_Release(device_ptr);
3680 DestroyWindow(hwnd);
3681 ok(!ref, "Unexpected refcount %lu.\n", ref);
3685 err_out:
3686 IDirect3D9_Release(d3d9_ptr);
3689 static void test_multi_device(void)
3691 IDirect3DDevice9 *device1, *device2;
3692 HWND window1, window2;
3693 IDirect3D9 *d3d9;
3694 ULONG refcount;
3696 window1 = create_window();
3697 ok(!!window1, "Failed to create a window.\n");
3698 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3699 ok(!!d3d9, "Failed to create a D3D object.\n");
3700 if (!(device1 = create_device(d3d9, window1, NULL)))
3702 skip("Failed to create a 3D device, skipping test.\n");
3703 IDirect3D9_Release(d3d9);
3704 DestroyWindow(window1);
3705 return;
3707 IDirect3D9_Release(d3d9);
3709 window2 = create_window();
3710 ok(!!window2, "Failed to create a window.\n");
3711 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3712 ok(!!d3d9, "Failed to create a D3D object.\n");
3713 device2 = create_device(d3d9, window2, NULL);
3714 IDirect3D9_Release(d3d9);
3716 refcount = IDirect3DDevice9_Release(device2);
3717 ok(!refcount, "Device has %lu references left.\n", refcount);
3718 refcount = IDirect3DDevice9_Release(device1);
3719 ok(!refcount, "Device has %lu references left.\n", refcount);
3720 DestroyWindow(window2);
3721 DestroyWindow(window1);
3724 static HWND filter_messages;
3726 enum message_window
3728 DEVICE_WINDOW,
3729 FOCUS_WINDOW,
3732 struct message
3734 UINT message;
3735 enum message_window window;
3736 BOOL check_wparam;
3737 WPARAM expect_wparam;
3738 HRESULT device_state;
3739 WINDOWPOS *store_wp;
3742 static const struct message *expect_messages;
3743 static HWND device_window, focus_window;
3744 static LONG windowposchanged_received, syscommand_received, wm_size_received;
3745 static IDirect3DDevice9 *focus_test_device;
3747 struct wndproc_thread_param
3749 HWND dummy_window;
3750 HANDLE window_created;
3751 HANDLE test_finished;
3752 BOOL running_in_foreground;
3755 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3757 HRESULT hr;
3759 if (filter_messages && filter_messages == hwnd)
3761 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
3762 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
3765 if (expect_messages)
3767 HWND w;
3769 switch (expect_messages->window)
3771 case DEVICE_WINDOW:
3772 w = device_window;
3773 break;
3775 case FOCUS_WINDOW:
3776 w = focus_window;
3777 break;
3779 default:
3780 w = NULL;
3781 break;
3784 if (hwnd == w && expect_messages->message == message)
3786 if (expect_messages->check_wparam)
3787 ok(wparam == expect_messages->expect_wparam,
3788 "Got unexpected wparam %#Ix for message %#x, expected %#Ix.\n",
3789 wparam, message, expect_messages->expect_wparam);
3791 if (expect_messages->store_wp)
3792 *expect_messages->store_wp = *(WINDOWPOS *)lparam;
3794 if (focus_test_device)
3796 hr = IDirect3DDevice9_TestCooperativeLevel(focus_test_device);
3797 /* Wined3d marks the device lost earlier than Windows (it follows ddraw
3798 * behavior. See test_wndproc before the focus_loss_messages sequence
3799 * about the D3DERR_DEVICENOTRESET behavior, */
3800 todo_wine_if(message != WM_ACTIVATEAPP || hr == D3D_OK)
3801 ok(hr == expect_messages->device_state,
3802 "Got device state %#lx on message %#x, expected %#lx.\n",
3803 hr, message, expect_messages->device_state);
3806 ++expect_messages;
3810 /* KDE randomly does something with the hidden window during the
3811 * mode change that sometimes generates a WM_WINDOWPOSCHANGING
3812 * message. A WM_WINDOWPOSCHANGED message is not generated, so
3813 * just flag WM_WINDOWPOSCHANGED as bad. */
3814 if (message == WM_WINDOWPOSCHANGED)
3815 InterlockedIncrement(&windowposchanged_received);
3816 else if (message == WM_SYSCOMMAND)
3817 InterlockedIncrement(&syscommand_received);
3818 else if (message == WM_SIZE)
3819 InterlockedIncrement(&wm_size_received);
3821 return DefWindowProcA(hwnd, message, wparam, lparam);
3824 static DWORD WINAPI wndproc_thread(void *param)
3826 struct wndproc_thread_param *p = param;
3827 DWORD res;
3828 BOOL ret;
3830 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3831 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
3832 registry_mode.dmPelsHeight, 0, 0, 0, 0);
3833 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
3835 ret = SetEvent(p->window_created);
3836 ok(ret, "SetEvent failed, last error %#lx.\n", GetLastError());
3838 for (;;)
3840 MSG msg;
3842 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
3843 res = WaitForSingleObject(p->test_finished, 100);
3844 if (res == WAIT_OBJECT_0) break;
3845 if (res != WAIT_TIMEOUT)
3847 ok(0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
3848 break;
3852 DestroyWindow(p->dummy_window);
3854 return 0;
3857 static void test_wndproc(void)
3859 unsigned int adapter_mode_count, i, d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
3860 struct wndproc_thread_param thread_params;
3861 struct device_desc device_desc;
3862 static WINDOWPOS windowpos;
3863 IDirect3DDevice9 *device;
3864 WNDCLASSA wc = {0};
3865 IDirect3D9 *d3d9;
3866 HANDLE thread;
3867 LONG_PTR proc;
3868 ULONG ref;
3869 DWORD res, tid;
3870 HWND tmp;
3871 HRESULT hr;
3872 D3DDISPLAYMODE d3ddm;
3873 DEVMODEW devmode;
3874 LONG change_ret, device_style;
3875 BOOL ret;
3877 static const struct message create_messages[] =
3879 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
3880 /* Do not test wparam here. If device creation succeeds,
3881 * wparam is WA_ACTIVE. If device creation fails (testbot)
3882 * wparam is set to WA_INACTIVE on some Windows versions. */
3883 {WM_ACTIVATE, FOCUS_WINDOW, FALSE, 0},
3884 {WM_SETFOCUS, FOCUS_WINDOW, FALSE, 0},
3885 {0, 0, FALSE, 0},
3887 static const struct message focus_loss_messages[] =
3889 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
3890 * not reliable on X11 WMs. When the window focus follows the
3891 * mouse pointer the message is not sent.
3892 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
3893 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0, D3DERR_DEVICENOTRESET},
3894 /* WM_DISPLAYCHANGE is sent to the focus window too, but the order is
3895 * not deterministic. */
3896 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0, D3DERR_DEVICENOTRESET},
3897 /* Windows sends WM_ACTIVATE to the device window, indicating that
3898 * SW_SHOWMINIMIZED is used instead of SW_MINIMIZE. Yet afterwards
3899 * the foreground and focus window are NULL. On Wine SW_SHOWMINIMIZED
3900 * leaves the device window active, breaking re-activation in the
3901 * lost device test.
3902 * {WM_ACTIVATE, DEVICE_WINDOW, TRUE, 0x200000 | WA_ACTIVE}, */
3903 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0, D3DERR_DEVICENOTRESET},
3904 {WM_SIZE, DEVICE_WINDOW, TRUE, SIZE_MINIMIZED,
3905 D3DERR_DEVICENOTRESET},
3906 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE, D3DERR_DEVICELOST},
3907 /* WM_ACTIVATEAPP is sent to the device window too, but the order is
3908 * not deterministic. It may be sent after the focus window handling
3909 * or before. */
3910 {0, 0, FALSE, 0, 0},
3912 static const struct message focus_loss_messages_nowc[] =
3914 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
3915 * not reliable on X11 WMs. When the window focus follows the
3916 * mouse pointer the message is not sent.
3917 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
3918 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0, D3DERR_DEVICENOTRESET},
3919 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE, D3DERR_DEVICELOST},
3920 {0, 0, FALSE, 0, 0},
3922 static const struct message reactivate_messages[] =
3924 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
3925 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
3926 /* optional WM_MOVE here if size changed */
3927 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, TRUE},
3928 {0, 0, FALSE, 0},
3930 static const struct message reactivate_messages_nowc[] =
3932 /* We're activating the device window before activating the
3933 * focus window, so no ACTIVATEAPP message is sent. */
3934 {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_ACTIVE},
3935 {0, 0, FALSE, 0},
3937 static const struct message focus_loss_messages_hidden[] =
3939 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
3940 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
3941 {0, 0, FALSE, 0},
3943 static const struct message focus_loss_messages_filtered[] =
3945 /* WM_ACTIVATE is delivered to the window proc because it is
3946 * generated by SetForegroundWindow before the d3d routine
3947 * starts it work. Don't check for it due to focus-follows-mouse
3948 * WMs though. */
3949 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
3950 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
3951 {0, 0, FALSE, 0},
3953 static const struct message reactivate_messages_filtered[] =
3955 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, TRUE},
3956 {0, 0, FALSE, 0},
3958 static const struct message sc_restore_messages[] =
3960 /* WM_SYSCOMMAND is delivered only once, after d3d has already
3961 * processed it. Our wndproc has no way to prevent d3d from
3962 * handling the message. The second DefWindowProc call done by
3963 * our wndproc doesn't do any changes to the window because it
3964 * is already restored due to d3d's handling. */
3965 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
3966 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
3967 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_RESTORED},
3968 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_RESTORE},
3969 {0, 0, FALSE, 0},
3971 static const struct message sc_minimize_messages[] =
3973 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MINIMIZE},
3974 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
3975 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
3976 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
3977 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_MINIMIZED},
3978 {0, 0, FALSE, 0},
3980 static const struct message sc_maximize_messages[] =
3982 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MAXIMIZE},
3983 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
3984 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
3985 /* Windows always sends WM_MOVE here.
3987 * In the first case, we are maximizing from a minimized state, and
3988 * hence the client rect moves from the minimized position to (0, 0).
3990 * In the second case, we are maximizing from an on-screen restored
3991 * state. The window is at (0, 0), but it has a caption, so the client
3992 * rect is offset, and the *client* will move to (0, 0) when maximized.
3994 * Wine doesn't send WM_MOVE here because it messes with the window
3995 * styles when switching to fullscreen, and hence the client rect is
3996 * already at (0, 0). Obviously Wine shouldn't do this, but it's hard to
3997 * fix, and the WM_MOVE is not particularly interesting, so just ignore
3998 * it. */
3999 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_MAXIMIZED},
4000 {0, 0, FALSE, 0},
4002 static const struct message mode_change_messages[] =
4004 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
4005 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
4006 {WM_SIZE, DEVICE_WINDOW, FALSE, 0},
4007 /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is
4008 * differs between Wine and Windows. */
4009 /* TODO 2: Windows sends a second WM_WINDOWPOSCHANGING(SWP_NOMOVE | SWP_NOSIZE
4010 * | SWP_NOACTIVATE) in this situation, suggesting a difference in their ShowWindow
4011 * implementation. This SetWindowPos call could in theory affect the Z order. Wine's
4012 * ShowWindow does not send such a message because the window is already visible. */
4013 {0, 0, FALSE, 0},
4015 static const struct message mode_change_messages_hidden[] =
4017 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
4018 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
4019 {WM_SIZE, DEVICE_WINDOW, FALSE, 0},
4020 {WM_SHOWWINDOW, DEVICE_WINDOW, FALSE, 0},
4021 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0, ~0U, &windowpos},
4022 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
4023 /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is
4024 * differs between Wine and Windows. */
4025 {0, 0, FALSE, 0},
4027 static const struct message mode_change_messages_nowc[] =
4029 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
4030 {0, 0, FALSE, 0},
4032 static const struct
4034 DWORD create_flags;
4035 const struct message *focus_loss_messages, *reactivate_messages;
4036 const struct message *mode_change_messages, *mode_change_messages_hidden;
4037 BOOL iconic;
4039 tests[] =
4043 focus_loss_messages,
4044 reactivate_messages,
4045 mode_change_messages,
4046 mode_change_messages_hidden,
4047 TRUE
4050 CREATE_DEVICE_NOWINDOWCHANGES,
4051 focus_loss_messages_nowc,
4052 reactivate_messages_nowc,
4053 mode_change_messages_nowc,
4054 mode_change_messages_nowc,
4055 FALSE
4059 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4060 ok(!!d3d9, "Failed to create a D3D object.\n");
4062 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
4063 for (i = 0; i < adapter_mode_count; ++i)
4065 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3ddm);
4066 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#lx.\n", hr);
4068 if (d3ddm.Width == registry_mode.dmPelsWidth && d3ddm.Height == registry_mode.dmPelsHeight)
4069 continue;
4070 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
4071 * refuses to create a device at these sizes. */
4072 if (d3ddm.Width < 640 || d3ddm.Height < 480)
4073 continue;
4075 if (!user32_width)
4077 user32_width = d3ddm.Width;
4078 user32_height = d3ddm.Height;
4079 continue;
4082 /* Make sure the d3d mode is smaller in width or height and at most
4083 * equal in the other dimension than the mode passed to
4084 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
4085 * the ChangeDisplaySettings parameters + 12. */
4086 if (d3ddm.Width == user32_width && d3ddm.Height == user32_height)
4087 continue;
4088 if (d3ddm.Width <= user32_width && d3ddm.Height <= user32_height)
4090 d3d_width = d3ddm.Width;
4091 d3d_height = d3ddm.Height;
4092 break;
4094 if (user32_width <= d3ddm.Width && user32_height <= d3ddm.Height)
4096 d3d_width = user32_width;
4097 d3d_height = user32_height;
4098 user32_width = d3ddm.Width;
4099 user32_height = d3ddm.Height;
4100 break;
4104 if (!d3d_width)
4106 skip("Could not find adequate modes, skipping mode tests.\n");
4107 IDirect3D9_Release(d3d9);
4108 return;
4111 filter_messages = NULL;
4112 expect_messages = NULL;
4114 wc.lpfnWndProc = test_proc;
4115 wc.lpszClassName = "d3d9_test_wndproc_wc";
4116 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4118 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
4119 ok(!!thread_params.window_created, "CreateEvent failed, last error %#lx.\n", GetLastError());
4120 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
4121 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#lx.\n", GetLastError());
4123 memset(&devmode, 0, sizeof(devmode));
4124 devmode.dmSize = sizeof(devmode);
4125 for (i = 0; i < ARRAY_SIZE(tests); ++i)
4127 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
4128 devmode.dmPelsWidth = user32_width;
4129 devmode.dmPelsHeight = user32_height;
4130 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
4131 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx.\n", change_ret);
4133 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
4134 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
4135 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
4136 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
4137 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
4138 ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
4140 res = WaitForSingleObject(thread_params.window_created, INFINITE);
4141 ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
4143 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4144 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4145 (LONG_PTR)test_proc, proc);
4146 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4147 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4148 (LONG_PTR)test_proc, proc);
4150 trace("device_window %p, focus_window %p, dummy_window %p.\n",
4151 device_window, focus_window, thread_params.dummy_window);
4153 tmp = GetFocus();
4154 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
4155 if (thread_params.running_in_foreground)
4157 tmp = GetForegroundWindow();
4158 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
4159 thread_params.dummy_window, tmp);
4161 else
4162 skip("Not running in foreground, skip foreground window test\n");
4164 flush_events();
4166 expect_messages = create_messages;
4168 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
4169 device_desc.device_window = device_window;
4170 device_desc.width = d3d_width;
4171 device_desc.height = d3d_height;
4172 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].create_flags;
4173 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4175 skip("Failed to create a D3D device, skipping tests.\n");
4176 goto done;
4179 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4180 expect_messages->message, expect_messages->window, i);
4181 expect_messages = NULL;
4183 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
4185 tmp = GetFocus();
4186 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
4187 tmp = GetForegroundWindow();
4188 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
4190 SetForegroundWindow(focus_window);
4191 flush_events();
4193 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4194 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix, i=%u.\n",
4195 (LONG_PTR)test_proc, proc, i);
4197 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4198 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#Ix, i=%u.\n",
4199 (LONG_PTR)test_proc, i);
4201 /* Change the mode while the device is in use and then drop focus. */
4202 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
4203 devmode.dmPelsWidth = user32_width;
4204 devmode.dmPelsHeight = user32_height;
4205 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
4206 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx, i=%u.\n", change_ret, i);
4208 /* Wine doesn't (yet) mark the device not reset when the mode is changed, thus the todo_wine.
4209 * But sometimes focus-follows-mouse WMs also temporarily drop window focus, which makes
4210 * mark the device lost, then not reset, causing the test to succeed for the wrong reason. */
4211 hr = IDirect3DDevice9_TestCooperativeLevel(device);
4212 todo_wine_if (hr != D3DERR_DEVICENOTRESET)
4213 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#lx.\n", hr);
4215 focus_test_device = device;
4216 expect_messages = tests[i].focus_loss_messages;
4217 /* SetForegroundWindow is a poor replacement for the user pressing alt-tab or
4218 * manually changing the focus. It generates the same messages, but the task
4219 * bar still shows the previous foreground window as active, and the window has
4220 * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating
4221 * the device is difficult, see below. */
4222 SetForegroundWindow(GetDesktopWindow());
4223 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4224 expect_messages->message, expect_messages->window, i);
4225 expect_messages = NULL;
4226 tmp = GetFocus();
4227 ok(tmp != device_window, "The device window is active, i=%u.\n", i);
4228 ok(tmp != focus_window, "The focus window is active, i=%u.\n", i);
4229 focus_test_device = NULL;
4231 hr = IDirect3DDevice9_TestCooperativeLevel(device);
4232 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#lx.\n", hr);
4234 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
4235 ok(ret, "Failed to get display mode.\n");
4236 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
4237 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpected screen size %lux%lu.\n",
4238 devmode.dmPelsWidth, devmode.dmPelsHeight);
4240 /* This is needed on native with D3DCREATE_NOWINDOWCHANGES, and it needs to be
4241 * done before the focus window is restored. This makes sense to some extent
4242 * because minimizing the window on focus loss is the application's job if this
4243 * flag is set. */
4244 if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
4246 ShowWindow(device_window, SW_MINIMIZE);
4247 ShowWindow(device_window, SW_RESTORE);
4249 flush_events();
4251 /* I have to minimize and restore the focus window, otherwise native d3d9 fails
4252 * device::reset with D3DERR_DEVICELOST. This does not happen when the window
4253 * restore is triggered by the user.
4255 * fvwm randomly sends a focus loss notification when we minimize, so do it
4256 * before checking the incoming messages. It might match WM_ACTIVATEAPP but has
4257 * a wrong WPARAM. Use SW_SHOWMINNOACTIVE to make sure we don't accidentally
4258 * activate the window at this point and miss our WM_ACTIVATEAPP(wparam=1). */
4259 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
4260 flush_events();
4261 expect_messages = tests[i].reactivate_messages;
4262 ShowWindow(focus_window, SW_RESTORE);
4263 /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
4264 SetForegroundWindow(focus_window);
4265 flush_events();
4266 SetForegroundWindow(focus_window);
4267 flush_events(); /* WM_WINDOWPOSCHANGING etc arrive after SetForegroundWindow returns. */
4268 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4269 expect_messages->message, expect_messages->window, i);
4270 expect_messages = NULL;
4272 hr = IDirect3DDevice9_TestCooperativeLevel(device);
4273 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#lx.\n", hr);
4275 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
4276 ok(ret, "Failed to get display mode.\n");
4277 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
4278 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpected screen size %lux%lu.\n",
4279 devmode.dmPelsWidth, devmode.dmPelsHeight);
4281 hr = reset_device(device, &device_desc);
4282 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4284 /* Remove the WS_VISIBLE flag to test hidden windows. This is enough to trigger d3d's hidden
4285 * window codepath, but does not actually hide the window without a SetWindowPos(SWP_FRAMECHANGED)
4286 * call. This way we avoid focus changes and random failures on focus follows mouse WMs. */
4287 device_style = GetWindowLongA(device_window, GWL_STYLE);
4288 SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE);
4289 flush_events();
4291 expect_messages = focus_loss_messages_hidden;
4292 windowposchanged_received = 0;
4293 SetForegroundWindow(GetDesktopWindow());
4294 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4295 expect_messages->message, expect_messages->window, i);
4296 flaky
4297 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it.\n");
4298 expect_messages = NULL;
4299 flush_events();
4301 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
4302 ok(ret, "Failed to get display mode.\n");
4303 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth, "Got unexpected width %lu.\n", devmode.dmPelsWidth);
4304 ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpected height %lu.\n", devmode.dmPelsHeight);
4306 /* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
4307 * send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
4308 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
4309 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
4310 flush_events();
4312 syscommand_received = 0;
4313 expect_messages = sc_restore_messages;
4314 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
4315 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4316 expect_messages->message, expect_messages->window, i);
4317 ok(syscommand_received == 1, "Got %ld WM_SYSCOMMAND messages.\n", syscommand_received);
4318 expect_messages = NULL;
4319 flush_events();
4321 expect_messages = sc_minimize_messages;
4322 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
4323 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4324 expect_messages->message, expect_messages->window, i);
4325 expect_messages = NULL;
4326 flush_events();
4328 expect_messages = sc_maximize_messages;
4329 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
4330 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4331 expect_messages->message, expect_messages->window, i);
4332 expect_messages = NULL;
4333 flush_events();
4335 SetForegroundWindow(GetDesktopWindow());
4336 ShowWindow(device_window, SW_MINIMIZE);
4337 ShowWindow(focus_window, SW_MINIMIZE);
4338 ShowWindow(focus_window, SW_RESTORE);
4339 SetForegroundWindow(focus_window);
4340 flush_events();
4342 /* Releasing a device in lost state breaks follow-up tests on native. */
4343 hr = IDirect3DDevice9_TestCooperativeLevel(device);
4344 if (hr == D3DERR_DEVICENOTRESET)
4346 hr = reset_device(device, &device_desc);
4347 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx, i=%u.\n", hr, i);
4350 filter_messages = focus_window;
4352 ref = IDirect3DDevice9_Release(device);
4353 ok(!ref, "Unexpected refcount %lu, i=%u.\n", ref, i);
4355 /* Fix up the mode until Wine's device release behavior is fixed. */
4356 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
4357 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx.\n", change_ret);
4359 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4360 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix, i=%u.\n",
4361 (LONG_PTR)test_proc, proc, i);
4363 /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
4364 * on native in the test below. It isn't needed anyways. Creating the third
4365 * device will show it again. */
4366 filter_messages = NULL;
4367 ShowWindow(device_window, SW_HIDE);
4368 /* Remove the maximized state from the SYSCOMMAND test while we're not
4369 * interfering with a device. */
4370 ShowWindow(focus_window, SW_SHOWNORMAL);
4371 filter_messages = focus_window;
4373 device_desc.device_window = focus_window;
4374 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4376 skip("Failed to create a D3D device, skipping tests.\n");
4377 goto done;
4379 filter_messages = NULL;
4380 SetForegroundWindow(focus_window); /* For KDE. */
4382 expect_messages = focus_loss_messages_filtered;
4383 windowposchanged_received = 0;
4384 SetForegroundWindow(GetDesktopWindow());
4385 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4386 expect_messages->message, expect_messages->window, i);
4388 /* kwin and Win8+ sometimes resize hidden windows. */
4389 flaky
4390 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
4392 expect_messages = NULL;
4394 /* The window is iconic even though no message was sent. */
4395 ok(!IsIconic(focus_window) == !tests[i].iconic,
4396 "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
4398 hr = IDirect3DDevice9_TestCooperativeLevel(device);
4399 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#lx.\n", hr);
4401 if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
4402 ShowWindow(focus_window, SW_MINIMIZE);
4404 syscommand_received = 0;
4405 expect_messages = sc_restore_messages;
4406 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
4407 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4408 expect_messages->message, expect_messages->window, i);
4409 ok(syscommand_received == 1, "Got %ld WM_SYSCOMMAND messages.\n", syscommand_received);
4410 expect_messages = NULL;
4411 flush_events();
4413 /* For FVWM. */
4414 ShowWindow(focus_window, SW_RESTORE);
4415 flush_events();
4417 expect_messages = sc_minimize_messages;
4418 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
4419 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4420 expect_messages->message, expect_messages->window, i);
4421 expect_messages = NULL;
4422 /* Needed to make the next test reliably send WM_SIZE(SIZE_MAXIMIZED). Without
4423 * this call it sends WM_SIZE(SIZE_RESTORED). */
4424 ShowWindow(focus_window, SW_RESTORE);
4425 flush_events();
4427 expect_messages = sc_maximize_messages;
4428 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
4429 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4430 expect_messages->message, expect_messages->window, i);
4431 expect_messages = NULL;
4432 flush_events();
4434 /* Make sure the SetWindowPos call done by d3d9 is not a no-op. */
4435 SetWindowPos(focus_window, NULL, 10, 10, 100, 100, SWP_NOZORDER | SWP_NOACTIVATE);
4436 SetForegroundWindow(GetDesktopWindow());
4437 flush_events();
4438 SetForegroundWindow(GetDesktopWindow()); /* For FVWM. */
4439 flush_events();
4441 expect_messages = reactivate_messages_filtered;
4442 windowposchanged_received = 0;
4443 SetForegroundWindow(focus_window);
4444 flush_events();
4445 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4446 expect_messages->message, expect_messages->window, i);
4447 /* About 1 in 8 test runs receives WM_WINDOWPOSCHANGED on Vista. */
4448 ok(!windowposchanged_received || broken(1),
4449 "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
4450 expect_messages = NULL;
4452 /* On Windows 10 style change messages are delivered both on reset and
4453 * on release. */
4454 hr = IDirect3DDevice9_TestCooperativeLevel(device);
4455 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#lx.\n", hr);
4457 hr = reset_device(device, &device_desc);
4458 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4460 ref = IDirect3DDevice9_Release(device);
4461 ok(!ref, "Unexpected refcount %lu, i=%u.\n", ref, i);
4463 ShowWindow(device_window, SW_RESTORE);
4464 SetForegroundWindow(focus_window);
4465 flush_events();
4467 filter_messages = focus_window;
4468 device_desc.device_window = device_window;
4469 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4471 skip("Failed to create a D3D device, skipping tests.\n");
4472 goto done;
4474 filter_messages = NULL;
4475 flush_events();
4477 device_desc.width = user32_width;
4478 device_desc.height = user32_height;
4480 expect_messages = tests[i].mode_change_messages;
4481 filter_messages = focus_window;
4482 hr = reset_device(device, &device_desc);
4483 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4484 filter_messages = NULL;
4486 /* The WINDOWPOS structure passed to the first WM_WINDOWPOSCHANGING differs between windows versions.
4487 * Prior to Win10 17.03 it is consistent with a MoveWindow(0, 0, width, height) call. Since Windows
4488 * 10 17.03 it has x = 0, y = 0, width = 0, height = 0, flags = SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE
4489 * | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER (0x1837). Visually
4490 * it is clear that the window has not been resized. In previous Windows version the window is resized. */
4492 flush_events();
4493 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4494 expect_messages->message, expect_messages->window, i);
4495 expect_messages = NULL;
4497 /* World of Warplanes hides the window by removing WS_VISIBLE and expects Reset() to show it again. */
4498 device_style = GetWindowLongA(device_window, GWL_STYLE);
4499 SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE);
4501 flush_events();
4502 device_desc.width = d3d_width;
4503 device_desc.height = d3d_height;
4504 memset(&windowpos, 0, sizeof(windowpos));
4506 expect_messages = tests[i].mode_change_messages_hidden;
4507 filter_messages = focus_window;
4508 hr = reset_device(device, &device_desc);
4509 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4510 filter_messages = NULL;
4512 flush_events();
4513 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
4514 expect_messages->message, expect_messages->window, i);
4515 expect_messages = NULL;
4517 if (!(tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES))
4519 ok(windowpos.hwnd == device_window && !windowpos.hwndInsertAfter
4520 && !windowpos.x && !windowpos.y && !windowpos.cx && !windowpos.cy
4521 && windowpos.flags == (SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE),
4522 "Got unexpected WINDOWPOS hwnd=%p, insertAfter=%p, x=%d, y=%d, cx=%d, cy=%d, flags=%x\n",
4523 windowpos.hwnd, windowpos.hwndInsertAfter, windowpos.x, windowpos.y, windowpos.cx,
4524 windowpos.cy, windowpos.flags);
4527 device_style = GetWindowLongA(device_window, GWL_STYLE);
4528 if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
4530 todo_wine ok(!(device_style & WS_VISIBLE), "Expected the device window to be hidden, i=%u.\n", i);
4531 ShowWindow(device_window, SW_MINIMIZE);
4532 ShowWindow(device_window, SW_RESTORE);
4534 else
4536 ok(device_style & WS_VISIBLE, "Expected the device window to be visible, i=%u.\n", i);
4539 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
4540 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#Ix, i=%u.\n",
4541 (LONG_PTR)test_proc, i);
4543 filter_messages = focus_window;
4544 ref = IDirect3DDevice9_Release(device);
4545 ok(!ref, "Unexpected refcount %lu, i=%u.\n", ref, i);
4547 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4548 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#Ix, got %#Ix, i=%u.\n",
4549 (LONG_PTR)DefWindowProcA, proc, i);
4551 done:
4552 filter_messages = NULL;
4553 expect_messages = NULL;
4554 DestroyWindow(device_window);
4555 DestroyWindow(focus_window);
4556 SetEvent(thread_params.test_finished);
4557 WaitForSingleObject(thread, INFINITE);
4558 CloseHandle(thread);
4561 IDirect3D9_Release(d3d9);
4562 CloseHandle(thread_params.test_finished);
4563 CloseHandle(thread_params.window_created);
4564 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
4565 change_ret = ChangeDisplaySettingsExW(NULL, NULL, NULL, 0, NULL);
4566 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret);
4569 static void test_wndproc_windowed(void)
4571 struct wndproc_thread_param thread_params;
4572 struct device_desc device_desc;
4573 IDirect3DDevice9 *device;
4574 WNDCLASSA wc = {0};
4575 IDirect3D9 *d3d9;
4576 HANDLE thread;
4577 LONG_PTR proc;
4578 HRESULT hr;
4579 ULONG ref;
4580 DWORD res, tid;
4581 HWND tmp;
4583 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4584 ok(!!d3d9, "Failed to create a D3D object.\n");
4586 filter_messages = NULL;
4587 expect_messages = NULL;
4589 wc.lpfnWndProc = test_proc;
4590 wc.lpszClassName = "d3d9_test_wndproc_wc";
4591 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4593 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
4594 ok(!!thread_params.window_created, "CreateEvent failed, last error %#lx.\n", GetLastError());
4595 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
4596 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#lx.\n", GetLastError());
4598 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
4599 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
4600 registry_mode.dmPelsHeight, 0, 0, 0, 0);
4601 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
4602 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
4603 registry_mode.dmPelsHeight, 0, 0, 0, 0);
4604 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
4605 ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
4607 res = WaitForSingleObject(thread_params.window_created, INFINITE);
4608 ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
4610 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4611 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4612 (LONG_PTR)test_proc, proc);
4613 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4614 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4615 (LONG_PTR)test_proc, proc);
4617 trace("device_window %p, focus_window %p, dummy_window %p.\n",
4618 device_window, focus_window, thread_params.dummy_window);
4620 tmp = GetFocus();
4621 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
4622 if (thread_params.running_in_foreground)
4624 tmp = GetForegroundWindow();
4625 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
4626 thread_params.dummy_window, tmp);
4628 else
4629 skip("Not running in foreground, skip foreground window test\n");
4631 filter_messages = focus_window;
4633 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
4634 device_desc.device_window = device_window;
4635 device_desc.width = 640;
4636 device_desc.height = 480;
4637 device_desc.flags = 0;
4638 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4640 skip("Failed to create a D3D device, skipping tests.\n");
4641 goto done;
4644 tmp = GetFocus();
4645 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
4646 tmp = GetForegroundWindow();
4647 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
4648 thread_params.dummy_window, tmp);
4650 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4651 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4652 (LONG_PTR)test_proc, proc);
4654 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4655 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4656 (LONG_PTR)test_proc, proc);
4658 filter_messages = NULL;
4660 device_desc.width = registry_mode.dmPelsWidth;
4661 device_desc.height = registry_mode.dmPelsHeight;
4662 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4663 hr = reset_device(device, &device_desc);
4664 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4666 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4667 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4668 (LONG_PTR)test_proc, proc);
4670 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4671 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#Ix.\n", (LONG_PTR)test_proc);
4673 device_desc.flags = 0;
4674 hr = reset_device(device, &device_desc);
4675 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4677 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4678 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4679 (LONG_PTR)test_proc, proc);
4681 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4682 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4683 (LONG_PTR)test_proc, proc);
4685 filter_messages = focus_window;
4687 ref = IDirect3DDevice9_Release(device);
4688 ok(!ref, "Unexpected refcount %lu.\n", ref);
4690 filter_messages = device_window;
4692 device_desc.device_window = focus_window;
4693 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4695 skip("Failed to create a D3D device, skipping tests.\n");
4696 goto done;
4699 filter_messages = NULL;
4701 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4702 hr = reset_device(device, &device_desc);
4703 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4705 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4706 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4707 (LONG_PTR)test_proc, proc);
4709 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4710 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#Ix.\n", (LONG_PTR)test_proc);
4712 device_desc.flags = 0;
4713 hr = reset_device(device, &device_desc);
4714 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4716 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4717 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4718 (LONG_PTR)test_proc, proc);
4720 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4721 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4722 (LONG_PTR)test_proc, proc);
4724 filter_messages = device_window;
4726 ref = IDirect3DDevice9_Release(device);
4727 ok(!ref, "Unexpected refcount %lu.\n", ref);
4729 device_desc.device_window = device_window;
4730 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4732 skip("Failed to create a D3D device, skipping tests.\n");
4733 goto done;
4736 filter_messages = NULL;
4738 device_desc.device_window = device_window;
4739 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4740 hr = reset_device(device, &device_desc);
4741 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4743 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4744 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4745 (LONG_PTR)test_proc, proc);
4747 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4748 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#Ix.\n", (LONG_PTR)test_proc);
4750 device_desc.flags = 0;
4751 hr = reset_device(device, &device_desc);
4752 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
4754 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4755 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4756 (LONG_PTR)test_proc, proc);
4758 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4759 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
4760 (LONG_PTR)test_proc, proc);
4762 filter_messages = device_window;
4764 ref = IDirect3DDevice9_Release(device);
4765 ok(!ref, "Unexpected refcount %lu.\n", ref);
4767 done:
4768 filter_messages = NULL;
4769 IDirect3D9_Release(d3d9);
4771 SetEvent(thread_params.test_finished);
4772 WaitForSingleObject(thread, INFINITE);
4773 CloseHandle(thread_params.test_finished);
4774 CloseHandle(thread_params.window_created);
4775 CloseHandle(thread);
4777 DestroyWindow(device_window);
4778 DestroyWindow(focus_window);
4779 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
4782 static void test_reset_fullscreen(void)
4784 struct device_desc device_desc;
4785 D3DDISPLAYMODE d3ddm, d3ddm2;
4786 unsigned int mode_count, i;
4787 IDirect3DDevice9 *device;
4788 WNDCLASSEXA wc = {0};
4789 IDirect3D9 *d3d;
4790 RECT r1, r2;
4791 HRESULT hr;
4792 ATOM atom;
4793 static const struct message messages[] =
4795 /* Windows usually sends wparam = TRUE, except on the testbot,
4796 * where it randomly sends FALSE. Ignore it. */
4797 {WM_ACTIVATEAPP, FOCUS_WINDOW, FALSE, 0},
4798 {0, 0, FALSE, 0},
4801 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4802 ok(!!d3d, "Failed to create a D3D object.\n");
4803 filter_messages = NULL;
4804 expect_messages = messages;
4806 wc.cbSize = sizeof(wc);
4807 wc.lpfnWndProc = test_proc;
4808 wc.lpszClassName = "test_reset_fullscreen";
4810 atom = RegisterClassExA(&wc);
4811 ok(atom, "Failed to register class, error %lu.\n", GetLastError());
4813 device_window = focus_window = CreateWindowExA(0, wc.lpszClassName, "Test Reset Fullscreen", 0,
4814 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight, NULL, NULL, NULL, NULL);
4815 ok(device_window != NULL, "Failed to create window. error %lu.\n", GetLastError());
4818 * Create a device in windowed mode.
4819 * Since the device is windowed and we haven't called any methods that
4820 * could show the window (such as ShowWindow or SetWindowPos) yet,
4821 * WM_ACTIVATEAPP will not have been sent.
4823 if (!(device = create_device(d3d, device_window, NULL)))
4825 skip("Unable to create device. Skipping test.\n");
4826 goto cleanup;
4830 * Switch to fullscreen mode.
4831 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
4832 * message to be sent.
4834 device_desc.width = registry_mode.dmPelsWidth;
4835 device_desc.height = registry_mode.dmPelsHeight;
4836 device_desc.device_window = device_window;
4837 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4838 ok(SUCCEEDED(reset_device(device, &device_desc)), "Failed to reset device.\n");
4840 flush_events();
4841 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
4842 expect_messages = NULL;
4844 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
4845 mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, d3ddm.Format);
4846 for (i = 0; i < mode_count; ++i)
4848 hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
4849 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#lx.\n", hr);
4851 if (d3ddm2.Width != d3ddm.Width || d3ddm2.Height != d3ddm.Height)
4852 break;
4854 if (i == mode_count)
4856 skip("Could not find a suitable display mode.\n");
4857 goto cleanup;
4860 wm_size_received = 0;
4862 /* Fullscreen mode change. */
4863 device_desc.width = d3ddm2.Width;
4864 device_desc.height = d3ddm2.Height;
4865 device_desc.device_window = device_window;
4866 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4867 ok(SUCCEEDED(reset_device(device, &device_desc)), "Failed to reset device.\n");
4869 /* We shouldn't receive a WM_SIZE message during the reset because d3d filters
4870 * messages sent to the focus window. This is important because some games
4871 * respond to WM_SIZE messages by calling Reset(), resulting in an endless
4872 * recursion. */
4873 ok(!wm_size_received, "Received unexpected WM_SIZE message.\n");
4874 GetWindowRect(device_window, &r1);
4876 flush_events();
4877 GetWindowRect(device_window, &r2);
4879 /* fvwm2 and 3 resize the window though. We learn about this when processing
4880 * events, after Reset() has finished and d3d is no longer filtering window
4881 * messages. This still shouldn't happen but won't lead to an endless recursion.
4883 * As far as I understand the fvwm3 source code, the WM doesn't expect a window
4884 * to change from size A maximized to size B maximized. It will un-maximize the
4885 * window, picking the stored normal size - which appens to be the size of the
4886 * first fullscreen mode above, but not necessarily the screen size at startup.
4888 * fvwm2 on the other hand doesn't understand mode switches at all. It will see
4889 * the window is fullscreen (it has separate flags for fullscreen and maximized),
4890 * and try to resize it to what it thinks is the display mode - which is the mode
4891 * that fvwm2 was started with. The above fvwm3 bug also exists in fvwm2 but is
4892 * hidden by the mode bug.
4894 * This comment is based on a very superficial understanding of fvwm's event
4895 * and window dimension handling code, which is about 10k lines of code. So it
4896 * may be wrong. */
4897 todo_wine_if(!EqualRect(&r1, &r2))
4898 ok(!wm_size_received, "Received unexpected WM_SIZE message.\n");
4900 cleanup:
4901 if (device) IDirect3DDevice9_Release(device);
4902 IDirect3D9_Release(d3d);
4903 DestroyWindow(device_window);
4904 device_window = focus_window = NULL;
4905 UnregisterClassA(wc.lpszClassName, GetModuleHandleA(NULL));
4909 static const GUID d3d9_private_data_test_guid =
4911 0xfdb37466,
4912 0x428f,
4913 0x4edf,
4914 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
4917 #if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__) && (defined(__GNUC__) || defined(__clang__)))
4919 static inline void set_fpu_cw(WORD cw)
4921 #if defined(_MSC_VER) && defined(__i386__)
4922 __asm fnclex;
4923 __asm fldcw cw;
4924 #else
4925 __asm__ volatile ("fnclex");
4926 __asm__ volatile ("fldcw %0" : : "m" (cw));
4927 #endif
4930 static inline WORD get_fpu_cw(void)
4932 WORD cw = 0;
4933 #if defined(_MSC_VER) && defined(__i386__)
4934 __asm fnstcw cw;
4935 #else
4936 __asm__ volatile ("fnstcw %0" : "=m" (cw));
4937 #endif
4938 return cw;
4941 static WORD callback_cw, callback_set_cw;
4942 static DWORD callback_tid;
4944 static HRESULT WINAPI dummy_object_QueryInterface(IUnknown *iface, REFIID riid, void **out)
4946 *out = NULL;
4947 return E_NOINTERFACE;
4950 static ULONG WINAPI dummy_object_AddRef(IUnknown *iface)
4952 callback_cw = get_fpu_cw();
4953 set_fpu_cw(callback_set_cw);
4954 callback_tid = GetCurrentThreadId();
4955 return 2;
4958 static ULONG WINAPI dummy_object_Release(IUnknown *iface)
4960 callback_cw = get_fpu_cw();
4961 set_fpu_cw(callback_set_cw);
4962 callback_tid = GetCurrentThreadId();
4963 return 1;
4966 static const IUnknownVtbl dummy_object_vtbl =
4968 dummy_object_QueryInterface,
4969 dummy_object_AddRef,
4970 dummy_object_Release,
4973 static void test_fpu_setup(void)
4975 static const BOOL is_64bit = sizeof(void *) > sizeof(int);
4976 IUnknown dummy_object = {&dummy_object_vtbl};
4977 struct device_desc device_desc;
4978 IDirect3DSurface9 *surface;
4979 IDirect3DDevice9 *device;
4980 WORD cw, expected_cw;
4981 HWND window = NULL;
4982 IDirect3D9 *d3d9;
4983 HRESULT hr;
4985 window = create_window();
4986 ok(!!window, "Failed to create a window.\n");
4987 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4988 ok(!!d3d9, "Failed to create a D3D object.\n");
4990 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
4991 device_desc.device_window = window;
4992 device_desc.width = 640;
4993 device_desc.height = 480;
4994 device_desc.flags = 0;
4996 set_fpu_cw(0xf60);
4997 cw = get_fpu_cw();
4998 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
5000 if (!(device = create_device(d3d9, window, &device_desc)))
5002 skip("Failed to create a 3D device, skipping test.\n");
5003 set_fpu_cw(0x37f);
5004 goto done;
5007 expected_cw = is_64bit ? 0xf60 : 0x7f;
5009 cw = get_fpu_cw();
5010 todo_wine_if(is_64bit)
5011 ok(cw == expected_cw, "cw is %#x, expected %#x.\n", cw, expected_cw);
5013 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
5014 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#lx.\n", hr);
5016 callback_set_cw = 0xf60;
5017 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
5018 &dummy_object, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5019 ok(SUCCEEDED(hr), "Failed to set private data, hr %#lx.\n", hr);
5020 todo_wine_if(is_64bit)
5021 ok(callback_cw == expected_cw, "Callback cw is %#x, expected %#x.\n", callback_cw, expected_cw);
5022 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
5023 cw = get_fpu_cw();
5024 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
5026 callback_cw = 0;
5027 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
5028 &dummy_object, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5029 ok(SUCCEEDED(hr), "Failed to set private data, hr %#lx.\n", hr);
5030 ok(callback_cw == 0xf60, "Callback cw is %#x, expected 0xf60.\n", callback_cw);
5031 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
5033 callback_set_cw = 0x7f;
5034 set_fpu_cw(0x7f);
5036 IDirect3DSurface9_Release(surface);
5038 callback_cw = 0;
5039 IDirect3DDevice9_Release(device);
5040 ok(callback_cw == 0x7f, "Callback cw is %#x, expected 0x7f.\n", callback_cw);
5041 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
5043 cw = get_fpu_cw();
5044 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
5045 set_fpu_cw(0xf60);
5046 cw = get_fpu_cw();
5047 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
5049 device_desc.flags = CREATE_DEVICE_FPU_PRESERVE;
5050 device = create_device(d3d9, window, &device_desc);
5051 ok(device != NULL, "CreateDevice failed.\n");
5053 cw = get_fpu_cw();
5054 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
5056 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
5057 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#lx.\n", hr);
5059 callback_cw = 0;
5060 callback_set_cw = 0x37f;
5061 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
5062 &dummy_object, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5063 ok(SUCCEEDED(hr), "Failed to set private data, hr %#lx.\n", hr);
5064 ok(callback_cw == 0xf60, "Callback cw is %#x, expected 0xf60.\n", callback_cw);
5065 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
5066 cw = get_fpu_cw();
5067 ok(cw == 0x37f, "cw is %#x, expected 0x37f.\n", cw);
5069 IDirect3DSurface9_Release(surface);
5071 callback_cw = 0;
5072 IDirect3DDevice9_Release(device);
5073 ok(callback_cw == 0x37f, "Callback cw is %#x, expected 0xf60.\n", callback_cw);
5074 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
5076 done:
5077 IDirect3D9_Release(d3d9);
5078 DestroyWindow(window);
5081 #else
5083 static void test_fpu_setup(void)
5087 #endif
5089 static void test_window_style(void)
5091 RECT focus_rect, device_rect, fullscreen_rect, r, r2;
5092 LONG device_style, device_exstyle;
5093 LONG focus_style, focus_exstyle;
5094 struct device_desc device_desc;
5095 LONG style, expected_style;
5096 IDirect3DDevice9 *device;
5097 IDirect3D9 *d3d9;
5098 HRESULT hr;
5099 ULONG ref;
5100 BOOL ret;
5101 static const struct
5103 DWORD device_flags;
5104 LONG create_style, style, focus_loss_style, exstyle, focus_loss_exstyle;
5106 tests[] =
5108 {0, 0, WS_VISIBLE, WS_MINIMIZE, WS_EX_TOPMOST, WS_EX_TOPMOST},
5109 {0, WS_VISIBLE, WS_VISIBLE, WS_MINIMIZE, 0, WS_EX_TOPMOST},
5110 {CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0, 0, 0},
5111 {CREATE_DEVICE_NOWINDOWCHANGES, WS_VISIBLE, WS_VISIBLE, 0, 0, 0},
5113 unsigned int i;
5115 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5116 ok(!!d3d9, "Failed to create a D3D object.\n");
5117 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
5119 for (i = 0; i < ARRAY_SIZE(tests); ++i)
5121 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].create_style,
5122 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
5123 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | tests[i].create_style,
5124 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
5126 device_style = GetWindowLongA(device_window, GWL_STYLE);
5127 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
5128 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
5129 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
5131 GetWindowRect(focus_window, &focus_rect);
5132 GetWindowRect(device_window, &device_rect);
5134 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5135 device_desc.device_window = device_window;
5136 device_desc.width = registry_mode.dmPelsWidth;
5137 device_desc.height = registry_mode.dmPelsHeight;
5138 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
5139 if (!(device = create_device(d3d9, focus_window, &device_desc)))
5141 skip("Failed to create a D3D device, skipping tests.\n");
5142 DestroyWindow(device_window);
5143 DestroyWindow(focus_window);
5144 break;
5147 style = GetWindowLongA(device_window, GWL_STYLE);
5148 expected_style = device_style | tests[i].style;
5149 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
5150 "Expected device window style %#lx, got %#lx, i=%u.\n",
5151 expected_style, style, i);
5152 style = GetWindowLongA(device_window, GWL_EXSTYLE);
5153 expected_style = device_exstyle | tests[i].exstyle;
5154 todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
5155 "Expected device window extended style %#lx, got %#lx, i=%u.\n",
5156 expected_style, style, i);
5158 style = GetWindowLongA(focus_window, GWL_STYLE);
5159 ok(style == focus_style, "Expected focus window style %#lx, got %#lx, i=%u.\n",
5160 focus_style, style, i);
5161 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
5162 ok(style == focus_exstyle, "Expected focus window extended style %#lx, got %#lx, i=%u.\n",
5163 focus_exstyle, style, i);
5165 GetWindowRect(device_window, &r);
5166 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
5167 todo_wine ok(EqualRect(&r, &device_rect), "Expected %s, got %s, i=%u.\n",
5168 wine_dbgstr_rect(&device_rect), wine_dbgstr_rect(&r), i);
5169 else
5170 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s, i=%u.\n",
5171 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r), i);
5172 GetClientRect(device_window, &r2);
5173 todo_wine ok(!EqualRect(&r, &r2) || broken(!(style & WS_THICKFRAME)) /* w1064v1809 */,
5174 "Client rect and window rect are equal, i=%u.\n", i);
5175 GetWindowRect(focus_window, &r);
5176 ok(EqualRect(&r, &focus_rect), "Expected %s, got %s, i=%u.\n",
5177 wine_dbgstr_rect(&focus_rect), wine_dbgstr_rect(&r), i);
5179 device_desc.flags = 0;
5180 hr = reset_device(device, &device_desc);
5181 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
5183 style = GetWindowLongA(device_window, GWL_STYLE);
5184 expected_style = device_style | tests[i].style;
5185 ok(style == expected_style, "Expected device window style %#lx, got %#lx, i=%u.\n",
5186 expected_style, style, i);
5187 style = GetWindowLongA(device_window, GWL_EXSTYLE);
5188 expected_style = device_exstyle | tests[i].exstyle;
5189 todo_wine_if (!(tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES) && (tests[i].create_style & WS_VISIBLE))
5190 ok(style == expected_style, "Expected device window extended style %#lx, got %#lx, i=%u.\n",
5191 expected_style, style, i);
5193 style = GetWindowLongA(focus_window, GWL_STYLE);
5194 ok(style == focus_style, "Expected focus window style %#lx, got %#lx, i=%u.\n",
5195 focus_style, style, i);
5196 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
5197 ok(style == focus_exstyle, "Expected focus window extended style %#lx, got %#lx, i=%u.\n",
5198 focus_exstyle, style, i);
5200 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5201 hr = reset_device(device, &device_desc);
5202 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
5203 ret = SetForegroundWindow(GetDesktopWindow());
5204 ok(ret, "Failed to set foreground window.\n");
5206 style = GetWindowLongA(device_window, GWL_STYLE);
5207 expected_style = device_style | tests[i].focus_loss_style | tests[i].style;
5208 todo_wine ok(style == expected_style, "Expected device window style %#lx, got %#lx, i=%u.\n",
5209 expected_style, style, i);
5210 style = GetWindowLongA(device_window, GWL_EXSTYLE);
5211 expected_style = device_exstyle | tests[i].focus_loss_exstyle | tests[i].exstyle;
5212 todo_wine ok(style == expected_style, "Expected device window extended style %#lx, got %#lx, i=%u.\n",
5213 expected_style, style, i);
5215 style = GetWindowLongA(focus_window, GWL_STYLE);
5216 ok(style == focus_style, "Expected focus window style %#lx, got %#lx, i=%u.\n",
5217 focus_style, style, i);
5218 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
5219 ok(style == focus_exstyle, "Expected focus window extended style %#lx, got %#lx, i=%u.\n",
5220 focus_exstyle, style, i);
5222 /* In d3d8 follow-up tests fail on native if the device is destroyed while
5223 * lost. This doesn't happen in d3d9 on my test machine but it still seems
5224 * like a good idea to reset it first. */
5225 ShowWindow(focus_window, SW_MINIMIZE);
5226 ShowWindow(focus_window, SW_RESTORE);
5227 ret = SetForegroundWindow(focus_window);
5228 ok(ret, "Failed to set foreground window.\n");
5229 flush_events();
5230 hr = reset_device(device, &device_desc);
5231 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
5233 ref = IDirect3DDevice9_Release(device);
5234 ok(!ref, "Unexpected refcount %lu.\n", ref);
5236 DestroyWindow(device_window);
5237 DestroyWindow(focus_window);
5239 IDirect3D9_Release(d3d9);
5242 static const POINT *expect_pos;
5244 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
5246 if (message == WM_MOUSEMOVE)
5248 if (expect_pos && expect_pos->x && expect_pos->y)
5250 POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
5252 ClientToScreen(window, &p);
5253 if (expect_pos->x == p.x && expect_pos->y == p.y)
5254 ++expect_pos;
5258 return DefWindowProcA(window, message, wparam, lparam);
5261 static void test_cursor_pos(void)
5263 IDirect3DSurface9 *cursor;
5264 IDirect3DDevice9 *device;
5265 WNDCLASSA wc = {0};
5266 IDirect3D9 *d3d9;
5267 ULONG refcount;
5268 HWND window;
5269 HRESULT hr;
5270 BOOL ret;
5271 POINT pt;
5273 /* Note that we don't check for movement we're not supposed to receive.
5274 * That's because it's hard to distinguish from the user accidentally
5275 * moving the mouse. */
5276 static const POINT points[] =
5278 {50, 50},
5279 {75, 75},
5280 {100, 100},
5281 {125, 125},
5282 {150, 150},
5283 {125, 125},
5284 {150, 150},
5285 {150, 150},
5286 {0, 0},
5289 /* Windows 10 1709 is unreliable. One or more of the cursor movements we
5290 * expect don't show up. Moving the mouse to a defined position beforehand
5291 * seems to get it into better shape - only the final 150x150 move we do
5292 * below is missing - it looks as if this Windows version filters redundant
5293 * SetCursorPos calls on the user32 level, although I am not entirely sure.
5295 * The weird thing is that the previous test leaves the cursor position
5296 * reliably at 512x384 on the testbot. So the 50x50 mouse move shouldn't
5297 * be stripped away anyway, but it might be a difference between moving the
5298 * cursor through SetCursorPos vs moving it by changing the display mode. */
5299 ret = SetCursorPos(99, 99);
5300 ok(ret, "Failed to set cursor position.\n");
5301 flush_events();
5303 /* Check if we can move the cursor. If we're running in a virtual desktop
5304 * that does not have focus or the mouse is outside the desktop window, some
5305 * window managers (e.g. kwin) will refuse to let us steal the pointer. That
5306 * is reasonable, but breaks the test. */
5307 ret = GetCursorPos(&pt);
5308 ok(ret, "Failed to get cursor position.\n");
5309 if (pt.x != 99 || pt.y != 99)
5311 skip("Could not warp the cursor (cur pos %ld,%ld), skipping test.\n", pt.x, pt.y);
5312 return;
5315 wc.lpfnWndProc = test_cursor_proc;
5316 wc.lpszClassName = "d3d9_test_cursor_wc";
5317 ok(RegisterClassA(&wc), "Failed to register window class.\n");
5318 window = CreateWindowA("d3d9_test_cursor_wc", "d3d9_test", WS_POPUP | WS_SYSMENU,
5319 0, 0, 320, 240, NULL, NULL, NULL, NULL);
5320 ShowWindow(window, SW_SHOW);
5321 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5322 ok(!!d3d9, "Failed to create a D3D object.\n");
5324 device = create_device(d3d9, window, NULL);
5325 if (!device)
5327 skip("Failed to create a D3D device, skipping tests.\n");
5328 goto done;
5331 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
5332 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
5333 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#lx.\n", hr);
5334 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
5335 ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#lx.\n", hr);
5336 IDirect3DSurface9_Release(cursor);
5337 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
5338 ok(!ret, "Got %#x.\n", ret);
5340 flush_events();
5341 expect_pos = points;
5343 ret = SetCursorPos(50, 50);
5344 ok(ret, "Failed to set cursor position.\n");
5345 flush_events();
5347 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
5348 flush_events();
5349 /* SetCursorPosition() eats duplicates. FIXME: Since we accept unexpected
5350 * mouse moves the test doesn't actually demonstrate that. */
5351 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
5352 flush_events();
5354 ret = SetCursorPos(100, 100);
5355 ok(ret, "Failed to set cursor position.\n");
5356 flush_events();
5357 /* Even if the position was set with SetCursorPos(). */
5358 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
5359 flush_events();
5361 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
5362 flush_events();
5363 ret = SetCursorPos(150, 150);
5364 ok(ret, "Failed to set cursor position.\n");
5365 flush_events();
5366 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
5367 flush_events();
5369 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
5370 flush_events();
5371 /* SetCursorPos() doesn't. Except for Win10 1709. */
5372 ret = SetCursorPos(150, 150);
5373 ok(ret, "Failed to set cursor position.\n");
5374 flush_events();
5376 flaky
5377 ok((!expect_pos->x && !expect_pos->y) || broken(expect_pos - points == 7),
5378 "Didn't receive MOUSEMOVE %u (%ld, %ld).\n",
5379 (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
5381 refcount = IDirect3DDevice9_Release(device);
5382 ok(!refcount, "Device has %lu references left.\n", refcount);
5383 done:
5384 DestroyWindow(window);
5385 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
5386 IDirect3D9_Release(d3d9);
5389 static void test_mode_change(void)
5391 unsigned int display_count = 0, d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
5392 DEVMODEW old_devmode, devmode, devmode2, *original_modes = NULL;
5393 struct device_desc device_desc, device_desc2;
5394 WCHAR second_monitor_name[CCHDEVICENAME];
5395 IDirect3DDevice9 *device, *device2;
5396 RECT d3d_rect, focus_rect, r;
5397 IDirect3DSurface9 *backbuffer;
5398 MONITORINFOEXW monitor_info;
5399 HMONITOR second_monitor;
5400 D3DSURFACE_DESC desc;
5401 IDirect3D9 *d3d9;
5402 ULONG refcount;
5403 UINT adapter_mode_count, i;
5404 HRESULT hr;
5405 BOOL ret;
5406 LONG change_ret;
5407 D3DDISPLAYMODE d3ddm;
5409 memset(&devmode, 0, sizeof(devmode));
5410 devmode.dmSize = sizeof(devmode);
5411 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
5412 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5413 ok(equal_mode_rect(&devmode, &registry_mode), "Got a different mode.\n");
5414 ret = EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &devmode);
5415 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5416 ok(equal_mode_rect(&devmode, &registry_mode), "Got a different mode.\n");
5418 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5419 ok(!!d3d9, "Failed to create a D3D object.\n");
5421 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
5422 for (i = 0; i < adapter_mode_count; ++i)
5424 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3ddm);
5425 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#lx.\n", hr);
5427 if (d3ddm.Width == registry_mode.dmPelsWidth && d3ddm.Height == registry_mode.dmPelsHeight)
5428 continue;
5429 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
5430 * refuses to create a device at these sizes. */
5431 if (d3ddm.Width < 640 || d3ddm.Height < 480)
5432 continue;
5434 if (!user32_width)
5436 user32_width = d3ddm.Width;
5437 user32_height = d3ddm.Height;
5438 continue;
5441 /* Make sure the d3d mode is smaller in width or height and at most
5442 * equal in the other dimension than the mode passed to
5443 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
5444 * the ChangeDisplaySettings parameters + 12. */
5445 if (d3ddm.Width == user32_width && d3ddm.Height == user32_height)
5446 continue;
5447 if (d3ddm.Width <= user32_width && d3ddm.Height <= user32_height)
5449 d3d_width = d3ddm.Width;
5450 d3d_height = d3ddm.Height;
5451 break;
5453 if (user32_width <= d3ddm.Width && user32_height <= d3ddm.Height)
5455 d3d_width = user32_width;
5456 d3d_height = user32_height;
5457 user32_width = d3ddm.Width;
5458 user32_height = d3ddm.Height;
5459 break;
5463 if (!d3d_width)
5465 skip("Could not find adequate modes, skipping mode tests.\n");
5466 IDirect3D9_Release(d3d9);
5467 return;
5470 ret = save_display_modes(&original_modes, &display_count);
5471 ok(ret, "Failed to save original display modes.\n");
5473 memset(&devmode, 0, sizeof(devmode));
5474 devmode.dmSize = sizeof(devmode);
5475 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
5476 devmode.dmPelsWidth = user32_width;
5477 devmode.dmPelsHeight = user32_height;
5478 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
5479 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx.\n", change_ret);
5481 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5482 0, 0, user32_width / 2, user32_height / 2, 0, 0, 0, 0);
5483 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5484 0, 0, user32_width / 2, user32_height / 2, 0, 0, 0, 0);
5486 SetRect(&d3d_rect, 0, 0, d3d_width, d3d_height);
5487 GetWindowRect(focus_window, &focus_rect);
5489 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5490 device_desc.device_window = device_window;
5491 device_desc.width = d3d_width;
5492 device_desc.height = d3d_height;
5493 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5494 if (!(device = create_device(d3d9, focus_window, &device_desc)))
5496 skip("Failed to create a D3D device, skipping tests.\n");
5497 goto done;
5500 devmode.dmPelsWidth = user32_width;
5501 devmode.dmPelsHeight = user32_height;
5502 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
5503 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx.\n", change_ret);
5505 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
5506 ok(ret, "Failed to get display mode.\n");
5507 ok(devmode.dmPelsWidth == user32_width && devmode.dmPelsHeight == user32_height,
5508 "Expected resolution %ux%u, got %lux%lu.\n",
5509 user32_width, user32_height, devmode.dmPelsWidth, devmode.dmPelsHeight);
5511 GetWindowRect(device_window, &r);
5512 ok(EqualRect(&r, &d3d_rect), "Expected %s, got %s.\n",
5513 wine_dbgstr_rect(&d3d_rect), wine_dbgstr_rect(&r));
5514 GetWindowRect(focus_window, &r);
5515 ok(EqualRect(&r, &focus_rect), "Expected %s, got %s.\n",
5516 wine_dbgstr_rect(&focus_rect), wine_dbgstr_rect(&r));
5518 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5519 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
5520 hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
5521 ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#lx.\n", hr);
5522 ok(desc.Width == d3d_width, "Got unexpected backbuffer width %u, expected %u.\n",
5523 desc.Width, d3d_width);
5524 ok(desc.Height == d3d_height, "Got unexpected backbuffer height %u, expected %u.\n",
5525 desc.Height, d3d_height);
5526 IDirect3DSurface9_Release(backbuffer);
5528 refcount = IDirect3DDevice9_Release(device);
5529 ok(!refcount, "Device has %lu references left.\n", refcount);
5531 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
5532 ok(ret, "Failed to get display mode.\n");
5533 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
5534 && devmode.dmPelsHeight == registry_mode.dmPelsHeight,
5535 "Expected resolution %lux%lu, got %lux%lu.\n",
5536 registry_mode.dmPelsWidth, registry_mode.dmPelsHeight, devmode.dmPelsWidth, devmode.dmPelsHeight);
5538 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
5539 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx.\n", change_ret);
5541 /* The mode restore also happens when the device was created at the original screen size. */
5543 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5544 device_desc.device_window = device_window;
5545 device_desc.width = registry_mode.dmPelsWidth;
5546 device_desc.height = registry_mode.dmPelsHeight;
5547 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5548 ok(!!(device = create_device(d3d9, focus_window, &device_desc)), "Failed to create a D3D device.\n");
5550 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
5551 devmode.dmPelsWidth = user32_width;
5552 devmode.dmPelsHeight = user32_height;
5553 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
5554 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#lx.\n", change_ret);
5556 refcount = IDirect3DDevice9_Release(device);
5557 ok(!refcount, "Device has %lu references left.\n", refcount);
5559 memset(&devmode2, 0, sizeof(devmode2));
5560 devmode2.dmSize = sizeof(devmode2);
5561 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode2);
5562 ok(ret, "Failed to get display mode.\n");
5563 ok(devmode2.dmPelsWidth == registry_mode.dmPelsWidth
5564 && devmode2.dmPelsHeight == registry_mode.dmPelsHeight,
5565 "Expected resolution %lux%lu, got %lux%lu.\n", registry_mode.dmPelsWidth,
5566 registry_mode.dmPelsHeight, devmode2.dmPelsWidth, devmode2.dmPelsHeight);
5567 ret = restore_display_modes(original_modes, display_count);
5568 ok(ret, "Failed to restore display modes.\n");
5570 /* Test that no mode restorations if no mode changes happened */
5571 change_ret = ChangeDisplaySettingsW(&devmode, CDS_UPDATEREGISTRY | CDS_NORESET);
5572 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsW failed with %ld.\n", change_ret);
5574 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5575 device_desc.device_window = device_window;
5576 device_desc.width = d3d_width;
5577 device_desc.height = d3d_height;
5578 device_desc.flags = 0;
5579 device = create_device(d3d9, device_window, &device_desc);
5580 ok(!!device, "Failed to create a D3D device.\n");
5581 refcount = IDirect3DDevice9_Release(device);
5582 ok(!refcount, "Device has %lu references left.\n", refcount);
5584 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode2);
5585 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5586 ok(equal_mode_rect(&devmode2, &registry_mode), "Got a different mode.\n");
5587 ret = restore_display_modes(original_modes, display_count);
5588 ok(ret, "Failed to restore display modes.\n");
5590 /* Test that mode restorations use display settings in the registry with a fullscreen device */
5591 change_ret = ChangeDisplaySettingsW(&devmode, CDS_UPDATEREGISTRY | CDS_NORESET);
5592 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsW failed with %ld.\n", change_ret);
5594 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5595 device_desc.device_window = device_window;
5596 device_desc.width = registry_mode.dmPelsWidth;
5597 device_desc.height = registry_mode.dmPelsHeight;
5598 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5599 device = create_device(d3d9, device_window, &device_desc);
5600 ok(!!device, "Failed to create a D3D device.\n");
5601 refcount = IDirect3DDevice9_Release(device);
5602 ok(!refcount, "Device has %lu references left.\n", refcount);
5604 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode2);
5605 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5606 ok(equal_mode_rect(&devmode2, &devmode), "Got a different mode.\n");
5607 ret = EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &devmode2);
5608 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5609 ok(equal_mode_rect(&devmode2, &devmode), "Got a different mode.\n");
5610 ret = restore_display_modes(original_modes, display_count);
5611 ok(ret, "Failed to restore display modes.\n");
5613 /* Test that mode restorations use display settings in the registry with a fullscreen device
5614 * having the same display mode and then reset to a different mode */
5615 change_ret = ChangeDisplaySettingsW(&devmode, CDS_UPDATEREGISTRY | CDS_NORESET);
5616 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsW failed with %ld.\n", change_ret);
5618 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5619 device_desc.device_window = device_window;
5620 device_desc.width = registry_mode.dmPelsWidth;
5621 device_desc.height = registry_mode.dmPelsHeight;
5622 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5623 device = create_device(d3d9, device_window, &device_desc);
5624 ok(!!device, "Failed to create a D3D device.\n");
5626 device_desc.width = d3d_width;
5627 device_desc.height = d3d_height;
5628 hr = reset_device(device, &device_desc);
5629 ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr);
5630 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode2);
5631 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5632 ok(devmode2.dmPelsWidth == d3d_width && devmode2.dmPelsHeight == d3d_height,
5633 "Expected resolution %ux%u, got %lux%lu.\n", d3d_width, d3d_height,
5634 devmode2.dmPelsWidth, devmode2.dmPelsHeight);
5636 refcount = IDirect3DDevice9_Release(device);
5637 ok(!refcount, "Device has %lu references left.\n", refcount);
5639 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode2);
5640 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5641 ok(equal_mode_rect(&devmode2, &devmode), "Got a different mode.\n");
5642 ret = EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &devmode2);
5643 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5644 ok(equal_mode_rect(&devmode2, &devmode), "Got a different mode.\n");
5645 ret = restore_display_modes(original_modes, display_count);
5646 ok(ret, "Failed to restore display modes.\n");
5648 if (IDirect3D9_GetAdapterCount(d3d9) < 2)
5650 skip("Following tests require two adapters.\n");
5651 goto done;
5654 second_monitor = IDirect3D9_GetAdapterMonitor(d3d9, 1);
5655 monitor_info.cbSize = sizeof(monitor_info);
5656 ret = GetMonitorInfoW(second_monitor, (MONITORINFO *)&monitor_info);
5657 ok(ret, "GetMonitorInfoW failed, error %#lx.\n", GetLastError());
5658 lstrcpyW(second_monitor_name, monitor_info.szDevice);
5660 memset(&old_devmode, 0, sizeof(old_devmode));
5661 old_devmode.dmSize = sizeof(old_devmode);
5662 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &old_devmode);
5663 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5665 i = 0;
5666 d3d_width = 0;
5667 d3d_height = 0;
5668 user32_width = 0;
5669 user32_height = 0;
5670 while (EnumDisplaySettingsW(second_monitor_name, i++, &devmode))
5672 if (devmode.dmPelsWidth == old_devmode.dmPelsWidth
5673 && devmode.dmPelsHeight == old_devmode.dmPelsHeight)
5674 continue;
5676 if (!d3d_width && !d3d_height)
5678 d3d_width = devmode.dmPelsWidth;
5679 d3d_height = devmode.dmPelsHeight;
5680 continue;
5683 if (devmode.dmPelsWidth == d3d_width && devmode.dmPelsHeight == d3d_height)
5684 continue;
5686 user32_width = devmode.dmPelsWidth;
5687 user32_height = devmode.dmPelsHeight;
5688 break;
5690 if (!user32_width || !user32_height)
5692 skip("Failed to find three different display modes for the second monitor.\n");
5693 goto done;
5696 /* Test that mode restorations also happen for non-primary monitors on device resets */
5697 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5698 device_desc.device_window = device_window;
5699 device_desc.width = registry_mode.dmPelsWidth;
5700 device_desc.height = registry_mode.dmPelsHeight;
5701 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5702 device = create_device(d3d9, device_window, &device_desc);
5703 ok(!!device, "Failed to create a D3D device.\n");
5705 change_ret = ChangeDisplaySettingsExW(second_monitor_name, &devmode, NULL, CDS_RESET, NULL);
5706 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret);
5707 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
5708 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5709 if (devmode2.dmPelsWidth == old_devmode.dmPelsWidth
5710 && devmode2.dmPelsHeight == old_devmode.dmPelsHeight)
5712 skip("Failed to change display settings of the second monitor.\n");
5713 refcount = IDirect3DDevice9_Release(device);
5714 ok(!refcount, "Device has %lu references left.\n", refcount);
5715 goto done;
5718 device_desc.flags = 0;
5719 hr = reset_device(device, &device_desc);
5720 ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr);
5722 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
5723 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5724 ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
5725 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_REGISTRY_SETTINGS, &devmode2);
5726 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5727 ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
5728 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, 1, &d3ddm);
5729 ok(hr == S_OK, "GetAdapterDisplayMode failed, hr %#lx.\n", hr);
5730 ok(d3ddm.Width == old_devmode.dmPelsWidth, "Expected width %lu, got %u.\n",
5731 old_devmode.dmPelsWidth, d3ddm.Width);
5732 ok(d3ddm.Height == old_devmode.dmPelsHeight, "Expected height %lu, got %u.\n",
5733 old_devmode.dmPelsHeight, d3ddm.Height);
5735 refcount = IDirect3DDevice9_Release(device);
5736 ok(!refcount, "Device has %lu references left.\n", refcount);
5737 ret = restore_display_modes(original_modes, display_count);
5738 ok(ret, "Failed to restore display modes.\n");
5740 /* Test that mode restorations happen for non-primary monitors on device releases */
5741 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5742 device_desc.device_window = device_window;
5743 device_desc.width = registry_mode.dmPelsWidth;
5744 device_desc.height = registry_mode.dmPelsHeight;
5745 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5746 device = create_device(d3d9, device_window, &device_desc);
5747 ok(!!device, "Failed to create a D3D device.\n");
5749 change_ret = ChangeDisplaySettingsExW(second_monitor_name, &devmode, NULL, CDS_RESET, NULL);
5750 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret);
5752 refcount = IDirect3DDevice9_Release(device);
5753 ok(!refcount, "Device has %lu references left.\n", refcount);
5755 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
5756 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5757 ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
5758 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_REGISTRY_SETTINGS, &devmode2);
5759 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5760 ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
5761 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, 1, &d3ddm);
5762 ok(hr == S_OK, "GetAdapterDisplayMode failed, hr %#lx.\n", hr);
5763 ok(d3ddm.Width == old_devmode.dmPelsWidth, "Expected width %lu, got %u.\n",
5764 old_devmode.dmPelsWidth, d3ddm.Width);
5765 ok(d3ddm.Height == old_devmode.dmPelsHeight, "Expected height %lu, got %u.\n",
5766 old_devmode.dmPelsHeight, d3ddm.Height);
5767 ret = restore_display_modes(original_modes, display_count);
5768 ok(ret, "Failed to restore display modes.\n");
5770 /* Test that mode restorations for non-primary monitors use display settings in the registry */
5771 device = create_device(d3d9, device_window, &device_desc);
5772 ok(!!device, "Failed to create a D3D device.\n");
5774 change_ret = ChangeDisplaySettingsExW(second_monitor_name, &devmode, NULL,
5775 CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
5776 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret);
5778 refcount = IDirect3DDevice9_Release(device);
5779 ok(!refcount, "Device has %lu references left.\n", refcount);
5781 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
5782 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5783 ok(devmode2.dmPelsWidth == devmode.dmPelsWidth && devmode2.dmPelsHeight == devmode.dmPelsHeight,
5784 "Expected resolution %lux%lu, got %lux%lu.\n", devmode.dmPelsWidth, devmode.dmPelsHeight,
5785 devmode2.dmPelsWidth, devmode2.dmPelsHeight);
5786 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_REGISTRY_SETTINGS, &devmode2);
5787 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5788 ok(devmode2.dmPelsWidth == devmode.dmPelsWidth && devmode2.dmPelsHeight == devmode.dmPelsHeight,
5789 "Expected resolution %lux%lu, got %lux%lu.\n", devmode.dmPelsWidth, devmode.dmPelsHeight,
5790 devmode2.dmPelsWidth, devmode2.dmPelsHeight);
5791 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, 1, &d3ddm);
5792 ok(hr == S_OK, "GetAdapterDisplayMode failed, hr %#lx.\n", hr);
5793 ok(d3ddm.Width == devmode.dmPelsWidth && d3ddm.Height == devmode.dmPelsHeight,
5794 "Expected resolution %lux%lu, got %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight,
5795 d3ddm.Width, d3ddm.Height);
5796 ret = restore_display_modes(original_modes, display_count);
5797 ok(ret, "Failed to restore display modes.\n");
5799 /* Test mode restorations when there are two fullscreen devices and one of them got reset */
5800 device = create_device(d3d9, focus_window, &device_desc);
5801 ok(!!device, "Failed to create a D3D device.\n");
5803 device_desc2.adapter_ordinal = 1;
5804 device_desc2.device_window = device_window;
5805 device_desc2.width = d3d_width;
5806 device_desc2.height = d3d_height;
5807 device_desc2.flags = CREATE_DEVICE_FULLSCREEN;
5808 device2 = create_device(d3d9, focus_window, &device_desc2);
5809 ok(!!device2, "Failed to create a D3D device.\n");
5811 change_ret = ChangeDisplaySettingsExW(second_monitor_name, &devmode, NULL, CDS_RESET, NULL);
5812 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret);
5814 device_desc.flags = 0;
5815 hr = reset_device(device, &device_desc);
5816 ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr);
5818 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
5819 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5820 ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
5821 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_REGISTRY_SETTINGS, &devmode2);
5822 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5823 ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
5824 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, 1, &d3ddm);
5825 ok(hr == S_OK, "GetAdapterDisplayMode failed, hr %#lx.\n", hr);
5826 ok(d3ddm.Width == old_devmode.dmPelsWidth && d3ddm.Height == old_devmode.dmPelsHeight,
5827 "Expected resolution %lux%lu, got %ux%u.\n", old_devmode.dmPelsWidth,
5828 old_devmode.dmPelsHeight, d3ddm.Width, d3ddm.Height);
5830 refcount = IDirect3DDevice9_Release(device2);
5831 ok(!refcount, "Device has %lu references left.\n", refcount);
5832 refcount = IDirect3DDevice9_Release(device);
5833 ok(!refcount, "Device has %lu references left.\n", refcount);
5834 ret = restore_display_modes(original_modes, display_count);
5835 ok(ret, "Failed to restore display modes.\n");
5837 /* Test mode restoration when there are two fullscreen devices and one of them got released */
5838 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5839 device = create_device(d3d9, focus_window, &device_desc);
5840 ok(!!device, "Failed to create a D3D device.\n");
5841 device2 = create_device(d3d9, focus_window, &device_desc2);
5842 ok(!!device2, "Failed to create a D3D device.\n");
5844 change_ret = ChangeDisplaySettingsExW(second_monitor_name, &devmode, NULL, CDS_RESET, NULL);
5845 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret);
5847 refcount = IDirect3DDevice9_Release(device);
5848 ok(!refcount, "Device has %lu references left.\n", refcount);
5850 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
5851 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5852 ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
5853 ret = EnumDisplaySettingsW(second_monitor_name, ENUM_REGISTRY_SETTINGS, &devmode2);
5854 ok(ret, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
5855 ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
5856 hr = IDirect3D9_GetAdapterDisplayMode(d3d9, 1, &d3ddm);
5857 ok(hr == S_OK, "GetAdapterDisplayMode failed, hr %#lx.\n", hr);
5858 ok(d3ddm.Width == old_devmode.dmPelsWidth && d3ddm.Height == old_devmode.dmPelsHeight,
5859 "Expected resolution %lux%lu, got %ux%u.\n", old_devmode.dmPelsWidth,
5860 old_devmode.dmPelsHeight, d3ddm.Width, d3ddm.Height);
5862 refcount = IDirect3DDevice9_Release(device2);
5863 ok(!refcount, "Device has %lu references left.\n", refcount);
5865 done:
5866 DestroyWindow(device_window);
5867 DestroyWindow(focus_window);
5868 IDirect3D9_Release(d3d9);
5869 ret = restore_display_modes(original_modes, display_count);
5870 ok(ret, "Failed to restore display modes.\n");
5871 free(original_modes);
5874 static void test_device_window_reset(void)
5876 RECT fullscreen_rect, device_rect, r;
5877 struct device_desc device_desc;
5878 IDirect3DDevice9 *device;
5879 WNDCLASSA wc = {0};
5880 IDirect3D9 *d3d9;
5881 LONG_PTR proc;
5882 HRESULT hr;
5883 ULONG ref;
5885 filter_messages = NULL;
5886 expect_messages = NULL;
5888 wc.lpfnWndProc = test_proc;
5889 wc.lpszClassName = "d3d9_test_wndproc_wc";
5890 ok(RegisterClassA(&wc), "Failed to register window class.\n");
5892 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5893 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
5894 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5895 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
5896 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5897 ok(!!d3d9, "Failed to create a D3D object.\n");
5899 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
5900 GetWindowRect(device_window, &device_rect);
5902 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
5903 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
5904 (LONG_PTR)test_proc, proc);
5905 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
5906 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
5907 (LONG_PTR)test_proc, proc);
5909 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
5910 device_desc.device_window = NULL;
5911 device_desc.width = registry_mode.dmPelsWidth;
5912 device_desc.height = registry_mode.dmPelsHeight;
5913 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5914 if (!(device = create_device(d3d9, focus_window, &device_desc)))
5916 skip("Failed to create a D3D device, skipping tests.\n");
5917 goto done;
5920 GetWindowRect(focus_window, &r);
5921 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
5922 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
5923 GetWindowRect(device_window, &r);
5924 ok(EqualRect(&r, &device_rect), "Expected %s, got %s.\n",
5925 wine_dbgstr_rect(&device_rect), wine_dbgstr_rect(&r));
5927 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
5928 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
5929 (LONG_PTR)test_proc, proc);
5930 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
5931 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#Ix.\n", (LONG_PTR)test_proc);
5933 device_desc.device_window = device_window;
5934 hr = reset_device(device, &device_desc);
5935 ok(SUCCEEDED(hr), "Failed to reset device.\n");
5937 GetWindowRect(focus_window, &r);
5938 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
5939 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
5940 GetWindowRect(device_window, &r);
5941 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
5942 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
5944 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
5945 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
5946 (LONG_PTR)test_proc, proc);
5947 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
5948 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#Ix.\n", (LONG_PTR)test_proc);
5950 ref = IDirect3DDevice9_Release(device);
5951 ok(!ref, "Unexpected refcount %lu.\n", ref);
5953 done:
5954 IDirect3D9_Release(d3d9);
5955 DestroyWindow(device_window);
5956 DestroyWindow(focus_window);
5957 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
5960 static void test_reset_resources(void)
5962 IDirect3DSurface9 *surface, *rt;
5963 IDirect3DTexture9 *texture;
5964 IDirect3DDevice9 *device;
5965 IDirect3D9 *d3d9;
5966 unsigned int i;
5967 D3DCAPS9 caps;
5968 HWND window;
5969 HRESULT hr;
5970 ULONG ref;
5972 window = create_window();
5973 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5974 ok(!!d3d9, "Failed to create a D3D object.\n");
5976 if (!(device = create_device(d3d9, window, NULL)))
5978 skip("Failed to create a D3D device, skipping tests.\n");
5979 goto done;
5982 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5983 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
5985 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128,
5986 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
5987 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#lx.\n", hr);
5988 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
5989 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#lx.\n", hr);
5990 IDirect3DSurface9_Release(surface);
5992 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
5994 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
5995 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5996 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#lx.\n", i, hr);
5997 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5998 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#lx.\n", i, hr);
5999 IDirect3DTexture9_Release(texture);
6000 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
6001 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#lx.\n", i, hr);
6002 IDirect3DSurface9_Release(surface);
6005 hr = reset_device(device, NULL);
6006 ok(SUCCEEDED(hr), "Failed to reset device.\n");
6008 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
6009 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
6010 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
6011 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#lx.\n", hr);
6012 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
6013 IDirect3DSurface9_Release(surface);
6014 IDirect3DSurface9_Release(rt);
6016 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
6018 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
6019 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#lx.\n", hr);
6022 ref = IDirect3DDevice9_Release(device);
6023 ok(!ref, "Unexpected refcount %lu.\n", ref);
6025 done:
6026 IDirect3D9_Release(d3d9);
6027 DestroyWindow(window);
6030 static void test_set_rt_vp_scissor(void)
6032 IDirect3DStateBlock9 *stateblock;
6033 IDirect3DDevice9 *device;
6034 IDirect3DSurface9 *rt;
6035 IDirect3D9 *d3d9;
6036 D3DVIEWPORT9 vp;
6037 ULONG refcount;
6038 HWND window;
6039 HRESULT hr;
6040 RECT rect;
6042 window = create_window();
6043 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6044 ok(!!d3d9, "Failed to create a D3D object.\n");
6045 if (!(device = create_device(d3d9, window, NULL)))
6047 skip("Failed to create a D3D device, skipping tests.\n");
6048 DestroyWindow(window);
6049 return;
6052 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
6053 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
6054 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
6056 hr = IDirect3DDevice9_GetViewport(device, &vp);
6057 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#lx.\n", hr);
6058 ok(!vp.X, "Got unexpected vp.X %lu.\n", vp.X);
6059 ok(!vp.Y, "Got unexpected vp.Y %lu.\n", vp.Y);
6060 ok(vp.Width == 640, "Got unexpected vp.Width %lu.\n", vp.Width);
6061 ok(vp.Height == 480, "Got unexpected vp.Height %lu.\n", vp.Height);
6062 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
6063 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
6065 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
6066 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#lx.\n", hr);
6067 ok(rect.left == 0 && rect.top == 0 && rect.right == 640 && rect.bottom == 480,
6068 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
6070 hr = IDirect3DDevice9_BeginStateBlock(device);
6071 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#lx.\n", hr);
6073 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
6074 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
6076 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
6077 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#lx.\n", hr);
6078 IDirect3DStateBlock9_Release(stateblock);
6080 hr = IDirect3DDevice9_GetViewport(device, &vp);
6081 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#lx.\n", hr);
6082 ok(!vp.X, "Got unexpected vp.X %lu.\n", vp.X);
6083 ok(!vp.Y, "Got unexpected vp.Y %lu.\n", vp.Y);
6084 ok(vp.Width == 128, "Got unexpected vp.Width %lu.\n", vp.Width);
6085 ok(vp.Height == 128, "Got unexpected vp.Height %lu.\n", vp.Height);
6086 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
6087 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
6089 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
6090 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#lx.\n", hr);
6091 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
6092 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
6094 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
6095 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
6097 vp.X = 10;
6098 vp.Y = 20;
6099 vp.Width = 30;
6100 vp.Height = 40;
6101 vp.MinZ = 0.25f;
6102 vp.MaxZ = 0.75f;
6103 hr = IDirect3DDevice9_SetViewport(device, &vp);
6104 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#lx.\n", hr);
6106 SetRect(&rect, 50, 60, 70, 80);
6107 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
6108 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#lx.\n", hr);
6110 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
6111 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
6113 hr = IDirect3DDevice9_GetViewport(device, &vp);
6114 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#lx.\n", hr);
6115 ok(!vp.X, "Got unexpected vp.X %lu.\n", vp.X);
6116 ok(!vp.Y, "Got unexpected vp.Y %lu.\n", vp.Y);
6117 ok(vp.Width == 128, "Got unexpected vp.Width %lu.\n", vp.Width);
6118 ok(vp.Height == 128, "Got unexpected vp.Height %lu.\n", vp.Height);
6119 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
6120 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
6122 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
6123 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#lx.\n", hr);
6124 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
6125 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
6127 IDirect3DSurface9_Release(rt);
6128 refcount = IDirect3DDevice9_Release(device);
6129 ok(!refcount, "Device has %lu references left.\n", refcount);
6130 IDirect3D9_Release(d3d9);
6131 DestroyWindow(window);
6134 static void test_volume_get_container(void)
6136 IDirect3DVolumeTexture9 *texture = NULL;
6137 IDirect3DVolume9 *volume = NULL;
6138 IDirect3DDevice9 *device;
6139 IUnknown *container;
6140 IDirect3D9 *d3d9;
6141 ULONG refcount;
6142 D3DCAPS9 caps;
6143 HWND window;
6144 HRESULT hr;
6146 window = create_window();
6147 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6148 ok(!!d3d9, "Failed to create a D3D object.\n");
6149 if (!(device = create_device(d3d9, window, NULL)))
6151 skip("Failed to create a D3D device, skipping tests.\n");
6152 IDirect3D9_Release(d3d9);
6153 DestroyWindow(window);
6154 return;
6157 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6158 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6159 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
6161 skip("No volume texture support, skipping tests.\n");
6162 IDirect3DDevice9_Release(device);
6163 IDirect3D9_Release(d3d9);
6164 DestroyWindow(window);
6165 return;
6168 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
6169 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
6170 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
6171 ok(!!texture, "Got unexpected texture %p.\n", texture);
6173 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
6174 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#lx.\n", hr);
6175 ok(!!volume, "Got unexpected volume %p.\n", volume);
6177 /* These should work... */
6178 container = NULL;
6179 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
6180 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#lx.\n", hr);
6181 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6182 IUnknown_Release(container);
6184 container = NULL;
6185 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
6186 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#lx.\n", hr);
6187 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6188 IUnknown_Release(container);
6190 container = NULL;
6191 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
6192 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#lx.\n", hr);
6193 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6194 IUnknown_Release(container);
6196 container = NULL;
6197 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
6198 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#lx.\n", hr);
6199 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6200 IUnknown_Release(container);
6202 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
6203 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
6204 ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr);
6205 ok(!container, "Got unexpected container %p.\n", container);
6207 IDirect3DVolume9_Release(volume);
6208 IDirect3DVolumeTexture9_Release(texture);
6209 refcount = IDirect3DDevice9_Release(device);
6210 ok(!refcount, "Device has %lu references left.\n", refcount);
6211 IDirect3D9_Release(d3d9);
6212 DestroyWindow(window);
6215 static void test_volume_resource(void)
6217 IDirect3DVolumeTexture9 *texture;
6218 IDirect3DResource9 *resource;
6219 IDirect3DVolume9 *volume;
6220 IDirect3DDevice9 *device;
6221 IDirect3D9 *d3d9;
6222 ULONG refcount;
6223 D3DCAPS9 caps;
6224 HWND window;
6225 HRESULT hr;
6227 window = create_window();
6228 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6229 ok(!!d3d9, "Failed to create a D3D object.\n");
6230 if (!(device = create_device(d3d9, window, NULL)))
6232 skip("Failed to create a D3D device, skipping tests.\n");
6233 IDirect3D9_Release(d3d9);
6234 DestroyWindow(window);
6235 return;
6238 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6239 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6240 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
6242 skip("No volume texture support, skipping tests.\n");
6243 IDirect3DDevice9_Release(device);
6244 IDirect3D9_Release(d3d9);
6245 DestroyWindow(window);
6246 return;
6249 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
6250 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
6251 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
6252 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
6253 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#lx.\n", hr);
6254 IDirect3DVolumeTexture9_Release(texture);
6256 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
6257 ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr);
6259 IDirect3DVolume9_Release(volume);
6260 refcount = IDirect3DDevice9_Release(device);
6261 ok(!refcount, "Device has %lu references left.\n", refcount);
6262 IDirect3D9_Release(d3d9);
6263 DestroyWindow(window);
6266 static void test_vb_lock_flags(void)
6268 static const struct
6270 DWORD flags;
6271 const char *debug_string;
6272 HRESULT win7_result;
6274 test_data[] =
6276 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
6277 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
6278 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
6279 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
6280 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
6281 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
6282 /* Completely bogus flags aren't an error. */
6283 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
6285 IDirect3DVertexBuffer9 *buffer;
6286 IDirect3DDevice9 *device;
6287 IDirect3D9 *d3d9;
6288 unsigned int i;
6289 ULONG refcount;
6290 HWND window;
6291 HRESULT hr;
6292 void *data;
6294 window = create_window();
6295 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6296 ok(!!d3d9, "Failed to create a D3D object.\n");
6297 if (!(device = create_device(d3d9, window, NULL)))
6299 skip("Failed to create a D3D device, skipping tests.\n");
6300 IDirect3D9_Release(d3d9);
6301 DestroyWindow(window);
6302 return;
6305 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
6306 0, D3DPOOL_DEFAULT, &buffer, NULL);
6307 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
6309 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
6311 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
6312 /* Windows XP always returns D3D_OK even with flags that don't make
6313 * sense. Windows 7 returns an error. At least one game (Shaiya)
6314 * depends on the Windows XP result, so mark the Windows 7 behavior as
6315 * broken. */
6316 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#lx for %s.\n",
6317 hr, test_data[i].debug_string);
6318 if (SUCCEEDED(hr))
6320 ok(!!data, "Got unexpected data %p.\n", data);
6321 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6322 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
6326 IDirect3DVertexBuffer9_Release(buffer);
6327 refcount = IDirect3DDevice9_Release(device);
6328 ok(!refcount, "Device has %lu references left.\n", refcount);
6329 IDirect3D9_Release(d3d9);
6330 DestroyWindow(window);
6333 static const char *debug_d3dpool(D3DPOOL pool)
6335 switch (pool)
6337 case D3DPOOL_DEFAULT:
6338 return "D3DPOOL_DEFAULT";
6339 case D3DPOOL_SYSTEMMEM:
6340 return "D3DPOOL_SYSTEMMEM";
6341 case D3DPOOL_SCRATCH:
6342 return "D3DPOOL_SCRATCH";
6343 case D3DPOOL_MANAGED:
6344 return "D3DPOOL_MANAGED";
6345 default:
6346 return "unknown pool";
6350 static void test_vertex_buffer_alignment(void)
6352 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
6353 static const unsigned int sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
6354 IDirect3DVertexBuffer9 *buffer = NULL;
6355 const unsigned int align = 16;
6356 IDirect3DDevice9 *device;
6357 unsigned int i, j;
6358 IDirect3D9 *d3d9;
6359 ULONG refcount;
6360 HWND window;
6361 HRESULT hr;
6362 void *data;
6364 window = create_window();
6365 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6366 ok(!!d3d9, "Failed to create a D3D object.\n");
6367 if (!(device = create_device(d3d9, window, NULL)))
6369 skip("Failed to create a D3D device, skipping tests.\n");
6370 IDirect3D9_Release(d3d9);
6371 DestroyWindow(window);
6372 return;
6375 for (i = 0; i < ARRAY_SIZE(sizes); ++i)
6377 for (j = 0; j < ARRAY_SIZE(pools); ++j)
6379 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
6380 if (pools[j] == D3DPOOL_SCRATCH)
6381 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
6382 else
6383 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#lx.\n",
6384 debug_d3dpool(pools[j]), sizes[i], hr);
6385 if (FAILED(hr))
6386 continue;
6388 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
6389 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
6390 ok(!((DWORD_PTR)data & (align - 1)),
6391 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
6392 data, align, sizes[i], debug_d3dpool(pools[j]));
6393 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6394 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
6395 IDirect3DVertexBuffer9_Release(buffer);
6399 refcount = IDirect3DDevice9_Release(device);
6400 ok(!refcount, "Device has %lu references left.\n", refcount);
6401 IDirect3D9_Release(d3d9);
6402 DestroyWindow(window);
6405 static void test_query_support(void)
6407 static const D3DQUERYTYPE queries[] =
6409 D3DQUERYTYPE_VCACHE,
6410 D3DQUERYTYPE_RESOURCEMANAGER,
6411 D3DQUERYTYPE_VERTEXSTATS,
6412 D3DQUERYTYPE_EVENT,
6413 D3DQUERYTYPE_OCCLUSION,
6414 D3DQUERYTYPE_TIMESTAMP,
6415 D3DQUERYTYPE_TIMESTAMPDISJOINT,
6416 D3DQUERYTYPE_TIMESTAMPFREQ,
6417 D3DQUERYTYPE_PIPELINETIMINGS,
6418 D3DQUERYTYPE_INTERFACETIMINGS,
6419 D3DQUERYTYPE_VERTEXTIMINGS,
6420 D3DQUERYTYPE_PIXELTIMINGS,
6421 D3DQUERYTYPE_BANDWIDTHTIMINGS,
6422 D3DQUERYTYPE_CACHEUTILIZATION,
6424 IDirect3DQuery9 *query = NULL;
6425 IDirect3DDevice9 *device;
6426 IDirect3D9 *d3d9;
6427 unsigned int i;
6428 ULONG refcount;
6429 BOOL supported;
6430 HWND window;
6431 HRESULT hr;
6433 window = create_window();
6434 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6435 ok(!!d3d9, "Failed to create a D3D object.\n");
6436 if (!(device = create_device(d3d9, window, NULL)))
6438 skip("Failed to create a D3D device, skipping tests.\n");
6439 IDirect3D9_Release(d3d9);
6440 DestroyWindow(window);
6441 return;
6444 for (i = 0; i < ARRAY_SIZE(queries); ++i)
6446 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
6447 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx for query %#x.\n", hr, queries[i]);
6449 supported = hr == D3D_OK;
6451 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
6452 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx for query %#x.\n", hr, queries[i]);
6454 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
6455 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
6457 if (query)
6459 IDirect3DQuery9_Release(query);
6460 query = NULL;
6464 for (i = 0; i < 40; ++i)
6466 /* Windows 10 17.09 (build 16299.19) added an undocumented query with an enum value of 0x16 (=22).
6467 * It returns D3D_OK when asking for support and E_FAIL when trying to actually create it. */
6468 if ((D3DQUERYTYPE_VCACHE <= i && i <= D3DQUERYTYPE_MEMORYPRESSURE) || i == 0x16)
6469 continue;
6471 hr = IDirect3DDevice9_CreateQuery(device, i, NULL);
6472 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx for query %#x.\n", hr, i);
6474 query = (IDirect3DQuery9 *)0xdeadbeef;
6475 hr = IDirect3DDevice9_CreateQuery(device, i, &query);
6476 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx for query %#x.\n", hr, i);
6477 ok(query == (IDirect3DQuery9 *)0xdeadbeef, "Got unexpected query %p.\n", query);
6480 refcount = IDirect3DDevice9_Release(device);
6481 ok(!refcount, "Device has %lu references left.\n", refcount);
6482 IDirect3D9_Release(d3d9);
6483 DestroyWindow(window);
6486 static void test_occlusion_query(void)
6488 static const float quad[] =
6490 -1.0f, -1.0f, 0.0f,
6491 -1.0f, 1.0f, 0.0f,
6492 1.0f, 1.0f, 0.0f,
6493 1.0f, -1.0f, 0.0f,
6495 unsigned int data_size, i, count;
6496 struct device_desc device_desc;
6497 LARGE_INTEGER start, end, freq;
6498 IDirect3DQuery9 *query = NULL;
6499 IDirect3DDevice9 *device;
6500 IDirect3DSurface9 *rt;
6501 IDirect3D9 *d3d9;
6502 D3DVIEWPORT9 vp;
6503 ULONG refcount;
6504 D3DCAPS9 caps;
6505 DWORD elapsed;
6506 HWND window;
6507 HRESULT hr;
6508 union
6510 WORD word[4];
6511 unsigned int dword[2];
6512 UINT64 uint;
6513 } data, expected;
6514 BOOL broken_occlusion = FALSE;
6515 expected.uint = registry_mode.dmPelsWidth * registry_mode.dmPelsHeight;
6516 QueryPerformanceFrequency(&freq);
6518 window = create_window();
6519 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6520 ok(!!d3d9, "Failed to create a D3D object.\n");
6521 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
6522 device_desc.device_window = window;
6523 device_desc.width = registry_mode.dmPelsWidth;
6524 device_desc.height = registry_mode.dmPelsHeight;
6525 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
6526 if (!(device = create_device(d3d9, window, &device_desc)))
6528 skip("Failed to create a D3D device, skipping tests.\n");
6529 IDirect3D9_Release(d3d9);
6530 DestroyWindow(window);
6531 return;
6534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
6535 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6536 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6537 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6538 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6539 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6541 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
6542 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
6543 if (!query)
6545 skip("Occlusion queries are not supported, skipping tests.\n");
6546 IDirect3DDevice9_Release(device);
6547 IDirect3D9_Release(d3d9);
6548 DestroyWindow(window);
6549 return;
6552 data_size = IDirect3DQuery9_GetDataSize(query);
6553 ok(data_size == sizeof(DWORD), "Unexpected data size %u.\n", data_size);
6555 memset(&data, 0xff, sizeof(data));
6556 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
6557 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6558 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
6559 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6560 ok(data.dword[0] == 0xdddddddd && data.dword[1] == 0xffffffff,
6561 "Got unexpected query result 0x%08x%08x.\n", data.dword[1], data.dword[0]);
6563 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6564 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6565 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
6566 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6567 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
6568 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6570 data.dword[0] = 0x12345678;
6571 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
6572 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6573 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
6574 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6575 if (hr == D3D_OK)
6576 ok(!data.dword[0], "Got unexpected query result %u.\n", data.dword[0]);
6578 hr = IDirect3DDevice9_BeginScene(device);
6579 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
6581 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6582 hr = IDirect3DDevice9_EndScene(device);
6583 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6585 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6586 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6588 wait_query(query);
6590 memset(&data, 0xff, sizeof(data));
6591 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
6592 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6593 ok(data.dword[0] == expected.dword[0] || broken(!data.dword[0]),
6594 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
6595 if (!data.dword[0])
6597 win_skip("Occlusion query result looks broken, ignoring returned count.\n");
6598 broken_occlusion = TRUE;
6601 memset(&data, 0xff, sizeof(data));
6602 hr = IDirect3DQuery9_GetData(query, &data, sizeof(WORD), D3DGETDATA_FLUSH);
6603 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6604 if (!broken_occlusion)
6605 ok(data.word[0] == expected.word[0],
6606 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
6607 ok(data.word[1] == 0xffff,
6608 "Data was modified outside of the expected size (0x%.8x).\n", data.dword[0]);
6610 memset(&data, 0xf0, sizeof(data));
6611 hr = IDirect3DQuery9_GetData(query, &data, sizeof(data), D3DGETDATA_FLUSH);
6612 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6613 if (!broken_occlusion)
6614 ok(data.dword[0] == expected.dword[0],
6615 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
6616 /* Different drivers seem to return different data in those high bytes on Windows, but they all
6617 write something there and the extra data is consistent (I've seen 0x00000000 and 0xdddddddd
6618 on AMD and Nvidia respectively). */
6619 if (0)
6621 ok(data.dword[1] != 0xf0f0f0f0, "high bytes of data were not modified (0x%.8x).\n",
6622 data.dword[1]);
6625 memset(&data, 0xff, sizeof(data));
6626 hr = IDirect3DQuery9_GetData(query, &data, 0, D3DGETDATA_FLUSH);
6627 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6628 ok(data.dword[0] == 0xffffffff, "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
6630 /* This crashes on Windows. */
6631 if (0)
6633 hr = IDirect3DQuery9_GetData(query, NULL, data_size, D3DGETDATA_FLUSH);
6634 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6637 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
6638 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6639 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6640 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6641 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6642 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6644 if (broken_occlusion)
6645 goto done;
6647 /* On my system (MacBookPro14,3 - Radeon 560M, i7-7920HQ), this loop
6648 * takes about 20 ms with HW rendering and 160 ms with mesa software.
6649 * I can't reliably read timings smaller than 20 ms though, so don't
6650 * reduce the test count too much.
6652 * wait_query() times out after 5 seconds, so if the 1000 iteration
6653 * loop takes more than 100 ms the full test is bound to fail. I put
6654 * it to 70 ms below to avoid flaky failures if e.g. a CI machine
6655 * has CPU load from other processes. */
6656 QueryPerformanceCounter(&start);
6657 hr = IDirect3DDevice9_BeginScene(device);
6658 ok(hr == D3D_OK, "Failed to begin scene, hr %#lx.\n", hr);
6659 for (i = 0; i < 1000; ++i)
6661 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
6662 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6663 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6664 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6666 hr = IDirect3DDevice9_EndScene(device);
6667 ok(hr == D3D_OK, "Failed to end scene, hr %#lx.\n", hr);
6669 wait_query(query);
6670 QueryPerformanceCounter(&end);
6672 elapsed = (end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart;
6674 if (elapsed > 70)
6676 skip("Test loop took too long (%lu ms), skipping large query tests.\n", elapsed);
6677 goto done;
6680 hr = IDirect3DDevice9_BeginScene(device);
6681 ok(hr == D3D_OK, "Failed to begin scene, hr %#lx.\n", hr);
6682 for (i = 0; i < 50000; ++i)
6684 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
6685 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6686 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6687 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6689 hr = IDirect3DDevice9_EndScene(device);
6690 ok(hr == D3D_OK, "Failed to end scene, hr %#lx.\n", hr);
6692 wait_query(query);
6694 memset(&data, 0xff, sizeof(data));
6695 hr = IDirect3DQuery9_GetData(query, &data, sizeof(data), D3DGETDATA_FLUSH);
6696 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6697 ok(data.dword[0] == 0 && data.dword[1] == 0,
6698 "Got unexpected query result 0x%08x%08x.\n", data.dword[1], data.dword[0]);
6700 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6701 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6703 vp.X = 0;
6704 vp.Y = 0;
6705 vp.Width = min(caps.MaxTextureWidth, 8192);
6706 vp.Height = min(caps.MaxTextureHeight, 8192);
6707 vp.MinZ = 0.0f;
6708 vp.MaxZ = 1.0f;
6709 hr = IDirect3DDevice9_SetViewport(device, &vp);
6710 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#lx.\n", hr);
6712 hr = IDirect3DDevice9_CreateRenderTarget(device, vp.Width, vp.Height,
6713 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
6714 if (FAILED(hr))
6716 skip("Failed to create render target (width %lu, height %lu), hr %#lx.\n", vp.Width, vp.Height, hr);
6717 goto done;
6719 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
6720 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
6721 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
6722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
6723 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6725 expected.uint = vp.Width * vp.Height;
6726 count = ((((UINT64)~0u) + 1) / expected.uint) + 1;
6727 expected.uint *= count;
6729 trace("Expects 0x%08x%08x samples.\n", expected.dword[1], expected.dword[0]);
6731 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
6732 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6733 hr = IDirect3DDevice9_BeginScene(device);
6734 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6735 for (i = 0; i < count; i++)
6737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
6738 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6740 hr = IDirect3DDevice9_EndScene(device);
6741 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6742 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6743 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6745 wait_query(query);
6747 memset(&data, 0xff, sizeof(data));
6748 hr = IDirect3DQuery9_GetData(query, &data, sizeof(data), D3DGETDATA_FLUSH);
6749 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6750 ok((data.dword[0] == expected.dword[0] && data.dword[1] == expected.dword[1])
6751 || (data.dword[0] == 0xffffffff && !data.dword[1])
6752 || broken(data.dword[0] < 0xffffffff && !data.dword[1]),
6753 "Got unexpected query result 0x%08x%08x.\n", data.dword[1], data.dword[0]);
6755 IDirect3DSurface9_Release(rt);
6757 done:
6758 IDirect3DQuery9_Release(query);
6759 refcount = IDirect3DDevice9_Release(device);
6760 ok(!refcount, "Device has %lu references left.\n", refcount);
6761 IDirect3D9_Release(d3d9);
6762 DestroyWindow(window);
6765 static void test_timestamp_query(void)
6767 static const float quad[] =
6769 -1.0f, -1.0f, 0.0f,
6770 -1.0f, 1.0f, 0.0f,
6771 1.0f, 1.0f, 0.0f,
6772 1.0f, -1.0f, 0.0f,
6774 IDirect3DQuery9 *query, *disjoint_query, *freq_query;
6775 unsigned int data_size, timestamp[2], freq[2];
6776 IDirect3DDevice9 *device;
6777 IDirect3D9 *d3d9;
6778 ULONG refcount;
6779 HWND window;
6780 HRESULT hr;
6781 WORD disjoint[2];
6783 window = create_window();
6784 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6785 ok(!!d3d9, "Failed to create a D3D object.\n");
6786 if (!(device = create_device(d3d9, window, NULL)))
6788 skip("Failed to create a D3D device, skipping tests.\n");
6789 IDirect3D9_Release(d3d9);
6790 DestroyWindow(window);
6791 return;
6794 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPFREQ, &freq_query);
6795 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
6796 if (FAILED(hr))
6798 skip("Timestamp queries are not supported, skipping tests.\n");
6799 IDirect3DDevice9_Release(device);
6800 IDirect3D9_Release(d3d9);
6801 DestroyWindow(window);
6802 return;
6804 data_size = IDirect3DQuery9_GetDataSize(freq_query);
6805 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
6807 memset(freq, 0xff, sizeof(freq));
6808 hr = IDirect3DQuery9_GetData(freq_query, NULL, 0, D3DGETDATA_FLUSH);
6809 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6810 hr = IDirect3DQuery9_GetData(freq_query, freq, sizeof(DWORD), D3DGETDATA_FLUSH);
6811 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6812 ok(freq[0] == 0xdddddddd && freq[1] == 0xffffffff,
6813 "Got unexpected query result 0x%08x%08x.\n", freq[1], freq[0]);
6815 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPDISJOINT, &disjoint_query);
6816 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6817 data_size = IDirect3DQuery9_GetDataSize(disjoint_query);
6818 ok(data_size == sizeof(BOOL), "Query data size is %u, 4 expected.\n", data_size);
6820 memset(disjoint, 0xff, sizeof(disjoint));
6821 hr = IDirect3DQuery9_GetData(disjoint_query, NULL, 0, D3DGETDATA_FLUSH);
6822 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6823 hr = IDirect3DQuery9_GetData(disjoint_query, &disjoint, sizeof(WORD), D3DGETDATA_FLUSH);
6824 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6825 ok(disjoint[0] == 0xdddd && disjoint[1] == 0xffff,
6826 "Got unexpected query result 0x%04x%04x.\n", disjoint[1], disjoint[0]);
6827 hr = IDirect3DQuery9_GetData(disjoint_query, &disjoint, sizeof(DWORD), D3DGETDATA_FLUSH);
6828 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6829 ok(disjoint[0] == 0xdddd && disjoint[1] == 0xdddd,
6830 "Got unexpected query result 0x%04x%04x.\n", disjoint[1], disjoint[0]);
6832 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMP, &query);
6833 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6834 data_size = IDirect3DQuery9_GetDataSize(query);
6835 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
6837 hr = IDirect3DQuery9_Issue(freq_query, D3DISSUE_END);
6839 wait_query(freq_query);
6841 memset(freq, 0xff, sizeof(freq));
6842 hr = IDirect3DQuery9_GetData(freq_query, freq, sizeof(DWORD), D3DGETDATA_FLUSH);
6843 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6844 ok(freq[1] == 0xffffffff,
6845 "Freq was modified outside of the expected size (0x%.8x).\n", freq[1]);
6846 hr = IDirect3DQuery9_GetData(freq_query, &freq, sizeof(freq), D3DGETDATA_FLUSH);
6847 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6848 ok(freq[1] != 0xffffffff, "High bytes of freq were not modified (0x%.8x).\n",
6849 freq[1]);
6851 memset(timestamp, 0xff, sizeof(timestamp));
6852 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
6853 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6854 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(DWORD), D3DGETDATA_FLUSH);
6855 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6856 ok(timestamp[0] == 0xdddddddd && timestamp[1] == 0xffffffff,
6857 "Got unexpected query result 0x%08x%08x.\n", timestamp[1], timestamp[0]);
6858 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
6859 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6860 ok(timestamp[0] == 0xdddddddd && timestamp[1] == 0xdddddddd,
6861 "Got unexpected query result 0x%08x%08x.\n", timestamp[1], timestamp[0]);
6863 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
6864 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6865 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
6866 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6867 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
6868 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6870 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
6871 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6873 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6874 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6875 hr = IDirect3DDevice9_BeginScene(device);
6876 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
6878 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6879 hr = IDirect3DDevice9_EndScene(device);
6880 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6882 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6883 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6885 wait_query(query);
6887 memset(timestamp, 0xff, sizeof(timestamp));
6888 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(DWORD), D3DGETDATA_FLUSH);
6889 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6890 ok(timestamp[1] == 0xffffffff,
6891 "Timestamp was modified outside of the expected size (0x%.8x).\n",
6892 timestamp[1]);
6894 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
6895 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6896 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6897 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6898 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6899 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6901 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
6902 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6904 wait_query(disjoint_query);
6906 memset(disjoint, 0xff, sizeof(disjoint));
6907 hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(WORD), D3DGETDATA_FLUSH);
6908 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6909 ok(disjoint[1] == 0xffff,
6910 "Disjoint was modified outside of the expected size (0x%.4hx).\n", disjoint[1]);
6911 hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(disjoint), D3DGETDATA_FLUSH);
6912 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6913 ok(disjoint[1] != 0xffff, "High bytes of disjoint were not modified (0x%.4hx).\n", disjoint[1]);
6915 /* It's not strictly necessary for the TIMESTAMP query to be inside
6916 * a TIMESTAMP_DISJOINT query. */
6917 hr = IDirect3DDevice9_BeginScene(device);
6918 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6919 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
6920 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6921 hr = IDirect3DDevice9_EndScene(device);
6922 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6924 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
6925 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
6927 wait_query(query);
6929 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
6930 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
6932 IDirect3DQuery9_Release(query);
6933 IDirect3DQuery9_Release(disjoint_query);
6934 IDirect3DQuery9_Release(freq_query);
6935 refcount = IDirect3DDevice9_Release(device);
6936 ok(!refcount, "Device has %lu references left.\n", refcount);
6937 IDirect3D9_Release(d3d9);
6938 DestroyWindow(window);
6941 static void test_get_set_vertex_shader(void)
6943 IDirect3DVertexShader9 *current_shader = NULL;
6944 IDirect3DVertexShader9 *shader = NULL;
6945 const IDirect3DVertexShader9Vtbl *shader_vtbl;
6946 IDirect3DDevice9 *device;
6947 ULONG refcount, i;
6948 IDirect3D9 *d3d;
6949 D3DCAPS9 caps;
6950 HWND window;
6951 HRESULT hr;
6953 window = create_window();
6954 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6955 ok(!!d3d, "Failed to create a D3D object.\n");
6956 if (!(device = create_device(d3d, window, NULL)))
6958 skip("Failed to create a D3D device, skipping tests.\n");
6959 IDirect3D9_Release(d3d);
6960 DestroyWindow(window);
6961 return;
6964 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6965 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6966 if (!(caps.VertexShaderVersion & 0xffff))
6968 skip("No vertex shader support, skipping tests.\n");
6969 IDirect3DDevice9_Release(device);
6970 IDirect3D9_Release(d3d);
6971 DestroyWindow(window);
6972 return;
6975 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
6976 ok(SUCCEEDED(hr), "Failed to create shader, hr %#lx.\n", hr);
6977 ok(!!shader, "Got unexpected shader %p.\n", shader);
6979 /* SetVertexShader() should not touch the shader's refcount. */
6980 i = get_refcount((IUnknown *)shader);
6981 hr = IDirect3DDevice9_SetVertexShader(device, shader);
6982 refcount = get_refcount((IUnknown *)shader);
6983 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
6984 ok(refcount == i, "Got unexpected refcount %lu, expected %lu.\n", refcount, i);
6986 /* GetVertexShader() should increase the shader's refcount by one. */
6987 i = refcount + 1;
6988 hr = IDirect3DDevice9_GetVertexShader(device, &current_shader);
6989 refcount = get_refcount((IUnknown *)shader);
6990 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#lx.\n", hr);
6991 ok(refcount == i, "Got unexpected refcount %lu, expected %lu.\n", refcount, i);
6992 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
6993 IDirect3DVertexShader9_Release(current_shader);
6995 /* SetVertexShader() with a bogus shader vtbl */
6996 shader_vtbl = shader->lpVtbl;
6997 shader->lpVtbl = (IDirect3DVertexShader9Vtbl *)0xdeadbeef;
6998 hr = IDirect3DDevice9_SetVertexShader(device, shader);
6999 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7000 shader->lpVtbl = NULL;
7001 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7002 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7003 shader->lpVtbl = shader_vtbl;
7005 IDirect3DVertexShader9_Release(shader);
7006 refcount = IDirect3DDevice9_Release(device);
7007 ok(!refcount, "Device has %lu references left.\n", refcount);
7008 IDirect3D9_Release(d3d);
7009 DestroyWindow(window);
7012 static void test_vertex_shader_constant(void)
7014 static const float d[16] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
7015 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
7016 IDirect3DDevice9 *device;
7017 struct device_desc desc;
7018 DWORD consts_swvp;
7019 IDirect3D9 *d3d;
7020 ULONG refcount;
7021 D3DCAPS9 caps;
7022 DWORD consts;
7023 HWND window;
7024 HRESULT hr;
7026 window = create_window();
7027 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7028 ok(!!d3d, "Failed to create a D3D object.\n");
7029 if (!(device = create_device(d3d, window, NULL)))
7031 skip("Failed to create a D3D device, skipping tests.\n");
7032 IDirect3D9_Release(d3d);
7033 DestroyWindow(window);
7034 return;
7037 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7038 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7039 if (!(caps.VertexShaderVersion & 0xffff))
7041 skip("No vertex shader support, skipping tests.\n");
7042 IDirect3DDevice9_Release(device);
7043 IDirect3D9_Release(d3d);
7044 DestroyWindow(window);
7045 return;
7047 consts = caps.MaxVertexShaderConst;
7049 /* A simple check that the stuff works at all. */
7050 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
7051 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7053 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
7054 * consts from MAX - 1. */
7055 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
7056 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7057 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
7058 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7059 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
7060 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7061 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
7062 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7064 /* Constant -1. */
7065 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
7066 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7068 refcount = IDirect3DDevice9_Release(device);
7069 ok(!refcount, "Device has %lu references left.\n", refcount);
7071 desc.adapter_ordinal = D3DADAPTER_DEFAULT;
7072 desc.device_window = window;
7073 desc.width = 640;
7074 desc.height = 480;
7075 desc.flags = CREATE_DEVICE_SWVP_ONLY;
7077 if (!(device = create_device(d3d, window, &desc)))
7079 skip("Failed to create a D3D device, skipping tests.\n");
7080 IDirect3D9_Release(d3d);
7081 DestroyWindow(window);
7082 return;
7084 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7085 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7086 consts_swvp = caps.MaxVertexShaderConst;
7087 todo_wine
7088 ok(consts_swvp == 8192, "Unexpected consts_swvp %lu.\n", consts_swvp);
7090 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
7091 todo_wine
7092 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7093 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
7094 todo_wine
7095 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7096 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
7097 todo_wine
7098 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7099 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
7100 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7101 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp, c, 1);
7102 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7104 refcount = IDirect3DDevice9_Release(device);
7105 ok(!refcount, "Device has %lu references left.\n", refcount);
7107 desc.flags = CREATE_DEVICE_MIXED_ONLY;
7108 if (!(device = create_device(d3d, window, &desc)))
7110 skip("Failed to create a D3D device, skipping tests.\n");
7111 IDirect3D9_Release(d3d);
7112 DestroyWindow(window);
7113 return;
7115 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7116 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7117 ok(consts == caps.MaxVertexShaderConst, "Unexpected caps.MaxVertexShaderConst %lu, consts %lu.\n",
7118 caps.MaxVertexShaderConst, consts);
7120 IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
7121 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
7122 todo_wine
7123 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7124 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
7125 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7127 IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
7129 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
7130 todo_wine
7131 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7132 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts_swvp - 1, c, 1);
7133 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7135 refcount = IDirect3DDevice9_Release(device);
7136 ok(!refcount, "Device has %lu references left.\n", refcount);
7138 IDirect3D9_Release(d3d);
7139 DestroyWindow(window);
7142 static void test_get_set_pixel_shader(void)
7144 IDirect3DPixelShader9 *current_shader = NULL;
7145 IDirect3DPixelShader9 *shader = NULL;
7146 const IDirect3DPixelShader9Vtbl *shader_vtbl;
7147 IDirect3DDevice9 *device;
7148 ULONG refcount, i;
7149 IDirect3D9 *d3d;
7150 D3DCAPS9 caps;
7151 HWND window;
7152 HRESULT hr;
7154 window = create_window();
7155 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7156 ok(!!d3d, "Failed to create a D3D object.\n");
7157 if (!(device = create_device(d3d, window, NULL)))
7159 skip("Failed to create a D3D device, skipping tests.\n");
7160 IDirect3D9_Release(d3d);
7161 DestroyWindow(window);
7162 return;
7165 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7166 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7167 if (!(caps.PixelShaderVersion & 0xffff))
7169 skip("No pixel shader support, skipping tests.\n");
7170 IDirect3DDevice9_Release(device);
7171 IDirect3D9_Release(d3d);
7172 DestroyWindow(window);
7173 return;
7176 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
7177 ok(SUCCEEDED(hr), "Failed to create shader, hr %#lx.\n", hr);
7178 ok(!!shader, "Got unexpected shader %p.\n", shader);
7180 /* SetPixelShader() should not touch the shader's refcount. */
7181 i = get_refcount((IUnknown *)shader);
7182 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7183 refcount = get_refcount((IUnknown *)shader);
7184 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7185 ok(refcount == i, "Got unexpected refcount %lu, expected %lu.\n", refcount, i);
7187 /* GetPixelShader() should increase the shader's refcount by one. */
7188 i = refcount + 1;
7189 hr = IDirect3DDevice9_GetPixelShader(device, &current_shader);
7190 refcount = get_refcount((IUnknown *)shader);
7191 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#lx.\n", hr);
7192 ok(refcount == i, "Got unexpected refcount %lu, expected %lu.\n", refcount, i);
7193 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
7194 IDirect3DPixelShader9_Release(current_shader);
7196 /* SetPixelShader() with a bogus shader vtbl */
7197 shader_vtbl = shader->lpVtbl;
7198 shader->lpVtbl = (IDirect3DPixelShader9Vtbl *)0xdeadbeef;
7199 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7200 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7201 shader->lpVtbl = NULL;
7202 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7203 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7204 shader->lpVtbl = shader_vtbl;
7206 IDirect3DPixelShader9_Release(shader);
7207 refcount = IDirect3DDevice9_Release(device);
7208 ok(!refcount, "Device has %lu references left.\n", refcount);
7209 IDirect3D9_Release(d3d);
7210 DestroyWindow(window);
7213 static void test_pixel_shader_constant(void)
7215 static const float d[16] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
7216 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
7217 IDirect3DDevice9 *device;
7218 DWORD consts = 0;
7219 IDirect3D9 *d3d;
7220 ULONG refcount;
7221 D3DCAPS9 caps;
7222 HWND window;
7223 HRESULT hr;
7225 window = create_window();
7226 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7227 ok(!!d3d, "Failed to create a D3D object.\n");
7228 if (!(device = create_device(d3d, window, NULL)))
7230 skip("Failed to create a D3D device, skipping tests.\n");
7231 IDirect3D9_Release(d3d);
7232 DestroyWindow(window);
7233 return;
7236 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7237 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7238 if (!(caps.PixelShaderVersion & 0xffff))
7240 skip("No pixel shader support, skipping tests.\n");
7241 IDirect3DDevice9_Release(device);
7242 IDirect3D9_Release(d3d);
7243 DestroyWindow(window);
7244 return;
7247 /* A simple check that the stuff works at all. */
7248 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
7249 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7251 /* Is there really no max pixel shader constant value??? Test how far I can go. */
7252 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
7253 consts = consts - 1;
7254 trace("SetPixelShaderConstantF was able to set %lu shader constants.\n", consts);
7256 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
7257 * pointless given the way the constant limit was determined. */
7258 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
7259 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7261 /* Constant -1. */
7262 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
7263 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7265 refcount = IDirect3DDevice9_Release(device);
7266 ok(!refcount, "Device has %lu references left.\n", refcount);
7267 IDirect3D9_Release(d3d);
7268 DestroyWindow(window);
7271 static void test_unsupported_shaders(void)
7273 static const DWORD vs_3_0[] =
7275 0xfffe0300, /* vs_3_0 */
7276 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7277 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7278 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7279 0x0000ffff, /* end */
7282 #if 0
7283 float4 main(const float4 color : COLOR) : SV_TARGET
7285 float4 o;
7287 o = color;
7289 return o;
7291 #endif
7292 static const DWORD ps_4_0[] =
7294 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
7295 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
7296 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
7297 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
7298 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
7299 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
7300 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7301 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
7302 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
7303 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
7304 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
7305 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
7306 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
7307 0x00000000, 0x00000000, 0x00000000,
7309 #if 0
7310 vs_1_1
7311 dcl_position v0
7312 def c255, 1.0, 1.0, 1.0, 1.0
7313 add r0, v0, c255
7314 mov oPos, r0
7315 #endif
7316 static const DWORD vs_1_255[] =
7318 0xfffe0101,
7319 0x0000001f, 0x80000000, 0x900f0000,
7320 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
7321 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
7322 0x00000001, 0xc00f0000, 0x80e40000,
7323 0x0000ffff
7325 #if 0
7326 vs_1_1
7327 dcl_position v0
7328 def c256, 1.0, 1.0, 1.0, 1.0
7329 add r0, v0, c256
7330 mov oPos, r0
7331 #endif
7332 static const DWORD vs_1_256[] =
7334 0xfffe0101,
7335 0x0000001f, 0x80000000, 0x900f0000,
7336 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
7337 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
7338 0x00000001, 0xc00f0000, 0x80e40000,
7339 0x0000ffff
7341 #if 0
7342 vs_3_0
7343 dcl_position v0
7344 dcl_position o0
7345 def c256, 1.0, 1.0, 1.0, 1.0
7346 add r0, v0, c256
7347 mov o0, r0
7348 #endif
7349 static const DWORD vs_3_256[] =
7351 0xfffe0300,
7352 0x0200001f, 0x80000000, 0x900f0000,
7353 0x0200001f, 0x80000000, 0xe00f0000,
7354 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
7355 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
7356 0x02000001, 0xe00f0000, 0x80e40000,
7357 0x0000ffff
7359 #if 0
7360 /* This shader source generates syntax errors with the native shader assembler
7361 * due to the constant register index values.
7362 * The bytecode was modified by hand to use the intended values. */
7363 vs_3_0
7364 dcl_position v0
7365 dcl_position o0
7366 defi i16, 1, 1, 1, 1
7367 rep i16
7368 add r0, r0, v0
7369 endrep
7370 mov o0, r0
7371 #endif
7372 static const DWORD vs_3_i16[] =
7374 0xfffe0300,
7375 0x0200001f, 0x80000000, 0x900f0000,
7376 0x0200001f, 0x80000000, 0xe00f0000,
7377 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
7378 0x01000026, 0xf0e40010,
7379 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
7380 0x00000027,
7381 0x02000001, 0xe00f0000, 0x80e40000,
7382 0x0000ffff
7384 #if 0
7385 /* This shader source generates syntax errors with the native shader assembler
7386 * due to the constant register index values.
7387 * The bytecode was modified by hand to use the intended values. */
7388 vs_3_0
7389 dcl_position v0
7390 dcl_position o0
7391 defb b16, true
7392 mov r0, v0
7393 if b16
7394 add r0, r0, v0
7395 endif
7396 mov o0, r0
7397 #endif
7398 static const DWORD vs_3_b16[] =
7400 0xfffe0300,
7401 0x0200001f, 0x80000000, 0x900f0000,
7402 0x0200001f, 0x80000000, 0xe00f0000,
7403 0x0200002f, 0xe00f0810, 0x00000001,
7404 0x02000001, 0x800f0000, 0x90e40000,
7405 0x01000028, 0xe0e40810,
7406 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
7407 0x0000002b,
7408 0x02000001, 0xe00f0000, 0x80e40000,
7409 0x0000ffff
7411 #if 0
7412 /* This shader source generates syntax errors with the native shader assembler
7413 * due to the constant register index values.
7414 * The bytecode was modified by hand to use the intended values. */
7415 ps_1_1
7416 def c8, 1.0, 1.0, 1.0, 1.0
7417 add r0, v0, c8
7418 #endif
7419 static const DWORD ps_1_8[] =
7421 0xffff0101,
7422 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
7423 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
7424 0x0000ffff
7426 #if 0
7427 /* This shader source generates syntax errors with the native shader assembler
7428 * due to the constant register index values.
7429 * The bytecode was modified by hand to use the intended values. */
7430 ps_2_0
7431 def c32, 1.0, 1.0, 1.0, 1.0
7432 add oC0, v0, c32
7433 #endif
7434 static const DWORD ps_2_32[] =
7436 0xffff0200,
7437 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
7438 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
7439 0x0000ffff
7441 #if 0
7442 /* This shader source generates syntax errors with the native shader assembler
7443 * due to the constant register index values.
7444 * The bytecode was modified by hand to use the intended values. */
7445 ps_3_0
7446 dcl_color0 v0
7447 def c224, 1.0, 1.0, 1.0, 1.0
7448 add oC0, v0, c224
7449 #endif
7450 static const DWORD ps_3_224[] =
7452 0xffff0300,
7453 0x0200001f, 0x8000000a, 0x900f0000,
7454 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
7455 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
7456 0x0000ffff
7458 #if 0
7459 /* This shader source generates syntax errors with the native shader assembler
7460 * due to the constant register index values.
7461 * The bytecode was modified by hand to use the intended values. */
7462 ps_2_0
7463 defb b0, true
7464 defi i0, 1, 1, 1, 1
7465 rep i0
7466 if b0
7467 add r0, r0, v0
7468 endif
7469 endrep
7470 mov oC0, r0
7471 #endif
7472 static const DWORD ps_2_0_boolint[] =
7474 0xffff0200,
7475 0x0200002f, 0xe00f0800, 0x00000001,
7476 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
7477 0x01000026, 0xf0e40000,
7478 0x01000028, 0xe0e40800,
7479 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
7480 0x0000002b,
7481 0x00000027,
7482 0x02000001, 0x800f0800, 0x80e40000,
7483 0x0000ffff
7486 IDirect3DVertexShader9 *vs = NULL;
7487 IDirect3DPixelShader9 *ps = NULL;
7488 IDirect3DDevice9 *device;
7489 struct device_desc desc;
7490 IDirect3D9 * d3d;
7491 ULONG refcount;
7492 D3DCAPS9 caps;
7493 HWND window;
7494 HRESULT hr;
7496 window = create_window();
7497 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7498 ok(!!d3d, "Failed to create a D3D object.\n");
7499 if (!(device = create_device(d3d, window, NULL)))
7501 skip("Failed to create a D3D device, skipping tests.\n");
7502 IDirect3D9_Release(d3d);
7503 DestroyWindow(window);
7504 return;
7507 /* These should always fail, regardless of supported shader version. */
7508 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
7509 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7510 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
7511 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7512 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
7513 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7515 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7516 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7517 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7519 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
7520 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7521 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
7523 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_255, &vs);
7524 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7526 else
7528 skip("GPU supports SM2+, skipping SM1 test.\n");
7531 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
7533 else
7535 skip("This GPU supports SM3, skipping unsupported shader test.\n");
7537 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_255, &vs);
7538 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7539 IDirect3DVertexShader9_Release(vs);
7540 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_256, &vs);
7541 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7542 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_256, &vs);
7543 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7544 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_i16, &vs);
7545 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7546 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_b16, &vs);
7547 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7550 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
7552 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
7553 goto cleanup;
7555 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_8, &ps);
7556 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7557 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_32, &ps);
7558 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7559 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_224, &ps);
7560 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7561 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_0_boolint, &ps);
7562 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7563 if (ps)
7564 IDirect3DPixelShader9_Release(ps);
7566 refcount = IDirect3DDevice9_Release(device);
7567 ok(!refcount, "Device has %lu references left.\n", refcount);
7569 desc.adapter_ordinal = D3DADAPTER_DEFAULT;
7570 desc.device_window = window;
7571 desc.width = 640;
7572 desc.height = 480;
7573 desc.flags = CREATE_DEVICE_SWVP_ONLY;
7575 if (!(device = create_device(d3d, window, &desc)))
7577 skip("Failed to create a D3D device, skipping tests.\n");
7578 IDirect3D9_Release(d3d);
7579 DestroyWindow(window);
7580 return;
7583 vs = NULL;
7584 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_256, &vs);
7585 todo_wine
7586 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7587 if (vs)
7588 IDirect3DVertexShader9_Release(vs);
7589 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_256, &vs);
7590 todo_wine
7591 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7592 if (vs)
7593 IDirect3DVertexShader9_Release(vs);
7595 refcount = IDirect3DDevice9_Release(device);
7596 ok(!refcount, "Device has %lu references left.\n", refcount);
7598 desc.flags = CREATE_DEVICE_MIXED_ONLY;
7599 if (!(device = create_device(d3d, window, &desc)))
7601 skip("Failed to create a D3D device, skipping tests.\n");
7602 IDirect3D9_Release(d3d);
7603 DestroyWindow(window);
7604 return;
7606 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
7607 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7609 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_256, &vs);
7610 todo_wine
7611 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7612 hr = IDirect3DDevice9_SetVertexShader(device, vs);
7613 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7614 if (vs)
7615 IDirect3DVertexShader9_Release(vs);
7617 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_256, &vs);
7618 todo_wine
7619 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7620 hr = IDirect3DDevice9_SetVertexShader(device, vs);
7621 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7622 if (vs)
7623 IDirect3DVertexShader9_Release(vs);
7625 cleanup:
7626 refcount = IDirect3DDevice9_Release(device);
7627 ok(!refcount, "Device has %lu references left.\n", refcount);
7628 IDirect3D9_Release(d3d);
7629 DestroyWindow(window);
7632 /* Test the default texture stage state values */
7633 static void test_texture_stage_states(void)
7635 IDirect3DDevice9 *device;
7636 IDirect3D9 *d3d;
7637 unsigned int i;
7638 ULONG refcount;
7639 D3DCAPS9 caps;
7640 DWORD value;
7641 HWND window;
7642 HRESULT hr;
7644 window = create_window();
7645 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7646 ok(!!d3d, "Failed to create a D3D object.\n");
7647 if (!(device = create_device(d3d, window, NULL)))
7649 skip("Failed to create a D3D device, skipping tests.\n");
7650 IDirect3D9_Release(d3d);
7651 DestroyWindow(window);
7652 return;
7655 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7656 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7658 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
7660 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
7661 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7662 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
7663 "Got unexpected value %#lx for D3DTSS_COLOROP, stage %u.\n", value, i);
7664 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
7665 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7666 ok(value == D3DTA_TEXTURE, "Got unexpected value %#lx for D3DTSS_COLORARG1, stage %u.\n", value, i);
7667 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
7668 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7669 ok(value == D3DTA_CURRENT, "Got unexpected value %#lx for D3DTSS_COLORARG2, stage %u.\n", value, i);
7670 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
7671 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7672 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
7673 "Got unexpected value %#lx for D3DTSS_ALPHAOP, stage %u.\n", value, i);
7674 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
7675 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7676 ok(value == D3DTA_TEXTURE, "Got unexpected value %#lx for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
7677 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
7678 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7679 ok(value == D3DTA_CURRENT, "Got unexpected value %#lx for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
7680 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
7681 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7682 ok(!value, "Got unexpected value %#lx for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
7683 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
7684 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7685 ok(!value, "Got unexpected value %#lx for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
7686 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
7687 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7688 ok(!value, "Got unexpected value %#lx for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
7689 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
7690 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7691 ok(!value, "Got unexpected value %#lx for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
7692 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
7693 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7694 ok(value == i, "Got unexpected value %#lx for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
7695 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
7696 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7697 ok(!value, "Got unexpected value %#lx for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
7698 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
7699 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7700 ok(!value, "Got unexpected value %#lx for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
7701 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
7702 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7703 ok(value == D3DTTFF_DISABLE,
7704 "Got unexpected value %#lx for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
7705 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
7706 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7707 ok(value == D3DTA_CURRENT, "Got unexpected value %#lx for D3DTSS_COLORARG0, stage %u.\n", value, i);
7708 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
7709 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7710 ok(value == D3DTA_CURRENT, "Got unexpected value %#lx for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
7711 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
7712 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7713 ok(value == D3DTA_CURRENT, "Got unexpected value %#lx for D3DTSS_RESULTARG, stage %u.\n", value, i);
7714 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
7715 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#lx.\n", hr);
7716 ok(!value, "Got unexpected value %#lx for D3DTSS_CONSTANT, stage %u.\n", value, i);
7719 refcount = IDirect3DDevice9_Release(device);
7720 ok(!refcount, "Device has %lu references left.\n", refcount);
7721 IDirect3D9_Release(d3d);
7722 DestroyWindow(window);
7725 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
7727 IDirect3DCubeTexture9 *texture;
7728 IDirect3D9 *d3d;
7729 HRESULT hr;
7731 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
7732 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#lx.\n", hr);
7733 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7734 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
7735 IDirect3D9_Release(d3d);
7736 if (hr != D3D_OK)
7738 skip("No cube mipmap generation support, skipping tests.\n");
7739 return;
7742 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
7743 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7744 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7745 IDirect3DCubeTexture9_Release(texture);
7747 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
7748 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7749 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7750 IDirect3DCubeTexture9_Release(texture);
7753 static void test_cube_texture_levels(IDirect3DDevice9 *device)
7755 IDirect3DCubeTexture9 *texture;
7756 IDirect3DSurface9 *surface;
7757 D3DSURFACE_DESC desc;
7758 DWORD levels;
7759 HRESULT hr;
7760 D3DCAPS9 caps;
7762 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7763 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7764 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
7765 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
7767 skip("Failed to create cube texture, skipping tests.\n");
7768 return;
7771 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
7772 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)
7773 ok(levels == 7, "Got unexpected levels %lu.\n", levels);
7774 else
7775 ok(levels == 1, "Got unexpected levels %lu.\n", levels);
7777 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
7778 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7779 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
7780 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7781 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
7782 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7784 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
7785 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7786 IDirect3DSurface9_Release(surface);
7787 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
7788 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7789 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
7790 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7792 IDirect3DCubeTexture9_Release(texture);
7795 static void test_cube_textures(void)
7797 IDirect3DCubeTexture9 *texture;
7798 IDirect3DDevice9 *device;
7799 IDirect3D9 *d3d;
7800 ULONG refcount;
7801 D3DCAPS9 caps;
7802 HWND window;
7803 HRESULT hr;
7805 window = create_window();
7806 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7807 ok(!!d3d, "Failed to create a D3D object.\n");
7808 if (!(device = create_device(d3d, window, NULL)))
7810 skip("Failed to create a D3D device, skipping tests.\n");
7811 IDirect3D9_Release(d3d);
7812 DestroyWindow(window);
7813 return;
7816 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7817 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7819 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
7821 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7822 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#lx.\n", hr);
7823 IDirect3DCubeTexture9_Release(texture);
7824 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7825 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#lx.\n", hr);
7826 IDirect3DCubeTexture9_Release(texture);
7827 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
7828 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#lx.\n", hr);
7829 IDirect3DCubeTexture9_Release(texture);
7831 else
7833 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7834 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for D3DPOOL_DEFAULT cube texture.\n", hr);
7835 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7836 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for D3DPOOL_MANAGED cube texture.\n", hr);
7837 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
7838 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
7840 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
7841 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#lx.\n", hr);
7842 IDirect3DCubeTexture9_Release(texture);
7844 test_cube_texture_mipmap_gen(device);
7845 test_cube_texture_levels(device);
7847 refcount = IDirect3DDevice9_Release(device);
7848 ok(!refcount, "Device has %lu references left.\n", refcount);
7849 IDirect3D9_Release(d3d);
7850 DestroyWindow(window);
7853 static void test_mipmap_gen(void)
7855 static const D3DFORMAT formats[] =
7857 D3DFMT_A8R8G8B8,
7858 D3DFMT_X8R8G8B8,
7859 D3DFMT_A1R5G5B5,
7860 D3DFMT_A4R4G4B4,
7861 D3DFMT_A8,
7862 D3DFMT_L8,
7863 D3DFMT_A8L8,
7864 D3DFMT_V8U8,
7865 D3DFMT_DXT5,
7867 D3DTEXTUREFILTERTYPE filter_type;
7868 IDirect3DTexture9 *texture;
7869 IDirect3DSurface9 *surface;
7870 IDirect3DDevice9 *device;
7871 unsigned int i, count;
7872 D3DSURFACE_DESC desc;
7873 D3DLOCKED_RECT lr;
7874 IDirect3D9 *d3d;
7875 BOOL renderable;
7876 ULONG refcount;
7877 DWORD levels;
7878 HWND window;
7879 HRESULT hr;
7881 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7882 ok(!!d3d, "Failed to create a D3D object.\n");
7884 for (i = 0; i < ARRAY_SIZE(formats); ++i)
7886 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7887 0, D3DRTYPE_TEXTURE, formats[i]);
7888 if (FAILED(hr))
7890 skip("Skipping unsupported format %#x.\n", formats[i]);
7891 continue;
7893 renderable = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7894 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i]));
7895 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7896 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, formats[i]);
7897 ok((hr == D3D_OK && renderable) || hr == D3DOK_NOAUTOGEN,
7898 "Got unexpected hr %#lx for %srenderable format %#x.\n",
7899 hr, renderable ? "" : "non", formats[i]);
7902 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7903 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
7905 skip("No mipmap generation support, skipping tests.\n");
7906 IDirect3D9_Release(d3d);
7907 return;
7910 window = create_window();
7911 if (!(device = create_device(d3d, window, NULL)))
7913 skip("Failed to create a D3D device, skipping tests.\n");
7914 IDirect3D9_Release(d3d);
7915 DestroyWindow(window);
7916 return;
7919 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
7920 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7921 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7922 IDirect3DTexture9_Release(texture);
7924 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
7925 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7926 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7928 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
7929 ok(filter_type == D3DTEXF_LINEAR, "Got unexpected filter_type %#x.\n", filter_type);
7930 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
7931 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7932 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
7933 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7934 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
7935 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
7936 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
7937 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7939 levels = IDirect3DTexture9_GetLevelCount(texture);
7940 ok(levels == 1, "Got unexpected levels %lu.\n", levels);
7942 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
7944 surface = NULL;
7945 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
7946 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#lx for level %u.\n", hr, i);
7947 if (surface)
7948 IDirect3DSurface9_Release(surface);
7950 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
7951 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#lx for level %u.\n", hr, i);
7953 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
7954 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#lx for level %u.\n", hr, i);
7955 if (SUCCEEDED(hr))
7957 hr = IDirect3DTexture9_UnlockRect(texture, i);
7958 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
7961 IDirect3DTexture9_Release(texture);
7963 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
7964 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
7965 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7966 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
7967 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
7968 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7970 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
7971 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
7972 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7973 levels = IDirect3DTexture9_GetLevelCount(texture);
7974 ok(levels == 1, "Got unexpected levels %lu.\n", levels);
7975 hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
7976 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
7977 ok(desc.Usage == D3DUSAGE_AUTOGENMIPMAP, "Got unexpected usage %#lx.\n", desc.Usage);
7978 IDirect3DTexture9_Release(texture);
7980 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
7981 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, 0);
7982 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
7984 for (i = 0; i < ARRAY_SIZE(formats); ++i)
7986 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8,
7987 D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, formats[i]);
7988 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
7990 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7991 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, formats[i]);
7992 if (SUCCEEDED(hr))
7994 /* i.e. there is no difference between the D3D_OK and the
7995 * D3DOK_NOAUTOGEN cases. */
7996 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
7997 formats[i], D3DPOOL_SYSTEMMEM, &texture, 0);
7998 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
8000 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
8001 formats[i], D3DPOOL_DEFAULT, &texture, 0);
8002 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
8003 count = IDirect3DTexture9_GetLevelCount(texture);
8004 ok(count == 1, "Unexpected level count %u.\n", count);
8005 hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
8006 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8007 ok(desc.Usage == D3DUSAGE_AUTOGENMIPMAP, "Got unexpected usage %#lx.\n", desc.Usage);
8008 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
8009 ok(filter_type == D3DTEXF_LINEAR, "Got unexpected filter_type %#x.\n", filter_type);
8010 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
8011 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8012 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
8013 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
8014 IDirect3DTexture9_Release(texture);
8018 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8019 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_WRAPANDMIP, D3DRTYPE_TEXTURE, D3DFMT_D16);
8020 if (hr == D3D_OK)
8022 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
8023 D3DFMT_D16, D3DPOOL_DEFAULT, &texture, 0);
8024 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
8025 count = IDirect3DTexture9_GetLevelCount(texture);
8026 ok(count == 7, "Unexpected level count %u.\n", count);
8027 IDirect3DTexture9_Release(texture);
8029 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8030 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_D16);
8031 ok(hr == D3DOK_NOAUTOGEN, "Unexpected hr %#lx.\n", hr);
8032 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
8033 D3DFMT_D16, D3DPOOL_DEFAULT, &texture, 0);
8034 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
8035 count = IDirect3DTexture9_GetLevelCount(texture);
8036 ok(count == 1, "Unexpected level count %u.\n", count);
8037 hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
8038 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8039 ok(desc.Usage == D3DUSAGE_AUTOGENMIPMAP, "Got unexpected usage %#lx.\n", desc.Usage);
8040 IDirect3DTexture9_Release(texture);
8042 else
8044 skip("Mipmapping not supported for D3DFMT_D16, skipping test.\n");
8047 hr = IDirect3DDevice9_CreateVolumeTexture(device, 64, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
8048 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DVolumeTexture9 **)&texture, 0);
8049 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
8051 refcount = IDirect3DDevice9_Release(device);
8052 ok(!refcount, "Device has %lu references left.\n", refcount);
8053 IDirect3D9_Release(d3d);
8054 DestroyWindow(window);
8057 static void test_filter(void)
8059 static const struct
8061 DWORD magfilter, minfilter, mipfilter;
8062 BOOL has_texture;
8063 HRESULT result;
8065 tests[] =
8067 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
8068 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
8069 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
8070 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
8071 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
8073 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
8074 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
8075 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
8076 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
8078 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
8079 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
8080 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
8081 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
8082 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
8084 IDirect3DTexture9 *texture;
8085 IDirect3DDevice9 *device;
8086 IDirect3D9 *d3d;
8087 unsigned int i;
8088 ULONG refcount;
8089 DWORD passes;
8090 HWND window;
8091 HRESULT hr;
8093 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8094 ok(!!d3d, "Failed to create a D3D object.\n");
8096 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8097 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
8099 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
8100 IDirect3D9_Release(d3d);
8101 return;
8104 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8105 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
8107 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
8108 IDirect3D9_Release(d3d);
8109 return;
8112 window = create_window();
8113 if (!(device = create_device(d3d, window, NULL)))
8115 skip("Failed to create a D3D device, skipping tests.\n");
8116 IDirect3D9_Release(d3d);
8117 DestroyWindow(window);
8118 return;
8121 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
8122 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
8123 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
8125 /* Needed for ValidateDevice(). */
8126 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8127 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
8129 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8131 if (tests[i].has_texture)
8133 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
8134 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
8136 else
8138 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8139 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
8142 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
8143 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
8144 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
8145 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
8146 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
8147 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
8149 passes = 0xdeadbeef;
8150 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
8151 ok(hr == tests[i].result,
8152 "Got unexpected hr %#lx, expected %#lx (mag %#lx, min %#lx, mip %#lx, has_texture %#x).\n",
8153 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
8154 tests[i].mipfilter, tests[i].has_texture);
8155 if (SUCCEEDED(hr))
8156 ok(!!passes, "Got unexpected passes %#lx.\n", passes);
8157 else
8158 ok(passes == 0xdeadbeef, "Got unexpected passes %#lx.\n", passes);
8161 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8162 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
8163 IDirect3DTexture9_Release(texture);
8165 refcount = IDirect3DDevice9_Release(device);
8166 ok(!refcount, "Device has %lu references left.\n", refcount);
8167 IDirect3D9_Release(d3d);
8168 DestroyWindow(window);
8171 static void test_get_set_texture(void)
8173 const IDirect3DBaseTexture9Vtbl *texture_vtbl;
8174 IDirect3DBaseTexture9 *texture;
8175 IDirect3DDevice9 *device;
8176 IDirect3D9 *d3d;
8177 ULONG refcount;
8178 HWND window;
8179 HRESULT hr;
8181 window = create_window();
8182 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8183 ok(!!d3d, "Failed to create a D3D object.\n");
8184 if (!(device = create_device(d3d, window, NULL)))
8186 skip("Failed to create a D3D device, skipping tests.\n");
8187 IDirect3D9_Release(d3d);
8188 DestroyWindow(window);
8189 return;
8192 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
8193 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8194 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8195 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
8196 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8197 ok(!texture, "Got unexpected texture %p.\n", texture);
8199 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8,
8200 D3DPOOL_MANAGED, (IDirect3DTexture9 **)&texture, NULL);
8201 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
8202 texture_vtbl = texture->lpVtbl;
8203 texture->lpVtbl = (IDirect3DBaseTexture9Vtbl *)0xdeadbeef;
8204 hr = IDirect3DDevice9_SetTexture(device, 0, texture);
8205 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
8206 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8207 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
8208 texture->lpVtbl = NULL;
8209 hr = IDirect3DDevice9_SetTexture(device, 0, texture);
8210 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
8211 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8212 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
8213 texture->lpVtbl = texture_vtbl;
8214 IDirect3DBaseTexture9_Release(texture);
8216 refcount = IDirect3DDevice9_Release(device);
8217 ok(!refcount, "Device has %lu references left.\n", refcount);
8218 IDirect3D9_Release(d3d);
8219 DestroyWindow(window);
8222 static void test_lod(void)
8224 IDirect3DTexture9 *texture;
8225 IDirect3DDevice9 *device;
8226 IDirect3D9 *d3d;
8227 ULONG refcount;
8228 HWND window;
8229 HRESULT hr;
8230 DWORD ret;
8232 window = create_window();
8233 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8234 ok(!!d3d, "Failed to create a D3D object.\n");
8235 if (!(device = create_device(d3d, window, NULL)))
8237 skip("Failed to create a D3D device, skipping tests.\n");
8238 IDirect3D9_Release(d3d);
8239 DestroyWindow(window);
8240 return;
8243 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
8244 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8245 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
8247 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
8248 * return a HRESULT, so it can't return a normal error. Instead, the call
8249 * is simply ignored. */
8250 ret = IDirect3DTexture9_SetLOD(texture, 0);
8251 ok(!ret, "Got unexpected ret %lu.\n", ret);
8252 ret = IDirect3DTexture9_SetLOD(texture, 1);
8253 ok(!ret, "Got unexpected ret %lu.\n", ret);
8254 ret = IDirect3DTexture9_SetLOD(texture, 2);
8255 ok(!ret, "Got unexpected ret %lu.\n", ret);
8256 ret = IDirect3DTexture9_GetLOD(texture);
8257 ok(!ret, "Got unexpected ret %lu.\n", ret);
8259 IDirect3DTexture9_Release(texture);
8260 refcount = IDirect3DDevice9_Release(device);
8261 ok(!refcount, "Device has %lu references left.\n", refcount);
8262 IDirect3D9_Release(d3d);
8263 DestroyWindow(window);
8266 static void test_surface_get_container(void)
8268 IDirect3DTexture9 *texture = NULL;
8269 IDirect3DSurface9 *surface = NULL;
8270 IDirect3DDevice9 *device;
8271 IUnknown *container;
8272 IDirect3D9 *d3d;
8273 ULONG refcount;
8274 HWND window;
8275 HRESULT hr;
8277 window = create_window();
8278 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8279 ok(!!d3d, "Failed to create a D3D object.\n");
8280 if (!(device = create_device(d3d, window, NULL)))
8282 skip("Failed to create a D3D device, skipping tests.\n");
8283 IDirect3D9_Release(d3d);
8284 DestroyWindow(window);
8285 return;
8288 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
8289 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8290 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
8291 ok(!!texture, "Got unexpected texture %p.\n", texture);
8293 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8294 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
8295 ok(!!surface, "Got unexpected surface %p.\n", surface);
8297 /* These should work... */
8298 container = NULL;
8299 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
8300 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#lx.\n", hr);
8301 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
8302 IUnknown_Release(container);
8304 container = NULL;
8305 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
8306 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#lx.\n", hr);
8307 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
8308 IUnknown_Release(container);
8310 container = NULL;
8311 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
8312 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#lx.\n", hr);
8313 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
8314 IUnknown_Release(container);
8316 container = NULL;
8317 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
8318 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#lx.\n", hr);
8319 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
8320 IUnknown_Release(container);
8322 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
8323 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
8324 ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr);
8325 ok(!container, "Got unexpected container %p.\n", container);
8327 IDirect3DSurface9_Release(surface);
8328 IDirect3DTexture9_Release(texture);
8329 refcount = IDirect3DDevice9_Release(device);
8330 ok(!refcount, "Device has %lu references left.\n", refcount);
8331 IDirect3D9_Release(d3d);
8332 DestroyWindow(window);
8335 static void test_surface_alignment(void)
8337 IDirect3DSurface9 *surface;
8338 IDirect3DDevice9 *device;
8339 D3DLOCKED_RECT lr;
8340 unsigned int i, j;
8341 IDirect3D9 *d3d;
8342 ULONG refcount;
8343 HWND window;
8344 HRESULT hr;
8346 window = create_window();
8347 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8348 ok(!!d3d, "Failed to create a D3D object.\n");
8349 if (!(device = create_device(d3d, window, NULL)))
8351 skip("Failed to create a D3D device, skipping tests.\n");
8352 IDirect3D9_Release(d3d);
8353 DestroyWindow(window);
8354 return;
8357 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
8358 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
8359 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
8360 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
8362 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
8363 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
8364 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
8365 /* Some applications also depend on the exact pitch, rather than just the
8366 * alignment. */
8367 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
8368 hr = IDirect3DSurface9_UnlockRect(surface);
8369 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
8370 IDirect3DSurface9_Release(surface);
8372 for (i = 0; i < 5; ++i)
8374 IDirect3DTexture9 *texture;
8375 unsigned int level_count;
8376 D3DSURFACE_DESC desc;
8377 int expected_pitch;
8379 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
8380 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
8381 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
8382 if (FAILED(hr))
8384 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
8385 continue;
8388 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
8389 for (j = 0; j < level_count; ++j)
8391 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
8392 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
8393 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
8394 hr = IDirect3DTexture9_UnlockRect(texture, j);
8395 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
8397 expected_pitch = ((desc.Width + 3) >> 2) << 3;
8398 if (i > 0)
8399 expected_pitch <<= 1;
8400 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
8401 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
8403 IDirect3DTexture9_Release(texture);
8406 refcount = IDirect3DDevice9_Release(device);
8407 ok(!refcount, "Device has %lu references left.\n", refcount);
8408 IDirect3D9_Release(d3d);
8409 DestroyWindow(window);
8412 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
8413 * different from regular formats. This test verifies we return the correct
8414 * memory offsets. */
8415 static void test_lockrect_offset(void)
8417 static const struct
8419 D3DFORMAT format;
8420 const char *name;
8421 unsigned int block_width;
8422 unsigned int block_height;
8423 unsigned int block_size;
8425 dxt_formats[] =
8427 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
8428 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
8429 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
8430 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
8431 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
8432 {MAKEFOURCC('A','T','I','1'), "ATI1N", 1, 1, 1},
8433 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
8435 unsigned int expected_offset, offset, i;
8436 const RECT rect = {60, 60, 68, 68};
8437 IDirect3DSurface9 *surface;
8438 D3DLOCKED_RECT locked_rect;
8439 IDirect3DDevice9 *device;
8440 int expected_pitch;
8441 IDirect3D9 *d3d;
8442 ULONG refcount;
8443 HWND window;
8444 BYTE *base;
8445 HRESULT hr;
8447 window = create_window();
8448 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8449 ok(!!d3d, "Failed to create a D3D object.\n");
8450 if (!(device = create_device(d3d, window, NULL)))
8452 skip("Failed to create a D3D device, skipping tests.\n");
8453 IDirect3D9_Release(d3d);
8454 DestroyWindow(window);
8455 return;
8458 for (i = 0; i < ARRAY_SIZE(dxt_formats); ++i)
8460 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8461 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
8463 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
8464 continue;
8467 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
8468 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
8469 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
8471 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
8472 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
8474 base = locked_rect.pBits;
8475 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
8476 * dxt_formats[i].block_size;
8477 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
8478 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
8480 hr = IDirect3DSurface9_UnlockRect(surface);
8481 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
8483 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
8484 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
8486 offset = (BYTE *)locked_rect.pBits - base;
8487 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
8488 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
8489 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
8490 offset, dxt_formats[i].name, expected_offset);
8492 hr = IDirect3DSurface9_UnlockRect(surface);
8493 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
8495 IDirect3DSurface9_Release(surface);
8498 refcount = IDirect3DDevice9_Release(device);
8499 ok(!refcount, "Device has %lu references left.\n", refcount);
8500 IDirect3D9_Release(d3d);
8501 DestroyWindow(window);
8504 static void test_lockrect_invalid(void)
8506 static const struct
8508 RECT rect;
8509 HRESULT win7_result;
8511 test_data[] =
8513 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
8514 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
8515 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
8516 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
8517 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
8518 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
8519 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
8520 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
8521 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
8522 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
8523 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
8524 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
8525 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
8527 static const RECT test_rect_2 = {0, 0, 8, 8};
8528 IDirect3DSurface9 *surface = NULL;
8529 D3DLOCKED_RECT locked_rect;
8530 IDirect3DDevice9 *device;
8531 IDirect3DTexture9 *texture;
8532 IDirect3DCubeTexture9 *cube_texture;
8533 HRESULT hr, expected_hr;
8534 unsigned int i, r;
8535 IDirect3D9 *d3d;
8536 ULONG refcount;
8537 HWND window;
8538 BYTE *base;
8539 static const struct
8541 D3DRESOURCETYPE type;
8542 D3DPOOL pool;
8543 const char *name;
8545 resources[] =
8547 {D3DRTYPE_SURFACE, D3DPOOL_SCRATCH, "scratch surface"},
8548 {D3DRTYPE_TEXTURE, D3DPOOL_MANAGED, "managed texture"},
8549 {D3DRTYPE_TEXTURE, D3DPOOL_SYSTEMMEM, "sysmem texture"},
8550 {D3DRTYPE_TEXTURE, D3DPOOL_SCRATCH, "scratch texture"},
8551 {D3DRTYPE_CUBETEXTURE, D3DPOOL_MANAGED, "default cube texture"},
8552 {D3DRTYPE_CUBETEXTURE, D3DPOOL_SYSTEMMEM, "sysmem cube texture"},
8553 {D3DRTYPE_CUBETEXTURE, D3DPOOL_SCRATCH, "scratch cube texture"},
8556 window = create_window();
8557 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8558 ok(!!d3d, "Failed to create a D3D object.\n");
8559 if (!(device = create_device(d3d, window, NULL)))
8561 skip("Failed to create a D3D device, skipping tests.\n");
8562 IDirect3D9_Release(d3d);
8563 DestroyWindow(window);
8564 return;
8567 for (r = 0; r < ARRAY_SIZE(resources); ++r)
8569 texture = NULL;
8570 cube_texture = NULL;
8571 switch (resources[r].type)
8573 case D3DRTYPE_SURFACE:
8574 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
8575 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
8576 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx, type %s.\n",
8577 hr, resources[r].name);
8578 break;
8580 case D3DRTYPE_TEXTURE:
8581 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
8582 resources[r].pool, &texture, NULL);
8583 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, type %s.\n",
8584 hr, resources[r].name);
8585 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8586 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx, type %s.\n",
8587 hr, resources[r].name);
8588 break;
8590 case D3DRTYPE_CUBETEXTURE:
8591 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
8592 resources[r].pool, &cube_texture, NULL);
8593 ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#lx, type %s.\n",
8594 hr, resources[r].name);
8595 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture,
8596 D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface);
8597 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx, type %s.\n",
8598 hr, resources[r].name);
8599 break;
8601 default:
8602 break;
8605 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
8606 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx, type %s.\n", hr, resources[r].name);
8607 base = locked_rect.pBits;
8608 hr = IDirect3DSurface9_UnlockRect(surface);
8609 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx, type %s.\n", hr, resources[r].name);
8610 expected_hr = resources[r].type == D3DRTYPE_TEXTURE ? D3D_OK : D3DERR_INVALIDCALL;
8611 hr = IDirect3DSurface9_UnlockRect(surface);
8612 ok(hr == expected_hr, "Got hr %#lx, expected %#lx, type %s.\n", hr, expected_hr, resources[r].name);
8614 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
8616 unsigned int offset, expected_offset;
8617 const RECT *rect = &test_data[i].rect;
8619 locked_rect.pBits = (BYTE *)0xdeadbeef;
8620 locked_rect.Pitch = 0xdeadbeef;
8622 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
8623 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
8624 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
8625 * one broken. */
8626 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
8627 "Failed to lock surface with rect %s, hr %#lx, type %s.\n",
8628 wine_dbgstr_rect(rect), hr, resources[r].name);
8629 if (FAILED(hr))
8630 continue;
8632 offset = (BYTE *)locked_rect.pBits - base;
8633 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
8634 ok(offset == expected_offset,
8635 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
8636 offset, expected_offset, wine_dbgstr_rect(rect), resources[r].name);
8638 hr = IDirect3DSurface9_UnlockRect(surface);
8639 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx, type %s.\n", hr, resources[r].name);
8641 if (texture)
8643 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, rect, 0);
8644 ok(SUCCEEDED(hr),
8645 "Failed to lock texture with rect %s, hr %#lx, type %s.\n",
8646 wine_dbgstr_rect(rect), hr, resources[r].name);
8647 if (FAILED(hr))
8648 continue;
8650 offset = (BYTE *)locked_rect.pBits - base;
8651 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
8652 ok(offset == expected_offset,
8653 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
8654 offset, expected_offset, wine_dbgstr_rect(rect), resources[r].name);
8656 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8657 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx, type %s.\n", hr, resources[r].name);
8659 if (cube_texture)
8661 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
8662 &locked_rect, rect, 0);
8663 ok(SUCCEEDED(hr),
8664 "Failed to lock texture with rect %s, hr %#lx, type %s.\n",
8665 wine_dbgstr_rect(rect), hr, resources[r].name);
8666 if (FAILED(hr))
8667 continue;
8669 offset = (BYTE *)locked_rect.pBits - base;
8670 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
8671 ok(offset == expected_offset,
8672 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
8673 offset, expected_offset, wine_dbgstr_rect(rect), resources[r].name);
8675 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0);
8676 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx, type %s.\n", hr, resources[r].name);
8680 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
8681 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#lx, type %s.\n", hr, resources[r].name);
8682 locked_rect.pBits = (BYTE *)0xdeadbeef;
8683 locked_rect.Pitch = 1;
8684 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
8685 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, type %s.\n", hr, resources[r].name);
8686 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n",
8687 locked_rect.pBits, resources[r].name);
8688 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n",
8689 locked_rect.Pitch, resources[r].name);
8690 hr = IDirect3DSurface9_UnlockRect(surface);
8691 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx, type %s.\n", hr, resources[r].name);
8693 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
8694 ok(hr == D3D_OK, "Got unexpected hr %#lx for rect %s, type %s.\n",
8695 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
8696 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
8697 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for rect %s, type %s.\n",
8698 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
8699 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
8700 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for rect %s, type %s.\n",
8701 hr, wine_dbgstr_rect(&test_rect_2), resources[r].name);
8702 hr = IDirect3DSurface9_UnlockRect(surface);
8703 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx, type %s.\n", hr, resources[r].name);
8705 IDirect3DSurface9_Release(surface);
8707 if (texture)
8709 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
8710 ok(SUCCEEDED(hr), "Failed to lock texture with rect NULL, hr %#lx, type %s.\n",
8711 hr, resources[r].name);
8712 locked_rect.pBits = (BYTE *)0xdeadbeef;
8713 locked_rect.Pitch = 1;
8714 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
8715 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, type %s.\n", hr, resources[r].name);
8716 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n",
8717 locked_rect.pBits, resources[r].name);
8718 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n",
8719 locked_rect.Pitch, resources[r].name);
8720 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
8721 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, type %s.\n", hr, resources[r].name);
8722 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8723 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx, type %s.\n", hr, resources[r].name);
8724 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8725 ok(hr == D3D_OK, "Got unexpected hr %#lx, type %s.\n", hr, resources[r].name);
8727 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_data[0].rect, 0);
8728 ok(hr == D3D_OK, "Got unexpected hr %#lx for rect %s, type %s.\n",
8729 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
8730 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_data[0].rect, 0);
8731 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for rect %s, type %s.\n",
8732 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
8733 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_rect_2, 0);
8734 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for rect %s, type %s.\n",
8735 hr, wine_dbgstr_rect(&test_rect_2), resources[r].name);
8736 hr = IDirect3DTexture9_UnlockRect(texture, 0);
8737 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx, type %s.\n", hr, resources[r].name);
8739 IDirect3DTexture9_Release(texture);
8741 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_WRITEONLY,
8742 D3DFMT_A8R8G8B8, resources[r].pool, &texture, NULL);
8743 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for type %s.\n",
8744 hr, resources[r].name);
8746 if (cube_texture)
8748 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
8749 &locked_rect, NULL, 0);
8750 ok(SUCCEEDED(hr), "Failed to lock texture with rect NULL, hr %#lx, type %s.\n",
8751 hr, resources[r].name);
8752 locked_rect.pBits = (BYTE *)0xdeadbeef;
8753 locked_rect.Pitch = 1;
8754 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
8755 &locked_rect, NULL, 0);
8756 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, type %s.\n", hr, resources[r].name);
8757 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n",
8758 locked_rect.pBits, resources[r].name);
8759 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n",
8760 locked_rect.Pitch, resources[r].name);
8761 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
8762 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, type %s.\n", hr, resources[r].name);
8763 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0);
8764 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx, type %s.\n", hr, resources[r].name);
8765 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0);
8766 todo_wine ok(hr == D3D_OK, "Got unexpected hr %#lx, type %s.\n", hr, resources[r].name);
8768 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
8769 &locked_rect, &test_data[0].rect, 0);
8770 ok(hr == D3D_OK, "Got unexpected hr %#lx for rect %s, type %s.\n",
8771 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
8772 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
8773 &locked_rect, &test_data[0].rect, 0);
8774 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for rect %s, type %s.\n",
8775 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
8776 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
8777 &locked_rect, &test_rect_2, 0);
8778 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for rect %s, type %s.\n",
8779 hr, wine_dbgstr_rect(&test_rect_2), resources[r].name);
8780 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0);
8781 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx, type %s.\n", hr, resources[r].name);
8783 IDirect3DCubeTexture9_Release(cube_texture);
8785 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, D3DUSAGE_WRITEONLY, D3DFMT_A8R8G8B8,
8786 resources[r].pool, &cube_texture, NULL);
8787 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for type %s.\n",
8788 hr, resources[r].name);
8792 refcount = IDirect3DDevice9_Release(device);
8793 ok(!refcount, "Device has %lu references left.\n", refcount);
8794 IDirect3D9_Release(d3d);
8795 DestroyWindow(window);
8798 static void test_private_data(void)
8800 ULONG refcount, expected_refcount;
8801 IDirect3DTexture9 *texture;
8802 IDirect3DSurface9 *surface, *surface2;
8803 IDirect3DDevice9 *device;
8804 IDirect3D9 *d3d;
8805 IUnknown *ptr;
8806 HWND window;
8807 HRESULT hr;
8808 DWORD size;
8809 DWORD data[4] = {1, 2, 3, 4};
8810 static const GUID d3d9_private_data_test_guid2 =
8812 0x2e5afac2,
8813 0x87b5,
8814 0x4c10,
8815 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
8818 window = create_window();
8819 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8820 ok(!!d3d, "Failed to create a D3D object.\n");
8821 if (!(device = create_device(d3d, window, NULL)))
8823 skip("Failed to create a D3D device, skipping tests.\n");
8824 IDirect3D9_Release(d3d);
8825 DestroyWindow(window);
8826 return;
8829 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
8830 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
8831 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
8833 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
8834 device, 0, D3DSPD_IUNKNOWN);
8835 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
8836 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
8837 device, 5, D3DSPD_IUNKNOWN);
8838 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
8839 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
8840 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
8841 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
8843 /* A failing SetPrivateData call does not clear the old data with the same tag. */
8844 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
8845 sizeof(device), D3DSPD_IUNKNOWN);
8846 ok(SUCCEEDED(hr), "Failed to set private data, hr %#lx.\n", hr);
8847 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
8848 sizeof(device) * 2, D3DSPD_IUNKNOWN);
8849 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
8850 size = sizeof(ptr);
8851 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
8852 ok(SUCCEEDED(hr), "Failed to get private data, hr %#lx.\n", hr);
8853 IUnknown_Release(ptr);
8854 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
8855 ok(SUCCEEDED(hr), "Failed to free private data, hr %#lx.\n", hr);
8857 refcount = get_refcount((IUnknown *)device);
8858 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
8859 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
8860 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8861 expected_refcount = refcount + 1;
8862 refcount = get_refcount((IUnknown *)device);
8863 ok(refcount == expected_refcount, "Got unexpected refcount %lu, expected %lu.\n", refcount, expected_refcount);
8864 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
8865 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8866 expected_refcount = refcount - 1;
8867 refcount = get_refcount((IUnknown *)device);
8868 ok(refcount == expected_refcount, "Got unexpected refcount %lu, expected %lu.\n", refcount, expected_refcount);
8870 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
8871 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
8872 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8873 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
8874 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
8875 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8876 refcount = get_refcount((IUnknown *)device);
8877 ok(refcount == expected_refcount, "Got unexpected refcount %lu, expected %lu.\n", refcount, expected_refcount);
8879 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
8880 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
8881 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8882 size = 2 * sizeof(ptr);
8883 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
8884 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8885 ok(size == sizeof(device), "Got unexpected size %lu.\n", size);
8886 expected_refcount = refcount + 2;
8887 refcount = get_refcount((IUnknown *)device);
8888 ok(refcount == expected_refcount, "Got unexpected refcount %lu, expected %lu.\n", refcount, expected_refcount);
8889 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
8890 IUnknown_Release(ptr);
8891 expected_refcount--;
8893 ptr = (IUnknown *)0xdeadbeef;
8894 size = 1;
8895 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
8896 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8897 ok(size == sizeof(device), "Got unexpected size %lu.\n", size);
8898 size = 2 * sizeof(ptr);
8899 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
8900 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8901 ok(size == sizeof(device), "Got unexpected size %lu.\n", size);
8902 refcount = get_refcount((IUnknown *)device);
8903 ok(refcount == expected_refcount, "Got unexpected refcount %lu, expected %lu.\n", refcount, expected_refcount);
8904 size = 1;
8905 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
8906 ok(hr == D3DERR_MOREDATA, "Got unexpected hr %#lx.\n", hr);
8907 ok(size == sizeof(device), "Got unexpected size %lu.\n", size);
8908 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
8909 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, NULL, NULL);
8910 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#lx.\n", hr);
8911 size = 0xdeadbabe;
8912 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, &ptr, &size);
8913 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#lx.\n", hr);
8914 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
8915 ok(size == 0xdeadbabe, "Got unexpected size %lu.\n", size);
8916 /* GetPrivateData with size = NULL causes an access violation on Windows if the
8917 * requested data exists. */
8919 /* Destroying the surface frees the held reference. */
8920 IDirect3DSurface9_Release(surface);
8921 expected_refcount = refcount - 2;
8922 refcount = get_refcount((IUnknown *)device);
8923 ok(refcount == expected_refcount, "Got unexpected refcount %lu, expected %lu.\n", refcount, expected_refcount);
8925 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH,
8926 &texture, NULL);
8927 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
8928 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8929 ok(SUCCEEDED(hr), "Failed to get texture level 0, hr %#lx.\n", hr);
8930 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
8931 ok(SUCCEEDED(hr), "Failed to get texture level 1, hr %#lx.\n", hr);
8933 hr = IDirect3DTexture9_SetPrivateData(texture, &d3d9_private_data_test_guid, data, sizeof(data), 0);
8934 ok(SUCCEEDED(hr), "Failed to set private data, hr %#lx.\n", hr);
8936 memset(data, 0, sizeof(data));
8937 size = sizeof(data);
8938 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, data, &size);
8939 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#lx.\n", hr);
8940 hr = IDirect3DTexture9_GetPrivateData(texture, &d3d9_private_data_test_guid, data, &size);
8941 ok(SUCCEEDED(hr), "Failed to get private data, hr %#lx.\n", hr);
8942 ok(data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4,
8943 "Got unexpected private data: %lu, %lu, %lu, %lu.\n", data[0], data[1], data[2], data[3]);
8945 hr = IDirect3DTexture9_FreePrivateData(texture, &d3d9_private_data_test_guid);
8946 ok(SUCCEEDED(hr), "Failed to free private data, hr %#lx.\n", hr);
8948 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, data, sizeof(data), 0);
8949 ok(SUCCEEDED(hr), "Failed to set private data, hr %#lx.\n", hr);
8950 hr = IDirect3DSurface9_GetPrivateData(surface2, &d3d9_private_data_test_guid, data, &size);
8951 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#lx.\n", hr);
8953 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
8954 ok(SUCCEEDED(hr), "Failed to free private data, hr %#lx.\n", hr);
8956 IDirect3DSurface9_Release(surface2);
8957 IDirect3DSurface9_Release(surface);
8958 IDirect3DTexture9_Release(texture);
8960 refcount = IDirect3DDevice9_Release(device);
8961 ok(!refcount, "Device has %lu references left.\n", refcount);
8962 IDirect3D9_Release(d3d);
8963 DestroyWindow(window);
8966 static void test_getdc(void)
8968 static const struct
8970 const char *name;
8971 D3DFORMAT format;
8972 unsigned int bit_count;
8973 DWORD mask_r, mask_g, mask_b;
8974 BOOL getdc_supported;
8976 testdata[] =
8978 {"A8R8G8B8", D3DFMT_A8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, TRUE },
8979 {"X8R8G8B8", D3DFMT_X8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, TRUE },
8980 {"R5G6B5", D3DFMT_R5G6B5, 16, 0x0000f800, 0x000007e0, 0x0000001f, TRUE },
8981 {"X1R5G5B5", D3DFMT_X1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, TRUE },
8982 {"A1R5G5B5", D3DFMT_A1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, TRUE },
8983 {"R8G8B8", D3DFMT_R8G8B8, 24, 0x00000000, 0x00000000, 0x00000000, TRUE },
8984 {"A2R10G10B10", D3DFMT_A2R10G10B10, 32, 0x00000000, 0x00000000, 0x00000000, FALSE},
8985 {"V8U8", D3DFMT_V8U8, 16, 0x00000000, 0x00000000, 0x00000000, FALSE},
8986 {"Q8W8V8U8", D3DFMT_Q8W8V8U8, 32, 0x00000000, 0x00000000, 0x00000000, FALSE},
8987 {"A8B8G8R8", D3DFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, FALSE},
8988 {"X8B8G8R8", D3DFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, FALSE},
8989 {"R3G3B2", D3DFMT_R3G3B2, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
8990 {"P8", D3DFMT_P8, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
8991 {"L8", D3DFMT_L8, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
8992 {"A8L8", D3DFMT_A8L8, 16, 0x00000000, 0x00000000, 0x00000000, FALSE},
8993 {"DXT1", D3DFMT_DXT1, 4, 0x00000000, 0x00000000, 0x00000000, FALSE},
8994 {"DXT2", D3DFMT_DXT2, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
8995 {"DXT3", D3DFMT_DXT3, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
8996 {"DXT4", D3DFMT_DXT4, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
8997 {"DXT5", D3DFMT_DXT5, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
8999 IDirect3DSurface9 *surface, *surface2;
9000 IDirect3DCubeTexture9 *cube_texture;
9001 struct device_desc device_desc;
9002 IDirect3DTexture9 *texture;
9003 IDirect3DDevice9 *device;
9004 D3DLOCKED_RECT map_desc;
9005 IDirect3D9 *d3d;
9006 unsigned int i;
9007 ULONG refcount;
9008 HWND window;
9009 HDC dc, dc2;
9010 HRESULT hr;
9012 window = create_window();
9013 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9014 ok(!!d3d, "Failed to create a D3D object.\n");
9015 if (!(device = create_device(d3d, window, NULL)))
9017 skip("Failed to create a D3D device, skipping tests.\n");
9018 IDirect3D9_Release(d3d);
9019 DestroyWindow(window);
9020 return;
9023 for (i = 0; i < ARRAY_SIZE(testdata); ++i)
9025 texture = NULL;
9026 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
9027 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
9028 if (FAILED(hr))
9030 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
9031 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
9032 if (FAILED(hr))
9034 skip("Failed to create surface for format %s (hr %#lx), skipping tests.\n", testdata[i].name, hr);
9035 continue;
9037 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9038 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
9041 dc = (void *)0x1234;
9042 hr = IDirect3DSurface9_GetDC(surface, &dc);
9043 if (testdata[i].getdc_supported)
9044 ok(SUCCEEDED(hr), "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9045 else
9046 ok(FAILED(hr), "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9048 if (SUCCEEDED(hr))
9050 unsigned int width_bytes;
9051 DIBSECTION dib;
9052 HBITMAP bitmap;
9053 DWORD type;
9054 int size;
9056 type = GetObjectType(dc);
9057 ok(type == OBJ_MEMDC, "Got unexpected object type %#lx for format %s.\n", type, testdata[i].name);
9058 bitmap = GetCurrentObject(dc, OBJ_BITMAP);
9059 type = GetObjectType(bitmap);
9060 ok(type == OBJ_BITMAP, "Got unexpected object type %#lx for format %s.\n", type, testdata[i].name);
9062 size = GetObjectA(bitmap, sizeof(dib), &dib);
9063 ok(size == sizeof(dib), "Got unexpected size %d for format %s.\n", size, testdata[i].name);
9064 ok(!dib.dsBm.bmType, "Got unexpected type %#x for format %s.\n",
9065 dib.dsBm.bmType, testdata[i].name);
9066 ok(dib.dsBm.bmWidth == 64, "Got unexpected width %d for format %s.\n",
9067 dib.dsBm.bmWidth, testdata[i].name);
9068 ok(dib.dsBm.bmHeight == 64, "Got unexpected height %d for format %s.\n",
9069 dib.dsBm.bmHeight, testdata[i].name);
9070 width_bytes = ((dib.dsBm.bmWidth * testdata[i].bit_count + 31) >> 3) & ~3;
9071 ok(dib.dsBm.bmWidthBytes == width_bytes, "Got unexpected width bytes %d for format %s.\n",
9072 dib.dsBm.bmWidthBytes, testdata[i].name);
9073 ok(dib.dsBm.bmPlanes == 1, "Got unexpected plane count %d for format %s.\n",
9074 dib.dsBm.bmPlanes, testdata[i].name);
9075 ok(dib.dsBm.bmBitsPixel == testdata[i].bit_count,
9076 "Got unexpected bit count %d for format %s.\n",
9077 dib.dsBm.bmBitsPixel, testdata[i].name);
9078 ok(!!dib.dsBm.bmBits, "Got unexpected bits %p for format %s.\n",
9079 dib.dsBm.bmBits, testdata[i].name);
9081 ok(dib.dsBmih.biSize == sizeof(dib.dsBmih), "Got unexpected size %lu for format %s.\n",
9082 dib.dsBmih.biSize, testdata[i].name);
9083 ok(dib.dsBmih.biWidth == 64, "Got unexpected width %ld for format %s.\n",
9084 dib.dsBmih.biHeight, testdata[i].name);
9085 ok(dib.dsBmih.biHeight == 64, "Got unexpected height %ld for format %s.\n",
9086 dib.dsBmih.biHeight, testdata[i].name);
9087 ok(dib.dsBmih.biPlanes == 1, "Got unexpected plane count %u for format %s.\n",
9088 dib.dsBmih.biPlanes, testdata[i].name);
9089 ok(dib.dsBmih.biBitCount == testdata[i].bit_count, "Got unexpected bit count %u for format %s.\n",
9090 dib.dsBmih.biBitCount, testdata[i].name);
9091 ok(dib.dsBmih.biCompression == (testdata[i].bit_count == 16 ? BI_BITFIELDS : BI_RGB),
9092 "Got unexpected compression %#lx for format %s.\n",
9093 dib.dsBmih.biCompression, testdata[i].name);
9094 ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %lu for format %s.\n",
9095 dib.dsBmih.biSizeImage, testdata[i].name);
9096 ok(!dib.dsBmih.biXPelsPerMeter, "Got unexpected horizontal resolution %ld for format %s.\n",
9097 dib.dsBmih.biXPelsPerMeter, testdata[i].name);
9098 ok(!dib.dsBmih.biYPelsPerMeter, "Got unexpected vertical resolution %ld for format %s.\n",
9099 dib.dsBmih.biYPelsPerMeter, testdata[i].name);
9100 ok(!dib.dsBmih.biClrUsed, "Got unexpected used colour count %lu for format %s.\n",
9101 dib.dsBmih.biClrUsed, testdata[i].name);
9102 ok(!dib.dsBmih.biClrImportant, "Got unexpected important colour count %lu for format %s.\n",
9103 dib.dsBmih.biClrImportant, testdata[i].name);
9105 if (dib.dsBmih.biCompression == BI_BITFIELDS)
9107 ok(dib.dsBitfields[0] == testdata[i].mask_r && dib.dsBitfields[1] == testdata[i].mask_g
9108 && dib.dsBitfields[2] == testdata[i].mask_b,
9109 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
9110 dib.dsBitfields[0], dib.dsBitfields[1], dib.dsBitfields[2], testdata[i].name);
9112 else
9114 ok(!dib.dsBitfields[0] && !dib.dsBitfields[1] && !dib.dsBitfields[2],
9115 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
9116 dib.dsBitfields[0], dib.dsBitfields[1], dib.dsBitfields[2], testdata[i].name);
9118 ok(!dib.dshSection, "Got unexpected section %p for format %s.\n", dib.dshSection, testdata[i].name);
9119 ok(!dib.dsOffset, "Got unexpected offset %lu for format %s.\n", dib.dsOffset, testdata[i].name);
9121 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9122 ok(hr == D3D_OK, "Failed to release DC, hr %#lx.\n", hr);
9124 else
9126 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
9129 IDirect3DSurface9_Release(surface);
9130 if (texture)
9131 IDirect3DTexture9_Release(texture);
9133 if (!testdata[i].getdc_supported)
9134 continue;
9136 if (FAILED(hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 3, 0,
9137 testdata[i].format, D3DPOOL_MANAGED, &cube_texture, NULL)))
9139 skip("Failed to create cube texture for format %s (hr %#lx), skipping tests.\n", testdata[i].name, hr);
9140 continue;
9143 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
9144 ok(SUCCEEDED(hr), "Failed to get cube surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9145 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_Y, 2, &surface2);
9146 ok(SUCCEEDED(hr), "Failed to get cube surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9148 hr = IDirect3DSurface9_GetDC(surface, &dc);
9149 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9150 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9151 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9152 hr = IDirect3DSurface9_GetDC(surface2, &dc);
9153 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9154 hr = IDirect3DSurface9_ReleaseDC(surface2, dc);
9155 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9157 hr = IDirect3DSurface9_GetDC(surface, &dc);
9158 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9159 dc2 = (void *)0x1234;
9160 hr = IDirect3DSurface9_GetDC(surface, &dc2);
9161 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9162 ok(dc2 == (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc, testdata[i].name);
9163 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9164 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9165 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9166 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9168 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
9169 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9170 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
9171 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9172 hr = IDirect3DSurface9_UnlockRect(surface);
9173 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9174 hr = IDirect3DSurface9_UnlockRect(surface);
9175 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9177 hr = IDirect3DSurface9_GetDC(surface, &dc);
9178 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9179 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
9180 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9181 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9182 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9184 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
9185 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9186 hr = IDirect3DSurface9_GetDC(surface, &dc);
9187 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9188 hr = IDirect3DSurface9_UnlockRect(surface);
9189 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9191 hr = IDirect3DSurface9_GetDC(surface, &dc);
9192 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9193 hr = IDirect3DSurface9_GetDC(surface2, &dc2);
9194 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9195 hr = IDirect3DSurface9_ReleaseDC(surface2, dc2);
9196 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9197 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9198 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9200 hr = IDirect3DSurface9_GetDC(surface2, &dc);
9201 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9202 hr = IDirect3DSurface9_GetDC(surface, &dc2);
9203 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9204 hr = IDirect3DSurface9_ReleaseDC(surface, dc2);
9205 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9206 hr = IDirect3DSurface9_ReleaseDC(surface2, dc);
9207 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9209 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
9210 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9211 hr = IDirect3DSurface9_LockRect(surface2, &map_desc, NULL, D3DLOCK_READONLY);
9212 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9213 hr = IDirect3DSurface9_UnlockRect(surface2);
9214 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9215 hr = IDirect3DSurface9_UnlockRect(surface);
9216 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9218 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
9219 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9220 hr = IDirect3DSurface9_GetDC(surface, &dc);
9221 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9222 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9223 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9224 hr = IDirect3DSurface9_UnlockRect(surface);
9225 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9227 hr = IDirect3DSurface9_LockRect(surface2, &map_desc, NULL, D3DLOCK_READONLY);
9228 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9229 hr = IDirect3DSurface9_GetDC(surface, &dc);
9230 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9231 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9232 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9233 hr = IDirect3DSurface9_UnlockRect(surface2);
9234 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9236 hr = IDirect3DSurface9_GetDC(surface, &dc);
9237 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9238 hr = IDirect3DSurface9_LockRect(surface2, &map_desc, NULL, D3DLOCK_READONLY);
9239 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9240 hr = IDirect3DSurface9_UnlockRect(surface2);
9241 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9242 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9243 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9245 hr = IDirect3DSurface9_GetDC(surface2, &dc);
9246 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9247 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
9248 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9249 hr = IDirect3DSurface9_UnlockRect(surface);
9250 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9251 hr = IDirect3DSurface9_ReleaseDC(surface2, dc);
9252 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9254 hr = IDirect3DSurface9_UnlockRect(surface);
9255 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9256 hr = IDirect3DSurface9_GetDC(surface2, &dc);
9257 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9258 hr = IDirect3DSurface9_UnlockRect(surface);
9259 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9260 hr = IDirect3DSurface9_ReleaseDC(surface2, dc);
9261 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9262 hr = IDirect3DSurface9_UnlockRect(surface);
9263 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9265 hr = IDirect3DSurface9_UnlockRect(surface2);
9266 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9267 hr = IDirect3DSurface9_GetDC(surface, &dc);
9268 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9269 hr = IDirect3DSurface9_UnlockRect(surface2);
9270 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#lx.\n", testdata[i].name, hr);
9271 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9272 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#lx.\n", testdata[i].name, hr);
9273 hr = IDirect3DSurface9_UnlockRect(surface2);
9274 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for format %s.\n", hr, testdata[i].name);
9276 IDirect3DSurface9_Release(surface2);
9277 IDirect3DSurface9_Release(surface);
9278 IDirect3DCubeTexture9_Release(cube_texture);
9281 refcount = IDirect3DDevice9_Release(device);
9282 ok(!refcount, "Device has %lu references left.\n", refcount);
9284 /* Backbuffer created with D3DFMT_UNKNOWN format. */
9285 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
9286 device_desc.width = 640;
9287 device_desc.height = 480;
9288 device_desc.device_window = window;
9289 device_desc.flags = CREATE_DEVICE_UNKNOWN_BACKBUFFER_FORMAT | CREATE_DEVICE_LOCKABLE_BACKBUFFER;
9291 device = create_device(d3d, window, &device_desc);
9292 ok(!!device, "Failed to create device.\n");
9294 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
9295 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
9297 dc = NULL;
9298 hr = IDirect3DSurface9_GetDC(surface, &dc);
9299 ok(!!dc, "Unexpected DC returned.\n");
9300 ok(SUCCEEDED(hr), "Failed to get backbuffer DC, hr %#lx.\n", hr);
9301 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
9302 ok(SUCCEEDED(hr), "Failed to release backbuffer DC, hr %#lx.\n", hr);
9304 IDirect3DSurface9_Release(surface);
9306 refcount = IDirect3DDevice9_Release(device);
9307 ok(!refcount, "Device has %lu references left.\n", refcount);
9309 IDirect3D9_Release(d3d);
9310 DestroyWindow(window);
9313 static void test_surface_dimensions(void)
9315 IDirect3DSurface9 *surface;
9316 IDirect3DDevice9 *device;
9317 IDirect3D9 *d3d;
9318 ULONG refcount;
9319 HWND window;
9320 HRESULT hr;
9322 window = create_window();
9323 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9324 ok(!!d3d, "Failed to create a D3D object.\n");
9325 if (!(device = create_device(d3d, window, NULL)))
9327 skip("Failed to create a D3D device, skipping tests.\n");
9328 IDirect3D9_Release(d3d);
9329 DestroyWindow(window);
9330 return;
9333 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
9334 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
9335 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
9336 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
9337 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
9338 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
9340 refcount = IDirect3DDevice9_Release(device);
9341 ok(!refcount, "Device has %lu references left.\n", refcount);
9342 IDirect3D9_Release(d3d);
9343 DestroyWindow(window);
9346 static void test_surface_format_null(void)
9348 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
9349 IDirect3DTexture9 *texture;
9350 IDirect3DSurface9 *surface;
9351 IDirect3DSurface9 *rt, *ds;
9352 D3DLOCKED_RECT locked_rect;
9353 IDirect3DDevice9 *device;
9354 D3DSURFACE_DESC desc;
9355 IDirect3D9 *d3d;
9356 ULONG refcount;
9357 HWND window;
9358 HRESULT hr;
9360 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9361 ok(!!d3d, "Failed to create a D3D object.\n");
9363 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9364 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
9365 if (hr != D3D_OK)
9367 skip("No D3DFMT_NULL support, skipping test.\n");
9368 IDirect3D9_Release(d3d);
9369 return;
9372 window = create_window();
9373 if (!(device = create_device(d3d, window, NULL)))
9375 skip("Failed to create a D3D device, skipping tests.\n");
9376 IDirect3D9_Release(d3d);
9377 DestroyWindow(window);
9378 return;
9381 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9382 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
9383 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#lx.\n", hr);
9385 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9386 D3DFMT_NULL, D3DFMT_D24S8);
9387 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#lx.\n", hr);
9389 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
9390 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
9391 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
9393 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
9394 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#lx.\n", hr);
9396 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
9397 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#lx.\n", hr);
9399 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
9400 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
9402 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9403 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
9405 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
9406 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
9408 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
9409 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
9411 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9412 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
9414 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
9415 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
9417 IDirect3DSurface9_Release(rt);
9418 IDirect3DSurface9_Release(ds);
9420 hr = IDirect3DSurface9_GetDesc(surface, &desc);
9421 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#lx.\n", hr);
9422 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
9423 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
9425 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
9426 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
9427 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
9428 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
9430 hr = IDirect3DSurface9_UnlockRect(surface);
9431 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
9433 IDirect3DSurface9_Release(surface);
9435 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
9436 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
9437 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
9438 IDirect3DTexture9_Release(texture);
9440 refcount = IDirect3DDevice9_Release(device);
9441 ok(!refcount, "Device has %lu references left.\n", refcount);
9442 IDirect3D9_Release(d3d);
9443 DestroyWindow(window);
9446 static void test_surface_double_unlock(void)
9448 static const D3DPOOL pools[] =
9450 D3DPOOL_DEFAULT,
9451 D3DPOOL_SCRATCH,
9452 D3DPOOL_SYSTEMMEM,
9454 IDirect3DSurface9 *surface;
9455 IDirect3DDevice9 *device;
9456 D3DSURFACE_DESC desc;
9457 D3DLOCKED_RECT lr;
9458 IDirect3D9 *d3d;
9459 unsigned int i;
9460 ULONG refcount;
9461 HWND window;
9462 HRESULT hr;
9464 window = create_window();
9465 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9466 ok(!!d3d, "Failed to create a D3D object.\n");
9467 if (!(device = create_device(d3d, window, NULL)))
9469 skip("Failed to create a D3D device, skipping tests.\n");
9470 IDirect3D9_Release(d3d);
9471 DestroyWindow(window);
9472 return;
9475 for (i = 0; i < ARRAY_SIZE(pools); ++i)
9477 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
9478 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
9479 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#lx.\n", pools[i], hr);
9481 hr = IDirect3DSurface9_GetDesc(surface, &desc);
9482 ok(hr == D3D_OK, "Pool %#x: Got unexpected hr %#lx.\n", pools[i], hr);
9483 ok(!desc.Usage, "Pool %#x: Got unexpected usage %#lx.\n", pools[i], desc.Usage);
9484 ok(desc.Pool == pools[i], "Pool %#x: Got unexpected pool %#x.\n", pools[i], desc.Pool);
9486 hr = IDirect3DSurface9_UnlockRect(surface);
9487 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, for surface in pool %#x.\n", hr, pools[i]);
9488 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9489 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#lx.\n", pools[i], hr);
9490 hr = IDirect3DSurface9_UnlockRect(surface);
9491 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#lx.\n", pools[i], hr);
9492 hr = IDirect3DSurface9_UnlockRect(surface);
9493 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, for surface in pool %#x.\n", hr, pools[i]);
9495 IDirect3DSurface9_Release(surface);
9498 refcount = IDirect3DDevice9_Release(device);
9499 ok(!refcount, "Device has %lu references left.\n", refcount);
9500 IDirect3D9_Release(d3d);
9501 DestroyWindow(window);
9504 static void test_surface_blocks(void)
9506 static const struct
9508 D3DFORMAT fmt;
9509 const char *name;
9510 unsigned int block_width;
9511 unsigned int block_height;
9512 BOOL broken;
9513 BOOL create_size_checked, core_fmt;
9515 formats[] =
9517 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE, TRUE, TRUE },
9518 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE, TRUE, TRUE },
9519 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE, TRUE, TRUE },
9520 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE, TRUE, TRUE },
9521 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE, TRUE, TRUE },
9522 /* ATI1N and ATI2N have 2x2 blocks on all AMD cards and Geforce 7 cards,
9523 * which doesn't match the format spec. On newer Nvidia cards
9524 * they have the correct 4x4 block size */
9525 {MAKEFOURCC('A','T','I','1'), "ATI1N", 4, 4, TRUE, FALSE, FALSE},
9526 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE, FALSE, FALSE},
9527 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE, FALSE, TRUE },
9528 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE, FALSE, TRUE },
9530 static const struct
9532 D3DPOOL pool;
9533 const char *name;
9534 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
9535 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
9536 BOOL success;
9538 pools[] =
9540 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
9541 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
9542 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
9543 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
9545 static struct
9547 D3DRESOURCETYPE rtype;
9548 const char *type_name;
9549 D3DPOOL pool;
9550 const char *pool_name;
9551 BOOL need_driver_support, need_runtime_support;
9553 create_tests[] =
9555 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
9556 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, TRUE },
9557 /* Managed offscreen plain surfaces are not supported */
9558 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
9560 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
9561 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
9562 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
9563 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
9565 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
9566 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
9567 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
9568 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
9570 IDirect3DTexture9 *texture;
9571 IDirect3DCubeTexture9 *cube_texture;
9572 IDirect3DSurface9 *surface;
9573 D3DLOCKED_RECT locked_rect;
9574 IDirect3DDevice9 *device;
9575 unsigned int i, j, k, w, h;
9576 BOOL surface_only;
9577 IDirect3D9 *d3d;
9578 ULONG refcount;
9579 HWND window;
9580 HRESULT hr;
9581 RECT rect;
9582 BOOL tex_pow2, cube_pow2;
9583 D3DCAPS9 caps;
9584 static const RECT invalid[] =
9586 {60, 60, 60, 68}, /* 0 height */
9587 {60, 60, 68, 60}, /* 0 width */
9588 {68, 60, 60, 68}, /* left > right */
9589 {60, 68, 68, 60}, /* top > bottom */
9590 {-8, 60, 0, 68}, /* left < surface */
9591 {60, -8, 68, 0}, /* top < surface */
9592 {-16, 60, -8, 68}, /* right < surface */
9593 {60, -16, 68, -8}, /* bottom < surface */
9594 {60, 60, 136, 68}, /* right > surface */
9595 {60, 60, 68, 136}, /* bottom > surface */
9596 {136, 60, 144, 68}, /* left > surface */
9597 {60, 136, 68, 144}, /* top > surface */
9600 window = create_window();
9601 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9602 ok(!!d3d, "Failed to create a D3D object.\n");
9603 if (!(device = create_device(d3d, window, NULL)))
9605 skip("Failed to create a D3D device, skipping tests.\n");
9606 IDirect3D9_Release(d3d);
9607 DestroyWindow(window);
9608 return;
9611 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9612 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
9613 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
9614 if (tex_pow2)
9615 tex_pow2 = !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
9616 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
9618 for (i = 0; i < ARRAY_SIZE(formats); ++i)
9620 BOOL tex_support, cube_support, surface_support, format_known, dynamic_tex_support;
9622 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9623 0, D3DRTYPE_TEXTURE, formats[i].fmt);
9624 tex_support = SUCCEEDED(hr);
9625 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9626 0, D3DRTYPE_CUBETEXTURE, formats[i].fmt);
9627 cube_support = SUCCEEDED(hr);
9628 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9629 0, D3DRTYPE_SURFACE, formats[i].fmt);
9630 surface_support = SUCCEEDED(hr);
9632 /* Scratch pool in general allows texture creation even if the driver does
9633 * not support the format. If the format is an extension format that is not
9634 * known to the runtime, like ATI2N, some driver support is required for
9635 * this to work.
9637 * It is also possible that Windows Vista and Windows 7 d3d9 runtimes know
9638 * about ATI2N. I cannot check this because all my Vista+ machines support
9639 * ATI2N in hardware, but none of my WinXP machines do. */
9640 format_known = tex_support || cube_support || surface_support;
9642 for (w = 1; w <= 8; w++)
9644 for (h = 1; h <= 8; h++)
9646 BOOL block_aligned = TRUE;
9647 BOOL size_is_pow2;
9649 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
9650 block_aligned = FALSE;
9652 size_is_pow2 = !(w & (w - 1) || h & (h - 1));
9654 for (j = 0; j < ARRAY_SIZE(create_tests); j++)
9656 BOOL support, pow2;
9657 HRESULT expect_hr;
9658 BOOL may_succeed = FALSE;
9659 IUnknown **check_null;
9661 if (!formats[i].core_fmt)
9663 /* AMD warns against creating ATI2N textures smaller than
9664 * the block size because the runtime cannot calculate the
9665 * correct texture size. Generalize this for all extension
9666 * formats. */
9667 if (w < formats[i].block_width || h < formats[i].block_height)
9668 continue;
9671 texture = (IDirect3DTexture9 *)0xdeadbeef;
9672 cube_texture = (IDirect3DCubeTexture9 *)0xdeadbeef;
9673 surface = (IDirect3DSurface9 *)0xdeadbeef;
9675 switch (create_tests[j].rtype)
9677 case D3DRTYPE_TEXTURE:
9678 check_null = (IUnknown **)&texture;
9679 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1, 0,
9680 formats[i].fmt, create_tests[j].pool, &texture, NULL);
9681 support = tex_support;
9682 pow2 = tex_pow2;
9683 break;
9685 case D3DRTYPE_CUBETEXTURE:
9686 if (w != h)
9687 continue;
9688 check_null = (IUnknown **)&cube_texture;
9689 hr = IDirect3DDevice9_CreateCubeTexture(device, w, 1, 0,
9690 formats[i].fmt, create_tests[j].pool, &cube_texture, NULL);
9691 support = cube_support;
9692 pow2 = cube_pow2;
9693 break;
9695 case D3DRTYPE_SURFACE:
9696 check_null = (IUnknown **)&surface;
9697 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, w, h,
9698 formats[i].fmt, create_tests[j].pool, &surface, NULL);
9699 support = surface_support;
9700 pow2 = FALSE;
9701 break;
9703 default:
9704 check_null = NULL;
9705 pow2 = FALSE;
9706 support = FALSE;
9707 break;
9710 if (create_tests[j].need_driver_support && !support)
9711 expect_hr = D3DERR_INVALIDCALL;
9712 else if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !format_known)
9713 expect_hr = D3DERR_INVALIDCALL;
9714 else if (formats[i].create_size_checked && !block_aligned)
9715 expect_hr = D3DERR_INVALIDCALL;
9716 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
9717 expect_hr = D3DERR_INVALIDCALL;
9718 else
9719 expect_hr = D3D_OK;
9721 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
9722 * does not support it. Accept scratch creation of extension formats on
9723 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
9724 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
9725 * support it. */
9726 if (!formats[i].core_fmt && !format_known && FAILED(expect_hr))
9727 may_succeed = TRUE;
9729 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
9730 "Got unexpected hr %#lx for format %s, pool %s, type %s, size %ux%u.\n",
9731 hr, formats[i].name, create_tests[j].pool_name, create_tests[j].type_name, w, h);
9732 if (FAILED(hr))
9733 ok(*check_null == NULL, "Got object ptr %p, expected NULL.\n", *check_null);
9734 else
9735 IUnknown_Release(*check_null);
9740 surface_only = FALSE;
9741 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9742 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt);
9743 dynamic_tex_support = SUCCEEDED(hr);
9744 if (!dynamic_tex_support)
9746 if (!surface_support)
9748 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
9749 continue;
9751 surface_only = TRUE;
9754 for (j = 0; j < ARRAY_SIZE(pools); ++j)
9756 switch (pools[j].pool)
9758 case D3DPOOL_SYSTEMMEM:
9759 case D3DPOOL_MANAGED:
9760 if (surface_only)
9761 continue;
9762 /* Fall through */
9763 case D3DPOOL_DEFAULT:
9764 if (surface_only)
9766 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
9767 formats[i].fmt, pools[j].pool, &surface, NULL);
9768 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
9770 else
9772 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
9773 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
9774 formats[i].fmt, pools[j].pool, &texture, NULL);
9775 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
9776 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9777 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
9778 IDirect3DTexture9_Release(texture);
9780 break;
9782 case D3DPOOL_SCRATCH:
9783 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
9784 formats[i].fmt, pools[j].pool, &surface, NULL);
9785 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
9786 break;
9788 default:
9789 break;
9792 if (formats[i].block_width > 1)
9794 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
9795 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
9796 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
9797 "Partial block lock %s, expected %s, format %s, pool %s.\n",
9798 SUCCEEDED(hr) ? "succeeded" : "failed",
9799 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
9800 if (SUCCEEDED(hr))
9802 hr = IDirect3DSurface9_UnlockRect(surface);
9803 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
9806 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
9807 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
9808 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
9809 "Partial block lock %s, expected %s, format %s, pool %s.\n",
9810 SUCCEEDED(hr) ? "succeeded" : "failed",
9811 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
9812 if (SUCCEEDED(hr))
9814 hr = IDirect3DSurface9_UnlockRect(surface);
9815 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
9819 if (formats[i].block_height > 1)
9821 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
9822 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
9823 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
9824 "Partial block lock %s, expected %s, format %s, pool %s.\n",
9825 SUCCEEDED(hr) ? "succeeded" : "failed",
9826 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
9827 if (SUCCEEDED(hr))
9829 hr = IDirect3DSurface9_UnlockRect(surface);
9830 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
9833 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
9834 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
9835 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
9836 "Partial block lock %s, expected %s, format %s, pool %s.\n",
9837 SUCCEEDED(hr) ? "succeeded" : "failed",
9838 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
9839 if (SUCCEEDED(hr))
9841 hr = IDirect3DSurface9_UnlockRect(surface);
9842 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
9846 for (k = 0; k < ARRAY_SIZE(invalid); ++k)
9848 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &invalid[k], 0);
9849 ok(FAILED(hr) == !pools[j].success, "Invalid lock %s(%#lx), expected %s, format %s, pool %s, case %u.\n",
9850 SUCCEEDED(hr) ? "succeeded" : "failed", hr, pools[j].success ? "success" : "failure",
9851 formats[i].name, pools[j].name, k);
9852 if (SUCCEEDED(hr))
9854 hr = IDirect3DSurface9_UnlockRect(surface);
9855 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
9859 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
9860 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
9861 ok(SUCCEEDED(hr), "Got unexpected hr %#lx for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
9862 hr = IDirect3DSurface9_UnlockRect(surface);
9863 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
9865 IDirect3DSurface9_Release(surface);
9868 if (!dynamic_tex_support)
9870 skip("Dynamic %s textures not supported, skipping mipmap test.\n", formats[i].name);
9871 continue;
9874 if (formats[i].block_width == 1 && formats[i].block_height == 1)
9875 continue;
9876 if (!formats[i].core_fmt)
9877 continue;
9879 hr = IDirect3DDevice9_CreateTexture(device, formats[i].block_width, formats[i].block_height, 2,
9880 D3DUSAGE_DYNAMIC, formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
9881 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, format %s.\n", hr, formats[i].name);
9883 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, NULL, 0);
9884 ok(SUCCEEDED(hr), "Failed lock texture, hr %#lx.\n", hr);
9885 hr = IDirect3DTexture9_UnlockRect(texture, 1);
9886 ok(SUCCEEDED(hr), "Failed lock texture, hr %#lx.\n", hr);
9888 SetRect(&rect, 0, 0, formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1,
9889 formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1);
9890 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
9891 ok(SUCCEEDED(hr), "Failed lock texture, hr %#lx.\n", hr);
9892 hr = IDirect3DTexture9_UnlockRect(texture, 1);
9893 ok(SUCCEEDED(hr), "Failed lock texture, hr %#lx.\n", hr);
9895 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
9896 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
9897 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
9898 if (SUCCEEDED(hr))
9899 IDirect3DTexture9_UnlockRect(texture, 1);
9901 IDirect3DTexture9_Release(texture);
9904 refcount = IDirect3DDevice9_Release(device);
9905 ok(!refcount, "Device has %lu references left.\n", refcount);
9906 IDirect3D9_Release(d3d);
9907 DestroyWindow(window);
9910 static void test_set_palette(void)
9912 IDirect3DDevice9 *device;
9913 IDirect3D9 *d3d9;
9914 ULONG refcount;
9915 HWND window;
9916 HRESULT hr;
9917 PALETTEENTRY pal[256];
9918 unsigned int i;
9919 D3DCAPS9 caps;
9921 window = create_window();
9922 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
9923 ok(!!d3d9, "Failed to create a D3D object.\n");
9924 if (!(device = create_device(d3d9, window, NULL)))
9926 skip("Failed to create a D3D device, skipping tests.\n");
9927 DestroyWindow(window);
9928 return;
9931 for (i = 0; i < ARRAY_SIZE(pal); i++)
9933 pal[i].peRed = i;
9934 pal[i].peGreen = i;
9935 pal[i].peBlue = i;
9936 pal[i].peFlags = 0xff;
9938 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
9939 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#lx.\n", hr);
9941 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9942 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
9943 for (i = 0; i < ARRAY_SIZE(pal); i++)
9945 pal[i].peRed = i;
9946 pal[i].peGreen = i;
9947 pal[i].peBlue = i;
9948 pal[i].peFlags = i;
9950 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
9952 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
9953 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#lx.\n", hr);
9955 else
9957 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
9958 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
9961 refcount = IDirect3DDevice9_Release(device);
9962 ok(!refcount, "Device has %lu references left.\n", refcount);
9963 IDirect3D9_Release(d3d9);
9964 DestroyWindow(window);
9967 static void test_pinned_buffers(void)
9969 static const struct
9971 DWORD device_flags;
9972 DWORD usage;
9973 D3DPOOL pool;
9975 tests[] =
9977 {CREATE_DEVICE_SWVP_ONLY, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT},
9978 /* This doesn't necessarily return the same address. */
9979 /* {0, 0, D3DPOOL_DEFAULT}, */
9980 {0, 0, D3DPOOL_MANAGED},
9981 {0, 0, D3DPOOL_SYSTEMMEM},
9983 static const unsigned int vertex_count = 1024;
9984 struct device_desc device_desc;
9985 IDirect3DVertexBuffer9 *buffer;
9986 D3DVERTEXBUFFER_DESC desc;
9987 IDirect3DDevice9 *device;
9988 struct vec3 *ptr, *ptr2;
9989 unsigned int i, test;
9990 IDirect3D9 *d3d;
9991 ULONG refcount;
9992 HWND window;
9993 HRESULT hr;
9995 window = create_window();
9996 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9997 ok(!!d3d, "Failed to create a D3D object.\n");
9999 for (test = 0; test < ARRAY_SIZE(tests); ++test)
10001 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
10002 device_desc.device_window = window;
10003 device_desc.width = 640;
10004 device_desc.height = 480;
10005 device_desc.flags = tests[test].device_flags;
10006 if (!(device = create_device(d3d, window, &device_desc)))
10008 skip("Test %u: failed to create a D3D device.\n", test);
10009 continue;
10012 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*ptr),
10013 tests[test].usage, 0, tests[test].pool, &buffer, NULL);
10014 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10015 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
10016 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10017 ok(desc.Pool == tests[test].pool, "Test %u: got unexpected pool %#x.\n", test, desc.Pool);
10018 ok(desc.Usage == tests[test].usage, "Test %u: got unexpected usage %#lx.\n", test, desc.Usage);
10020 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
10021 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10022 for (i = 0; i < vertex_count; ++i)
10024 ptr[i].x = i * 1.0f;
10025 ptr[i].y = i * 2.0f;
10026 ptr[i].z = i * 3.0f;
10028 hr = IDirect3DVertexBuffer9_Unlock(buffer);
10029 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10031 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10032 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10033 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
10034 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10035 hr = IDirect3DDevice9_BeginScene(device);
10036 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10037 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
10038 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10039 hr = IDirect3DDevice9_EndScene(device);
10040 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10042 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
10043 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10044 ok(ptr2 == ptr, "Test %u: got unexpected ptr2 %p, expected %p.\n", test, ptr2, ptr);
10045 for (i = 0; i < vertex_count; ++i)
10047 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
10049 ok(FALSE, "Test %u: got unexpected vertex %u {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n",
10050 test, i, ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
10051 break;
10054 hr = IDirect3DVertexBuffer9_Unlock(buffer);
10055 ok(hr == D3D_OK, "Test %u: got unexpected hr %#lx.\n", test, hr);
10057 IDirect3DVertexBuffer9_Release(buffer);
10058 refcount = IDirect3DDevice9_Release(device);
10059 ok(!refcount, "Test %u: device has %lu references left.\n", test, refcount);
10061 IDirect3D9_Release(d3d);
10062 DestroyWindow(window);
10065 static void test_npot_textures(void)
10067 IDirect3DDevice9 *device = NULL;
10068 IDirect3D9 *d3d9;
10069 ULONG refcount;
10070 HWND window = NULL;
10071 HRESULT hr;
10072 D3DCAPS9 caps;
10073 IDirect3DTexture9 *texture;
10074 IDirect3DCubeTexture9 *cube_texture;
10075 IDirect3DVolumeTexture9 *volume_texture;
10076 struct
10078 D3DPOOL pool;
10079 const char *pool_name;
10080 HRESULT hr;
10082 pools[] =
10084 { D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL },
10085 { D3DPOOL_MANAGED, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL },
10086 { D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL },
10087 { D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", D3D_OK },
10089 unsigned int i, levels;
10090 BOOL tex_pow2, cube_pow2, vol_pow2;
10092 window = create_window();
10093 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
10094 ok(!!d3d9, "Failed to create a D3D object.\n");
10095 if (!(device = create_device(d3d9, window, NULL)))
10097 skip("Failed to create a D3D device, skipping tests.\n");
10098 goto done;
10101 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10102 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
10103 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
10104 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
10105 vol_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
10106 ok(cube_pow2 == tex_pow2, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
10107 ok(vol_pow2 == tex_pow2, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
10109 for (i = 0; i < ARRAY_SIZE(pools); i++)
10111 for (levels = 0; levels <= 2; levels++)
10113 HRESULT expected;
10115 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, levels, 0, D3DFMT_X8R8G8B8,
10116 pools[i].pool, &texture, NULL);
10117 if (!tex_pow2)
10119 expected = D3D_OK;
10121 else if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
10123 if (levels == 1)
10124 expected = D3D_OK;
10125 else
10126 expected = pools[i].hr;
10128 else
10130 expected = pools[i].hr;
10132 ok(hr == expected, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#lx, expected %#lx.\n",
10133 pools[i].pool_name, levels, hr, expected);
10135 if (SUCCEEDED(hr))
10136 IDirect3DTexture9_Release(texture);
10139 hr = IDirect3DDevice9_CreateCubeTexture(device, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
10140 &cube_texture, NULL);
10141 if (tex_pow2)
10143 ok(hr == pools[i].hr, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#lx, expected %#lx.\n",
10144 pools[i].pool_name, hr, pools[i].hr);
10146 else
10148 ok(SUCCEEDED(hr), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#lx, expected %#lx.\n",
10149 pools[i].pool_name, hr, D3D_OK);
10152 if (SUCCEEDED(hr))
10153 IDirect3DCubeTexture9_Release(cube_texture);
10155 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
10156 &volume_texture, NULL);
10157 if (tex_pow2)
10159 ok(hr == pools[i].hr, "CreateVolumeTextur(Depth=3, %s) returned hr %#lx, expected %#lx.\n",
10160 pools[i].pool_name, hr, pools[i].hr);
10162 else
10164 ok(SUCCEEDED(hr), "CreateVolumeTextur(Depth=3, %s) returned hr %#lx, expected %#lx.\n",
10165 pools[i].pool_name, hr, D3D_OK);
10168 if (SUCCEEDED(hr))
10169 IDirect3DVolumeTexture9_Release(volume_texture);
10172 done:
10173 if (device)
10175 refcount = IDirect3DDevice9_Release(device);
10176 ok(!refcount, "Device has %lu references left.\n", refcount);
10178 IDirect3D9_Release(d3d9);
10179 DestroyWindow(window);
10183 static void test_vidmem_accounting(void)
10185 IDirect3DDevice9 *device;
10186 IDirect3D9 *d3d9;
10187 ULONG refcount;
10188 HWND window;
10189 HRESULT hr = D3D_OK;
10190 IDirect3DTexture9 *textures[20];
10191 unsigned int i;
10192 UINT vidmem_start, vidmem_end, diff;
10194 window = create_window();
10195 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
10196 ok(!!d3d9, "Failed to create a D3D object.\n");
10197 if (!(device = create_device(d3d9, window, NULL)))
10199 skip("Failed to create a D3D device, skipping tests.\n");
10200 IDirect3D9_Release(d3d9);
10201 DestroyWindow(window);
10202 return;
10205 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
10206 memset(textures, 0, sizeof(textures));
10207 for (i = 0; i < ARRAY_SIZE(textures); i++)
10209 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
10210 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
10211 /* D3DERR_OUTOFVIDEOMEMORY is returned when the card runs out of video memory
10212 * E_FAIL is returned on address space or system memory exhaustion */
10213 ok(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY,
10214 "Failed to create texture, hr %#lx.\n", hr);
10216 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
10218 ok(vidmem_start > vidmem_end, "Expected available texture memory to decrease during texture creation.\n");
10219 diff = vidmem_start - vidmem_end;
10220 ok(diff > 1024 * 1024 * 2 * i, "Expected a video memory difference of at least %u MB, got %u MB.\n",
10221 2 * i, diff / 1024 / 1024);
10223 for (i = 0; i < ARRAY_SIZE(textures); i++)
10225 if (textures[i])
10226 IDirect3DTexture9_Release(textures[i]);
10229 refcount = IDirect3DDevice9_Release(device);
10230 ok(!refcount, "Device has %lu references left.\n", refcount);
10231 IDirect3D9_Release(d3d9);
10232 DestroyWindow(window);
10235 static void test_volume_locking(void)
10237 IDirect3DDevice9 *device;
10238 IDirect3D9 *d3d9;
10239 HWND window;
10240 HRESULT hr;
10241 IDirect3DVolumeTexture9 *texture;
10242 unsigned int i;
10243 D3DLOCKED_BOX locked_box;
10244 ULONG refcount;
10245 D3DCAPS9 caps;
10246 static const struct
10248 D3DPOOL pool;
10249 DWORD usage;
10250 HRESULT create_hr, lock_hr;
10252 tests[] =
10254 { D3DPOOL_DEFAULT, 0, D3D_OK, D3DERR_INVALIDCALL },
10255 { D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
10256 { D3DPOOL_SYSTEMMEM, 0, D3D_OK, D3D_OK },
10257 { D3DPOOL_SYSTEMMEM, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
10258 { D3DPOOL_MANAGED, 0, D3D_OK, D3D_OK },
10259 { D3DPOOL_MANAGED, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
10260 { D3DPOOL_SCRATCH, 0, D3D_OK, D3D_OK },
10261 { D3DPOOL_SCRATCH, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
10264 window = create_window();
10265 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
10266 ok(!!d3d9, "Failed to create a D3D object.\n");
10267 if (!(device = create_device(d3d9, window, NULL)))
10269 skip("Failed to create a D3D device, skipping tests.\n");
10270 IDirect3D9_Release(d3d9);
10271 DestroyWindow(window);
10272 return;
10275 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10276 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
10277 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
10279 skip("Volume textures not supported, skipping test.\n");
10280 goto out;
10283 for (i = 0; i < ARRAY_SIZE(tests); i++)
10285 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, tests[i].usage,
10286 D3DFMT_A8R8G8B8, tests[i].pool, &texture, NULL);
10287 ok(hr == tests[i].create_hr, "Creating volume texture pool=%u, usage=%#lx returned %#lx, expected %#lx.\n",
10288 tests[i].pool, tests[i].usage, hr, tests[i].create_hr);
10289 if (FAILED(hr))
10290 continue;
10292 locked_box.pBits = (void *)0xdeadbeef;
10293 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
10294 ok(hr == tests[i].lock_hr, "Lock returned %#lx, expected %#lx.\n", hr, tests[i].lock_hr);
10295 if (SUCCEEDED(hr))
10297 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10298 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10300 else
10302 ok(locked_box.pBits == NULL, "Failed lock set pBits = %p, expected NULL.\n", locked_box.pBits);
10304 IDirect3DVolumeTexture9_Release(texture);
10307 out:
10308 refcount = IDirect3DDevice9_Release(device);
10309 ok(!refcount, "Device has %lu references left.\n", refcount);
10310 IDirect3D9_Release(d3d9);
10311 DestroyWindow(window);
10314 static void test_update_texture_pool(void)
10316 static const struct
10318 D3DPOOL pool;
10319 DWORD usage;
10321 tests[] =
10323 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC},
10324 {D3DPOOL_MANAGED, 0},
10325 {D3DPOOL_SYSTEMMEM, 0},
10326 {D3DPOOL_SCRATCH, 0},
10329 unsigned int expect_colour, colour, i, j;
10330 IDirect3DVolumeTexture9 *src_3d, *dst_3d;
10331 IDirect3DTexture9 *src_2d, *dst_2d;
10332 D3DLOCKED_RECT locked_rect;
10333 IDirect3DDevice9 *device;
10334 D3DLOCKED_BOX locked_box;
10335 IDirect3D9 *d3d9;
10336 ULONG refcount;
10337 D3DCAPS9 caps;
10338 HWND window;
10339 HRESULT hr;
10341 window = create_window();
10342 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
10343 ok(!!d3d9, "Failed to create a D3D object.\n");
10344 if (!(device = create_device(d3d9, window, NULL)))
10346 skip("Failed to create a D3D device, skipping tests.\n");
10347 IDirect3D9_Release(d3d9);
10348 DestroyWindow(window);
10349 return;
10352 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10353 ok(hr == S_OK, "Failed to get caps, hr %#lx.\n", hr);
10355 for (i = 0; i < ARRAY_SIZE(tests); ++i)
10357 for (j = 0; j < ARRAY_SIZE(tests); ++j)
10359 winetest_push_context("Source test %u, destination test %u", i, j);
10361 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1,
10362 tests[i].usage, D3DFMT_A8R8G8B8, tests[i].pool, &src_2d, NULL);
10363 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10364 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1,
10365 tests[j].usage, D3DFMT_A8R8G8B8, tests[j].pool, &dst_2d, NULL);
10366 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10368 hr = IDirect3DTexture9_LockRect(src_2d, 0, &locked_rect, NULL, 0);
10369 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10370 *((DWORD *)locked_rect.pBits) = 0x11223344;
10371 hr = IDirect3DTexture9_UnlockRect(src_2d, 0);
10372 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10374 hr = IDirect3DTexture9_LockRect(dst_2d, 0, &locked_rect, NULL, 0);
10375 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10376 *((DWORD *)locked_rect.pBits) = 0x44332211;
10377 hr = IDirect3DTexture9_UnlockRect(dst_2d, 0);
10378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10380 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src_2d,
10381 (IDirect3DBaseTexture9 *)dst_2d);
10382 if (tests[i].pool == D3DPOOL_SYSTEMMEM && tests[j].pool == D3DPOOL_DEFAULT)
10384 expect_colour = 0x11223344;
10385 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10387 else
10389 expect_colour = 0x44332211;
10390 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
10393 hr = IDirect3DTexture9_LockRect(dst_2d, 0, &locked_rect, NULL, 0);
10394 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10395 colour = *((DWORD *)locked_rect.pBits);
10396 ok(colour == expect_colour, "Expected colour %08x, got %08x.\n", expect_colour, colour);
10397 hr = IDirect3DTexture9_UnlockRect(dst_2d, 0);
10398 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10400 IDirect3DTexture9_Release(src_2d);
10401 IDirect3DTexture9_Release(dst_2d);
10403 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
10404 continue;
10406 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1,
10407 tests[i].usage, D3DFMT_A8R8G8B8, tests[i].pool, &src_3d, NULL);
10408 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10409 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1,
10410 tests[j].usage, D3DFMT_A8R8G8B8, tests[j].pool, &dst_3d, NULL);
10411 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10413 hr = IDirect3DVolumeTexture9_LockBox(src_3d, 0, &locked_box, NULL, 0);
10414 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10415 *((DWORD *)locked_box.pBits) = 0x11223344;
10416 hr = IDirect3DVolumeTexture9_UnlockBox(src_3d, 0);
10417 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10419 hr = IDirect3DVolumeTexture9_LockBox(dst_3d, 0, &locked_box, NULL, 0);
10420 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10421 *((DWORD *)locked_box.pBits) = 0x44332211;
10422 hr = IDirect3DVolumeTexture9_UnlockBox(dst_3d, 0);
10423 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10425 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src_3d,
10426 (IDirect3DBaseTexture9 *)dst_3d);
10427 if (tests[i].pool == D3DPOOL_SYSTEMMEM && tests[j].pool == D3DPOOL_DEFAULT)
10429 expect_colour = 0x11223344;
10430 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10432 else
10434 expect_colour = 0x44332211;
10435 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
10438 hr = IDirect3DVolumeTexture9_LockBox(dst_3d, 0, &locked_box, NULL, 0);
10439 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10440 colour = *((DWORD *)locked_box.pBits);
10441 ok(colour == expect_colour, "Expected colour %08x, got %08x.\n", expect_colour, colour);
10442 hr = IDirect3DVolumeTexture9_UnlockBox(dst_3d, 0);
10443 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10445 IDirect3DVolumeTexture9_Release(src_3d);
10446 IDirect3DVolumeTexture9_Release(dst_3d);
10448 winetest_pop_context();
10452 refcount = IDirect3DDevice9_Release(device);
10453 ok(!refcount, "Device has %lu references left.\n", refcount);
10454 IDirect3D9_Release(d3d9);
10455 DestroyWindow(window);
10458 static void test_update_volumetexture(void)
10460 D3DADAPTER_IDENTIFIER9 identifier;
10461 IDirect3DDevice9 *device;
10462 IDirect3D9 *d3d9;
10463 HWND window;
10464 HRESULT hr;
10465 IDirect3DVolumeTexture9 *src, *dst;
10466 unsigned int i;
10467 ULONG refcount;
10468 D3DCAPS9 caps;
10469 BOOL is_warp;
10471 static const struct
10473 UINT src_size, dst_size;
10474 UINT src_lvl, dst_lvl;
10475 D3DFORMAT src_fmt, dst_fmt;
10477 tests[] =
10479 { 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
10480 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
10481 { 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
10482 { 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
10483 { 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
10484 { 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different level count */
10485 { 4, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different size */
10486 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8 }, /* Different format */
10489 window = create_window();
10490 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
10491 ok(!!d3d9, "Failed to create a D3D object.\n");
10492 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
10493 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
10494 is_warp = adapter_is_warp(&identifier);
10495 if (!(device = create_device(d3d9, window, NULL)))
10497 skip("Failed to create a D3D device, skipping tests.\n");
10498 IDirect3D9_Release(d3d9);
10499 DestroyWindow(window);
10500 return;
10503 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10504 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
10505 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)|| !(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
10507 skip("Mipmapped volume maps not supported.\n");
10508 goto out;
10511 for (i = 0; i < ARRAY_SIZE(tests); i++)
10513 hr = IDirect3DDevice9_CreateVolumeTexture(device,
10514 tests[i].src_size, tests[i].src_size, tests[i].src_size,
10515 tests[i].src_lvl, 0, tests[i].src_fmt, D3DPOOL_SYSTEMMEM, &src, NULL);
10516 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx, case %u.\n", hr, i);
10517 hr = IDirect3DDevice9_CreateVolumeTexture(device,
10518 tests[i].dst_size, tests[i].dst_size, tests[i].dst_size,
10519 tests[i].dst_lvl, 0, tests[i].dst_fmt, D3DPOOL_DEFAULT, &dst, NULL);
10520 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx, case %u.\n", hr, i);
10522 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
10523 todo_wine_if (FAILED(hr))
10524 ok(SUCCEEDED(hr) || (is_warp && (i == 6 || i == 7)), /* Fails with Win10 WARP driver */
10525 "Failed to update texture, hr %#lx, case %u.\n", hr, i);
10527 IDirect3DVolumeTexture9_Release(src);
10528 IDirect3DVolumeTexture9_Release(dst);
10531 /* As far as I can see, UpdateTexture on non-matching texture behaves like a memcpy. The raw data
10532 * stays the same in a format change, a 2x2x1 texture is copied into the first row of a 4x4x1 texture,
10533 * etc. I could not get it to segfault, but the nonexistent 5th pixel of a 2x2x1 texture is copied into
10534 * pixel 1x2x1 of a 4x4x1 texture, demonstrating a read beyond the texture's end. I suspect any bad
10535 * memory access is silently ignored by the runtime, in the kernel or on the GPU.
10537 * I'm not adding tests for this behavior until an application needs it. */
10539 out:
10540 refcount = IDirect3DDevice9_Release(device);
10541 ok(!refcount, "Device has %lu references left.\n", refcount);
10542 IDirect3D9_Release(d3d9);
10543 DestroyWindow(window);
10546 static void test_create_rt_ds_fail(void)
10548 IDirect3DDevice9 *device;
10549 HWND window;
10550 HRESULT hr;
10551 ULONG refcount;
10552 IDirect3D9 *d3d9;
10553 IDirect3DSurface9 *surface;
10555 window = create_window();
10556 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
10557 ok(!!d3d9, "Failed to create a D3D object.\n");
10558 if (!(device = create_device(d3d9, window, NULL)))
10560 skip("Failed to create a D3D device, skipping tests.\n");
10561 IDirect3D9_Release(d3d9);
10562 DestroyWindow(window);
10563 return;
10566 /* Output pointer == NULL segfaults on Windows. */
10568 surface = (IDirect3DSurface9 *)0xdeadbeef;
10569 hr = IDirect3DDevice9_CreateRenderTarget(device, 4, 4, D3DFMT_D16,
10570 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
10571 ok(hr == D3DERR_INVALIDCALL, "Creating a D16 render target returned hr %#lx.\n", hr);
10572 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
10573 if (SUCCEEDED(hr))
10574 IDirect3DSurface9_Release(surface);
10576 surface = (IDirect3DSurface9 *)0xdeadbeef;
10577 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 4, 4, D3DFMT_A8R8G8B8,
10578 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
10579 ok(hr == D3DERR_INVALIDCALL, "Creating a A8R8G8B8 depth stencil returned hr %#lx.\n", hr);
10580 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
10581 if (SUCCEEDED(hr))
10582 IDirect3DSurface9_Release(surface);
10584 refcount = IDirect3DDevice9_Release(device);
10585 ok(!refcount, "Device has %lu references left.\n", refcount);
10586 IDirect3D9_Release(d3d9);
10587 DestroyWindow(window);
10590 static void test_volume_blocks(void)
10592 IDirect3DDevice9 *device;
10593 IDirect3D9 *d3d9;
10594 ULONG refcount;
10595 HWND window;
10596 HRESULT hr;
10597 D3DCAPS9 caps;
10598 IDirect3DVolumeTexture9 *texture;
10599 unsigned int w, h, d, i, j;
10600 static const struct
10602 D3DFORMAT fmt;
10603 const char *name;
10604 unsigned int block_width;
10605 unsigned int block_height;
10606 unsigned int block_depth;
10607 unsigned int block_size;
10608 unsigned int broken;
10609 BOOL create_size_checked, core_fmt;
10611 formats[] =
10613 /* Scratch volumes enforce DXTn block locks, unlike their surface counterparts.
10614 * ATI2N and YUV blocks are not enforced on any tested card (r200, gtx 460). */
10615 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 1, 8, 0, TRUE, TRUE },
10616 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 1, 16, 0, TRUE, TRUE },
10617 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 1, 16, 0, TRUE, TRUE },
10618 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 1, 16, 0, TRUE, TRUE },
10619 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, 0, TRUE, TRUE },
10620 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, 0, TRUE, TRUE },
10621 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
10622 * which doesn't match the format spec. On newer Nvidia cards
10623 * it has the correct 4x4 block size.
10624 * ATI1N volume textures are only supported by AMD GPUs right
10625 * now and locking offsets seem just wrong. */
10626 {MAKEFOURCC('A','T','I','1'), "ATI1N", 4, 4, 1, 8, 2, FALSE, FALSE},
10627 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, 1, 16, 1, FALSE, FALSE},
10628 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, 1, 4, 1, FALSE, TRUE },
10629 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, 1, 4, 1, FALSE, TRUE },
10631 static const struct
10633 D3DPOOL pool;
10634 const char *name;
10635 BOOL need_driver_support, need_runtime_support;
10637 create_tests[] =
10639 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
10640 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
10641 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE, FALSE},
10642 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
10644 static const struct
10646 unsigned int x, y, z, x2, y2, z2;
10648 offset_tests[] =
10650 {0, 0, 0, 8, 8, 8},
10651 {0, 0, 3, 8, 8, 8},
10652 {0, 4, 0, 8, 8, 8},
10653 {0, 4, 3, 8, 8, 8},
10654 {4, 0, 0, 8, 8, 8},
10655 {4, 0, 3, 8, 8, 8},
10656 {4, 4, 0, 8, 8, 8},
10657 {4, 4, 3, 8, 8, 8},
10659 D3DBOX box;
10660 D3DLOCKED_BOX locked_box;
10661 BYTE *base;
10662 INT expected_row_pitch, expected_slice_pitch;
10663 BOOL support;
10664 BOOL pow2;
10665 unsigned int offset, expected_offset;
10667 window = create_window();
10668 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
10669 ok(!!d3d9, "Failed to create a D3D object.\n");
10670 if (!(device = create_device(d3d9, window, NULL)))
10672 skip("Failed to create a D3D device, skipping tests.\n");
10673 IDirect3D9_Release(d3d9);
10674 DestroyWindow(window);
10675 return;
10677 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10678 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
10679 pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
10681 for (i = 0; i < ARRAY_SIZE(formats); i++)
10683 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10684 0, D3DRTYPE_VOLUMETEXTURE, formats[i].fmt);
10685 support = SUCCEEDED(hr);
10687 /* Test creation restrictions */
10688 for (w = 1; w <= 8; w++)
10690 for (h = 1; h <= 8; h++)
10692 for (d = 1; d <= 8; d++)
10694 HRESULT expect_hr;
10695 BOOL size_is_pow2;
10696 BOOL block_aligned = TRUE;
10698 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
10699 block_aligned = FALSE;
10701 size_is_pow2 = !((w & (w - 1)) || (h & (h - 1)) || (d & (d - 1)));
10703 for (j = 0; j < ARRAY_SIZE(create_tests); j++)
10705 BOOL may_succeed = FALSE;
10707 if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !support)
10708 expect_hr = D3DERR_INVALIDCALL;
10709 else if (formats[i].create_size_checked && !block_aligned)
10710 expect_hr = D3DERR_INVALIDCALL;
10711 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
10712 expect_hr = D3DERR_INVALIDCALL;
10713 else if (create_tests[j].need_driver_support && !support)
10714 expect_hr = D3DERR_INVALIDCALL;
10715 else
10716 expect_hr = D3D_OK;
10718 texture = (IDirect3DVolumeTexture9 *)0xdeadbeef;
10719 hr = IDirect3DDevice9_CreateVolumeTexture(device, w, h, d, 1, 0,
10720 formats[i].fmt, create_tests[j].pool, &texture, NULL);
10722 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
10723 * does not support it. Accept scratch creation of extension formats on
10724 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
10725 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
10726 * support it. */
10727 if (!formats[i].core_fmt && !support && FAILED(expect_hr))
10728 may_succeed = TRUE;
10730 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
10731 "Got unexpected hr %#lx for format %s, pool %s, size %ux%ux%u.\n",
10732 hr, formats[i].name, create_tests[j].name, w, h, d);
10734 if (FAILED(hr))
10735 ok(texture == NULL, "Got texture ptr %p, expected NULL.\n", texture);
10736 else
10737 IDirect3DVolumeTexture9_Release(texture);
10743 if (!support && !formats[i].core_fmt)
10744 continue;
10746 hr = IDirect3DDevice9_CreateVolumeTexture(device, 24, 8, 8, 1, 0,
10747 formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
10748 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
10750 /* Test lockrect offset */
10751 for (j = 0; j < ARRAY_SIZE(offset_tests); j++)
10753 unsigned int bytes_per_pixel;
10754 bytes_per_pixel = formats[i].block_size / (formats[i].block_width * formats[i].block_height);
10756 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
10757 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10759 base = locked_box.pBits;
10760 if (formats[i].broken == 1)
10762 expected_row_pitch = bytes_per_pixel * 24;
10764 else if (formats[i].broken == 2)
10766 expected_row_pitch = 24;
10768 else
10770 expected_row_pitch = (24 /* tex width */ + formats[i].block_height - 1) / formats[i].block_width
10771 * formats[i].block_size;
10773 ok(locked_box.RowPitch == expected_row_pitch, "Got unexpected row pitch %d for format %s, expected %d.\n",
10774 locked_box.RowPitch, formats[i].name, expected_row_pitch);
10776 if (formats[i].broken)
10778 expected_slice_pitch = expected_row_pitch * 8;
10780 else
10782 expected_slice_pitch = (8 /* tex height */ + formats[i].block_depth - 1) / formats[i].block_height
10783 * expected_row_pitch;
10785 ok(locked_box.SlicePitch == expected_slice_pitch,
10786 "Got unexpected slice pitch %d for format %s, expected %d.\n",
10787 locked_box.SlicePitch, formats[i].name, expected_slice_pitch);
10789 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10790 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx, j %u.\n", hr, j);
10792 box.Left = offset_tests[j].x;
10793 box.Top = offset_tests[j].y;
10794 box.Front = offset_tests[j].z;
10795 box.Right = offset_tests[j].x2;
10796 box.Bottom = offset_tests[j].y2;
10797 box.Back = offset_tests[j].z2;
10798 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
10799 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx, j %u.\n", hr, j);
10801 offset = (BYTE *)locked_box.pBits - base;
10802 if (formats[i].broken == 1)
10804 expected_offset = box.Front * expected_slice_pitch
10805 + box.Top * expected_row_pitch
10806 + box.Left * bytes_per_pixel;
10808 else if (formats[i].broken == 2)
10810 expected_offset = box.Front * expected_slice_pitch
10811 + box.Top * expected_row_pitch
10812 + box.Left;
10814 else
10816 expected_offset = (box.Front / formats[i].block_depth) * expected_slice_pitch
10817 + (box.Top / formats[i].block_height) * expected_row_pitch
10818 + (box.Left / formats[i].block_width) * formats[i].block_size;
10820 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u, box start %ux%ux%u.\n",
10821 offset, formats[i].name, expected_offset, box.Left, box.Top, box.Front);
10823 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10824 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10827 /* Test partial block locks */
10828 box.Front = 0;
10829 box.Back = 1;
10830 if (formats[i].block_width > 1)
10832 box.Left = formats[i].block_width >> 1;
10833 box.Top = 0;
10834 box.Right = formats[i].block_width;
10835 box.Bottom = formats[i].block_height;
10836 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
10837 ok(FAILED(hr) || broken(formats[i].broken),
10838 "Partial block lock succeeded, expected failure, format %s.\n",
10839 formats[i].name);
10840 if (SUCCEEDED(hr))
10842 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10843 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10846 box.Left = 0;
10847 box.Top = 0;
10848 box.Right = formats[i].block_width >> 1;
10849 box.Bottom = formats[i].block_height;
10850 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
10851 ok(FAILED(hr) || broken(formats[i].broken),
10852 "Partial block lock succeeded, expected failure, format %s.\n",
10853 formats[i].name);
10854 if (SUCCEEDED(hr))
10856 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10857 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10861 if (formats[i].block_height > 1)
10863 box.Left = 0;
10864 box.Top = formats[i].block_height >> 1;
10865 box.Right = formats[i].block_width;
10866 box.Bottom = formats[i].block_height;
10867 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
10868 ok(FAILED(hr) || broken(formats[i].broken),
10869 "Partial block lock succeeded, expected failure, format %s.\n",
10870 formats[i].name);
10871 if (SUCCEEDED(hr))
10873 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10874 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10877 box.Left = 0;
10878 box.Top = 0;
10879 box.Right = formats[i].block_width;
10880 box.Bottom = formats[i].block_height >> 1;
10881 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
10882 ok(FAILED(hr) || broken(formats[i].broken),
10883 "Partial block lock succeeded, expected failure, format %s.\n",
10884 formats[i].name);
10885 if (SUCCEEDED(hr))
10887 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10888 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10892 /* Test full block lock */
10893 box.Left = 0;
10894 box.Top = 0;
10895 box.Right = formats[i].block_width;
10896 box.Bottom = formats[i].block_height;
10897 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
10898 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
10899 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10900 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10902 IDirect3DVolumeTexture9_Release(texture);
10904 /* Test mipmap locks. Don't do this with ATI2N, AMD warns that the runtime
10905 * does not allocate surfaces smaller than the blocksize properly. */
10906 if ((formats[i].block_width > 1 || formats[i].block_height > 1) && formats[i].core_fmt)
10908 hr = IDirect3DDevice9_CreateVolumeTexture(device, formats[i].block_width, formats[i].block_height,
10909 2, 2, 0, formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
10910 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
10912 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, NULL, 0);
10913 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#lx.\n", hr);
10914 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
10915 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10917 box.Left = box.Top = box.Front = 0;
10918 box.Right = formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1;
10919 box.Bottom = formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1;
10920 box.Back = 1;
10921 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
10922 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#lx.\n", hr);
10923 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
10924 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10926 box.Right = formats[i].block_width;
10927 box.Bottom = formats[i].block_height;
10928 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
10929 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10930 if (SUCCEEDED(hr))
10931 IDirect3DVolumeTexture9_UnlockBox(texture, 1);
10933 IDirect3DVolumeTexture9_Release(texture);
10937 refcount = IDirect3DDevice9_Release(device);
10938 ok(!refcount, "Device has %lu references left.\n", refcount);
10939 IDirect3D9_Release(d3d9);
10940 DestroyWindow(window);
10943 static void test_lockbox_invalid(void)
10945 static const struct
10947 D3DBOX box;
10948 HRESULT result;
10950 test_data[] =
10952 {{0, 0, 2, 2, 0, 1}, D3D_OK}, /* Valid */
10953 {{0, 0, 4, 4, 0, 1}, D3D_OK}, /* Valid */
10954 {{0, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* 0 height */
10955 {{0, 0, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* 0 width */
10956 {{0, 0, 4, 4, 1, 1}, D3DERR_INVALIDCALL}, /* 0 depth */
10957 {{4, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > right */
10958 {{0, 4, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* top > bottom */
10959 {{0, 0, 4, 4, 1, 0}, D3DERR_INVALIDCALL}, /* back > front */
10960 {{0, 0, 8, 4, 0, 1}, D3DERR_INVALIDCALL}, /* right > surface */
10961 {{0, 0, 4, 8, 0, 1}, D3DERR_INVALIDCALL}, /* bottom > surface */
10962 {{0, 0, 4, 4, 0, 3}, D3DERR_INVALIDCALL}, /* back > surface */
10963 {{8, 0, 16, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > surface */
10964 {{0, 8, 4, 16, 0, 1}, D3DERR_INVALIDCALL}, /* top > surface */
10965 {{0, 0, 4, 4, 2, 4}, D3DERR_INVALIDCALL}, /* top > surface */
10967 static const D3DBOX test_boxt_2 = {2, 2, 4, 4, 0, 1};
10968 IDirect3DVolumeTexture9 *texture = NULL;
10969 D3DLOCKED_BOX locked_box;
10970 IDirect3DDevice9 *device;
10971 IDirect3D9 *d3d;
10972 unsigned int i;
10973 ULONG refcount;
10974 HWND window;
10975 BYTE *base;
10976 HRESULT hr;
10978 window = create_window();
10979 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10980 ok(!!d3d, "Failed to create a D3D object.\n");
10981 if (!(device = create_device(d3d, window, NULL)))
10983 skip("Failed to create a D3D device, skipping tests.\n");
10984 IDirect3D9_Release(d3d);
10985 DestroyWindow(window);
10986 return;
10989 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0,
10990 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
10991 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
10992 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
10993 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
10994 base = locked_box.pBits;
10995 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
10996 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
10998 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
11000 unsigned int offset, expected_offset;
11001 const D3DBOX *box = &test_data[i].box;
11003 locked_box.pBits = (BYTE *)0xdeadbeef;
11004 locked_box.RowPitch = 0xdeadbeef;
11005 locked_box.SlicePitch = 0xdeadbeef;
11007 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, box, 0);
11008 /* Unlike surfaces, volumes properly check the box even in Windows XP */
11009 ok(hr == test_data[i].result,
11010 "Got unexpected hr %#lx with box [%u, %u, %u]->[%u, %u, %u], expected %#lx.\n",
11011 hr, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back,
11012 test_data[i].result);
11013 if (FAILED(hr))
11014 continue;
11016 offset = (BYTE *)locked_box.pBits - base;
11017 expected_offset = box->Front * locked_box.SlicePitch + box->Top * locked_box.RowPitch + box->Left * 4;
11018 ok(offset == expected_offset,
11019 "Got unexpected offset %u (expected %u) for rect [%u, %u, %u]->[%u, %u, %u].\n",
11020 offset, expected_offset, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back);
11022 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
11023 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
11026 /* locked_box = NULL throws an exception on Windows */
11027 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
11028 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
11029 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
11030 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11031 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
11032 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
11033 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
11034 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11036 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
11037 ok(hr == D3D_OK, "Got unexpected hr %#lx for rect [%u, %u, %u]->[%u, %u, %u].\n",
11038 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
11039 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
11040 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
11041 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for rect [%u, %u, %u]->[%u, %u, %u].\n",
11042 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
11043 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
11044 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_boxt_2, 0);
11045 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx for rect [%u, %u, %u]->[%u, %u, %u].\n",
11046 hr, test_boxt_2.Left, test_boxt_2.Top, test_boxt_2.Front,
11047 test_boxt_2.Right, test_boxt_2.Bottom, test_boxt_2.Back);
11048 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
11049 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
11051 IDirect3DVolumeTexture9_Release(texture);
11053 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, D3DUSAGE_WRITEONLY,
11054 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
11055 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11057 refcount = IDirect3DDevice9_Release(device);
11058 ok(!refcount, "Device has %lu references left.\n", refcount);
11059 IDirect3D9_Release(d3d);
11060 DestroyWindow(window);
11063 static void test_shared_handle(void)
11065 IDirect3DDevice9 *device;
11066 IDirect3D9 *d3d;
11067 ULONG refcount;
11068 HWND window;
11069 HRESULT hr;
11070 /* Native d3d9ex refuses to create a shared texture if the texture pointer
11071 * is not initialized to NULL. Make sure this doesn't cause issues here. */
11072 IDirect3DTexture9 *texture = NULL;
11073 IDirect3DSurface9 *surface = NULL;
11074 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
11075 IDirect3DIndexBuffer9 *index_buffer = NULL;
11076 HANDLE handle = NULL;
11077 void *mem;
11078 D3DCAPS9 caps;
11080 window = create_window();
11081 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11082 ok(!!d3d, "Failed to create a D3D object.\n");
11083 if (!(device = create_device(d3d, window, NULL)))
11085 skip("Failed to create a D3D device, skipping tests.\n");
11086 IDirect3D9_Release(d3d);
11087 DestroyWindow(window);
11088 return;
11091 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11092 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
11093 mem = malloc(128 * 128 * 4);
11095 /* Windows XP returns E_NOTIMPL, Windows 7 returns INVALIDCALL, except for
11096 * CreateVertexBuffer, where it returns NOTAVAILABLE. */
11097 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
11098 D3DPOOL_DEFAULT, &texture, &handle);
11099 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11100 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
11101 D3DPOOL_SYSTEMMEM, &texture, &mem);
11102 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11104 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
11105 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, &handle);
11106 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11107 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
11108 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, &mem);
11109 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11111 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
11112 &vertex_buffer, &handle);
11113 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11114 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
11115 &vertex_buffer, &mem);
11116 ok(hr == E_NOTIMPL || broken(hr == D3DERR_NOTAVAILABLE), "Got unexpected hr %#lx.\n", hr);
11118 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
11119 &index_buffer, &handle);
11120 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11121 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
11122 &index_buffer, &mem);
11123 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11125 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11127 IDirect3DCubeTexture9 *cube_texture = NULL;
11128 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
11129 D3DPOOL_DEFAULT, &cube_texture, &handle);
11130 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11131 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
11132 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
11133 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11136 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
11138 IDirect3DVolumeTexture9 *volume_texture = NULL;
11139 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
11140 D3DPOOL_DEFAULT, &volume_texture, &handle);
11141 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11142 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
11143 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
11144 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11147 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
11148 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
11149 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11151 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24X8,
11152 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
11153 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
11155 free(mem);
11156 refcount = IDirect3DDevice9_Release(device);
11157 ok(!refcount, "Device has %lu references left.\n", refcount);
11158 IDirect3D9_Release(d3d);
11159 DestroyWindow(window);
11162 static void test_pixel_format(void)
11164 int format, test_format;
11165 PIXELFORMATDESCRIPTOR pfd;
11166 IDirect3D9 *d3d9 = NULL;
11167 IDirect3DDevice9 *device = NULL;
11168 HWND hwnd, hwnd2, hwnd3;
11169 HDC hdc, hdc2, hdc3;
11170 ULONG refcount;
11171 HMODULE gl;
11172 HRESULT hr;
11173 BOOL ret;
11175 static const float point[] = {0.0f, 0.0f, 0.0f};
11177 hwnd = create_window();
11178 ok(!!hwnd, "Failed to create window.\n");
11179 hwnd2 = create_window();
11180 ok(!!hwnd2, "Failed to create window.\n");
11182 hdc = GetDC(hwnd);
11183 ok(!!hdc, "Failed to get DC.\n");
11184 hdc2 = GetDC(hwnd2);
11185 ok(!!hdc2, "Failed to get DC.\n");
11187 gl = LoadLibraryA("opengl32.dll");
11188 ok(!!gl, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
11190 format = GetPixelFormat(hdc);
11191 ok(format == 0, "new window has pixel format %d\n", format);
11193 ZeroMemory(&pfd, sizeof(pfd));
11194 pfd.nSize = sizeof(pfd);
11195 pfd.nVersion = 1;
11196 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
11197 pfd.iPixelType = PFD_TYPE_RGBA;
11198 pfd.iLayerType = PFD_MAIN_PLANE;
11199 format = ChoosePixelFormat(hdc, &pfd);
11200 if (format <= 0)
11202 skip("no pixel format available\n");
11203 goto cleanup;
11206 if (!SetPixelFormat(hdc, format, &pfd) || GetPixelFormat(hdc) != format)
11208 skip("failed to set pixel format\n");
11209 goto cleanup;
11212 if (!SetPixelFormat(hdc2, format, &pfd) || GetPixelFormat(hdc2) != format)
11214 skip("failed to set pixel format on second window\n");
11215 goto cleanup;
11218 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
11219 ok(!!d3d9, "Failed to create a D3D object.\n");
11221 test_format = GetPixelFormat(hdc);
11222 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11224 if (!(device = create_device(d3d9, hwnd, NULL)))
11226 skip("Failed to create device\n");
11227 goto cleanup;
11230 test_format = GetPixelFormat(hdc);
11231 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11233 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11234 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11236 test_format = GetPixelFormat(hdc);
11237 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11239 hr = IDirect3DDevice9_BeginScene(device);
11240 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11242 test_format = GetPixelFormat(hdc);
11243 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11245 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
11246 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11248 test_format = GetPixelFormat(hdc);
11249 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11251 hr = IDirect3DDevice9_EndScene(device);
11252 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11254 test_format = GetPixelFormat(hdc);
11255 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11257 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11258 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11260 test_format = GetPixelFormat(hdc);
11261 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11263 hr = IDirect3DDevice9_Present(device, NULL, NULL, hwnd2, NULL);
11264 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11266 test_format = GetPixelFormat(hdc);
11267 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11269 test_format = GetPixelFormat(hdc2);
11270 ok(test_format == format, "second window has pixel format %d, expected %d\n", test_format, format);
11272 refcount = IDirect3DDevice9_Release(device);
11273 ok(!refcount, "Device has %lu references left.\n", refcount);
11274 IDirect3D9_Release(d3d9);
11276 test_format = GetPixelFormat(hdc);
11277 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
11279 test_format = GetPixelFormat(hdc2);
11280 ok(test_format == format, "second window has pixel format %d, expected %d\n", test_format, format);
11282 /* Test that creating a device doesn't set a pixel format on a window which
11283 * never had one. */
11285 hwnd3 = create_window();
11286 hdc3 = GetDC(hwnd3);
11288 test_format = GetPixelFormat(hdc3);
11289 ok(!test_format, "Expected no format, got %d.\n", test_format);
11291 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
11292 ok(!!d3d9, "Failed to create a D3D object.\n");
11293 if (!(device = create_device(d3d9, hwnd3, NULL)))
11295 skip("Failed to create device\n");
11296 goto cleanup;
11299 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11300 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11301 hr = IDirect3DDevice9_BeginScene(device);
11302 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11303 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
11304 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11305 hr = IDirect3DDevice9_EndScene(device);
11306 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11308 test_format = GetPixelFormat(hdc3);
11309 ok(!test_format, "Expected no format, got %d.\n", test_format);
11311 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11314 test_format = GetPixelFormat(hdc3);
11315 ok(!test_format, "Expected no format, got %d.\n", test_format);
11317 refcount = IDirect3DDevice9_Release(device);
11318 ok(!refcount, "Device has %lu references left.\n", refcount);
11319 IDirect3D9_Release(d3d9);
11321 test_format = GetPixelFormat(hdc3);
11322 ok(!test_format, "Expected no format, got %d.\n", test_format);
11324 ret = SetPixelFormat(hdc3, format, &pfd);
11325 ok(ret, "Failed to set pixel format %d.\n", format);
11327 test_format = GetPixelFormat(hdc3);
11328 ok(test_format == format, "Expected pixel format %d, got %d.\n", format, test_format);
11330 ReleaseDC(hwnd3, hdc3);
11331 DestroyWindow(hwnd3);
11333 cleanup:
11334 FreeLibrary(gl);
11335 ReleaseDC(hwnd2, hdc2);
11336 ReleaseDC(hwnd, hdc);
11337 DestroyWindow(hwnd2);
11338 DestroyWindow(hwnd);
11341 static void test_begin_end_state_block(void)
11343 IDirect3DStateBlock9 *stateblock, *stateblock2;
11344 IDirect3DDevice9 *device;
11345 IDirect3D9 *d3d;
11346 ULONG refcount;
11347 DWORD value;
11348 HWND window;
11349 HRESULT hr;
11351 window = create_window();
11352 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11353 ok(!!d3d, "Failed to create a D3D object.\n");
11354 if (!(device = create_device(d3d, window, NULL)))
11356 skip("Failed to create a D3D device, skipping tests.\n");
11357 IDirect3D9_Release(d3d);
11358 DestroyWindow(window);
11359 return;
11362 hr = IDirect3DDevice9_BeginStateBlock(device);
11363 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11365 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11366 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11368 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
11369 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
11370 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11371 ok(!!stateblock && stateblock != (IDirect3DStateBlock9 *)0xdeadbeef,
11372 "Got unexpected stateblock %p.\n", stateblock);
11374 stateblock2 = (IDirect3DStateBlock9 *)0xdeadbeef;
11375 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock2);
11376 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11377 ok(stateblock2 == (IDirect3DStateBlock9 *)0xdeadbeef,
11378 "Got unexpected stateblock %p.\n", stateblock2);
11380 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
11381 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11382 ok(value == TRUE, "Got unexpected value %#lx.\n", value);
11384 hr = IDirect3DDevice9_BeginStateBlock(device);
11385 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11387 hr = IDirect3DDevice9_BeginStateBlock(device);
11388 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11390 hr = IDirect3DStateBlock9_Apply(stateblock);
11391 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11393 hr = IDirect3DStateBlock9_Capture(stateblock);
11394 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11396 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &stateblock2);
11397 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11399 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
11400 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11401 ok(value == TRUE, "Got unexpected value %#lx.\n", value);
11403 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock2);
11404 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11406 hr = IDirect3DStateBlock9_Apply(stateblock2);
11407 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11409 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_LIGHTING, &value);
11410 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11411 ok(value == TRUE, "Got unexpected value %#lx.\n", value);
11413 IDirect3DStateBlock9_Release(stateblock);
11414 IDirect3DStateBlock9_Release(stateblock2);
11415 refcount = IDirect3DDevice9_Release(device);
11416 ok(!refcount, "Device has %lu references left.\n", refcount);
11417 IDirect3D9_Release(d3d);
11418 DestroyWindow(window);
11421 static void test_shader_constant_apply(void)
11423 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
11424 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
11425 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
11426 IDirect3DStateBlock9 *stateblock;
11427 DWORD vs_version, ps_version;
11428 IDirect3DDevice9 *device;
11429 IDirect3D9 *d3d;
11430 ULONG refcount;
11431 D3DCAPS9 caps;
11432 float ret[4];
11433 HWND window;
11434 HRESULT hr;
11436 window = create_window();
11437 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11438 ok(!!d3d, "Failed to create a D3D object.\n");
11439 if (!(device = create_device(d3d, window, NULL)))
11441 skip("Failed to create a D3D device, skipping tests.\n");
11442 IDirect3D9_Release(d3d);
11443 DestroyWindow(window);
11444 return;
11447 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11448 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
11449 vs_version = caps.VertexShaderVersion & 0xffff;
11450 ps_version = caps.PixelShaderVersion & 0xffff;
11452 if (vs_version)
11454 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
11455 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
11456 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
11457 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
11459 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
11460 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#lx.\n", hr);
11461 ok(!memcmp(ret, initial, sizeof(initial)),
11462 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11463 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
11464 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
11465 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#lx.\n", hr);
11466 ok(!memcmp(ret, initial, sizeof(initial)),
11467 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11468 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
11470 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
11471 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
11473 if (ps_version)
11475 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
11476 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#lx.\n", hr);
11477 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
11478 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#lx.\n", hr);
11480 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
11481 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#lx.\n", hr);
11482 ok(!memcmp(ret, initial, sizeof(initial)),
11483 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11484 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
11485 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
11486 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#lx.\n", hr);
11487 ok(!memcmp(ret, initial, sizeof(initial)),
11488 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11489 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
11491 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
11492 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#lx.\n", hr);
11495 hr = IDirect3DDevice9_BeginStateBlock(device);
11496 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#lx.\n", hr);
11498 if (vs_version)
11500 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
11501 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
11503 if (ps_version)
11505 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
11506 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#lx.\n", hr);
11509 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
11510 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#lx.\n", hr);
11512 if (vs_version)
11514 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
11515 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#lx.\n", hr);
11516 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
11517 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11518 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
11519 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
11520 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#lx.\n", hr);
11521 ok(!memcmp(ret, initial, sizeof(initial)),
11522 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11523 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
11525 if (ps_version)
11527 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
11528 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#lx.\n", hr);
11529 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
11530 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11531 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
11532 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
11533 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#lx.\n", hr);
11534 ok(!memcmp(ret, initial, sizeof(initial)),
11535 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11536 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
11539 /* Apply doesn't overwrite constants that aren't explicitly set on the
11540 * source stateblock. */
11541 hr = IDirect3DStateBlock9_Apply(stateblock);
11542 ok(SUCCEEDED(hr), "Failed to apply stateblock, hr %#lx.\n", hr);
11544 if (vs_version)
11546 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
11547 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#lx.\n", hr);
11548 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
11549 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11550 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
11551 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
11552 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#lx.\n", hr);
11553 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
11554 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11555 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
11557 if (ps_version)
11559 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
11560 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#lx.\n", hr);
11561 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
11562 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11563 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
11564 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
11565 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#lx.\n", hr);
11566 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
11567 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
11568 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
11571 IDirect3DStateBlock9_Release(stateblock);
11572 refcount = IDirect3DDevice9_Release(device);
11573 ok(!refcount, "Device has %lu references left.\n", refcount);
11574 IDirect3D9_Release(d3d);
11575 DestroyWindow(window);
11578 static void test_vdecl_apply(void)
11580 IDirect3DVertexDeclaration9 *declaration, *declaration1, *declaration2;
11581 IDirect3DStateBlock9 *stateblock;
11582 IDirect3DDevice9 *device;
11583 IDirect3D9 *d3d;
11584 ULONG refcount;
11585 HWND window;
11586 HRESULT hr;
11588 static const D3DVERTEXELEMENT9 decl1[] =
11590 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11591 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11592 D3DDECL_END(),
11595 static const D3DVERTEXELEMENT9 decl2[] =
11597 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11598 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11599 {0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
11600 D3DDECL_END(),
11603 window = create_window();
11604 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11605 ok(!!d3d, "Failed to create a D3D object.\n");
11606 if (!(device = create_device(d3d, window, NULL)))
11608 skip("Failed to create a D3D device, skipping tests.\n");
11609 IDirect3D9_Release(d3d);
11610 DestroyWindow(window);
11611 return;
11614 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl1, &declaration1);
11615 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#lx.\n", hr);
11617 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl2, &declaration2);
11618 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#lx.\n", hr);
11620 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11621 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11622 hr = IDirect3DDevice9_BeginStateBlock(device);
11623 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#lx.\n", hr);
11624 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
11625 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11626 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
11627 ok(SUCCEEDED(hr), "EndStateBlock failed, hr %#lx.\n", hr);
11628 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11629 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11630 hr = IDirect3DStateBlock9_Apply(stateblock);
11631 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11632 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11633 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11634 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
11635 declaration, declaration1);
11636 IDirect3DVertexDeclaration9_Release(declaration);
11638 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11639 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11640 hr = IDirect3DStateBlock9_Capture(stateblock);
11641 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
11642 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
11643 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11644 hr = IDirect3DStateBlock9_Apply(stateblock);
11645 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11646 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11647 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11648 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
11649 declaration, declaration2);
11650 IDirect3DVertexDeclaration9_Release(declaration);
11652 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
11653 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11654 hr = IDirect3DStateBlock9_Capture(stateblock);
11655 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
11656 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11657 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11658 hr = IDirect3DStateBlock9_Apply(stateblock);
11659 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11660 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11661 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11662 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
11663 declaration, declaration2);
11664 IDirect3DVertexDeclaration9_Release(declaration);
11666 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11667 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11668 hr = IDirect3DStateBlock9_Capture(stateblock);
11669 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
11670 hr = IDirect3DStateBlock9_Apply(stateblock);
11671 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11672 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11673 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11674 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
11676 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
11677 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11678 hr = IDirect3DStateBlock9_Capture(stateblock);
11679 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
11680 hr = IDirect3DStateBlock9_Apply(stateblock);
11681 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11682 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11683 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11684 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
11685 declaration, declaration2);
11686 IDirect3DVertexDeclaration9_Release(declaration);
11688 IDirect3DStateBlock9_Release(stateblock);
11689 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
11690 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11691 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &stateblock);
11692 ok(SUCCEEDED(hr), "CreateStateBlock failed, hr %#lx.\n", hr);
11693 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11694 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11695 hr = IDirect3DStateBlock9_Apply(stateblock);
11696 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11697 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11698 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11699 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
11700 declaration, declaration1);
11701 IDirect3DVertexDeclaration9_Release(declaration);
11703 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11704 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11705 hr = IDirect3DStateBlock9_Capture(stateblock);
11706 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
11707 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
11708 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11709 hr = IDirect3DStateBlock9_Apply(stateblock);
11710 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11711 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11712 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11713 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
11714 declaration, declaration2);
11715 IDirect3DVertexDeclaration9_Release(declaration);
11717 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
11718 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11719 hr = IDirect3DStateBlock9_Capture(stateblock);
11720 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
11721 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11722 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11723 hr = IDirect3DStateBlock9_Apply(stateblock);
11724 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11725 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11726 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11727 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
11728 declaration, declaration2);
11729 IDirect3DVertexDeclaration9_Release(declaration);
11731 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11732 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11733 hr = IDirect3DStateBlock9_Capture(stateblock);
11734 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
11735 hr = IDirect3DStateBlock9_Apply(stateblock);
11736 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11737 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11738 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11739 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
11741 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
11742 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11743 hr = IDirect3DStateBlock9_Capture(stateblock);
11744 ok(SUCCEEDED(hr), "Capture failed, hr %#lx.\n", hr);
11745 hr = IDirect3DStateBlock9_Apply(stateblock);
11746 ok(SUCCEEDED(hr), "Apply failed, hr %#lx.\n", hr);
11747 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
11748 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#lx.\n", hr);
11749 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
11750 declaration, declaration2);
11751 IDirect3DVertexDeclaration9_Release(declaration);
11753 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
11754 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx.\n", hr);
11755 IDirect3DVertexDeclaration9_Release(declaration1);
11756 IDirect3DVertexDeclaration9_Release(declaration2);
11757 IDirect3DStateBlock9_Release(stateblock);
11758 refcount = IDirect3DDevice9_Release(device);
11759 ok(!refcount, "Device has %lu references left.\n", refcount);
11760 IDirect3D9_Release(d3d);
11761 DestroyWindow(window);
11764 static void test_resource_type(void)
11766 IDirect3DDevice9 *device;
11767 IDirect3DSurface9 *surface;
11768 IDirect3DTexture9 *texture;
11769 IDirect3DCubeTexture9 *cube_texture;
11770 IDirect3DVolume9 *volume;
11771 IDirect3DVolumeTexture9 *volume_texture;
11772 D3DSURFACE_DESC surface_desc;
11773 D3DVOLUME_DESC volume_desc;
11774 D3DRESOURCETYPE type;
11775 IDirect3D9 *d3d;
11776 ULONG refcount;
11777 HWND window;
11778 HRESULT hr;
11779 D3DCAPS9 caps;
11781 window = create_window();
11782 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11783 ok(!!d3d, "Failed to create a D3D object.\n");
11784 if (!(device = create_device(d3d, window, NULL)))
11786 skip("Failed to create a D3D device, skipping tests.\n");
11787 IDirect3D9_Release(d3d);
11788 DestroyWindow(window);
11789 return;
11792 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11793 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
11795 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_X8R8G8B8,
11796 D3DPOOL_SYSTEMMEM, &surface, NULL);
11797 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
11798 type = IDirect3DSurface9_GetType(surface);
11799 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
11800 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
11801 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#lx.\n", hr);
11802 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
11803 surface_desc.Type);
11804 IDirect3DSurface9_Release(surface);
11806 hr = IDirect3DDevice9_CreateTexture(device, 2, 8, 4, 0, D3DFMT_X8R8G8B8,
11807 D3DPOOL_SYSTEMMEM, &texture, NULL);
11808 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
11809 type = IDirect3DTexture9_GetType(texture);
11810 ok(type == D3DRTYPE_TEXTURE, "Expected type D3DRTYPE_TEXTURE, got %u.\n", type);
11812 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
11813 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
11814 /* The following code crashes, for the sake of completeness:
11815 * type = texture->lpVtbl->GetType((IDirect3DTexture9 *)surface);
11816 * ok(type == D3DRTYPE_PONIES, "Expected type D3DRTYPE_PONIES, got %u.\n", type);
11818 * So applications will not depend on getting the "right" resource type - whatever it
11819 * may be - from the "wrong" vtable. */
11820 type = IDirect3DSurface9_GetType(surface);
11821 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
11822 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
11823 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#lx.\n", hr);
11824 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
11825 surface_desc.Type);
11826 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
11827 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
11828 hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &surface_desc);
11829 ok(SUCCEEDED(hr), "Failed to get level description, hr %#lx.\n", hr);
11830 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
11831 surface_desc.Type);
11832 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
11833 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
11834 IDirect3DSurface9_Release(surface);
11836 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
11837 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
11838 type = IDirect3DSurface9_GetType(surface);
11839 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
11840 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
11841 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#lx.\n", hr);
11842 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
11843 surface_desc.Type);
11844 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
11845 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
11846 hr = IDirect3DTexture9_GetLevelDesc(texture, 2, &surface_desc);
11847 ok(SUCCEEDED(hr), "Failed to get level description, hr %#lx.\n", hr);
11848 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
11849 surface_desc.Type);
11850 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
11851 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
11852 IDirect3DSurface9_Release(surface);
11853 IDirect3DTexture9_Release(texture);
11855 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11857 hr = IDirect3DDevice9_CreateCubeTexture(device, 1, 1, 0, D3DFMT_X8R8G8B8,
11858 D3DPOOL_SYSTEMMEM, &cube_texture, NULL);
11859 ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#lx.\n", hr);
11860 type = IDirect3DCubeTexture9_GetType(cube_texture);
11861 ok(type == D3DRTYPE_CUBETEXTURE, "Expected type D3DRTYPE_CUBETEXTURE, got %u.\n", type);
11863 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture,
11864 D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface);
11865 ok(SUCCEEDED(hr), "Failed to get cube map surface, hr %#lx.\n", hr);
11866 type = IDirect3DSurface9_GetType(surface);
11867 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
11868 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
11869 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#lx.\n", hr);
11870 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
11871 surface_desc.Type);
11872 hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
11873 ok(SUCCEEDED(hr), "Failed to get level description, hr %#lx.\n", hr);
11874 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
11875 surface_desc.Type);
11876 IDirect3DSurface9_Release(surface);
11877 IDirect3DCubeTexture9_Release(cube_texture);
11879 else
11880 skip("Cube maps not supported.\n");
11882 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP)
11884 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 4, 8, 4, 0, D3DFMT_X8R8G8B8,
11885 D3DPOOL_SYSTEMMEM, &volume_texture, NULL);
11886 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
11887 type = IDirect3DVolumeTexture9_GetType(volume_texture);
11888 ok(type == D3DRTYPE_VOLUMETEXTURE, "Expected type D3DRTYPE_VOLUMETEXTURE, got %u.\n", type);
11890 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
11891 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#lx.\n", hr);
11892 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
11893 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
11894 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#lx.\n", hr);
11895 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
11896 volume_desc.Type);
11897 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
11898 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
11899 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
11900 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
11901 ok(SUCCEEDED(hr), "Failed to get level description, hr %#lx.\n", hr);
11902 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
11903 volume_desc.Type);
11904 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
11905 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
11906 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
11907 IDirect3DVolume9_Release(volume);
11909 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 2, &volume);
11910 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#lx.\n", hr);
11911 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
11912 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
11913 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#lx.\n", hr);
11914 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
11915 volume_desc.Type);
11916 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
11917 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
11918 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
11919 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 2, &volume_desc);
11920 ok(SUCCEEDED(hr), "Failed to get level description, hr %#lx.\n", hr);
11921 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
11922 volume_desc.Type);
11923 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
11924 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
11925 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
11926 IDirect3DVolume9_Release(volume);
11927 IDirect3DVolumeTexture9_Release(volume_texture);
11929 else
11930 skip("Mipmapped volume maps not supported.\n");
11932 refcount = IDirect3DDevice9_Release(device);
11933 ok(!refcount, "Device has %lu references left.\n", refcount);
11934 IDirect3D9_Release(d3d);
11935 DestroyWindow(window);
11938 static void test_mipmap_lock(void)
11940 IDirect3DDevice9 *device;
11941 IDirect3DSurface9 *surface, *surface2, *surface_dst, *surface_dst2;
11942 IDirect3DTexture9 *texture, *texture_dst;
11943 IDirect3D9 *d3d;
11944 ULONG refcount;
11945 HWND window;
11946 HRESULT hr;
11947 D3DLOCKED_RECT locked_rect;
11949 window = create_window();
11950 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11951 ok(!!d3d, "Failed to create a D3D object.\n");
11952 if (!(device = create_device(d3d, window, NULL)))
11954 skip("Failed to create a D3D device, skipping tests.\n");
11955 IDirect3D9_Release(d3d);
11956 DestroyWindow(window);
11957 return;
11960 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
11961 D3DPOOL_DEFAULT, &texture_dst, NULL);
11962 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
11963 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 0, &surface_dst);
11964 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
11965 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 1, &surface_dst2);
11966 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
11968 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
11969 D3DPOOL_SYSTEMMEM, &texture, NULL);
11970 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
11971 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
11972 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
11973 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
11974 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
11976 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
11977 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
11978 hr = IDirect3DSurface9_LockRect(surface2, &locked_rect, NULL, 0);
11979 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
11980 hr = IDirect3DSurface9_UnlockRect(surface);
11981 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
11983 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, surface_dst, NULL);
11984 ok(SUCCEEDED(hr), "Failed to update surface, hr %#lx.\n", hr);
11985 hr = IDirect3DDevice9_UpdateSurface(device, surface2, NULL, surface_dst2, NULL);
11986 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
11988 /* Apparently there's no validation on the container. */
11989 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
11990 (IDirect3DBaseTexture9 *)texture_dst);
11991 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
11993 hr = IDirect3DSurface9_UnlockRect(surface2);
11994 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
11996 IDirect3DSurface9_Release(surface_dst2);
11997 IDirect3DSurface9_Release(surface_dst);
11998 IDirect3DSurface9_Release(surface2);
11999 IDirect3DSurface9_Release(surface);
12000 IDirect3DTexture9_Release(texture_dst);
12001 IDirect3DTexture9_Release(texture);
12003 refcount = IDirect3DDevice9_Release(device);
12004 ok(!refcount, "Device has %lu references left.\n", refcount);
12005 IDirect3D9_Release(d3d);
12006 DestroyWindow(window);
12009 static void test_writeonly_resource(void)
12011 IDirect3D9 *d3d;
12012 IDirect3DDevice9 *device;
12013 IDirect3DVertexBuffer9 *buffer;
12014 ULONG refcount;
12015 HWND window;
12016 HRESULT hr;
12017 void *ptr;
12018 static const struct
12020 struct vec3 pos;
12022 quad[] =
12024 {{-1.0f, -1.0f, 0.0f}},
12025 {{-1.0f, 1.0f, 0.0f}},
12026 {{ 1.0f, -1.0f, 0.0f}},
12027 {{ 1.0f, 1.0f, 0.0f}}
12030 window = create_window();
12031 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12032 ok(!!d3d, "Failed to create a D3D object.\n");
12033 if (!(device = create_device(d3d, window, NULL)))
12035 skip("Failed to create a D3D device, skipping tests.\n");
12036 IDirect3D9_Release(d3d);
12037 DestroyWindow(window);
12038 return;
12041 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad),
12042 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
12043 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#lx.\n", hr);
12045 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
12046 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
12047 memcpy(ptr, quad, sizeof(quad));
12048 hr = IDirect3DVertexBuffer9_Unlock(buffer);
12049 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
12050 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quad));
12051 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
12052 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12053 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
12055 hr = IDirect3DDevice9_BeginScene(device);
12056 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12057 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
12058 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12059 hr = IDirect3DDevice9_EndScene(device);
12060 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12062 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, 0);
12063 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
12064 ok(!memcmp(ptr, quad, sizeof(quad)), "Got unexpected vertex buffer data.\n");
12065 hr = IDirect3DVertexBuffer9_Unlock(buffer);
12066 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
12068 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, D3DLOCK_READONLY);
12069 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
12070 ok(!memcmp(ptr, quad, sizeof(quad)), "Got unexpected vertex buffer data.\n");
12071 hr = IDirect3DVertexBuffer9_Unlock(buffer);
12072 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
12074 refcount = IDirect3DVertexBuffer9_Release(buffer);
12075 ok(!refcount, "Vertex buffer has %lu references left.\n", refcount);
12076 refcount = IDirect3DDevice9_Release(device);
12077 ok(!refcount, "Device has %lu references left.\n", refcount);
12078 IDirect3D9_Release(d3d);
12079 DestroyWindow(window);
12082 static void test_lost_device(void)
12084 struct device_desc device_desc;
12085 IDirect3DDevice9 *device;
12086 IDirect3D9 *d3d;
12087 ULONG refcount;
12088 HWND window;
12089 HRESULT hr;
12090 BOOL ret;
12092 window = create_window();
12093 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12094 ok(!!d3d, "Failed to create a D3D object.\n");
12095 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
12096 device_desc.device_window = window;
12097 device_desc.width = registry_mode.dmPelsWidth;
12098 device_desc.height = registry_mode.dmPelsHeight;
12099 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
12100 if (!(device = create_device(d3d, window, &device_desc)))
12102 skip("Failed to create a D3D device, skipping tests.\n");
12103 goto done;
12106 hr = IDirect3DDevice9_TestCooperativeLevel(device);
12107 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12108 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12109 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12111 ret = SetForegroundWindow(GetDesktopWindow());
12112 ok(ret, "Failed to set foreground window.\n");
12113 hr = IDirect3DDevice9_TestCooperativeLevel(device);
12114 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#lx.\n", hr);
12115 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12116 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#lx.\n", hr);
12118 ret = ShowWindow(window, SW_RESTORE);
12119 ok(ret, "Failed to restore window.\n");
12120 ret = SetForegroundWindow(window);
12121 ok(ret, "Failed to set foreground window.\n");
12122 hr = IDirect3DDevice9_TestCooperativeLevel(device);
12123 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#lx.\n", hr);
12124 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12125 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#lx.\n", hr);
12127 hr = reset_device(device, &device_desc);
12128 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12129 hr = IDirect3DDevice9_TestCooperativeLevel(device);
12130 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12131 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12132 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12134 device_desc.flags = 0;
12135 hr = reset_device(device, &device_desc);
12136 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12137 hr = IDirect3DDevice9_TestCooperativeLevel(device);
12138 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12139 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12140 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12142 ret = SetForegroundWindow(GetDesktopWindow());
12143 ok(ret, "Failed to set foreground window.\n");
12144 hr = IDirect3DDevice9_TestCooperativeLevel(device);
12145 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12146 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12147 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12149 ret = ShowWindow(window, SW_RESTORE);
12150 ok(ret, "Failed to restore window.\n");
12151 ret = SetForegroundWindow(window);
12152 ok(ret, "Failed to set foreground window.\n");
12153 hr = IDirect3DDevice9_TestCooperativeLevel(device);
12154 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12155 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12156 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12158 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
12159 hr = reset_device(device, &device_desc);
12160 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12161 hr = IDirect3DDevice9_TestCooperativeLevel(device);
12162 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12163 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12164 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12166 ret = SetForegroundWindow(GetDesktopWindow());
12167 ok(ret, "Failed to set foreground window.\n");
12168 hr = reset_device(device, &device_desc);
12169 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#lx.\n", hr);
12170 ret = ShowWindow(window, SW_RESTORE);
12171 ok(ret, "Failed to restore window.\n");
12172 ret = SetForegroundWindow(window);
12173 ok(ret, "Failed to set foreground window.\n");
12174 hr = reset_device(device, &device_desc);
12175 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12177 refcount = IDirect3DDevice9_Release(device);
12178 ok(!refcount, "Device has %lu references left.\n", refcount);
12179 done:
12180 IDirect3D9_Release(d3d);
12181 DestroyWindow(window);
12184 static void test_resource_priority(void)
12186 IDirect3DDevice9 *device;
12187 IDirect3DSurface9 *surface;
12188 IDirect3DTexture9 *texture;
12189 IDirect3DVertexBuffer9 *buffer;
12190 IDirect3D9 *d3d;
12191 ULONG refcount;
12192 HWND window;
12193 HRESULT hr;
12194 static const struct
12196 D3DPOOL pool;
12197 const char *name;
12198 BOOL can_set_priority;
12200 test_data[] =
12202 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
12203 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", FALSE},
12204 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
12205 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE}
12207 unsigned int i;
12208 DWORD priority;
12210 window = create_window();
12211 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12212 ok(!!d3d, "Failed to create a D3D object.\n");
12213 if (!(device = create_device(d3d, window, NULL)))
12215 skip("Failed to create a D3D device, skipping tests.\n");
12216 IDirect3D9_Release(d3d);
12217 DestroyWindow(window);
12218 return;
12221 for (i = 0; i < ARRAY_SIZE(test_data); i++)
12223 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 0, 0, D3DFMT_X8R8G8B8,
12224 test_data[i].pool, &texture, NULL);
12225 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, pool %s.\n", hr, test_data[i].name);
12226 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
12227 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
12229 priority = IDirect3DTexture9_GetPriority(texture);
12230 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12231 priority = IDirect3DTexture9_SetPriority(texture, 1);
12232 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12233 priority = IDirect3DTexture9_GetPriority(texture);
12234 if (test_data[i].can_set_priority)
12236 ok(priority == 1, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12237 priority = IDirect3DTexture9_SetPriority(texture, 2);
12238 ok(priority == 1, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12240 else
12241 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12243 priority = IDirect3DSurface9_GetPriority(surface);
12244 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12245 priority = IDirect3DSurface9_SetPriority(surface, 1);
12246 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12247 priority = IDirect3DSurface9_GetPriority(surface);
12248 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12250 IDirect3DSurface9_Release(surface);
12251 IDirect3DTexture9_Release(texture);
12253 if (test_data[i].pool != D3DPOOL_MANAGED)
12255 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16, D3DFMT_X8R8G8B8,
12256 test_data[i].pool, &surface, NULL);
12257 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx, pool %s.\n", hr, test_data[i].name);
12259 priority = IDirect3DSurface9_GetPriority(surface);
12260 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12261 priority = IDirect3DSurface9_SetPriority(surface, 1);
12262 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12263 priority = IDirect3DSurface9_GetPriority(surface);
12264 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12266 IDirect3DSurface9_Release(surface);
12269 if (test_data[i].pool != D3DPOOL_SCRATCH)
12271 hr = IDirect3DDevice9_CreateVertexBuffer(device, 256, 0, 0,
12272 test_data[i].pool, &buffer, NULL);
12273 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#lx, pool %s.\n", hr, test_data[i].name);
12275 priority = IDirect3DVertexBuffer9_GetPriority(buffer);
12276 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12277 priority = IDirect3DVertexBuffer9_SetPriority(buffer, 1);
12278 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12279 priority = IDirect3DVertexBuffer9_GetPriority(buffer);
12280 if (test_data[i].can_set_priority)
12282 ok(priority == 1, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12283 priority = IDirect3DVertexBuffer9_SetPriority(buffer, 0);
12284 ok(priority == 1, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12286 else
12287 ok(priority == 0, "Got unexpected priority %lu, pool %s.\n", priority, test_data[i].name);
12289 IDirect3DVertexBuffer9_Release(buffer);
12293 hr = IDirect3DDevice9_CreateRenderTarget(device, 16, 16, D3DFMT_X8R8G8B8,
12294 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
12296 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
12297 priority = IDirect3DSurface9_GetPriority(surface);
12298 ok(priority == 0, "Got unexpected priority %lu.\n", priority);
12299 priority = IDirect3DSurface9_SetPriority(surface, 1);
12300 ok(priority == 0, "Got unexpected priority %lu.\n", priority);
12301 priority = IDirect3DSurface9_GetPriority(surface);
12302 ok(priority == 0, "Got unexpected priority %lu.\n", priority);
12304 IDirect3DSurface9_Release(surface);
12306 refcount = IDirect3DDevice9_Release(device);
12307 ok(!refcount, "Device has %lu references left.\n", refcount);
12308 IDirect3D9_Release(d3d);
12309 DestroyWindow(window);
12312 static void test_swapchain_parameters(void)
12314 IDirect3DDevice9 *device;
12315 HRESULT hr, expected_hr;
12316 RECT client_rect;
12317 IDirect3D9 *d3d;
12318 D3DCAPS9 caps;
12319 HWND window;
12320 unsigned int i;
12321 D3DPRESENT_PARAMETERS present_parameters, present_parameters_windowed = {0}, present_parameters2;
12322 IDirect3DSwapChain9 *swapchain;
12323 static const struct
12325 BOOL windowed;
12326 UINT backbuffer_count;
12327 D3DSWAPEFFECT swap_effect;
12328 HRESULT hr;
12330 tests[] =
12332 /* Swap effect 0 is not allowed. */
12333 {TRUE, 1, 0, D3DERR_INVALIDCALL},
12334 {FALSE, 1, 0, D3DERR_INVALIDCALL},
12336 /* All (non-ex) swap effects are allowed in
12337 * windowed and fullscreen mode. */
12338 {TRUE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
12339 {TRUE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
12340 {FALSE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
12341 {FALSE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
12342 {FALSE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
12344 /* Only one backbuffer in copy mode. */
12345 {TRUE, 0, D3DSWAPEFFECT_COPY, D3D_OK},
12346 {TRUE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
12347 {TRUE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
12348 {FALSE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
12350 /* Ok with the others, in fullscreen and windowed mode. */
12351 {TRUE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
12352 {TRUE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
12353 {FALSE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
12354 {FALSE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
12356 /* D3D9Ex swap effects. */
12357 {TRUE, 1, D3DSWAPEFFECT_OVERLAY, D3DERR_INVALIDCALL},
12358 {TRUE, 1, D3DSWAPEFFECT_FLIPEX, D3DERR_INVALIDCALL},
12359 {TRUE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
12360 {FALSE, 1, D3DSWAPEFFECT_OVERLAY, D3DERR_INVALIDCALL},
12361 {FALSE, 1, D3DSWAPEFFECT_FLIPEX, D3DERR_INVALIDCALL},
12362 {FALSE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
12364 /* 3 is the highest allowed backbuffer count. */
12365 {TRUE, 3, D3DSWAPEFFECT_DISCARD, D3D_OK},
12366 {TRUE, 4, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
12367 {TRUE, 4, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
12368 {FALSE, 4, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
12369 {FALSE, 4, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
12372 window = create_window();
12373 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12374 ok(!!d3d, "Failed to create a D3D object.\n");
12375 if (!(device = create_device(d3d, window, NULL)))
12377 skip("Failed to create a D3D device, skipping tests.\n");
12378 IDirect3D9_Release(d3d);
12379 DestroyWindow(window);
12380 return;
12382 memset(&caps, 0, sizeof(caps));
12383 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12384 ok(hr == D3D_OK, "Failed to get device caps, hr %#lx.\n", hr);
12385 IDirect3DDevice9_Release(device);
12387 present_parameters_windowed.BackBufferWidth = registry_mode.dmPelsWidth;
12388 present_parameters_windowed.BackBufferHeight = registry_mode.dmPelsHeight;
12389 present_parameters_windowed.hDeviceWindow = NULL;
12390 present_parameters_windowed.BackBufferFormat = D3DFMT_X8R8G8B8;
12391 present_parameters_windowed.SwapEffect = D3DSWAPEFFECT_COPY;
12392 present_parameters_windowed.Windowed = TRUE;
12393 present_parameters_windowed.BackBufferCount = 1;
12395 for (i = 0; i < ARRAY_SIZE(tests); ++i)
12397 memset(&present_parameters, 0, sizeof(present_parameters));
12398 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
12399 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
12400 present_parameters.hDeviceWindow = NULL;
12401 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
12403 present_parameters.SwapEffect = tests[i].swap_effect;
12404 present_parameters.Windowed = tests[i].windowed;
12405 present_parameters.BackBufferCount = tests[i].backbuffer_count;
12407 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
12408 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
12409 ok(hr == tests[i].hr, "Expected hr %#lx, got %#lx, test %u.\n", tests[i].hr, hr, i);
12410 if (SUCCEEDED(hr))
12412 UINT bb_count = tests[i].backbuffer_count ? tests[i].backbuffer_count : 1;
12414 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
12415 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#lx, test %u.\n", hr, i);
12417 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters2);
12418 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
12419 ok(present_parameters2.hDeviceWindow == window, "Got window %p, expected %p.\n",
12420 present_parameters2.hDeviceWindow, window);
12421 ok(present_parameters2.SwapEffect == tests[i].swap_effect, "Swap effect changed from %u to %u, test %u.\n",
12422 tests[i].swap_effect, present_parameters2.SwapEffect, i);
12423 ok(present_parameters2.BackBufferCount == bb_count, "Backbuffer count changed from %u to %u, test %u.\n",
12424 bb_count, present_parameters2.BackBufferCount, i);
12425 ok(present_parameters2.Windowed == tests[i].windowed, "Windowed changed from %u to %u, test %u.\n",
12426 tests[i].windowed, present_parameters2.Windowed, i);
12428 IDirect3DSwapChain9_Release(swapchain);
12429 IDirect3DDevice9_Release(device);
12432 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
12433 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters_windowed, &device);
12434 ok(SUCCEEDED(hr), "Failed to create device, hr %#lx, test %u.\n", hr, i);
12436 memset(&present_parameters, 0, sizeof(present_parameters));
12437 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
12438 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
12439 present_parameters.hDeviceWindow = NULL;
12440 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
12442 present_parameters.SwapEffect = tests[i].swap_effect;
12443 present_parameters.Windowed = tests[i].windowed;
12444 present_parameters.BackBufferCount = tests[i].backbuffer_count;
12446 hr = IDirect3DDevice9_Reset(device, &present_parameters);
12447 ok(hr == tests[i].hr, "Expected hr %#lx, got %#lx, test %u.\n", tests[i].hr, hr, i);
12449 if (FAILED(hr))
12451 present_parameters_windowed.hDeviceWindow = NULL;
12452 hr = IDirect3DDevice9_Reset(device, &present_parameters_windowed);
12453 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx, test %u.\n", hr, i);
12456 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
12457 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
12458 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters2);
12459 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
12460 ok(present_parameters2.hDeviceWindow == window, "Got window %p, expected %p.\n",
12461 present_parameters2.hDeviceWindow, window);
12462 IDirect3DSwapChain9_Release(swapchain);
12463 IDirect3DDevice9_Release(device);
12466 for (i = 0; i < 10; ++i)
12468 memset(&present_parameters, 0, sizeof(present_parameters));
12469 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
12470 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
12471 present_parameters.hDeviceWindow = window;
12472 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
12473 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
12474 present_parameters.Windowed = FALSE;
12475 present_parameters.BackBufferCount = 2;
12477 present_parameters.PresentationInterval = i;
12478 switch (present_parameters.PresentationInterval)
12480 case D3DPRESENT_INTERVAL_ONE:
12481 case D3DPRESENT_INTERVAL_TWO:
12482 case D3DPRESENT_INTERVAL_THREE:
12483 case D3DPRESENT_INTERVAL_FOUR:
12484 if (!(caps.PresentationIntervals & present_parameters.PresentationInterval))
12485 continue;
12486 /* Fall through */
12487 case D3DPRESENT_INTERVAL_DEFAULT:
12488 expected_hr = D3D_OK;
12489 break;
12490 default:
12491 expected_hr = D3DERR_INVALIDCALL;
12492 break;
12495 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
12496 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
12497 ok(hr == expected_hr, "Got unexpected hr %#lx, test %u.\n", hr, i);
12498 if (FAILED(hr))
12499 continue;
12501 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
12502 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#lx, test %u.\n", hr, i);
12504 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters2);
12505 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#lx, test %u.\n", hr, i);
12506 ok(present_parameters2.PresentationInterval == i,
12507 "Got presentation interval %#x, expected %#x.\n",
12508 present_parameters2.PresentationInterval, i);
12510 IDirect3DSwapChain9_Release(swapchain);
12511 IDirect3DDevice9_Release(device);
12514 memset(&present_parameters, 0, sizeof(present_parameters));
12515 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
12516 present_parameters.Windowed = TRUE;
12517 present_parameters.BackBufferWidth = 0;
12518 present_parameters.BackBufferHeight = 0;
12519 present_parameters.BackBufferFormat = D3DFMT_UNKNOWN;
12521 GetClientRect(window, &client_rect);
12523 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12524 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
12525 &present_parameters, &device);
12527 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
12528 ok(present_parameters.BackBufferWidth == client_rect.right, "Got unexpected BackBufferWidth %u, expected %ld.\n",
12529 present_parameters.BackBufferWidth, client_rect.right);
12530 ok(present_parameters.BackBufferHeight == client_rect.bottom, "Got unexpected BackBufferHeight %u, expected %ld.\n",
12531 present_parameters.BackBufferHeight, client_rect.bottom);
12532 ok(present_parameters.BackBufferFormat != D3DFMT_UNKNOWN, "Got unexpected BackBufferFormat %#x.\n",
12533 present_parameters.BackBufferFormat);
12534 ok(present_parameters.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", present_parameters.BackBufferCount);
12535 ok(!present_parameters.MultiSampleType, "Got unexpected MultiSampleType %u.\n", present_parameters.MultiSampleType);
12536 ok(!present_parameters.MultiSampleQuality, "Got unexpected MultiSampleQuality %lu.\n", present_parameters.MultiSampleQuality);
12537 ok(present_parameters.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", present_parameters.SwapEffect);
12538 ok(!present_parameters.hDeviceWindow, "Got unexpected hDeviceWindow %p.\n", present_parameters.hDeviceWindow);
12539 ok(present_parameters.Windowed, "Got unexpected Windowed %#x.\n", present_parameters.Windowed);
12540 ok(!present_parameters.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", present_parameters.EnableAutoDepthStencil);
12541 ok(!present_parameters.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", present_parameters.AutoDepthStencilFormat);
12542 ok(!present_parameters.Flags, "Got unexpected Flags %#lx.\n", present_parameters.Flags);
12543 ok(!present_parameters.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
12544 present_parameters.FullScreen_RefreshRateInHz);
12545 ok(!present_parameters.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", present_parameters.PresentationInterval);
12547 IDirect3DDevice9_Release(device);
12548 IDirect3D9_Release(d3d);
12549 DestroyWindow(window);
12552 static void test_check_device_format(void)
12554 static const D3DFORMAT mipmap_autogen_formats[] =
12556 D3DFMT_R8G8B8,
12557 D3DFMT_A8R8G8B8,
12558 D3DFMT_X8R8G8B8,
12559 D3DFMT_R5G6B5,
12560 D3DFMT_X1R5G5B5,
12561 D3DFMT_A8P8,
12562 D3DFMT_P8,
12563 D3DFMT_A1R5G5B5,
12564 D3DFMT_A4R4G4B4,
12567 BOOL render_target_supported;
12568 D3DDEVTYPE device_type;
12569 D3DFORMAT format;
12570 IDirect3D9 *d3d;
12571 unsigned int i;
12572 HRESULT hr;
12574 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12575 ok(!!d3d, "Failed to create a D3D object.\n");
12577 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12578 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
12580 skip("D3DFMT_A8R8G8B8 textures with SRGBWRITE not supported.\n");
12582 else
12584 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12585 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
12586 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
12587 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12588 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
12589 ok(FAILED(hr), "Got unexpected hr %#lx.\n", hr);
12592 for (device_type = D3DDEVTYPE_HAL; device_type < D3DDEVTYPE_NULLREF; ++device_type)
12594 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, device_type, D3DFMT_UNKNOWN,
12595 0, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
12596 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, device type %#x.\n", hr, device_type);
12597 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, device_type, D3DFMT_UNKNOWN,
12598 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
12599 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, device type %#x.\n", hr, device_type);
12600 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, device_type, D3DFMT_UNKNOWN,
12601 0, D3DRTYPE_SURFACE, D3DFMT_X8R8G8B8);
12602 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, device type %#x.\n", hr, device_type);
12603 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, device_type, D3DFMT_UNKNOWN,
12604 0, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8);
12605 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, device type %#x.\n", hr, device_type);
12608 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12609 0, D3DRTYPE_VERTEXBUFFER, D3DFMT_VERTEXDATA);
12610 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12611 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12612 0, D3DRTYPE_INDEXBUFFER, D3DFMT_VERTEXDATA);
12613 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12614 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12615 0, D3DRTYPE_INDEXBUFFER, D3DFMT_INDEX16);
12616 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12618 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12619 D3DUSAGE_SOFTWAREPROCESSING, D3DRTYPE_VERTEXBUFFER, D3DFMT_VERTEXDATA);
12620 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12621 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12622 D3DUSAGE_SOFTWAREPROCESSING, D3DRTYPE_INDEXBUFFER, D3DFMT_VERTEXDATA);
12623 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12624 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12625 D3DUSAGE_SOFTWAREPROCESSING, D3DRTYPE_INDEXBUFFER, D3DFMT_INDEX16);
12626 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12628 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8,
12629 0, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8);
12630 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
12631 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12632 0, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8);
12633 ok(hr == D3D_OK || broken(hr == D3DERR_NOTAVAILABLE) /* Testbot Windows <= 7 */,
12634 "Got unexpected hr %#lx.\n", hr);
12636 for (i = 0; i < ARRAY_SIZE(mipmap_autogen_formats); ++i)
12638 format = mipmap_autogen_formats[i];
12640 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12641 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, format);
12642 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
12643 render_target_supported = hr == D3D_OK;
12645 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12646 D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, format);
12647 if (render_target_supported)
12649 ok(hr == D3D_OK || hr == D3DOK_NOAUTOGEN, "Got unexpected hr %#lx.\n", hr);
12651 else
12653 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr);
12657 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT,
12658 D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_D32);
12659 ok(hr == D3DERR_NOTAVAILABLE || broken(hr == D3DERR_INVALIDCALL /* Windows 10 */),
12660 "Got unexpected hr %#lx.\n", hr);
12662 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT,
12663 D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, D3DFMT_D32);
12664 ok(hr == D3DERR_NOTAVAILABLE || broken(hr == D3DERR_INVALIDCALL /* Windows 10 */),
12665 "Got unexpected hr %#lx.\n", hr);
12667 IDirect3D9_Release(d3d);
12670 static void test_miptree_layout(void)
12672 unsigned int pool_idx, format_idx, base_dimension, level_count, offset, i, j;
12673 IDirect3DCubeTexture9 *texture_cube;
12674 IDirect3DTexture9 *texture_2d;
12675 IDirect3DDevice9 *device;
12676 D3DLOCKED_RECT map_desc;
12677 BYTE *base = NULL;
12678 IDirect3D9 *d3d;
12679 ULONG refcount;
12680 D3DCAPS9 caps;
12681 HWND window;
12682 HRESULT hr;
12684 static const struct
12686 D3DFORMAT format;
12687 const char *name;
12689 formats[] =
12691 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8"},
12692 {D3DFMT_A8, "D3DFMT_A8"},
12693 {D3DFMT_L8, "D3DFMT_L8"},
12694 {MAKEFOURCC('A','T','I','1'), "D3DFMT_ATI1"},
12695 {MAKEFOURCC('A','T','I','2'), "D3DFMT_ATI2"},
12697 static const struct
12699 D3DPOOL pool;
12700 const char *name;
12702 pools[] =
12704 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED"},
12705 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM"},
12706 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH"},
12709 window = create_window();
12710 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12711 ok(!!d3d, "Failed to create a D3D object.\n");
12712 if (!(device = create_device(d3d, window, NULL)))
12714 skip("Failed to create a D3D device, skipping tests.\n");
12715 goto done;
12718 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12719 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
12721 base_dimension = 257;
12722 if (caps.TextureCaps & (D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_CUBEMAP_POW2))
12724 skip("Using power of two base dimension.\n");
12725 base_dimension = 256;
12728 for (format_idx = 0; format_idx < ARRAY_SIZE(formats); ++format_idx)
12730 if (FAILED(hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12731 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[format_idx].format)))
12733 skip("%s textures not supported, skipping tests.\n", formats[format_idx].name);
12734 continue;
12737 for (pool_idx = 0; pool_idx < ARRAY_SIZE(pools); ++pool_idx)
12739 hr = IDirect3DDevice9_CreateTexture(device, base_dimension, base_dimension, 0, 0,
12740 formats[format_idx].format, pools[pool_idx].pool, &texture_2d, NULL);
12741 ok(SUCCEEDED(hr), "Failed to create a %s %s texture, hr %#lx.\n",
12742 pools[pool_idx].name, formats[format_idx].name, hr);
12744 level_count = IDirect3DTexture9_GetLevelCount(texture_2d);
12745 for (i = 0, offset = 0; i < level_count; ++i)
12747 hr = IDirect3DTexture9_LockRect(texture_2d, i, &map_desc, NULL, 0);
12748 ok(SUCCEEDED(hr), "%s, %s: Failed to lock level %u, hr %#lx.\n",
12749 pools[pool_idx].name, formats[format_idx].name, i, hr);
12751 if (!i)
12752 base = map_desc.pBits;
12753 else
12754 ok(map_desc.pBits == base + offset,
12755 "%s, %s, level %u: Got unexpected pBits %p, expected %p.\n",
12756 pools[pool_idx].name, formats[format_idx].name, i, map_desc.pBits, base + offset);
12757 offset += (base_dimension >> i) * map_desc.Pitch;
12759 hr = IDirect3DTexture9_UnlockRect(texture_2d, i);
12760 ok(SUCCEEDED(hr), "%s, %s Failed to unlock level %u, hr %#lx.\n",
12761 pools[pool_idx].name, formats[format_idx].name, i, hr);
12764 IDirect3DTexture9_Release(texture_2d);
12767 if (FAILED(hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
12768 D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, formats[format_idx].format)))
12770 skip("%s cube textures not supported, skipping tests.\n", formats[format_idx].name);
12771 continue;
12774 for (pool_idx = 0; pool_idx < ARRAY_SIZE(pools); ++pool_idx)
12776 hr = IDirect3DDevice9_CreateCubeTexture(device, base_dimension, 0, 0,
12777 formats[format_idx].format, pools[pool_idx].pool, &texture_cube, NULL);
12778 ok(SUCCEEDED(hr), "Failed to create a %s %s cube texture, hr %#lx.\n",
12779 pools[pool_idx].name, formats[format_idx].name, hr);
12781 level_count = IDirect3DCubeTexture9_GetLevelCount(texture_cube);
12782 for (i = 0, offset = 0; i < 6; ++i)
12784 for (j = 0; j < level_count; ++j)
12786 hr = IDirect3DCubeTexture9_LockRect(texture_cube, i, j, &map_desc, NULL, 0);
12787 ok(SUCCEEDED(hr), "%s, %s: Failed to lock face %u, level %u, hr %#lx.\n",
12788 pools[pool_idx].name, formats[format_idx].name, i, j, hr);
12790 if (!i && !j)
12791 base = map_desc.pBits;
12792 else
12793 ok(map_desc.pBits == base + offset,
12794 "%s, %s, face %u, level %u: Got unexpected pBits %p, expected %p.\n",
12795 pools[pool_idx].name, formats[format_idx].name, i, j, map_desc.pBits, base + offset);
12796 offset += (base_dimension >> j) * map_desc.Pitch;
12798 hr = IDirect3DCubeTexture9_UnlockRect(texture_cube, i, j);
12799 ok(SUCCEEDED(hr), "%s, %s: Failed to unlock face %u, level %u, hr %#lx.\n",
12800 pools[pool_idx].name, formats[format_idx].name, i, j, hr);
12802 offset = (offset + 15) & ~15;
12805 IDirect3DCubeTexture9_Release(texture_cube);
12809 refcount = IDirect3DDevice9_Release(device);
12810 ok(!refcount, "Device has %lu references left.\n", refcount);
12811 done:
12812 IDirect3D9_Release(d3d);
12813 DestroyWindow(window);
12816 static void test_get_render_target_data(void)
12818 IDirect3DSurface9 *offscreen_surface, *render_target;
12819 IDirect3DDevice9 *device;
12820 IDirect3D9 *d3d;
12821 ULONG refcount;
12822 HWND window;
12823 HRESULT hr;
12825 window = create_window();
12826 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12827 ok(!!d3d, "Failed to create a D3D object.\n");
12828 if (!(device = create_device(d3d, window, NULL)))
12830 skip("Failed to create a D3D device.\n");
12831 IDirect3D9_Release(d3d);
12832 DestroyWindow(window);
12833 return;
12836 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
12837 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
12838 ok(SUCCEEDED(hr), "Failed to create offscreen surface, hr %#lx.\n", hr);
12840 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
12841 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL);
12842 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
12844 hr = IDirect3DDevice9_GetRenderTargetData(device, NULL, NULL);
12845 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12847 hr = IDirect3DDevice9_GetRenderTargetData(device, render_target, NULL);
12848 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12850 hr = IDirect3DDevice9_GetRenderTargetData(device, NULL, offscreen_surface);
12851 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12853 hr = IDirect3DDevice9_GetRenderTargetData(device, render_target, offscreen_surface);
12854 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
12856 IDirect3DSurface9_Release(render_target);
12857 IDirect3DSurface9_Release(offscreen_surface);
12858 refcount = IDirect3DDevice9_Release(device);
12859 ok(!refcount, "Device has %lu references left.\n", refcount);
12860 IDirect3D9_Release(d3d);
12861 DestroyWindow(window);
12864 static void test_render_target_device_mismatch(void)
12866 IDirect3DDevice9 *device, *device2;
12867 IDirect3DSurface9 *surface, *rt;
12868 IDirect3D9 *d3d;
12869 ULONG refcount;
12870 HWND window;
12871 HRESULT hr;
12873 window = create_window();
12874 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12875 ok(!!d3d, "Failed to create a D3D object.\n");
12876 if (!(device = create_device(d3d, window, NULL)))
12878 skip("Failed to create a D3D device.\n");
12879 IDirect3D9_Release(d3d);
12880 DestroyWindow(window);
12881 return;
12884 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
12885 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
12887 device2 = create_device(d3d, window, NULL);
12888 ok(!!device2, "Failed to create a D3D device.\n");
12890 hr = IDirect3DDevice9_CreateRenderTarget(device2, 640, 480,
12891 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
12892 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
12894 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
12895 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12897 IDirect3DSurface9_Release(surface);
12899 hr = IDirect3DDevice9_GetRenderTarget(device2, 0, &surface);
12900 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
12902 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
12903 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12905 IDirect3DSurface9_Release(surface);
12907 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
12908 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
12909 ok(surface == rt, "Got unexpected render target %p, expected %p.\n", surface, rt);
12910 IDirect3DSurface9_Release(surface);
12911 IDirect3DSurface9_Release(rt);
12913 refcount = IDirect3DDevice9_Release(device);
12914 ok(!refcount, "Device has %lu references left.\n", refcount);
12915 refcount = IDirect3DDevice9_Release(device2);
12916 ok(!refcount, "Device has %lu references left.\n", refcount);
12917 IDirect3D9_Release(d3d);
12918 DestroyWindow(window);
12921 static void test_format_unknown(void)
12923 IDirect3DDevice9 *device;
12924 IDirect3D9 *d3d;
12925 ULONG refcount;
12926 HWND window;
12927 void *iface;
12928 HRESULT hr;
12930 window = create_window();
12931 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12932 ok(!!d3d, "Failed to create a D3D object.\n");
12933 if (!(device = create_device(d3d, window, NULL)))
12935 skip("Failed to create a D3D device.\n");
12936 IDirect3D9_Release(d3d);
12937 DestroyWindow(window);
12938 return;
12941 iface = (void *)0xdeadbeef;
12942 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
12943 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, FALSE, (IDirect3DSurface9 **)&iface, NULL);
12944 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12945 ok(!iface, "Got unexpected iface %p.\n", iface);
12947 iface = (void *)0xdeadbeef;
12948 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 64, 64,
12949 D3DFMT_UNKNOWN, D3DMULTISAMPLE_NONE, 0, TRUE, (IDirect3DSurface9 **)&iface, NULL);
12950 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12951 ok(!iface, "Got unexpected iface %p.\n", iface);
12953 iface = (void *)0xdeadbeef;
12954 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
12955 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DSurface9 **)&iface, NULL);
12956 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12957 ok(!iface, "Got unexpected iface %p.\n", iface);
12959 iface = (void *)0xdeadbeef;
12960 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
12961 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DTexture9 **)&iface, NULL);
12962 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12963 ok(!iface, "Got unexpected iface %p.\n", iface);
12965 iface = (void *)0xdeadbeef;
12966 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 1, 0,
12967 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DCubeTexture9 **)&iface, NULL);
12968 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12969 ok(!iface, "Got unexpected iface %p.\n", iface);
12971 iface = (void *)0xdeadbeef;
12972 hr = IDirect3DDevice9_CreateVolumeTexture(device, 64, 64, 1, 1, 0,
12973 D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, (IDirect3DVolumeTexture9 **)&iface, NULL);
12974 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
12975 ok(!iface, "Got unexpected iface %p.\n", iface);
12977 refcount = IDirect3DDevice9_Release(device);
12978 ok(!refcount, "Device has %lu references left.\n", refcount);
12979 IDirect3D9_Release(d3d);
12980 DestroyWindow(window);
12983 static void test_destroyed_window(void)
12985 IDirect3DDevice9 *device;
12986 IDirect3D9 *d3d9;
12987 ULONG refcount;
12988 HWND window;
12989 HRESULT hr;
12991 /* No WS_VISIBLE. */
12992 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
12993 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12994 ok(!!window, "Failed to create a window.\n");
12996 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
12997 ok(!!d3d9, "Failed to create a D3D object.\n");
12998 device = create_device(d3d9, window, NULL);
12999 IDirect3D9_Release(d3d9);
13000 DestroyWindow(window);
13001 if (!device)
13003 skip("Failed to create a 3D device, skipping test.\n");
13004 return;
13007 hr = IDirect3DDevice9_BeginScene(device);
13008 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
13009 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
13010 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
13011 hr = IDirect3DDevice9_EndScene(device);
13012 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
13013 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13014 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
13016 refcount = IDirect3DDevice9_Release(device);
13017 ok(!refcount, "Device has %lu references left.\n", refcount);
13020 static void test_lockable_backbuffer(void)
13022 D3DPRESENT_PARAMETERS present_parameters = {0};
13023 struct device_desc device_desc;
13024 IDirect3DSurface9 *surface;
13025 IDirect3DDevice9 *device;
13026 D3DLOCKED_RECT lockrect;
13027 IDirect3D9 *d3d;
13028 ULONG refcount;
13029 HWND window;
13030 HRESULT hr;
13031 HDC dc;
13033 window = create_window();
13034 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13035 ok(!!d3d, "Failed to create a D3D object.\n");
13037 if (!(device = create_device(d3d, window, NULL)))
13039 skip("Failed to create a D3D device, skipping tests.\n");
13040 IDirect3D9_Release(d3d);
13041 DestroyWindow(window);
13042 return;
13045 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
13046 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
13048 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
13049 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
13051 dc = (void *)0xdeadbeef;
13052 hr = IDirect3DSurface9_GetDC(surface, &dc);
13053 ok(dc == (void *)0xdeadbeef, "Unexpected DC returned.\n");
13054 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
13056 IDirect3DSurface9_Release(surface);
13058 /* Reset with D3DPRESENTFLAG_LOCKABLE_BACKBUFFER. */
13059 present_parameters.BackBufferWidth = 640;
13060 present_parameters.BackBufferHeight = 480;
13061 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
13062 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
13063 present_parameters.hDeviceWindow = window;
13064 present_parameters.Windowed = TRUE;
13065 present_parameters.EnableAutoDepthStencil = TRUE;
13066 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
13067 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
13069 hr = IDirect3DDevice9_Reset(device, &present_parameters);
13070 ok(SUCCEEDED(hr), "Failed to reset device, hr %#lx.\n", hr);
13072 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
13073 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
13075 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
13076 ok(SUCCEEDED(hr), "Failed to lock rect, hr %#lx.\n", hr);
13077 hr = IDirect3DSurface9_UnlockRect(surface);
13078 ok(SUCCEEDED(hr), "Failed to unlock rect, hr %#lx.\n", hr);
13080 IDirect3DSurface9_Release(surface);
13081 refcount = IDirect3DDevice9_Release(device);
13082 ok(!refcount, "Device has %lu references left.\n", refcount);
13084 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
13085 device_desc.width = 640;
13086 device_desc.height = 480;
13087 device_desc.device_window = window;
13088 device_desc.flags = CREATE_DEVICE_LOCKABLE_BACKBUFFER;
13090 device = create_device(d3d, window, &device_desc);
13091 ok(!!device, "Failed to create device.\n");
13093 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
13094 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
13096 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
13097 ok(SUCCEEDED(hr), "Failed to lock rect, hr %#lx.\n", hr);
13098 hr = IDirect3DSurface9_UnlockRect(surface);
13099 ok(SUCCEEDED(hr), "Failed to unlock rect, hr %#lx.\n", hr);
13101 IDirect3DSurface9_Release(surface);
13102 refcount = IDirect3DDevice9_Release(device);
13103 ok(!refcount, "Device has %lu references left.\n", refcount);
13104 IDirect3D9_Release(d3d);
13105 DestroyWindow(window);
13108 static void test_clip_planes_limits(void)
13110 static const DWORD device_flags[] = {0, CREATE_DEVICE_SWVP_ONLY};
13111 IDirect3DDevice9 *device;
13112 struct device_desc desc;
13113 unsigned int i, j;
13114 IDirect3D9 *d3d;
13115 ULONG refcount;
13116 float plane[4];
13117 D3DCAPS9 caps;
13118 DWORD state;
13119 HWND window;
13120 HRESULT hr;
13122 window = create_window();
13123 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13124 ok(!!d3d, "Failed to create a D3D object.\n");
13126 for (i = 0; i < ARRAY_SIZE(device_flags); ++i)
13128 desc.adapter_ordinal = D3DADAPTER_DEFAULT;
13129 desc.device_window = window;
13130 desc.width = 640;
13131 desc.height = 480;
13132 desc.flags = device_flags[i];
13133 if (!(device = create_device(d3d, window, &desc)))
13135 skip("Failed to create D3D device, flags %#lx.\n", desc.flags);
13136 continue;
13139 memset(&caps, 0, sizeof(caps));
13140 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13141 ok(hr == D3D_OK, "Failed to get caps, hr %#lx.\n", hr);
13143 trace("Max user clip planes: %lu.\n", caps.MaxUserClipPlanes);
13145 for (j = 0; j < 2 * D3DMAXUSERCLIPPLANES; ++j)
13147 memset(plane, 0xff, sizeof(plane));
13148 hr = IDirect3DDevice9_GetClipPlane(device, j, plane);
13149 ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#lx.\n", j, hr);
13150 ok(!plane[0] && !plane[1] && !plane[2] && !plane[3],
13151 "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n",
13152 j, plane[0], plane[1], plane[2], plane[3]);
13155 plane[0] = 2.0f;
13156 plane[1] = 8.0f;
13157 plane[2] = 5.0f;
13158 for (j = 0; j < 2 * D3DMAXUSERCLIPPLANES; ++j)
13160 plane[3] = j;
13161 hr = IDirect3DDevice9_SetClipPlane(device, j, plane);
13162 ok(hr == D3D_OK, "Failed to set clip plane %u, hr %#lx.\n", j, hr);
13164 for (j = 0; j < 2 * D3DMAXUSERCLIPPLANES; ++j)
13166 float expected_d = j >= caps.MaxUserClipPlanes - 1 ? 2 * D3DMAXUSERCLIPPLANES - 1 : j;
13167 memset(plane, 0xff, sizeof(plane));
13168 hr = IDirect3DDevice9_GetClipPlane(device, j, plane);
13169 ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#lx.\n", j, hr);
13170 ok(plane[0] == 2.0f && plane[1] == 8.0f && plane[2] == 5.0f && plane[3] == expected_d,
13171 "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n",
13172 j, plane[0], plane[1], plane[2], plane[3]);
13175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0xffffffff);
13176 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
13177 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_CLIPPLANEENABLE, &state);
13178 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
13179 ok(state == 0xffffffff, "Got unexpected state %#lx.\n", state);
13180 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x80000000);
13181 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
13182 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_CLIPPLANEENABLE, &state);
13183 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
13184 ok(state == 0x80000000, "Got unexpected state %#lx.\n", state);
13186 refcount = IDirect3DDevice9_Release(device);
13187 ok(!refcount, "Device has %lu references left.\n", refcount);
13190 IDirect3D9_Release(d3d);
13191 DestroyWindow(window);
13194 static void test_swapchain_multisample_reset(void)
13196 IDirect3DSwapChain9 *swapchain;
13197 D3DPRESENT_PARAMETERS d3dpp;
13198 IDirect3DDevice9 *device;
13199 DWORD quality_levels;
13200 IDirect3D9 *d3d;
13201 ULONG refcount;
13202 HWND window;
13203 HRESULT hr;
13205 window = create_window();
13206 ok(!!window, "Failed to create a window.\n");
13207 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13208 ok(!!d3d, "Failed to create a D3D object.\n");
13210 if (IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13211 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels) == D3DERR_NOTAVAILABLE)
13213 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
13214 IDirect3D9_Release(d3d);
13215 DestroyWindow(window);
13216 return;
13219 if (!(device = create_device(d3d, window, NULL)))
13221 skip("Failed to create a 3D device.\n");
13222 IDirect3D9_Release(d3d);
13223 DestroyWindow(window);
13224 return;
13227 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
13228 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
13230 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
13231 ok(hr == D3D_OK, "Failed to get the implicit swapchain, hr %#lx.\n", hr);
13232 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
13233 ok(hr == D3D_OK, "Failed to get present parameters, hr %#lx.\n", hr);
13234 ok(d3dpp.MultiSampleType == D3DMULTISAMPLE_NONE,
13235 "Got unexpected multisample type %#x.\n", d3dpp.MultiSampleType);
13236 IDirect3DSwapChain9_Release(swapchain);
13238 d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
13239 d3dpp.MultiSampleQuality = quality_levels - 1;
13240 hr = IDirect3DDevice9_Reset(device, &d3dpp);
13241 ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr);
13243 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
13244 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
13246 refcount = IDirect3DDevice9_Release(device);
13247 ok(!refcount, "Device has %lu references left.\n", refcount);
13248 IDirect3D9_Release(d3d);
13249 DestroyWindow(window);
13252 static void test_stretch_rect(void)
13254 IDirect3DTexture9 *src_texture, *dst_texture;
13255 IDirect3DSurface9 *src_surface, *dst_surface;
13256 IDirect3DSurface9 *src_rt, *dst_rt;
13257 D3DFORMAT src_format, dst_format;
13258 IDirect3DSurface9 *src, *dst;
13259 D3DPOOL src_pool, dst_pool;
13260 BOOL can_stretch_textures;
13261 IDirect3DDevice9 *device;
13262 HRESULT expected_hr;
13263 unsigned int i, j;
13264 IDirect3D9 *d3d;
13265 ULONG refcount;
13266 D3DCAPS9 caps;
13267 HWND window;
13268 HRESULT hr;
13270 static const D3DFORMAT formats[] =
13272 D3DFMT_A8R8G8B8,
13273 D3DFMT_X8R8G8B8,
13274 D3DFMT_R5G6B5,
13277 window = create_window();
13278 ok(!!window, "Failed to create a window.\n");
13279 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13280 ok(!!d3d, "Failed to create a D3D object.\n");
13282 if (!(device = create_device(d3d, window, NULL)))
13284 skip("Failed to create a 3D device.\n");
13285 IDirect3D9_Release(d3d);
13286 DestroyWindow(window);
13287 return;
13290 memset(&caps, 0, sizeof(caps));
13291 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13292 ok(hr == D3D_OK, "Failed to get caps, hr %#lx.\n", hr);
13293 can_stretch_textures = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES;
13295 for (i = 0; i < ARRAY_SIZE(formats); ++i)
13297 src_format = formats[i];
13298 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13299 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, src_format))
13300 || FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13301 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, src_format)))
13303 skip("Format %#x not supported.\n", src_format);
13304 continue;
13307 for (j = 0; j < ARRAY_SIZE(formats); ++j)
13309 dst_format = formats[j];
13310 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13311 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, dst_format))
13312 || FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13313 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, dst_format)))
13315 skip("Format %#x not supported.\n", dst_format);
13316 continue;
13319 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, src_format,
13320 D3DMULTISAMPLE_NONE, 0, FALSE, &src_rt, NULL);
13321 ok(hr == D3D_OK, "Failed to create render target, hr %#lx.\n", hr);
13322 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, dst_format,
13323 D3DMULTISAMPLE_NONE, 0, FALSE, &dst_rt, NULL);
13324 ok(hr == D3D_OK, "Failed to create render target, hr %#lx.\n", hr);
13326 hr = IDirect3DDevice9_StretchRect(device, src_rt, NULL, dst_rt, NULL, D3DTEXF_NONE);
13327 ok(hr == D3D_OK, "Got hr %#lx (formats %#x/%#x).\n", hr, src_format, dst_format);
13329 for (src_pool = D3DPOOL_DEFAULT; src_pool <= D3DPOOL_SCRATCH; ++src_pool)
13331 for (dst_pool = D3DPOOL_DEFAULT; dst_pool <= D3DPOOL_SCRATCH; ++dst_pool)
13333 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0,
13334 src_format, src_pool, &src_texture, NULL);
13335 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
13336 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0,
13337 dst_format, dst_pool, &dst_texture, NULL);
13338 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
13339 hr = IDirect3DTexture9_GetSurfaceLevel(src_texture, 0, &src);
13340 ok(hr == D3D_OK, "Failed to get surface, hr %#lx.\n", hr);
13341 hr = IDirect3DTexture9_GetSurfaceLevel(dst_texture, 0, &dst);
13342 ok(hr == D3D_OK, "Failed to get surface, hr %#lx.\n", hr);
13343 IDirect3DTexture9_Release(src_texture);
13344 IDirect3DTexture9_Release(dst_texture);
13346 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_NONE);
13347 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx (formats %#x/%#x, pools %#x/%#x).\n",
13348 hr, src_format, dst_format, src_pool, dst_pool);
13350 /* render target <-> texture */
13351 if (src_pool == D3DPOOL_DEFAULT && can_stretch_textures)
13352 expected_hr = D3D_OK;
13353 else
13354 expected_hr = D3DERR_INVALIDCALL;
13355 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst_rt, NULL, D3DTEXF_NONE);
13356 ok(hr == expected_hr, "Got hr %#lx, expected hr %#lx (formats %#x/%#x, pool %#x).\n",
13357 hr, expected_hr, src_format, dst_format, src_pool);
13358 hr = IDirect3DDevice9_StretchRect(device, src_rt, NULL, dst, NULL, D3DTEXF_NONE);
13359 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx (formats %#x/%#x, pool %#x).\n",
13360 hr, src_format, dst_format, dst_pool);
13362 if (src_pool == D3DPOOL_MANAGED || dst_pool == D3DPOOL_MANAGED)
13364 IDirect3DSurface9_Release(src);
13365 IDirect3DSurface9_Release(dst);
13366 continue;
13369 if (src_pool == D3DPOOL_DEFAULT && dst_pool == D3DPOOL_DEFAULT)
13370 expected_hr = D3D_OK;
13371 else
13372 expected_hr = D3DERR_INVALIDCALL;
13374 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13375 src_format, src_pool, &src_surface, NULL);
13376 ok(hr == D3D_OK, "Failed to create surface, hr %#lx.\n", hr);
13377 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13378 dst_format, dst_pool, &dst_surface, NULL);
13379 ok(hr == D3D_OK, "Failed to create surface, hr %#lx.\n", hr);
13381 hr = IDirect3DDevice9_StretchRect(device, src_surface, NULL, dst_surface, NULL, D3DTEXF_NONE);
13382 ok(hr == expected_hr, "Got hr %#lx, expected %#lx (formats %#x/%#x, pools %#x/%#x).\n",
13383 hr, expected_hr, src_format, dst_format, src_pool, dst_pool);
13385 /* offscreen plain <-> texture */
13386 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst_surface, NULL, D3DTEXF_NONE);
13387 todo_wine_if(src_pool == D3DPOOL_DEFAULT && dst_pool == D3DPOOL_DEFAULT)
13388 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx (formats %#x/%#x, pools %#x/%#x).\n",
13389 hr, src_format, dst_format, src_pool, dst_pool);
13390 hr = IDirect3DDevice9_StretchRect(device, src_surface, NULL, dst, NULL, D3DTEXF_NONE);
13391 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx (formats %#x/%#x, pools %#x/%#x).\n",
13392 hr, src_format, dst_format, src_pool, dst_pool);
13394 /* offscreen plain <-> render target */
13395 expected_hr = src_pool == D3DPOOL_DEFAULT ? D3D_OK : D3DERR_INVALIDCALL;
13396 hr = IDirect3DDevice9_StretchRect(device, src_surface, NULL, dst_rt, NULL, D3DTEXF_NONE);
13397 ok(hr == expected_hr, "Got hr %#lx, expected hr %#lx (formats %#x/%#x, pool %#x).\n",
13398 hr, expected_hr, src_format, dst_format, src_pool);
13399 hr = IDirect3DDevice9_StretchRect(device, src_rt, NULL, dst_surface, NULL, D3DTEXF_NONE);
13400 todo_wine_if(dst_pool == D3DPOOL_DEFAULT)
13401 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx (formats %#x/%#x, pool %#x).\n",
13402 hr, src_format, dst_format, dst_pool);
13404 IDirect3DSurface9_Release(src_surface);
13405 IDirect3DSurface9_Release(dst_surface);
13407 IDirect3DSurface9_Release(src);
13408 IDirect3DSurface9_Release(dst);
13412 IDirect3DSurface9_Release(src_rt);
13413 IDirect3DSurface9_Release(dst_rt);
13417 refcount = IDirect3DDevice9_Release(device);
13418 ok(!refcount, "Device has %lu references left.\n", refcount);
13419 IDirect3D9_Release(d3d);
13420 DestroyWindow(window);
13423 #define test_device_caps_adapter_group(a, b, c) _test_device_caps_adapter_group(a, b, c, __LINE__)
13424 static void _test_device_caps_adapter_group(const D3DCAPS9 *caps, unsigned int adapter_idx,
13425 unsigned int adapter_count, int line)
13427 ok_(__FILE__, line)(caps->AdapterOrdinal == adapter_idx,
13428 "Adapter %u: Got unexpected AdapterOrdinal %u.\n", adapter_idx, caps->AdapterOrdinal);
13429 /* Single GPU */
13430 if (caps->NumberOfAdaptersInGroup == adapter_count)
13432 ok_(__FILE__, line)(caps->MasterAdapterOrdinal == 0,
13433 "Adapter %u: Expect MasterAdapterOrdinal %u, got %u.\n", adapter_idx, 0,
13434 caps->MasterAdapterOrdinal);
13435 ok_(__FILE__, line)(caps->AdapterOrdinalInGroup == caps->AdapterOrdinal,
13436 "Adapter %u: Expect AdapterOrdinalInGroup %u, got %u.\n", adapter_idx,
13437 caps->AdapterOrdinal, caps->AdapterOrdinalInGroup);
13438 ok_(__FILE__, line)(caps->NumberOfAdaptersInGroup ==
13439 (caps->AdapterOrdinalInGroup ? 0 : adapter_count),
13440 "Adapter %u: Expect NumberOfAdaptersInGroup %u, got %u.\n", adapter_idx,
13441 (caps->AdapterOrdinalInGroup ? 0 : adapter_count),
13442 caps->NumberOfAdaptersInGroup);
13444 /* Multiple GPUs and each GPU has only one output */
13445 else if (caps->NumberOfAdaptersInGroup == 1)
13447 ok_(__FILE__, line)(caps->MasterAdapterOrdinal == caps->AdapterOrdinal,
13448 "Adapter %u: Expect MasterAdapterOrdinal %u, got %u.\n", adapter_idx,
13449 caps->AdapterOrdinal, caps->MasterAdapterOrdinal);
13450 ok_(__FILE__, line)(caps->AdapterOrdinalInGroup == 0,
13451 "Adapter %u: Expect AdapterOrdinalInGroup %u, got %u.\n", adapter_idx, 0,
13452 caps->AdapterOrdinalInGroup);
13454 /* TODO: Test other multi-GPU setup */
13457 static void test_device_caps(void)
13459 unsigned int adapter_idx, adapter_count;
13460 struct device_desc device_desc;
13461 IDirect3DDevice9 *device;
13462 IDirect3D9 *d3d;
13463 ULONG refcount;
13464 D3DCAPS9 caps;
13465 HWND window;
13466 HRESULT hr;
13468 window = create_window();
13469 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13470 ok(!!d3d, "Failed to create a D3D object.\n");
13472 device_desc.device_window = window;
13473 device_desc.width = 640;
13474 device_desc.height = 480;
13475 device_desc.flags = 0;
13477 adapter_count = IDirect3D9_GetAdapterCount(d3d);
13478 for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx)
13480 /* Test IDirect3D9_GetDeviceCaps */
13481 hr = IDirect3D9_GetDeviceCaps(d3d, adapter_idx, D3DDEVTYPE_HAL, &caps);
13482 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Adapter %u: GetDeviceCaps failed, hr %#lx.\n",
13483 adapter_idx, hr);
13484 if (hr == D3DERR_NOTAVAILABLE)
13486 skip("Adapter %u: No Direct3D support, skipping test.\n", adapter_idx);
13487 break;
13489 test_device_caps_adapter_group(&caps, adapter_idx, adapter_count);
13491 /* Test IDirect3DDevice9_GetDeviceCaps */
13492 device_desc.adapter_ordinal = adapter_idx;
13493 device = create_device(d3d, window, &device_desc);
13494 if (!device)
13496 skip("Adapter %u: Failed to create a D3D device, skipping test.\n", adapter_idx);
13497 break;
13499 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13500 ok(SUCCEEDED(hr), "Adapter %u: Failed to get caps, hr %#lx.\n", adapter_idx, hr);
13502 test_device_caps_adapter_group(&caps, adapter_idx, adapter_count);
13503 ok(!(caps.Caps & ~D3DCAPS_READ_SCANLINE),
13504 "Adapter %u: Caps field has unexpected flags %#lx.\n", adapter_idx, caps.Caps);
13505 ok(!(caps.Caps2 & ~(D3DCAPS2_FULLSCREENGAMMA | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED
13506 | D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP
13507 | D3DCAPS2_CANSHARERESOURCE)),
13508 "Adapter %u: Caps2 field has unexpected flags %#lx.\n", adapter_idx, caps.Caps2);
13509 /* AMD doesn't filter all the ddraw / d3d9 caps. Consider that behavior
13510 * broken. */
13511 ok(!(caps.Caps3 & ~(D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD
13512 | D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION | D3DCAPS3_COPY_TO_VIDMEM
13513 | D3DCAPS3_COPY_TO_SYSTEMMEM | D3DCAPS3_DXVAHD | D3DCAPS3_DXVAHD_LIMITED
13514 | D3DCAPS3_RESERVED)),
13515 "Adapter %u: Caps3 field has unexpected flags %#lx.\n", adapter_idx, caps.Caps3);
13516 ok(!(caps.PrimitiveMiscCaps & ~(D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP
13517 | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW
13518 | D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
13519 | D3DPMISCCAPS_CLIPTLVERTS | D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_BLENDOP
13520 | D3DPMISCCAPS_NULLREFERENCE | D3DPMISCCAPS_INDEPENDENTWRITEMASKS
13521 | D3DPMISCCAPS_PERSTAGECONSTANT | D3DPMISCCAPS_FOGANDSPECULARALPHA
13522 | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
13523 | D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING | D3DPMISCCAPS_FOGVERTEXCLAMPED
13524 | D3DPMISCCAPS_POSTBLENDSRGBCONVERT)),
13525 "Adapter %u: PrimitiveMiscCaps field has unexpected flags %#lx.\n", adapter_idx,
13526 caps.PrimitiveMiscCaps);
13527 ok(!(caps.RasterCaps & ~(D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST
13528 | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE
13529 | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR
13530 | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER
13531 | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE
13532 | D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
13533 | D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_MULTISAMPLE_TOGGLE))
13534 || broken(!(caps.RasterCaps & ~0x0f736191)),
13535 "Adapter %u: RasterCaps field has unexpected flags %#lx.\n", adapter_idx,
13536 caps.RasterCaps);
13537 /* D3DPBLENDCAPS_SRCCOLOR2 and D3DPBLENDCAPS_INVSRCCOLOR2 are only
13538 * advertised on the reference rasterizer and WARP. */
13539 ok(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
13540 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
13541 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
13542 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
13543 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR))
13544 || broken(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
13545 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
13546 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
13547 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
13548 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR
13549 | D3DPBLENDCAPS_SRCCOLOR2 | D3DPBLENDCAPS_INVSRCCOLOR2))),
13550 "Adapter %u: SrcBlendCaps field has unexpected flags %#lx.\n", adapter_idx,
13551 caps.SrcBlendCaps);
13552 ok(!(caps.DestBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
13553 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
13554 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
13555 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
13556 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR))
13557 || broken(!(caps.SrcBlendCaps & ~(D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR
13558 | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA
13559 | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR
13560 | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA
13561 | D3DPBLENDCAPS_BOTHINVSRCALPHA | D3DPBLENDCAPS_BLENDFACTOR
13562 | D3DPBLENDCAPS_SRCCOLOR2 | D3DPBLENDCAPS_INVSRCCOLOR2))),
13563 "Adapter %u: DestBlendCaps field has unexpected flags %#lx.\n", adapter_idx,
13564 caps.DestBlendCaps);
13565 ok(!(caps.TextureCaps & ~(D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2
13566 | D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_SQUAREONLY
13567 | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE
13568 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PROJECTED
13569 | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP | D3DPTEXTURECAPS_MIPMAP
13570 | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP
13571 | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2
13572 | D3DPTEXTURECAPS_NOPROJECTEDBUMPENV)),
13573 "Adapter %u: TextureCaps field has unexpected flags %#lx.\n", adapter_idx,
13574 caps.TextureCaps);
13575 ok(!(caps.TextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
13576 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
13577 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
13578 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_CONVOLUTIONMONO
13579 | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
13580 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
13581 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
13582 "Adapter %u: TextureFilterCaps field has unexpected flags %#lx.\n", adapter_idx,
13583 caps.TextureFilterCaps);
13584 ok(!(caps.CubeTextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
13585 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
13586 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
13587 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
13588 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
13589 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
13590 "Adapter %u: CubeTextureFilterCaps field has unexpected flags %#lx.\n", adapter_idx,
13591 caps.CubeTextureFilterCaps);
13592 ok(!(caps.VolumeTextureFilterCaps & ~(D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR
13593 | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MINFPYRAMIDALQUAD
13594 | D3DPTFILTERCAPS_MINFGAUSSIANQUAD | D3DPTFILTERCAPS_MIPFPOINT
13595 | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR
13596 | D3DPTFILTERCAPS_MAGFANISOTROPIC | D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD
13597 | D3DPTFILTERCAPS_MAGFGAUSSIANQUAD)),
13598 "Adapter %u: VolumeTextureFilterCaps field has unexpected flags %#lx.\n",
13599 adapter_idx, caps.VolumeTextureFilterCaps);
13600 ok(!(caps.LineCaps & ~(D3DLINECAPS_TEXTURE | D3DLINECAPS_ZTEST | D3DLINECAPS_BLEND
13601 | D3DLINECAPS_ALPHACMP | D3DLINECAPS_FOG | D3DLINECAPS_ANTIALIAS)),
13602 "Adapter %u: LineCaps field has unexpected flags %#lx.\n", adapter_idx,
13603 caps.LineCaps);
13604 ok(!(caps.StencilCaps & ~(D3DSTENCILCAPS_KEEP | D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE
13605 | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INVERT
13606 | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR | D3DSTENCILCAPS_TWOSIDED)),
13607 "Adapter %u: StencilCaps field has unexpected flags %#lx.\n", adapter_idx,
13608 caps.StencilCaps);
13609 ok(!(caps.VertexProcessingCaps & ~(D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7
13610 | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER
13611 | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_TEXGEN_SPHEREMAP
13612 | D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER)),
13613 "Adapter %u: VertexProcessingCaps field has unexpected flags %#lx.\n", adapter_idx,
13614 caps.VertexProcessingCaps);
13615 /* Both Nvidia and AMD give 10 here. */
13616 ok(caps.MaxActiveLights <= 10,
13617 "Adapter %u: MaxActiveLights field has unexpected value %lu.\n", adapter_idx,
13618 caps.MaxActiveLights);
13619 /* AMD gives 6, Nvidia returns 8. */
13620 ok(caps.MaxUserClipPlanes <= 8,
13621 "Adapter %u: MaxUserClipPlanes field has unexpected value %lu.\n", adapter_idx,
13622 caps.MaxUserClipPlanes);
13623 ok(caps.MaxVertexW == 0.0f || caps.MaxVertexW >= 1e10f,
13624 "Adapter %u: MaxVertexW field has unexpected value %.8e.\n", adapter_idx,
13625 caps.MaxVertexW);
13627 refcount = IDirect3DDevice9_Release(device);
13628 ok(!refcount, "Adapter %u: Device has %lu references left.\n", adapter_idx, refcount);
13630 IDirect3D9_Release(d3d);
13631 DestroyWindow(window);
13634 static void test_resource_access(void)
13636 IDirect3DSurface9 *backbuffer, *depth_stencil;
13637 D3DFORMAT colour_format, depth_format, format;
13638 BOOL depth_2d, depth_cube, depth_plain;
13639 D3DADAPTER_IDENTIFIER9 identifier;
13640 struct device_desc device_desc;
13641 D3DSURFACE_DESC surface_desc;
13642 BOOL skip_ati2n_once = FALSE;
13643 IDirect3DDevice9 *device;
13644 unsigned int i, j;
13645 IDirect3D9 *d3d;
13646 ULONG refcount;
13647 HWND window;
13648 HRESULT hr;
13649 BOOL warp;
13651 enum surface_type
13653 SURFACE_2D,
13654 SURFACE_CUBE,
13655 SURFACE_RT,
13656 SURFACE_DS,
13657 SURFACE_PLAIN,
13660 enum resource_format
13662 FORMAT_COLOUR,
13663 FORMAT_ATI2,
13664 FORMAT_DEPTH,
13667 static const struct
13669 D3DPOOL pool;
13670 enum resource_format format;
13671 DWORD usage;
13672 BOOL valid;
13674 tests[] =
13676 /* 0 */
13677 {D3DPOOL_DEFAULT, FORMAT_COLOUR, 0, TRUE},
13678 {D3DPOOL_DEFAULT, FORMAT_ATI2, 0, TRUE},
13679 {D3DPOOL_DEFAULT, FORMAT_DEPTH, 0, TRUE},
13680 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, TRUE},
13681 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
13682 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
13683 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, TRUE},
13684 /* 7 */
13685 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC, TRUE},
13686 {D3DPOOL_DEFAULT, FORMAT_ATI2, D3DUSAGE_DYNAMIC, TRUE},
13687 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC, TRUE},
13688 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET, FALSE},
13689 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET, FALSE},
13690 {D3DPOOL_DEFAULT, FORMAT_COLOUR, D3DUSAGE_DYNAMIC | D3DUSAGE_DEPTHSTENCIL, FALSE},
13691 {D3DPOOL_DEFAULT, FORMAT_DEPTH, D3DUSAGE_DYNAMIC | D3DUSAGE_DEPTHSTENCIL, FALSE},
13692 /* 14 */
13693 {D3DPOOL_MANAGED, FORMAT_COLOUR, 0, TRUE},
13694 {D3DPOOL_MANAGED, FORMAT_ATI2, 0, TRUE},
13695 {D3DPOOL_MANAGED, FORMAT_DEPTH, 0, FALSE},
13696 {D3DPOOL_MANAGED, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
13697 {D3DPOOL_MANAGED, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
13698 {D3DPOOL_MANAGED, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
13699 {D3DPOOL_MANAGED, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
13700 /* 21 */
13701 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, 0, TRUE},
13702 {D3DPOOL_SYSTEMMEM, FORMAT_ATI2, 0, TRUE},
13703 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, 0, FALSE},
13704 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
13705 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
13706 {D3DPOOL_SYSTEMMEM, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
13707 {D3DPOOL_SYSTEMMEM, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
13708 /* 28 */
13709 {D3DPOOL_SCRATCH, FORMAT_COLOUR, 0, TRUE},
13710 {D3DPOOL_SCRATCH, FORMAT_ATI2, 0, TRUE},
13711 {D3DPOOL_SCRATCH, FORMAT_DEPTH, 0, FALSE},
13712 {D3DPOOL_SCRATCH, FORMAT_COLOUR, D3DUSAGE_RENDERTARGET, FALSE},
13713 {D3DPOOL_SCRATCH, FORMAT_DEPTH, D3DUSAGE_RENDERTARGET, FALSE},
13714 {D3DPOOL_SCRATCH, FORMAT_COLOUR, D3DUSAGE_DEPTHSTENCIL, FALSE},
13715 {D3DPOOL_SCRATCH, FORMAT_DEPTH, D3DUSAGE_DEPTHSTENCIL, FALSE},
13717 static const struct
13719 const char *name;
13720 enum surface_type type;
13722 surface_types[] =
13724 {"2D", SURFACE_2D},
13725 {"CUBE", SURFACE_CUBE},
13726 {"RT", SURFACE_RT},
13727 {"DS", SURFACE_DS},
13728 {"PLAIN", SURFACE_PLAIN},
13731 window = create_window();
13732 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13733 ok(!!d3d, "Failed to create a D3D object.\n");
13735 device_desc.adapter_ordinal = D3DADAPTER_DEFAULT;
13736 device_desc.device_window = window;
13737 device_desc.width = 16;
13738 device_desc.height = 16;
13739 device_desc.flags = 0;
13740 if (!(device = create_device(d3d, window, &device_desc)))
13742 skip("Failed to create a D3D device.\n");
13743 IDirect3D9_Release(d3d);
13744 DestroyWindow(window);
13745 return;
13747 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
13748 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
13749 warp = adapter_is_warp(&identifier);
13751 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
13752 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
13753 hr = IDirect3DSurface9_GetDesc(backbuffer, &surface_desc);
13754 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
13755 colour_format = surface_desc.Format;
13757 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &depth_stencil);
13758 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
13759 hr = IDirect3DSurface9_GetDesc(depth_stencil, &surface_desc);
13760 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
13761 depth_format = surface_desc.Format;
13763 depth_2d = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13764 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, depth_format));
13765 depth_cube = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13766 D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, depth_format));
13767 depth_plain = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
13768 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, depth_format));
13770 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
13771 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
13773 for (i = 0; i < ARRAY_SIZE(surface_types); ++i)
13775 for (j = 0; j < ARRAY_SIZE(tests); ++j)
13777 IDirect3DCubeTexture9 *texture_cube;
13778 IDirect3DBaseTexture9 *texture;
13779 IDirect3DTexture9 *texture_2d;
13780 IDirect3DSurface9 *surface;
13781 HRESULT expected_hr;
13782 D3DLOCKED_RECT lr;
13784 if (tests[j].format == FORMAT_ATI2)
13785 format = MAKEFOURCC('A','T','I','2');
13786 else if (tests[j].format == FORMAT_DEPTH)
13787 format = depth_format;
13788 else
13789 format = colour_format;
13791 if (tests[j].format == FORMAT_ATI2 && FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT,
13792 D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, format)))
13794 if (!skip_ati2n_once)
13796 skip("ATI2N texture not supported.\n");
13797 skip_ati2n_once = TRUE;
13799 continue;
13802 switch (surface_types[i].type)
13804 case SURFACE_2D:
13805 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1,
13806 tests[j].usage, format, tests[j].pool, &texture_2d, NULL);
13807 todo_wine_if(!tests[j].valid && tests[j].format == FORMAT_DEPTH && !tests[j].usage)
13808 ok(hr == (tests[j].valid && (tests[j].format != FORMAT_DEPTH || depth_2d)
13809 ? D3D_OK : D3DERR_INVALIDCALL),
13810 "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13811 if (FAILED(hr))
13812 continue;
13814 hr = IDirect3DTexture9_GetSurfaceLevel(texture_2d, 0, &surface);
13815 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13816 IDirect3DTexture9_Release(texture_2d);
13817 break;
13819 case SURFACE_CUBE:
13820 hr = IDirect3DDevice9_CreateCubeTexture(device, 16, 1,
13821 tests[j].usage, format, tests[j].pool, &texture_cube, NULL);
13822 todo_wine_if(!tests[j].valid && tests[j].format == FORMAT_DEPTH && !tests[j].usage)
13823 ok(hr == (tests[j].valid && (tests[j].format != FORMAT_DEPTH || depth_cube)
13824 ? D3D_OK : D3DERR_INVALIDCALL),
13825 "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13826 if (FAILED(hr))
13827 continue;
13829 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture_cube,
13830 D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
13831 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13832 IDirect3DCubeTexture9_Release(texture_cube);
13833 break;
13835 case SURFACE_RT:
13836 hr = IDirect3DDevice9_CreateRenderTarget(device, 16, 16, format,
13837 D3DMULTISAMPLE_NONE, 0, tests[j].usage & D3DUSAGE_DYNAMIC, &surface, NULL);
13838 ok(hr == (tests[j].format == FORMAT_COLOUR ? D3D_OK : D3DERR_INVALIDCALL),
13839 "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13840 if (FAILED(hr))
13841 continue;
13842 break;
13844 case SURFACE_DS:
13845 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 16, 16, format,
13846 D3DMULTISAMPLE_NONE, 0, tests[j].usage & D3DUSAGE_DYNAMIC, &surface, NULL);
13847 ok(hr == (tests[j].format == FORMAT_DEPTH ? D3D_OK : D3DERR_INVALIDCALL),
13848 "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13849 if (FAILED(hr))
13850 continue;
13851 break;
13853 case SURFACE_PLAIN:
13854 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device,
13855 16, 16, format, tests[j].pool, &surface, NULL);
13856 todo_wine_if(tests[j].format == FORMAT_ATI2 && tests[j].pool != D3DPOOL_MANAGED
13857 && tests[j].pool != D3DPOOL_SCRATCH)
13858 ok(hr == (tests[j].pool != D3DPOOL_MANAGED && (tests[j].format != FORMAT_DEPTH || depth_plain)
13859 && (tests[j].format != FORMAT_ATI2 || tests[j].pool == D3DPOOL_SCRATCH)
13860 ? D3D_OK : D3DERR_INVALIDCALL),
13861 "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13862 if (FAILED(hr))
13863 continue;
13864 break;
13866 default:
13867 ok(0, "Invalid surface type %#x.\n", surface_types[i].type);
13868 continue;
13871 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
13872 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13873 if (surface_types[i].type == SURFACE_RT)
13875 ok(surface_desc.Usage == D3DUSAGE_RENDERTARGET, "Test %s %u: Got unexpected usage %#lx.\n",
13876 surface_types[i].name, j, surface_desc.Usage);
13877 ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %s %u: Got unexpected pool %#x.\n",
13878 surface_types[i].name, j, surface_desc.Pool);
13880 else if (surface_types[i].type == SURFACE_DS)
13882 ok(surface_desc.Usage == D3DUSAGE_DEPTHSTENCIL, "Test %s %u: Got unexpected usage %#lx.\n",
13883 surface_types[i].name, j, surface_desc.Usage);
13884 ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %s %u: Got unexpected pool %#x.\n",
13885 surface_types[i].name, j, surface_desc.Pool);
13887 else if (surface_types[i].type == SURFACE_PLAIN)
13889 ok(!surface_desc.Usage, "Test %s %u: Got unexpected usage %#lx.\n",
13890 surface_types[i].name, j, surface_desc.Usage);
13891 ok(surface_desc.Pool == tests[j].pool, "Test %s %u: Got unexpected pool %#x.\n",
13892 surface_types[i].name, j, surface_desc.Pool);
13894 else
13896 ok(surface_desc.Usage == tests[j].usage, "Test %s %u: Got unexpected usage %#lx.\n",
13897 surface_types[i].name, j, surface_desc.Usage);
13898 ok(surface_desc.Pool == tests[j].pool, "Test %s %u: Got unexpected pool %#x.\n",
13899 surface_types[i].name, j, surface_desc.Pool);
13902 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
13903 if (surface_desc.Pool != D3DPOOL_DEFAULT || surface_desc.Usage & D3DUSAGE_DYNAMIC
13904 || (surface_types[i].type == SURFACE_RT && tests[j].usage & D3DUSAGE_DYNAMIC)
13905 || surface_types[i].type == SURFACE_PLAIN
13906 || tests[j].format == FORMAT_ATI2)
13907 expected_hr = D3D_OK;
13908 else
13909 expected_hr = D3DERR_INVALIDCALL;
13910 ok(hr == expected_hr, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13911 hr = IDirect3DSurface9_UnlockRect(surface);
13912 todo_wine_if(expected_hr != D3D_OK && surface_types[i].type == SURFACE_2D)
13913 ok(hr == expected_hr, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13915 if (SUCCEEDED(IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&texture)))
13917 hr = IDirect3DDevice9_SetTexture(device, 0, texture);
13918 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13919 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13920 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13921 IDirect3DBaseTexture9_Release(texture);
13924 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
13925 ok(hr == (surface_desc.Usage & D3DUSAGE_RENDERTARGET ? D3D_OK : D3DERR_INVALIDCALL),
13926 "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13927 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13928 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13930 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
13931 ok(hr == (surface_desc.Usage & D3DUSAGE_DEPTHSTENCIL ? D3D_OK : D3DERR_INVALIDCALL),
13932 "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13933 hr = IDirect3DDevice9_SetDepthStencilSurface(device, depth_stencil);
13934 ok(hr == D3D_OK, "Test %s %u: Got unexpected hr %#lx.\n", surface_types[i].name, j, hr);
13936 IDirect3DSurface9_Release(surface);
13940 for (i = 0; i < ARRAY_SIZE(tests); ++i)
13942 IDirect3DVolumeTexture9 *texture;
13943 D3DVOLUME_DESC volume_desc;
13944 IDirect3DVolume9 *volume;
13945 HRESULT expected_hr;
13946 D3DLOCKED_BOX lb;
13948 if (tests[i].format == FORMAT_DEPTH)
13949 continue;
13951 if (tests[i].format == FORMAT_ATI2)
13952 format = MAKEFOURCC('A','T','I','2');
13953 else
13954 format = colour_format;
13956 if (tests[i].format == FORMAT_ATI2 && FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT,
13957 D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, format)))
13959 if (!skip_ati2n_once)
13961 skip("ATI2N texture not supported.\n");
13962 skip_ati2n_once = TRUE;
13964 continue;
13967 hr = IDirect3DDevice9_CreateVolumeTexture(device, 16, 16, 1, 1,
13968 tests[i].usage, format, tests[i].pool, &texture, NULL);
13969 ok((hr == (!(tests[i].usage & ~D3DUSAGE_DYNAMIC)
13970 && (tests[i].format != FORMAT_ATI2 || tests[i].pool == D3DPOOL_SCRATCH)
13971 ? D3D_OK : D3DERR_INVALIDCALL))
13972 || (tests[i].format == FORMAT_ATI2 && (hr == D3D_OK || warp)),
13973 "Test %u: Got unexpected hr %#lx.\n", i, hr);
13974 if (FAILED(hr))
13975 continue;
13977 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
13978 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
13980 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
13981 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
13982 ok(volume_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#lx.\n", i, volume_desc.Usage);
13983 ok(volume_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, volume_desc.Pool);
13985 hr = IDirect3DVolume9_LockBox(volume, &lb, NULL, 0);
13986 if (volume_desc.Pool != D3DPOOL_DEFAULT || volume_desc.Usage & D3DUSAGE_DYNAMIC)
13987 expected_hr = D3D_OK;
13988 else
13989 expected_hr = D3DERR_INVALIDCALL;
13990 ok(hr == expected_hr || (volume_desc.Pool == D3DPOOL_DEFAULT && hr == D3D_OK),
13991 "Test %u: Got unexpected hr %#lx.\n", i, hr);
13992 hr = IDirect3DVolume9_UnlockBox(volume);
13993 ok(hr == expected_hr || (volume_desc.Pool == D3DPOOL_DEFAULT && hr == D3D_OK),
13994 "Test %u: Got unexpected hr %#lx.\n", i, hr);
13996 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13997 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
13998 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
13999 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14001 IDirect3DVolume9_Release(volume);
14002 IDirect3DVolumeTexture9_Release(texture);
14005 for (i = 0; i < ARRAY_SIZE(tests); ++i)
14007 D3DINDEXBUFFER_DESC ib_desc;
14008 IDirect3DIndexBuffer9 *ib;
14009 void *data;
14011 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, tests[i].usage,
14012 tests[i].format == FORMAT_COLOUR ? D3DFMT_INDEX32 : D3DFMT_INDEX16, tests[i].pool, &ib, NULL);
14013 ok(hr == (tests[i].pool == D3DPOOL_SCRATCH || (tests[i].usage & ~D3DUSAGE_DYNAMIC)
14014 ? D3DERR_INVALIDCALL : D3D_OK), "Test %u: Got unexpected hr %#lx.\n", i, hr);
14015 if (FAILED(hr))
14016 continue;
14018 hr = IDirect3DIndexBuffer9_GetDesc(ib, &ib_desc);
14019 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14020 ok(ib_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#lx.\n", i, ib_desc.Usage);
14021 ok(ib_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, ib_desc.Pool);
14023 hr = IDirect3DIndexBuffer9_Lock(ib, 0, 0, &data, 0);
14024 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14025 hr = IDirect3DIndexBuffer9_Unlock(ib);
14026 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14028 hr = IDirect3DDevice9_SetIndices(device, ib);
14029 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14030 hr = IDirect3DDevice9_SetIndices(device, NULL);
14031 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14033 IDirect3DIndexBuffer9_Release(ib);
14036 for (i = 0; i < ARRAY_SIZE(tests); ++i)
14038 D3DVERTEXBUFFER_DESC vb_desc;
14039 IDirect3DVertexBuffer9 *vb;
14040 void *data;
14042 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, tests[i].usage,
14043 tests[i].format == FORMAT_COLOUR ? 0 : D3DFVF_XYZRHW, tests[i].pool, &vb, NULL);
14044 ok(hr == (tests[i].pool == D3DPOOL_SCRATCH || (tests[i].usage & ~D3DUSAGE_DYNAMIC)
14045 ? D3DERR_INVALIDCALL : D3D_OK), "Test %u: Got unexpected hr %#lx.\n", i, hr);
14046 if (FAILED(hr))
14047 continue;
14049 hr = IDirect3DVertexBuffer9_GetDesc(vb, &vb_desc);
14050 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14051 ok(vb_desc.Usage == tests[i].usage, "Test %u: Got unexpected usage %#lx.\n", i, vb_desc.Usage);
14052 ok(vb_desc.Pool == tests[i].pool, "Test %u: Got unexpected pool %#x.\n", i, vb_desc.Pool);
14054 hr = IDirect3DVertexBuffer9_Lock(vb, 0, 0, &data, 0);
14055 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14056 hr = IDirect3DVertexBuffer9_Unlock(vb);
14057 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14059 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, 16);
14060 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14061 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
14062 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14064 IDirect3DVertexBuffer9_Release(vb);
14067 IDirect3DSurface9_Release(depth_stencil);
14068 IDirect3DSurface9_Release(backbuffer);
14069 refcount = IDirect3DDevice9_Release(device);
14070 ok(!refcount, "Device has %lu references left.\n", refcount);
14071 IDirect3D9_Release(d3d);
14072 DestroyWindow(window);
14075 static void test_multiply_transform(void)
14077 IDirect3DStateBlock9 *stateblock;
14078 IDirect3DDevice9 *device;
14079 D3DMATRIX ret_mat;
14080 IDirect3D9 *d3d;
14081 unsigned int i;
14082 ULONG refcount;
14083 HWND window;
14084 HRESULT hr;
14086 static const D3DTRANSFORMSTATETYPE tests[] =
14088 D3DTS_VIEW,
14089 D3DTS_PROJECTION,
14090 D3DTS_TEXTURE0,
14091 D3DTS_TEXTURE1,
14092 D3DTS_TEXTURE2,
14093 D3DTS_TEXTURE3,
14094 D3DTS_TEXTURE4,
14095 D3DTS_TEXTURE5,
14096 D3DTS_TEXTURE6,
14097 D3DTS_TEXTURE7,
14098 D3DTS_WORLDMATRIX(0),
14099 D3DTS_WORLDMATRIX(1),
14100 D3DTS_WORLDMATRIX(2),
14101 D3DTS_WORLDMATRIX(3),
14102 D3DTS_WORLDMATRIX(255),
14105 static const D3DMATRIX mat1 =
14107 1.0f, 0.0f, 0.0f, 0.0f,
14108 0.0f, 1.0f, 0.0f, 0.0f,
14109 0.0f, 0.0f, 1.0f, 0.0f,
14110 0.0f, 0.0f, 0.0f, 1.0f,
14111 }}},
14112 mat2 =
14114 2.0f, 0.0f, 0.0f, 0.0f,
14115 0.0f, 2.0f, 0.0f, 0.0f,
14116 0.0f, 0.0f, 2.0f, 0.0f,
14117 0.0f, 0.0f, 0.0f, 2.0f,
14118 }}};
14120 window = create_window();
14121 ok(!!window, "Failed to create a window.\n");
14122 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14123 ok(!!d3d, "Failed to create D3D object.\n");
14125 if (!(device = create_device(d3d, window, NULL)))
14127 skip("Failed to create 3D device.\n");
14128 IDirect3D9_Release(d3d);
14129 DestroyWindow(window);
14130 return;
14133 for (i = 0; i < ARRAY_SIZE(tests); ++i)
14135 hr = IDirect3DDevice9_GetTransform(device, tests[i], &ret_mat);
14136 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14137 ok(!memcmp(&ret_mat, &mat1, sizeof(mat1)), "Test %u: Got unexpected transform matrix.\n", i);
14139 hr = IDirect3DDevice9_MultiplyTransform(device, tests[i], &mat2);
14140 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14142 hr = IDirect3DDevice9_GetTransform(device, tests[i], &ret_mat);
14143 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14144 ok(!memcmp(&ret_mat, &mat2, sizeof(mat2)), "Test %u: Got unexpected transform matrix.\n", i);
14146 /* MultiplyTransform() goes directly into the primary stateblock. */
14148 hr = IDirect3DDevice9_SetTransform(device, tests[i], &mat1);
14149 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14151 hr = IDirect3DDevice9_BeginStateBlock(device);
14152 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14154 hr = IDirect3DDevice9_MultiplyTransform(device, tests[i], &mat2);
14155 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14157 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
14158 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14160 hr = IDirect3DDevice9_GetTransform(device, tests[i], &ret_mat);
14161 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14162 ok(!memcmp(&ret_mat, &mat2, sizeof(mat2)), "Test %u: Got unexpected transform matrix.\n", i);
14164 hr = IDirect3DStateBlock9_Capture(stateblock);
14165 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14167 hr = IDirect3DDevice9_SetTransform(device, tests[i], &mat1);
14168 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14170 hr = IDirect3DStateBlock9_Apply(stateblock);
14171 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14173 hr = IDirect3DDevice9_GetTransform(device, tests[i], &ret_mat);
14174 ok(hr == D3D_OK, "Test %u: Got unexpected hr %#lx.\n", i, hr);
14175 ok(!memcmp(&ret_mat, &mat1, sizeof(mat1)), "Test %u: Got unexpected transform matrix.\n", i);
14177 IDirect3DStateBlock9_Release(stateblock);
14180 refcount = IDirect3DDevice9_Release(device);
14181 ok(!refcount, "Device has %lu references left.\n", refcount);
14182 IDirect3D9_Release(d3d);
14183 DestroyWindow(window);
14186 static void test_vertex_buffer_read_write(void)
14188 IDirect3DVertexBuffer9 *buffer;
14189 IDirect3DDevice9 *device;
14190 IDirect3D9 *d3d;
14191 ULONG refcount;
14192 unsigned int i;
14193 float *data;
14194 HWND window;
14195 HRESULT hr;
14197 static const struct vec3 tri[] =
14199 {-1.0f, -1.0f, 0.0f},
14200 {-1.0f, 1.0f, 0.0f},
14201 { 1.0f, 1.0f, 0.0f},
14204 window = create_window();
14205 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14206 ok(!!d3d, "Failed to create a D3D object.\n");
14207 if (!(device = create_device(d3d, window, NULL)))
14209 skip("Failed to create a D3D device, skipping tests.\n");
14210 IDirect3D9_Release(d3d);
14211 DestroyWindow(window);
14212 return;
14214 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(tri),
14215 D3DUSAGE_DYNAMIC, D3DFVF_XYZ, D3DPOOL_DEFAULT, &buffer, NULL);
14216 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14218 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(tri), (void **)&data, D3DLOCK_DISCARD);
14219 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14220 memcpy(data, tri, sizeof(tri));
14221 hr = IDirect3DVertexBuffer9_Unlock(buffer);
14222 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14224 /* Draw using the buffer to make wined3d create BO. */
14225 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*tri));
14226 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14227 hr = IDirect3DDevice9_BeginScene(device);
14228 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14229 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14230 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14231 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 1);
14232 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14233 hr = IDirect3DDevice9_EndScene(device);
14234 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14235 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14236 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14238 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(tri), (void **)&data, D3DLOCK_NOOVERWRITE);
14239 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14240 for (i = 0; i < 3; ++i)
14241 data[i] = 3.0f;
14242 hr = IDirect3DVertexBuffer9_Unlock(buffer);
14243 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14245 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(tri), (void **)&data, D3DLOCK_NOOVERWRITE);
14246 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14247 for (i = 0; i < 3; ++i)
14248 ok(data[i] == 3.0f, "Got unexpected value %.8e, i %u.\n", data[i], i);
14249 hr = IDirect3DVertexBuffer9_Unlock(buffer);
14250 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14252 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(tri), (void **)&data, 0);
14253 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14254 for (i = 0; i < 3; ++i)
14255 ok(data[i] == 3.0f, "Got unexpected value %.8e, i %u.\n", data[i], i);
14256 hr = IDirect3DVertexBuffer9_Unlock(buffer);
14257 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14259 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(tri), (void **)&data, D3DLOCK_NOOVERWRITE);
14260 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14261 for (i = 0; i < 3; ++i)
14262 ok(data[i] == 3.0f, "Got unexpected value %.8e, i %u.\n", data[i], i);
14263 hr = IDirect3DVertexBuffer9_Unlock(buffer);
14264 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14266 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(tri), (void **)&data, 0);
14267 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14268 for (i = 0; i < 3; ++i)
14269 data[i] = 4.0f;
14270 hr = IDirect3DVertexBuffer9_Unlock(buffer);
14271 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14273 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(tri), (void **)&data, D3DLOCK_NOOVERWRITE);
14274 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14275 for (i = 0; i < 3; ++i)
14276 ok(data[i] == 4.0f, "Got unexpected value %.8e, i %u.\n", data[i], i);
14277 hr = IDirect3DVertexBuffer9_Unlock(buffer);
14278 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14280 IDirect3DVertexBuffer9_Release(buffer);
14281 refcount = IDirect3DDevice9_Release(device);
14282 ok(!refcount, "Device has %lu references left.\n", refcount);
14283 IDirect3D9_Release(d3d);
14284 DestroyWindow(window);
14287 static void test_get_display_mode(void)
14289 static const DWORD creation_flags[] = {0, CREATE_DEVICE_FULLSCREEN};
14290 unsigned int adapter_idx, adapter_count, mode_idx, test_idx;
14291 IDirect3DSwapChain9 *swapchain;
14292 RECT previous_monitor_rect;
14293 unsigned int width, height;
14294 IDirect3DDevice9 *device;
14295 MONITORINFO monitor_info;
14296 struct device_desc desc;
14297 D3DDISPLAYMODE mode;
14298 HMONITOR monitor;
14299 IDirect3D9 *d3d;
14300 ULONG refcount;
14301 HWND window;
14302 HRESULT hr;
14303 BOOL ret;
14305 window = create_window();
14306 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14307 ok(!!d3d, "Failed to create a D3D object.\n");
14309 if (!(device = create_device(d3d, window, NULL)))
14311 skip("Failed to create a D3D device.\n");
14312 IDirect3D9_Release(d3d);
14313 DestroyWindow(window);
14314 return;
14317 hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
14318 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14319 ok(mode.Format == D3DFMT_X8R8G8B8, "Unexpected format %#x.\n", mode.Format);
14320 hr = IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &mode);
14321 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14322 ok(mode.Format == D3DFMT_X8R8G8B8, "Unexpected format %#x.\n", mode.Format);
14323 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
14324 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14325 hr = IDirect3DSwapChain9_GetDisplayMode(swapchain, &mode);
14326 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14327 ok(mode.Format == D3DFMT_X8R8G8B8, "Unexpected format %#x.\n", mode.Format);
14328 IDirect3DSwapChain9_Release(swapchain);
14330 refcount = IDirect3DDevice9_Release(device);
14331 ok(!refcount, "Device has %lu references left.\n", refcount);
14333 desc.adapter_ordinal = D3DADAPTER_DEFAULT;
14334 desc.device_window = window;
14335 desc.width = 640;
14336 desc.height = 480;
14337 desc.flags = CREATE_DEVICE_FULLSCREEN;
14338 if (!(device = create_device(d3d, window, &desc)))
14340 skip("Failed to create a D3D device.\n");
14341 IDirect3D9_Release(d3d);
14342 DestroyWindow(window);
14343 return;
14346 hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
14347 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14348 ok(mode.Width == 640, "Unexpected width %u.\n", mode.Width);
14349 ok(mode.Height == 480, "Unexpected width %u.\n", mode.Height);
14350 ok(mode.Format == D3DFMT_X8R8G8B8, "Unexpected format %#x.\n", mode.Format);
14351 hr = IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &mode);
14352 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14353 ok(mode.Width == 640, "Unexpected width %u.\n", mode.Width);
14354 ok(mode.Height == 480, "Unexpected width %u.\n", mode.Height);
14355 ok(mode.Format == D3DFMT_X8R8G8B8, "Unexpected format %#x.\n", mode.Format);
14356 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
14357 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14358 hr = IDirect3DSwapChain9_GetDisplayMode(swapchain, &mode);
14359 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14360 ok(mode.Width == 640, "Unexpected width %u.\n", mode.Width);
14361 ok(mode.Height == 480, "Unexpected width %u.\n", mode.Height);
14362 ok(mode.Format == D3DFMT_X8R8G8B8, "Unexpected format %#x.\n", mode.Format);
14363 IDirect3DSwapChain9_Release(swapchain);
14365 refcount = IDirect3DDevice9_Release(device);
14366 ok(!refcount, "Device has %lu references left.\n", refcount);
14367 DestroyWindow(window);
14369 /* D3D9 uses adapter indices to determine which adapter to use to get the display mode */
14370 adapter_count = IDirect3D9_GetAdapterCount(d3d);
14371 for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx)
14373 if (!adapter_idx)
14375 desc.width = 640;
14376 desc.height = 480;
14378 else
14380 /* Find a mode different than that of the previous adapter, so that tests can be sure
14381 * that they are comparing to the current adapter display mode */
14382 monitor = IDirect3D9_GetAdapterMonitor(d3d, adapter_idx - 1);
14383 ok(!!monitor, "Adapter %u: GetAdapterMonitor failed.\n", adapter_idx - 1);
14384 monitor_info.cbSize = sizeof(monitor_info);
14385 ret = GetMonitorInfoW(monitor, &monitor_info);
14386 ok(ret, "Adapter %u: GetMonitorInfoW failed, error %#lx.\n", adapter_idx - 1,
14387 GetLastError());
14388 previous_monitor_rect = monitor_info.rcMonitor;
14390 desc.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
14391 desc.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
14392 for (mode_idx = 0; SUCCEEDED(IDirect3D9_EnumAdapterModes(d3d, adapter_idx,
14393 D3DFMT_X8R8G8B8, mode_idx, &mode)); ++mode_idx)
14395 if (mode.Width < 640 || mode.Height < 480)
14396 continue;
14397 if (mode.Width != desc.width && mode.Height != desc.height)
14398 break;
14400 ok(mode.Width != desc.width && mode.Height != desc.height,
14401 "Adapter %u: Failed to find a different mode than %ux%u.\n", adapter_idx,
14402 desc.width, desc.height);
14403 desc.width = mode.Width;
14404 desc.height = mode.Height;
14407 for (test_idx = 0; test_idx < ARRAY_SIZE(creation_flags); ++test_idx)
14409 window = create_window();
14410 desc.adapter_ordinal = adapter_idx;
14411 desc.device_window = window;
14412 desc.flags = creation_flags[test_idx];
14413 if (!(device = create_device(d3d, window, &desc)))
14415 skip("Adapter %u test %u: Failed to create a D3D device.\n", adapter_idx, test_idx);
14416 DestroyWindow(window);
14417 continue;
14420 monitor = IDirect3D9_GetAdapterMonitor(d3d, adapter_idx);
14421 ok(!!monitor, "Adapter %u test %u: GetAdapterMonitor failed.\n", adapter_idx, test_idx);
14422 monitor_info.cbSize = sizeof(monitor_info);
14423 ret = GetMonitorInfoW(monitor, &monitor_info);
14424 ok(ret, "Adapter %u test %u: GetMonitorInfoW failed, error %#lx.\n", adapter_idx,
14425 test_idx, GetLastError());
14426 width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
14427 height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
14429 if (adapter_idx)
14431 /* Move the device window to the previous monitor to test that the device window
14432 * position doesn't affect which adapter to use to get the display mode */
14433 ret = SetWindowPos(window, 0, previous_monitor_rect.left, previous_monitor_rect.top,
14434 0, 0, SWP_NOZORDER | SWP_NOSIZE);
14435 ok(ret, "Adapter %u test %u: SetWindowPos failed, error %#lx.\n", adapter_idx,
14436 test_idx, GetLastError());
14439 hr = IDirect3D9_GetAdapterDisplayMode(d3d, adapter_idx, &mode);
14440 ok(hr == D3D_OK, "Adapter %u test %u: GetAdapterDisplayMode failed, hr %#lx.\n",
14441 adapter_idx, test_idx, hr);
14442 ok(mode.Width == width, "Adapter %u test %u: Expect width %u, got %u.\n", adapter_idx,
14443 test_idx, width, mode.Width);
14444 ok(mode.Height == height, "Adapter %u test %u: Expect height %u, got %u.\n",
14445 adapter_idx, test_idx, height, mode.Height);
14447 hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
14448 ok(hr == D3D_OK, "Adapter %u test %u: GetDisplayMode failed, hr %#lx.\n", adapter_idx,
14449 test_idx, hr);
14450 ok(mode.Width == width, "Adapter %u test %u: Expect width %u, got %u.\n", adapter_idx,
14451 test_idx, width, mode.Width);
14452 ok(mode.Height == height, "Adapter %u test %u: Expect height %u, got %u.\n",
14453 adapter_idx, test_idx, height, mode.Height);
14455 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
14456 ok(hr == D3D_OK, "Adapter %u test %u: GetSwapChain failed, hr %#lx.\n", adapter_idx,
14457 test_idx, hr);
14458 hr = IDirect3DSwapChain9_GetDisplayMode(swapchain, &mode);
14459 ok(hr == D3D_OK, "Adapter %u test %u: GetDisplayMode failed, hr %#lx.\n", adapter_idx,
14460 test_idx, hr);
14461 ok(mode.Width == width, "Adapter %u test %u: Expect width %u, got %u.\n", adapter_idx,
14462 test_idx, width, mode.Width);
14463 ok(mode.Height == height, "Adapter %u test %u: Expect height %u, got %u.\n",
14464 adapter_idx, test_idx, height, mode.Height);
14465 IDirect3DSwapChain9_Release(swapchain);
14467 refcount = IDirect3DDevice9_Release(device);
14468 ok(!refcount, "Adapter %u test %u: Device has %lu references left.\n", adapter_idx,
14469 test_idx, refcount);
14470 DestroyWindow(window);
14474 IDirect3D9_Release(d3d);
14477 static void test_multi_adapter(void)
14479 unsigned int i, adapter_count, expected_adapter_count = 0;
14480 DISPLAY_DEVICEA display_device;
14481 MONITORINFOEXA monitor_info;
14482 DEVMODEA old_mode, mode;
14483 HMONITOR monitor;
14484 IDirect3D9 *d3d;
14485 LONG ret;
14487 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14488 ok(!!d3d, "Failed to create a D3D object.\n");
14490 display_device.cb = sizeof(display_device);
14491 for (i = 0; EnumDisplayDevicesA(NULL, i, &display_device, 0); ++i)
14493 if (display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
14494 ++expected_adapter_count;
14497 adapter_count = IDirect3D9_GetAdapterCount(d3d);
14498 ok(adapter_count == expected_adapter_count, "Got unexpected adapter count %u, expected %u.\n",
14499 adapter_count, expected_adapter_count);
14501 for (i = 0; i < adapter_count; ++i)
14503 monitor = IDirect3D9_GetAdapterMonitor(d3d, i);
14504 ok(!!monitor, "Adapter %u: Failed to get monitor.\n", i);
14506 monitor_info.cbSize = sizeof(monitor_info);
14507 ret = GetMonitorInfoA(monitor, (MONITORINFO *)&monitor_info);
14508 ok(ret, "Adapter %u: Failed to get monitor info, error %#lx.\n", i, GetLastError());
14510 if (!i)
14511 ok(monitor_info.dwFlags == MONITORINFOF_PRIMARY,
14512 "Adapter %u: Got unexpected monitor flags %#lx.\n", i, monitor_info.dwFlags);
14513 else
14514 ok(!monitor_info.dwFlags, "Adapter %u: Got unexpected monitor flags %#lx.\n", i,
14515 monitor_info.dwFlags);
14517 /* Test D3D adapters after they got detached */
14518 if (monitor_info.dwFlags == MONITORINFOF_PRIMARY)
14519 continue;
14521 /* Save current display settings */
14522 memset(&old_mode, 0, sizeof(old_mode));
14523 old_mode.dmSize = sizeof(old_mode);
14524 ret = EnumDisplaySettingsA(monitor_info.szDevice, ENUM_CURRENT_SETTINGS, &old_mode);
14525 /* Win10 TestBots may return FALSE but it's actually successful */
14526 ok(ret || broken(!ret), "Adapter %u: EnumDisplaySettingsA failed for %s, error %#lx.\n", i,
14527 monitor_info.szDevice, GetLastError());
14529 /* Detach */
14530 memset(&mode, 0, sizeof(mode));
14531 mode.dmSize = sizeof(mode);
14532 mode.dmFields = DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT;
14533 mode.dmPosition = old_mode.dmPosition;
14534 ret = ChangeDisplaySettingsExA(monitor_info.szDevice, &mode, NULL,
14535 CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
14536 ok(ret == DISP_CHANGE_SUCCESSFUL,
14537 "Adapter %u: ChangeDisplaySettingsExA %s returned unexpected %ld.\n", i,
14538 monitor_info.szDevice, ret);
14539 ret = ChangeDisplaySettingsExA(monitor_info.szDevice, NULL, NULL, 0, NULL);
14540 ok(ret == DISP_CHANGE_SUCCESSFUL,
14541 "Adapter %u: ChangeDisplaySettingsExA %s returned unexpected %ld.\n", i,
14542 monitor_info.szDevice, ret);
14544 /* Check if it is really detached */
14545 memset(&mode, 0, sizeof(mode));
14546 mode.dmSize = sizeof(mode);
14547 ret = EnumDisplaySettingsA(monitor_info.szDevice, ENUM_CURRENT_SETTINGS, &mode);
14548 /* Win10 TestBots may return FALSE but it's actually successful */
14549 ok(ret || broken(!ret) , "Adapter %u: EnumDisplaySettingsA failed for %s, error %#lx.\n", i,
14550 monitor_info.szDevice, GetLastError());
14551 if (mode.dmPelsWidth && mode.dmPelsHeight)
14553 skip("Adapter %u: Failed to detach device %s.\n", i, monitor_info.szDevice);
14554 continue;
14557 /* Detaching adapter shouldn't reduce the adapter count */
14558 expected_adapter_count = adapter_count;
14559 adapter_count = IDirect3D9_GetAdapterCount(d3d);
14560 ok(adapter_count == expected_adapter_count,
14561 "Adapter %u: Got unexpected adapter count %u, expected %u.\n", i, adapter_count,
14562 expected_adapter_count);
14564 monitor = IDirect3D9_GetAdapterMonitor(d3d, i);
14565 ok(!monitor, "Adapter %u: Expect monitor to be NULL.\n", i);
14567 /* Restore settings */
14568 ret = ChangeDisplaySettingsExA(monitor_info.szDevice, &old_mode, NULL,
14569 CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
14570 ok(ret == DISP_CHANGE_SUCCESSFUL,
14571 "Adapter %u: ChangeDisplaySettingsExA %s returned unexpected %ld.\n", i,
14572 monitor_info.szDevice, ret);
14573 ret = ChangeDisplaySettingsExA(monitor_info.szDevice, NULL, NULL, 0, NULL);
14574 ok(ret == DISP_CHANGE_SUCCESSFUL,
14575 "Adapter %u: ChangeDisplaySettingsExA %s returned unexpected %ld.\n", i,
14576 monitor_info.szDevice, ret);
14579 IDirect3D9_Release(d3d);
14582 typedef HRESULT (WINAPI *shader_validator_cb)(const char *file, int line,
14583 DWORD_PTR arg3, DWORD_PTR message_id, const char *message, void *context);
14585 typedef struct IDirect3DShaderValidator9 IDirect3DShaderValidator9;
14587 struct IDirect3DShaderValidator9Vtbl
14589 HRESULT (WINAPI *QueryInterface)(IDirect3DShaderValidator9 *iface, REFIID iid, void **out);
14590 ULONG (WINAPI *AddRef)(IDirect3DShaderValidator9 *iface);
14591 ULONG (WINAPI *Release)(IDirect3DShaderValidator9 *iface);
14592 HRESULT (WINAPI *Begin)(IDirect3DShaderValidator9 *iface,
14593 shader_validator_cb callback, void *context, DWORD_PTR arg3);
14594 HRESULT (WINAPI *Instruction)(IDirect3DShaderValidator9 *iface,
14595 const char *file, int line, const DWORD *tokens, unsigned int token_count);
14596 HRESULT (WINAPI *End)(IDirect3DShaderValidator9 *iface);
14599 struct IDirect3DShaderValidator9
14601 const struct IDirect3DShaderValidator9Vtbl *vtbl;
14604 #define MAX_VALIDATOR_CB_CALL_COUNT 5
14606 struct test_shader_validator_cb_context
14608 unsigned int call_count;
14609 const char *file[MAX_VALIDATOR_CB_CALL_COUNT];
14610 int line[MAX_VALIDATOR_CB_CALL_COUNT];
14611 DWORD_PTR message_id[MAX_VALIDATOR_CB_CALL_COUNT];
14612 const char *message[MAX_VALIDATOR_CB_CALL_COUNT];
14615 HRESULT WINAPI test_shader_validator_cb(const char *file, int line, DWORD_PTR arg3,
14616 DWORD_PTR message_id, const char *message, void *context)
14618 if (context)
14620 struct test_shader_validator_cb_context *c = context;
14622 c->file[c->call_count] = file;
14623 c->line[c->call_count] = line;
14624 c->message_id[c->call_count] = message_id;
14625 c->message[c->call_count] = message;
14626 ++c->call_count;
14628 else
14630 ok(0, "Unexpected call.\n");
14632 return S_OK;
14635 static void test_shader_validator(void)
14637 static const DWORD dcl_texcoord_9_9[] = {0x0200001f, 0x80090005, 0x902f0009}; /* dcl_texcoord9_pp v9 */
14638 static const DWORD dcl_texcoord_9_10[] = {0x0200001f, 0x80090005, 0x902f000a}; /* dcl_texcoord9_pp v10 */
14639 static const DWORD dcl_texcoord_10_9[] = {0x0200001f, 0x800a0005, 0x902f0009}; /* dcl_texcoord10_pp v9 */
14640 static const DWORD mov_r2_v9[] = {0x02000001, 0x80220002, 0x90ff0009}; /* mov_pp r2.y, v9.w */
14641 static const DWORD mov_r2_v10[] = {0x02000001, 0x80220002, 0x90ff000a}; /* mov_pp r2.y, v10.w */
14643 static const DWORD ps_3_0 = D3DPS_VERSION(3, 0);
14644 static const DWORD end_token = 0x0000ffff;
14645 static const char *test_file_name = "test_file";
14646 static const struct instruction_test
14648 DWORD shader_version;
14649 const DWORD *instruction;
14650 unsigned int instruction_length;
14651 DWORD_PTR message_id;
14652 const DWORD *decl;
14653 unsigned int decl_length;
14655 instruction_tests[] =
14657 {D3DPS_VERSION(3, 0), dcl_texcoord_9_9, ARRAY_SIZE(dcl_texcoord_9_9)},
14658 {D3DPS_VERSION(3, 0), dcl_texcoord_9_10, ARRAY_SIZE(dcl_texcoord_9_10), 0x12c},
14659 {D3DPS_VERSION(3, 0), dcl_texcoord_10_9, ARRAY_SIZE(dcl_texcoord_10_9)},
14660 {D3DPS_VERSION(3, 0), mov_r2_v9, ARRAY_SIZE(mov_r2_v9), 0, dcl_texcoord_9_9, ARRAY_SIZE(dcl_texcoord_9_9)},
14661 {D3DPS_VERSION(3, 0), mov_r2_v10, ARRAY_SIZE(mov_r2_v10), 0x167},
14664 struct test_shader_validator_cb_context context;
14665 IDirect3DShaderValidator9 *validator;
14666 HRESULT expected_hr, hr;
14667 unsigned int i;
14668 ULONG refcount;
14670 validator = Direct3DShaderValidatorCreate9();
14672 hr = validator->vtbl->Begin(validator, test_shader_validator_cb, NULL, 0);
14673 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14674 hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[0], 1);
14675 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14676 hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[1], 3);
14677 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14678 hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[4], 4);
14679 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14680 hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[8], 4);
14681 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14682 hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[12], 4);
14683 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14684 hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[16], 4);
14685 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14686 hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[20], 1);
14687 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14688 hr = validator->vtbl->End(validator);
14689 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14691 hr = validator->vtbl->Begin(validator, test_shader_validator_cb, &context, 0);
14692 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14694 memset(&context, 0, sizeof(context));
14695 hr = validator->vtbl->Instruction(validator, test_file_name, 28, &simple_vs[1], 3);
14696 todo_wine
14698 ok(hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
14699 ok(context.call_count == 2, "Got unexpected call_count %u.\n", context.call_count);
14700 ok(!!context.message[0], "Got NULL message.\n");
14701 ok(!!context.message[1], "Got NULL message.\n");
14702 ok(context.message_id[0] == 0xef, "Got unexpected message_id[0] %p.\n", (void *)context.message_id[0]);
14703 ok(context.message_id[1] == 0xf0, "Got unexpected message_id[1] %p.\n", (void *)context.message_id[1]);
14704 ok(context.line[0] == -1, "Got unexpected line %d.\n", context.line[0]);
14706 ok(!context.file[0], "Got unexpected file[0] %s.\n", context.file[0]);
14707 ok(!context.file[1], "Got unexpected file[0] %s.\n", context.file[1]);
14708 ok(!context.line[1], "Got unexpected line %d.\n", context.line[1]);
14710 memset(&context, 0, sizeof(context));
14711 hr = validator->vtbl->End(validator);
14712 todo_wine ok(hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
14713 ok(!context.call_count, "Got unexpected call_count %u.\n", context.call_count);
14715 memset(&context, 0, sizeof(context));
14716 hr = validator->vtbl->Begin(validator, test_shader_validator_cb, &context, 0);
14717 todo_wine
14719 ok(hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
14720 ok(context.call_count == 1, "Got unexpected call_count %u.\n", context.call_count);
14721 ok(context.message_id[0] == 0xeb, "Got unexpected message_id[0] %p.\n", (void *)context.message_id[0]);
14722 ok(!!context.message[0], "Got NULL message.\n");
14724 ok(!context.file[0], "Got unexpected file[0] %s.\n", context.file[0]);
14725 ok(!context.line[0], "Got unexpected line %d.\n", context.line[0]);
14727 hr = validator->vtbl->Begin(validator, NULL, &context, 0);
14728 todo_wine ok(hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
14730 refcount = validator->vtbl->Release(validator);
14731 todo_wine ok(!refcount, "Validator has %lu references left.\n", refcount);
14732 validator = Direct3DShaderValidatorCreate9();
14734 hr = validator->vtbl->Begin(validator, NULL, &context, 0);
14735 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14736 hr = validator->vtbl->Instruction(validator, test_file_name, 1, &ps_3_0, 1);
14737 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14738 hr = validator->vtbl->Instruction(validator, test_file_name, 5, &end_token, 1);
14739 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14740 hr = validator->vtbl->End(validator);
14741 ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
14743 for (i = 0; i < ARRAY_SIZE(instruction_tests); ++i)
14745 const struct instruction_test *test = &instruction_tests[i];
14747 hr = validator->vtbl->Begin(validator, test_shader_validator_cb, &context, 0);
14748 ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
14750 hr = validator->vtbl->Instruction(validator, test_file_name, 1, &test->shader_version, 1);
14751 ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
14753 if (test->decl)
14755 memset(&context, 0, sizeof(context));
14756 hr = validator->vtbl->Instruction(validator, test_file_name, 3, test->decl, test->decl_length);
14757 ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
14758 ok(!context.call_count, "Got unexpected call_count %u, test %u.\n", context.call_count, i);
14761 memset(&context, 0, sizeof(context));
14762 hr = validator->vtbl->Instruction(validator, test_file_name, 3, test->instruction, test->instruction_length);
14763 ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
14764 if (test->message_id)
14766 todo_wine
14768 ok(context.call_count == 1, "Got unexpected call_count %u, test %u.\n", context.call_count, i);
14769 ok(!!context.message[0], "Got NULL message, test %u.\n", i);
14770 ok(context.message_id[0] == test->message_id, "Got unexpected message_id[0] %p, test %u.\n",
14771 (void *)context.message_id[0], i);
14772 ok(context.file[0] == test_file_name, "Got unexpected file[0] %s, test %u.\n", context.file[0], i);
14773 ok(context.line[0] == 3, "Got unexpected line %d, test %u.\n", context.line[0], i);
14776 else
14778 ok(!context.call_count, "Got unexpected call_count %u, test %u.\n", context.call_count, i);
14781 hr = validator->vtbl->Instruction(validator, test_file_name, 5, &end_token, 1);
14782 ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
14784 hr = validator->vtbl->End(validator);
14785 expected_hr = test->message_id ? E_FAIL : S_OK;
14786 todo_wine_if(expected_hr) ok(hr == expected_hr, "Got unexpected hr %#lx, test %u.\n", hr, i);
14789 refcount = validator->vtbl->Release(validator);
14790 todo_wine ok(!refcount, "Validator has %lu references left.\n", refcount);
14793 static void test_creation_parameters(void)
14795 unsigned int adapter_idx, adapter_count;
14796 D3DDEVICE_CREATION_PARAMETERS params;
14797 struct device_desc device_desc;
14798 IDirect3DDevice9 *device;
14799 IDirect3D9 *d3d;
14800 HWND window;
14801 HRESULT hr;
14803 window = create_window();
14804 ok(!!window, "Failed to create a window.\n");
14805 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14806 ok(!!d3d, "Failed to create a D3D object.\n");
14808 device_desc.device_window = window;
14809 device_desc.width = 640;
14810 device_desc.height = 480;
14811 device_desc.flags = 0;
14813 adapter_count = IDirect3D9_GetAdapterCount(d3d);
14814 for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx)
14816 device_desc.adapter_ordinal = adapter_idx;
14817 if (!(device = create_device(d3d, window, &device_desc)))
14819 skip("Adapter %u: Failed to create a D3D device.\n", adapter_idx);
14820 break;
14823 memset(&params, 0, sizeof(params));
14824 hr = IDirect3DDevice9_GetCreationParameters(device, &params);
14825 ok(hr == D3D_OK, "Adapter %u: GetCreationParameters failed, hr %#lx.\n", adapter_idx, hr);
14826 ok(params.AdapterOrdinal == adapter_idx, "Adapter %u: Got unexpected adapter ordinal %u.\n",
14827 adapter_idx, params.AdapterOrdinal);
14828 ok(params.DeviceType == D3DDEVTYPE_HAL, "Adapter %u: Expect device type %#x, got %#x.\n",
14829 adapter_idx, D3DDEVTYPE_HAL, params.DeviceType);
14830 ok(params.hFocusWindow == window, "Adapter %u: Expect focus window %p, got %p.\n",
14831 adapter_idx, window, params.hFocusWindow);
14833 IDirect3DDevice9_Release(device);
14836 IDirect3D9_Release(d3d);
14837 DestroyWindow(window);
14840 static void test_cursor_clipping(void)
14842 unsigned int adapter_idx, adapter_count, mode_idx;
14843 D3DDISPLAYMODE mode, current_mode;
14844 struct device_desc device_desc;
14845 RECT virtual_rect, clip_rect;
14846 IDirect3DDevice9 *device;
14847 IDirect3D9 *d3d;
14848 HWND window;
14849 HRESULT hr;
14850 BOOL ret;
14852 window = create_window();
14853 ok(!!window, "Failed to create a window.\n");
14854 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14855 ok(!!d3d, "Failed to create a D3D object.\n");
14857 device_desc.device_window = window;
14858 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
14860 adapter_count = IDirect3D9_GetAdapterCount(d3d);
14861 for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx)
14863 hr = IDirect3D9_GetAdapterDisplayMode(d3d, adapter_idx, &current_mode);
14864 ok(hr == D3D_OK, "Adapter %u: GetAdapterDisplayMode failed, hr %#lx.\n", adapter_idx, hr);
14865 for (mode_idx = 0; SUCCEEDED(IDirect3D9_EnumAdapterModes(d3d, adapter_idx, D3DFMT_X8R8G8B8,
14866 mode_idx, &mode)); ++mode_idx)
14868 if (mode.Width < 640 || mode.Height < 480)
14869 continue;
14870 if (mode.Width != current_mode.Width && mode.Height != current_mode.Height)
14871 break;
14873 ok(mode.Width != current_mode.Width && mode.Height != current_mode.Height,
14874 "Adapter %u: Failed to find a different mode than %ux%u.\n", adapter_idx,
14875 current_mode.Width, current_mode.Height);
14877 ret = ClipCursor(NULL);
14878 ok(ret, "Adapter %u: ClipCursor failed, error %#lx.\n", adapter_idx,
14879 GetLastError());
14880 get_virtual_rect(&virtual_rect);
14881 ret = GetClipCursor(&clip_rect);
14882 ok(ret, "Adapter %u: GetClipCursor failed, error %#lx.\n", adapter_idx,
14883 GetLastError());
14884 ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u: Expect clip rect %s, got %s.\n",
14885 adapter_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect));
14887 device_desc.adapter_ordinal = adapter_idx;
14888 device_desc.width = mode.Width;
14889 device_desc.height = mode.Height;
14890 if (!(device = create_device(d3d, window, &device_desc)))
14892 skip("Adapter %u: Failed to create a D3D device.\n", adapter_idx);
14893 break;
14895 flush_events();
14896 get_virtual_rect(&virtual_rect);
14897 ret = GetClipCursor(&clip_rect);
14898 ok(ret, "Adapter %u: GetClipCursor failed, error %#lx.\n", adapter_idx,
14899 GetLastError());
14900 ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u: Expect clip rect %s, got %s.\n",
14901 adapter_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect));
14903 IDirect3DDevice9_Release(device);
14904 flush_events();
14905 get_virtual_rect(&virtual_rect);
14906 ret = GetClipCursor(&clip_rect);
14907 ok(ret, "Adapter %u: GetClipCursor failed, error %#lx.\n", adapter_idx,
14908 GetLastError());
14909 ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u: Expect clip rect %s, got %s.\n",
14910 adapter_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect));
14913 IDirect3D9_Release(d3d);
14914 DestroyWindow(window);
14917 static void test_window_position(void)
14919 unsigned int adapter_idx, adapter_count;
14920 struct device_desc device_desc;
14921 RECT window_rect, new_rect;
14922 IDirect3DDevice9 *device;
14923 MONITORINFO monitor_info;
14924 HMONITOR monitor;
14925 IDirect3D9 *d3d;
14926 HWND window;
14927 HRESULT hr;
14928 BOOL ret;
14930 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14931 ok(!!d3d, "Failed to create a D3D object.\n");
14933 adapter_count = IDirect3D9_GetAdapterCount(d3d);
14934 for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx)
14936 monitor = IDirect3D9_GetAdapterMonitor(d3d, adapter_idx);
14937 ok(!!monitor, "Adapter %u: GetAdapterMonitor failed.\n", adapter_idx);
14938 monitor_info.cbSize = sizeof(monitor_info);
14939 ret = GetMonitorInfoW(monitor, &monitor_info);
14940 ok(ret, "Adapter %u: GetMonitorInfoW failed, error %#lx.\n", adapter_idx, GetLastError());
14942 window = create_window();
14943 device_desc.adapter_ordinal = adapter_idx;
14944 device_desc.device_window = window;
14945 device_desc.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
14946 device_desc.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
14947 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
14948 if (!(device = create_device(d3d, window, &device_desc)))
14950 skip("Adapter %u: Failed to create a D3D device, skipping tests.\n", adapter_idx);
14951 DestroyWindow(window);
14952 continue;
14954 flush_events();
14955 ret = GetWindowRect(window, &window_rect);
14956 ok(ret, "Adapter %u: GetWindowRect failed, error %#lx.\n", adapter_idx, GetLastError());
14957 ok(EqualRect(&window_rect, &monitor_info.rcMonitor),
14958 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx,
14959 wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&window_rect));
14961 new_rect = window_rect;
14962 --new_rect.right;
14963 --new_rect.bottom;
14965 ret = MoveWindow(window, new_rect.left, new_rect.top, new_rect.right - new_rect.left,
14966 new_rect.bottom - new_rect.top, TRUE);
14967 ok(ret, "Got unexpected ret %#x, error %#lx, Adapter %u.\n", ret, GetLastError(), adapter_idx);
14968 ret = GetWindowRect(window, &window_rect);
14969 ok(ret, "Got unexpected ret %#x, error %#lx, Adapter %u.\n", ret, GetLastError(), adapter_idx);
14970 ok(EqualRect(&window_rect, &new_rect),
14971 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx,
14972 wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&window_rect));
14973 /* After processing window events window rectangle gets restored. But only once, the size set
14974 * on the second resize remains. */
14975 flush_events();
14976 ret = GetWindowRect(window, &window_rect);
14977 ok(ret, "Got unexpected ret %#x, error %#lx, Adapter %u.\n", ret, GetLastError(), adapter_idx);
14978 todo_wine ok(EqualRect(&window_rect, &monitor_info.rcMonitor),
14979 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx,
14980 wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&window_rect));
14982 ret = MoveWindow(window, new_rect.left, new_rect.top, new_rect.right - new_rect.left,
14983 new_rect.bottom - new_rect.top, TRUE);
14984 ok(ret, "Got unexpected ret %#x, error %#lx, Adapter %u.\n", ret, GetLastError(), adapter_idx);
14985 ret = GetWindowRect(window, &window_rect);
14986 ok(ret, "Got unexpected ret %#x, error %#lx, Adapter %u.\n", ret, GetLastError(), adapter_idx);
14987 ok(EqualRect(&window_rect, &new_rect),
14988 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx,
14989 wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&window_rect));
14990 flush_events();
14991 ret = GetWindowRect(window, &window_rect);
14992 ok(ret, "Got unexpected ret %#x, error %#lx, Adapter %u.\n", ret, GetLastError(), adapter_idx);
14993 ok(EqualRect(&window_rect, &new_rect),
14994 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx,
14995 wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&window_rect));
14997 /* Device resets should restore the window rectangle to fit the whole monitor */
14998 ret = SetWindowPos(window, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
14999 ok(ret, "Adapter %u: SetWindowPos failed, error %#lx.\n", adapter_idx, GetLastError());
15000 hr = reset_device(device, &device_desc);
15001 ok(hr == D3D_OK, "Adapter %u: Failed to reset device, hr %#lx.\n", adapter_idx, hr);
15002 flush_events();
15003 ret = GetWindowRect(window, &window_rect);
15004 ok(ret, "Adapter %u: GetWindowRect failed, error %#lx.\n", adapter_idx, GetLastError());
15005 ok(EqualRect(&window_rect, &monitor_info.rcMonitor),
15006 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx,
15007 wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&window_rect));
15009 /* Window activation should restore the window rectangle to fit the whole monitor */
15010 ret = SetWindowPos(window, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
15011 ok(ret, "Adapter %u: SetWindowPos failed, error %#lx.\n", adapter_idx, GetLastError());
15012 ret = SetForegroundWindow(GetDesktopWindow());
15013 ok(ret, "Adapter %u: SetForegroundWindow failed, error %#lx.\n", adapter_idx, GetLastError());
15014 flush_events();
15015 ret = ShowWindow(window, SW_RESTORE);
15016 ok(ret, "Adapter %u: Failed to restore window, error %#lx.\n", adapter_idx, GetLastError());
15017 flush_events();
15018 ret = SetForegroundWindow(window);
15019 ok(ret, "Adapter %u: SetForegroundWindow failed, error %#lx.\n", adapter_idx, GetLastError());
15020 flush_events();
15021 ret = GetWindowRect(window, &window_rect);
15022 ok(ret, "Adapter %u: GetWindowRect failed, error %#lx.\n", adapter_idx, GetLastError());
15023 ok(EqualRect(&window_rect, &monitor_info.rcMonitor),
15024 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx,
15025 wine_dbgstr_rect(&monitor_info.rcMonitor), wine_dbgstr_rect(&window_rect));
15027 IDirect3DDevice9_Release(device);
15028 DestroyWindow(window);
15031 IDirect3D9_Release(d3d);
15034 START_TEST(device)
15036 HMODULE d3d9_handle = GetModuleHandleA("d3d9.dll");
15037 WNDCLASSA wc = {0};
15038 IDirect3D9 *d3d9;
15039 DEVMODEW current_mode;
15041 memset(&current_mode, 0, sizeof(current_mode));
15042 current_mode.dmSize = sizeof(current_mode);
15043 ok(EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &current_mode), "Failed to get display mode.\n");
15044 registry_mode.dmSize = sizeof(registry_mode);
15045 ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
15046 if (registry_mode.dmPelsWidth != current_mode.dmPelsWidth
15047 || registry_mode.dmPelsHeight != current_mode.dmPelsHeight)
15049 skip("Current mode does not match registry mode, skipping test.\n");
15050 return;
15053 if (!(d3d9 = Direct3DCreate9(D3D_SDK_VERSION)))
15055 skip("could not create D3D9 object\n");
15056 return;
15058 IDirect3D9_Release(d3d9);
15060 wc.lpfnWndProc = DefWindowProcA;
15061 wc.lpszClassName = "d3d9_test_wc";
15062 RegisterClassA(&wc);
15064 Direct3DShaderValidatorCreate9 = (void *)GetProcAddress(d3d9_handle, "Direct3DShaderValidatorCreate9");
15066 test_get_set_vertex_declaration();
15067 test_get_declaration();
15068 test_fvf_decl_conversion();
15069 test_fvf_decl_management();
15070 test_vertex_declaration_alignment();
15071 test_unused_declaration_type();
15072 test_fpu_setup();
15073 test_multi_device();
15074 test_display_formats();
15075 test_display_modes();
15076 test_swapchain();
15077 test_refcount();
15078 test_mipmap_levels();
15079 test_checkdevicemultisampletype();
15080 test_invalid_multisample();
15081 test_cursor();
15082 test_cursor_pos();
15083 test_reset_fullscreen();
15084 test_reset();
15085 test_scene();
15086 test_limits();
15087 test_depthstenciltest();
15088 test_get_rt();
15089 test_draw_primitive();
15090 test_null_stream();
15091 test_lights();
15092 test_set_stream_source();
15093 test_scissor_size();
15094 test_wndproc();
15095 test_wndproc_windowed();
15096 test_window_style();
15097 test_mode_change();
15098 test_device_window_reset();
15099 test_reset_resources();
15100 test_set_rt_vp_scissor();
15101 test_volume_get_container();
15102 test_volume_resource();
15103 test_vb_lock_flags();
15104 test_vertex_buffer_alignment();
15105 test_query_support();
15106 test_occlusion_query();
15107 test_timestamp_query();
15108 test_get_set_vertex_shader();
15109 test_vertex_shader_constant();
15110 test_get_set_pixel_shader();
15111 test_pixel_shader_constant();
15112 test_unsupported_shaders();
15113 test_texture_stage_states();
15114 test_cube_textures();
15115 test_mipmap_gen();
15116 test_filter();
15117 test_get_set_texture();
15118 test_lod();
15119 test_surface_get_container();
15120 test_surface_alignment();
15121 test_lockrect_offset();
15122 test_lockrect_invalid();
15123 test_private_data();
15124 test_getdc();
15125 test_surface_dimensions();
15126 test_surface_format_null();
15127 test_surface_double_unlock();
15128 test_surface_blocks();
15129 test_set_palette();
15130 test_pinned_buffers();
15131 test_npot_textures();
15132 test_vidmem_accounting();
15133 test_volume_locking();
15134 test_update_texture_pool();
15135 test_update_volumetexture();
15136 test_create_rt_ds_fail();
15137 test_volume_blocks();
15138 test_lockbox_invalid();
15139 test_shared_handle();
15140 test_pixel_format();
15141 test_begin_end_state_block();
15142 test_shader_constant_apply();
15143 test_vdecl_apply();
15144 test_resource_type();
15145 test_mipmap_lock();
15146 test_writeonly_resource();
15147 test_lost_device();
15148 test_resource_priority();
15149 test_swapchain_parameters();
15150 test_check_device_format();
15151 test_miptree_layout();
15152 test_get_render_target_data();
15153 test_render_target_device_mismatch();
15154 test_format_unknown();
15155 test_destroyed_window();
15156 test_lockable_backbuffer();
15157 test_clip_planes_limits();
15158 test_swapchain_multisample_reset();
15159 test_stretch_rect();
15160 test_device_caps();
15161 test_resource_access();
15162 test_multiply_transform();
15163 test_vertex_buffer_read_write();
15164 test_get_display_mode();
15165 test_multi_adapter();
15166 test_shader_validator();
15167 test_creation_parameters();
15168 test_cursor_clipping();
15169 test_window_position();
15171 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));