d3d9/tests: Skip unsupported resources in test_resource_type.
[wine.git] / dlls / d3d9 / tests / device.c
blob2b7edd73317a0f2798255c367c2d21a4c9601d84
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 "wine/test.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
39 struct device_desc
41 HWND device_window;
42 unsigned int width;
43 unsigned int height;
44 DWORD flags;
47 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
48 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
50 static INT screen_width;
51 static INT screen_height;
53 static const DWORD simple_vs[] =
55 0xfffe0101, /* vs_1_1 */
56 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
57 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
58 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
59 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
60 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
61 0x0000ffff, /* end */
64 static const DWORD simple_ps[] =
66 0xffff0101, /* ps_1_1 */
67 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
68 0x00000042, 0xb00f0000, /* tex t0 */
69 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
70 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
71 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
72 0x0000ffff, /* end */
75 static int get_refcount(IUnknown *object)
77 IUnknown_AddRef( object );
78 return IUnknown_Release( object );
81 static BOOL compare_elements(IDirect3DVertexDeclaration9 *declaration, const D3DVERTEXELEMENT9 *expected_elements)
83 unsigned int element_count, i;
84 D3DVERTEXELEMENT9 *elements;
85 BOOL equal = TRUE;
86 HRESULT hr;
88 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
89 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
90 elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(*elements));
91 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
92 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
94 for (i = 0; i < element_count; ++i)
96 if (memcmp(&elements[i], &expected_elements[i], sizeof(*elements)))
98 equal = FALSE;
99 break;
103 if (!equal)
105 for (i = 0; i < element_count; ++i)
107 trace("[Element %u] stream %u, offset %u, type %#x, method %#x, usage %#x, usage index %u.\n",
108 i, elements[i].Stream, elements[i].Offset, elements[i].Type,
109 elements[i].Method, elements[i].Usage, elements[i].UsageIndex);
113 HeapFree(GetProcessHeap(), 0, elements);
114 return equal;
117 /* try to make sure pending X events have been processed before continuing */
118 static void flush_events(void)
120 MSG msg;
121 int diff = 200;
122 int min_timeout = 100;
123 DWORD time = GetTickCount() + diff;
125 while (diff > 0)
127 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
128 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
129 diff = time - GetTickCount();
133 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window, const struct device_desc *desc)
135 D3DPRESENT_PARAMETERS present_parameters = {0};
136 IDirect3DDevice9 *device;
137 DWORD behavior_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
139 present_parameters.BackBufferWidth = 640;
140 present_parameters.BackBufferHeight = 480;
141 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
142 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
143 present_parameters.hDeviceWindow = focus_window;
144 present_parameters.Windowed = TRUE;
145 present_parameters.EnableAutoDepthStencil = TRUE;
146 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
148 if (desc)
150 present_parameters.BackBufferWidth = desc->width;
151 present_parameters.BackBufferHeight = desc->height;
152 present_parameters.hDeviceWindow = desc->device_window;
153 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
154 if (desc->flags & CREATE_DEVICE_SWVP_ONLY)
155 behavior_flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
156 if (desc->flags & CREATE_DEVICE_NOWINDOWCHANGES)
157 behavior_flags |= D3DCREATE_NOWINDOWCHANGES;
158 if (desc->flags & CREATE_DEVICE_FPU_PRESERVE)
159 behavior_flags |= D3DCREATE_FPU_PRESERVE;
162 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
163 behavior_flags, &present_parameters, &device)))
164 return device;
166 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
167 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
168 behavior_flags, &present_parameters, &device)))
169 return device;
171 if (desc && desc->flags & CREATE_DEVICE_SWVP_ONLY)
172 return NULL;
173 behavior_flags ^= (D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING);
175 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
176 behavior_flags, &present_parameters, &device)))
177 return device;
179 return NULL;
182 static HRESULT reset_device(IDirect3DDevice9 *device, HWND device_window, BOOL windowed)
184 D3DPRESENT_PARAMETERS present_parameters = {0};
186 present_parameters.Windowed = windowed;
187 present_parameters.hDeviceWindow = device_window;
188 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
189 present_parameters.BackBufferWidth = screen_width;
190 present_parameters.BackBufferHeight = screen_height;
191 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
192 present_parameters.EnableAutoDepthStencil = TRUE;
193 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
195 return IDirect3DDevice9_Reset(device, &present_parameters);
198 #define CHECK_CALL(r,c,d,rc) \
199 if (SUCCEEDED(r)) {\
200 int tmp1 = get_refcount( (IUnknown *)d ); \
201 int rc_new = rc; \
202 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
203 } else {\
204 trace("%s failed: %08x\n", c, r); \
207 #define CHECK_RELEASE(obj,d,rc) \
208 if (obj) { \
209 int tmp1, rc_new = rc; \
210 IUnknown_Release( (IUnknown*)obj ); \
211 tmp1 = get_refcount( (IUnknown *)d ); \
212 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
215 #define CHECK_REFCOUNT(obj,rc) \
217 int rc_new = rc; \
218 int count = get_refcount( (IUnknown *)obj ); \
219 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
222 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
224 int rc_new = rc; \
225 int count = IUnknown_Release( (IUnknown *)obj ); \
226 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
229 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
231 int rc_new = rc; \
232 int count = IUnknown_AddRef( (IUnknown *)obj ); \
233 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
236 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
238 void *container_ptr = (void *)0x1337c0d3; \
239 hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
240 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
241 "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
242 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
245 static void test_get_set_vertex_declaration(void)
247 IDirect3DVertexDeclaration9 *declaration, *tmp;
248 ULONG refcount, expected_refcount;
249 IDirect3DDevice9 *device;
250 IDirect3D9 *d3d;
251 HWND window;
252 HRESULT hr;
254 static const D3DVERTEXELEMENT9 simple_decl[] =
256 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
257 D3DDECL_END()
260 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
261 0, 0, 640, 480, NULL, NULL, NULL, NULL);
262 d3d = Direct3DCreate9(D3D_SDK_VERSION);
263 ok(!!d3d, "Failed to create a D3D object.\n");
264 if (!(device = create_device(d3d, window, NULL)))
266 skip("Failed to create a D3D device, skipping tests.\n");
267 goto done;
270 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
271 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
273 /* SetVertexDeclaration() should not touch the declaration's refcount. */
274 expected_refcount = get_refcount((IUnknown *)declaration);
275 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
276 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
277 refcount = get_refcount((IUnknown *)declaration);
278 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
280 /* GetVertexDeclaration() should increase the declaration's refcount by one. */
281 tmp = NULL;
282 expected_refcount = refcount + 1;
283 hr = IDirect3DDevice9_GetVertexDeclaration(device, &tmp);
284 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
285 ok(tmp == declaration, "Got unexpected declaration %p, expected %p.\n", tmp, declaration);
286 refcount = get_refcount((IUnknown *)declaration);
287 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
288 IDirect3DVertexDeclaration9_Release(tmp);
290 IDirect3DVertexDeclaration9_Release(declaration);
291 refcount = IDirect3DDevice9_Release(device);
292 ok(!refcount, "Device has %u references left.\n", refcount);
293 done:
294 IDirect3D9_Release(d3d);
295 DestroyWindow(window);
298 static void test_get_declaration(void)
300 unsigned int element_count, expected_element_count;
301 IDirect3DVertexDeclaration9 *declaration;
302 D3DVERTEXELEMENT9 *elements;
303 IDirect3DDevice9 *device;
304 IDirect3D9 *d3d;
305 ULONG refcount;
306 HWND window;
307 HRESULT hr;
309 static const D3DVERTEXELEMENT9 simple_decl[] =
311 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
312 D3DDECL_END()
315 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
316 0, 0, 640, 480, NULL, NULL, NULL, NULL);
317 d3d = Direct3DCreate9(D3D_SDK_VERSION);
318 ok(!!d3d, "Failed to create a D3D object.\n");
319 if (!(device = create_device(d3d, window, NULL)))
321 skip("Failed to create a D3D device, skipping tests.\n");
322 goto done;
325 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
326 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
328 /* First test only getting the number of elements. */
329 element_count = 0x1337c0de;
330 expected_element_count = sizeof(simple_decl) / sizeof(*simple_decl);
331 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
332 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
333 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
334 element_count, expected_element_count);
336 element_count = 0;
337 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
338 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
339 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
340 element_count, expected_element_count);
342 /* Also test the returned data. */
343 elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(simple_decl));
345 element_count = 0x1337c0de;
346 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
347 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
348 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
349 element_count, expected_element_count);
350 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
351 "Original and returned vertexdeclarations are not the same.\n");
353 memset(elements, 0, sizeof(simple_decl));
355 element_count = 0;
356 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
357 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
358 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
359 element_count, expected_element_count);
360 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
361 "Original and returned vertexdeclarations are not the same.\n");
363 HeapFree(GetProcessHeap(), 0, elements);
364 IDirect3DVertexDeclaration9_Release(declaration);
365 refcount = IDirect3DDevice9_Release(device);
366 ok(!refcount, "Device has %u references left.\n", refcount);
367 done:
368 IDirect3D9_Release(d3d);
369 DestroyWindow(window);
372 static void test_fvf_decl_conversion(void)
374 IDirect3DVertexDeclaration9 *default_decl;
375 IDirect3DVertexDeclaration9 *declaration;
376 IDirect3DDevice9 *device;
377 IDirect3D9 *d3d;
378 ULONG refcount;
379 unsigned int i;
380 HWND window;
381 HRESULT hr;
383 static const D3DVERTEXELEMENT9 default_elements[] =
385 {0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
386 {0, 4, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
387 D3DDECL_END()
389 /* Test conversions from vertex declaration to an FVF. For some reason
390 * those seem to occur only for POSITION/POSITIONT, otherwise the FVF is
391 * forced to 0 - maybe this is configuration specific. */
392 static const struct
394 D3DVERTEXELEMENT9 elements[7];
395 DWORD fvf;
396 BOOL todo;
398 decl_to_fvf_tests[] =
400 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}, D3DFVF_XYZ, TRUE },
401 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}, D3DFVF_XYZRHW, TRUE },
402 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
403 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
404 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
405 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
406 {{{0, 0, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0}, D3DDECL_END()}, 0, FALSE},
407 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}, 0, FALSE},
408 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}, 0, FALSE},
409 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}, 0, FALSE},
410 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}, 0, FALSE},
411 /* No FVF mapping available. */
412 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 1}, D3DDECL_END()}, 0, FALSE},
413 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 1}, D3DDECL_END()}, 0, FALSE},
414 /* Try empty declaration. */
415 {{ D3DDECL_END()}, 0, FALSE},
416 /* Make sure textures of different sizes work. */
417 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
418 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
419 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
420 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
421 /* Make sure the TEXCOORD index works correctly - try several textures. */
424 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
425 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
426 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
427 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
428 D3DDECL_END(),
429 }, 0, FALSE,
431 /* Now try a combination test. */
434 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITIONT, 0},
435 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
436 {0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0},
437 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
438 {0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
439 {0, 44, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1},
440 D3DDECL_END(),
441 }, 0, FALSE,
444 /* Test conversions from FVF to a vertex declaration. These seem to always
445 * occur internally. A new declaration object is created if necessary. */
446 static const struct
448 DWORD fvf;
449 D3DVERTEXELEMENT9 elements[7];
451 fvf_to_decl_tests[] =
453 {D3DFVF_XYZ, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
454 {D3DFVF_XYZW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
455 {D3DFVF_XYZRHW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}},
457 D3DFVF_XYZB5,
459 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
460 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
461 {0, 28, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDINDICES, 0},
462 D3DDECL_END(),
466 D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4,
468 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
469 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
470 {0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
471 D3DDECL_END(),
475 D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR,
477 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
478 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
479 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
480 D3DDECL_END(),
484 D3DFVF_XYZB1,
486 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
487 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
488 D3DDECL_END(),
492 D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4,
494 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
495 {0, 12, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
496 D3DDECL_END(),
500 D3DFVF_XYZB1 | D3DFVF_LASTBETA_D3DCOLOR,
502 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
503 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
504 D3DDECL_END(),
508 D3DFVF_XYZB2,
510 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
511 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
512 D3DDECL_END(),
516 D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4,
518 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
519 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
520 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
521 D3DDECL_END(),
525 D3DFVF_XYZB2 | D3DFVF_LASTBETA_D3DCOLOR,
527 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
528 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
529 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
530 D3DDECL_END(),
534 D3DFVF_XYZB3,
536 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
537 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
538 D3DDECL_END(),
542 D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4,
544 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
545 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
546 {0, 20, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
547 D3DDECL_END(),
551 D3DFVF_XYZB3 | D3DFVF_LASTBETA_D3DCOLOR,
553 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
554 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
555 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
556 D3DDECL_END(),
560 D3DFVF_XYZB4,
562 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
563 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
564 D3DDECL_END(),
568 D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4,
570 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
571 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
572 {0, 24, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
573 D3DDECL_END(),
577 D3DFVF_XYZB4 | D3DFVF_LASTBETA_D3DCOLOR,
579 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
580 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
581 {0, 24, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
582 D3DDECL_END(),
585 {D3DFVF_NORMAL, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}},
586 {D3DFVF_PSIZE, {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}},
587 {D3DFVF_DIFFUSE, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}},
588 {D3DFVF_SPECULAR, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}},
589 /* Make sure textures of different sizes work. */
591 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1,
592 {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
595 D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1,
596 {{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
599 D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1,
600 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
603 D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1,
604 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
606 /* Make sure the TEXCOORD index works correctly - try several textures. */
608 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE2(2)
609 | D3DFVF_TEXCOORDSIZE4(3) | D3DFVF_TEX4,
611 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
612 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
613 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
614 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
615 D3DDECL_END(),
618 /* Now try a combination test. */
620 D3DFVF_XYZB4 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEXCOORDSIZE2(0)
621 | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEX2,
623 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
624 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
625 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
626 {0, 32, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
627 {0, 36, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0},
628 {0, 44, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
629 D3DDECL_END(),
634 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
635 0, 0, 640, 480, NULL, NULL, NULL, NULL);
636 d3d = Direct3DCreate9(D3D_SDK_VERSION);
637 ok(!!d3d, "Failed to create a D3D object.\n");
638 if (!(device = create_device(d3d, window, NULL)))
640 skip("Failed to create a D3D device, skipping tests.\n");
641 goto done;
644 for (i = 0; i < sizeof(decl_to_fvf_tests) / sizeof(*decl_to_fvf_tests); ++i)
646 DWORD fvf = 0xdeadbeef;
647 HRESULT hr;
649 /* Set a default FVF of SPECULAR and DIFFUSE to make sure it is changed
650 * back to 0. */
651 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
652 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#x.\n", i, hr);
654 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_to_fvf_tests[i].elements, &declaration);
655 ok(SUCCEEDED(hr), "Test %u: Failed to create vertex declaration, hr %#x.\n", i, hr);
656 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
657 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#x.\n", i, hr);
659 /* Check the FVF. */
660 hr = IDirect3DDevice9_GetFVF(device, &fvf);
661 ok(SUCCEEDED(hr), "Test %u: Failed to get FVF, hr %#x.\n", i, hr);
663 if (decl_to_fvf_tests[i].todo)
664 todo_wine ok(fvf == decl_to_fvf_tests[i].fvf,
665 "Test %u: Got unexpected FVF %#x, expected %#x.\n",
666 i, fvf, decl_to_fvf_tests[i].fvf);
667 else
668 ok(fvf == decl_to_fvf_tests[i].fvf,
669 "Test %u: Got unexpected FVF %#x, expected %#x.\n",
670 i, fvf, decl_to_fvf_tests[i].fvf);
672 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
673 IDirect3DVertexDeclaration9_Release(declaration);
676 /* Create a default declaration and FVF that does not match any of the
677 * tests. */
678 hr = IDirect3DDevice9_CreateVertexDeclaration(device, default_elements, &default_decl);
679 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
681 for (i = 0; i < sizeof(fvf_to_decl_tests) / sizeof(*fvf_to_decl_tests); ++i)
683 /* Set a default declaration to make sure it is changed. */
684 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
685 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#x.\n", i, hr);
687 hr = IDirect3DDevice9_SetFVF(device, fvf_to_decl_tests[i].fvf);
688 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#x.\n", i, hr);
690 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
691 ok(SUCCEEDED(hr), "Test %u: Failed to get vertex declaration, hr %#x.\n", i, hr);
692 ok(!!declaration && declaration != default_decl,
693 "Test %u: Got unexpected declaration %p.\n", i, declaration);
694 ok(compare_elements(declaration, fvf_to_decl_tests[i].elements),
695 "Test %u: Declaration does not match.\n", i);
696 IDirect3DVertexDeclaration9_Release(declaration);
699 /* Setting the FVF to 0 should result in no change to the default decl. */
700 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
701 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
702 hr = IDirect3DDevice9_SetFVF(device, 0);
703 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
704 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
705 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
706 ok(declaration == default_decl, "Got unexpected declaration %p, expected %p.\n", declaration, default_decl);
707 IDirect3DVertexDeclaration9_Release(declaration);
709 IDirect3DVertexDeclaration9_Release(default_decl);
710 refcount = IDirect3DDevice9_Release(device);
711 ok(!refcount, "Device has %u references left.\n", refcount);
712 done:
713 IDirect3D9_Release(d3d);
714 DestroyWindow(window);
717 /* Check whether a declaration converted from FVF is shared.
718 * Check whether refcounts behave as expected. */
719 static void test_fvf_decl_management(void)
721 IDirect3DVertexDeclaration9 *declaration1;
722 IDirect3DVertexDeclaration9 *declaration2;
723 IDirect3DVertexDeclaration9 *declaration3;
724 IDirect3DVertexDeclaration9 *declaration4;
725 IDirect3DDevice9 *device;
726 IDirect3D9 *d3d;
727 ULONG refcount;
728 HWND window;
729 HRESULT hr;
731 static const D3DVERTEXELEMENT9 test_elements1[] =
732 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()};
733 static const D3DVERTEXELEMENT9 test_elements2[] =
734 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()};
736 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
737 0, 0, 640, 480, NULL, NULL, NULL, NULL);
738 d3d = Direct3DCreate9(D3D_SDK_VERSION);
739 ok(!!d3d, "Failed to create a D3D object.\n");
740 if (!(device = create_device(d3d, window, NULL)))
742 skip("Failed to create a D3D device, skipping tests.\n");
743 goto done;
746 /* Clear down any current vertex declaration. */
747 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
748 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
749 /* Conversion. */
750 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
751 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
752 /* Get converted decl (#1). */
753 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration1);
754 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
755 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
756 /* Get converted decl again (#2). */
757 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration2);
758 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
759 ok(declaration2 == declaration1, "Got unexpected declaration2 %p, expected %p.\n", declaration2, declaration1);
761 /* Conversion. */
762 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_NORMAL);
763 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
764 /* Get converted decl (#3). */
765 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration3);
766 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
767 ok(declaration3 != declaration2, "Got unexpected declaration3 %p.\n", declaration3);
768 /* The contents should correspond to the second conversion. */
769 ok(compare_elements(declaration3, test_elements2), "Declaration does not match.\n");
770 /* Re-Check if the first decl was overwritten by the new Get(). */
771 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
773 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
774 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
775 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration4);
776 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
777 ok(declaration4 == declaration1, "Got unexpected declaration4 %p, expected %p.\n", declaration4, declaration1);
779 refcount = get_refcount((IUnknown*)declaration1);
780 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
781 refcount = get_refcount((IUnknown*)declaration2);
782 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
783 refcount = get_refcount((IUnknown*)declaration3);
784 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
785 refcount = get_refcount((IUnknown*)declaration4);
786 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
788 IDirect3DVertexDeclaration9_Release(declaration4);
789 IDirect3DVertexDeclaration9_Release(declaration3);
790 IDirect3DVertexDeclaration9_Release(declaration2);
791 IDirect3DVertexDeclaration9_Release(declaration1);
793 refcount = IDirect3DDevice9_Release(device);
794 ok(!refcount, "Device has %u references left.\n", refcount);
795 done:
796 IDirect3D9_Release(d3d);
797 DestroyWindow(window);
800 static void test_vertex_declaration_alignment(void)
802 IDirect3DVertexDeclaration9 *declaration;
803 IDirect3DDevice9 *device;
804 IDirect3D9 *d3d;
805 unsigned int i;
806 ULONG refcount;
807 HWND window;
808 HRESULT hr;
810 static const struct
812 D3DVERTEXELEMENT9 elements[3];
813 HRESULT hr;
815 test_data[] =
819 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
820 {0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
821 D3DDECL_END(),
822 }, D3D_OK,
826 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
827 {0, 17, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
828 D3DDECL_END(),
829 }, E_FAIL,
833 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
834 {0, 18, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
835 D3DDECL_END(),
836 }, E_FAIL,
840 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
841 {0, 19, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
842 D3DDECL_END(),
843 }, E_FAIL,
847 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
848 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
849 D3DDECL_END(),
850 }, D3D_OK,
854 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
855 0, 0, 640, 480, NULL, NULL, NULL, NULL);
856 d3d = Direct3DCreate9(D3D_SDK_VERSION);
857 ok(!!d3d, "Failed to create a D3D object.\n");
858 if (!(device = create_device(d3d, window, NULL)))
860 skip("Failed to create a D3D device, skipping tests.\n");
861 goto done;
864 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
866 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_data[i].elements, &declaration);
867 ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr);
868 if (SUCCEEDED(hr))
869 IDirect3DVertexDeclaration9_Release(declaration);
872 refcount = IDirect3DDevice9_Release(device);
873 ok(!refcount, "Device has %u references left.\n", refcount);
874 done:
875 IDirect3D9_Release(d3d);
876 DestroyWindow(window);
879 static void test_unused_declaration_type(void)
881 IDirect3DVertexDeclaration9 *declaration;
882 IDirect3DDevice9 *device;
883 IDirect3D9 *d3d;
884 unsigned int i;
885 ULONG refcount;
886 HWND window;
887 HRESULT hr;
889 static const D3DVERTEXELEMENT9 test_elements[][3] =
892 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
893 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_COLOR , 0 },
894 D3DDECL_END(),
897 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
898 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 0 },
899 D3DDECL_END(),
902 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
903 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 1 },
904 D3DDECL_END(),
907 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
908 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
909 D3DDECL_END(),
912 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
913 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
914 D3DDECL_END(),
917 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
918 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
919 D3DDECL_END(),
922 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
923 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
924 D3DDECL_END(),
928 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
929 0, 0, 640, 480, NULL, NULL, NULL, NULL);
930 d3d = Direct3DCreate9(D3D_SDK_VERSION);
931 ok(!!d3d, "Failed to create a D3D object.\n");
932 if (!(device = create_device(d3d, window, NULL)))
934 skip("Failed to create a D3D device, skipping tests.\n");
935 goto done;
938 for (i = 0; i < sizeof(test_elements) / sizeof(*test_elements); ++i)
940 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &declaration);
941 ok(hr == E_FAIL, "Test %u: Got unexpected hr %#x.\n", i, hr);
944 refcount = IDirect3DDevice9_Release(device);
945 ok(!refcount, "Device has %u references left.\n", refcount);
946 done:
947 IDirect3D9_Release(d3d);
948 DestroyWindow(window);
951 static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count)
953 IDirect3DBaseTexture9* texture = NULL;
954 HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0,
955 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
957 if (SUCCEEDED(hr)) {
958 DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
959 ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
960 } else
961 trace("CreateTexture failed: %08x\n", hr);
963 if (texture) IDirect3DBaseTexture9_Release( texture );
966 static void test_mipmap_levels(void)
968 IDirect3DDevice9 *device;
969 IDirect3D9 *d3d;
970 ULONG refcount;
971 HWND window;
973 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
974 0, 0, 640, 480, NULL, NULL, NULL, NULL);
975 ok(!!window, "Failed to create a window.\n");
976 d3d = Direct3DCreate9(D3D_SDK_VERSION);
977 ok(!!d3d, "Failed to create a D3D object.\n");
978 if (!(device = create_device(d3d, window, NULL)))
980 skip("Failed to create a 3D device, skipping test.\n");
981 goto cleanup;
984 check_mipmap_levels(device, 32, 32, 6);
985 check_mipmap_levels(device, 256, 1, 9);
986 check_mipmap_levels(device, 1, 256, 9);
987 check_mipmap_levels(device, 1, 1, 1);
989 refcount = IDirect3DDevice9_Release(device);
990 ok(!refcount, "Device has %u references left.\n", refcount);
991 cleanup:
992 IDirect3D9_Release(d3d);
993 DestroyWindow(window);
996 static void test_checkdevicemultisampletype(void)
998 IDirect3DDevice9 *device;
999 DWORD quality_levels;
1000 IDirect3D9 *d3d;
1001 ULONG refcount;
1002 HWND window;
1003 HRESULT hr;
1005 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1006 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1007 ok(!!window, "Failed to create a window.\n");
1008 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1009 ok(!!d3d, "Failed to create a D3D object.\n");
1010 if (!(device = create_device(d3d, window, NULL)))
1012 skip("Failed to create a 3D device, skipping test.\n");
1013 goto cleanup;
1016 quality_levels = 0;
1017 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1018 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality_levels);
1019 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
1020 if (hr == D3DERR_NOTAVAILABLE)
1022 skip("IDirect3D9_CheckDeviceMultiSampleType not available\n");
1023 goto cleanup;
1025 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
1027 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1028 D3DFMT_X8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality_levels);
1029 ok(SUCCEEDED(hr), "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
1030 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
1032 cleanup:
1033 if (device)
1035 refcount = IDirect3DDevice9_Release(device);
1036 ok(!refcount, "Device has %u references left.\n", refcount);
1038 IDirect3D9_Release(d3d);
1039 DestroyWindow(window);
1042 static void test_swapchain(void)
1044 IDirect3DSwapChain9 *swapchain0;
1045 IDirect3DSwapChain9 *swapchain1;
1046 IDirect3DSwapChain9 *swapchain2;
1047 IDirect3DSwapChain9 *swapchain3;
1048 IDirect3DSwapChain9 *swapchainX;
1049 IDirect3DSurface9 *backbuffer;
1050 D3DPRESENT_PARAMETERS d3dpp;
1051 IDirect3DDevice9 *device;
1052 IDirect3D9 *d3d;
1053 ULONG refcount;
1054 HWND window;
1055 HRESULT hr;
1057 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1058 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1059 ok(!!window, "Failed to create a window.\n");
1060 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1061 ok(!!d3d, "Failed to create a D3D object.\n");
1062 if (!(device = create_device(d3d, window, NULL)))
1064 skip("Failed to create a 3D device, skipping test.\n");
1065 goto cleanup;
1068 /* Get the implicit swapchain */
1069 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain0);
1070 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
1071 /* Check if the back buffer count was modified */
1072 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain0, &d3dpp);
1073 ok(d3dpp.BackBufferCount == 1, "Got unexpected back buffer count %u.\n", d3dpp.BackBufferCount);
1074 IDirect3DSwapChain9_Release(swapchain0);
1076 /* Check if there is a back buffer */
1077 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1078 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1079 ok(backbuffer != NULL, "The back buffer is NULL\n");
1080 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1082 /* Try to get a nonexistent swapchain */
1083 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1084 ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr);
1085 ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
1086 if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
1088 /* Create a bunch of swapchains */
1089 d3dpp.BackBufferCount = 0;
1090 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1091 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1092 ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
1094 d3dpp.BackBufferCount = 1;
1095 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain2);
1096 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1098 d3dpp.BackBufferCount = 2;
1099 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain3);
1100 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1101 if(SUCCEEDED(hr)) {
1102 /* Swapchain 3, created with backbuffercount 2 */
1103 backbuffer = (void *) 0xdeadbeef;
1104 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
1105 ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%08x)\n", hr);
1106 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1107 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1109 backbuffer = (void *) 0xdeadbeef;
1110 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
1111 ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%08x)\n", hr);
1112 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1113 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1115 backbuffer = (void *) 0xdeadbeef;
1116 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
1117 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
1118 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1119 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1121 backbuffer = (void *) 0xdeadbeef;
1122 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
1123 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1124 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1125 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1128 /* Check the back buffers of the swapchains */
1129 /* Swapchain 1, created with backbuffercount 0 */
1130 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1131 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1132 ok(backbuffer != NULL, "The back buffer is NULL (%08x)\n", hr);
1133 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1135 backbuffer = (void *) 0xdeadbeef;
1136 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
1137 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1138 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1139 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1141 /* Swapchain 2 - created with backbuffercount 1 */
1142 backbuffer = (void *) 0xdeadbeef;
1143 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
1144 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1145 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1146 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1148 backbuffer = (void *) 0xdeadbeef;
1149 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
1150 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
1151 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1152 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1154 backbuffer = (void *) 0xdeadbeef;
1155 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
1156 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1157 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1158 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1160 /* Try getSwapChain on a manually created swapchain
1161 * it should fail, apparently GetSwapChain only returns implicit swapchains
1163 swapchainX = (void *) 0xdeadbeef;
1164 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1165 ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%08x)\n", hr);
1166 ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
1167 if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
1169 IDirect3DSwapChain9_Release(swapchain3);
1170 IDirect3DSwapChain9_Release(swapchain2);
1171 IDirect3DSwapChain9_Release(swapchain1);
1172 refcount = IDirect3DDevice9_Release(device);
1173 ok(!refcount, "Device has %u references left.\n", refcount);
1174 cleanup:
1175 IDirect3D9_Release(d3d);
1176 DestroyWindow(window);
1179 static void test_refcount(void)
1181 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
1182 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
1183 IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
1184 IDirect3DVertexShader9 *pVertexShader = NULL;
1185 IDirect3DPixelShader9 *pPixelShader = NULL;
1186 IDirect3DCubeTexture9 *pCubeTexture = NULL;
1187 IDirect3DTexture9 *pTexture = NULL;
1188 IDirect3DVolumeTexture9 *pVolumeTexture = NULL;
1189 IDirect3DVolume9 *pVolumeLevel = NULL;
1190 IDirect3DSurface9 *pStencilSurface = NULL;
1191 IDirect3DSurface9 *pOffscreenSurface = NULL;
1192 IDirect3DSurface9 *pRenderTarget = NULL;
1193 IDirect3DSurface9 *pRenderTarget2 = NULL;
1194 IDirect3DSurface9 *pRenderTarget3 = NULL;
1195 IDirect3DSurface9 *pTextureLevel = NULL;
1196 IDirect3DSurface9 *pBackBuffer = NULL;
1197 IDirect3DStateBlock9 *pStateBlock = NULL;
1198 IDirect3DStateBlock9 *pStateBlock1 = NULL;
1199 IDirect3DSwapChain9 *pSwapChain = NULL;
1200 IDirect3DQuery9 *pQuery = NULL;
1201 D3DPRESENT_PARAMETERS d3dpp;
1202 IDirect3DDevice9 *device;
1203 ULONG refcount = 0, tmp;
1204 IDirect3D9 *d3d, *d3d2;
1205 HWND window;
1206 HRESULT hr;
1208 D3DVERTEXELEMENT9 decl[] =
1210 D3DDECL_END()
1213 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1214 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1215 ok(!!window, "Failed to create a window.\n");
1216 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1217 ok(!!d3d, "Failed to create a D3D object.\n");
1219 CHECK_REFCOUNT(d3d, 1);
1221 if (!(device = create_device(d3d, window, NULL)))
1223 skip("Failed to create a 3D device, skipping test.\n");
1224 goto cleanup;
1227 refcount = get_refcount((IUnknown *)device);
1228 ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
1230 CHECK_REFCOUNT(d3d, 2);
1232 hr = IDirect3DDevice9_GetDirect3D(device, &d3d2);
1233 CHECK_CALL(hr, "GetDirect3D", device, refcount);
1235 ok(d3d2 == d3d, "Expected IDirect3D9 pointers to be equal.\n");
1236 CHECK_REFCOUNT(d3d, 3);
1237 CHECK_RELEASE_REFCOUNT(d3d, 2);
1240 * Check refcount of implicit surfaces and implicit swapchain. Findings:
1241 * - the container is the device OR swapchain
1242 * - they hold a reference to the device
1243 * - they are created with a refcount of 0 (Get/Release returns original refcount)
1244 * - they are not freed if refcount reaches 0.
1245 * - the refcount is not forwarded to the container.
1247 hr = IDirect3DDevice9_GetSwapChain(device, 0, &pSwapChain);
1248 CHECK_CALL(hr, "GetSwapChain", device, ++refcount);
1249 if (pSwapChain)
1251 CHECK_REFCOUNT( pSwapChain, 1);
1253 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1254 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1255 CHECK_REFCOUNT( pSwapChain, 1);
1256 if(pRenderTarget)
1258 CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
1259 CHECK_REFCOUNT( pRenderTarget, 1);
1261 CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
1262 CHECK_REFCOUNT(device, refcount);
1263 CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
1264 CHECK_REFCOUNT(device, refcount);
1266 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1267 CHECK_CALL(hr, "GetRenderTarget", device, refcount);
1268 CHECK_REFCOUNT( pRenderTarget, 2);
1269 CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
1270 CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
1271 CHECK_REFCOUNT(device, --refcount);
1273 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
1274 CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
1275 CHECK_REFCOUNT(device, ++refcount);
1276 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
1277 CHECK_REFCOUNT(device, --refcount);
1280 /* Render target and back buffer are identical. */
1281 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, 0, &pBackBuffer);
1282 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1283 if(pBackBuffer)
1285 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1286 ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
1287 pRenderTarget, pBackBuffer);
1288 pBackBuffer = NULL;
1290 CHECK_REFCOUNT(device, --refcount);
1292 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &pStencilSurface);
1293 CHECK_CALL(hr, "GetDepthStencilSurface", device, ++refcount);
1294 CHECK_REFCOUNT( pSwapChain, 1);
1295 if(pStencilSurface)
1297 CHECK_SURFACE_CONTAINER(pStencilSurface, IID_IDirect3DDevice9, device);
1298 CHECK_REFCOUNT( pStencilSurface, 1);
1300 CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
1301 CHECK_REFCOUNT(device, refcount);
1302 CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
1303 CHECK_REFCOUNT(device, refcount);
1305 CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
1306 CHECK_REFCOUNT(device, --refcount);
1308 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
1309 CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
1310 CHECK_REFCOUNT(device, ++refcount);
1311 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
1312 CHECK_REFCOUNT(device, --refcount);
1313 pStencilSurface = NULL;
1316 CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
1317 CHECK_REFCOUNT(device, --refcount);
1319 /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
1320 CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
1321 CHECK_REFCOUNT(device, ++refcount);
1322 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1323 CHECK_REFCOUNT(device, --refcount);
1324 pSwapChain = NULL;
1327 /* Buffers */
1328 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL);
1329 CHECK_CALL(hr, "CreateIndexBuffer", device, ++refcount );
1330 if(pIndexBuffer)
1332 tmp = get_refcount( (IUnknown *)pIndexBuffer );
1334 hr = IDirect3DDevice9_SetIndices(device, pIndexBuffer);
1335 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1336 hr = IDirect3DDevice9_SetIndices(device, NULL);
1337 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1340 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL);
1341 CHECK_CALL(hr, "CreateVertexBuffer", device, ++refcount);
1342 if(pVertexBuffer)
1344 IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
1345 UINT offset = ~0;
1346 UINT stride = ~0;
1348 tmp = get_refcount( (IUnknown *)pVertexBuffer );
1350 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 3 * sizeof(float));
1351 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1352 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1353 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1355 hr = IDirect3DDevice9_GetStreamSource(device, 0, &pVBuf, &offset, &stride);
1356 ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
1357 ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
1358 ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
1359 ok(offset==0, "offset not 0 (got %u)!\n", offset);
1361 /* Shaders */
1362 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pVertexDeclaration);
1363 CHECK_CALL(hr, "CreateVertexDeclaration", device, ++refcount);
1364 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &pVertexShader);
1365 CHECK_CALL(hr, "CreateVertexShader", device, ++refcount);
1366 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &pPixelShader);
1367 CHECK_CALL(hr, "CreatePixelShader", device, ++refcount);
1368 /* Textures */
1369 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL);
1370 CHECK_CALL(hr, "CreateTexture", device, ++refcount);
1371 if (pTexture)
1373 tmp = get_refcount( (IUnknown *)pTexture );
1375 /* SetTexture should not increase refcounts */
1376 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)pTexture);
1377 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1378 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1379 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1381 /* This should not increment device refcount */
1382 hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
1383 CHECK_CALL(hr, "GetSurfaceLevel", device, refcount);
1384 /* But should increment texture's refcount */
1385 CHECK_REFCOUNT( pTexture, tmp+1 );
1386 /* Because the texture and surface refcount are identical */
1387 if (pTextureLevel)
1389 CHECK_REFCOUNT ( pTextureLevel, tmp+1 );
1390 CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
1391 CHECK_REFCOUNT ( pTexture , tmp+2 );
1392 CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
1393 CHECK_REFCOUNT ( pTexture , tmp+1 );
1394 CHECK_RELEASE_REFCOUNT( pTexture , tmp );
1395 CHECK_REFCOUNT ( pTextureLevel, tmp );
1398 hr = IDirect3DDevice9_CreateCubeTexture(device, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL);
1399 CHECK_CALL(hr, "CreateCubeTexture", device, ++refcount);
1400 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 2, 0, 0,
1401 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL);
1402 CHECK_CALL(hr, "CreateVolumeTexture", device, ++refcount);
1403 if (pVolumeTexture)
1405 tmp = get_refcount( (IUnknown *)pVolumeTexture );
1407 /* This should not increment device refcount */
1408 hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
1409 CHECK_CALL(hr, "GetVolumeLevel", device, refcount);
1410 /* But should increment volume texture's refcount */
1411 CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
1412 /* Because the volume texture and volume refcount are identical */
1413 if (pVolumeLevel)
1415 CHECK_REFCOUNT ( pVolumeLevel , tmp+1 );
1416 CHECK_ADDREF_REFCOUNT ( pVolumeLevel , tmp+2 );
1417 CHECK_REFCOUNT ( pVolumeTexture, tmp+2 );
1418 CHECK_RELEASE_REFCOUNT( pVolumeLevel , tmp+1 );
1419 CHECK_REFCOUNT ( pVolumeTexture, tmp+1 );
1420 CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp );
1421 CHECK_REFCOUNT ( pVolumeLevel , tmp );
1424 /* Surfaces */
1425 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32,
1426 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL);
1427 CHECK_CALL(hr, "CreateDepthStencilSurface", device, ++refcount);
1428 CHECK_REFCOUNT( pStencilSurface, 1 );
1429 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1430 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL);
1431 CHECK_CALL(hr, "CreateOffscreenPlainSurface", device, ++refcount);
1432 CHECK_REFCOUNT( pOffscreenSurface, 1 );
1433 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
1434 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL);
1435 CHECK_CALL(hr, "CreateRenderTarget", device, ++refcount);
1436 CHECK_REFCOUNT( pRenderTarget3, 1 );
1437 /* Misc */
1438 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &pStateBlock);
1439 CHECK_CALL(hr, "CreateStateBlock", device, ++refcount);
1441 memset(&d3dpp, 0, sizeof(d3dpp));
1442 d3dpp.Windowed = TRUE;
1443 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1444 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1445 d3dpp.EnableAutoDepthStencil = TRUE;
1446 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1447 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &pSwapChain);
1448 CHECK_CALL(hr, "CreateAdditionalSwapChain", device, ++refcount);
1449 if(pSwapChain)
1451 /* check implicit back buffer */
1452 hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
1453 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1454 CHECK_REFCOUNT( pSwapChain, 1);
1455 if(pBackBuffer)
1457 CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
1458 CHECK_REFCOUNT( pBackBuffer, 1);
1459 CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
1460 CHECK_REFCOUNT(device, --refcount);
1462 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
1463 CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
1464 CHECK_REFCOUNT(device, ++refcount);
1465 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1466 CHECK_REFCOUNT(device, --refcount);
1467 pBackBuffer = NULL;
1469 CHECK_REFCOUNT( pSwapChain, 1);
1471 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &pQuery);
1472 CHECK_CALL(hr, "CreateQuery", device, ++refcount);
1474 hr = IDirect3DDevice9_BeginStateBlock(device);
1475 CHECK_CALL(hr, "BeginStateBlock", device, refcount);
1476 hr = IDirect3DDevice9_EndStateBlock(device, &pStateBlock1);
1477 CHECK_CALL(hr, "EndStateBlock", device, ++refcount);
1479 /* The implicit render target is not freed if refcount reaches 0.
1480 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
1481 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget2);
1482 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1483 if(pRenderTarget2)
1485 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
1486 ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
1487 pRenderTarget, pRenderTarget2);
1488 CHECK_REFCOUNT(device, --refcount);
1489 pRenderTarget2 = NULL;
1491 pRenderTarget = NULL;
1493 cleanup:
1494 CHECK_RELEASE(device, device, --refcount);
1496 /* Buffers */
1497 CHECK_RELEASE(pVertexBuffer, device, --refcount);
1498 CHECK_RELEASE(pIndexBuffer, device, --refcount);
1499 /* Shaders */
1500 CHECK_RELEASE(pVertexDeclaration, device, --refcount);
1501 CHECK_RELEASE(pVertexShader, device, --refcount);
1502 CHECK_RELEASE(pPixelShader, device, --refcount);
1503 /* Textures */
1504 CHECK_RELEASE(pTextureLevel, device, --refcount);
1505 CHECK_RELEASE(pCubeTexture, device, --refcount);
1506 CHECK_RELEASE(pVolumeTexture, device, --refcount);
1507 /* Surfaces */
1508 CHECK_RELEASE(pStencilSurface, device, --refcount);
1509 CHECK_RELEASE(pOffscreenSurface, device, --refcount);
1510 CHECK_RELEASE(pRenderTarget3, device, --refcount);
1511 /* Misc */
1512 CHECK_RELEASE(pStateBlock, device, --refcount);
1513 CHECK_RELEASE(pSwapChain, device, --refcount);
1514 CHECK_RELEASE(pQuery, device, --refcount);
1515 /* This will destroy device - cannot check the refcount here */
1516 if (pStateBlock1) CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
1517 CHECK_RELEASE_REFCOUNT(d3d, 0);
1518 DestroyWindow(window);
1521 static void test_cursor(void)
1523 IDirect3DSurface9 *cursor = NULL;
1524 IDirect3DDevice9 *device;
1525 CURSORINFO info;
1526 IDirect3D9 *d3d;
1527 ULONG refcount;
1528 HCURSOR cur;
1529 HWND window;
1530 HRESULT hr;
1532 memset(&info, 0, sizeof(info));
1533 info.cbSize = sizeof(info);
1534 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1535 cur = info.hCursor;
1537 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1538 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1539 ok(!!window, "Failed to create a window.\n");
1540 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1541 ok(!!d3d, "Failed to create a D3D object.\n");
1542 if (!(device = create_device(d3d, window, NULL)))
1544 skip("Failed to create a 3D device, skipping test.\n");
1545 goto cleanup;
1548 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1549 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
1550 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
1552 /* Initially hidden */
1553 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1554 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1556 /* Not enabled without a surface*/
1557 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1558 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1560 /* Fails */
1561 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, NULL);
1562 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
1564 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
1565 ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
1567 IDirect3DSurface9_Release(cursor);
1569 memset(&info, 0, sizeof(info));
1570 info.cbSize = sizeof(info);
1571 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1572 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
1573 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
1575 /* Still hidden */
1576 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1577 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1579 /* Enabled now*/
1580 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1581 ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1583 /* GDI cursor unchanged */
1584 memset(&info, 0, sizeof(info));
1585 info.cbSize = sizeof(info);
1586 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1587 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
1588 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
1590 refcount = IDirect3DDevice9_Release(device);
1591 ok(!refcount, "Device has %u references left.\n", refcount);
1592 cleanup:
1593 IDirect3D9_Release(d3d);
1594 DestroyWindow(window);
1597 static void test_reset(void)
1599 HRESULT hr;
1600 RECT winrect;
1601 D3DPRESENT_PARAMETERS d3dpp;
1602 D3DDISPLAYMODE d3ddm, d3ddm2;
1603 D3DVIEWPORT9 vp;
1604 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
1605 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
1606 IDirect3DSwapChain9 *pSwapchain;
1607 IDirect3DSurface9 *surface;
1608 IDirect3DTexture9 *texture;
1609 IDirect3DVertexShader9 *shader;
1610 UINT i, adapter_mode_count;
1611 D3DLOCKED_RECT lockrect;
1612 IDirect3DDevice9 *device1 = NULL;
1613 IDirect3DDevice9 *device2 = NULL;
1614 IDirect3D9 *d3d;
1615 D3DCAPS9 caps;
1616 DWORD value;
1617 HWND hwnd;
1618 struct
1620 UINT w;
1621 UINT h;
1622 } *modes = NULL;
1623 UINT mode_count = 0;
1625 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1626 100, 100, 160, 160, NULL, NULL, NULL, NULL);
1627 ok(!!hwnd, "Failed to create a window.\n");
1628 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1629 ok(!!d3d, "Failed to create a D3D object.\n");
1631 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
1632 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, d3ddm.Format);
1633 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
1634 for(i = 0; i < adapter_mode_count; ++i)
1636 UINT j;
1637 ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
1638 hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
1639 ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#x\n", hr);
1641 for (j = 0; j < mode_count; ++j)
1643 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
1644 break;
1646 if (j == mode_count)
1648 modes[j].w = d3ddm2.Width;
1649 modes[j].h = d3ddm2.Height;
1650 ++mode_count;
1653 /* We use them as invalid modes */
1654 if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
1655 (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
1656 skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
1657 d3ddm2.Width, d3ddm2.Height);
1658 goto cleanup;
1662 if (mode_count < 2)
1664 skip("Less than 2 modes supported, skipping mode tests\n");
1665 goto cleanup;
1668 i = 0;
1669 if (modes[i].w == orig_width && modes[i].h == orig_height) ++i;
1671 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1672 d3dpp.Windowed = FALSE;
1673 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1674 d3dpp.BackBufferWidth = modes[i].w;
1675 d3dpp.BackBufferHeight = modes[i].h;
1676 d3dpp.BackBufferFormat = d3ddm.Format;
1677 d3dpp.EnableAutoDepthStencil = TRUE;
1678 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1680 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1681 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device1);
1682 if (FAILED(hr))
1684 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1685 goto cleanup;
1687 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1688 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1690 hr = IDirect3DDevice9_GetDeviceCaps(device1, &caps);
1691 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
1693 width = GetSystemMetrics(SM_CXSCREEN);
1694 height = GetSystemMetrics(SM_CYSCREEN);
1695 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1696 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1698 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1699 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1700 if(SUCCEEDED(hr))
1702 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1703 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1704 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1705 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1706 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1707 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1710 i = 1;
1711 vp.X = 10;
1712 vp.Y = 20;
1713 vp.MinZ = 2;
1714 vp.MaxZ = 3;
1715 hr = IDirect3DDevice9_SetViewport(device1, &vp);
1716 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1718 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1719 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1720 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1721 hr = IDirect3DDevice9_SetRenderState(device1, D3DRS_LIGHTING, FALSE);
1722 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1724 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1725 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1726 d3dpp.Windowed = FALSE;
1727 d3dpp.BackBufferWidth = modes[i].w;
1728 d3dpp.BackBufferHeight = modes[i].h;
1729 d3dpp.BackBufferFormat = d3ddm.Format;
1730 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1731 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1732 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1733 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1735 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1736 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1737 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1739 ZeroMemory(&vp, sizeof(vp));
1740 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1741 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1742 if(SUCCEEDED(hr))
1744 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1745 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1746 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1747 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1748 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1749 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1752 width = GetSystemMetrics(SM_CXSCREEN);
1753 height = GetSystemMetrics(SM_CYSCREEN);
1754 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1755 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1757 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1758 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1759 if(SUCCEEDED(hr))
1761 ZeroMemory(&d3dpp, sizeof(d3dpp));
1762 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1763 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1764 if(SUCCEEDED(hr))
1766 ok(d3dpp.BackBufferWidth == modes[i].w, "Back buffer width is %u, expected %u\n",
1767 d3dpp.BackBufferWidth, modes[i].w);
1768 ok(d3dpp.BackBufferHeight == modes[i].h, "Back buffer height is %u, expected %u\n",
1769 d3dpp.BackBufferHeight, modes[i].h);
1771 IDirect3DSwapChain9_Release(pSwapchain);
1774 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1775 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1776 d3dpp.Windowed = TRUE;
1777 d3dpp.BackBufferWidth = 400;
1778 d3dpp.BackBufferHeight = 300;
1779 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1780 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1781 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1782 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1784 width = GetSystemMetrics(SM_CXSCREEN);
1785 height = GetSystemMetrics(SM_CYSCREEN);
1786 ok(width == orig_width, "Screen width is %d\n", width);
1787 ok(height == orig_height, "Screen height is %d\n", height);
1789 ZeroMemory(&vp, sizeof(vp));
1790 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1791 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1792 if(SUCCEEDED(hr))
1794 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1795 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1796 ok(vp.Width == 400, "D3DVIEWPORT->Width = %d\n", vp.Width);
1797 ok(vp.Height == 300, "D3DVIEWPORT->Height = %d\n", vp.Height);
1798 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1799 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1802 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1803 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1804 if(SUCCEEDED(hr))
1806 ZeroMemory(&d3dpp, sizeof(d3dpp));
1807 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1808 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1809 if(SUCCEEDED(hr))
1811 ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1812 ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1814 IDirect3DSwapChain9_Release(pSwapchain);
1817 winrect.left = 0;
1818 winrect.top = 0;
1819 winrect.right = 200;
1820 winrect.bottom = 150;
1821 ok(AdjustWindowRect(&winrect, WS_OVERLAPPEDWINDOW, FALSE), "AdjustWindowRect failed\n");
1822 ok(SetWindowPos(hwnd, NULL, 0, 0,
1823 winrect.right-winrect.left,
1824 winrect.bottom-winrect.top,
1825 SWP_NOMOVE|SWP_NOZORDER),
1826 "SetWindowPos failed\n");
1828 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1829 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1830 d3dpp.Windowed = TRUE;
1831 d3dpp.BackBufferWidth = 0;
1832 d3dpp.BackBufferHeight = 0;
1833 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1834 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1835 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1836 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1838 ZeroMemory(&vp, sizeof(vp));
1839 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1840 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1841 if(SUCCEEDED(hr))
1843 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1844 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1845 ok(vp.Width == 200, "D3DVIEWPORT->Width = %d\n", vp.Width);
1846 ok(vp.Height == 150, "D3DVIEWPORT->Height = %d\n", vp.Height);
1847 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1848 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1851 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1852 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1853 if(SUCCEEDED(hr))
1855 ZeroMemory(&d3dpp, sizeof(d3dpp));
1856 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1857 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1858 if(SUCCEEDED(hr))
1860 ok(d3dpp.BackBufferWidth == 200, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1861 ok(d3dpp.BackBufferHeight == 150, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1863 IDirect3DSwapChain9_Release(pSwapchain);
1866 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1867 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1868 d3dpp.Windowed = TRUE;
1869 d3dpp.BackBufferWidth = 400;
1870 d3dpp.BackBufferHeight = 300;
1872 /* _Reset fails if there is a resource in the default pool */
1873 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1874 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1875 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1876 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1877 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1878 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1879 IDirect3DSurface9_Release(surface);
1880 /* Reset again to get the device out of the lost state */
1881 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1882 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1883 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1884 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1886 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1888 IDirect3DVolumeTexture9 *volume_texture;
1890 hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
1891 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1892 ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#x.\n", hr);
1893 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1894 ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
1895 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1896 ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n",
1897 hr, D3DERR_DEVICENOTRESET);
1898 IDirect3DVolumeTexture9_Release(volume_texture);
1899 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1900 ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
1901 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1902 ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#x.\n", hr);
1904 else
1906 skip("Volume textures not supported.\n");
1909 /* Scratch, sysmem and managed pools are fine */
1910 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1911 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1912 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1913 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1914 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1915 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1916 IDirect3DSurface9_Release(surface);
1918 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1919 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1920 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1921 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1922 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1923 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1924 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1925 IDirect3DSurface9_Release(surface);
1927 /* The depth stencil should get reset to the auto depth stencil when present. */
1928 hr = IDirect3DDevice9_SetDepthStencilSurface(device1, NULL);
1929 ok(hr == D3D_OK, "SetDepthStencilSurface failed with 0x%08x\n", hr);
1931 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1932 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1933 ok(surface == NULL, "Depth stencil should be NULL\n");
1935 d3dpp.EnableAutoDepthStencil = TRUE;
1936 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1937 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1938 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1940 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1941 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1942 ok(surface != NULL, "Depth stencil should not be NULL\n");
1943 if (surface) IDirect3DSurface9_Release(surface);
1945 d3dpp.EnableAutoDepthStencil = FALSE;
1946 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1947 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1949 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1950 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1951 ok(surface == NULL, "Depth stencil should be NULL\n");
1953 /* Will a sysmem or scratch survive while locked */
1954 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1955 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1956 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1957 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1958 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1959 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1960 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1961 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1962 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1963 IDirect3DSurface9_UnlockRect(surface);
1964 IDirect3DSurface9_Release(surface);
1966 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1967 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1968 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1969 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1970 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1971 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1972 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1973 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1974 IDirect3DSurface9_UnlockRect(surface);
1975 IDirect3DSurface9_Release(surface);
1977 hr = IDirect3DDevice9_CreateTexture(device1, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
1978 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
1979 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1980 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1981 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1982 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1983 IDirect3DTexture9_Release(texture);
1985 /* A reference held to an implicit surface causes failures as well */
1986 hr = IDirect3DDevice9_GetBackBuffer(device1, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1987 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr);
1988 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1989 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1990 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1991 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1992 IDirect3DSurface9_Release(surface);
1993 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1994 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1995 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1996 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1998 /* Shaders are fine as well */
1999 hr = IDirect3DDevice9_CreateVertexShader(device1, simple_vs, &shader);
2000 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2001 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2002 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2003 IDirect3DVertexShader9_Release(shader);
2005 /* Try setting invalid modes */
2006 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2007 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2008 d3dpp.Windowed = FALSE;
2009 d3dpp.BackBufferWidth = 32;
2010 d3dpp.BackBufferHeight = 32;
2011 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2012 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr);
2013 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2014 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2016 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2017 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2018 d3dpp.Windowed = FALSE;
2019 d3dpp.BackBufferWidth = 801;
2020 d3dpp.BackBufferHeight = 600;
2021 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2022 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr);
2023 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2024 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2026 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2027 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2028 d3dpp.Windowed = FALSE;
2029 d3dpp.BackBufferWidth = 0;
2030 d3dpp.BackBufferHeight = 0;
2031 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2032 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=0, h=0, windowed=FALSE failed with %08x\n", hr);
2033 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2034 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2036 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2038 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2039 d3dpp.Windowed = TRUE;
2040 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2041 d3dpp.BackBufferFormat = d3ddm.Format;
2042 d3dpp.EnableAutoDepthStencil = FALSE;
2043 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2045 if (FAILED(hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2046 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2)))
2048 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
2049 goto cleanup;
2052 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
2053 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
2055 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2056 d3dpp.Windowed = TRUE;
2057 d3dpp.BackBufferWidth = 400;
2058 d3dpp.BackBufferHeight = 300;
2059 d3dpp.EnableAutoDepthStencil = TRUE;
2060 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2062 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
2063 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
2065 if (FAILED(hr)) goto cleanup;
2067 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
2068 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
2069 ok(surface != NULL, "Depth stencil should not be NULL\n");
2070 if (surface) IDirect3DSurface9_Release(surface);
2072 cleanup:
2073 HeapFree(GetProcessHeap(), 0, modes);
2074 if (device2)
2076 UINT refcount = IDirect3DDevice9_Release(device2);
2077 ok(!refcount, "Device has %u references left.\n", refcount);
2079 if (device1)
2081 UINT refcount = IDirect3DDevice9_Release(device1);
2082 ok(!refcount, "Device has %u references left.\n", refcount);
2084 IDirect3D9_Release(d3d);
2085 DestroyWindow(hwnd);
2088 /* Test adapter display modes */
2089 static void test_display_modes(void)
2091 D3DDISPLAYMODE dmode;
2092 IDirect3D9 *d3d;
2094 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2095 ok(!!d3d, "Failed to create a D3D object.\n");
2097 #define TEST_FMT(x,r) do { \
2098 HRESULT res = IDirect3D9_EnumAdapterModes(d3d, 0, (x), 0, &dmode); \
2099 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
2100 } while(0)
2102 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
2103 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
2104 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2105 /* D3DFMT_R5G6B5 */
2106 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
2107 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
2108 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
2109 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
2110 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
2111 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
2112 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
2113 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
2114 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
2115 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2116 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
2117 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
2119 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
2120 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
2122 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
2123 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
2124 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
2126 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
2127 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
2128 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
2129 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
2130 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
2131 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
2133 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
2134 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
2135 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
2136 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
2137 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
2138 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
2139 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
2140 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
2141 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
2142 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
2144 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
2145 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
2146 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
2147 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
2148 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
2149 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
2150 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
2151 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
2152 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
2153 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
2155 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
2156 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
2157 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
2158 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
2159 /* Floating point formats */
2160 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
2161 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
2162 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
2164 /* IEEE formats */
2165 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
2166 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
2167 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
2169 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
2171 TEST_FMT(0, D3DERR_INVALIDCALL);
2173 IDirect3D9_Release(d3d);
2176 static void test_scene(void)
2178 IDirect3DSurface9 *surface1, *surface2, *surface3;
2179 IDirect3DSurface9 *backBuffer, *rt, *ds;
2180 RECT rect = {0, 0, 128, 128};
2181 IDirect3DDevice9 *device;
2182 IDirect3D9 *d3d;
2183 ULONG refcount;
2184 D3DCAPS9 caps;
2185 HWND window;
2186 HRESULT hr;
2188 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2189 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2190 ok(!!window, "Failed to create a window.\n");
2191 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2192 ok(!!d3d, "Failed to create a D3D object.\n");
2193 if (!(device = create_device(d3d, window, NULL)))
2195 skip("Failed to create a 3D device, skipping test.\n");
2196 goto cleanup;
2199 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
2200 memset(&caps, 0, sizeof(caps));
2201 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2202 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
2204 /* Test an EndScene without BeginScene. Should return an error */
2205 hr = IDirect3DDevice9_EndScene(device);
2206 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2208 /* Test a normal BeginScene / EndScene pair, this should work */
2209 hr = IDirect3DDevice9_BeginScene(device);
2210 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2211 hr = IDirect3DDevice9_EndScene(device);
2212 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2214 /* Test another EndScene without having begun a new scene. Should return an error */
2215 hr = IDirect3DDevice9_EndScene(device);
2216 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2218 /* Two nested BeginScene and EndScene calls */
2219 hr = IDirect3DDevice9_BeginScene(device);
2220 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2221 hr = IDirect3DDevice9_BeginScene(device);
2222 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
2223 hr = IDirect3DDevice9_EndScene(device);
2224 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2225 hr = IDirect3DDevice9_EndScene(device);
2226 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2228 /* Create some surfaces to test stretchrect between the scenes */
2229 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2230 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface1, NULL);
2231 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2232 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2233 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface2, NULL);
2234 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2235 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 800, 600,
2236 D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &surface3, NULL);
2237 ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
2238 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
2239 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
2240 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
2242 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
2243 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
2244 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
2245 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
2247 /* First make sure a simple StretchRect call works */
2248 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2249 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2250 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2251 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2252 if (0) /* Disabled for now because it crashes in wine */
2254 HRESULT expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
2255 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2256 ok(hr == expected, "Got unexpected hr %#x, expected %#x.\n", hr, expected);
2259 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a
2260 * BeginScene - Endscene pair with normal surfaces and render targets, but
2261 * not depth stencil surfaces. */
2262 hr = IDirect3DDevice9_BeginScene(device);
2263 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2265 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2266 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2267 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2268 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2269 /* This is supposed to fail inside a BeginScene - EndScene pair. */
2270 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2271 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
2273 hr = IDirect3DDevice9_EndScene(device);
2274 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2276 /* Does a SetRenderTarget influence BeginScene / EndScene ?
2277 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
2278 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
2280 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
2281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
2282 hr = IDirect3DDevice9_BeginScene(device);
2283 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2284 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backBuffer);
2285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
2286 hr = IDirect3DDevice9_EndScene(device);
2287 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2289 IDirect3DSurface9_Release(rt);
2290 IDirect3DSurface9_Release(ds);
2291 IDirect3DSurface9_Release(backBuffer);
2292 IDirect3DSurface9_Release(surface1);
2293 IDirect3DSurface9_Release(surface2);
2294 IDirect3DSurface9_Release(surface3);
2295 refcount = IDirect3DDevice9_Release(device);
2296 ok(!refcount, "Device has %u references left.\n", refcount);
2297 cleanup:
2298 IDirect3D9_Release(d3d);
2299 DestroyWindow(window);
2302 static void test_limits(void)
2304 IDirect3DTexture9 *texture;
2305 IDirect3DDevice9 *device;
2306 IDirect3D9 *d3d;
2307 unsigned int i;
2308 ULONG refcount;
2309 HWND window;
2310 HRESULT hr;
2312 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2313 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2314 ok(!!window, "Failed to create a window.\n");
2315 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2316 ok(!!d3d, "Failed to create a D3D object.\n");
2317 if (!(device = create_device(d3d, window, NULL)))
2319 skip("Failed to create a 3D device, skipping test.\n");
2320 goto cleanup;
2323 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
2324 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2326 /* There are 16 pixel samplers. We should be able to access all of them */
2327 for (i = 0; i < 16; ++i)
2329 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture);
2330 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
2331 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2332 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
2333 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_SRGBTEXTURE, TRUE);
2334 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
2337 /* Now test all 8 textures stage states */
2338 for (i = 0; i < 8; ++i)
2340 hr = IDirect3DDevice9_SetTextureStageState(device, i, D3DTSS_COLOROP, D3DTOP_ADD);
2341 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
2344 /* Investigations show that accessing higher samplers / textures stage
2345 * states does not return an error either. Writing to too high samplers
2346 * (approximately sampler 40) causes memory corruption in Windows, so
2347 * there is no bounds checking. */
2348 IDirect3DTexture9_Release(texture);
2349 refcount = IDirect3D9_Release(device);
2350 ok(!refcount, "Device has %u references left.\n", refcount);
2351 cleanup:
2352 IDirect3D9_Release(d3d);
2353 DestroyWindow(window);
2356 static void test_depthstenciltest(void)
2358 HRESULT hr;
2359 IDirect3DDevice9 *pDevice = NULL;
2360 D3DPRESENT_PARAMETERS d3dpp;
2361 D3DDISPLAYMODE d3ddm;
2362 IDirect3DSurface9 *pDepthStencil = NULL;
2363 IDirect3DSurface9 *pDepthStencil2 = NULL;
2364 IDirect3D9 *d3d;
2365 DWORD state;
2366 HWND hwnd;
2368 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2369 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2370 ok(!!hwnd, "Failed to create a window.\n");
2371 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2372 ok(!!d3d, "Failed to create a D3D object.\n");
2374 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2375 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2376 d3dpp.Windowed = TRUE;
2377 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2378 d3dpp.BackBufferWidth = 800;
2379 d3dpp.BackBufferHeight = 600;
2380 d3dpp.BackBufferFormat = d3ddm.Format;
2381 d3dpp.EnableAutoDepthStencil = TRUE;
2382 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2384 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2385 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2386 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || broken(hr == D3DERR_INVALIDCALL), "IDirect3D9_CreateDevice failed with %08x\n", hr);
2387 if(!pDevice)
2389 skip("Failed to create a d3d device\n");
2390 goto cleanup;
2393 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2394 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
2396 /* Try to clear */
2397 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2398 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2400 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
2401 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
2403 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
2404 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
2405 ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
2406 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
2408 /* This left the render states untouched! */
2409 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2410 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2411 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2412 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
2413 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2414 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
2415 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
2416 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2417 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
2418 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
2419 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2420 ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
2422 /* This is supposed to fail now */
2423 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2424 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2426 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
2427 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
2429 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
2430 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
2432 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2433 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2434 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2436 /* Now it works again */
2437 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2438 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2440 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2441 if(pDevice) IDirect3D9_Release(pDevice);
2443 /* Now see if autodepthstencil disable is honored. First, without a format set */
2444 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2445 d3dpp.Windowed = TRUE;
2446 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2447 d3dpp.BackBufferWidth = 800;
2448 d3dpp.BackBufferHeight = 600;
2449 d3dpp.BackBufferFormat = d3ddm.Format;
2450 d3dpp.EnableAutoDepthStencil = FALSE;
2451 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2453 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2454 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2455 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2456 if(!pDevice)
2458 skip("Failed to create a d3d device\n");
2459 goto cleanup;
2462 pDepthStencil = NULL;
2463 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2464 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
2465 if(pDepthStencil) {
2466 IDirect3DSurface9_Release(pDepthStencil);
2467 pDepthStencil = NULL;
2470 /* Check the depth test state */
2471 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2472 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2473 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2475 if(pDevice) IDirect3D9_Release(pDevice);
2477 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
2478 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2479 d3dpp.Windowed = TRUE;
2480 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2481 d3dpp.BackBufferWidth = 800;
2482 d3dpp.BackBufferHeight = 600;
2483 d3dpp.BackBufferFormat = d3ddm.Format;
2484 d3dpp.EnableAutoDepthStencil = FALSE;
2485 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2487 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2488 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2489 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2490 if(!pDevice)
2492 skip("Failed to create a d3d device\n");
2493 goto cleanup;
2496 pDepthStencil = NULL;
2497 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2498 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
2499 if(pDepthStencil) {
2500 IDirect3DSurface9_Release(pDepthStencil);
2501 pDepthStencil = NULL;
2504 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2505 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2506 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2508 cleanup:
2509 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2510 if (pDevice)
2512 UINT refcount = IDirect3D9_Release(pDevice);
2513 ok(!refcount, "Device has %u references left.\n", refcount);
2515 IDirect3D9_Release(d3d);
2516 DestroyWindow(hwnd);
2519 static void test_get_rt(void)
2521 IDirect3DSurface9 *backbuffer, *rt;
2522 IDirect3DDevice9 *device;
2523 IDirect3D9 *d3d9;
2524 D3DCAPS9 caps;
2525 HWND window;
2526 HRESULT hr;
2527 ULONG ref;
2528 UINT i;
2530 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2531 0, 0, 128, 128, 0, 0, 0, 0);
2532 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2533 ok(!!d3d9, "Failed to create a D3D object.\n");
2534 device = create_device(d3d9, window, NULL);
2535 if (!device)
2537 skip("Failed to create a D3D device, skipping tests.\n");
2538 goto done;
2541 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
2542 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
2543 ok(!!backbuffer, "Got a NULL backbuffer.\n");
2545 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2546 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2548 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
2550 rt = backbuffer;
2551 hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
2552 ok(hr == D3DERR_NOTFOUND, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr);
2553 ok(!rt, "Got rt %p.\n", rt);
2556 IDirect3DSurface9_Release(backbuffer);
2558 ref = IDirect3DDevice9_Release(device);
2559 ok(!ref, "The device was not properly freed: refcount %u.\n", ref);
2560 done:
2561 IDirect3D9_Release(d3d9);
2562 DestroyWindow(window);
2565 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
2566 static void test_draw_indexed(void)
2568 static const struct {
2569 float position[3];
2570 DWORD color;
2571 } quad[] = {
2572 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2573 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2574 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2575 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2577 WORD indices[] = {0, 1, 2, 3, 0, 2};
2579 static const D3DVERTEXELEMENT9 decl_elements[] = {
2580 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2581 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2582 D3DDECL_END()
2585 IDirect3DVertexDeclaration9 *vertex_declaration;
2586 IDirect3DVertexBuffer9 *vertex_buffer;
2587 IDirect3DIndexBuffer9 *index_buffer;
2588 IDirect3DDevice9 *device;
2589 IDirect3D9 *d3d9;
2590 ULONG refcount;
2591 HWND window;
2592 HRESULT hr;
2593 void *ptr;
2595 window = CreateWindowA("d3d9_test_wc", "d3d9_test", 0,
2596 0, 0, 640, 480, 0, 0, 0, 0);
2597 ok(!!window, "Failed to create a window.\n");
2598 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2599 ok(!!d3d9, "Failed to create a D3D object.\n");
2600 if (!(device = create_device(d3d9, window, NULL)))
2602 skip("Failed to create a 3D device, skipping test.\n");
2603 goto cleanup;
2606 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2607 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2608 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2609 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2611 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
2612 ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
2613 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
2614 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
2615 memcpy(ptr, quad, sizeof(quad));
2616 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
2617 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
2618 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
2619 ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
2621 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
2622 ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
2623 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
2624 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
2625 memcpy(ptr, indices, sizeof(indices));
2626 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
2627 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
2628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2629 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
2630 hr = IDirect3DDevice9_BeginScene(device);
2631 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2633 /* NULL index buffer. Should fail */
2634 hr = IDirect3DDevice9_SetIndices(device, NULL);
2635 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
2636 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2637 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2638 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
2639 hr, D3DERR_INVALIDCALL);
2641 /* Valid index buffer, NULL vertex declaration. Should fail */
2642 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
2643 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
2644 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2645 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2646 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
2647 hr, D3DERR_INVALIDCALL);
2649 /* Valid index buffer and vertex declaration. Should succeed */
2650 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2651 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2652 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2653 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2654 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
2656 hr = IDirect3DDevice9_EndScene(device);
2657 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2660 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2662 IDirect3DVertexBuffer9_Release(vertex_buffer);
2663 IDirect3DIndexBuffer9_Release(index_buffer);
2664 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2665 refcount = IDirect3DDevice9_Release(device);
2666 ok(!refcount, "Device has %u references left.\n", refcount);
2667 cleanup:
2668 IDirect3D9_Release(d3d9);
2669 DestroyWindow(window);
2672 static void test_null_stream(void)
2674 IDirect3DVertexBuffer9 *buffer = NULL;
2675 IDirect3DDevice9 *device;
2676 IDirect3D9 *d3d9;
2677 ULONG refcount;
2678 HWND window;
2679 HRESULT hr;
2680 IDirect3DVertexShader9 *shader = NULL;
2681 IDirect3DVertexDeclaration9 *decl = NULL;
2682 static const DWORD shader_code[] =
2684 0xfffe0101, /* vs_1_1 */
2685 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2686 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2687 0x0000ffff /* end */
2689 static const D3DVERTEXELEMENT9 decl_elements[] = {
2690 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2691 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2692 D3DDECL_END()
2695 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2696 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2697 ok(!!window, "Failed to create a window.\n");
2698 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2699 ok(!!d3d9, "Failed to create a D3D object.\n");
2700 if (!(device = create_device(d3d9, window, NULL)))
2702 skip("Failed to create a 3D device, skipping test.\n");
2703 goto cleanup;
2706 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2707 if(FAILED(hr)) {
2708 skip("No vertex shader support\n");
2709 goto cleanup;
2711 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2712 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2713 if (FAILED(hr)) {
2714 skip("Vertex declaration handling not possible.\n");
2715 goto cleanup;
2717 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
2718 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
2719 if (FAILED(hr)) {
2720 skip("Vertex buffer handling not possible.\n");
2721 goto cleanup;
2724 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
2725 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2726 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
2727 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2728 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2729 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
2730 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2731 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
2733 hr = IDirect3DDevice9_BeginScene(device);
2734 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2735 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
2736 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2737 hr = IDirect3DDevice9_EndScene(device);
2738 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2740 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2741 IDirect3DDevice9_SetVertexShader(device, NULL);
2742 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2744 cleanup:
2745 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2746 if (decl) IDirect3DVertexDeclaration9_Release(decl);
2747 if (shader) IDirect3DVertexShader9_Release(shader);
2748 if (device)
2750 refcount = IDirect3DDevice9_Release(device);
2751 ok(!refcount, "Device has %u references left.\n", refcount);
2753 IDirect3D9_Release(d3d9);
2754 DestroyWindow(window);
2757 static void test_lights(void)
2759 IDirect3DDevice9 *device;
2760 IDirect3D9 *d3d9;
2761 ULONG refcount;
2762 HWND window;
2763 HRESULT hr;
2764 unsigned int i;
2765 BOOL enabled;
2766 D3DCAPS9 caps;
2768 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2769 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2770 ok(!!window, "Failed to create a window.\n");
2771 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2772 ok(!!d3d9, "Failed to create a D3D object.\n");
2773 if (!(device = create_device(d3d9, window, NULL)))
2775 skip("Failed to create a 3D device, skipping test.\n");
2776 goto cleanup;
2779 memset(&caps, 0, sizeof(caps));
2780 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2781 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
2783 for(i = 1; i <= caps.MaxActiveLights; i++) {
2784 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
2785 ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
2786 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
2787 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
2788 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
2791 /* TODO: Test the rendering results in this situation */
2792 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
2793 ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
2794 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
2795 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
2796 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
2797 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
2798 ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
2800 for(i = 1; i <= caps.MaxActiveLights; i++) {
2801 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
2802 ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
2805 refcount = IDirect3DDevice9_Release(device);
2806 ok(!refcount, "Device has %u references left.\n", refcount);
2807 cleanup:
2808 IDirect3D9_Release(d3d9);
2809 DestroyWindow(window);
2812 static void test_set_stream_source(void)
2814 IDirect3DVertexBuffer9 *vb;
2815 IDirect3DDevice9 *device;
2816 IDirect3D9 *d3d9;
2817 ULONG refcount;
2818 HWND window;
2819 HRESULT hr;
2821 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2822 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2823 ok(!!window, "Failed to create a window.\n");
2824 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2825 ok(!!d3d9, "Failed to create a D3D object.\n");
2826 if (!(device = create_device(d3d9, window, NULL)))
2828 skip("Failed to create a 3D device, skipping test.\n");
2829 goto cleanup;
2832 hr = IDirect3DDevice9_CreateVertexBuffer(device, 512, 0, 0, D3DPOOL_DEFAULT, &vb, NULL);
2833 ok(SUCCEEDED(hr), "Failed to create a vertex buffer, hr %#x.\n", hr);
2835 /* Some cards (GeForce 7400 at least) accept non-aligned offsets, others
2836 * (Radeon 9000 verified) reject them, so accept both results. Wine
2837 * currently rejects this to be able to optimize the vbo conversion, but
2838 * writes a WARN. */
2839 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, 32);
2840 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2841 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 1, 32);
2842 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2843 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 2, 32);
2844 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2845 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 3, 32);
2846 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2847 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 4, 32);
2848 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2850 /* Try to set the NULL buffer with an offset and stride 0 */
2851 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2852 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2853 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
2854 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2855 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
2856 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2857 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
2858 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2859 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
2860 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2862 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2863 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2865 IDirect3DVertexBuffer9_Release(vb);
2866 refcount = IDirect3DDevice9_Release(device);
2867 ok(!refcount, "Device has %u references left.\n", refcount);
2868 cleanup:
2869 IDirect3D9_Release(d3d9);
2870 DestroyWindow(window);
2873 /* Direct3D9 offers 4 display formats: R5G6B5, X1R5G5B5, X8R8G8B8 and
2874 * A2R10G10B10. Next to these there are 6 different back buffer formats. Only
2875 * a fixed number of combinations are possible in fullscreen mode. In windowed
2876 * mode more combinations are allowed due to format conversion and this is
2877 * likely driver dependent. */
2878 static void test_display_formats(void)
2880 D3DDEVTYPE device_type = D3DDEVTYPE_HAL;
2881 unsigned int backbuffer, display;
2882 unsigned int windowed;
2883 IDirect3D9 *d3d9;
2884 BOOL should_pass;
2885 BOOL has_modes;
2886 HRESULT hr;
2888 static const struct
2890 const char *name;
2891 D3DFORMAT format;
2892 D3DFORMAT alpha_format;
2893 BOOL display;
2894 BOOL windowed;
2896 formats[] =
2898 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, 0, TRUE, TRUE},
2899 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE, TRUE},
2900 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE, FALSE},
2901 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE, TRUE},
2902 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, FALSE},
2903 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, 0, TRUE, FALSE},
2904 {"D3DFMT_UNKNOWN", D3DFMT_UNKNOWN, 0, FALSE, FALSE},
2907 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2908 ok(!!d3d9, "Failed to create a D3D object.\n");
2910 for (display = 0; display < sizeof(formats) / sizeof(*formats); ++display)
2912 has_modes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, formats[display].format);
2914 for (windowed = 0; windowed <= 1; ++windowed)
2916 for (backbuffer = 0; backbuffer < sizeof(formats) / sizeof(*formats); ++backbuffer)
2918 should_pass = FALSE;
2920 if (formats[display].display && (formats[display].windowed || !windowed) && (has_modes || windowed))
2922 D3DFORMAT backbuffer_format;
2924 if (windowed && formats[backbuffer].format == D3DFMT_UNKNOWN)
2925 backbuffer_format = formats[display].format;
2926 else
2927 backbuffer_format = formats[backbuffer].format;
2929 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, device_type, formats[display].format,
2930 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, backbuffer_format);
2931 if (hr == D3D_OK)
2933 if (windowed)
2935 hr = IDirect3D9_CheckDeviceFormatConversion(d3d9, D3DADAPTER_DEFAULT, device_type,
2936 backbuffer_format, formats[display].format);
2937 should_pass = (hr == D3D_OK);
2939 else
2940 should_pass = (formats[display].format == formats[backbuffer].format
2941 || (formats[display].alpha_format
2942 && formats[display].alpha_format == formats[backbuffer].alpha_format));
2946 hr = IDirect3D9_CheckDeviceType(d3d9, D3DADAPTER_DEFAULT, device_type,
2947 formats[display].format, formats[backbuffer].format, windowed);
2948 ok(SUCCEEDED(hr) == should_pass || broken(SUCCEEDED(hr) && !has_modes) /* Win8 64-bit */,
2949 "Got unexpected hr %#x for %s / %s, windowed %#x, should_pass %#x.\n",
2950 hr, formats[display].name, formats[backbuffer].name, windowed, should_pass);
2955 IDirect3D9_Release(d3d9);
2958 static void test_scissor_size(void)
2960 struct device_desc device_desc;
2961 IDirect3D9 *d3d9_ptr;
2962 unsigned int i;
2963 static struct {
2964 int winx; int winy; int backx; int backy; BOOL window;
2965 } scts[] = { /* scissor tests */
2966 {800, 600, 640, 480, TRUE},
2967 {800, 600, 640, 480, FALSE},
2968 {640, 480, 800, 600, TRUE},
2969 {640, 480, 800, 600, FALSE},
2972 d3d9_ptr = Direct3DCreate9(D3D_SDK_VERSION);
2973 ok(!!d3d9_ptr, "Failed to create a D3D object.\n");
2975 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2976 IDirect3DDevice9 *device_ptr = 0;
2977 HRESULT hr;
2978 HWND hwnd = 0;
2979 RECT scissorrect;
2981 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
2982 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
2984 if (!scts[i].window)
2986 scts[i].backx = screen_width;
2987 scts[i].backy = screen_height;
2990 device_desc.device_window = hwnd;
2991 device_desc.width = scts[i].backx;
2992 device_desc.height = scts[i].backy;
2993 device_desc.flags = scts[i].window ? 0 : CREATE_DEVICE_FULLSCREEN;
2994 if (!(device_ptr = create_device(d3d9_ptr, hwnd, &device_desc)))
2996 skip("Failed to create a 3D device, skipping test.\n");
2997 DestroyWindow(hwnd);
2998 goto err_out;
3001 /* Check for the default scissor rect size */
3002 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
3003 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
3004 ok(scissorrect.right == scts[i].backx && scissorrect.bottom == scts[i].backy && scissorrect.top == 0 && scissorrect.left == 0, "Scissorrect missmatch (%d, %d) should be (%d, %d)\n", scissorrect.right, scissorrect.bottom, scts[i].backx, scts[i].backy);
3006 /* check the scissorrect values after a reset */
3007 hr = reset_device(device_ptr, hwnd, scts[i].window);
3008 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
3009 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
3010 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
3012 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
3013 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
3014 ok(scissorrect.right == screen_width && scissorrect.bottom == screen_height && scissorrect.top == 0 && scissorrect.left == 0, "Scissorrect missmatch (%d, %d) should be (%d, %d)\n", scissorrect.right, scissorrect.bottom, screen_width, screen_height);
3016 if(device_ptr) {
3017 ULONG ref;
3019 ref = IDirect3DDevice9_Release(device_ptr);
3020 DestroyWindow(hwnd);
3021 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
3025 err_out:
3026 IDirect3D9_Release(d3d9_ptr);
3029 static void test_multi_device(void)
3031 IDirect3DDevice9 *device1, *device2;
3032 HWND window1, window2;
3033 IDirect3D9 *d3d9;
3034 ULONG refcount;
3036 window1 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3037 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3038 ok(!!window1, "Failed to create a window.\n");
3039 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3040 ok(!!d3d9, "Failed to create a D3D object.\n");
3041 if (!(device1 = create_device(d3d9, window1, NULL)))
3043 skip("Failed to create a 3D device, skipping test.\n");
3044 IDirect3D9_Release(d3d9);
3045 DestroyWindow(window1);
3046 return;
3048 IDirect3D9_Release(d3d9);
3050 window2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3051 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3052 ok(!!window2, "Failed to create a window.\n");
3053 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3054 ok(!!d3d9, "Failed to create a D3D object.\n");
3055 device2 = create_device(d3d9, window2, NULL);
3056 IDirect3D9_Release(d3d9);
3058 refcount = IDirect3DDevice9_Release(device2);
3059 ok(!refcount, "Device has %u references left.\n", refcount);
3060 refcount = IDirect3DDevice9_Release(device1);
3061 ok(!refcount, "Device has %u references left.\n", refcount);
3062 DestroyWindow(window2);
3063 DestroyWindow(window1);
3066 static HWND filter_messages;
3068 enum message_window
3070 DEVICE_WINDOW,
3071 FOCUS_WINDOW,
3074 struct message
3076 UINT message;
3077 enum message_window window;
3080 static const struct message *expect_messages;
3081 static HWND device_window, focus_window;
3083 struct wndproc_thread_param
3085 HWND dummy_window;
3086 HANDLE window_created;
3087 HANDLE test_finished;
3088 BOOL running_in_foreground;
3091 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3093 if (filter_messages && filter_messages == hwnd)
3095 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
3096 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
3099 if (expect_messages)
3101 HWND w;
3103 switch (expect_messages->window)
3105 case DEVICE_WINDOW:
3106 w = device_window;
3107 break;
3109 case FOCUS_WINDOW:
3110 w = focus_window;
3111 break;
3113 default:
3114 w = NULL;
3115 break;
3118 if (hwnd == w && expect_messages->message == message) ++expect_messages;
3121 return DefWindowProcA(hwnd, message, wparam, lparam);
3124 static DWORD WINAPI wndproc_thread(void *param)
3126 struct wndproc_thread_param *p = param;
3127 DWORD res;
3128 BOOL ret;
3130 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3131 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3132 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
3134 ret = SetEvent(p->window_created);
3135 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
3137 for (;;)
3139 MSG msg;
3141 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
3142 res = WaitForSingleObject(p->test_finished, 100);
3143 if (res == WAIT_OBJECT_0) break;
3144 if (res != WAIT_TIMEOUT)
3146 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3147 break;
3151 DestroyWindow(p->dummy_window);
3153 return 0;
3156 static void test_wndproc(void)
3158 struct wndproc_thread_param thread_params;
3159 struct device_desc device_desc;
3160 IDirect3DDevice9 *device;
3161 WNDCLASSA wc = {0};
3162 IDirect3D9 *d3d9;
3163 HANDLE thread;
3164 LONG_PTR proc;
3165 ULONG ref;
3166 DWORD res, tid;
3167 HWND tmp;
3169 static const struct message messages[] =
3171 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
3172 {WM_ACTIVATE, FOCUS_WINDOW},
3173 {WM_SETFOCUS, FOCUS_WINDOW},
3174 {0, 0},
3177 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3178 ok(!!d3d9, "Failed to create a D3D object.\n");
3180 wc.lpfnWndProc = test_proc;
3181 wc.lpszClassName = "d3d9_test_wndproc_wc";
3182 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3184 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3185 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3186 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3187 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3189 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3190 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3191 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3192 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3193 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3194 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3196 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3197 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3199 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3200 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3201 (LONG_PTR)test_proc, proc);
3202 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3203 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3204 (LONG_PTR)test_proc, proc);
3206 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3207 device_window, focus_window, thread_params.dummy_window);
3209 tmp = GetFocus();
3210 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3211 if (thread_params.running_in_foreground)
3213 tmp = GetForegroundWindow();
3214 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3215 thread_params.dummy_window, tmp);
3217 else
3218 skip("Not running in foreground, skip foreground window test\n");
3220 flush_events();
3222 expect_messages = messages;
3224 device_desc.device_window = device_window;
3225 device_desc.width = screen_width;
3226 device_desc.height = screen_height;
3227 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3228 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3230 skip("Failed to create a D3D device, skipping tests.\n");
3231 goto done;
3234 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
3235 expect_messages->message, expect_messages->window);
3236 expect_messages = NULL;
3238 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
3240 tmp = GetFocus();
3241 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
3242 tmp = GetForegroundWindow();
3243 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
3245 SetForegroundWindow(focus_window);
3246 flush_events();
3248 filter_messages = focus_window;
3250 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3251 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3252 (LONG_PTR)test_proc, proc);
3254 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3255 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3256 (LONG_PTR)test_proc, proc);
3258 ref = IDirect3DDevice9_Release(device);
3259 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3261 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3262 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3263 (LONG_PTR)test_proc, proc);
3265 device_desc.device_window = focus_window;
3266 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3268 skip("Failed to create a D3D device, skipping tests.\n");
3269 goto done;
3272 ref = IDirect3DDevice9_Release(device);
3273 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3275 device_desc.device_window = device_window;
3276 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3278 skip("Failed to create a D3D device, skipping tests.\n");
3279 goto done;
3282 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3283 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3284 (LONG_PTR)test_proc, proc);
3286 ref = IDirect3DDevice9_Release(device);
3287 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3289 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3290 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3291 (LONG_PTR)DefWindowProcA, proc);
3293 done:
3294 filter_messages = NULL;
3295 IDirect3D9_Release(d3d9);
3297 SetEvent(thread_params.test_finished);
3298 WaitForSingleObject(thread, INFINITE);
3299 CloseHandle(thread_params.test_finished);
3300 CloseHandle(thread_params.window_created);
3301 CloseHandle(thread);
3303 DestroyWindow(device_window);
3304 DestroyWindow(focus_window);
3305 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3308 static void test_wndproc_windowed(void)
3310 struct wndproc_thread_param thread_params;
3311 struct device_desc device_desc;
3312 IDirect3DDevice9 *device;
3313 WNDCLASSA wc = {0};
3314 IDirect3D9 *d3d9;
3315 HANDLE thread;
3316 LONG_PTR proc;
3317 HRESULT hr;
3318 ULONG ref;
3319 DWORD res, tid;
3320 HWND tmp;
3322 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3323 ok(!!d3d9, "Failed to create a D3D object.\n");
3325 wc.lpfnWndProc = test_proc;
3326 wc.lpszClassName = "d3d9_test_wndproc_wc";
3327 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3329 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3330 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3331 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3332 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3334 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3335 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3336 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3337 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3338 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3339 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3341 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3342 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3344 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3345 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3346 (LONG_PTR)test_proc, proc);
3347 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3348 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3349 (LONG_PTR)test_proc, proc);
3351 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3352 device_window, focus_window, thread_params.dummy_window);
3354 tmp = GetFocus();
3355 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3356 if (thread_params.running_in_foreground)
3358 tmp = GetForegroundWindow();
3359 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3360 thread_params.dummy_window, tmp);
3362 else
3363 skip("Not running in foreground, skip foreground window test\n");
3365 filter_messages = focus_window;
3367 device_desc.device_window = device_window;
3368 device_desc.width = 640;
3369 device_desc.height = 480;
3370 device_desc.flags = 0;
3371 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3373 skip("Failed to create a D3D device, skipping tests.\n");
3374 goto done;
3377 tmp = GetFocus();
3378 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3379 tmp = GetForegroundWindow();
3380 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3381 thread_params.dummy_window, tmp);
3383 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3384 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3385 (LONG_PTR)test_proc, proc);
3387 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3388 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3389 (LONG_PTR)test_proc, proc);
3391 filter_messages = NULL;
3393 hr = reset_device(device, device_window, FALSE);
3394 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3396 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3397 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3398 (LONG_PTR)test_proc, proc);
3400 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3401 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3402 (LONG_PTR)test_proc, proc);
3404 hr = reset_device(device, device_window, TRUE);
3405 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3407 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3408 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3409 (LONG_PTR)test_proc, proc);
3411 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3412 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3413 (LONG_PTR)test_proc, proc);
3415 filter_messages = focus_window;
3417 ref = IDirect3DDevice9_Release(device);
3418 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3420 filter_messages = device_window;
3422 device_desc.device_window = focus_window;
3423 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3425 skip("Failed to create a D3D device, skipping tests.\n");
3426 goto done;
3429 filter_messages = NULL;
3431 hr = reset_device(device, focus_window, FALSE);
3432 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3434 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3435 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3436 (LONG_PTR)test_proc, proc);
3438 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3439 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3440 (LONG_PTR)test_proc, proc);
3442 hr = reset_device(device, focus_window, TRUE);
3443 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3445 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3446 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3447 (LONG_PTR)test_proc, proc);
3449 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3450 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3451 (LONG_PTR)test_proc, proc);
3453 filter_messages = device_window;
3455 ref = IDirect3DDevice9_Release(device);
3456 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3458 device_desc.device_window = device_window;
3459 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3461 skip("Failed to create a D3D device, skipping tests.\n");
3462 goto done;
3465 filter_messages = NULL;
3467 hr = reset_device(device, device_window, FALSE);
3468 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3470 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3471 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3472 (LONG_PTR)test_proc, proc);
3474 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3475 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3476 (LONG_PTR)test_proc, proc);
3478 hr = reset_device(device, device_window, TRUE);
3479 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3481 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3482 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3483 (LONG_PTR)test_proc, proc);
3485 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3486 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3487 (LONG_PTR)test_proc, proc);
3489 filter_messages = device_window;
3491 ref = IDirect3DDevice9_Release(device);
3492 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3494 done:
3495 filter_messages = NULL;
3496 IDirect3D9_Release(d3d9);
3498 SetEvent(thread_params.test_finished);
3499 WaitForSingleObject(thread, INFINITE);
3500 CloseHandle(thread_params.test_finished);
3501 CloseHandle(thread_params.window_created);
3502 CloseHandle(thread);
3504 DestroyWindow(device_window);
3505 DestroyWindow(focus_window);
3506 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3509 static void test_reset_fullscreen(void)
3511 WNDCLASSEXA wc = {0};
3512 IDirect3DDevice9 *device = NULL;
3513 IDirect3D9 *d3d;
3514 ATOM atom;
3515 static const struct message messages[] =
3517 {WM_ACTIVATEAPP, FOCUS_WINDOW},
3518 {0, 0},
3521 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3522 ok(!!d3d, "Failed to create a D3D object.\n");
3523 expect_messages = messages;
3525 wc.cbSize = sizeof(wc);
3526 wc.lpfnWndProc = test_proc;
3527 wc.lpszClassName = "test_reset_fullscreen";
3529 atom = RegisterClassExA(&wc);
3530 ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
3532 device_window = focus_window = CreateWindowExA(0, wc.lpszClassName, "Test Reset Fullscreen", 0,
3533 0, 0, screen_width, screen_height, NULL, NULL, NULL, NULL);
3534 ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
3537 * Create a device in windowed mode.
3538 * Since the device is windowed and we haven't called any methods that
3539 * could show the window (such as ShowWindow or SetWindowPos) yet,
3540 * WM_ACTIVATEAPP will not have been sent.
3542 if (!(device = create_device(d3d, device_window, NULL)))
3544 skip("Unable to create device. Skipping test.\n");
3545 goto cleanup;
3549 * Switch to fullscreen mode.
3550 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
3551 * message to be sent.
3553 ok(SUCCEEDED(reset_device(device, device_window, FALSE)), "Failed to reset device.\n");
3555 flush_events();
3556 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
3557 expect_messages = NULL;
3559 cleanup:
3560 if (device) IDirect3DDevice9_Release(device);
3561 IDirect3D9_Release(d3d);
3562 DestroyWindow(device_window);
3563 device_window = focus_window = NULL;
3564 UnregisterClassA(wc.lpszClassName, GetModuleHandleA(NULL));
3568 static inline void set_fpu_cw(WORD cw)
3570 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3571 #define D3D9_TEST_SET_FPU_CW 1
3572 __asm__ volatile ("fnclex");
3573 __asm__ volatile ("fldcw %0" : : "m" (cw));
3574 #elif defined(__i386__) && defined(_MSC_VER)
3575 #define D3D9_TEST_SET_FPU_CW 1
3576 __asm fnclex;
3577 __asm fldcw cw;
3578 #endif
3581 static inline WORD get_fpu_cw(void)
3583 WORD cw = 0;
3584 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3585 #define D3D9_TEST_GET_FPU_CW 1
3586 __asm__ volatile ("fnstcw %0" : "=m" (cw));
3587 #elif defined(__i386__) && defined(_MSC_VER)
3588 #define D3D9_TEST_GET_FPU_CW 1
3589 __asm fnstcw cw;
3590 #endif
3591 return cw;
3594 static void test_fpu_setup(void)
3596 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
3597 struct device_desc device_desc;
3598 IDirect3DDevice9 *device;
3599 HWND window = NULL;
3600 IDirect3D9 *d3d9;
3601 WORD cw;
3603 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3604 ok(!!window, "Failed to create a window.\n");
3605 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3606 ok(!!d3d9, "Failed to create a D3D object.\n");
3608 device_desc.device_window = window;
3609 device_desc.width = 640;
3610 device_desc.height = 480;
3611 device_desc.flags = 0;
3613 set_fpu_cw(0xf60);
3614 cw = get_fpu_cw();
3615 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3617 if (!(device = create_device(d3d9, window, &device_desc)))
3619 skip("Failed to create a 3D device, skipping test.\n");
3620 set_fpu_cw(0x37f);
3621 goto done;
3624 cw = get_fpu_cw();
3625 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3627 IDirect3DDevice9_Release(device);
3629 cw = get_fpu_cw();
3630 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3631 set_fpu_cw(0xf60);
3632 cw = get_fpu_cw();
3633 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3635 device_desc.flags = CREATE_DEVICE_FPU_PRESERVE;
3636 device = create_device(d3d9, window, &device_desc);
3637 ok(device != NULL, "CreateDevice failed.\n");
3639 cw = get_fpu_cw();
3640 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3641 set_fpu_cw(0x37f);
3643 IDirect3DDevice9_Release(device);
3645 done:
3646 IDirect3D9_Release(d3d9);
3647 DestroyWindow(window);
3648 #endif
3651 static void test_window_style(void)
3653 RECT focus_rect, device_rect, fullscreen_rect, r, r2;
3654 LONG device_style, device_exstyle;
3655 LONG focus_style, focus_exstyle;
3656 struct device_desc device_desc;
3657 LONG style, expected_style;
3658 IDirect3DDevice9 *device;
3659 IDirect3D9 *d3d9;
3660 HRESULT hr;
3661 ULONG ref;
3662 static const struct
3664 DWORD device_flags;
3665 LONG style, exstyle;
3667 tests[] =
3669 {0, WS_VISIBLE, WS_EX_TOPMOST},
3670 {CREATE_DEVICE_NOWINDOWCHANGES, 0},
3672 unsigned int i;
3674 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3675 ok(!!d3d9, "Failed to create a D3D object.\n");
3676 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3678 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
3680 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3681 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3682 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3683 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3685 device_style = GetWindowLongA(device_window, GWL_STYLE);
3686 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3687 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3688 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3690 GetWindowRect(focus_window, &focus_rect);
3691 GetWindowRect(device_window, &device_rect);
3693 device_desc.device_window = device_window;
3694 device_desc.width = screen_width;
3695 device_desc.height = screen_height;
3696 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
3697 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3699 skip("Failed to create a D3D device, skipping tests.\n");
3700 DestroyWindow(device_window);
3701 DestroyWindow(focus_window);
3702 break;
3705 style = GetWindowLongA(device_window, GWL_STYLE);
3706 expected_style = device_style | tests[i].style;
3707 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3708 expected_style, style, i);
3709 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3710 expected_style = device_exstyle | tests[i].exstyle;
3711 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3712 expected_style, style, i);
3714 style = GetWindowLongA(focus_window, GWL_STYLE);
3715 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3716 focus_style, style, i);
3717 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3718 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3719 focus_exstyle, style, i);
3721 GetWindowRect(device_window, &r);
3722 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3723 todo_wine ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
3724 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
3725 r.left, r.top, r.right, r.bottom, i);
3726 else
3727 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
3728 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3729 r.left, r.top, r.right, r.bottom, i);
3730 GetClientRect(device_window, &r2);
3731 todo_wine ok(!EqualRect(&r, &r2), "Client rect and window rect are equal.\n");
3732 GetWindowRect(focus_window, &r);
3733 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}, i=%u.\n",
3734 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3735 r.left, r.top, r.right, r.bottom, i);
3737 hr = reset_device(device, device_window, TRUE);
3738 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3740 style = GetWindowLongA(device_window, GWL_STYLE);
3741 expected_style = device_style | tests[i].style;
3742 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3743 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3744 expected_style, style, i);
3745 else
3746 ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
3747 expected_style, style, i);
3748 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3749 expected_style = device_exstyle | tests[i].exstyle;
3750 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3751 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3752 expected_style, style, i);
3753 else
3754 ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
3755 expected_style, style, i);
3757 style = GetWindowLongA(focus_window, GWL_STYLE);
3758 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
3759 focus_style, style, i);
3760 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3761 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
3762 focus_exstyle, style, i);
3764 ref = IDirect3DDevice9_Release(device);
3765 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3767 DestroyWindow(device_window);
3768 DestroyWindow(focus_window);
3770 IDirect3D9_Release(d3d9);
3773 static const POINT *expect_pos;
3775 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
3777 if (message == WM_MOUSEMOVE)
3779 if (expect_pos && expect_pos->x && expect_pos->y)
3781 POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
3783 ClientToScreen(window, &p);
3784 if (expect_pos->x == p.x && expect_pos->y == p.y)
3785 ++expect_pos;
3789 return DefWindowProcA(window, message, wparam, lparam);
3792 static void test_cursor_pos(void)
3794 IDirect3DSurface9 *cursor;
3795 IDirect3DDevice9 *device;
3796 WNDCLASSA wc = {0};
3797 IDirect3D9 *d3d9;
3798 UINT refcount;
3799 HWND window;
3800 HRESULT hr;
3801 BOOL ret;
3803 /* Note that we don't check for movement we're not supposed to receive.
3804 * That's because it's hard to distinguish from the user accidentally
3805 * moving the mouse. */
3806 static const POINT points[] =
3808 {50, 50},
3809 {75, 75},
3810 {100, 100},
3811 {125, 125},
3812 {150, 150},
3813 {125, 125},
3814 {150, 150},
3815 {150, 150},
3816 {0, 0},
3819 wc.lpfnWndProc = test_cursor_proc;
3820 wc.lpszClassName = "d3d9_test_cursor_wc";
3821 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3822 window = CreateWindowA("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3823 0, 0, 320, 240, NULL, NULL, NULL, NULL);
3824 ShowWindow(window, SW_SHOW);
3825 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3826 ok(!!d3d9, "Failed to create a D3D object.\n");
3828 device = create_device(d3d9, window, NULL);
3829 if (!device)
3831 skip("Failed to create a D3D device, skipping tests.\n");
3832 goto done;
3835 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3836 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
3837 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
3838 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
3839 ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#x.\n", hr);
3840 IDirect3DSurface9_Release(cursor);
3841 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
3842 ok(!ret, "Failed to show cursor, hr %#x.\n", ret);
3844 flush_events();
3845 expect_pos = points;
3847 ret = SetCursorPos(50, 50);
3848 ok(ret, "Failed to set cursor position.\n");
3849 flush_events();
3851 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3852 flush_events();
3853 /* SetCursorPosition() eats duplicates. */
3854 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3855 flush_events();
3857 ret = SetCursorPos(100, 100);
3858 ok(ret, "Failed to set cursor position.\n");
3859 flush_events();
3860 /* Even if the position was set with SetCursorPos(). */
3861 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
3862 flush_events();
3864 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3865 flush_events();
3866 ret = SetCursorPos(150, 150);
3867 ok(ret, "Failed to set cursor position.\n");
3868 flush_events();
3869 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3870 flush_events();
3872 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
3873 flush_events();
3874 /* SetCursorPos() doesn't. */
3875 ret = SetCursorPos(150, 150);
3876 ok(ret, "Failed to set cursor position.\n");
3877 flush_events();
3879 ok(!expect_pos->x && !expect_pos->y, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
3880 (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
3882 refcount = IDirect3DDevice9_Release(device);
3883 ok(!refcount, "Device has %u references left.\n", refcount);
3884 done:
3885 DestroyWindow(window);
3886 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
3887 IDirect3D9_Release(d3d9);
3890 static void test_mode_change(void)
3892 RECT fullscreen_rect, focus_rect, r;
3893 struct device_desc device_desc;
3894 IDirect3DSurface9 *backbuffer;
3895 IDirect3DDevice9 *device;
3896 D3DSURFACE_DESC desc;
3897 IDirect3D9 *d3d9;
3898 DEVMODEW devmode;
3899 UINT refcount;
3900 HRESULT hr;
3901 DWORD ret;
3903 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3904 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3905 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3906 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3907 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3908 ok(!!d3d9, "Failed to create a D3D object.\n");
3910 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3911 GetWindowRect(focus_window, &focus_rect);
3913 device_desc.device_window = device_window;
3914 device_desc.width = screen_width;
3915 device_desc.height = screen_height;
3916 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
3917 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3919 skip("Failed to create a D3D device, skipping tests.\n");
3920 goto done;
3923 memset(&devmode, 0, sizeof(devmode));
3924 devmode.dmSize = sizeof(devmode);
3925 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3926 devmode.dmPelsWidth = 640;
3927 devmode.dmPelsHeight = 480;
3929 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3930 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
3932 memset(&devmode, 0, sizeof(devmode));
3933 devmode.dmSize = sizeof(devmode);
3934 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3935 ok(ret, "Failed to get display mode.\n");
3936 ok(devmode.dmPelsWidth == 640, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3937 ok(devmode.dmPelsHeight == 480, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3939 GetWindowRect(device_window, &r);
3940 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3941 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3942 r.left, r.top, r.right, r.bottom);
3943 GetWindowRect(focus_window, &r);
3944 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3945 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3946 r.left, r.top, r.right, r.bottom);
3948 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3949 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3950 hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
3951 ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#x.\n", hr);
3952 ok(desc.Width == screen_width, "Got unexpected backbuffer width %u.\n", desc.Width);
3953 ok(desc.Height == screen_height, "Got unexpected backbuffer height %u.\n", desc.Height);
3954 IDirect3DSurface9_Release(backbuffer);
3956 refcount = IDirect3DDevice9_Release(device);
3957 ok(!refcount, "Device has %u references left.\n", refcount);
3959 memset(&devmode, 0, sizeof(devmode));
3960 devmode.dmSize = sizeof(devmode);
3961 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3962 ok(ret, "Failed to get display mode.\n");
3963 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3964 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3966 done:
3967 DestroyWindow(device_window);
3968 DestroyWindow(focus_window);
3969 IDirect3D9_Release(d3d9);
3971 memset(&devmode, 0, sizeof(devmode));
3972 devmode.dmSize = sizeof(devmode);
3973 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3974 ok(ret, "Failed to get display mode.\n");
3975 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3976 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3979 static void test_device_window_reset(void)
3981 RECT fullscreen_rect, device_rect, r;
3982 struct device_desc device_desc;
3983 IDirect3DDevice9 *device;
3984 WNDCLASSA wc = {0};
3985 IDirect3D9 *d3d9;
3986 LONG_PTR proc;
3987 HRESULT hr;
3988 ULONG ref;
3990 wc.lpfnWndProc = test_proc;
3991 wc.lpszClassName = "d3d9_test_wndproc_wc";
3992 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3994 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3995 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3996 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3997 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3998 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3999 ok(!!d3d9, "Failed to create a D3D object.\n");
4001 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
4002 GetWindowRect(device_window, &device_rect);
4004 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4005 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4006 (LONG_PTR)test_proc, proc);
4007 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4008 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4009 (LONG_PTR)test_proc, proc);
4011 device_desc.device_window = NULL;
4012 device_desc.width = screen_width;
4013 device_desc.height = screen_height;
4014 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4015 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4017 skip("Failed to create a D3D device, skipping tests.\n");
4018 goto done;
4021 GetWindowRect(focus_window, &r);
4022 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4023 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4024 r.left, r.top, r.right, r.bottom);
4025 GetWindowRect(device_window, &r);
4026 ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4027 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
4028 r.left, r.top, r.right, r.bottom);
4030 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4031 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4032 (LONG_PTR)test_proc, proc);
4033 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4034 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4035 (LONG_PTR)test_proc, proc);
4037 hr = reset_device(device, device_window, FALSE);
4038 ok(SUCCEEDED(hr), "Failed to reset device.\n");
4040 GetWindowRect(focus_window, &r);
4041 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4042 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4043 r.left, r.top, r.right, r.bottom);
4044 GetWindowRect(device_window, &r);
4045 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4046 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4047 r.left, r.top, r.right, r.bottom);
4049 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4050 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4051 (LONG_PTR)test_proc, proc);
4052 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4053 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4054 (LONG_PTR)test_proc, proc);
4056 ref = IDirect3DDevice9_Release(device);
4057 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4059 done:
4060 IDirect3D9_Release(d3d9);
4061 DestroyWindow(device_window);
4062 DestroyWindow(focus_window);
4063 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
4066 static void test_reset_resources(void)
4068 IDirect3DSurface9 *surface, *rt;
4069 IDirect3DTexture9 *texture;
4070 IDirect3DDevice9 *device;
4071 IDirect3D9 *d3d9;
4072 unsigned int i;
4073 D3DCAPS9 caps;
4074 HWND window;
4075 HRESULT hr;
4076 ULONG ref;
4078 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
4079 0, 0, 640, 480, 0, 0, 0, 0);
4080 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4081 ok(!!d3d9, "Failed to create a D3D object.\n");
4083 if (!(device = create_device(d3d9, window, NULL)))
4085 skip("Failed to create a D3D device, skipping tests.\n");
4086 goto done;
4089 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4090 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4092 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128,
4093 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
4094 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
4095 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
4096 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
4097 IDirect3DSurface9_Release(surface);
4099 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
4101 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
4102 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4103 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
4104 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4105 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
4106 IDirect3DTexture9_Release(texture);
4107 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
4108 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
4109 IDirect3DSurface9_Release(surface);
4112 hr = reset_device(device, device_window, TRUE);
4113 ok(SUCCEEDED(hr), "Failed to reset device.\n");
4115 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
4116 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
4117 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
4118 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4119 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
4120 IDirect3DSurface9_Release(surface);
4121 IDirect3DSurface9_Release(rt);
4123 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
4125 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
4126 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
4129 ref = IDirect3DDevice9_Release(device);
4130 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4132 done:
4133 IDirect3D9_Release(d3d9);
4134 DestroyWindow(window);
4137 static void test_set_rt_vp_scissor(void)
4139 IDirect3DStateBlock9 *stateblock;
4140 IDirect3DDevice9 *device;
4141 IDirect3DSurface9 *rt;
4142 IDirect3D9 *d3d9;
4143 D3DVIEWPORT9 vp;
4144 UINT refcount;
4145 HWND window;
4146 HRESULT hr;
4147 RECT rect;
4149 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
4150 0, 0, 640, 480, 0, 0, 0, 0);
4151 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4152 ok(!!d3d9, "Failed to create a D3D object.\n");
4153 if (!(device = create_device(d3d9, window, NULL)))
4155 skip("Failed to create a D3D device, skipping tests.\n");
4156 DestroyWindow(window);
4157 return;
4160 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
4161 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
4162 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4164 hr = IDirect3DDevice9_GetViewport(device, &vp);
4165 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4166 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4167 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4168 ok(vp.Width == 640, "Got unexpected vp.Width %u.\n", vp.Width);
4169 ok(vp.Height == 480, "Got unexpected vp.Height %u.\n", vp.Height);
4170 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4171 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4173 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4174 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4175 ok(rect.left == 0 && rect.top == 0 && rect.right == 640 && rect.bottom == 480,
4176 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4177 rect.left, rect.top, rect.right, rect.bottom);
4179 hr = IDirect3DDevice9_BeginStateBlock(device);
4180 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
4182 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4183 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4185 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
4186 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
4187 IDirect3DStateBlock9_Release(stateblock);
4189 hr = IDirect3DDevice9_GetViewport(device, &vp);
4190 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4191 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4192 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4193 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
4194 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
4195 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4196 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4198 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4199 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4200 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
4201 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4202 rect.left, rect.top, rect.right, rect.bottom);
4204 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4205 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4207 vp.X = 10;
4208 vp.Y = 20;
4209 vp.Width = 30;
4210 vp.Height = 40;
4211 vp.MinZ = 0.25f;
4212 vp.MaxZ = 0.75f;
4213 hr = IDirect3DDevice9_SetViewport(device, &vp);
4214 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
4216 SetRect(&rect, 50, 60, 70, 80);
4217 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
4218 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
4220 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4221 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4223 hr = IDirect3DDevice9_GetViewport(device, &vp);
4224 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4225 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4226 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4227 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
4228 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
4229 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4230 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4232 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4233 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4234 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
4235 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4236 rect.left, rect.top, rect.right, rect.bottom);
4238 IDirect3DSurface9_Release(rt);
4239 refcount = IDirect3DDevice9_Release(device);
4240 ok(!refcount, "Device has %u references left.\n", refcount);
4241 IDirect3D9_Release(d3d9);
4242 DestroyWindow(window);
4245 static void test_volume_get_container(void)
4247 IDirect3DVolumeTexture9 *texture = NULL;
4248 IDirect3DVolume9 *volume = NULL;
4249 IDirect3DDevice9 *device;
4250 IUnknown *container;
4251 IDirect3D9 *d3d9;
4252 ULONG refcount;
4253 D3DCAPS9 caps;
4254 HWND window;
4255 HRESULT hr;
4257 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4258 0, 0, 640, 480, 0, 0, 0, 0);
4259 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4260 ok(!!d3d9, "Failed to create a D3D object.\n");
4261 if (!(device = create_device(d3d9, window, NULL)))
4263 skip("Failed to create a D3D device, skipping tests.\n");
4264 IDirect3D9_Release(d3d9);
4265 DestroyWindow(window);
4266 return;
4269 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4270 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4271 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
4273 skip("No volume texture support, skipping tests.\n");
4274 IDirect3DDevice9_Release(device);
4275 IDirect3D9_Release(d3d9);
4276 DestroyWindow(window);
4277 return;
4280 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
4281 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
4282 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4283 ok(!!texture, "Got unexpected texture %p.\n", texture);
4285 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
4286 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
4287 ok(!!volume, "Got unexpected volume %p.\n", volume);
4289 /* These should work... */
4290 container = NULL;
4291 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
4292 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4293 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4294 IUnknown_Release(container);
4296 container = NULL;
4297 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
4298 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4299 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4300 IUnknown_Release(container);
4302 container = NULL;
4303 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
4304 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4305 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4306 IUnknown_Release(container);
4308 container = NULL;
4309 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
4310 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4311 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4312 IUnknown_Release(container);
4314 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
4315 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
4316 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
4317 ok(!container, "Got unexpected container %p.\n", container);
4319 IDirect3DVolume9_Release(volume);
4320 IDirect3DVolumeTexture9_Release(texture);
4321 refcount = IDirect3DDevice9_Release(device);
4322 ok(!refcount, "Device has %u references left.\n", refcount);
4323 IDirect3D9_Release(d3d9);
4324 DestroyWindow(window);
4327 static void test_volume_resource(void)
4329 IDirect3DVolumeTexture9 *texture;
4330 IDirect3DResource9 *resource;
4331 IDirect3DVolume9 *volume;
4332 IDirect3DDevice9 *device;
4333 IDirect3D9 *d3d9;
4334 ULONG refcount;
4335 D3DCAPS9 caps;
4336 HWND window;
4337 HRESULT hr;
4339 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4340 0, 0, 640, 480, 0, 0, 0, 0);
4341 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4342 ok(!!d3d9, "Failed to create a D3D object.\n");
4343 if (!(device = create_device(d3d9, window, NULL)))
4345 skip("Failed to create a D3D device, skipping tests.\n");
4346 IDirect3D9_Release(d3d9);
4347 DestroyWindow(window);
4348 return;
4351 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4352 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4353 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
4355 skip("No volume texture support, skipping tests.\n");
4356 IDirect3DDevice9_Release(device);
4357 IDirect3D9_Release(d3d9);
4358 DestroyWindow(window);
4359 return;
4362 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
4363 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
4364 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4365 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
4366 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
4367 IDirect3DVolumeTexture9_Release(texture);
4369 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
4370 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
4372 IDirect3DVolume9_Release(volume);
4373 refcount = IDirect3DDevice9_Release(device);
4374 ok(!refcount, "Device has %u references left.\n", refcount);
4375 IDirect3D9_Release(d3d9);
4376 DestroyWindow(window);
4379 static void test_vb_lock_flags(void)
4381 static const struct
4383 DWORD flags;
4384 const char *debug_string;
4385 HRESULT win7_result;
4387 test_data[] =
4389 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
4390 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
4391 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
4392 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
4393 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
4394 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
4395 /* Completely bogus flags aren't an error. */
4396 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
4398 IDirect3DVertexBuffer9 *buffer;
4399 IDirect3DDevice9 *device;
4400 IDirect3D9 *d3d9;
4401 unsigned int i;
4402 ULONG refcount;
4403 HWND window;
4404 HRESULT hr;
4405 void *data;
4407 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4408 0, 0, 640, 480, 0, 0, 0, 0);
4409 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4410 ok(!!d3d9, "Failed to create a D3D object.\n");
4411 if (!(device = create_device(d3d9, window, NULL)))
4413 skip("Failed to create a D3D device, skipping tests.\n");
4414 IDirect3D9_Release(d3d9);
4415 DestroyWindow(window);
4416 return;
4419 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
4420 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4422 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
4424 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
4425 /* Windows XP always returns D3D_OK even with flags that don't make
4426 * sense. Windows 7 returns an error. At least one game (Shaiya)
4427 * depends on the Windows XP result, so mark the Windows 7 behavior as
4428 * broken. */
4429 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
4430 hr, test_data[i].debug_string);
4431 if (SUCCEEDED(hr))
4433 ok(!!data, "Got unexpected data %p.\n", data);
4434 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4435 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
4439 IDirect3DVertexBuffer9_Release(buffer);
4440 refcount = IDirect3DDevice9_Release(device);
4441 ok(!refcount, "Device has %u references left.\n", refcount);
4442 IDirect3D9_Release(d3d9);
4443 DestroyWindow(window);
4446 static const char *debug_d3dpool(D3DPOOL pool)
4448 switch (pool)
4450 case D3DPOOL_DEFAULT:
4451 return "D3DPOOL_DEFAULT";
4452 case D3DPOOL_SYSTEMMEM:
4453 return "D3DPOOL_SYSTEMMEM";
4454 case D3DPOOL_SCRATCH:
4455 return "D3DPOOL_SCRATCH";
4456 case D3DPOOL_MANAGED:
4457 return "D3DPOOL_MANAGED";
4458 default:
4459 return "unknown pool";
4463 static void test_vertex_buffer_alignment(void)
4465 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
4466 static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
4467 IDirect3DVertexBuffer9 *buffer = NULL;
4468 const unsigned int align = 16;
4469 IDirect3DDevice9 *device;
4470 unsigned int i, j;
4471 IDirect3D9 *d3d9;
4472 ULONG refcount;
4473 HWND window;
4474 HRESULT hr;
4475 void *data;
4477 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4478 0, 0, 640, 480, 0, 0, 0, 0);
4479 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4480 ok(!!d3d9, "Failed to create a D3D object.\n");
4481 if (!(device = create_device(d3d9, window, NULL)))
4483 skip("Failed to create a D3D device, skipping tests.\n");
4484 IDirect3D9_Release(d3d9);
4485 DestroyWindow(window);
4486 return;
4489 for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
4491 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
4493 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
4494 if (pools[j] == D3DPOOL_SCRATCH)
4495 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
4496 else
4497 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
4498 debug_d3dpool(pools[j]), sizes[i], hr);
4499 if (FAILED(hr))
4500 continue;
4502 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
4503 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
4504 ok(!((DWORD_PTR)data & (align - 1)),
4505 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
4506 data, align, sizes[i], debug_d3dpool(pools[j]));
4507 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4508 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
4509 IDirect3DVertexBuffer9_Release(buffer);
4513 refcount = IDirect3DDevice9_Release(device);
4514 ok(!refcount, "Device has %u references left.\n", refcount);
4515 IDirect3D9_Release(d3d9);
4516 DestroyWindow(window);
4519 static void test_query_support(void)
4521 static const D3DQUERYTYPE queries[] =
4523 D3DQUERYTYPE_VCACHE,
4524 D3DQUERYTYPE_RESOURCEMANAGER,
4525 D3DQUERYTYPE_VERTEXSTATS,
4526 D3DQUERYTYPE_EVENT,
4527 D3DQUERYTYPE_OCCLUSION,
4528 D3DQUERYTYPE_TIMESTAMP,
4529 D3DQUERYTYPE_TIMESTAMPDISJOINT,
4530 D3DQUERYTYPE_TIMESTAMPFREQ,
4531 D3DQUERYTYPE_PIPELINETIMINGS,
4532 D3DQUERYTYPE_INTERFACETIMINGS,
4533 D3DQUERYTYPE_VERTEXTIMINGS,
4534 D3DQUERYTYPE_PIXELTIMINGS,
4535 D3DQUERYTYPE_BANDWIDTHTIMINGS,
4536 D3DQUERYTYPE_CACHEUTILIZATION,
4538 IDirect3DQuery9 *query = NULL;
4539 IDirect3DDevice9 *device;
4540 IDirect3D9 *d3d9;
4541 unsigned int i;
4542 ULONG refcount;
4543 BOOL supported;
4544 HWND window;
4545 HRESULT hr;
4547 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4548 0, 0, 640, 480, 0, 0, 0, 0);
4549 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4550 ok(!!d3d9, "Failed to create a D3D object.\n");
4551 if (!(device = create_device(d3d9, window, NULL)))
4553 skip("Failed to create a D3D device, skipping tests.\n");
4554 IDirect3D9_Release(d3d9);
4555 DestroyWindow(window);
4556 return;
4559 for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
4561 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
4562 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4564 supported = hr == D3D_OK;
4566 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
4567 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4569 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
4570 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
4572 if (query)
4574 IDirect3DQuery9_Release(query);
4575 query = NULL;
4579 refcount = IDirect3DDevice9_Release(device);
4580 ok(!refcount, "Device has %u references left.\n", refcount);
4581 IDirect3D9_Release(d3d9);
4582 DestroyWindow(window);
4585 static void test_occlusion_query_states(void)
4587 static const float quad[] =
4589 -1.0f, -1.0f, 0.0f,
4590 -1.0f, 1.0f, 0.0f,
4591 1.0f, 1.0f, 0.0f,
4592 1.0f, -1.0f, 0.0f,
4594 struct device_desc device_desc;
4595 IDirect3DQuery9 *query = NULL;
4596 unsigned int data_size, i;
4597 IDirect3DDevice9 *device;
4598 IDirect3D9 *d3d9;
4599 ULONG refcount;
4600 HWND window;
4601 HRESULT hr;
4602 union
4604 WORD word[4];
4605 DWORD dword[2];
4606 } data;
4607 BOOL broken_occlusion = FALSE;
4608 DWORD expected = screen_width * screen_height;
4610 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4611 0, 0, 640, 480, 0, 0, 0, 0);
4612 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4613 ok(!!d3d9, "Failed to create a D3D object.\n");
4614 device_desc.device_window = window;
4615 device_desc.width = screen_width;
4616 device_desc.height = screen_height;
4617 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4618 if (!(device = create_device(d3d9, window, &device_desc)))
4620 skip("Failed to create a D3D device, skipping tests.\n");
4621 IDirect3D9_Release(d3d9);
4622 DestroyWindow(window);
4623 return;
4626 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
4627 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4629 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4630 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4631 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4633 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4634 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4635 if (!query)
4637 skip("Occlusion queries are not supported, skipping tests.\n");
4638 IDirect3DDevice9_Release(device);
4639 IDirect3D9_Release(d3d9);
4640 DestroyWindow(window);
4641 return;
4644 data_size = IDirect3DQuery9_GetDataSize(query);
4645 ok(data_size == sizeof(DWORD), "Unexpected data size %u.\n", data_size);
4647 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4648 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4649 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
4650 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4652 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4653 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4654 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4655 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4656 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4657 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4659 data.dword[0] = 0x12345678;
4660 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4661 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4662 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
4663 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4664 if (hr == D3D_OK)
4665 ok(!data.dword[0], "Got unexpected query result %u.\n", data.dword[0]);
4667 hr = IDirect3DDevice9_BeginScene(device);
4668 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
4670 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4671 hr = IDirect3DDevice9_EndScene(device);
4672 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4674 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4675 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4676 for (i = 0; i < 500; ++i)
4678 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4679 break;
4680 Sleep(10);
4682 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4684 memset(&data, 0xff, sizeof(data));
4685 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
4686 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4687 ok(data.dword[0] == expected || broken(!data.dword[0]),
4688 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
4689 if (!data.dword[0])
4691 win_skip("Occlusion query result looks broken, ignoring returned count.\n");
4692 broken_occlusion = TRUE;
4695 memset(&data, 0xff, sizeof(data));
4696 hr = IDirect3DQuery9_GetData(query, &data, sizeof(WORD), D3DGETDATA_FLUSH);
4697 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4698 if (!broken_occlusion)
4699 ok(data.word[0] == (WORD)expected,
4700 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
4701 ok(data.word[1] == 0xffff,
4702 "data was modified outside of the expected size (0x%.8x).\n", data.dword[0]);
4704 memset(&data, 0xf0, sizeof(data));
4705 hr = IDirect3DQuery9_GetData(query, &data, sizeof(data), D3DGETDATA_FLUSH);
4706 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4707 if (!broken_occlusion)
4708 ok(data.dword[0] == expected,
4709 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
4710 /* Different drivers seem to return different data in those high bytes on Windows, but they all
4711 write something there and the extra data is consistent (I've seen 0x00000000 and 0xdddddddd
4712 on AMD and Nvidia respectively). */
4713 if (0)
4715 ok(data.dword[1] != 0xf0f0f0f0, "high bytes of data were not modified (0x%.8x).\n",
4716 data.dword[1]);
4719 memset(&data, 0xff, sizeof(data));
4720 hr = IDirect3DQuery9_GetData(query, &data, 0, D3DGETDATA_FLUSH);
4721 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4722 ok(data.dword[0] == 0xffffffff, "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
4724 /* This crashes on Windows. */
4725 if (0)
4727 hr = IDirect3DQuery9_GetData(query, NULL, data_size, D3DGETDATA_FLUSH);
4728 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4731 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4732 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4733 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4734 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4735 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4736 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4738 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4740 IDirect3DQuery9_Release(query);
4741 refcount = IDirect3DDevice9_Release(device);
4742 ok(!refcount, "Device has %u references left.\n", refcount);
4743 IDirect3D9_Release(d3d9);
4744 DestroyWindow(window);
4747 static void test_timestamp_query(void)
4749 static const float quad[] =
4751 -1.0f, -1.0f, 0.0f,
4752 -1.0f, 1.0f, 0.0f,
4753 1.0f, 1.0f, 0.0f,
4754 1.0f, -1.0f, 0.0f,
4756 IDirect3DQuery9 *query, *disjoint_query, *freq_query;
4757 unsigned int data_size, i;
4758 IDirect3DDevice9 *device;
4759 IDirect3D9 *d3d9;
4760 ULONG refcount;
4761 HWND window;
4762 HRESULT hr;
4763 DWORD timestamp[2], freq[2];
4764 WORD disjoint[2];
4766 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4767 0, 0, 640, 480, 0, 0, 0, 0);
4768 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4769 ok(!!d3d9, "Failed to create a D3D object.\n");
4770 if (!(device = create_device(d3d9, window, NULL)))
4772 skip("Failed to create a D3D device, skipping tests.\n");
4773 IDirect3D9_Release(d3d9);
4774 DestroyWindow(window);
4775 return;
4778 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPFREQ, &freq_query);
4779 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4780 if (FAILED(hr))
4782 skip("Timestamp queries are not supported, skipping tests.\n");
4783 IDirect3DDevice9_Release(device);
4784 IDirect3D9_Release(d3d9);
4785 DestroyWindow(window);
4786 return;
4788 data_size = IDirect3DQuery9_GetDataSize(freq_query);
4789 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
4791 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPDISJOINT, &disjoint_query);
4792 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4793 data_size = IDirect3DQuery9_GetDataSize(disjoint_query);
4794 ok(data_size == sizeof(BOOL), "Query data size is %u, 4 expected.\n", data_size);
4796 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMP, &query);
4797 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4798 data_size = IDirect3DQuery9_GetDataSize(query);
4799 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
4801 hr = IDirect3DQuery9_Issue(freq_query, D3DISSUE_END);
4802 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4803 for (i = 0; i < 500; ++i)
4805 if ((hr = IDirect3DQuery9_GetData(freq_query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4806 break;
4807 Sleep(10);
4809 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4811 memset(freq, 0xff, sizeof(freq));
4812 hr = IDirect3DQuery9_GetData(freq_query, freq, sizeof(DWORD), D3DGETDATA_FLUSH);
4813 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4814 ok(freq[1] == 0xffffffff,
4815 "freq was modified outside of the expected size (0x%.8x).\n", freq[1]);
4816 hr = IDirect3DQuery9_GetData(freq_query, &freq, sizeof(freq), D3DGETDATA_FLUSH);
4817 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4818 ok(freq[1] != 0xffffffff, "high bytes of freq were not modified (0x%.8x).\n",
4819 freq[1]);
4821 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4822 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4823 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4824 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4826 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
4827 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4828 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
4829 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4830 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
4831 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4833 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4834 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4836 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4837 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4838 hr = IDirect3DDevice9_BeginScene(device);
4839 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
4841 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4842 hr = IDirect3DDevice9_EndScene(device);
4843 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4845 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4846 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4847 for (i = 0; i < 500; ++i)
4849 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4850 break;
4851 Sleep(10);
4853 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4855 memset(timestamp, 0xff, sizeof(timestamp));
4856 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(DWORD), D3DGETDATA_FLUSH);
4857 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4858 ok(timestamp[1] == 0xffffffff,
4859 "timestamp was modified outside of the expected size (0x%.8x).\n",
4860 timestamp[1]);
4862 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4863 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4864 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4865 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4866 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4867 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4869 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
4870 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4871 for (i = 0; i < 500; ++i)
4873 if ((hr = IDirect3DQuery9_GetData(disjoint_query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4874 break;
4875 Sleep(10);
4877 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4879 memset(disjoint, 0xff, sizeof(disjoint));
4880 hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(WORD), D3DGETDATA_FLUSH);
4881 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4882 ok(disjoint[1] == 0xffff,
4883 "disjoint was modified outside of the expected size (0x%.4hx).\n", disjoint[1]);
4884 hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(disjoint), D3DGETDATA_FLUSH);
4885 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4886 ok(disjoint[1] != 0xffff, "high bytes of disjoint were not modified (0x%.4hx).\n", disjoint[1]);
4888 /* It's not strictly necessary for the TIMESTAMP query to be inside
4889 * a TIMESTAMP_DISJOINT query. */
4890 hr = IDirect3DDevice9_BeginScene(device);
4891 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4892 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
4893 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4894 hr = IDirect3DDevice9_EndScene(device);
4895 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4897 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4898 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4899 for (i = 0; i < 500; ++i)
4901 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4902 break;
4903 Sleep(10);
4905 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4906 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4907 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4909 IDirect3DQuery9_Release(query);
4910 IDirect3DQuery9_Release(disjoint_query);
4911 IDirect3DQuery9_Release(freq_query);
4912 refcount = IDirect3DDevice9_Release(device);
4913 ok(!refcount, "Device has %u references left.\n", refcount);
4914 IDirect3D9_Release(d3d9);
4915 DestroyWindow(window);
4918 static void test_get_set_vertex_shader(void)
4920 IDirect3DVertexShader9 *current_shader = NULL;
4921 IDirect3DVertexShader9 *shader = NULL;
4922 IDirect3DDevice9 *device;
4923 ULONG refcount, i;
4924 IDirect3D9 *d3d;
4925 D3DCAPS9 caps;
4926 HWND window;
4927 HRESULT hr;
4929 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4930 0, 0, 640, 480, 0, 0, 0, 0);
4931 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4932 ok(!!d3d, "Failed to create a D3D object.\n");
4933 if (!(device = create_device(d3d, window, NULL)))
4935 skip("Failed to create a D3D device, skipping tests.\n");
4936 IDirect3D9_Release(d3d);
4937 DestroyWindow(window);
4938 return;
4941 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4942 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4943 if (!(caps.VertexShaderVersion & 0xffff))
4945 skip("No vertex shader support, skipping tests.\n");
4946 IDirect3DDevice9_Release(device);
4947 IDirect3D9_Release(d3d);
4948 DestroyWindow(window);
4949 return;
4952 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
4953 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4954 ok(!!shader, "Got unexpected shader %p.\n", shader);
4956 /* SetVertexShader() should not touch the shader's refcount. */
4957 i = get_refcount((IUnknown *)shader);
4958 hr = IDirect3DDevice9_SetVertexShader(device, shader);
4959 refcount = get_refcount((IUnknown *)shader);
4960 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4961 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4963 /* GetVertexShader() should increase the shader's refcount by one. */
4964 i = refcount + 1;
4965 hr = IDirect3DDevice9_GetVertexShader(device, &current_shader);
4966 refcount = get_refcount((IUnknown *)shader);
4967 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
4968 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4969 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4970 IDirect3DVertexShader9_Release(current_shader);
4972 IDirect3DVertexShader9_Release(shader);
4973 refcount = IDirect3DDevice9_Release(device);
4974 ok(!refcount, "Device has %u references left.\n", refcount);
4975 IDirect3D9_Release(d3d);
4976 DestroyWindow(window);
4979 static void test_vertex_shader_constant(void)
4981 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};
4982 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4983 IDirect3DDevice9 *device;
4984 IDirect3D9 *d3d;
4985 ULONG refcount;
4986 D3DCAPS9 caps;
4987 DWORD consts;
4988 HWND window;
4989 HRESULT hr;
4991 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4992 0, 0, 640, 480, 0, 0, 0, 0);
4993 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4994 ok(!!d3d, "Failed to create a D3D object.\n");
4995 if (!(device = create_device(d3d, window, NULL)))
4997 skip("Failed to create a D3D device, skipping tests.\n");
4998 IDirect3D9_Release(d3d);
4999 DestroyWindow(window);
5000 return;
5003 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5004 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5005 if (!(caps.VertexShaderVersion & 0xffff))
5007 skip("No vertex shader support, skipping tests.\n");
5008 IDirect3DDevice9_Release(device);
5009 IDirect3D9_Release(d3d);
5010 DestroyWindow(window);
5011 return;
5013 consts = caps.MaxVertexShaderConst;
5015 /* A simple check that the stuff works at all. */
5016 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
5017 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5019 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
5020 * consts from MAX - 1. */
5021 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
5022 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5023 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
5024 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5025 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
5026 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5027 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
5028 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5030 /* Constant -1. */
5031 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
5032 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5034 refcount = IDirect3DDevice9_Release(device);
5035 ok(!refcount, "Device has %u references left.\n", refcount);
5036 IDirect3D9_Release(d3d);
5037 DestroyWindow(window);
5040 static void test_get_set_pixel_shader(void)
5042 IDirect3DPixelShader9 *current_shader = NULL;
5043 IDirect3DPixelShader9 *shader = NULL;
5044 IDirect3DDevice9 *device;
5045 ULONG refcount, i;
5046 IDirect3D9 *d3d;
5047 D3DCAPS9 caps;
5048 HWND window;
5049 HRESULT hr;
5051 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5052 0, 0, 640, 480, 0, 0, 0, 0);
5053 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5054 ok(!!d3d, "Failed to create a D3D object.\n");
5055 if (!(device = create_device(d3d, window, NULL)))
5057 skip("Failed to create a D3D device, skipping tests.\n");
5058 IDirect3D9_Release(d3d);
5059 DestroyWindow(window);
5060 return;
5063 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5064 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5065 if (!(caps.PixelShaderVersion & 0xffff))
5067 skip("No pixel shader support, skipping tests.\n");
5068 IDirect3DDevice9_Release(device);
5069 IDirect3D9_Release(d3d);
5070 DestroyWindow(window);
5071 return;
5074 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
5075 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
5076 ok(!!shader, "Got unexpected shader %p.\n", shader);
5078 /* SetPixelShader() should not touch the shader's refcount. */
5079 i = get_refcount((IUnknown *)shader);
5080 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5081 refcount = get_refcount((IUnknown *)shader);
5082 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5083 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
5085 /* GetPixelShader() should increase the shader's refcount by one. */
5086 i = refcount + 1;
5087 hr = IDirect3DDevice9_GetPixelShader(device, &current_shader);
5088 refcount = get_refcount((IUnknown *)shader);
5089 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
5090 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
5091 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
5092 IDirect3DPixelShader9_Release(current_shader);
5094 IDirect3DPixelShader9_Release(shader);
5095 refcount = IDirect3DDevice9_Release(device);
5096 ok(!refcount, "Device has %u references left.\n", refcount);
5097 IDirect3D9_Release(d3d);
5098 DestroyWindow(window);
5101 static void test_pixel_shader_constant(void)
5103 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};
5104 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
5105 IDirect3DDevice9 *device;
5106 DWORD consts = 0;
5107 IDirect3D9 *d3d;
5108 ULONG refcount;
5109 D3DCAPS9 caps;
5110 HWND window;
5111 HRESULT hr;
5113 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5114 0, 0, 640, 480, 0, 0, 0, 0);
5115 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5116 ok(!!d3d, "Failed to create a D3D object.\n");
5117 if (!(device = create_device(d3d, window, NULL)))
5119 skip("Failed to create a D3D device, skipping tests.\n");
5120 IDirect3D9_Release(d3d);
5121 DestroyWindow(window);
5122 return;
5125 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5126 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5127 if (!(caps.PixelShaderVersion & 0xffff))
5129 skip("No pixel shader support, skipping tests.\n");
5130 IDirect3DDevice9_Release(device);
5131 IDirect3D9_Release(d3d);
5132 DestroyWindow(window);
5133 return;
5136 /* A simple check that the stuff works at all. */
5137 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
5138 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5140 /* Is there really no max pixel shader constant value??? Test how far I can go. */
5141 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
5142 consts = consts - 1;
5143 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
5145 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
5146 * pointless given the way the constant limit was determined. */
5147 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
5148 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5150 /* Constant -1. */
5151 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
5152 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5154 refcount = IDirect3DDevice9_Release(device);
5155 ok(!refcount, "Device has %u references left.\n", refcount);
5156 IDirect3D9_Release(d3d);
5157 DestroyWindow(window);
5160 static void test_unsupported_shaders(void)
5162 static const DWORD vs_3_0[] =
5164 0xfffe0300, /* vs_3_0 */
5165 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5166 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5167 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5168 0x0000ffff, /* end */
5171 #if 0
5172 float4 main(const float4 color : COLOR) : SV_TARGET
5174 float4 o;
5176 o = color;
5178 return o;
5180 #endif
5181 static const DWORD ps_4_0[] =
5183 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
5184 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
5185 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
5186 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
5187 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
5188 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
5189 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
5190 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
5191 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
5192 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
5193 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
5194 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5195 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5196 0x00000000, 0x00000000, 0x00000000,
5198 #if 0
5199 vs_1_1
5200 dcl_position v0
5201 def c255, 1.0, 1.0, 1.0, 1.0
5202 add r0, v0, c255
5203 mov oPos, r0
5204 #endif
5205 static const DWORD vs_1_255[] =
5207 0xfffe0101,
5208 0x0000001f, 0x80000000, 0x900f0000,
5209 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5210 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
5211 0x00000001, 0xc00f0000, 0x80e40000,
5212 0x0000ffff
5214 #if 0
5215 vs_1_1
5216 dcl_position v0
5217 def c256, 1.0, 1.0, 1.0, 1.0
5218 add r0, v0, c256
5219 mov oPos, r0
5220 #endif
5221 static const DWORD vs_1_256[] =
5223 0xfffe0101,
5224 0x0000001f, 0x80000000, 0x900f0000,
5225 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5226 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
5227 0x00000001, 0xc00f0000, 0x80e40000,
5228 0x0000ffff
5230 #if 0
5231 vs_3_0
5232 dcl_position v0
5233 dcl_position o0
5234 def c256, 1.0, 1.0, 1.0, 1.0
5235 add r0, v0, c256
5236 mov o0, r0
5237 #endif
5238 static const DWORD vs_3_256[] =
5240 0xfffe0300,
5241 0x0200001f, 0x80000000, 0x900f0000,
5242 0x0200001f, 0x80000000, 0xe00f0000,
5243 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5244 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
5245 0x02000001, 0xe00f0000, 0x80e40000,
5246 0x0000ffff
5248 #if 0
5249 /* This shader source generates syntax errors with the native shader assembler
5250 * due to the constant register index values.
5251 * The bytecode was modified by hand to use the intended values. */
5252 vs_3_0
5253 dcl_position v0
5254 dcl_position o0
5255 defi i16, 1, 1, 1, 1
5256 rep i16
5257 add r0, r0, v0
5258 endrep
5259 mov o0, r0
5260 #endif
5261 static const DWORD vs_3_i16[] =
5263 0xfffe0300,
5264 0x0200001f, 0x80000000, 0x900f0000,
5265 0x0200001f, 0x80000000, 0xe00f0000,
5266 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
5267 0x01000026, 0xf0e40010,
5268 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
5269 0x00000027,
5270 0x02000001, 0xe00f0000, 0x80e40000,
5271 0x0000ffff
5273 #if 0
5274 /* This shader source generates syntax errors with the native shader assembler
5275 * due to the constant register index values.
5276 * The bytecode was modified by hand to use the intended values. */
5277 vs_3_0
5278 dcl_position v0
5279 dcl_position o0
5280 defb b16, true
5281 mov r0, v0
5282 if b16
5283 add r0, r0, v0
5284 endif
5285 mov o0, r0
5286 #endif
5287 static const DWORD vs_3_b16[] =
5289 0xfffe0300,
5290 0x0200001f, 0x80000000, 0x900f0000,
5291 0x0200001f, 0x80000000, 0xe00f0000,
5292 0x0200002f, 0xe00f0810, 0x00000001,
5293 0x02000001, 0x800f0000, 0x90e40000,
5294 0x01000028, 0xe0e40810,
5295 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
5296 0x0000002b,
5297 0x02000001, 0xe00f0000, 0x80e40000,
5298 0x0000ffff
5300 #if 0
5301 /* This shader source generates syntax errors with the native shader assembler
5302 * due to the constant register index values.
5303 * The bytecode was modified by hand to use the intended values. */
5304 ps_1_1
5305 def c8, 1.0, 1.0, 1.0, 1.0
5306 add r0, v0, c8
5307 #endif
5308 static const DWORD ps_1_8[] =
5310 0xffff0101,
5311 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5312 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
5313 0x0000ffff
5315 #if 0
5316 /* This shader source generates syntax errors with the native shader assembler
5317 * due to the constant register index values.
5318 * The bytecode was modified by hand to use the intended values. */
5319 ps_2_0
5320 def c32, 1.0, 1.0, 1.0, 1.0
5321 add oC0, v0, c32
5322 #endif
5323 static const DWORD ps_2_32[] =
5325 0xffff0200,
5326 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5327 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
5328 0x0000ffff
5330 #if 0
5331 /* This shader source generates syntax errors with the native shader assembler
5332 * due to the constant register index values.
5333 * The bytecode was modified by hand to use the intended values. */
5334 ps_3_0
5335 dcl_color0 v0
5336 def c224, 1.0, 1.0, 1.0, 1.0
5337 add oC0, v0, c224
5338 #endif
5339 static const DWORD ps_3_224[] =
5341 0xffff0300,
5342 0x0200001f, 0x8000000a, 0x900f0000,
5343 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5344 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
5345 0x0000ffff
5347 #if 0
5348 /* This shader source generates syntax errors with the native shader assembler
5349 * due to the constant register index values.
5350 * The bytecode was modified by hand to use the intended values. */
5351 ps_2_0
5352 defb b0, true
5353 defi i0, 1, 1, 1, 1
5354 rep i0
5355 if b0
5356 add r0, r0, v0
5357 endif
5358 endrep
5359 mov oC0, r0
5360 #endif
5361 static const DWORD ps_2_0_boolint[] =
5363 0xffff0200,
5364 0x0200002f, 0xe00f0800, 0x00000001,
5365 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
5366 0x01000026, 0xf0e40000,
5367 0x01000028, 0xe0e40800,
5368 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
5369 0x0000002b,
5370 0x00000027,
5371 0x02000001, 0x800f0800, 0x80e40000,
5372 0x0000ffff
5375 IDirect3DVertexShader9 *vs = NULL;
5376 IDirect3DPixelShader9 *ps = NULL;
5377 IDirect3DDevice9 *device;
5378 IDirect3D9 * d3d;
5379 ULONG refcount;
5380 D3DCAPS9 caps;
5381 HWND window;
5382 HRESULT hr;
5384 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5385 0, 0, 640, 480, 0, 0, 0, 0);
5386 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5387 ok(!!d3d, "Failed to create a D3D object.\n");
5388 if (!(device = create_device(d3d, window, NULL)))
5390 skip("Failed to create a D3D device, skipping tests.\n");
5391 IDirect3D9_Release(d3d);
5392 DestroyWindow(window);
5393 return;
5396 /* These should always fail, regardless of supported shader version. */
5397 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
5398 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5399 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
5400 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5401 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
5402 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5404 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5405 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5406 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
5408 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
5409 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5410 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
5412 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_255, &vs);
5413 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5415 else
5417 skip("GPU supports SM2+, skipping SM1 test.\n");
5420 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
5422 else
5424 skip("This GPU supports SM3, skipping unsupported shader test.\n");
5426 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_255, &vs);
5427 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5428 IDirect3DVertexShader9_Release(vs);
5429 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_256, &vs);
5430 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5431 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_256, &vs);
5432 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5433 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_i16, &vs);
5434 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5435 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_b16, &vs);
5436 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5439 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
5441 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
5442 goto cleanup;
5444 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_8, &ps);
5445 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5446 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_32, &ps);
5447 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5448 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_224, &ps);
5449 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5450 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_0_boolint, &ps);
5451 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5452 if (ps)
5453 IDirect3DPixelShader9_Release(ps);
5455 cleanup:
5456 refcount = IDirect3DDevice9_Release(device);
5457 ok(!refcount, "Device has %u references left.\n", refcount);
5458 IDirect3D9_Release(d3d);
5459 DestroyWindow(window);
5462 /* Test the default texture stage state values */
5463 static void test_texture_stage_states(void)
5465 IDirect3DDevice9 *device;
5466 IDirect3D9 *d3d;
5467 unsigned int i;
5468 ULONG refcount;
5469 D3DCAPS9 caps;
5470 DWORD value;
5471 HWND window;
5472 HRESULT hr;
5474 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5475 0, 0, 640, 480, 0, 0, 0, 0);
5476 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5477 ok(!!d3d, "Failed to create a D3D object.\n");
5478 if (!(device = create_device(d3d, window, NULL)))
5480 skip("Failed to create a D3D device, skipping tests.\n");
5481 IDirect3D9_Release(d3d);
5482 DestroyWindow(window);
5483 return;
5486 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5487 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5489 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
5491 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
5492 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5493 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
5494 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
5495 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
5496 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5497 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
5498 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
5499 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5500 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
5501 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
5502 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5503 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
5504 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
5505 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
5506 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5507 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
5508 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
5509 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5510 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
5511 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
5512 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5513 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
5514 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
5515 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5516 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
5517 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
5518 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5519 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
5520 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
5521 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5522 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
5523 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
5524 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5525 ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
5526 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
5527 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5528 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
5529 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
5530 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5531 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
5532 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
5533 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5534 ok(value == D3DTTFF_DISABLE,
5535 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
5536 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
5537 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5538 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
5539 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
5540 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5541 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
5542 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
5543 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5544 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value, i);
5545 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
5546 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5547 ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
5550 refcount = IDirect3DDevice9_Release(device);
5551 ok(!refcount, "Device has %u references left.\n", refcount);
5552 IDirect3D9_Release(d3d);
5553 DestroyWindow(window);
5556 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
5558 IDirect3DCubeTexture9 *texture;
5559 IDirect3D9 *d3d;
5560 HRESULT hr;
5562 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
5563 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
5564 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5565 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
5566 IDirect3D9_Release(d3d);
5567 if (FAILED(hr))
5569 skip("No cube mipmap generation support, skipping tests.\n");
5570 return;
5573 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
5574 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5575 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5576 IDirect3DCubeTexture9_Release(texture);
5578 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
5579 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5580 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5581 IDirect3DCubeTexture9_Release(texture);
5584 static void test_cube_texture_levels(IDirect3DDevice9 *device)
5586 IDirect3DCubeTexture9 *texture;
5587 IDirect3DSurface9 *surface;
5588 D3DSURFACE_DESC desc;
5589 DWORD levels;
5590 HRESULT hr;
5591 D3DCAPS9 caps;
5593 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5594 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5595 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
5596 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
5598 skip("Failed to create cube texture, skipping tests.\n");
5599 return;
5602 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
5603 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)
5604 ok(levels == 7, "Got unexpected levels %u.\n", levels);
5605 else
5606 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5608 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
5609 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5610 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
5611 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5612 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
5613 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5615 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
5616 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5617 IDirect3DSurface9_Release(surface);
5618 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
5619 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5620 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
5621 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5623 IDirect3DCubeTexture9_Release(texture);
5626 static void test_cube_textures(void)
5628 IDirect3DCubeTexture9 *texture;
5629 IDirect3DDevice9 *device;
5630 IDirect3D9 *d3d;
5631 ULONG refcount;
5632 D3DCAPS9 caps;
5633 HWND window;
5634 HRESULT hr;
5636 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5637 0, 0, 640, 480, 0, 0, 0, 0);
5638 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5639 ok(!!d3d, "Failed to create a D3D object.\n");
5640 if (!(device = create_device(d3d, window, NULL)))
5642 skip("Failed to create a D3D device, skipping tests.\n");
5643 IDirect3D9_Release(d3d);
5644 DestroyWindow(window);
5645 return;
5648 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5649 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5651 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
5653 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5654 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
5655 IDirect3DCubeTexture9_Release(texture);
5656 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5657 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
5658 IDirect3DCubeTexture9_Release(texture);
5659 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
5660 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
5661 IDirect3DCubeTexture9_Release(texture);
5663 else
5665 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5666 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
5667 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5668 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
5669 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
5670 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
5672 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
5673 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
5674 IDirect3DCubeTexture9_Release(texture);
5676 test_cube_texture_mipmap_gen(device);
5677 test_cube_texture_levels(device);
5679 refcount = IDirect3DDevice9_Release(device);
5680 ok(!refcount, "Device has %u references left.\n", refcount);
5681 IDirect3D9_Release(d3d);
5682 DestroyWindow(window);
5685 static void test_mipmap_gen(void)
5687 D3DTEXTUREFILTERTYPE filter_type;
5688 IDirect3DTexture9 *texture;
5689 IDirect3DSurface9 *surface;
5690 IDirect3DDevice9 *device;
5691 D3DSURFACE_DESC desc;
5692 D3DLOCKED_RECT lr;
5693 IDirect3D9 *d3d;
5694 ULONG refcount;
5695 unsigned int i;
5696 DWORD levels;
5697 HWND window;
5698 HRESULT hr;
5700 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5701 ok(!!d3d, "Failed to create a D3D object.\n");
5703 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5704 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
5706 skip("No mipmap generation support, skipping tests.\n");
5707 IDirect3D9_Release(d3d);
5708 return;
5711 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5712 0, 0, 640, 480, 0, 0, 0, 0);
5713 if (!(device = create_device(d3d, window, NULL)))
5715 skip("Failed to create a D3D device, skipping tests.\n");
5716 IDirect3D9_Release(d3d);
5717 DestroyWindow(window);
5718 return;
5721 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
5722 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5723 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5724 IDirect3DTexture9_Release(texture);
5726 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
5727 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5728 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5730 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
5731 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
5732 "Got unexpected filter_type %#x.\n", filter_type);
5733 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
5734 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5735 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
5736 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5737 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
5738 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
5739 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
5740 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5742 levels = IDirect3DTexture9_GetLevelCount(texture);
5743 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5745 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
5747 surface = NULL;
5748 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
5749 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5750 if (surface)
5751 IDirect3DSurface9_Release(surface);
5753 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
5754 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5756 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
5757 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5758 if (SUCCEEDED(hr))
5760 hr = IDirect3DTexture9_UnlockRect(texture, i);
5761 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5764 IDirect3DTexture9_Release(texture);
5766 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
5767 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5768 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5769 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
5770 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5771 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5773 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
5774 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5775 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5776 levels = IDirect3DTexture9_GetLevelCount(texture);
5777 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5778 IDirect3DTexture9_Release(texture);
5780 refcount = IDirect3DDevice9_Release(device);
5781 ok(!refcount, "Device has %u references left.\n", refcount);
5782 IDirect3D9_Release(d3d);
5783 DestroyWindow(window);
5786 static void test_filter(void)
5788 static const struct
5790 DWORD magfilter, minfilter, mipfilter;
5791 BOOL has_texture;
5792 HRESULT result;
5794 tests[] =
5796 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5797 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5798 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5799 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
5800 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
5802 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5803 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5804 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
5805 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
5807 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5808 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5809 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
5810 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
5811 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
5813 IDirect3DTexture9 *texture;
5814 IDirect3DDevice9 *device;
5815 IDirect3D9 *d3d;
5816 unsigned int i;
5817 ULONG refcount;
5818 DWORD passes;
5819 HWND window;
5820 HRESULT hr;
5822 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5823 ok(!!d3d, "Failed to create a D3D object.\n");
5825 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5826 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
5828 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
5829 IDirect3D9_Release(d3d);
5830 return;
5833 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5834 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
5836 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
5837 IDirect3D9_Release(d3d);
5838 return;
5841 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5842 0, 0, 640, 480, 0, 0, 0, 0);
5843 if (!(device = create_device(d3d, window, NULL)))
5845 skip("Failed to create a D3D device, skipping tests.\n");
5846 IDirect3D9_Release(d3d);
5847 DestroyWindow(window);
5848 return;
5851 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
5852 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
5853 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5855 /* Needed for ValidateDevice(). */
5856 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5857 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5859 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
5861 if (tests[i].has_texture)
5863 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
5864 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5866 else
5868 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5869 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5872 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
5873 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5874 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
5875 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5876 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
5877 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5879 passes = 0xdeadbeef;
5880 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
5881 ok(hr == tests[i].result,
5882 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
5883 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
5884 tests[i].mipfilter, tests[i].has_texture);
5885 if (SUCCEEDED(hr))
5886 ok(!!passes, "Got unexpected passes %#x.\n", passes);
5887 else
5888 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
5891 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5892 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5893 IDirect3DTexture9_Release(texture);
5895 refcount = IDirect3DDevice9_Release(device);
5896 ok(!refcount, "Device has %u references left.\n", refcount);
5897 IDirect3D9_Release(d3d);
5898 DestroyWindow(window);
5901 static void test_get_texture(void)
5903 IDirect3DBaseTexture9 *texture;
5904 IDirect3DDevice9 *device;
5905 IDirect3D9 *d3d;
5906 ULONG refcount;
5907 HWND window;
5908 HRESULT hr;
5910 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5911 0, 0, 640, 480, 0, 0, 0, 0);
5912 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5913 ok(!!d3d, "Failed to create a D3D object.\n");
5914 if (!(device = create_device(d3d, window, NULL)))
5916 skip("Failed to create a D3D device, skipping tests.\n");
5917 IDirect3D9_Release(d3d);
5918 DestroyWindow(window);
5919 return;
5922 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
5923 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5924 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5925 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
5926 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5927 ok(!texture, "Got unexpected texture %p.\n", texture);
5929 refcount = IDirect3DDevice9_Release(device);
5930 ok(!refcount, "Device has %u references left.\n", refcount);
5931 IDirect3D9_Release(d3d);
5932 DestroyWindow(window);
5935 static void test_lod(void)
5937 IDirect3DTexture9 *texture;
5938 IDirect3DDevice9 *device;
5939 IDirect3D9 *d3d;
5940 ULONG refcount;
5941 HWND window;
5942 HRESULT hr;
5943 DWORD ret;
5945 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5946 0, 0, 640, 480, 0, 0, 0, 0);
5947 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5948 ok(!!d3d, "Failed to create a D3D object.\n");
5949 if (!(device = create_device(d3d, window, NULL)))
5951 skip("Failed to create a D3D device, skipping tests.\n");
5952 IDirect3D9_Release(d3d);
5953 DestroyWindow(window);
5954 return;
5957 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5958 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5959 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5961 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5962 * return a HRESULT, so it can't return a normal error. Instead, the call
5963 * is simply ignored. */
5964 ret = IDirect3DTexture9_SetLOD(texture, 0);
5965 ok(!ret, "Got unexpected ret %u.\n", ret);
5966 ret = IDirect3DTexture9_SetLOD(texture, 1);
5967 ok(!ret, "Got unexpected ret %u.\n", ret);
5968 ret = IDirect3DTexture9_SetLOD(texture, 2);
5969 ok(!ret, "Got unexpected ret %u.\n", ret);
5970 ret = IDirect3DTexture9_GetLOD(texture);
5971 ok(!ret, "Got unexpected ret %u.\n", ret);
5973 IDirect3DTexture9_Release(texture);
5974 refcount = IDirect3DDevice9_Release(device);
5975 ok(!refcount, "Device has %u references left.\n", refcount);
5976 IDirect3D9_Release(d3d);
5977 DestroyWindow(window);
5980 static void test_surface_get_container(void)
5982 IDirect3DTexture9 *texture = NULL;
5983 IDirect3DSurface9 *surface = NULL;
5984 IDirect3DDevice9 *device;
5985 IUnknown *container;
5986 IDirect3D9 *d3d;
5987 ULONG refcount;
5988 HWND window;
5989 HRESULT hr;
5991 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5992 0, 0, 640, 480, 0, 0, 0, 0);
5993 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5994 ok(!!d3d, "Failed to create a D3D object.\n");
5995 if (!(device = create_device(d3d, window, NULL)))
5997 skip("Failed to create a D3D device, skipping tests.\n");
5998 IDirect3D9_Release(d3d);
5999 DestroyWindow(window);
6000 return;
6003 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
6004 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6005 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6006 ok(!!texture, "Got unexpected texture %p.\n", texture);
6008 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6009 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
6010 ok(!!surface, "Got unexpected surface %p.\n", surface);
6012 /* These should work... */
6013 container = NULL;
6014 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
6015 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
6016 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6017 IUnknown_Release(container);
6019 container = NULL;
6020 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
6021 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
6022 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6023 IUnknown_Release(container);
6025 container = NULL;
6026 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
6027 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
6028 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6029 IUnknown_Release(container);
6031 container = NULL;
6032 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
6033 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
6034 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6035 IUnknown_Release(container);
6037 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
6038 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
6039 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
6040 ok(!container, "Got unexpected container %p.\n", container);
6042 IDirect3DSurface9_Release(surface);
6043 IDirect3DTexture9_Release(texture);
6044 refcount = IDirect3DDevice9_Release(device);
6045 ok(!refcount, "Device has %u references left.\n", refcount);
6046 IDirect3D9_Release(d3d);
6047 DestroyWindow(window);
6050 static void test_surface_alignment(void)
6052 IDirect3DSurface9 *surface;
6053 IDirect3DDevice9 *device;
6054 D3DLOCKED_RECT lr;
6055 unsigned int i, j;
6056 IDirect3D9 *d3d;
6057 ULONG refcount;
6058 HWND window;
6059 HRESULT hr;
6061 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6062 0, 0, 640, 480, 0, 0, 0, 0);
6063 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6064 ok(!!d3d, "Failed to create a D3D object.\n");
6065 if (!(device = create_device(d3d, window, NULL)))
6067 skip("Failed to create a D3D device, skipping tests.\n");
6068 IDirect3D9_Release(d3d);
6069 DestroyWindow(window);
6070 return;
6073 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
6074 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
6075 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
6076 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6078 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6079 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6080 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
6081 /* Some applications also depend on the exact pitch, rather than just the
6082 * alignment. */
6083 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
6084 hr = IDirect3DSurface9_UnlockRect(surface);
6085 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6086 IDirect3DSurface9_Release(surface);
6088 for (i = 0; i < 5; ++i)
6090 IDirect3DTexture9 *texture;
6091 unsigned int level_count;
6092 D3DSURFACE_DESC desc;
6093 int expected_pitch;
6095 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
6096 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
6097 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6098 if (FAILED(hr))
6100 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
6101 continue;
6104 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
6105 for (j = 0; j < level_count; ++j)
6107 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
6108 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
6109 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6110 hr = IDirect3DTexture9_UnlockRect(texture, j);
6111 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6113 expected_pitch = ((desc.Width + 3) >> 2) << 3;
6114 if (i > 0)
6115 expected_pitch <<= 1;
6116 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
6117 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
6119 IDirect3DTexture9_Release(texture);
6122 refcount = IDirect3DDevice9_Release(device);
6123 ok(!refcount, "Device has %u references left.\n", refcount);
6124 IDirect3D9_Release(d3d);
6125 DestroyWindow(window);
6128 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
6129 * different from regular formats. This test verifies we return the correct
6130 * memory offsets. */
6131 static void test_lockrect_offset(void)
6133 static const struct
6135 D3DFORMAT format;
6136 const char *name;
6137 unsigned int block_width;
6138 unsigned int block_height;
6139 unsigned int block_size;
6141 dxt_formats[] =
6143 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
6144 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
6145 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
6146 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
6147 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
6148 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
6150 unsigned int expected_offset, offset, i;
6151 const RECT rect = {60, 60, 68, 68};
6152 IDirect3DSurface9 *surface;
6153 D3DLOCKED_RECT locked_rect;
6154 IDirect3DDevice9 *device;
6155 int expected_pitch;
6156 IDirect3D9 *d3d;
6157 ULONG refcount;
6158 HWND window;
6159 BYTE *base;
6160 HRESULT hr;
6162 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6163 0, 0, 640, 480, 0, 0, 0, 0);
6164 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6165 ok(!!d3d, "Failed to create a D3D object.\n");
6166 if (!(device = create_device(d3d, window, NULL)))
6168 skip("Failed to create a D3D device, skipping tests.\n");
6169 IDirect3D9_Release(d3d);
6170 DestroyWindow(window);
6171 return;
6174 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
6176 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6177 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
6179 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
6180 continue;
6183 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
6184 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
6185 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6187 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6188 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6190 base = locked_rect.pBits;
6191 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
6192 * dxt_formats[i].block_size;
6193 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
6194 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
6196 hr = IDirect3DSurface9_UnlockRect(surface);
6197 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6199 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
6200 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6202 offset = (BYTE *)locked_rect.pBits - base;
6203 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
6204 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
6205 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
6206 offset, dxt_formats[i].name, expected_offset);
6208 hr = IDirect3DSurface9_UnlockRect(surface);
6209 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6211 IDirect3DSurface9_Release(surface);
6214 refcount = IDirect3DDevice9_Release(device);
6215 ok(!refcount, "Device has %u references left.\n", refcount);
6216 IDirect3D9_Release(d3d);
6217 DestroyWindow(window);
6220 static void test_lockrect_invalid(void)
6222 static const struct
6224 RECT rect;
6225 HRESULT win7_result;
6227 test_data[] =
6229 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
6230 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
6231 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
6232 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
6233 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
6234 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
6235 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
6236 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
6237 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
6238 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
6239 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
6240 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
6241 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
6243 static const RECT test_rect_2 = {0, 0, 8, 8};
6244 IDirect3DSurface9 *surface = NULL;
6245 D3DLOCKED_RECT locked_rect;
6246 IDirect3DDevice9 *device;
6247 IDirect3D9 *d3d;
6248 unsigned int i;
6249 ULONG refcount;
6250 HWND window;
6251 BYTE *base;
6252 HRESULT hr;
6254 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6255 0, 0, 640, 480, 0, 0, 0, 0);
6256 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6257 ok(!!d3d, "Failed to create a D3D object.\n");
6258 if (!(device = create_device(d3d, window, NULL)))
6260 skip("Failed to create a D3D device, skipping tests.\n");
6261 IDirect3D9_Release(d3d);
6262 DestroyWindow(window);
6263 return;
6266 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
6267 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6268 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6269 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6270 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6271 base = locked_rect.pBits;
6272 hr = IDirect3DSurface9_UnlockRect(surface);
6273 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6275 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
6277 unsigned int offset, expected_offset;
6278 const RECT *rect = &test_data[i].rect;
6280 locked_rect.pBits = (BYTE *)0xdeadbeef;
6281 locked_rect.Pitch = 0xdeadbeef;
6283 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
6284 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
6285 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
6286 * one broken. */
6287 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
6288 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
6289 rect->left, rect->top, rect->right, rect->bottom, hr);
6290 if (FAILED(hr))
6291 continue;
6293 offset = (BYTE *)locked_rect.pBits - base;
6294 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
6295 ok(offset == expected_offset,
6296 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
6297 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
6299 hr = IDirect3DSurface9_UnlockRect(surface);
6300 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6303 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6304 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
6305 locked_rect.pBits = (BYTE *)0xdeadbeef;
6306 locked_rect.Pitch = 1;
6307 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6308 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6309 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p\n",
6310 locked_rect.pBits);
6311 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d\n", locked_rect.Pitch);
6312 hr = IDirect3DSurface9_UnlockRect(surface);
6313 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6315 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
6316 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
6317 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
6318 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
6319 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
6320 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
6321 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
6322 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
6323 hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
6324 hr = IDirect3DSurface9_UnlockRect(surface);
6325 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6327 IDirect3DSurface9_Release(surface);
6328 refcount = IDirect3DDevice9_Release(device);
6329 ok(!refcount, "Device has %u references left.\n", refcount);
6330 IDirect3D9_Release(d3d);
6331 DestroyWindow(window);
6334 static void test_private_data(void)
6336 ULONG refcount, expected_refcount;
6337 IDirect3DTexture9 *texture;
6338 IDirect3DSurface9 *surface, *surface2;
6339 IDirect3DDevice9 *device;
6340 IDirect3D9 *d3d;
6341 IUnknown *ptr;
6342 HWND window;
6343 HRESULT hr;
6344 DWORD size;
6345 DWORD data[4] = {1, 2, 3, 4};
6346 static const GUID d3d9_private_data_test_guid =
6348 0xfdb37466,
6349 0x428f,
6350 0x4edf,
6351 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
6353 static const GUID d3d9_private_data_test_guid2 =
6355 0x2e5afac2,
6356 0x87b5,
6357 0x4c10,
6358 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
6361 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6362 0, 0, 640, 480, 0, 0, 0, 0);
6363 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6364 ok(!!d3d, "Failed to create a D3D object.\n");
6365 if (!(device = create_device(d3d, window, NULL)))
6367 skip("Failed to create a D3D device, skipping tests.\n");
6368 IDirect3D9_Release(d3d);
6369 DestroyWindow(window);
6370 return;
6373 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
6374 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6375 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6377 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6378 device, 0, D3DSPD_IUNKNOWN);
6379 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6380 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6381 device, 5, D3DSPD_IUNKNOWN);
6382 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6383 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6384 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
6385 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6387 /* A failing SetPrivateData call does not clear the old data with the same tag. */
6388 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
6389 sizeof(device), D3DSPD_IUNKNOWN);
6390 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6391 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
6392 sizeof(device) * 2, D3DSPD_IUNKNOWN);
6393 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6394 size = sizeof(ptr);
6395 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6396 ok(SUCCEEDED(hr), "Failed to get private data, hr %#x.\n", hr);
6397 IUnknown_Release(ptr);
6398 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6399 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6401 refcount = get_refcount((IUnknown *)device);
6402 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6403 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6404 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6405 expected_refcount = refcount + 1;
6406 refcount = get_refcount((IUnknown *)device);
6407 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6408 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6409 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6410 expected_refcount = refcount - 1;
6411 refcount = get_refcount((IUnknown *)device);
6412 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6414 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6415 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6416 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6417 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6418 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6419 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6420 refcount = get_refcount((IUnknown *)device);
6421 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6423 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6424 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6425 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6426 size = 2 * sizeof(ptr);
6427 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6428 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6429 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6430 expected_refcount = refcount + 2;
6431 refcount = get_refcount((IUnknown *)device);
6432 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6433 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
6434 IUnknown_Release(ptr);
6435 expected_refcount--;
6437 ptr = (IUnknown *)0xdeadbeef;
6438 size = 1;
6439 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
6440 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6441 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6442 size = 2 * sizeof(ptr);
6443 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
6444 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6445 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6446 refcount = get_refcount((IUnknown *)device);
6447 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6448 size = 1;
6449 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6450 ok(hr == D3DERR_MOREDATA, "Got unexpected hr %#x.\n", hr);
6451 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6452 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
6453 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, NULL, NULL);
6454 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6455 size = 0xdeadbabe;
6456 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, &ptr, &size);
6457 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6458 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
6459 ok(size == 0xdeadbabe, "Got unexpected size %u.\n", size);
6460 /* GetPrivateData with size = NULL causes an access violation on Windows if the
6461 * requested data exists. */
6463 /* Destroying the surface frees the held reference. */
6464 IDirect3DSurface9_Release(surface);
6465 expected_refcount = refcount - 2;
6466 refcount = get_refcount((IUnknown *)device);
6467 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6469 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH,
6470 &texture, NULL);
6471 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6472 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6473 ok(SUCCEEDED(hr), "Failed to get texture level 0, hr %#x.\n", hr);
6474 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
6475 ok(SUCCEEDED(hr), "Failed to get texture level 1, hr %#x.\n", hr);
6477 hr = IDirect3DTexture9_SetPrivateData(texture, &d3d9_private_data_test_guid, data, sizeof(data), 0);
6478 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6480 memset(data, 0, sizeof(data));
6481 size = sizeof(data);
6482 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, data, &size);
6483 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6484 hr = IDirect3DTexture9_GetPrivateData(texture, &d3d9_private_data_test_guid, data, &size);
6485 ok(SUCCEEDED(hr), "Failed to get private data, hr %#x.\n", hr);
6486 ok(data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4,
6487 "Got unexpected private data: %u, %u, %u, %u.\n", data[0], data[1], data[2], data[3]);
6489 hr = IDirect3DTexture9_FreePrivateData(texture, &d3d9_private_data_test_guid);
6490 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6492 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, data, sizeof(data), 0);
6493 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6494 hr = IDirect3DSurface9_GetPrivateData(surface2, &d3d9_private_data_test_guid, data, &size);
6495 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6497 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6498 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6500 IDirect3DSurface9_Release(surface2);
6501 IDirect3DSurface9_Release(surface);
6502 IDirect3DTexture9_Release(texture);
6504 refcount = IDirect3DDevice9_Release(device);
6505 ok(!refcount, "Device has %u references left.\n", refcount);
6506 IDirect3D9_Release(d3d);
6507 DestroyWindow(window);
6510 static void test_getdc(void)
6512 static const struct
6514 const char *name;
6515 D3DFORMAT format;
6516 BOOL getdc_supported;
6518 testdata[] =
6520 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, TRUE },
6521 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, TRUE },
6522 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, TRUE },
6523 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, TRUE },
6524 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, TRUE },
6525 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8, TRUE },
6526 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
6527 {"D3DFMT_V8U8", D3DFMT_V8U8, FALSE},
6528 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8, FALSE},
6529 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
6530 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
6531 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2, FALSE},
6532 {"D3DFMT_P8", D3DFMT_P8, FALSE},
6533 {"D3DFMT_L8", D3DFMT_L8, FALSE},
6534 {"D3DFMT_A8L8", D3DFMT_A8L8, FALSE},
6535 {"D3DFMT_DXT1", D3DFMT_DXT1, FALSE},
6536 {"D3DFMT_DXT2", D3DFMT_DXT2, FALSE},
6537 {"D3DFMT_DXT3", D3DFMT_DXT3, FALSE},
6538 {"D3DFMT_DXT4", D3DFMT_DXT4, FALSE},
6539 {"D3DFMT_DXT5", D3DFMT_DXT5, FALSE},
6541 IDirect3DTexture9 *texture;
6542 IDirect3DSurface9 *surface;
6543 IDirect3DDevice9 *device;
6544 IDirect3D9 *d3d;
6545 unsigned int i;
6546 ULONG refcount;
6547 HWND window;
6548 HRESULT hr;
6549 HDC dc;
6551 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6552 0, 0, 640, 480, 0, 0, 0, 0);
6553 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6554 ok(!!d3d, "Failed to create a D3D object.\n");
6555 if (!(device = create_device(d3d, window, NULL)))
6557 skip("Failed to create a D3D device, skipping tests.\n");
6558 IDirect3D9_Release(d3d);
6559 DestroyWindow(window);
6560 return;
6563 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
6565 texture = NULL;
6566 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
6567 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
6568 if (FAILED(hr))
6570 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
6571 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
6572 if (FAILED(hr))
6574 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
6575 continue;
6577 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6578 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
6581 dc = (void *)0x1234;
6582 hr = IDirect3DSurface9_GetDC(surface, &dc);
6583 if (testdata[i].getdc_supported)
6584 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
6585 else
6586 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
6588 if (SUCCEEDED(hr))
6590 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
6591 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
6593 else
6595 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
6598 IDirect3DSurface9_Release(surface);
6599 if (texture)
6600 IDirect3DTexture9_Release(texture);
6603 refcount = IDirect3DDevice9_Release(device);
6604 ok(!refcount, "Device has %u references left.\n", refcount);
6605 IDirect3D9_Release(d3d);
6606 DestroyWindow(window);
6609 static void test_surface_dimensions(void)
6611 IDirect3DSurface9 *surface;
6612 IDirect3DDevice9 *device;
6613 IDirect3D9 *d3d;
6614 ULONG refcount;
6615 HWND window;
6616 HRESULT hr;
6618 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6619 0, 0, 640, 480, 0, 0, 0, 0);
6620 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6621 ok(!!d3d, "Failed to create a D3D object.\n");
6622 if (!(device = create_device(d3d, window, NULL)))
6624 skip("Failed to create a D3D device, skipping tests.\n");
6625 IDirect3D9_Release(d3d);
6626 DestroyWindow(window);
6627 return;
6630 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
6631 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6632 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6633 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
6634 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6635 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6637 refcount = IDirect3DDevice9_Release(device);
6638 ok(!refcount, "Device has %u references left.\n", refcount);
6639 IDirect3D9_Release(d3d);
6640 DestroyWindow(window);
6643 static void test_surface_format_null(void)
6645 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
6646 IDirect3DTexture9 *texture;
6647 IDirect3DSurface9 *surface;
6648 IDirect3DSurface9 *rt, *ds;
6649 D3DLOCKED_RECT locked_rect;
6650 IDirect3DDevice9 *device;
6651 D3DSURFACE_DESC desc;
6652 IDirect3D9 *d3d;
6653 ULONG refcount;
6654 HWND window;
6655 HRESULT hr;
6657 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6658 ok(!!d3d, "Failed to create a D3D object.\n");
6660 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6661 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
6662 if (hr != D3D_OK)
6664 skip("No D3DFMT_NULL support, skipping test.\n");
6665 IDirect3D9_Release(d3d);
6666 return;
6669 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6670 0, 0, 640, 480, 0, 0, 0, 0);
6671 if (!(device = create_device(d3d, window, NULL)))
6673 skip("Failed to create a D3D device, skipping tests.\n");
6674 IDirect3D9_Release(d3d);
6675 DestroyWindow(window);
6676 return;
6679 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6680 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
6681 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
6683 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6684 D3DFMT_NULL, D3DFMT_D24S8);
6685 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
6687 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
6688 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
6689 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
6691 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
6692 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
6694 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
6695 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
6697 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
6698 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
6700 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
6701 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6703 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
6704 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
6706 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
6707 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
6709 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
6710 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6712 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
6713 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
6715 IDirect3DSurface9_Release(rt);
6716 IDirect3DSurface9_Release(ds);
6718 hr = IDirect3DSurface9_GetDesc(surface, &desc);
6719 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
6720 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
6721 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
6723 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6724 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6725 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
6726 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
6728 hr = IDirect3DSurface9_UnlockRect(surface);
6729 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6731 IDirect3DSurface9_Release(surface);
6733 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
6734 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
6735 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6736 IDirect3DTexture9_Release(texture);
6738 refcount = IDirect3DDevice9_Release(device);
6739 ok(!refcount, "Device has %u references left.\n", refcount);
6740 IDirect3D9_Release(d3d);
6741 DestroyWindow(window);
6744 static void test_surface_double_unlock(void)
6746 static const D3DPOOL pools[] =
6748 D3DPOOL_DEFAULT,
6749 D3DPOOL_SCRATCH,
6750 D3DPOOL_SYSTEMMEM,
6752 IDirect3DSurface9 *surface;
6753 IDirect3DDevice9 *device;
6754 D3DLOCKED_RECT lr;
6755 IDirect3D9 *d3d;
6756 unsigned int i;
6757 ULONG refcount;
6758 HWND window;
6759 HRESULT hr;
6761 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6762 0, 0, 640, 480, 0, 0, 0, 0);
6763 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6764 ok(!!d3d, "Failed to create a D3D object.\n");
6765 if (!(device = create_device(d3d, window, NULL)))
6767 skip("Failed to create a D3D device, skipping tests.\n");
6768 IDirect3D9_Release(d3d);
6769 DestroyWindow(window);
6770 return;
6773 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
6775 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
6776 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
6777 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
6779 hr = IDirect3DSurface9_UnlockRect(surface);
6780 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
6781 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6782 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
6783 hr = IDirect3DSurface9_UnlockRect(surface);
6784 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
6785 hr = IDirect3DSurface9_UnlockRect(surface);
6786 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
6788 IDirect3DSurface9_Release(surface);
6791 refcount = IDirect3DDevice9_Release(device);
6792 ok(!refcount, "Device has %u references left.\n", refcount);
6793 IDirect3D9_Release(d3d);
6794 DestroyWindow(window);
6797 static void test_surface_blocks(void)
6799 static const struct
6801 D3DFORMAT fmt;
6802 const char *name;
6803 unsigned int block_width;
6804 unsigned int block_height;
6805 BOOL broken;
6806 BOOL create_size_checked, core_fmt;
6808 formats[] =
6810 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE, TRUE, TRUE },
6811 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE, TRUE, TRUE },
6812 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE, TRUE, TRUE },
6813 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE, TRUE, TRUE },
6814 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE, TRUE, TRUE },
6815 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
6816 * which doesn't match the format spec. On newer Nvidia cards
6817 * it has the correct 4x4 block size */
6818 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE, FALSE, FALSE},
6819 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE, FALSE, TRUE },
6820 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE, FALSE, TRUE },
6822 static const struct
6824 D3DPOOL pool;
6825 const char *name;
6826 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
6827 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
6828 BOOL success;
6830 pools[] =
6832 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
6833 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
6834 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
6835 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
6837 static struct
6839 D3DRESOURCETYPE rtype;
6840 const char *type_name;
6841 D3DPOOL pool;
6842 const char *pool_name;
6843 BOOL need_driver_support, need_runtime_support;
6845 create_tests[] =
6847 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6848 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, TRUE },
6849 /* Managed offscreen plain surfaces are not supported */
6850 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6852 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6853 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
6854 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
6855 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6857 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6858 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
6859 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
6860 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6862 IDirect3DTexture9 *texture;
6863 IDirect3DCubeTexture9 *cube_texture;
6864 IDirect3DSurface9 *surface;
6865 D3DLOCKED_RECT locked_rect;
6866 IDirect3DDevice9 *device;
6867 unsigned int i, j, w, h;
6868 BOOL surface_only;
6869 IDirect3D9 *d3d;
6870 ULONG refcount;
6871 HWND window;
6872 HRESULT hr;
6873 RECT rect;
6874 BOOL tex_pow2, cube_pow2;
6875 D3DCAPS9 caps;
6877 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6878 0, 0, 640, 480, 0, 0, 0, 0);
6879 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6880 ok(!!d3d, "Failed to create a D3D object.\n");
6881 if (!(device = create_device(d3d, window, NULL)))
6883 skip("Failed to create a D3D device, skipping tests.\n");
6884 IDirect3D9_Release(d3d);
6885 DestroyWindow(window);
6886 return;
6889 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6890 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6891 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
6892 if (tex_pow2)
6893 tex_pow2 = !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
6894 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
6896 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
6898 BOOL tex_support, cube_support, surface_support, format_known, dynamic_tex_support;
6900 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6901 0, D3DRTYPE_TEXTURE, formats[i].fmt);
6902 tex_support = SUCCEEDED(hr);
6903 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6904 0, D3DRTYPE_CUBETEXTURE, formats[i].fmt);
6905 cube_support = SUCCEEDED(hr);
6906 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6907 0, D3DRTYPE_SURFACE, formats[i].fmt);
6908 surface_support = SUCCEEDED(hr);
6910 /* Scratch pool in general allows texture creation even if the driver does
6911 * not support the format. If the format is an extension format that is not
6912 * known to the runtime, like ATI2N, some driver support is required for
6913 * this to work.
6915 * It is also possible that Windows Vista and Windows 7 d3d9 runtimes know
6916 * about ATI2N. I cannot check this because all my Vista+ machines support
6917 * ATI2N in hardware, but none of my WinXP machines do. */
6918 format_known = tex_support || cube_support || surface_support;
6920 for (w = 1; w <= 8; w++)
6922 for (h = 1; h <= 8; h++)
6924 BOOL block_aligned = TRUE;
6925 BOOL size_is_pow2;
6927 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
6928 block_aligned = FALSE;
6930 size_is_pow2 = !(w & (w - 1) || h & (h - 1));
6932 for (j = 0; j < sizeof(create_tests) / sizeof(*create_tests); j++)
6934 BOOL support, pow2;
6935 HRESULT expect_hr;
6936 BOOL may_succeed = FALSE;
6937 IUnknown **check_null;
6939 if (!formats[i].core_fmt)
6941 /* AMD warns against creating ATI2N textures smaller than
6942 * the block size because the runtime cannot calculate the
6943 * correct texture size. Generalize this for all extension
6944 * formats. */
6945 if (w < formats[i].block_width || h < formats[i].block_height)
6946 continue;
6949 texture = (IDirect3DTexture9 *)0xdeadbeef;
6950 cube_texture = (IDirect3DCubeTexture9 *)0xdeadbeef;
6951 surface = (IDirect3DSurface9 *)0xdeadbeef;
6953 switch (create_tests[j].rtype)
6955 case D3DRTYPE_TEXTURE:
6956 check_null = (IUnknown **)&texture;
6957 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1, 0,
6958 formats[i].fmt, create_tests[j].pool, &texture, NULL);
6959 support = tex_support;
6960 pow2 = tex_pow2;
6961 break;
6963 case D3DRTYPE_CUBETEXTURE:
6964 if (w != h)
6965 continue;
6966 check_null = (IUnknown **)&cube_texture;
6967 hr = IDirect3DDevice9_CreateCubeTexture(device, w, 1, 0,
6968 formats[i].fmt, create_tests[j].pool, &cube_texture, NULL);
6969 support = cube_support;
6970 pow2 = cube_pow2;
6971 break;
6973 case D3DRTYPE_SURFACE:
6974 check_null = (IUnknown **)&surface;
6975 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, w, h,
6976 formats[i].fmt, create_tests[j].pool, &surface, NULL);
6977 support = surface_support;
6978 pow2 = FALSE;
6979 break;
6981 default:
6982 check_null = NULL;
6983 pow2 = FALSE;
6984 support = FALSE;
6985 break;
6988 if (create_tests[j].need_driver_support && !support)
6989 expect_hr = D3DERR_INVALIDCALL;
6990 else if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !format_known)
6991 expect_hr = D3DERR_INVALIDCALL;
6992 else if (formats[i].create_size_checked && !block_aligned)
6993 expect_hr = D3DERR_INVALIDCALL;
6994 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
6995 expect_hr = D3DERR_INVALIDCALL;
6996 else
6997 expect_hr = D3D_OK;
6999 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
7000 * does not support it. Accept scratch creation of extension formats on
7001 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
7002 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
7003 * support it. */
7004 if (!formats[i].core_fmt && !format_known && FAILED(expect_hr))
7005 may_succeed = TRUE;
7007 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
7008 "Got unexpected hr %#x for format %s, pool %s, type %s, size %ux%u.\n",
7009 hr, formats[i].name, create_tests[j].pool_name, create_tests[j].type_name, w, h);
7010 if (FAILED(hr))
7011 ok(*check_null == NULL, "Got object ptr %p, expected NULL.\n", *check_null);
7012 else
7013 IUnknown_Release(*check_null);
7018 surface_only = FALSE;
7019 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7020 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt);
7021 dynamic_tex_support = SUCCEEDED(hr);
7022 if (!dynamic_tex_support)
7024 if (!surface_support)
7026 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
7027 continue;
7029 surface_only = TRUE;
7032 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
7034 switch (pools[j].pool)
7036 case D3DPOOL_SYSTEMMEM:
7037 case D3DPOOL_MANAGED:
7038 if (surface_only)
7039 continue;
7040 /* Fall through */
7041 case D3DPOOL_DEFAULT:
7042 if (surface_only)
7044 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
7045 formats[i].fmt, pools[j].pool, &surface, NULL);
7046 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
7048 else
7050 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
7051 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
7052 formats[i].fmt, pools[j].pool, &texture, NULL);
7053 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7054 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7055 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
7056 IDirect3DTexture9_Release(texture);
7058 break;
7060 case D3DPOOL_SCRATCH:
7061 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
7062 formats[i].fmt, pools[j].pool, &surface, NULL);
7063 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
7064 break;
7066 default:
7067 break;
7070 if (formats[i].block_width > 1)
7072 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
7073 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7074 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
7075 "Partial block lock %s, expected %s, format %s, pool %s.\n",
7076 SUCCEEDED(hr) ? "succeeded" : "failed",
7077 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
7078 if (SUCCEEDED(hr))
7080 hr = IDirect3DSurface9_UnlockRect(surface);
7081 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7084 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
7085 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7086 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
7087 "Partial block lock %s, expected %s, format %s, pool %s.\n",
7088 SUCCEEDED(hr) ? "succeeded" : "failed",
7089 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
7090 if (SUCCEEDED(hr))
7092 hr = IDirect3DSurface9_UnlockRect(surface);
7093 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7097 if (formats[i].block_height > 1)
7099 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
7100 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7101 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
7102 "Partial block lock %s, expected %s, format %s, pool %s.\n",
7103 SUCCEEDED(hr) ? "succeeded" : "failed",
7104 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
7105 if (SUCCEEDED(hr))
7107 hr = IDirect3DSurface9_UnlockRect(surface);
7108 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7111 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
7112 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7113 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
7114 "Partial block lock %s, expected %s, format %s, pool %s.\n",
7115 SUCCEEDED(hr) ? "succeeded" : "failed",
7116 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
7117 if (SUCCEEDED(hr))
7119 hr = IDirect3DSurface9_UnlockRect(surface);
7120 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7124 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
7125 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7126 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
7127 hr = IDirect3DSurface9_UnlockRect(surface);
7128 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7130 IDirect3DSurface9_Release(surface);
7133 if (!dynamic_tex_support)
7135 skip("Dynamic %s textures not supported, skipping mipmap test.\n", formats[i].name);
7136 continue;
7139 if (formats[i].block_width == 1 && formats[i].block_height == 1)
7140 continue;
7141 if (!formats[i].core_fmt)
7142 continue;
7144 hr = IDirect3DDevice9_CreateTexture(device, formats[i].block_width, formats[i].block_height, 2,
7145 D3DUSAGE_DYNAMIC, formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
7146 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, format %s.\n", hr, formats[i].name);
7148 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, NULL, 0);
7149 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
7150 hr = IDirect3DTexture9_UnlockRect(texture, 1);
7151 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
7153 rect.left = 0;
7154 rect.top = 0;
7155 rect.right = formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1;
7156 rect.bottom = formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1;
7157 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
7158 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
7159 hr = IDirect3DTexture9_UnlockRect(texture, 1);
7160 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
7162 rect.right = formats[i].block_width;
7163 rect.bottom = formats[i].block_height;
7164 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
7165 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7166 if (SUCCEEDED(hr))
7167 IDirect3DTexture9_UnlockRect(texture, 1);
7169 IDirect3DTexture9_Release(texture);
7172 refcount = IDirect3DDevice9_Release(device);
7173 ok(!refcount, "Device has %u references left.\n", refcount);
7174 IDirect3D9_Release(d3d);
7175 DestroyWindow(window);
7178 static void test_set_palette(void)
7180 IDirect3DDevice9 *device;
7181 IDirect3D9 *d3d9;
7182 UINT refcount;
7183 HWND window;
7184 HRESULT hr;
7185 PALETTEENTRY pal[256];
7186 unsigned int i;
7187 D3DCAPS9 caps;
7189 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7190 0, 0, 640, 480, 0, 0, 0, 0);
7191 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7192 ok(!!d3d9, "Failed to create a D3D object.\n");
7193 if (!(device = create_device(d3d9, window, NULL)))
7195 skip("Failed to create a D3D device, skipping tests.\n");
7196 DestroyWindow(window);
7197 return;
7200 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
7202 pal[i].peRed = i;
7203 pal[i].peGreen = i;
7204 pal[i].peBlue = i;
7205 pal[i].peFlags = 0xff;
7207 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
7208 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
7210 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7211 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7212 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
7214 pal[i].peRed = i;
7215 pal[i].peGreen = i;
7216 pal[i].peBlue = i;
7217 pal[i].peFlags = i;
7219 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
7221 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
7222 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
7224 else
7226 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
7227 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
7230 refcount = IDirect3DDevice9_Release(device);
7231 ok(!refcount, "Device has %u references left.\n", refcount);
7232 IDirect3D9_Release(d3d9);
7233 DestroyWindow(window);
7236 static void test_swvp_buffer(void)
7238 IDirect3DDevice9 *device;
7239 IDirect3D9 *d3d9;
7240 UINT refcount;
7241 HWND window;
7242 HRESULT hr;
7243 unsigned int i;
7244 IDirect3DVertexBuffer9 *buffer;
7245 static const unsigned int bufsize = 1024;
7246 D3DVERTEXBUFFER_DESC desc;
7247 struct device_desc device_desc;
7248 struct
7250 float x, y, z;
7251 } *ptr, *ptr2;
7253 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7254 0, 0, 640, 480, 0, 0, 0, 0);
7255 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7256 ok(!!d3d9, "Failed to create a D3D object.\n");
7258 device_desc.device_window = window;
7259 device_desc.width = 640;
7260 device_desc.height = 480;
7261 device_desc.flags = CREATE_DEVICE_SWVP_ONLY;
7262 if (!(device = create_device(d3d9, window, &device_desc)))
7264 skip("Failed to create a D3D device, skipping tests.\n");
7265 DestroyWindow(window);
7266 IDirect3D9_Release(d3d9);
7267 return;
7270 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
7271 D3DPOOL_DEFAULT, &buffer, NULL);
7272 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
7273 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
7274 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
7275 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
7276 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
7277 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
7279 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
7280 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
7281 for (i = 0; i < bufsize; i++)
7283 ptr[i].x = i * 1.0f;
7284 ptr[i].y = i * 2.0f;
7285 ptr[i].z = i * 3.0f;
7287 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7288 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
7290 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7291 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
7292 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
7293 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
7294 hr = IDirect3DDevice9_BeginScene(device);
7295 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7296 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
7297 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7298 hr = IDirect3DDevice9_EndScene(device);
7299 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7301 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
7302 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
7303 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
7304 for (i = 0; i < bufsize; i++)
7306 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
7308 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
7309 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
7310 break;
7313 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7314 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
7316 IDirect3DVertexBuffer9_Release(buffer);
7317 refcount = IDirect3DDevice9_Release(device);
7318 ok(!refcount, "Device has %u references left.\n", refcount);
7319 IDirect3D9_Release(d3d9);
7320 DestroyWindow(window);
7323 static void test_npot_textures(void)
7325 IDirect3DDevice9 *device = NULL;
7326 IDirect3D9 *d3d9;
7327 ULONG refcount;
7328 HWND window = NULL;
7329 HRESULT hr;
7330 D3DCAPS9 caps;
7331 IDirect3DTexture9 *texture;
7332 IDirect3DCubeTexture9 *cube_texture;
7333 IDirect3DVolumeTexture9 *volume_texture;
7334 struct
7336 D3DPOOL pool;
7337 const char *pool_name;
7338 HRESULT hr;
7340 pools[] =
7342 { D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL },
7343 { D3DPOOL_MANAGED, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL },
7344 { D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL },
7345 { D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", D3D_OK },
7347 unsigned int i, levels;
7348 BOOL tex_pow2, cube_pow2, vol_pow2;
7350 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7351 0, 0, 640, 480, 0, 0, 0, 0);
7352 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7353 ok(!!d3d9, "Failed to create a D3D object.\n");
7354 if (!(device = create_device(d3d9, window, NULL)))
7356 skip("Failed to create a D3D device, skipping tests.\n");
7357 goto done;
7360 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7361 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7362 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
7363 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
7364 vol_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
7365 ok(cube_pow2 == tex_pow2, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
7366 ok(vol_pow2 == tex_pow2, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
7368 for (i = 0; i < sizeof(pools) / sizeof(*pools); i++)
7370 for (levels = 0; levels <= 2; levels++)
7372 HRESULT expected;
7374 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, levels, 0, D3DFMT_X8R8G8B8,
7375 pools[i].pool, &texture, NULL);
7376 if (!tex_pow2)
7378 expected = D3D_OK;
7380 else if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7382 if (levels == 1)
7383 expected = D3D_OK;
7384 else
7385 expected = pools[i].hr;
7387 else
7389 expected = pools[i].hr;
7391 ok(hr == expected, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#x, expected %#x.\n",
7392 pools[i].pool_name, levels, hr, expected);
7394 if (SUCCEEDED(hr))
7395 IDirect3DTexture9_Release(texture);
7398 hr = IDirect3DDevice9_CreateCubeTexture(device, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
7399 &cube_texture, NULL);
7400 if (tex_pow2)
7402 ok(hr == pools[i].hr, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
7403 pools[i].pool_name, hr, pools[i].hr);
7405 else
7407 ok(SUCCEEDED(hr), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
7408 pools[i].pool_name, hr, D3D_OK);
7411 if (SUCCEEDED(hr))
7412 IDirect3DCubeTexture9_Release(cube_texture);
7414 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
7415 &volume_texture, NULL);
7416 if (tex_pow2)
7418 ok(hr == pools[i].hr, "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
7419 pools[i].pool_name, hr, pools[i].hr);
7421 else
7423 ok(SUCCEEDED(hr), "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
7424 pools[i].pool_name, hr, D3D_OK);
7427 if (SUCCEEDED(hr))
7428 IDirect3DVolumeTexture9_Release(volume_texture);
7431 done:
7432 if (device)
7434 refcount = IDirect3DDevice9_Release(device);
7435 ok(!refcount, "Device has %u references left.\n", refcount);
7437 IDirect3D9_Release(d3d9);
7438 DestroyWindow(window);
7442 static void test_vidmem_accounting(void)
7444 IDirect3DDevice9 *device;
7445 IDirect3D9 *d3d9;
7446 ULONG refcount;
7447 HWND window;
7448 HRESULT hr = D3D_OK;
7449 IDirect3DTexture9 *textures[20];
7450 unsigned int i;
7451 UINT vidmem_start, vidmem_end, diff;
7453 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7454 0, 0, 640, 480, 0, 0, 0, 0);
7455 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7456 ok(!!d3d9, "Failed to create a D3D object.\n");
7457 if (!(device = create_device(d3d9, window, NULL)))
7459 skip("Failed to create a D3D device, skipping tests.\n");
7460 IDirect3D9_Release(d3d9);
7461 DestroyWindow(window);
7462 return;
7465 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
7466 memset(textures, 0, sizeof(textures));
7467 for (i = 0; i < sizeof(textures) / sizeof(*textures) && SUCCEEDED(hr); i++)
7469 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
7470 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
7471 /* D3DERR_OUTOFVIDEOMEMORY is returned when the card runs out of video memory
7472 * E_FAIL is returned on address space or system memory exhaustion */
7473 ok(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY,
7474 "Failed to create texture, hr %#x.\n", hr);
7476 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
7478 ok(vidmem_start > vidmem_end, "Expected available texture memory to decrease during texture creation.\n");
7479 diff = vidmem_start - vidmem_end;
7480 ok(diff > 1024 * 1024 * 2 * i, "Expected a video memory difference of at least %u MB, got %u MB.\n",
7481 2 * i, diff / 1024 / 1024);
7483 for (i = 0; i < sizeof(textures) / sizeof(*textures); i++)
7485 if (textures[i])
7486 IDirect3DTexture9_Release(textures[i]);
7489 refcount = IDirect3DDevice9_Release(device);
7490 ok(!refcount, "Device has %u references left.\n", refcount);
7491 IDirect3D9_Release(d3d9);
7492 DestroyWindow(window);
7495 static void test_volume_locking(void)
7497 IDirect3DDevice9 *device;
7498 IDirect3D9 *d3d9;
7499 HWND window;
7500 HRESULT hr;
7501 IDirect3DVolumeTexture9 *texture;
7502 unsigned int i;
7503 D3DLOCKED_BOX locked_box;
7504 ULONG refcount;
7505 D3DCAPS9 caps;
7506 static const struct
7508 D3DPOOL pool;
7509 DWORD usage;
7510 HRESULT create_hr, lock_hr;
7512 tests[] =
7514 { D3DPOOL_DEFAULT, 0, D3D_OK, D3DERR_INVALIDCALL },
7515 { D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
7516 { D3DPOOL_SYSTEMMEM, 0, D3D_OK, D3D_OK },
7517 { D3DPOOL_SYSTEMMEM, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
7518 { D3DPOOL_MANAGED, 0, D3D_OK, D3D_OK },
7519 { D3DPOOL_MANAGED, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
7520 { D3DPOOL_SCRATCH, 0, D3D_OK, D3D_OK },
7521 { D3DPOOL_SCRATCH, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
7524 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7525 0, 0, 640, 480, 0, 0, 0, 0);
7526 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7527 ok(!!d3d9, "Failed to create a D3D object.\n");
7528 if (!(device = create_device(d3d9, window, NULL)))
7530 skip("Failed to create a D3D device, skipping tests.\n");
7531 IDirect3D9_Release(d3d9);
7532 DestroyWindow(window);
7533 return;
7536 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7537 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7538 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
7540 skip("Volume textures not supported, skipping test.\n");
7541 goto out;
7544 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
7546 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, tests[i].usage,
7547 D3DFMT_A8R8G8B8, tests[i].pool, &texture, NULL);
7548 ok(hr == tests[i].create_hr, "Creating volume texture pool=%u, usage=%#x returned %#x, expected %#x.\n",
7549 tests[i].pool, tests[i].usage, hr, tests[i].create_hr);
7550 if (FAILED(hr))
7551 continue;
7553 locked_box.pBits = (void *)0xdeadbeef;
7554 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7555 ok(hr == tests[i].lock_hr, "Lock returned %#x, expected %#x.\n", hr, tests[i].lock_hr);
7556 if (SUCCEEDED(hr))
7558 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7559 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7561 else
7563 ok(locked_box.pBits == NULL, "Failed lock set pBits = %p, expected NULL.\n", locked_box.pBits);
7565 IDirect3DVolumeTexture9_Release(texture);
7568 out:
7569 refcount = IDirect3DDevice9_Release(device);
7570 ok(!refcount, "Device has %u references left.\n", refcount);
7571 IDirect3D9_Release(d3d9);
7572 DestroyWindow(window);
7575 static void test_update_volumetexture(void)
7577 IDirect3DDevice9 *device;
7578 IDirect3D9 *d3d9;
7579 HWND window;
7580 HRESULT hr;
7581 IDirect3DVolumeTexture9 *src, *dst;
7582 unsigned int i;
7583 D3DLOCKED_BOX locked_box;
7584 ULONG refcount;
7585 D3DCAPS9 caps;
7586 static const struct
7588 D3DPOOL src_pool, dst_pool;
7589 HRESULT hr;
7591 tests[] =
7593 { D3DPOOL_DEFAULT, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7594 { D3DPOOL_MANAGED, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7595 { D3DPOOL_SYSTEMMEM, D3DPOOL_DEFAULT, D3D_OK },
7596 { D3DPOOL_SCRATCH, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7598 { D3DPOOL_DEFAULT, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7599 { D3DPOOL_MANAGED, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7600 { D3DPOOL_SYSTEMMEM, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7601 { D3DPOOL_SCRATCH, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7603 { D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7604 { D3DPOOL_MANAGED, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7605 { D3DPOOL_SYSTEMMEM, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7606 { D3DPOOL_SCRATCH, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7608 { D3DPOOL_DEFAULT, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7609 { D3DPOOL_MANAGED, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7610 { D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7611 { D3DPOOL_SCRATCH, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7613 static const struct
7615 UINT src_size, dst_size;
7616 UINT src_lvl, dst_lvl;
7617 D3DFORMAT src_fmt, dst_fmt;
7619 tests2[] =
7621 { 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7622 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7623 { 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7624 { 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7625 { 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7626 { 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different level count */
7627 { 4, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different size */
7628 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8 }, /* Different format */
7631 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7632 0, 0, 640, 480, 0, 0, 0, 0);
7633 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7634 ok(!!d3d9, "Failed to create a D3D object.\n");
7635 if (!(device = create_device(d3d9, window, NULL)))
7637 skip("Failed to create a D3D device, skipping tests.\n");
7638 IDirect3D9_Release(d3d9);
7639 DestroyWindow(window);
7640 return;
7643 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7644 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7645 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
7647 skip("Volume textures not supported, skipping test.\n");
7648 goto out;
7651 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
7653 DWORD src_usage = tests[i].src_pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0;
7654 DWORD dst_usage = tests[i].dst_pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0;
7656 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, src_usage,
7657 D3DFMT_A8R8G8B8, tests[i].src_pool, &src, NULL);
7658 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7659 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, dst_usage,
7660 D3DFMT_A8R8G8B8, tests[i].dst_pool, &dst, NULL);
7661 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7663 hr = IDirect3DVolumeTexture9_LockBox(src, 0, &locked_box, NULL, 0);
7664 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7665 *((DWORD *)locked_box.pBits) = 0x11223344;
7666 hr = IDirect3DVolumeTexture9_UnlockBox(src, 0);
7667 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7669 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
7670 ok(hr == tests[i].hr, "UpdateTexture returned %#x, expected %#x, src pool %x, dst pool %u.\n",
7671 hr, tests[i].hr, tests[i].src_pool, tests[i].dst_pool);
7673 if (SUCCEEDED(hr))
7675 DWORD content = *((DWORD *)locked_box.pBits);
7676 hr = IDirect3DVolumeTexture9_LockBox(dst, 0, &locked_box, NULL, 0);
7677 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7678 ok(content == 0x11223344, "Dest texture contained %#x, expected 0x11223344.\n", content);
7679 hr = IDirect3DVolumeTexture9_UnlockBox(dst, 0);
7680 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7682 IDirect3DVolumeTexture9_Release(src);
7683 IDirect3DVolumeTexture9_Release(dst);
7686 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
7688 skip("Mipmapped volume maps not supported.\n");
7689 goto out;
7692 for (i = 0; i < sizeof(tests2) / sizeof(*tests2); i++)
7694 hr = IDirect3DDevice9_CreateVolumeTexture(device,
7695 tests2[i].src_size, tests2[i].src_size, tests2[i].src_size,
7696 tests2[i].src_lvl, 0, tests2[i].src_fmt, D3DPOOL_SYSTEMMEM, &src, NULL);
7697 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x, case %u.\n", hr, i);
7698 hr = IDirect3DDevice9_CreateVolumeTexture(device,
7699 tests2[i].dst_size, tests2[i].dst_size, tests2[i].dst_size,
7700 tests2[i].dst_lvl, 0, tests2[i].dst_fmt, D3DPOOL_DEFAULT, &dst, NULL);
7701 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x, case %u.\n", hr, i);
7703 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
7704 if (FAILED(hr))
7705 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u.\n", hr, i);
7706 else
7707 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u.\n", hr, i);
7709 IDirect3DVolumeTexture9_Release(src);
7710 IDirect3DVolumeTexture9_Release(dst);
7713 /* As far as I can see, UpdateTexture on non-matching texture behaves like a memcpy. The raw data
7714 * stays the same in a format change, a 2x2x1 texture is copied into the first row of a 4x4x1 texture,
7715 * etc. I could not get it to segfault, but the nonexistent 5th pixel of a 2x2x1 texture is copied into
7716 * pixel 1x2x1 of a 4x4x1 texture, demonstrating a read beyond the texture's end. I suspect any bad
7717 * memory access is silently ignored by the runtime, in the kernel or on the GPU.
7719 * I'm not adding tests for this behavior until an application needs it. */
7721 out:
7722 refcount = IDirect3DDevice9_Release(device);
7723 ok(!refcount, "Device has %u references left.\n", refcount);
7724 IDirect3D9_Release(d3d9);
7725 DestroyWindow(window);
7728 static void test_create_rt_ds_fail(void)
7730 IDirect3DDevice9 *device;
7731 HWND window;
7732 HRESULT hr;
7733 ULONG refcount;
7734 IDirect3D9 *d3d9;
7735 IDirect3DSurface9 *surface;
7737 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7738 0, 0, 640, 480, 0, 0, 0, 0);
7739 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7740 ok(!!d3d9, "Failed to create a D3D object.\n");
7741 if (!(device = create_device(d3d9, window, NULL)))
7743 skip("Failed to create a D3D device, skipping tests.\n");
7744 IDirect3D9_Release(d3d9);
7745 DestroyWindow(window);
7746 return;
7749 /* Output pointer == NULL segfaults on Windows. */
7751 surface = (IDirect3DSurface9 *)0xdeadbeef;
7752 hr = IDirect3DDevice9_CreateRenderTarget(device, 4, 4, D3DFMT_D16,
7753 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
7754 ok(hr == D3DERR_INVALIDCALL, "Creating a D16 render target returned hr %#x.\n", hr);
7755 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
7756 if (SUCCEEDED(hr))
7757 IDirect3DSurface9_Release(surface);
7759 surface = (IDirect3DSurface9 *)0xdeadbeef;
7760 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 4, 4, D3DFMT_A8R8G8B8,
7761 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
7762 ok(hr == D3DERR_INVALIDCALL, "Creating a A8R8G8B8 depth stencil returned hr %#x.\n", hr);
7763 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
7764 if (SUCCEEDED(hr))
7765 IDirect3DSurface9_Release(surface);
7767 refcount = IDirect3DDevice9_Release(device);
7768 ok(!refcount, "Device has %u references left.\n", refcount);
7769 IDirect3D9_Release(d3d9);
7770 DestroyWindow(window);
7773 static void test_volume_blocks(void)
7775 IDirect3DDevice9 *device;
7776 IDirect3D9 *d3d9;
7777 UINT refcount;
7778 HWND window;
7779 HRESULT hr;
7780 D3DCAPS9 caps;
7781 IDirect3DVolumeTexture9 *texture;
7782 unsigned int w, h, d, i, j;
7783 static const struct
7785 D3DFORMAT fmt;
7786 const char *name;
7787 unsigned int block_width;
7788 unsigned int block_height;
7789 unsigned int block_depth;
7790 unsigned int block_size;
7791 BOOL broken;
7792 BOOL create_size_checked, core_fmt;
7794 formats[] =
7796 /* Scratch volumes enforce DXTn block locks, unlike their surface counterparts.
7797 * ATI2N and YUV blocks are not enforced on any tested card (r200, gtx 460). */
7798 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 1, 8, FALSE, TRUE, TRUE },
7799 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7800 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7801 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7802 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7803 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7804 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
7805 * which doesn't match the format spec. On newer Nvidia cards
7806 * it has the correct 4x4 block size */
7807 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, 1, 16, TRUE, FALSE, FALSE},
7808 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, 1, 4, TRUE, FALSE, TRUE },
7809 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, 1, 4, TRUE, FALSE, TRUE },
7811 static const struct
7813 D3DPOOL pool;
7814 const char *name;
7815 BOOL need_driver_support, need_runtime_support;
7817 create_tests[] =
7819 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
7820 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
7821 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE, FALSE},
7822 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
7824 static const struct
7826 unsigned int x, y, z, x2, y2, z2;
7828 offset_tests[] =
7830 {0, 0, 0, 8, 8, 8},
7831 {0, 0, 3, 8, 8, 8},
7832 {0, 4, 0, 8, 8, 8},
7833 {0, 4, 3, 8, 8, 8},
7834 {4, 0, 0, 8, 8, 8},
7835 {4, 0, 3, 8, 8, 8},
7836 {4, 4, 0, 8, 8, 8},
7837 {4, 4, 3, 8, 8, 8},
7839 D3DBOX box;
7840 D3DLOCKED_BOX locked_box;
7841 BYTE *base;
7842 INT expected_row_pitch, expected_slice_pitch;
7843 BOOL support, support_2d;
7844 BOOL pow2;
7845 unsigned int offset, expected_offset;
7847 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7848 0, 0, 640, 480, 0, 0, 0, 0);
7849 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7850 ok(!!d3d9, "Failed to create a D3D object.\n");
7851 if (!(device = create_device(d3d9, window, NULL)))
7853 skip("Failed to create a D3D device, skipping tests.\n");
7854 IDirect3D9_Release(d3d9);
7855 DestroyWindow(window);
7856 return;
7858 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7859 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7860 pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
7862 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
7864 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7865 0, D3DRTYPE_VOLUMETEXTURE, formats[i].fmt);
7866 support = SUCCEEDED(hr);
7867 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7868 0, D3DRTYPE_TEXTURE, formats[i].fmt);
7869 support_2d = SUCCEEDED(hr);
7871 /* Test creation restrictions */
7872 for (w = 1; w <= 8; w++)
7874 for (h = 1; h <= 8; h++)
7876 for (d = 1; d <= 8; d++)
7878 HRESULT expect_hr;
7879 BOOL size_is_pow2;
7880 BOOL block_aligned = TRUE;
7882 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
7883 block_aligned = FALSE;
7885 size_is_pow2 = !((w & (w - 1)) || (h & (h - 1)) || (d & (d - 1)));
7887 for (j = 0; j < sizeof(create_tests) / sizeof(*create_tests); j++)
7889 BOOL may_succeed = FALSE;
7890 BOOL todo = FALSE;
7892 if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !support)
7893 expect_hr = D3DERR_INVALIDCALL;
7894 else if (formats[i].create_size_checked && !block_aligned)
7895 expect_hr = D3DERR_INVALIDCALL;
7896 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
7897 expect_hr = D3DERR_INVALIDCALL;
7898 else if (create_tests[j].need_driver_support && !support)
7900 todo = support_2d;
7901 expect_hr = D3DERR_INVALIDCALL;
7903 else
7904 expect_hr = D3D_OK;
7906 texture = (IDirect3DVolumeTexture9 *)0xdeadbeef;
7907 hr = IDirect3DDevice9_CreateVolumeTexture(device, w, h, d, 1, 0,
7908 formats[i].fmt, create_tests[j].pool, &texture, NULL);
7910 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
7911 * does not support it. Accept scratch creation of extension formats on
7912 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
7913 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
7914 * support it. */
7915 if (!formats[i].core_fmt && !support && FAILED(expect_hr))
7916 may_succeed = TRUE;
7918 if (todo)
7920 todo_wine ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
7921 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
7922 hr, formats[i].name, create_tests[j].name, w, h, d);
7924 else
7926 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
7927 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
7928 hr, formats[i].name, create_tests[j].name, w, h, d);
7931 if (FAILED(hr))
7932 ok(texture == NULL, "Got texture ptr %p, expected NULL.\n", texture);
7933 else
7934 IDirect3DVolumeTexture9_Release(texture);
7940 if (!support && !formats[i].core_fmt)
7941 continue;
7943 hr = IDirect3DDevice9_CreateVolumeTexture(device, 24, 8, 8, 1, 0,
7944 formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
7945 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7947 /* Test lockrect offset */
7948 for (j = 0; j < sizeof(offset_tests) / sizeof(*offset_tests); j++)
7950 unsigned int bytes_per_pixel;
7951 bytes_per_pixel = formats[i].block_size / (formats[i].block_width * formats[i].block_height);
7953 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7954 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7956 base = locked_box.pBits;
7957 if (formats[i].broken)
7959 expected_row_pitch = bytes_per_pixel * 24;
7961 else
7963 expected_row_pitch = (24 /* tex width */ + formats[i].block_height - 1) / formats[i].block_width
7964 * formats[i].block_size;
7966 ok(locked_box.RowPitch == expected_row_pitch, "Got unexpected row pitch %d for format %s, expected %d.\n",
7967 locked_box.RowPitch, formats[i].name, expected_row_pitch);
7969 if (formats[i].broken)
7971 expected_slice_pitch = expected_row_pitch * 8;
7973 else
7975 expected_slice_pitch = (8 /* tex height */ + formats[i].block_depth - 1) / formats[i].block_height
7976 * expected_row_pitch;
7978 ok(locked_box.SlicePitch == expected_slice_pitch,
7979 "Got unexpected slice pitch %d for format %s, expected %d.\n",
7980 locked_box.SlicePitch, formats[i].name, expected_slice_pitch);
7982 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7983 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x, j %u.\n", hr, j);
7985 box.Left = offset_tests[j].x;
7986 box.Top = offset_tests[j].y;
7987 box.Front = offset_tests[j].z;
7988 box.Right = offset_tests[j].x2;
7989 box.Bottom = offset_tests[j].y2;
7990 box.Back = offset_tests[j].z2;
7991 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7992 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x, j %u.\n", hr, j);
7994 offset = (BYTE *)locked_box.pBits - base;
7995 if (formats[i].broken)
7997 expected_offset = box.Front * expected_slice_pitch
7998 + box.Top * expected_row_pitch
7999 + box.Left * bytes_per_pixel;
8001 else
8003 expected_offset = (box.Front / formats[i].block_depth) * expected_slice_pitch
8004 + (box.Top / formats[i].block_height) * expected_row_pitch
8005 + (box.Left / formats[i].block_width) * formats[i].block_size;
8007 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u, box start %ux%ux%u.\n",
8008 offset, formats[i].name, expected_offset, box.Left, box.Top, box.Front);
8010 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8011 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8014 /* Test partial block locks */
8015 box.Front = 0;
8016 box.Back = 1;
8017 if (formats[i].block_width > 1)
8019 box.Left = formats[i].block_width >> 1;
8020 box.Top = 0;
8021 box.Right = formats[i].block_width;
8022 box.Bottom = formats[i].block_height;
8023 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
8024 ok(FAILED(hr) || broken(formats[i].broken),
8025 "Partial block lock succeeded, expected failure, format %s.\n",
8026 formats[i].name);
8027 if (SUCCEEDED(hr))
8029 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8030 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8033 box.Left = 0;
8034 box.Top = 0;
8035 box.Right = formats[i].block_width >> 1;
8036 box.Bottom = formats[i].block_height;
8037 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
8038 ok(FAILED(hr) || broken(formats[i].broken),
8039 "Partial block lock succeeded, expected failure, format %s.\n",
8040 formats[i].name);
8041 if (SUCCEEDED(hr))
8043 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8044 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8048 if (formats[i].block_height > 1)
8050 box.Left = 0;
8051 box.Top = formats[i].block_height >> 1;
8052 box.Right = formats[i].block_width;
8053 box.Bottom = formats[i].block_height;
8054 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
8055 ok(FAILED(hr) || broken(formats[i].broken),
8056 "Partial block lock succeeded, expected failure, format %s.\n",
8057 formats[i].name);
8058 if (SUCCEEDED(hr))
8060 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8061 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8064 box.Left = 0;
8065 box.Top = 0;
8066 box.Right = formats[i].block_width;
8067 box.Bottom = formats[i].block_height >> 1;
8068 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
8069 ok(FAILED(hr) || broken(formats[i].broken),
8070 "Partial block lock succeeded, expected failure, format %s.\n",
8071 formats[i].name);
8072 if (SUCCEEDED(hr))
8074 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8075 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8079 /* Test full block lock */
8080 box.Left = 0;
8081 box.Top = 0;
8082 box.Right = formats[i].block_width;
8083 box.Bottom = formats[i].block_height;
8084 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
8085 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
8086 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8087 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8089 IDirect3DVolumeTexture9_Release(texture);
8091 /* Test mipmap locks. Don't do this with ATI2N, AMD warns that the runtime
8092 * does not allocate surfaces smaller than the blocksize properly. */
8093 if ((formats[i].block_width > 1 || formats[i].block_height > 1) && formats[i].core_fmt)
8095 hr = IDirect3DDevice9_CreateVolumeTexture(device, formats[i].block_width, formats[i].block_height,
8096 2, 2, 0, formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
8098 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, NULL, 0);
8099 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#x.\n", hr);
8100 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
8101 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8103 box.Left = box.Top = box.Front = 0;
8104 box.Right = formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1;
8105 box.Bottom = formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1;
8106 box.Back = 1;
8107 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
8108 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#x.\n", hr);
8109 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
8110 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8112 box.Right = formats[i].block_width;
8113 box.Bottom = formats[i].block_height;
8114 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
8115 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8116 if (SUCCEEDED(hr))
8117 IDirect3DVolumeTexture9_UnlockBox(texture, 1);
8119 IDirect3DVolumeTexture9_Release(texture);
8123 refcount = IDirect3DDevice9_Release(device);
8124 ok(!refcount, "Device has %u references left.\n", refcount);
8125 IDirect3D9_Release(d3d9);
8126 DestroyWindow(window);
8129 static void test_lockbox_invalid(void)
8131 static const struct
8133 D3DBOX box;
8134 HRESULT result;
8136 test_data[] =
8138 {{0, 0, 2, 2, 0, 1}, D3D_OK}, /* Valid */
8139 {{0, 0, 4, 4, 0, 1}, D3D_OK}, /* Valid */
8140 {{0, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* 0 height */
8141 {{0, 0, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* 0 width */
8142 {{0, 0, 4, 4, 1, 1}, D3DERR_INVALIDCALL}, /* 0 depth */
8143 {{4, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > right */
8144 {{0, 4, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* top > bottom */
8145 {{0, 0, 4, 4, 1, 0}, D3DERR_INVALIDCALL}, /* back > front */
8146 {{0, 0, 8, 4, 0, 1}, D3DERR_INVALIDCALL}, /* right > surface */
8147 {{0, 0, 4, 8, 0, 1}, D3DERR_INVALIDCALL}, /* bottom > surface */
8148 {{0, 0, 4, 4, 0, 3}, D3DERR_INVALIDCALL}, /* back > surface */
8149 {{8, 0, 16, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > surface */
8150 {{0, 8, 4, 16, 0, 1}, D3DERR_INVALIDCALL}, /* top > surface */
8151 {{0, 0, 4, 4, 2, 4}, D3DERR_INVALIDCALL}, /* top > surface */
8153 static const D3DBOX test_boxt_2 = {2, 2, 4, 4, 0, 1};
8154 IDirect3DVolumeTexture9 *texture = NULL;
8155 D3DLOCKED_BOX locked_box;
8156 IDirect3DDevice9 *device;
8157 IDirect3D9 *d3d;
8158 unsigned int i;
8159 ULONG refcount;
8160 HWND window;
8161 BYTE *base;
8162 HRESULT hr;
8164 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8165 0, 0, 640, 480, 0, 0, 0, 0);
8166 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8167 ok(!!d3d, "Failed to create a D3D object.\n");
8168 if (!(device = create_device(d3d, window, NULL)))
8170 skip("Failed to create a D3D device, skipping tests.\n");
8171 IDirect3D9_Release(d3d);
8172 DestroyWindow(window);
8173 return;
8176 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0,
8177 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
8178 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
8179 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
8180 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
8181 base = locked_box.pBits;
8182 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8183 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8185 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
8187 unsigned int offset, expected_offset;
8188 const D3DBOX *box = &test_data[i].box;
8190 locked_box.pBits = (BYTE *)0xdeadbeef;
8191 locked_box.RowPitch = 0xdeadbeef;
8192 locked_box.SlicePitch = 0xdeadbeef;
8194 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, box, 0);
8195 /* Unlike surfaces, volumes properly check the box even in Windows XP */
8196 ok(hr == test_data[i].result,
8197 "Got unexpected hr %#x with box [%u, %u, %u]->[%u, %u, %u], expected %#x.\n",
8198 hr, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back,
8199 test_data[i].result);
8200 if (FAILED(hr))
8201 continue;
8203 offset = (BYTE *)locked_box.pBits - base;
8204 expected_offset = box->Front * locked_box.SlicePitch + box->Top * locked_box.RowPitch + box->Left * 4;
8205 ok(offset == expected_offset,
8206 "Got unexpected offset %u (expected %u) for rect [%u, %u, %u]->[%u, %u, %u].\n",
8207 offset, expected_offset, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back);
8209 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8210 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8213 /* locked_box = NULL throws an exception on Windows */
8214 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
8215 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
8216 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
8217 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8218 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8219 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8220 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8221 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8223 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
8224 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
8225 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
8226 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
8227 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
8228 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
8229 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
8230 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
8231 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_boxt_2, 0);
8232 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
8233 hr, test_boxt_2.Left, test_boxt_2.Top, test_boxt_2.Front,
8234 test_boxt_2.Right, test_boxt_2.Bottom, test_boxt_2.Back);
8235 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8236 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8238 IDirect3DVolumeTexture9_Release(texture);
8239 refcount = IDirect3DDevice9_Release(device);
8240 ok(!refcount, "Device has %u references left.\n", refcount);
8241 IDirect3D9_Release(d3d);
8242 DestroyWindow(window);
8245 static void test_shared_handle(void)
8247 IDirect3DDevice9 *device;
8248 IDirect3D9 *d3d;
8249 ULONG refcount;
8250 HWND window;
8251 HRESULT hr;
8252 /* Native d3d9ex refuses to create a shared texture if the texture pointer
8253 * is not initialized to NULL. Make sure this doesn't cause issues here. */
8254 IDirect3DTexture9 *texture = NULL;
8255 IDirect3DSurface9 *surface = NULL;
8256 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
8257 IDirect3DIndexBuffer9 *index_buffer = NULL;
8258 HANDLE handle = NULL;
8259 void *mem;
8260 D3DCAPS9 caps;
8262 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8263 0, 0, 640, 480, 0, 0, 0, 0);
8264 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8265 ok(!!d3d, "Failed to create a D3D object.\n");
8266 if (!(device = create_device(d3d, window, NULL)))
8268 skip("Failed to create a D3D device, skipping tests.\n");
8269 IDirect3D9_Release(d3d);
8270 DestroyWindow(window);
8271 return;
8274 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8275 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8276 mem = HeapAlloc(GetProcessHeap(), 0, 128 * 128 * 4);
8278 /* Windows XP returns E_NOTIMPL, Windows 7 returns INVALIDCALL, except for
8279 * CreateVertexBuffer, where it returns NOTAVAILABLE. */
8280 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
8281 D3DPOOL_DEFAULT, &texture, &handle);
8282 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8283 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
8284 D3DPOOL_SYSTEMMEM, &texture, &mem);
8285 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8287 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
8288 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, &handle);
8289 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8290 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
8291 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, &mem);
8292 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8294 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
8295 &vertex_buffer, &handle);
8296 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8297 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
8298 &vertex_buffer, &mem);
8299 ok(hr == E_NOTIMPL || broken(hr == D3DERR_NOTAVAILABLE), "Got unexpected hr %#x.\n", hr);
8301 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
8302 &index_buffer, &handle);
8303 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8304 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
8305 &index_buffer, &mem);
8306 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8308 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
8310 IDirect3DCubeTexture9 *cube_texture = NULL;
8311 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
8312 D3DPOOL_DEFAULT, &cube_texture, &handle);
8313 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8314 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
8315 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
8316 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8319 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
8321 IDirect3DVolumeTexture9 *volume_texture = NULL;
8322 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
8323 D3DPOOL_DEFAULT, &volume_texture, &handle);
8324 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8325 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
8326 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
8327 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8330 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8331 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
8332 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8334 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24X8,
8335 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
8336 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8338 HeapFree(GetProcessHeap(), 0, mem);
8339 refcount = IDirect3DDevice9_Release(device);
8340 ok(!refcount, "Device has %u references left.\n", refcount);
8341 IDirect3D9_Release(d3d);
8342 DestroyWindow(window);
8345 static void test_pixel_format(void)
8347 HWND hwnd, hwnd2 = NULL;
8348 HDC hdc, hdc2 = NULL;
8349 HMODULE gl = NULL;
8350 int format, test_format;
8351 PIXELFORMATDESCRIPTOR pfd;
8352 IDirect3D9 *d3d9 = NULL;
8353 IDirect3DDevice9 *device = NULL;
8354 HRESULT hr;
8355 static const float point[3] = {0.0, 0.0, 0.0};
8357 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8358 100, 100, 160, 160, NULL, NULL, NULL, NULL);
8359 if (!hwnd)
8361 skip("Failed to create window\n");
8362 return;
8365 hwnd2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8366 100, 100, 160, 160, NULL, NULL, NULL, NULL);
8368 hdc = GetDC(hwnd);
8369 if (!hdc)
8371 skip("Failed to get DC\n");
8372 goto cleanup;
8375 if (hwnd2)
8376 hdc2 = GetDC(hwnd2);
8378 gl = LoadLibraryA("opengl32.dll");
8379 ok(!!gl, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
8381 format = GetPixelFormat(hdc);
8382 ok(format == 0, "new window has pixel format %d\n", format);
8384 ZeroMemory(&pfd, sizeof(pfd));
8385 pfd.nSize = sizeof(pfd);
8386 pfd.nVersion = 1;
8387 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
8388 pfd.iPixelType = PFD_TYPE_RGBA;
8389 pfd.iLayerType = PFD_MAIN_PLANE;
8390 format = ChoosePixelFormat(hdc, &pfd);
8391 if (format <= 0)
8393 skip("no pixel format available\n");
8394 goto cleanup;
8397 if (!SetPixelFormat(hdc, format, &pfd) || GetPixelFormat(hdc) != format)
8399 skip("failed to set pixel format\n");
8400 goto cleanup;
8403 if (!hdc2 || !SetPixelFormat(hdc2, format, &pfd) || GetPixelFormat(hdc2) != format)
8405 skip("failed to set pixel format on second window\n");
8406 if (hdc2)
8408 ReleaseDC(hwnd2, hdc2);
8409 hdc2 = NULL;
8413 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8414 ok(!!d3d9, "Failed to create a D3D object.\n");
8416 test_format = GetPixelFormat(hdc);
8417 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8419 if (!(device = create_device(d3d9, hwnd, NULL)))
8421 skip("Failed to create device\n");
8422 goto cleanup;
8425 test_format = GetPixelFormat(hdc);
8426 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8428 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8429 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8431 test_format = GetPixelFormat(hdc);
8432 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8434 hr = IDirect3DDevice9_BeginScene(device);
8435 ok(SUCCEEDED(hr), "BeginScene failed %#x\n", hr);
8437 test_format = GetPixelFormat(hdc);
8438 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8440 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
8441 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8443 test_format = GetPixelFormat(hdc);
8444 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8446 hr = IDirect3DDevice9_EndScene(device);
8447 ok(SUCCEEDED(hr), "EndScene failed %#x\n", hr);
8449 test_format = GetPixelFormat(hdc);
8450 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8452 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8453 ok(SUCCEEDED(hr), "Present failed %#x\n", hr);
8455 test_format = GetPixelFormat(hdc);
8456 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8458 if (hdc2)
8460 hr = IDirect3DDevice9_Present(device, NULL, NULL, hwnd2, NULL);
8461 ok(SUCCEEDED(hr), "Present failed %#x\n", hr);
8463 test_format = GetPixelFormat(hdc);
8464 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8466 test_format = GetPixelFormat(hdc2);
8467 ok(test_format == format, "second window has pixel format %d, expected %d\n", test_format, format);
8470 cleanup:
8471 if (device)
8473 UINT refcount = IDirect3DDevice9_Release(device);
8474 ok(!refcount, "Device has %u references left.\n", refcount);
8476 if (d3d9) IDirect3D9_Release(d3d9);
8477 if (gl) FreeLibrary(gl);
8478 if (hdc) ReleaseDC(hwnd, hdc);
8479 if (hdc2) ReleaseDC(hwnd2, hdc2);
8480 if (hwnd) DestroyWindow(hwnd);
8481 if (hwnd2) DestroyWindow(hwnd2);
8484 static void test_begin_end_state_block(void)
8486 IDirect3DStateBlock9 *stateblock;
8487 IDirect3DDevice9 *device;
8488 IDirect3D9 *d3d;
8489 ULONG refcount;
8490 HWND window;
8491 HRESULT hr;
8493 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8494 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8495 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8496 ok(!!d3d, "Failed to create a D3D object.\n");
8497 if (!(device = create_device(d3d, window, NULL)))
8499 skip("Failed to create a D3D device, skipping tests.\n");
8500 IDirect3D9_Release(d3d);
8501 DestroyWindow(window);
8502 return;
8505 /* Should succeed. */
8506 hr = IDirect3DDevice9_BeginStateBlock(device);
8507 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
8509 /* Calling BeginStateBlock() while recording should return
8510 * D3DERR_INVALIDCALL. */
8511 hr = IDirect3DDevice9_BeginStateBlock(device);
8512 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8514 /* Should succeed. */
8515 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
8516 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8517 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
8518 ok(!!stateblock && stateblock != (IDirect3DStateBlock9 *)0xdeadbeef,
8519 "Got unexpected stateblock %p.\n", stateblock);
8520 IDirect3DStateBlock9_Release(stateblock);
8522 /* Calling EndStateBlock() while not recording should return
8523 * D3DERR_INVALIDCALL. stateblock should not be touched. */
8524 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
8525 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8526 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8527 ok(stateblock == (IDirect3DStateBlock9 *)0xdeadbeef,
8528 "Got unexpected stateblock %p.\n", stateblock);
8530 refcount = IDirect3DDevice9_Release(device);
8531 ok(!refcount, "Device has %u references left.\n", refcount);
8532 IDirect3D9_Release(d3d);
8533 DestroyWindow(window);
8536 static void test_shader_constant_apply(void)
8538 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
8539 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
8540 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
8541 IDirect3DStateBlock9 *stateblock;
8542 DWORD vs_version, ps_version;
8543 IDirect3DDevice9 *device;
8544 IDirect3D9 *d3d;
8545 ULONG refcount;
8546 D3DCAPS9 caps;
8547 float ret[4];
8548 HWND window;
8549 HRESULT hr;
8551 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8552 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8553 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8554 ok(!!d3d, "Failed to create a D3D object.\n");
8555 if (!(device = create_device(d3d, window, NULL)))
8557 skip("Failed to create a D3D device, skipping tests.\n");
8558 IDirect3D9_Release(d3d);
8559 DestroyWindow(window);
8560 return;
8563 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8564 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8565 vs_version = caps.VertexShaderVersion & 0xffff;
8566 ps_version = caps.PixelShaderVersion & 0xffff;
8568 if (vs_version)
8570 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
8571 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8572 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
8573 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8575 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8576 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8577 ok(!memcmp(ret, initial, sizeof(initial)),
8578 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8579 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8580 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8581 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8582 ok(!memcmp(ret, initial, sizeof(initial)),
8583 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8584 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8586 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
8587 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8589 if (ps_version)
8591 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
8592 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8593 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
8594 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8596 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8597 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8598 ok(!memcmp(ret, initial, sizeof(initial)),
8599 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8600 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8601 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8602 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8603 ok(!memcmp(ret, initial, sizeof(initial)),
8604 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8605 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8607 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
8608 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8611 hr = IDirect3DDevice9_BeginStateBlock(device);
8612 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
8614 if (vs_version)
8616 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
8617 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8619 if (ps_version)
8621 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
8622 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8625 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8626 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
8628 if (vs_version)
8630 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8631 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8632 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8633 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8634 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8635 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8636 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8637 ok(!memcmp(ret, initial, sizeof(initial)),
8638 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8639 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8641 if (ps_version)
8643 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8644 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8645 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8646 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8647 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8648 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8649 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8650 ok(!memcmp(ret, initial, sizeof(initial)),
8651 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8652 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8655 /* Apply doesn't overwrite constants that aren't explicitly set on the
8656 * source stateblock. */
8657 hr = IDirect3DStateBlock9_Apply(stateblock);
8658 ok(SUCCEEDED(hr), "Failed to apply stateblock, hr %#x.\n", hr);
8660 if (vs_version)
8662 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8663 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8664 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8665 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8666 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8667 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8668 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8669 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8670 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8671 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8673 if (ps_version)
8675 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8676 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8677 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8678 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8679 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8680 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8681 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8682 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8683 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8684 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8687 IDirect3DStateBlock9_Release(stateblock);
8688 refcount = IDirect3DDevice9_Release(device);
8689 ok(!refcount, "Device has %u references left.\n", refcount);
8690 IDirect3D9_Release(d3d);
8691 DestroyWindow(window);
8694 static void test_vdecl_apply(void)
8696 IDirect3DVertexDeclaration9 *declaration, *declaration1, *declaration2;
8697 IDirect3DStateBlock9 *stateblock;
8698 IDirect3DDevice9 *device;
8699 IDirect3D9 *d3d;
8700 ULONG refcount;
8701 HWND window;
8702 HRESULT hr;
8704 static const D3DVERTEXELEMENT9 decl1[] =
8706 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8707 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8708 D3DDECL_END(),
8711 static const D3DVERTEXELEMENT9 decl2[] =
8713 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8714 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8715 {0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
8716 D3DDECL_END(),
8719 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8720 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8721 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8722 ok(!!d3d, "Failed to create a D3D object.\n");
8723 if (!(device = create_device(d3d, window, NULL)))
8725 skip("Failed to create a D3D device, skipping tests.\n");
8726 IDirect3D9_Release(d3d);
8727 DestroyWindow(window);
8728 return;
8731 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl1, &declaration1);
8732 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
8734 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl2, &declaration2);
8735 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
8737 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8738 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8739 hr = IDirect3DDevice9_BeginStateBlock(device);
8740 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#x.\n", hr);
8741 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
8742 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8743 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8744 ok(SUCCEEDED(hr), "EndStateBlock failed, hr %#x.\n", hr);
8745 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8746 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8747 hr = IDirect3DStateBlock9_Apply(stateblock);
8748 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8749 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8750 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8751 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
8752 declaration, declaration1);
8753 IDirect3DVertexDeclaration9_Release(declaration);
8755 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8756 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8757 hr = IDirect3DStateBlock9_Capture(stateblock);
8758 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8759 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8760 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8761 hr = IDirect3DStateBlock9_Apply(stateblock);
8762 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8763 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8764 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8765 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8766 declaration, declaration2);
8767 IDirect3DVertexDeclaration9_Release(declaration);
8769 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8770 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8771 hr = IDirect3DStateBlock9_Capture(stateblock);
8772 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8773 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8774 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8775 hr = IDirect3DStateBlock9_Apply(stateblock);
8776 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8777 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8778 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8779 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8780 declaration, declaration2);
8781 IDirect3DVertexDeclaration9_Release(declaration);
8783 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8784 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8785 hr = IDirect3DStateBlock9_Capture(stateblock);
8786 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8787 hr = IDirect3DStateBlock9_Apply(stateblock);
8788 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8789 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8790 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8791 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
8793 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8794 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8795 hr = IDirect3DStateBlock9_Capture(stateblock);
8796 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8797 hr = IDirect3DStateBlock9_Apply(stateblock);
8798 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8799 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8800 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8801 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8802 declaration, declaration2);
8803 IDirect3DVertexDeclaration9_Release(declaration);
8805 IDirect3DStateBlock9_Release(stateblock);
8806 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
8807 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8808 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &stateblock);
8809 ok(SUCCEEDED(hr), "CreateStateBlock failed, hr %#x.\n", hr);
8810 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8811 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8812 hr = IDirect3DStateBlock9_Apply(stateblock);
8813 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8814 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8815 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8816 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
8817 declaration, declaration1);
8818 IDirect3DVertexDeclaration9_Release(declaration);
8820 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8821 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8822 hr = IDirect3DStateBlock9_Capture(stateblock);
8823 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8824 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8825 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8826 hr = IDirect3DStateBlock9_Apply(stateblock);
8827 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8828 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8829 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8830 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8831 declaration, declaration2);
8832 IDirect3DVertexDeclaration9_Release(declaration);
8834 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8835 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8836 hr = IDirect3DStateBlock9_Capture(stateblock);
8837 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8838 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8839 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8840 hr = IDirect3DStateBlock9_Apply(stateblock);
8841 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8842 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8843 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8844 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8845 declaration, declaration2);
8846 IDirect3DVertexDeclaration9_Release(declaration);
8848 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8849 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8850 hr = IDirect3DStateBlock9_Capture(stateblock);
8851 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8852 hr = IDirect3DStateBlock9_Apply(stateblock);
8853 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8854 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8855 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8856 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
8858 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8859 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8860 hr = IDirect3DStateBlock9_Capture(stateblock);
8861 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8862 hr = IDirect3DStateBlock9_Apply(stateblock);
8863 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8864 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8865 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8866 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8867 declaration, declaration2);
8868 IDirect3DVertexDeclaration9_Release(declaration);
8870 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8871 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8872 IDirect3DVertexDeclaration9_Release(declaration1);
8873 IDirect3DVertexDeclaration9_Release(declaration2);
8874 IDirect3DStateBlock9_Release(stateblock);
8875 refcount = IDirect3DDevice9_Release(device);
8876 ok(!refcount, "Device has %u references left.\n", refcount);
8877 IDirect3D9_Release(d3d);
8878 DestroyWindow(window);
8881 static void test_resource_type(void)
8883 IDirect3DDevice9 *device;
8884 IDirect3DSurface9 *surface;
8885 IDirect3DTexture9 *texture;
8886 IDirect3DCubeTexture9 *cube_texture;
8887 IDirect3DVolume9 *volume;
8888 IDirect3DVolumeTexture9 *volume_texture;
8889 D3DSURFACE_DESC surface_desc;
8890 D3DVOLUME_DESC volume_desc;
8891 D3DRESOURCETYPE type;
8892 IDirect3D9 *d3d;
8893 ULONG refcount;
8894 HWND window;
8895 HRESULT hr;
8896 D3DCAPS9 caps;
8898 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8899 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8900 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8901 ok(!!d3d, "Failed to create a D3D object.\n");
8902 if (!(device = create_device(d3d, window, NULL)))
8904 skip("Failed to create a D3D device, skipping tests.\n");
8905 IDirect3D9_Release(d3d);
8906 DestroyWindow(window);
8907 return;
8910 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8911 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8913 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_X8R8G8B8,
8914 D3DPOOL_SYSTEMMEM, &surface, NULL);
8915 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8916 type = IDirect3DSurface9_GetType(surface);
8917 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8918 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8919 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8920 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8921 surface_desc.Type);
8922 IDirect3DSurface9_Release(surface);
8924 hr = IDirect3DDevice9_CreateTexture(device, 2, 8, 4, 0, D3DFMT_X8R8G8B8,
8925 D3DPOOL_SYSTEMMEM, &texture, NULL);
8926 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8927 type = IDirect3DTexture9_GetType(texture);
8928 ok(type == D3DRTYPE_TEXTURE, "Expected type D3DRTYPE_TEXTURE, got %u.\n", type);
8930 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8931 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8932 /* The following code crashes, for the sake of completeness:
8933 * type = texture->lpVtbl->GetType((IDirect3DTexture9 *)surface);
8934 * ok(type == D3DRTYPE_PONIES, "Expected type D3DRTYPE_PONIES, got %u.\n", type);
8936 * So applications will not depend on getting the "right" resource type - whatever it
8937 * may be - from the "wrong" vtable. */
8938 type = IDirect3DSurface9_GetType(surface);
8939 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8940 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8941 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8942 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8943 surface_desc.Type);
8944 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
8945 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
8946 hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &surface_desc);
8947 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8948 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8949 surface_desc.Type);
8950 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
8951 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
8952 IDirect3DSurface9_Release(surface);
8954 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
8955 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8956 type = IDirect3DSurface9_GetType(surface);
8957 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8958 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8959 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8960 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8961 surface_desc.Type);
8962 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
8963 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
8964 hr = IDirect3DTexture9_GetLevelDesc(texture, 2, &surface_desc);
8965 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8966 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8967 surface_desc.Type);
8968 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
8969 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
8970 IDirect3DSurface9_Release(surface);
8971 IDirect3DTexture9_Release(texture);
8973 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
8975 hr = IDirect3DDevice9_CreateCubeTexture(device, 1, 1, 0, D3DFMT_X8R8G8B8,
8976 D3DPOOL_SYSTEMMEM, &cube_texture, NULL);
8977 ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#x.\n", hr);
8978 type = IDirect3DCubeTexture9_GetType(cube_texture);
8979 ok(type == D3DRTYPE_CUBETEXTURE, "Expected type D3DRTYPE_CUBETEXTURE, got %u.\n", type);
8981 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture,
8982 D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface);
8983 ok(SUCCEEDED(hr), "Failed to get cube map surface, hr %#x.\n", hr);
8984 type = IDirect3DSurface9_GetType(surface);
8985 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8986 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8987 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8988 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8989 surface_desc.Type);
8990 hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
8991 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8992 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8993 surface_desc.Type);
8994 IDirect3DSurface9_Release(surface);
8995 IDirect3DCubeTexture9_Release(cube_texture);
8997 else
8998 skip("Cube maps not supported.\n");
9000 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP)
9002 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 4, 8, 4, 0, D3DFMT_X8R8G8B8,
9003 D3DPOOL_SYSTEMMEM, &volume_texture, NULL);
9004 type = IDirect3DVolumeTexture9_GetType(volume_texture);
9005 ok(type == D3DRTYPE_VOLUMETEXTURE, "Expected type D3DRTYPE_VOLUMETEXTURE, got %u.\n", type);
9007 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
9008 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
9009 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
9010 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
9011 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#x.\n", hr);
9012 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
9013 volume_desc.Type);
9014 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
9015 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
9016 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
9017 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
9018 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
9019 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
9020 volume_desc.Type);
9021 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
9022 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
9023 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
9024 IDirect3DVolume9_Release(volume);
9026 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 2, &volume);
9027 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
9028 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
9029 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
9030 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#x.\n", hr);
9031 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
9032 volume_desc.Type);
9033 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
9034 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
9035 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
9036 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 2, &volume_desc);
9037 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
9038 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
9039 volume_desc.Type);
9040 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
9041 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
9042 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
9043 IDirect3DVolume9_Release(volume);
9044 IDirect3DVolumeTexture9_Release(volume_texture);
9046 else
9047 skip("Mipmapped volume maps not supported.\n");
9049 refcount = IDirect3DDevice9_Release(device);
9050 ok(!refcount, "Device has %u references left.\n", refcount);
9051 IDirect3D9_Release(d3d);
9052 DestroyWindow(window);
9055 static void test_mipmap_lock(void)
9057 IDirect3DDevice9 *device;
9058 IDirect3DSurface9 *surface, *surface2, *surface_dst, *surface_dst2;
9059 IDirect3DTexture9 *texture, *texture_dst;
9060 IDirect3D9 *d3d;
9061 ULONG refcount;
9062 HWND window;
9063 HRESULT hr;
9064 D3DLOCKED_RECT locked_rect;
9066 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9067 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9068 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9069 ok(!!d3d, "Failed to create a D3D object.\n");
9070 if (!(device = create_device(d3d, window, NULL)))
9072 skip("Failed to create a D3D device, skipping tests.\n");
9073 IDirect3D9_Release(d3d);
9074 DestroyWindow(window);
9075 return;
9078 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
9079 D3DPOOL_DEFAULT, &texture_dst, NULL);
9080 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
9081 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 0, &surface_dst);
9082 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9083 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 1, &surface_dst2);
9084 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9086 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
9087 D3DPOOL_SYSTEMMEM, &texture, NULL);
9088 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
9089 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9090 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9091 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
9092 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9094 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
9095 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
9096 hr = IDirect3DSurface9_LockRect(surface2, &locked_rect, NULL, 0);
9097 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
9098 hr = IDirect3DSurface9_UnlockRect(surface);
9099 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
9101 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, surface_dst, NULL);
9102 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
9103 hr = IDirect3DDevice9_UpdateSurface(device, surface2, NULL, surface_dst2, NULL);
9104 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9106 /* Apparently there's no validation on the container. */
9107 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
9108 (IDirect3DBaseTexture9 *)texture_dst);
9109 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
9111 hr = IDirect3DSurface9_UnlockRect(surface2);
9112 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
9114 IDirect3DSurface9_Release(surface_dst2);
9115 IDirect3DSurface9_Release(surface_dst);
9116 IDirect3DSurface9_Release(surface2);
9117 IDirect3DSurface9_Release(surface);
9118 IDirect3DTexture9_Release(texture_dst);
9119 IDirect3DTexture9_Release(texture);
9121 refcount = IDirect3DDevice9_Release(device);
9122 ok(!refcount, "Device has %u references left.\n", refcount);
9123 IDirect3D9_Release(d3d);
9124 DestroyWindow(window);
9127 static void test_writeonly_resource(void)
9129 IDirect3D9 *d3d;
9130 IDirect3DDevice9 *device;
9131 IDirect3DVertexBuffer9 *buffer;
9132 ULONG refcount;
9133 HWND window;
9134 HRESULT hr;
9135 void *ptr;
9136 static const struct
9138 struct vec3 pos;
9140 quad[] =
9142 {{-1.0f, -1.0f, 0.0f}},
9143 {{-1.0f, 1.0f, 0.0f}},
9144 {{ 1.0f, -1.0f, 0.0f}},
9145 {{ 1.0f, 1.0f, 0.0f}}
9148 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9149 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9150 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9151 ok(!!d3d, "Failed to create a D3D object.\n");
9152 if (!(device = create_device(d3d, window, NULL)))
9154 skip("Failed to create a D3D device, skipping tests.\n");
9155 IDirect3D9_Release(d3d);
9156 DestroyWindow(window);
9157 return;
9160 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad),
9161 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
9162 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
9164 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
9165 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9166 memcpy(ptr, quad, sizeof(quad));
9167 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9168 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9169 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quad));
9170 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9171 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9172 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9174 hr = IDirect3DDevice9_BeginScene(device);
9175 ok(SUCCEEDED(hr), "Failed to begin scene %#x\n", hr);
9176 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9177 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9178 hr = IDirect3DDevice9_EndScene(device);
9179 ok(SUCCEEDED(hr), "Failed to end scene %#x\n", hr);
9181 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, 0);
9182 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9183 ok(!memcmp(ptr, quad, sizeof(quad)), "Got unexpected vertex buffer data.\n");
9184 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9185 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9187 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, D3DLOCK_READONLY);
9188 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9189 ok(!memcmp(ptr, quad, sizeof(quad)), "Got unexpected vertex buffer data.\n");
9190 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9191 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9193 refcount = IDirect3DVertexBuffer9_Release(buffer);
9194 ok(!refcount, "Vertex buffer has %u references left.\n", refcount);
9195 refcount = IDirect3DDevice9_Release(device);
9196 ok(!refcount, "Device has %u references left.\n", refcount);
9197 IDirect3D9_Release(d3d);
9198 DestroyWindow(window);
9201 static void test_lost_device(void)
9203 struct device_desc device_desc;
9204 IDirect3DDevice9 *device;
9205 IDirect3D9 *d3d;
9206 ULONG refcount;
9207 HWND window;
9208 HRESULT hr;
9209 BOOL ret;
9211 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9212 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9213 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9214 ok(!!d3d, "Failed to create a D3D object.\n");
9215 device_desc.device_window = window;
9216 device_desc.width = screen_width;
9217 device_desc.height = screen_height;
9218 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
9219 if (!(device = create_device(d3d, window, &device_desc)))
9221 skip("Failed to create a D3D device, skipping tests.\n");
9222 goto done;
9225 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9226 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9227 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9228 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9230 ret = SetForegroundWindow(GetDesktopWindow());
9231 ok(ret, "Failed to set foreground window.\n");
9232 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9233 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
9234 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9235 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
9237 ret = ShowWindow(window, SW_RESTORE);
9238 ok(ret, "Failed to restore window.\n");
9239 ret = SetForegroundWindow(window);
9240 ok(ret, "Failed to set foreground window.\n");
9241 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9242 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
9243 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9244 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
9246 hr = reset_device(device, window, FALSE);
9247 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9248 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9249 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9250 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9251 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9253 hr = reset_device(device, window, TRUE);
9254 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9255 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9256 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9257 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9258 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9260 ret = SetForegroundWindow(GetDesktopWindow());
9261 ok(ret, "Failed to set foreground window.\n");
9262 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9263 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9264 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9265 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9267 ret = ShowWindow(window, SW_RESTORE);
9268 ok(ret, "Failed to restore window.\n");
9269 ret = SetForegroundWindow(window);
9270 ok(ret, "Failed to set foreground window.\n");
9271 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9272 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9273 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9274 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9276 hr = reset_device(device, window, FALSE);
9277 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9278 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9279 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9280 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9281 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9283 refcount = IDirect3DDevice9_Release(device);
9284 ok(!refcount, "Device has %u references left.\n", refcount);
9285 done:
9286 IDirect3D9_Release(d3d);
9287 DestroyWindow(window);
9290 static void test_resource_priority(void)
9292 IDirect3DDevice9 *device;
9293 IDirect3DSurface9 *surface;
9294 IDirect3DTexture9 *texture;
9295 IDirect3DVertexBuffer9 *buffer;
9296 IDirect3D9 *d3d;
9297 ULONG refcount;
9298 HWND window;
9299 HRESULT hr;
9300 static const struct
9302 D3DPOOL pool;
9303 const char *name;
9304 BOOL can_set_priority;
9306 test_data[] =
9308 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
9309 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", FALSE},
9310 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
9311 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE}
9313 unsigned int i;
9314 DWORD priority;
9316 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9317 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9318 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9319 ok(!!d3d, "Failed to create a D3D object.\n");
9320 if (!(device = create_device(d3d, window, NULL)))
9322 skip("Failed to create a D3D device, skipping tests.\n");
9323 IDirect3D9_Release(d3d);
9324 DestroyWindow(window);
9325 return;
9328 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); i++)
9330 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 0, 0, D3DFMT_X8R8G8B8,
9331 test_data[i].pool, &texture, NULL);
9332 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, pool %s.\n", hr, test_data[i].name);
9333 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9334 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9336 priority = IDirect3DTexture9_GetPriority(texture);
9337 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9338 priority = IDirect3DTexture9_SetPriority(texture, 1);
9339 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9340 priority = IDirect3DTexture9_GetPriority(texture);
9341 if (test_data[i].can_set_priority)
9343 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9344 priority = IDirect3DTexture9_SetPriority(texture, 2);
9345 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9347 else
9348 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9350 priority = IDirect3DSurface9_GetPriority(surface);
9351 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9352 priority = IDirect3DSurface9_SetPriority(surface, 1);
9353 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9354 priority = IDirect3DSurface9_GetPriority(surface);
9355 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9357 IDirect3DSurface9_Release(surface);
9358 IDirect3DTexture9_Release(texture);
9360 if (test_data[i].pool != D3DPOOL_MANAGED)
9362 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16, D3DFMT_X8R8G8B8,
9363 test_data[i].pool, &surface, NULL);
9364 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, pool %s.\n", hr, test_data[i].name);
9366 priority = IDirect3DSurface9_GetPriority(surface);
9367 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9368 priority = IDirect3DSurface9_SetPriority(surface, 1);
9369 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9370 priority = IDirect3DSurface9_GetPriority(surface);
9371 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9373 IDirect3DSurface9_Release(surface);
9376 if (test_data[i].pool != D3DPOOL_SCRATCH)
9378 hr = IDirect3DDevice9_CreateVertexBuffer(device, 256, 0, 0,
9379 test_data[i].pool, &buffer, NULL);
9380 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x, pool %s.\n", hr, test_data[i].name);
9382 priority = IDirect3DVertexBuffer9_GetPriority(buffer);
9383 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9384 priority = IDirect3DVertexBuffer9_SetPriority(buffer, 1);
9385 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9386 priority = IDirect3DVertexBuffer9_GetPriority(buffer);
9387 if (test_data[i].can_set_priority)
9389 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9390 priority = IDirect3DVertexBuffer9_SetPriority(buffer, 0);
9391 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9393 else
9394 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9396 IDirect3DVertexBuffer9_Release(buffer);
9400 hr = IDirect3DDevice9_CreateRenderTarget(device, 16, 16, D3DFMT_X8R8G8B8,
9401 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
9403 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
9404 priority = IDirect3DSurface9_GetPriority(surface);
9405 ok(priority == 0, "Got unexpected priority %u.\n", priority);
9406 priority = IDirect3DSurface9_SetPriority(surface, 1);
9407 ok(priority == 0, "Got unexpected priority %u.\n", priority);
9408 priority = IDirect3DSurface9_GetPriority(surface);
9409 ok(priority == 0, "Got unexpected priority %u.\n", priority);
9411 IDirect3DSurface9_Release(surface);
9413 refcount = IDirect3DDevice9_Release(device);
9414 ok(!refcount, "Device has %u references left.\n", refcount);
9415 IDirect3D9_Release(d3d);
9416 DestroyWindow(window);
9419 START_TEST(device)
9421 WNDCLASSA wc = {0};
9422 IDirect3D9 *d3d9;
9424 if (!(d3d9 = Direct3DCreate9(D3D_SDK_VERSION)))
9426 skip("could not create D3D9 object\n");
9427 return;
9429 IDirect3D9_Release(d3d9);
9431 wc.lpfnWndProc = DefWindowProcA;
9432 wc.lpszClassName = "d3d9_test_wc";
9433 RegisterClassA(&wc);
9435 screen_width = GetSystemMetrics(SM_CXSCREEN);
9436 screen_height = GetSystemMetrics(SM_CYSCREEN);
9438 test_get_set_vertex_declaration();
9439 test_get_declaration();
9440 test_fvf_decl_conversion();
9441 test_fvf_decl_management();
9442 test_vertex_declaration_alignment();
9443 test_unused_declaration_type();
9444 test_fpu_setup();
9445 test_multi_device();
9446 test_display_formats();
9447 test_display_modes();
9448 test_swapchain();
9449 test_refcount();
9450 test_mipmap_levels();
9451 test_checkdevicemultisampletype();
9452 test_cursor();
9453 test_cursor_pos();
9454 test_reset_fullscreen();
9455 test_reset();
9456 test_scene();
9457 test_limits();
9458 test_depthstenciltest();
9459 test_get_rt();
9460 test_draw_indexed();
9461 test_null_stream();
9462 test_lights();
9463 test_set_stream_source();
9464 test_scissor_size();
9465 test_wndproc();
9466 test_wndproc_windowed();
9467 test_window_style();
9468 test_mode_change();
9469 test_device_window_reset();
9470 test_reset_resources();
9471 test_set_rt_vp_scissor();
9472 test_volume_get_container();
9473 test_volume_resource();
9474 test_vb_lock_flags();
9475 test_vertex_buffer_alignment();
9476 test_query_support();
9477 test_occlusion_query_states();
9478 test_timestamp_query();
9479 test_get_set_vertex_shader();
9480 test_vertex_shader_constant();
9481 test_get_set_pixel_shader();
9482 test_pixel_shader_constant();
9483 test_unsupported_shaders();
9484 test_texture_stage_states();
9485 test_cube_textures();
9486 test_mipmap_gen();
9487 test_filter();
9488 test_get_texture();
9489 test_lod();
9490 test_surface_get_container();
9491 test_surface_alignment();
9492 test_lockrect_offset();
9493 test_lockrect_invalid();
9494 test_private_data();
9495 test_getdc();
9496 test_surface_dimensions();
9497 test_surface_format_null();
9498 test_surface_double_unlock();
9499 test_surface_blocks();
9500 test_set_palette();
9501 test_swvp_buffer();
9502 test_npot_textures();
9503 test_vidmem_accounting();
9504 test_volume_locking();
9505 test_update_volumetexture();
9506 test_create_rt_ds_fail();
9507 test_volume_blocks();
9508 test_lockbox_invalid();
9509 test_shared_handle();
9510 test_pixel_format();
9511 test_begin_end_state_block();
9512 test_shader_constant_apply();
9513 test_vdecl_apply();
9514 test_resource_type();
9515 test_mipmap_lock();
9516 test_writeonly_resource();
9517 test_lost_device();
9518 test_resource_priority();
9520 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));