wined3d: Rename wined3d_cull enum values.
[wine.git] / dlls / d3d9 / tests / device.c
blob715e34c62db0184f7b01fda6fe23ee210667bc4a
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 WINVER 0x0602 /* for CURSOR_SUPPRESSED */
26 #define COBJMACROS
27 #include <d3d9.h>
28 #include "wine/test.h"
30 struct vec3
32 float x, y, z;
35 #define CREATE_DEVICE_FULLSCREEN 0x01
36 #define CREATE_DEVICE_NOWINDOWCHANGES 0x02
37 #define CREATE_DEVICE_FPU_PRESERVE 0x04
38 #define CREATE_DEVICE_SWVP_ONLY 0x08
40 struct device_desc
42 HWND device_window;
43 unsigned int width;
44 unsigned int height;
45 DWORD flags;
48 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
49 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
51 static DEVMODEW registry_mode;
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, const struct device_desc *desc)
184 D3DPRESENT_PARAMETERS present_parameters = {0};
186 present_parameters.BackBufferWidth = 640;
187 present_parameters.BackBufferHeight = 480;
188 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
189 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
190 present_parameters.hDeviceWindow = NULL;
191 present_parameters.Windowed = TRUE;
192 present_parameters.EnableAutoDepthStencil = TRUE;
193 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
195 if (desc)
197 present_parameters.BackBufferWidth = desc->width;
198 present_parameters.BackBufferHeight = desc->height;
199 present_parameters.hDeviceWindow = desc->device_window;
200 present_parameters.Windowed = !(desc->flags & CREATE_DEVICE_FULLSCREEN);
203 return IDirect3DDevice9_Reset(device, &present_parameters);
206 #define CHECK_CALL(r,c,d,rc) \
207 if (SUCCEEDED(r)) {\
208 int tmp1 = get_refcount( (IUnknown *)d ); \
209 int rc_new = rc; \
210 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
211 } else {\
212 trace("%s failed: %08x\n", c, r); \
215 #define CHECK_RELEASE(obj,d,rc) \
216 if (obj) { \
217 int tmp1, rc_new = rc; \
218 IUnknown_Release( (IUnknown*)obj ); \
219 tmp1 = get_refcount( (IUnknown *)d ); \
220 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
223 #define CHECK_REFCOUNT(obj,rc) \
225 int rc_new = rc; \
226 int count = get_refcount( (IUnknown *)obj ); \
227 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
230 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
232 int rc_new = rc; \
233 int count = IUnknown_Release( (IUnknown *)obj ); \
234 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
237 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
239 int rc_new = rc; \
240 int count = IUnknown_AddRef( (IUnknown *)obj ); \
241 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
244 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
246 void *container_ptr = (void *)0x1337c0d3; \
247 hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
248 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
249 "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
250 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
253 static void test_get_set_vertex_declaration(void)
255 IDirect3DVertexDeclaration9 *declaration, *tmp;
256 ULONG refcount, expected_refcount;
257 IDirect3DDevice9 *device;
258 IDirect3D9 *d3d;
259 HWND window;
260 HRESULT hr;
262 static const D3DVERTEXELEMENT9 simple_decl[] =
264 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
265 D3DDECL_END()
268 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
269 0, 0, 640, 480, NULL, NULL, NULL, NULL);
270 d3d = Direct3DCreate9(D3D_SDK_VERSION);
271 ok(!!d3d, "Failed to create a D3D object.\n");
272 if (!(device = create_device(d3d, window, NULL)))
274 skip("Failed to create a D3D device, skipping tests.\n");
275 goto done;
278 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
279 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
281 /* SetVertexDeclaration() should not touch the declaration's refcount. */
282 expected_refcount = get_refcount((IUnknown *)declaration);
283 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
284 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
285 refcount = get_refcount((IUnknown *)declaration);
286 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
288 /* GetVertexDeclaration() should increase the declaration's refcount by one. */
289 tmp = NULL;
290 expected_refcount = refcount + 1;
291 hr = IDirect3DDevice9_GetVertexDeclaration(device, &tmp);
292 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
293 ok(tmp == declaration, "Got unexpected declaration %p, expected %p.\n", tmp, declaration);
294 refcount = get_refcount((IUnknown *)declaration);
295 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
296 IDirect3DVertexDeclaration9_Release(tmp);
298 IDirect3DVertexDeclaration9_Release(declaration);
299 refcount = IDirect3DDevice9_Release(device);
300 ok(!refcount, "Device has %u references left.\n", refcount);
301 done:
302 IDirect3D9_Release(d3d);
303 DestroyWindow(window);
306 static void test_get_declaration(void)
308 unsigned int element_count, expected_element_count;
309 IDirect3DVertexDeclaration9 *declaration;
310 D3DVERTEXELEMENT9 *elements;
311 IDirect3DDevice9 *device;
312 IDirect3D9 *d3d;
313 ULONG refcount;
314 HWND window;
315 HRESULT hr;
317 static const D3DVERTEXELEMENT9 simple_decl[] =
319 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
320 D3DDECL_END()
323 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
324 0, 0, 640, 480, NULL, NULL, NULL, NULL);
325 d3d = Direct3DCreate9(D3D_SDK_VERSION);
326 ok(!!d3d, "Failed to create a D3D object.\n");
327 if (!(device = create_device(d3d, window, NULL)))
329 skip("Failed to create a D3D device, skipping tests.\n");
330 goto done;
333 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
334 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
336 /* First test only getting the number of elements. */
337 element_count = 0x1337c0de;
338 expected_element_count = sizeof(simple_decl) / sizeof(*simple_decl);
339 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
340 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
341 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
342 element_count, expected_element_count);
344 element_count = 0;
345 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
346 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
347 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
348 element_count, expected_element_count);
350 /* Also test the returned data. */
351 elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(simple_decl));
353 element_count = 0x1337c0de;
354 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
355 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
356 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
357 element_count, expected_element_count);
358 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
359 "Original and returned vertexdeclarations are not the same.\n");
361 memset(elements, 0, sizeof(simple_decl));
363 element_count = 0;
364 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
365 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
366 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
367 element_count, expected_element_count);
368 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
369 "Original and returned vertexdeclarations are not the same.\n");
371 HeapFree(GetProcessHeap(), 0, elements);
372 IDirect3DVertexDeclaration9_Release(declaration);
373 refcount = IDirect3DDevice9_Release(device);
374 ok(!refcount, "Device has %u references left.\n", refcount);
375 done:
376 IDirect3D9_Release(d3d);
377 DestroyWindow(window);
380 static void test_fvf_decl_conversion(void)
382 IDirect3DVertexDeclaration9 *default_decl;
383 IDirect3DVertexDeclaration9 *declaration;
384 IDirect3DDevice9 *device;
385 IDirect3D9 *d3d;
386 ULONG refcount;
387 unsigned int i;
388 HWND window;
389 HRESULT hr;
391 static const D3DVERTEXELEMENT9 default_elements[] =
393 {0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
394 {0, 4, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
395 D3DDECL_END()
397 /* Test conversions from vertex declaration to an FVF. For some reason
398 * those seem to occur only for POSITION/POSITIONT, otherwise the FVF is
399 * forced to 0 - maybe this is configuration specific. */
400 static const struct
402 D3DVERTEXELEMENT9 elements[7];
403 DWORD fvf;
404 BOOL todo;
406 decl_to_fvf_tests[] =
408 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}, D3DFVF_XYZ, TRUE },
409 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}, D3DFVF_XYZRHW, TRUE },
410 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
411 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
412 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
413 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
414 {{{0, 0, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0}, D3DDECL_END()}, 0, FALSE},
415 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}, 0, FALSE},
416 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}, 0, FALSE},
417 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}, 0, FALSE},
418 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}, 0, FALSE},
419 /* No FVF mapping available. */
420 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 1}, D3DDECL_END()}, 0, FALSE},
421 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 1}, D3DDECL_END()}, 0, FALSE},
422 /* Try empty declaration. */
423 {{ D3DDECL_END()}, 0, FALSE},
424 /* Make sure textures of different sizes work. */
425 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
426 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
427 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
428 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
429 /* Make sure the TEXCOORD index works correctly - try several textures. */
432 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
433 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
434 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
435 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
436 D3DDECL_END(),
437 }, 0, FALSE,
439 /* Now try a combination test. */
442 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITIONT, 0},
443 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
444 {0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0},
445 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
446 {0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
447 {0, 44, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1},
448 D3DDECL_END(),
449 }, 0, FALSE,
452 /* Test conversions from FVF to a vertex declaration. These seem to always
453 * occur internally. A new declaration object is created if necessary. */
454 static const struct
456 DWORD fvf;
457 D3DVERTEXELEMENT9 elements[7];
459 fvf_to_decl_tests[] =
461 {D3DFVF_XYZ, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
462 {D3DFVF_XYZW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
463 {D3DFVF_XYZRHW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}},
465 D3DFVF_XYZB5,
467 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
468 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
469 {0, 28, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDINDICES, 0},
470 D3DDECL_END(),
474 D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4,
476 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
477 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
478 {0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
479 D3DDECL_END(),
483 D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR,
485 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
486 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
487 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
488 D3DDECL_END(),
492 D3DFVF_XYZB1,
494 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
495 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
496 D3DDECL_END(),
500 D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4,
502 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
503 {0, 12, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
504 D3DDECL_END(),
508 D3DFVF_XYZB1 | D3DFVF_LASTBETA_D3DCOLOR,
510 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
511 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
512 D3DDECL_END(),
516 D3DFVF_XYZB2,
518 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
519 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
520 D3DDECL_END(),
524 D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4,
526 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
527 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
528 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
529 D3DDECL_END(),
533 D3DFVF_XYZB2 | D3DFVF_LASTBETA_D3DCOLOR,
535 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
536 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
537 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
538 D3DDECL_END(),
542 D3DFVF_XYZB3,
544 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
545 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
546 D3DDECL_END(),
550 D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4,
552 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
553 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
554 {0, 20, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
555 D3DDECL_END(),
559 D3DFVF_XYZB3 | D3DFVF_LASTBETA_D3DCOLOR,
561 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
562 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
563 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
564 D3DDECL_END(),
568 D3DFVF_XYZB4,
570 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
571 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
572 D3DDECL_END(),
576 D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4,
578 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
579 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
580 {0, 24, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
581 D3DDECL_END(),
585 D3DFVF_XYZB4 | D3DFVF_LASTBETA_D3DCOLOR,
587 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
588 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
589 {0, 24, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
590 D3DDECL_END(),
593 {D3DFVF_NORMAL, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}},
594 {D3DFVF_PSIZE, {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}},
595 {D3DFVF_DIFFUSE, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}},
596 {D3DFVF_SPECULAR, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}},
597 /* Make sure textures of different sizes work. */
599 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1,
600 {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
603 D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1,
604 {{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
607 D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1,
608 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
611 D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1,
612 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
614 /* Make sure the TEXCOORD index works correctly - try several textures. */
616 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE2(2)
617 | D3DFVF_TEXCOORDSIZE4(3) | D3DFVF_TEX4,
619 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
620 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
621 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
622 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
623 D3DDECL_END(),
626 /* Now try a combination test. */
628 D3DFVF_XYZB4 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEXCOORDSIZE2(0)
629 | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEX2,
631 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
632 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
633 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
634 {0, 32, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
635 {0, 36, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0},
636 {0, 44, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
637 D3DDECL_END(),
642 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
643 0, 0, 640, 480, NULL, NULL, NULL, NULL);
644 d3d = Direct3DCreate9(D3D_SDK_VERSION);
645 ok(!!d3d, "Failed to create a D3D object.\n");
646 if (!(device = create_device(d3d, window, NULL)))
648 skip("Failed to create a D3D device, skipping tests.\n");
649 goto done;
652 for (i = 0; i < sizeof(decl_to_fvf_tests) / sizeof(*decl_to_fvf_tests); ++i)
654 DWORD fvf = 0xdeadbeef;
655 HRESULT hr;
657 /* Set a default FVF of SPECULAR and DIFFUSE to make sure it is changed
658 * back to 0. */
659 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
660 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#x.\n", i, hr);
662 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_to_fvf_tests[i].elements, &declaration);
663 ok(SUCCEEDED(hr), "Test %u: Failed to create vertex declaration, hr %#x.\n", i, hr);
664 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
665 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#x.\n", i, hr);
667 /* Check the FVF. */
668 hr = IDirect3DDevice9_GetFVF(device, &fvf);
669 ok(SUCCEEDED(hr), "Test %u: Failed to get FVF, hr %#x.\n", i, hr);
671 todo_wine_if (decl_to_fvf_tests[i].todo)
672 ok(fvf == decl_to_fvf_tests[i].fvf,
673 "Test %u: Got unexpected FVF %#x, expected %#x.\n",
674 i, fvf, decl_to_fvf_tests[i].fvf);
676 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
677 IDirect3DVertexDeclaration9_Release(declaration);
680 /* Create a default declaration and FVF that does not match any of the
681 * tests. */
682 hr = IDirect3DDevice9_CreateVertexDeclaration(device, default_elements, &default_decl);
683 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
685 for (i = 0; i < sizeof(fvf_to_decl_tests) / sizeof(*fvf_to_decl_tests); ++i)
687 /* Set a default declaration to make sure it is changed. */
688 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
689 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#x.\n", i, hr);
691 hr = IDirect3DDevice9_SetFVF(device, fvf_to_decl_tests[i].fvf);
692 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#x.\n", i, hr);
694 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
695 ok(SUCCEEDED(hr), "Test %u: Failed to get vertex declaration, hr %#x.\n", i, hr);
696 ok(!!declaration && declaration != default_decl,
697 "Test %u: Got unexpected declaration %p.\n", i, declaration);
698 ok(compare_elements(declaration, fvf_to_decl_tests[i].elements),
699 "Test %u: Declaration does not match.\n", i);
700 IDirect3DVertexDeclaration9_Release(declaration);
703 /* Setting the FVF to 0 should result in no change to the default decl. */
704 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
705 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
706 hr = IDirect3DDevice9_SetFVF(device, 0);
707 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
708 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
709 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
710 ok(declaration == default_decl, "Got unexpected declaration %p, expected %p.\n", declaration, default_decl);
711 IDirect3DVertexDeclaration9_Release(declaration);
713 IDirect3DVertexDeclaration9_Release(default_decl);
714 refcount = IDirect3DDevice9_Release(device);
715 ok(!refcount, "Device has %u references left.\n", refcount);
716 done:
717 IDirect3D9_Release(d3d);
718 DestroyWindow(window);
721 /* Check whether a declaration converted from FVF is shared.
722 * Check whether refcounts behave as expected. */
723 static void test_fvf_decl_management(void)
725 IDirect3DVertexDeclaration9 *declaration1;
726 IDirect3DVertexDeclaration9 *declaration2;
727 IDirect3DVertexDeclaration9 *declaration3;
728 IDirect3DVertexDeclaration9 *declaration4;
729 IDirect3DDevice9 *device;
730 IDirect3D9 *d3d;
731 ULONG refcount;
732 HWND window;
733 HRESULT hr;
735 static const D3DVERTEXELEMENT9 test_elements1[] =
736 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()};
737 static const D3DVERTEXELEMENT9 test_elements2[] =
738 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()};
740 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
741 0, 0, 640, 480, NULL, NULL, NULL, NULL);
742 d3d = Direct3DCreate9(D3D_SDK_VERSION);
743 ok(!!d3d, "Failed to create a D3D object.\n");
744 if (!(device = create_device(d3d, window, NULL)))
746 skip("Failed to create a D3D device, skipping tests.\n");
747 goto done;
750 /* Clear down any current vertex declaration. */
751 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
752 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
753 /* Conversion. */
754 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
755 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
756 /* Get converted decl (#1). */
757 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration1);
758 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
759 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
760 /* Get converted decl again (#2). */
761 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration2);
762 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
763 ok(declaration2 == declaration1, "Got unexpected declaration2 %p, expected %p.\n", declaration2, declaration1);
765 /* Conversion. */
766 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_NORMAL);
767 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
768 /* Get converted decl (#3). */
769 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration3);
770 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
771 ok(declaration3 != declaration2, "Got unexpected declaration3 %p.\n", declaration3);
772 /* The contents should correspond to the second conversion. */
773 ok(compare_elements(declaration3, test_elements2), "Declaration does not match.\n");
774 /* Re-Check if the first decl was overwritten by the new Get(). */
775 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
777 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
778 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
779 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration4);
780 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
781 ok(declaration4 == declaration1, "Got unexpected declaration4 %p, expected %p.\n", declaration4, declaration1);
783 refcount = get_refcount((IUnknown*)declaration1);
784 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
785 refcount = get_refcount((IUnknown*)declaration2);
786 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
787 refcount = get_refcount((IUnknown*)declaration3);
788 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
789 refcount = get_refcount((IUnknown*)declaration4);
790 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
792 IDirect3DVertexDeclaration9_Release(declaration4);
793 IDirect3DVertexDeclaration9_Release(declaration3);
794 IDirect3DVertexDeclaration9_Release(declaration2);
795 IDirect3DVertexDeclaration9_Release(declaration1);
797 refcount = IDirect3DDevice9_Release(device);
798 ok(!refcount, "Device has %u references left.\n", refcount);
799 done:
800 IDirect3D9_Release(d3d);
801 DestroyWindow(window);
804 static void test_vertex_declaration_alignment(void)
806 IDirect3DVertexDeclaration9 *declaration;
807 IDirect3DDevice9 *device;
808 IDirect3D9 *d3d;
809 unsigned int i;
810 ULONG refcount;
811 HWND window;
812 HRESULT hr;
814 static const struct
816 D3DVERTEXELEMENT9 elements[3];
817 HRESULT hr;
819 test_data[] =
823 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
824 {0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
825 D3DDECL_END(),
826 }, D3D_OK,
830 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
831 {0, 17, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
832 D3DDECL_END(),
833 }, E_FAIL,
837 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
838 {0, 18, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
839 D3DDECL_END(),
840 }, E_FAIL,
844 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
845 {0, 19, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
846 D3DDECL_END(),
847 }, E_FAIL,
851 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
852 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
853 D3DDECL_END(),
854 }, D3D_OK,
858 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
859 0, 0, 640, 480, NULL, NULL, NULL, NULL);
860 d3d = Direct3DCreate9(D3D_SDK_VERSION);
861 ok(!!d3d, "Failed to create a D3D object.\n");
862 if (!(device = create_device(d3d, window, NULL)))
864 skip("Failed to create a D3D device, skipping tests.\n");
865 goto done;
868 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
870 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_data[i].elements, &declaration);
871 ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr);
872 if (SUCCEEDED(hr))
873 IDirect3DVertexDeclaration9_Release(declaration);
876 refcount = IDirect3DDevice9_Release(device);
877 ok(!refcount, "Device has %u references left.\n", refcount);
878 done:
879 IDirect3D9_Release(d3d);
880 DestroyWindow(window);
883 static void test_unused_declaration_type(void)
885 IDirect3DVertexDeclaration9 *declaration;
886 IDirect3DDevice9 *device;
887 IDirect3D9 *d3d;
888 unsigned int i;
889 ULONG refcount;
890 HWND window;
891 HRESULT hr;
893 static const D3DVERTEXELEMENT9 test_elements[][3] =
896 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
897 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_COLOR , 0 },
898 D3DDECL_END(),
901 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
902 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 0 },
903 D3DDECL_END(),
906 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
907 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 1 },
908 D3DDECL_END(),
911 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
912 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
913 D3DDECL_END(),
916 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
917 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
918 D3DDECL_END(),
921 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
922 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
923 D3DDECL_END(),
926 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
927 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
928 D3DDECL_END(),
932 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
933 0, 0, 640, 480, NULL, NULL, NULL, NULL);
934 d3d = Direct3DCreate9(D3D_SDK_VERSION);
935 ok(!!d3d, "Failed to create a D3D object.\n");
936 if (!(device = create_device(d3d, window, NULL)))
938 skip("Failed to create a D3D device, skipping tests.\n");
939 goto done;
942 for (i = 0; i < sizeof(test_elements) / sizeof(*test_elements); ++i)
944 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &declaration);
945 ok(hr == E_FAIL, "Test %u: Got unexpected hr %#x.\n", i, hr);
948 refcount = IDirect3DDevice9_Release(device);
949 ok(!refcount, "Device has %u references left.\n", refcount);
950 done:
951 IDirect3D9_Release(d3d);
952 DestroyWindow(window);
955 static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count)
957 IDirect3DBaseTexture9* texture = NULL;
958 HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0,
959 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
961 if (SUCCEEDED(hr)) {
962 DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
963 ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
964 } else
965 trace("CreateTexture failed: %08x\n", hr);
967 if (texture) IDirect3DBaseTexture9_Release( texture );
970 static void test_mipmap_levels(void)
972 IDirect3DDevice9 *device;
973 IDirect3D9 *d3d;
974 ULONG refcount;
975 HWND window;
977 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
978 0, 0, 640, 480, NULL, NULL, NULL, NULL);
979 ok(!!window, "Failed to create a window.\n");
980 d3d = Direct3DCreate9(D3D_SDK_VERSION);
981 ok(!!d3d, "Failed to create a D3D object.\n");
982 if (!(device = create_device(d3d, window, NULL)))
984 skip("Failed to create a 3D device, skipping test.\n");
985 goto cleanup;
988 check_mipmap_levels(device, 32, 32, 6);
989 check_mipmap_levels(device, 256, 1, 9);
990 check_mipmap_levels(device, 1, 256, 9);
991 check_mipmap_levels(device, 1, 1, 1);
993 refcount = IDirect3DDevice9_Release(device);
994 ok(!refcount, "Device has %u references left.\n", refcount);
995 cleanup:
996 IDirect3D9_Release(d3d);
997 DestroyWindow(window);
1000 static void test_checkdevicemultisampletype(void)
1002 DWORD quality_levels;
1003 IDirect3D9 *d3d;
1004 HWND window;
1005 HRESULT hr;
1007 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1008 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1009 ok(!!window, "Failed to create a window.\n");
1010 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1011 ok(!!d3d, "Failed to create a D3D object.\n");
1013 if (IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1014 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL) == D3DERR_NOTAVAILABLE)
1016 skip("Multisampling not supported for D3DFMT_X8R8G8B8, skipping test.\n");
1017 goto cleanup;
1020 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1021 D3DFMT_UNKNOWN, TRUE, D3DMULTISAMPLE_NONE, NULL);
1022 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1023 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1024 65536, TRUE, D3DMULTISAMPLE_NONE, NULL);
1025 todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1027 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1028 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, NULL);
1029 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1031 quality_levels = 0;
1032 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1033 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality_levels);
1034 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1035 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
1036 quality_levels = 0;
1037 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1038 D3DFMT_X8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality_levels);
1039 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1040 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
1042 quality_levels = 0;
1043 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1044 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, NULL);
1045 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1046 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1047 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, &quality_levels);
1048 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1049 ok(quality_levels, "Got unexpected quality_levels %u.\n", quality_levels);
1051 quality_levels = 0;
1052 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1053 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
1054 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1055 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1056 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels);
1057 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1058 ok(quality_levels, "Got unexpected quality_levels %u.\n", quality_levels);
1060 /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */
1061 quality_levels = 0;
1062 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1063 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, NULL);
1064 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
1065 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1066 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, &quality_levels);
1067 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
1068 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
1070 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1071 D3DFMT_X8R8G8B8, TRUE, 65536, NULL);
1072 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1074 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1075 D3DFMT_DXT5, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL);
1076 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
1078 cleanup:
1079 IDirect3D9_Release(d3d);
1080 DestroyWindow(window);
1083 static void test_invalid_multisample(void)
1085 IDirect3DDevice9 *device;
1086 IDirect3DSurface9 *rt;
1087 DWORD quality_levels;
1088 IDirect3D9 *d3d;
1089 BOOL available;
1090 ULONG refcount;
1091 HWND window;
1092 HRESULT hr;
1094 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1095 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1096 ok(!!window, "Failed to create a window.\n");
1097 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1098 ok(!!d3d, "Failed to create a D3D object.\n");
1100 if (!(device = create_device(d3d, window, NULL)))
1102 skip("Failed to create a 3D device, skipping test.\n");
1103 goto cleanup;
1106 available = SUCCEEDED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1107 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, &quality_levels));
1108 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1109 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONMASKABLE, 0, FALSE, &rt, NULL);
1110 if (available)
1112 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1113 IDirect3DSurface9_Release(rt);
1114 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1115 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONMASKABLE, quality_levels, FALSE, &rt, NULL);
1116 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1118 else
1120 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1123 available = SUCCEEDED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1124 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels));
1125 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1126 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
1127 if (available)
1129 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1130 IDirect3DSurface9_Release(rt);
1131 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1132 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, quality_levels, FALSE, &rt, NULL);
1133 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1135 else
1137 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1140 /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */
1141 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1142 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, NULL);
1143 ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
1144 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
1145 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_15_SAMPLES, 0, FALSE, &rt, NULL);
1146 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1148 refcount = IDirect3DDevice9_Release(device);
1149 ok(!refcount, "Device has %u references left.\n", refcount);
1150 cleanup:
1151 IDirect3D9_Release(d3d);
1152 DestroyWindow(window);
1155 static void test_swapchain(void)
1157 IDirect3DSwapChain9 *swapchain0;
1158 IDirect3DSwapChain9 *swapchain1;
1159 IDirect3DSwapChain9 *swapchain2;
1160 IDirect3DSwapChain9 *swapchain3;
1161 IDirect3DSwapChain9 *swapchainX;
1162 IDirect3DSurface9 *backbuffer, *stereo_buffer;
1163 D3DPRESENT_PARAMETERS d3dpp;
1164 IDirect3DDevice9 *device;
1165 IDirect3D9 *d3d;
1166 ULONG refcount;
1167 HWND window, window2;
1168 HRESULT hr;
1169 struct device_desc device_desc;
1171 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1172 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1173 ok(!!window, "Failed to create a window.\n");
1174 window2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1175 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1176 ok(!!window2, "Failed to create a window.\n");
1177 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1178 ok(!!d3d, "Failed to create a D3D object.\n");
1179 if (!(device = create_device(d3d, window, NULL)))
1181 skip("Failed to create a 3D device, skipping test.\n");
1182 goto cleanup;
1185 /* Get the implicit swapchain */
1186 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain0);
1187 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
1188 /* Check if the back buffer count was modified */
1189 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain0, &d3dpp);
1190 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1191 ok(d3dpp.BackBufferCount == 1, "Got unexpected back buffer count %u.\n", d3dpp.BackBufferCount);
1192 IDirect3DSwapChain9_Release(swapchain0);
1194 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, NULL);
1195 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1196 /* IDirect3DDevice9::GetBackBuffer crashes if a NULL output pointer is passed. */
1197 backbuffer = (void *)0xdeadbeef;
1198 hr = IDirect3DDevice9_GetBackBuffer(device, 1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1199 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1200 ok(!backbuffer, "The back buffer pointer is %p, expected NULL.\n", backbuffer);
1201 backbuffer = (void *)0xdeadbeef;
1202 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 1, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1203 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1204 ok(!backbuffer, "The back buffer pointer is %p, expected NULL.\n", backbuffer);
1206 /* Check if there is a back buffer */
1207 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1208 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1209 ok(backbuffer != NULL, "The back buffer is NULL\n");
1210 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1212 /* The back buffer type value is ignored. */
1213 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_LEFT, &stereo_buffer);
1214 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#x.\n", hr);
1215 ok(stereo_buffer == backbuffer, "Expected left back buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1216 IDirect3DSurface9_Release(stereo_buffer);
1217 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_RIGHT, &stereo_buffer);
1218 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#x.\n", hr);
1219 ok(stereo_buffer == backbuffer, "Expected right back buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1220 IDirect3DSurface9_Release(stereo_buffer);
1221 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, (D3DBACKBUFFER_TYPE)0xdeadbeef, &stereo_buffer);
1222 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#x.\n", hr);
1223 ok(stereo_buffer == backbuffer, "Expected unknown buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1224 IDirect3DSurface9_Release(stereo_buffer);
1226 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_LEFT, &stereo_buffer);
1227 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#x.\n", hr);
1228 ok(stereo_buffer == backbuffer, "Expected left back buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1229 IDirect3DSurface9_Release(stereo_buffer);
1230 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_RIGHT, &stereo_buffer);
1231 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#x.\n", hr);
1232 ok(stereo_buffer == backbuffer, "Expected right back buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1233 IDirect3DSurface9_Release(stereo_buffer);
1234 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, (D3DBACKBUFFER_TYPE)0xdeadbeef, &stereo_buffer);
1235 ok(SUCCEEDED(hr), "Failed to get the back buffer, hr %#x.\n", hr);
1236 ok(stereo_buffer == backbuffer, "Expected unknown buffer = %p, got %p.\n", backbuffer, stereo_buffer);
1237 IDirect3DSurface9_Release(stereo_buffer);
1239 /* Try to get a nonexistent swapchain */
1240 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1241 ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr);
1242 ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
1243 if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
1245 /* Create a bunch of swapchains */
1246 d3dpp.BackBufferCount = 0;
1247 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1248 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1249 ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
1251 d3dpp.BackBufferCount = 1;
1252 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain2);
1253 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1255 d3dpp.BackBufferCount = 2;
1256 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain3);
1257 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1258 if(SUCCEEDED(hr)) {
1259 /* Swapchain 3, created with backbuffercount 2 */
1260 backbuffer = (void *) 0xdeadbeef;
1261 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
1262 ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%08x)\n", hr);
1263 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1264 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1266 backbuffer = (void *) 0xdeadbeef;
1267 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
1268 ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%08x)\n", hr);
1269 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1270 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1272 backbuffer = (void *) 0xdeadbeef;
1273 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
1274 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
1275 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1276 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1278 backbuffer = (void *) 0xdeadbeef;
1279 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
1280 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1281 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1282 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1285 /* Check the back buffers of the swapchains */
1286 /* Swapchain 1, created with backbuffercount 0 */
1287 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1288 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1289 ok(backbuffer != NULL, "The back buffer is NULL (%08x)\n", hr);
1290 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1292 backbuffer = (void *) 0xdeadbeef;
1293 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
1294 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1295 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1296 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1298 /* Swapchain 2 - created with backbuffercount 1 */
1299 backbuffer = (void *) 0xdeadbeef;
1300 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
1301 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1302 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1303 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1305 backbuffer = (void *) 0xdeadbeef;
1306 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
1307 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
1308 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1309 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1311 backbuffer = (void *) 0xdeadbeef;
1312 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
1313 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1314 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1315 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1317 /* Try getSwapChain on a manually created swapchain
1318 * it should fail, apparently GetSwapChain only returns implicit swapchains
1320 swapchainX = (void *) 0xdeadbeef;
1321 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1322 ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%08x)\n", hr);
1323 ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
1324 if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
1326 IDirect3DSwapChain9_Release(swapchain3);
1327 IDirect3DSwapChain9_Release(swapchain2);
1328 IDirect3DSwapChain9_Release(swapchain1);
1330 d3dpp.Windowed = FALSE;
1331 d3dpp.hDeviceWindow = window;
1332 d3dpp.BackBufferCount = 1;
1333 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1334 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x\n", hr);
1335 d3dpp.hDeviceWindow = window2;
1336 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1337 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x\n", hr);
1339 device_desc.width = registry_mode.dmPelsWidth;
1340 device_desc.height = registry_mode.dmPelsHeight;
1341 device_desc.device_window = window;
1342 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
1343 hr = reset_device(device, &device_desc);
1344 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
1346 d3dpp.hDeviceWindow = window;
1347 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1348 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x\n", hr);
1349 d3dpp.hDeviceWindow = window2;
1350 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1351 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x\n", hr);
1352 d3dpp.Windowed = TRUE;
1353 d3dpp.hDeviceWindow = window;
1354 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1355 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x\n", hr);
1356 d3dpp.hDeviceWindow = window2;
1357 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1358 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x\n", hr);
1360 refcount = IDirect3DDevice9_Release(device);
1361 ok(!refcount, "Device has %u references left.\n", refcount);
1362 cleanup:
1363 IDirect3D9_Release(d3d);
1364 DestroyWindow(window2);
1365 DestroyWindow(window);
1368 static void test_refcount(void)
1370 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
1371 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
1372 IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
1373 IDirect3DVertexShader9 *pVertexShader = NULL;
1374 IDirect3DPixelShader9 *pPixelShader = NULL;
1375 IDirect3DCubeTexture9 *pCubeTexture = NULL;
1376 IDirect3DTexture9 *pTexture = NULL;
1377 IDirect3DVolumeTexture9 *pVolumeTexture = NULL;
1378 IDirect3DVolume9 *pVolumeLevel = NULL;
1379 IDirect3DSurface9 *pStencilSurface = NULL;
1380 IDirect3DSurface9 *pOffscreenSurface = NULL;
1381 IDirect3DSurface9 *pRenderTarget = NULL;
1382 IDirect3DSurface9 *pRenderTarget2 = NULL;
1383 IDirect3DSurface9 *pRenderTarget3 = NULL;
1384 IDirect3DSurface9 *pTextureLevel = NULL;
1385 IDirect3DSurface9 *pBackBuffer = NULL;
1386 IDirect3DStateBlock9 *pStateBlock = NULL;
1387 IDirect3DStateBlock9 *pStateBlock1 = NULL;
1388 IDirect3DSwapChain9 *pSwapChain = NULL;
1389 IDirect3DQuery9 *pQuery = NULL;
1390 D3DPRESENT_PARAMETERS d3dpp;
1391 IDirect3DDevice9 *device;
1392 ULONG refcount = 0, tmp;
1393 IDirect3D9 *d3d, *d3d2;
1394 HWND window;
1395 HRESULT hr;
1397 D3DVERTEXELEMENT9 decl[] =
1399 D3DDECL_END()
1402 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1403 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1404 ok(!!window, "Failed to create a window.\n");
1405 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1406 ok(!!d3d, "Failed to create a D3D object.\n");
1408 CHECK_REFCOUNT(d3d, 1);
1410 if (!(device = create_device(d3d, window, NULL)))
1412 skip("Failed to create a 3D device, skipping test.\n");
1413 goto cleanup;
1416 refcount = get_refcount((IUnknown *)device);
1417 ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
1419 CHECK_REFCOUNT(d3d, 2);
1421 hr = IDirect3DDevice9_GetDirect3D(device, &d3d2);
1422 CHECK_CALL(hr, "GetDirect3D", device, refcount);
1424 ok(d3d2 == d3d, "Expected IDirect3D9 pointers to be equal.\n");
1425 CHECK_REFCOUNT(d3d, 3);
1426 CHECK_RELEASE_REFCOUNT(d3d, 2);
1429 * Check refcount of implicit surfaces and implicit swapchain. Findings:
1430 * - the container is the device OR swapchain
1431 * - they hold a reference to the device
1432 * - they are created with a refcount of 0 (Get/Release returns original refcount)
1433 * - they are not freed if refcount reaches 0.
1434 * - the refcount is not forwarded to the container.
1436 hr = IDirect3DDevice9_GetSwapChain(device, 0, &pSwapChain);
1437 CHECK_CALL(hr, "GetSwapChain", device, ++refcount);
1438 if (pSwapChain)
1440 CHECK_REFCOUNT( pSwapChain, 1);
1442 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1443 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1444 CHECK_REFCOUNT( pSwapChain, 1);
1445 if(pRenderTarget)
1447 CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
1448 CHECK_REFCOUNT( pRenderTarget, 1);
1450 CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
1451 CHECK_REFCOUNT(device, refcount);
1452 CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
1453 CHECK_REFCOUNT(device, refcount);
1455 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1456 CHECK_CALL(hr, "GetRenderTarget", device, refcount);
1457 CHECK_REFCOUNT( pRenderTarget, 2);
1458 CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
1459 CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
1460 CHECK_REFCOUNT(device, --refcount);
1462 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
1463 CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
1464 CHECK_REFCOUNT(device, ++refcount);
1465 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
1466 CHECK_REFCOUNT(device, --refcount);
1469 /* Render target and back buffer are identical. */
1470 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, 0, &pBackBuffer);
1471 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1472 if(pBackBuffer)
1474 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1475 ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
1476 pRenderTarget, pBackBuffer);
1477 pBackBuffer = NULL;
1479 CHECK_REFCOUNT(device, --refcount);
1481 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &pStencilSurface);
1482 CHECK_CALL(hr, "GetDepthStencilSurface", device, ++refcount);
1483 CHECK_REFCOUNT( pSwapChain, 1);
1484 if(pStencilSurface)
1486 CHECK_SURFACE_CONTAINER(pStencilSurface, IID_IDirect3DDevice9, device);
1487 CHECK_REFCOUNT( pStencilSurface, 1);
1489 CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
1490 CHECK_REFCOUNT(device, refcount);
1491 CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
1492 CHECK_REFCOUNT(device, refcount);
1494 CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
1495 CHECK_REFCOUNT(device, --refcount);
1497 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
1498 CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
1499 CHECK_REFCOUNT(device, ++refcount);
1500 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
1501 CHECK_REFCOUNT(device, --refcount);
1502 pStencilSurface = NULL;
1505 CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
1506 CHECK_REFCOUNT(device, --refcount);
1508 /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
1509 CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
1510 CHECK_REFCOUNT(device, ++refcount);
1511 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1512 CHECK_REFCOUNT(device, --refcount);
1513 pSwapChain = NULL;
1516 /* Buffers */
1517 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL);
1518 CHECK_CALL(hr, "CreateIndexBuffer", device, ++refcount );
1519 if(pIndexBuffer)
1521 tmp = get_refcount( (IUnknown *)pIndexBuffer );
1523 hr = IDirect3DDevice9_SetIndices(device, pIndexBuffer);
1524 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1525 hr = IDirect3DDevice9_SetIndices(device, NULL);
1526 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1529 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL);
1530 CHECK_CALL(hr, "CreateVertexBuffer", device, ++refcount);
1531 if(pVertexBuffer)
1533 IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
1534 UINT offset = ~0;
1535 UINT stride = ~0;
1537 tmp = get_refcount( (IUnknown *)pVertexBuffer );
1539 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 3 * sizeof(float));
1540 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1541 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1542 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1544 hr = IDirect3DDevice9_GetStreamSource(device, 0, &pVBuf, &offset, &stride);
1545 ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
1546 ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
1547 ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
1548 ok(offset==0, "offset not 0 (got %u)!\n", offset);
1550 /* Shaders */
1551 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pVertexDeclaration);
1552 CHECK_CALL(hr, "CreateVertexDeclaration", device, ++refcount);
1553 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &pVertexShader);
1554 CHECK_CALL(hr, "CreateVertexShader", device, ++refcount);
1555 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &pPixelShader);
1556 CHECK_CALL(hr, "CreatePixelShader", device, ++refcount);
1557 /* Textures */
1558 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL);
1559 CHECK_CALL(hr, "CreateTexture", device, ++refcount);
1560 if (pTexture)
1562 tmp = get_refcount( (IUnknown *)pTexture );
1564 /* SetTexture should not increase refcounts */
1565 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)pTexture);
1566 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1567 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1568 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1570 /* This should not increment device refcount */
1571 hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
1572 CHECK_CALL(hr, "GetSurfaceLevel", device, refcount);
1573 /* But should increment texture's refcount */
1574 CHECK_REFCOUNT( pTexture, tmp+1 );
1575 /* Because the texture and surface refcount are identical */
1576 if (pTextureLevel)
1578 CHECK_REFCOUNT ( pTextureLevel, tmp+1 );
1579 CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
1580 CHECK_REFCOUNT ( pTexture , tmp+2 );
1581 CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
1582 CHECK_REFCOUNT ( pTexture , tmp+1 );
1583 CHECK_RELEASE_REFCOUNT( pTexture , tmp );
1584 CHECK_REFCOUNT ( pTextureLevel, tmp );
1587 hr = IDirect3DDevice9_CreateCubeTexture(device, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL);
1588 CHECK_CALL(hr, "CreateCubeTexture", device, ++refcount);
1589 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 2, 0, 0,
1590 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL);
1591 CHECK_CALL(hr, "CreateVolumeTexture", device, ++refcount);
1592 if (pVolumeTexture)
1594 tmp = get_refcount( (IUnknown *)pVolumeTexture );
1596 /* This should not increment device refcount */
1597 hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
1598 CHECK_CALL(hr, "GetVolumeLevel", device, refcount);
1599 /* But should increment volume texture's refcount */
1600 CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
1601 /* Because the volume texture and volume refcount are identical */
1602 if (pVolumeLevel)
1604 CHECK_REFCOUNT ( pVolumeLevel , tmp+1 );
1605 CHECK_ADDREF_REFCOUNT ( pVolumeLevel , tmp+2 );
1606 CHECK_REFCOUNT ( pVolumeTexture, tmp+2 );
1607 CHECK_RELEASE_REFCOUNT( pVolumeLevel , tmp+1 );
1608 CHECK_REFCOUNT ( pVolumeTexture, tmp+1 );
1609 CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp );
1610 CHECK_REFCOUNT ( pVolumeLevel , tmp );
1613 /* Surfaces */
1614 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32,
1615 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL);
1616 CHECK_CALL(hr, "CreateDepthStencilSurface", device, ++refcount);
1617 CHECK_REFCOUNT( pStencilSurface, 1 );
1618 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1619 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL);
1620 CHECK_CALL(hr, "CreateOffscreenPlainSurface", device, ++refcount);
1621 CHECK_REFCOUNT( pOffscreenSurface, 1 );
1622 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
1623 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL);
1624 CHECK_CALL(hr, "CreateRenderTarget", device, ++refcount);
1625 CHECK_REFCOUNT( pRenderTarget3, 1 );
1626 /* Misc */
1627 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &pStateBlock);
1628 CHECK_CALL(hr, "CreateStateBlock", device, ++refcount);
1630 memset(&d3dpp, 0, sizeof(d3dpp));
1631 d3dpp.Windowed = TRUE;
1632 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1633 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1634 d3dpp.EnableAutoDepthStencil = TRUE;
1635 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1636 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &pSwapChain);
1637 CHECK_CALL(hr, "CreateAdditionalSwapChain", device, ++refcount);
1638 if(pSwapChain)
1640 /* check implicit back buffer */
1641 hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
1642 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1643 CHECK_REFCOUNT( pSwapChain, 1);
1644 if(pBackBuffer)
1646 CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
1647 CHECK_REFCOUNT( pBackBuffer, 1);
1648 CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
1649 CHECK_REFCOUNT(device, --refcount);
1651 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
1652 CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
1653 CHECK_REFCOUNT(device, ++refcount);
1654 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1655 CHECK_REFCOUNT(device, --refcount);
1656 pBackBuffer = NULL;
1658 CHECK_REFCOUNT( pSwapChain, 1);
1660 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &pQuery);
1661 CHECK_CALL(hr, "CreateQuery", device, ++refcount);
1663 hr = IDirect3DDevice9_BeginStateBlock(device);
1664 CHECK_CALL(hr, "BeginStateBlock", device, refcount);
1665 hr = IDirect3DDevice9_EndStateBlock(device, &pStateBlock1);
1666 CHECK_CALL(hr, "EndStateBlock", device, ++refcount);
1668 /* The implicit render target is not freed if refcount reaches 0.
1669 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
1670 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget2);
1671 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1672 if(pRenderTarget2)
1674 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
1675 ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
1676 pRenderTarget, pRenderTarget2);
1677 CHECK_REFCOUNT(device, --refcount);
1678 pRenderTarget2 = NULL;
1680 pRenderTarget = NULL;
1682 cleanup:
1683 CHECK_RELEASE(device, device, --refcount);
1685 /* Buffers */
1686 CHECK_RELEASE(pVertexBuffer, device, --refcount);
1687 CHECK_RELEASE(pIndexBuffer, device, --refcount);
1688 /* Shaders */
1689 CHECK_RELEASE(pVertexDeclaration, device, --refcount);
1690 CHECK_RELEASE(pVertexShader, device, --refcount);
1691 CHECK_RELEASE(pPixelShader, device, --refcount);
1692 /* Textures */
1693 CHECK_RELEASE(pTextureLevel, device, --refcount);
1694 CHECK_RELEASE(pCubeTexture, device, --refcount);
1695 CHECK_RELEASE(pVolumeTexture, device, --refcount);
1696 /* Surfaces */
1697 CHECK_RELEASE(pStencilSurface, device, --refcount);
1698 CHECK_RELEASE(pOffscreenSurface, device, --refcount);
1699 CHECK_RELEASE(pRenderTarget3, device, --refcount);
1700 /* Misc */
1701 CHECK_RELEASE(pStateBlock, device, --refcount);
1702 CHECK_RELEASE(pSwapChain, device, --refcount);
1703 CHECK_RELEASE(pQuery, device, --refcount);
1704 /* This will destroy device - cannot check the refcount here */
1705 if (pStateBlock1) CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
1706 CHECK_RELEASE_REFCOUNT(d3d, 0);
1707 DestroyWindow(window);
1710 static void test_cursor(void)
1712 IDirect3DSurface9 *cursor = NULL;
1713 IDirect3DDevice9 *device;
1714 CURSORINFO info;
1715 IDirect3D9 *d3d;
1716 ULONG refcount;
1717 HCURSOR cur;
1718 HWND window;
1719 HRESULT hr;
1720 BOOL ret;
1722 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1723 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1724 ok(!!window, "Failed to create a window.\n");
1726 ret = SetCursorPos(50, 50);
1727 ok(ret, "Failed to set cursor position.\n");
1728 flush_events();
1729 memset(&info, 0, sizeof(info));
1730 info.cbSize = sizeof(info);
1731 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1732 cur = info.hCursor;
1734 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1735 ok(!!d3d, "Failed to create a D3D object.\n");
1736 if (!(device = create_device(d3d, window, NULL)))
1738 skip("Failed to create a 3D device, skipping test.\n");
1739 goto cleanup;
1742 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1743 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
1744 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
1746 /* Initially hidden */
1747 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
1748 ok(!ret, "IDirect3DDevice9_ShowCursor returned %d\n", ret);
1750 /* Not enabled without a surface*/
1751 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
1752 ok(!ret, "IDirect3DDevice9_ShowCursor returned %d\n", ret);
1754 /* Fails */
1755 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, NULL);
1756 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
1758 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
1759 ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
1761 IDirect3DSurface9_Release(cursor);
1763 memset(&info, 0, sizeof(info));
1764 info.cbSize = sizeof(info);
1765 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1766 ok(info.flags & (CURSOR_SHOWING|CURSOR_SUPPRESSED), "The gdi cursor is hidden (%08x)\n", info.flags);
1767 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
1769 /* Still hidden */
1770 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
1771 ok(!ret, "IDirect3DDevice9_ShowCursor returned %d\n", ret);
1773 /* Enabled now*/
1774 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
1775 ok(ret, "IDirect3DDevice9_ShowCursor returned %d\n", ret);
1777 memset(&info, 0, sizeof(info));
1778 info.cbSize = sizeof(info);
1779 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1780 ok(info.flags & (CURSOR_SHOWING|CURSOR_SUPPRESSED), "The gdi cursor is hidden (%08x)\n", info.flags);
1781 ok(info.hCursor != cur, "The cursor handle is %p\n", info.hCursor);
1783 refcount = IDirect3DDevice9_Release(device);
1784 ok(!refcount, "Device has %u references left.\n", refcount);
1785 cleanup:
1786 IDirect3D9_Release(d3d);
1787 DestroyWindow(window);
1790 static void test_reset(void)
1792 HRESULT hr;
1793 RECT winrect;
1794 D3DPRESENT_PARAMETERS d3dpp;
1795 D3DDISPLAYMODE d3ddm, d3ddm2;
1796 D3DVIEWPORT9 vp;
1797 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
1798 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
1799 IDirect3DSurface9 *surface;
1800 IDirect3DTexture9 *texture;
1801 IDirect3DVertexShader9 *shader;
1802 UINT i, adapter_mode_count;
1803 D3DLOCKED_RECT lockrect;
1804 IDirect3DDevice9 *device1 = NULL;
1805 IDirect3DDevice9 *device2 = NULL;
1806 IDirect3DSwapChain9 *swapchain;
1807 struct device_desc device_desc;
1808 IDirect3D9 *d3d;
1809 D3DCAPS9 caps;
1810 DWORD value;
1811 HWND hwnd;
1812 struct
1814 UINT w;
1815 UINT h;
1816 } *modes = NULL;
1817 UINT mode_count = 0;
1819 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1820 100, 100, 160, 160, NULL, NULL, NULL, NULL);
1821 ok(!!hwnd, "Failed to create a window.\n");
1822 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1823 ok(!!d3d, "Failed to create a D3D object.\n");
1825 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
1826 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, d3ddm.Format);
1827 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
1828 for(i = 0; i < adapter_mode_count; ++i)
1830 UINT j;
1831 ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
1832 hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
1833 ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#x\n", hr);
1835 for (j = 0; j < mode_count; ++j)
1837 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
1838 break;
1840 if (j == mode_count)
1842 modes[j].w = d3ddm2.Width;
1843 modes[j].h = d3ddm2.Height;
1844 ++mode_count;
1847 /* We use them as invalid modes */
1848 if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
1849 (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
1850 skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
1851 d3ddm2.Width, d3ddm2.Height);
1852 goto cleanup;
1856 if (mode_count < 2)
1858 skip("Less than 2 modes supported, skipping mode tests\n");
1859 goto cleanup;
1862 i = 0;
1863 if (modes[i].w == orig_width && modes[i].h == orig_height) ++i;
1865 device_desc.width = modes[i].w;
1866 device_desc.height = modes[i].h;
1867 device_desc.device_window = hwnd;
1868 device_desc.flags = CREATE_DEVICE_FULLSCREEN | CREATE_DEVICE_SWVP_ONLY;
1869 if (!(device1 = create_device(d3d, hwnd, &device_desc)))
1871 skip("Failed to create a D3D device, skipping tests.\n");
1872 goto cleanup;
1874 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1875 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1877 hr = IDirect3DDevice9_GetDeviceCaps(device1, &caps);
1878 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
1880 width = GetSystemMetrics(SM_CXSCREEN);
1881 height = GetSystemMetrics(SM_CYSCREEN);
1882 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1883 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1885 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1886 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1887 if(SUCCEEDED(hr))
1889 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1890 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1891 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1892 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1893 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1894 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1897 i = 1;
1898 vp.X = 10;
1899 vp.Y = 20;
1900 vp.MinZ = 2;
1901 vp.MaxZ = 3;
1902 hr = IDirect3DDevice9_SetViewport(device1, &vp);
1903 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1905 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1906 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1907 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1908 hr = IDirect3DDevice9_SetRenderState(device1, D3DRS_LIGHTING, FALSE);
1909 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1911 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1912 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1913 d3dpp.Windowed = FALSE;
1914 d3dpp.BackBufferWidth = modes[i].w;
1915 d3dpp.BackBufferHeight = modes[i].h;
1916 d3dpp.BackBufferFormat = d3ddm.Format;
1917 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1918 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1919 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1920 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1922 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1923 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1924 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1926 ZeroMemory(&vp, sizeof(vp));
1927 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1928 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1929 if(SUCCEEDED(hr))
1931 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1932 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1933 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1934 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1935 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1936 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1939 width = GetSystemMetrics(SM_CXSCREEN);
1940 height = GetSystemMetrics(SM_CYSCREEN);
1941 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1942 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1944 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &swapchain);
1945 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1946 memset(&d3dpp, 0, sizeof(d3dpp));
1947 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1948 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1949 ok(d3dpp.BackBufferWidth == modes[i].w, "Got unexpected BackBufferWidth %u, expected %u.\n",
1950 d3dpp.BackBufferWidth, modes[i].w);
1951 ok(d3dpp.BackBufferHeight == modes[i].h, "Got unexpected BackBufferHeight %u, expected %u.\n",
1952 d3dpp.BackBufferHeight, modes[i].h);
1953 IDirect3DSwapChain9_Release(swapchain);
1955 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1956 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1957 d3dpp.Windowed = TRUE;
1958 d3dpp.BackBufferWidth = 400;
1959 d3dpp.BackBufferHeight = 300;
1960 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1961 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1962 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1963 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1964 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1966 width = GetSystemMetrics(SM_CXSCREEN);
1967 height = GetSystemMetrics(SM_CYSCREEN);
1968 ok(width == orig_width, "Screen width is %d\n", width);
1969 ok(height == orig_height, "Screen height is %d\n", height);
1971 ZeroMemory(&vp, sizeof(vp));
1972 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1973 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1974 if(SUCCEEDED(hr))
1976 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1977 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1978 ok(vp.Width == 400, "D3DVIEWPORT->Width = %d\n", vp.Width);
1979 ok(vp.Height == 300, "D3DVIEWPORT->Height = %d\n", vp.Height);
1980 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1981 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1984 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &swapchain);
1985 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
1986 memset(&d3dpp, 0, sizeof(d3dpp));
1987 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
1988 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
1989 ok(d3dpp.BackBufferWidth == 400, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
1990 ok(d3dpp.BackBufferHeight == 300, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
1991 IDirect3DSwapChain9_Release(swapchain);
1993 SetRect(&winrect, 0, 0, 200, 150);
1994 ok(AdjustWindowRect(&winrect, WS_OVERLAPPEDWINDOW, FALSE), "AdjustWindowRect failed\n");
1995 ok(SetWindowPos(hwnd, NULL, 0, 0,
1996 winrect.right-winrect.left,
1997 winrect.bottom-winrect.top,
1998 SWP_NOMOVE|SWP_NOZORDER),
1999 "SetWindowPos failed\n");
2001 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2002 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2003 d3dpp.Windowed = TRUE;
2004 d3dpp.BackBufferWidth = 0;
2005 d3dpp.BackBufferHeight = 0;
2006 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
2007 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2008 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2009 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2010 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2012 ok(d3dpp.BackBufferWidth == 200, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
2013 ok(d3dpp.BackBufferHeight == 150, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
2014 ok(d3dpp.BackBufferFormat == d3ddm.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
2015 d3dpp.BackBufferFormat, d3ddm.Format);
2016 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
2017 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
2018 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
2019 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
2020 ok(!d3dpp.hDeviceWindow, "Got unexpected hDeviceWindow %p.\n", d3dpp.hDeviceWindow);
2021 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
2022 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
2023 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
2024 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
2025 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
2026 d3dpp.FullScreen_RefreshRateInHz);
2027 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
2029 ZeroMemory(&vp, sizeof(vp));
2030 hr = IDirect3DDevice9_GetViewport(device1, &vp);
2031 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
2032 if(SUCCEEDED(hr))
2034 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
2035 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
2036 ok(vp.Width == 200, "D3DVIEWPORT->Width = %d\n", vp.Width);
2037 ok(vp.Height == 150, "D3DVIEWPORT->Height = %d\n", vp.Height);
2038 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
2039 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
2042 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &swapchain);
2043 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x.\n", hr);
2044 memset(&d3dpp, 0, sizeof(d3dpp));
2045 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
2046 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x.\n", hr);
2047 ok(d3dpp.BackBufferWidth == 200, "Got unexpected BackBufferWidth %u.\n", d3dpp.BackBufferWidth);
2048 ok(d3dpp.BackBufferHeight == 150, "Got unexpected BackBufferHeight %u.\n", d3dpp.BackBufferHeight);
2049 ok(d3dpp.BackBufferFormat == d3ddm.Format, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
2050 d3dpp.BackBufferFormat, d3ddm.Format);
2051 ok(d3dpp.BackBufferCount == 1, "Got unexpected BackBufferCount %u.\n", d3dpp.BackBufferCount);
2052 ok(!d3dpp.MultiSampleType, "Got unexpected MultiSampleType %u.\n", d3dpp.MultiSampleType);
2053 ok(!d3dpp.MultiSampleQuality, "Got unexpected MultiSampleQuality %u.\n", d3dpp.MultiSampleQuality);
2054 ok(d3dpp.SwapEffect == D3DSWAPEFFECT_DISCARD, "Got unexpected SwapEffect %#x.\n", d3dpp.SwapEffect);
2055 ok(d3dpp.hDeviceWindow == hwnd, "Got unexpected hDeviceWindow %p, expected %p.\n", d3dpp.hDeviceWindow, hwnd);
2056 ok(d3dpp.Windowed, "Got unexpected Windowed %#x.\n", d3dpp.Windowed);
2057 ok(!d3dpp.EnableAutoDepthStencil, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp.EnableAutoDepthStencil);
2058 ok(!d3dpp.AutoDepthStencilFormat, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp.AutoDepthStencilFormat);
2059 ok(!d3dpp.Flags, "Got unexpected Flags %#x.\n", d3dpp.Flags);
2060 ok(!d3dpp.FullScreen_RefreshRateInHz, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
2061 d3dpp.FullScreen_RefreshRateInHz);
2062 ok(!d3dpp.PresentationInterval, "Got unexpected PresentationInterval %#x.\n", d3dpp.PresentationInterval);
2063 IDirect3DSwapChain9_Release(swapchain);
2065 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2066 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2067 d3dpp.Windowed = TRUE;
2068 d3dpp.BackBufferWidth = 400;
2069 d3dpp.BackBufferHeight = 300;
2071 /* _Reset fails if there is a resource in the default pool */
2072 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
2073 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
2074 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2075 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2076 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2077 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2078 IDirect3DSurface9_Release(surface);
2079 /* Reset again to get the device out of the lost state */
2080 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2081 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2082 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2083 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2085 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
2087 IDirect3DVolumeTexture9 *volume_texture;
2089 hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
2090 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
2091 ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#x.\n", hr);
2092 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2093 ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
2094 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2095 ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n",
2096 hr, D3DERR_DEVICENOTRESET);
2097 IDirect3DVolumeTexture9_Release(volume_texture);
2098 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2099 ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
2100 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2101 ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#x.\n", hr);
2103 else
2105 skip("Volume textures not supported.\n");
2108 /* Scratch, sysmem and managed pools are fine */
2109 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
2110 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
2111 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2112 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2113 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2114 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2115 IDirect3DSurface9_Release(surface);
2117 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
2118 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
2119 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
2120 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2121 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2122 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2123 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2124 IDirect3DSurface9_Release(surface);
2126 /* The depth stencil should get reset to the auto depth stencil when present. */
2127 hr = IDirect3DDevice9_SetDepthStencilSurface(device1, NULL);
2128 ok(hr == D3D_OK, "SetDepthStencilSurface failed with 0x%08x\n", hr);
2130 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
2131 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
2132 ok(surface == NULL, "Depth stencil should be NULL\n");
2134 d3dpp.EnableAutoDepthStencil = TRUE;
2135 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2136 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2137 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
2139 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
2140 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
2141 ok(surface != NULL, "Depth stencil should not be NULL\n");
2142 if (surface) IDirect3DSurface9_Release(surface);
2144 d3dpp.EnableAutoDepthStencil = FALSE;
2145 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2146 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
2148 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
2149 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
2150 ok(surface == NULL, "Depth stencil should be NULL\n");
2152 /* Will a sysmem or scratch survive while locked */
2153 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
2154 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
2155 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
2156 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
2157 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
2158 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2159 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2160 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2161 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2162 IDirect3DSurface9_UnlockRect(surface);
2163 IDirect3DSurface9_Release(surface);
2165 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
2166 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
2167 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
2168 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
2169 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2170 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2171 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2172 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2173 IDirect3DSurface9_UnlockRect(surface);
2174 IDirect3DSurface9_Release(surface);
2176 hr = IDirect3DDevice9_CreateTexture(device1, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
2177 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
2178 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2179 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2180 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2181 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2182 IDirect3DTexture9_Release(texture);
2184 /* A reference held to an implicit surface causes failures as well */
2185 hr = IDirect3DDevice9_GetBackBuffer(device1, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
2186 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr);
2187 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2188 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2189 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2190 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2191 IDirect3DSurface9_Release(surface);
2192 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2193 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2194 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2195 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2197 /* Shaders are fine as well */
2198 hr = IDirect3DDevice9_CreateVertexShader(device1, simple_vs, &shader);
2199 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2200 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2201 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2202 IDirect3DVertexShader9_Release(shader);
2204 /* Try setting invalid modes */
2205 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2206 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2207 d3dpp.Windowed = FALSE;
2208 d3dpp.BackBufferWidth = 32;
2209 d3dpp.BackBufferHeight = 32;
2210 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2211 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr);
2212 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2213 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2215 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2216 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2217 d3dpp.Windowed = FALSE;
2218 d3dpp.BackBufferWidth = 801;
2219 d3dpp.BackBufferHeight = 600;
2220 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2221 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr);
2222 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2223 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2225 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2226 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2227 d3dpp.Windowed = FALSE;
2228 d3dpp.BackBufferWidth = 0;
2229 d3dpp.BackBufferHeight = 0;
2230 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2231 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=0, h=0, windowed=FALSE failed with %08x\n", hr);
2232 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2233 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2235 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2237 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2238 d3dpp.Windowed = TRUE;
2239 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2240 d3dpp.BackBufferFormat = d3ddm.Format;
2241 d3dpp.EnableAutoDepthStencil = FALSE;
2242 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2244 if (FAILED(hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2245 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2)))
2247 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
2248 goto cleanup;
2251 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
2252 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
2254 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2255 d3dpp.Windowed = TRUE;
2256 d3dpp.BackBufferWidth = 400;
2257 d3dpp.BackBufferHeight = 300;
2258 d3dpp.EnableAutoDepthStencil = TRUE;
2259 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2261 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
2262 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
2264 if (FAILED(hr)) goto cleanup;
2266 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
2267 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
2268 ok(surface != NULL, "Depth stencil should not be NULL\n");
2269 if (surface) IDirect3DSurface9_Release(surface);
2271 cleanup:
2272 HeapFree(GetProcessHeap(), 0, modes);
2273 if (device2)
2275 UINT refcount = IDirect3DDevice9_Release(device2);
2276 ok(!refcount, "Device has %u references left.\n", refcount);
2278 if (device1)
2280 UINT refcount = IDirect3DDevice9_Release(device1);
2281 ok(!refcount, "Device has %u references left.\n", refcount);
2283 IDirect3D9_Release(d3d);
2284 DestroyWindow(hwnd);
2287 /* Test adapter display modes */
2288 static void test_display_modes(void)
2290 D3DDISPLAYMODE dmode;
2291 IDirect3D9 *d3d;
2293 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2294 ok(!!d3d, "Failed to create a D3D object.\n");
2296 #define TEST_FMT(x,r) do { \
2297 HRESULT res = IDirect3D9_EnumAdapterModes(d3d, 0, (x), 0, &dmode); \
2298 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
2299 } while(0)
2301 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
2302 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
2303 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2304 /* D3DFMT_R5G6B5 */
2305 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
2306 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
2307 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
2308 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
2309 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
2310 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
2311 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
2312 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
2313 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
2314 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2315 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
2316 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
2318 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
2319 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
2321 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
2322 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
2323 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
2325 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
2326 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
2327 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
2328 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
2329 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
2330 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
2332 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
2333 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
2334 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
2335 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
2336 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
2337 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
2338 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
2339 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
2340 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
2341 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
2343 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
2344 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
2345 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
2346 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
2347 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
2348 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
2349 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
2350 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
2351 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
2352 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
2354 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
2355 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
2356 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
2357 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
2358 /* Floating point formats */
2359 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
2360 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
2361 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
2363 /* IEEE formats */
2364 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
2365 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
2366 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
2368 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
2370 TEST_FMT(0, D3DERR_INVALIDCALL);
2372 IDirect3D9_Release(d3d);
2375 static void test_scene(void)
2377 IDirect3DSurface9 *surface1, *surface2, *surface3;
2378 IDirect3DSurface9 *backBuffer, *rt, *ds;
2379 RECT rect = {0, 0, 128, 128};
2380 IDirect3DDevice9 *device;
2381 IDirect3D9 *d3d;
2382 ULONG refcount;
2383 D3DCAPS9 caps;
2384 HWND window;
2385 HRESULT hr;
2387 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2388 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2389 ok(!!window, "Failed to create a window.\n");
2390 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2391 ok(!!d3d, "Failed to create a D3D object.\n");
2392 if (!(device = create_device(d3d, window, NULL)))
2394 skip("Failed to create a 3D device, skipping test.\n");
2395 goto cleanup;
2398 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
2399 memset(&caps, 0, sizeof(caps));
2400 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2401 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
2403 /* Test an EndScene without BeginScene. Should return an error */
2404 hr = IDirect3DDevice9_EndScene(device);
2405 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2407 /* Test a normal BeginScene / EndScene pair, this should work */
2408 hr = IDirect3DDevice9_BeginScene(device);
2409 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2410 hr = IDirect3DDevice9_EndScene(device);
2411 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2413 /* Test another EndScene without having begun a new scene. Should return an error */
2414 hr = IDirect3DDevice9_EndScene(device);
2415 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2417 /* Two nested BeginScene and EndScene calls */
2418 hr = IDirect3DDevice9_BeginScene(device);
2419 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2420 hr = IDirect3DDevice9_BeginScene(device);
2421 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
2422 hr = IDirect3DDevice9_EndScene(device);
2423 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2424 hr = IDirect3DDevice9_EndScene(device);
2425 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2427 /* Create some surfaces to test stretchrect between the scenes */
2428 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2429 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface1, NULL);
2430 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2431 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2432 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface2, NULL);
2433 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2434 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 800, 600,
2435 D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &surface3, NULL);
2436 ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
2437 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
2438 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
2439 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
2441 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
2442 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
2443 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
2444 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
2446 /* First make sure a simple StretchRect call works */
2447 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2448 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2449 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2450 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2451 if (0) /* Disabled for now because it crashes in wine */
2453 HRESULT expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
2454 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2455 ok(hr == expected, "Got unexpected hr %#x, expected %#x.\n", hr, expected);
2458 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a
2459 * BeginScene - Endscene pair with normal surfaces and render targets, but
2460 * not depth stencil surfaces. */
2461 hr = IDirect3DDevice9_BeginScene(device);
2462 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2464 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2465 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2466 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2467 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2468 /* This is supposed to fail inside a BeginScene - EndScene pair. */
2469 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2470 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
2472 hr = IDirect3DDevice9_EndScene(device);
2473 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2475 /* Does a SetRenderTarget influence BeginScene / EndScene ?
2476 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
2477 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
2479 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
2480 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
2481 hr = IDirect3DDevice9_BeginScene(device);
2482 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2483 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backBuffer);
2484 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
2485 hr = IDirect3DDevice9_EndScene(device);
2486 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2488 IDirect3DSurface9_Release(rt);
2489 IDirect3DSurface9_Release(ds);
2490 IDirect3DSurface9_Release(backBuffer);
2491 IDirect3DSurface9_Release(surface1);
2492 IDirect3DSurface9_Release(surface2);
2493 IDirect3DSurface9_Release(surface3);
2494 refcount = IDirect3DDevice9_Release(device);
2495 ok(!refcount, "Device has %u references left.\n", refcount);
2496 cleanup:
2497 IDirect3D9_Release(d3d);
2498 DestroyWindow(window);
2501 static void test_limits(void)
2503 IDirect3DTexture9 *texture;
2504 IDirect3DDevice9 *device;
2505 IDirect3D9 *d3d;
2506 unsigned int i;
2507 ULONG refcount;
2508 HWND window;
2509 HRESULT hr;
2511 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2512 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2513 ok(!!window, "Failed to create a window.\n");
2514 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2515 ok(!!d3d, "Failed to create a D3D object.\n");
2516 if (!(device = create_device(d3d, window, NULL)))
2518 skip("Failed to create a 3D device, skipping test.\n");
2519 goto cleanup;
2522 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
2523 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2525 /* There are 16 pixel samplers. We should be able to access all of them */
2526 for (i = 0; i < 16; ++i)
2528 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture);
2529 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
2530 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2531 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
2532 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_SRGBTEXTURE, TRUE);
2533 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
2536 /* Now test all 8 textures stage states */
2537 for (i = 0; i < 8; ++i)
2539 hr = IDirect3DDevice9_SetTextureStageState(device, i, D3DTSS_COLOROP, D3DTOP_ADD);
2540 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
2543 /* Investigations show that accessing higher samplers / textures stage
2544 * states does not return an error either. Writing to too high samplers
2545 * (approximately sampler 40) causes memory corruption in Windows, so
2546 * there is no bounds checking. */
2547 IDirect3DTexture9_Release(texture);
2548 refcount = IDirect3D9_Release(device);
2549 ok(!refcount, "Device has %u references left.\n", refcount);
2550 cleanup:
2551 IDirect3D9_Release(d3d);
2552 DestroyWindow(window);
2555 static void test_depthstenciltest(void)
2557 HRESULT hr;
2558 IDirect3DDevice9 *pDevice = NULL;
2559 D3DPRESENT_PARAMETERS d3dpp;
2560 D3DDISPLAYMODE d3ddm;
2561 IDirect3DSurface9 *pDepthStencil = NULL;
2562 IDirect3DSurface9 *pDepthStencil2 = NULL;
2563 IDirect3D9 *d3d;
2564 DWORD state;
2565 HWND hwnd;
2567 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2568 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2569 ok(!!hwnd, "Failed to create a window.\n");
2570 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2571 ok(!!d3d, "Failed to create a D3D object.\n");
2573 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2574 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2575 d3dpp.Windowed = TRUE;
2576 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2577 d3dpp.BackBufferWidth = 800;
2578 d3dpp.BackBufferHeight = 600;
2579 d3dpp.BackBufferFormat = d3ddm.Format;
2580 d3dpp.EnableAutoDepthStencil = TRUE;
2581 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2583 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2584 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2585 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || broken(hr == D3DERR_INVALIDCALL), "IDirect3D9_CreateDevice failed with %08x\n", hr);
2586 if(!pDevice)
2588 skip("Failed to create a d3d device\n");
2589 goto cleanup;
2592 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2593 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
2595 /* Try to clear */
2596 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2597 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2599 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
2600 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
2602 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
2603 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
2604 ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
2605 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
2607 /* This left the render states untouched! */
2608 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2609 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2610 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2611 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
2612 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2613 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
2614 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
2615 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2616 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
2617 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
2618 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2619 ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
2621 /* This is supposed to fail now */
2622 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2623 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2625 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
2626 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
2628 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
2629 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
2631 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2632 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2633 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2635 /* Now it works again */
2636 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2637 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2639 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2640 if(pDevice) IDirect3D9_Release(pDevice);
2642 /* Now see if autodepthstencil disable is honored. First, without a format set */
2643 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2644 d3dpp.Windowed = TRUE;
2645 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2646 d3dpp.BackBufferWidth = 800;
2647 d3dpp.BackBufferHeight = 600;
2648 d3dpp.BackBufferFormat = d3ddm.Format;
2649 d3dpp.EnableAutoDepthStencil = FALSE;
2650 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2652 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2653 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2654 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2655 if(!pDevice)
2657 skip("Failed to create a d3d device\n");
2658 goto cleanup;
2661 pDepthStencil = NULL;
2662 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2663 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
2664 if(pDepthStencil) {
2665 IDirect3DSurface9_Release(pDepthStencil);
2666 pDepthStencil = NULL;
2669 /* Check the depth test state */
2670 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2671 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2672 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2674 if(pDevice) IDirect3D9_Release(pDevice);
2676 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
2677 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2678 d3dpp.Windowed = TRUE;
2679 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2680 d3dpp.BackBufferWidth = 800;
2681 d3dpp.BackBufferHeight = 600;
2682 d3dpp.BackBufferFormat = d3ddm.Format;
2683 d3dpp.EnableAutoDepthStencil = FALSE;
2684 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2686 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2687 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2688 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2689 if(!pDevice)
2691 skip("Failed to create a d3d device\n");
2692 goto cleanup;
2695 pDepthStencil = NULL;
2696 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2697 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
2698 if(pDepthStencil) {
2699 IDirect3DSurface9_Release(pDepthStencil);
2700 pDepthStencil = NULL;
2703 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2704 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2705 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2707 cleanup:
2708 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2709 if (pDevice)
2711 UINT refcount = IDirect3D9_Release(pDevice);
2712 ok(!refcount, "Device has %u references left.\n", refcount);
2714 IDirect3D9_Release(d3d);
2715 DestroyWindow(hwnd);
2718 static void test_get_rt(void)
2720 IDirect3DSurface9 *backbuffer, *rt;
2721 IDirect3DDevice9 *device;
2722 IDirect3D9 *d3d9;
2723 D3DCAPS9 caps;
2724 HWND window;
2725 HRESULT hr;
2726 ULONG ref;
2727 UINT i;
2729 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2730 0, 0, 128, 128, 0, 0, 0, 0);
2731 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2732 ok(!!d3d9, "Failed to create a D3D object.\n");
2733 device = create_device(d3d9, window, NULL);
2734 if (!device)
2736 skip("Failed to create a D3D device, skipping tests.\n");
2737 goto done;
2740 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
2741 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
2742 ok(!!backbuffer, "Got a NULL backbuffer.\n");
2744 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2745 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2747 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
2749 rt = backbuffer;
2750 hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
2751 ok(hr == D3DERR_NOTFOUND, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr);
2752 ok(!rt, "Got rt %p.\n", rt);
2755 IDirect3DSurface9_Release(backbuffer);
2757 ref = IDirect3DDevice9_Release(device);
2758 ok(!ref, "The device was not properly freed: refcount %u.\n", ref);
2759 done:
2760 IDirect3D9_Release(d3d9);
2761 DestroyWindow(window);
2764 static void test_draw_primitive(void)
2766 static const struct
2768 float position[3];
2769 DWORD color;
2771 quad[] =
2773 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2774 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2775 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2776 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2778 static const WORD indices[] = {0, 1, 2, 3, 0, 2};
2779 static const D3DVERTEXELEMENT9 decl_elements[] =
2781 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2782 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2783 D3DDECL_END()
2786 IDirect3DVertexDeclaration9 *vertex_declaration;
2787 IDirect3DVertexBuffer9 *vertex_buffer;
2788 IDirect3DIndexBuffer9 *index_buffer;
2789 IDirect3DDevice9 *device;
2790 IDirect3D9 *d3d9;
2791 ULONG refcount;
2792 HWND window;
2793 HRESULT hr;
2794 void *ptr;
2796 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
2797 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2798 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2799 ok(!!d3d9, "Failed to create a D3D object.\n");
2800 if (!(device = create_device(d3d9, window, NULL)))
2802 skip("Failed to create a D3D device.\n");
2803 IDirect3D9_Release(d3d9);
2804 DestroyWindow(window);
2805 return;
2808 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2809 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
2811 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
2812 D3DPOOL_DEFAULT, &vertex_buffer, NULL);
2813 ok(SUCCEEDED(hr), "CreateVertexBuffer failed, hr %#x.\n", hr);
2814 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
2815 ok(SUCCEEDED(hr), "Lock failed, hr %#x.\n", hr);
2816 memcpy(ptr, quad, sizeof(quad));
2817 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
2818 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
2819 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
2820 ok(SUCCEEDED(hr), "SetStreamSource failed, hr %#x.\n", hr);
2822 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16,
2823 D3DPOOL_DEFAULT, &index_buffer, NULL);
2824 ok(SUCCEEDED(hr), "CreateIndexBuffer failed, hr %#x.\n", hr);
2825 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
2826 ok(SUCCEEDED(hr), "Lock failed, hr %#x.\n", hr);
2827 memcpy(ptr, indices, sizeof(indices));
2828 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
2829 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
2831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2832 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed, hr %#x.\n", hr);
2834 hr = IDirect3DDevice9_BeginScene(device);
2835 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
2837 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2838 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2840 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
2841 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2843 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 2, quad, sizeof(*quad));
2844 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2846 hr = IDirect3DDevice9_SetIndices(device, NULL);
2847 ok(SUCCEEDED(hr), "SetIndices failed, hr %#x.\n", hr);
2848 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */,
2849 0 /* MinIndex */, 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2850 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2852 /* Valid index buffer, NULL vertex declaration. Should fail */
2853 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
2854 ok(SUCCEEDED(hr), "SetIndices failed, hr %#x.\n", hr);
2855 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */,
2856 0 /* MinIndex */, 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2857 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2859 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4, 2,
2860 indices, D3DFMT_INDEX16, quad, sizeof(*quad));
2861 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2863 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2864 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
2866 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
2867 ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
2869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 2, quad, sizeof(*quad));
2870 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
2872 /* NULL index buffer, valid vertex vertex declaration. Should succeed */
2873 hr = IDirect3DDevice9_SetIndices(device, NULL);
2874 ok(SUCCEEDED(hr), "SetIndices failed, hr %#x.\n", hr);
2875 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */,
2876 0 /* MinIndex */, 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2877 todo_wine ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed, hr %#x.\n", hr);
2879 /* Valid index buffer and vertex declaration. Should succeed */
2880 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
2881 ok(SUCCEEDED(hr), "SetIndices failed, hr %#x.\n", hr);
2882 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */,
2883 0 /* MinIndex */, 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2884 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed, hr %#x.\n", hr);
2886 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4, 2,
2887 indices, D3DFMT_INDEX16, quad, sizeof(*quad));
2888 ok(SUCCEEDED(hr), "DrawIndexedPrimitiveUP failed, hr %#x.\n", hr);
2890 hr = IDirect3DDevice9_EndScene(device);
2891 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
2893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2894 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
2896 IDirect3DVertexBuffer9_Release(vertex_buffer);
2897 IDirect3DIndexBuffer9_Release(index_buffer);
2898 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2899 refcount = IDirect3DDevice9_Release(device);
2900 ok(!refcount, "Device has %u references left.\n", refcount);
2901 IDirect3D9_Release(d3d9);
2902 DestroyWindow(window);
2905 static void test_null_stream(void)
2907 IDirect3DVertexBuffer9 *buffer = NULL;
2908 IDirect3DDevice9 *device;
2909 IDirect3D9 *d3d9;
2910 ULONG refcount;
2911 HWND window;
2912 HRESULT hr;
2913 IDirect3DVertexShader9 *shader = NULL;
2914 IDirect3DVertexDeclaration9 *decl = NULL;
2915 static const DWORD shader_code[] =
2917 0xfffe0101, /* vs_1_1 */
2918 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2919 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2920 0x0000ffff /* end */
2922 static const D3DVERTEXELEMENT9 decl_elements[] = {
2923 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2924 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2925 D3DDECL_END()
2928 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2929 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2930 ok(!!window, "Failed to create a window.\n");
2931 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2932 ok(!!d3d9, "Failed to create a D3D object.\n");
2933 if (!(device = create_device(d3d9, window, NULL)))
2935 skip("Failed to create a 3D device, skipping test.\n");
2936 goto cleanup;
2939 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2940 if(FAILED(hr)) {
2941 skip("No vertex shader support\n");
2942 goto cleanup;
2944 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2945 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2946 if (FAILED(hr)) {
2947 skip("Vertex declaration handling not possible.\n");
2948 goto cleanup;
2950 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
2951 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
2952 if (FAILED(hr)) {
2953 skip("Vertex buffer handling not possible.\n");
2954 goto cleanup;
2957 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
2958 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2959 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
2960 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2961 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2962 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
2963 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2964 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
2966 hr = IDirect3DDevice9_BeginScene(device);
2967 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2968 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
2969 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2970 hr = IDirect3DDevice9_EndScene(device);
2971 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2973 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2974 IDirect3DDevice9_SetVertexShader(device, NULL);
2975 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2977 cleanup:
2978 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2979 if (decl) IDirect3DVertexDeclaration9_Release(decl);
2980 if (shader) IDirect3DVertexShader9_Release(shader);
2981 if (device)
2983 refcount = IDirect3DDevice9_Release(device);
2984 ok(!refcount, "Device has %u references left.\n", refcount);
2986 IDirect3D9_Release(d3d9);
2987 DestroyWindow(window);
2990 static void test_lights(void)
2992 IDirect3DDevice9 *device;
2993 IDirect3D9 *d3d9;
2994 ULONG refcount;
2995 HWND window;
2996 HRESULT hr;
2997 unsigned int i;
2998 BOOL enabled;
2999 D3DCAPS9 caps;
3001 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3002 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3003 ok(!!window, "Failed to create a window.\n");
3004 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3005 ok(!!d3d9, "Failed to create a D3D object.\n");
3006 if (!(device = create_device(d3d9, window, NULL)))
3008 skip("Failed to create a 3D device, skipping test.\n");
3009 goto cleanup;
3012 memset(&caps, 0, sizeof(caps));
3013 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3014 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
3016 for(i = 1; i <= caps.MaxActiveLights; i++) {
3017 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
3018 ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
3019 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
3020 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
3021 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
3024 /* TODO: Test the rendering results in this situation */
3025 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
3026 ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
3027 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
3028 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
3029 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
3030 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
3031 ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
3033 for(i = 1; i <= caps.MaxActiveLights; i++) {
3034 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
3035 ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
3038 refcount = IDirect3DDevice9_Release(device);
3039 ok(!refcount, "Device has %u references left.\n", refcount);
3040 cleanup:
3041 IDirect3D9_Release(d3d9);
3042 DestroyWindow(window);
3045 static void test_set_stream_source(void)
3047 IDirect3DVertexBuffer9 *vb;
3048 IDirect3DDevice9 *device;
3049 IDirect3D9 *d3d9;
3050 ULONG refcount;
3051 HWND window;
3052 HRESULT hr;
3054 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3055 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3056 ok(!!window, "Failed to create a window.\n");
3057 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3058 ok(!!d3d9, "Failed to create a D3D object.\n");
3059 if (!(device = create_device(d3d9, window, NULL)))
3061 skip("Failed to create a 3D device, skipping test.\n");
3062 goto cleanup;
3065 hr = IDirect3DDevice9_CreateVertexBuffer(device, 512, 0, 0, D3DPOOL_DEFAULT, &vb, NULL);
3066 ok(SUCCEEDED(hr), "Failed to create a vertex buffer, hr %#x.\n", hr);
3068 /* Some cards (GeForce 7400 at least) accept non-aligned offsets, others
3069 * (Radeon 9000 verified) reject them, so accept both results. Wine
3070 * currently rejects this to be able to optimize the vbo conversion, but
3071 * writes a WARN. */
3072 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, 32);
3073 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
3074 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 1, 32);
3075 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3076 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 2, 32);
3077 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3078 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 3, 32);
3079 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3080 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 4, 32);
3081 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
3083 /* Try to set the NULL buffer with an offset and stride 0 */
3084 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3085 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
3086 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
3087 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3088 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
3089 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3090 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
3091 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3092 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
3093 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
3095 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3096 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
3098 IDirect3DVertexBuffer9_Release(vb);
3099 refcount = IDirect3DDevice9_Release(device);
3100 ok(!refcount, "Device has %u references left.\n", refcount);
3101 cleanup:
3102 IDirect3D9_Release(d3d9);
3103 DestroyWindow(window);
3106 /* Direct3D9 offers 4 display formats: R5G6B5, X1R5G5B5, X8R8G8B8 and
3107 * A2R10G10B10. Next to these there are 6 different back buffer formats. Only
3108 * a fixed number of combinations are possible in fullscreen mode. In windowed
3109 * mode more combinations are allowed due to format conversion and this is
3110 * likely driver dependent. */
3111 static void test_display_formats(void)
3113 D3DDEVTYPE device_type = D3DDEVTYPE_HAL;
3114 unsigned int backbuffer, display;
3115 unsigned int windowed;
3116 IDirect3D9 *d3d9;
3117 BOOL should_pass;
3118 BOOL has_modes;
3119 HRESULT hr;
3121 static const struct
3123 const char *name;
3124 D3DFORMAT format;
3125 D3DFORMAT alpha_format;
3126 BOOL display;
3127 BOOL windowed;
3129 formats[] =
3131 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, 0, TRUE, TRUE},
3132 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE, TRUE},
3133 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE, FALSE},
3134 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE, TRUE},
3135 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, FALSE},
3136 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, 0, TRUE, FALSE},
3137 {"D3DFMT_UNKNOWN", D3DFMT_UNKNOWN, 0, FALSE, FALSE},
3140 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3141 ok(!!d3d9, "Failed to create a D3D object.\n");
3143 for (display = 0; display < sizeof(formats) / sizeof(*formats); ++display)
3145 has_modes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, formats[display].format);
3147 for (windowed = 0; windowed <= 1; ++windowed)
3149 for (backbuffer = 0; backbuffer < sizeof(formats) / sizeof(*formats); ++backbuffer)
3151 should_pass = FALSE;
3153 if (formats[display].display && (formats[display].windowed || !windowed) && (has_modes || windowed))
3155 D3DFORMAT backbuffer_format;
3157 if (windowed && formats[backbuffer].format == D3DFMT_UNKNOWN)
3158 backbuffer_format = formats[display].format;
3159 else
3160 backbuffer_format = formats[backbuffer].format;
3162 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, device_type, formats[display].format,
3163 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, backbuffer_format);
3164 if (hr == D3D_OK)
3166 if (windowed)
3168 hr = IDirect3D9_CheckDeviceFormatConversion(d3d9, D3DADAPTER_DEFAULT, device_type,
3169 backbuffer_format, formats[display].format);
3170 should_pass = (hr == D3D_OK);
3172 else
3173 should_pass = (formats[display].format == formats[backbuffer].format
3174 || (formats[display].alpha_format
3175 && formats[display].alpha_format == formats[backbuffer].alpha_format));
3179 hr = IDirect3D9_CheckDeviceType(d3d9, D3DADAPTER_DEFAULT, device_type,
3180 formats[display].format, formats[backbuffer].format, windowed);
3181 ok(SUCCEEDED(hr) == should_pass || broken(SUCCEEDED(hr) && !has_modes) /* Win8 64-bit */,
3182 "Got unexpected hr %#x for %s / %s, windowed %#x, should_pass %#x.\n",
3183 hr, formats[display].name, formats[backbuffer].name, windowed, should_pass);
3188 IDirect3D9_Release(d3d9);
3191 static void test_scissor_size(void)
3193 struct device_desc device_desc;
3194 IDirect3D9 *d3d9_ptr;
3195 unsigned int i;
3196 static struct {
3197 int winx; int winy; int backx; int backy; DWORD flags;
3198 } scts[] = { /* scissor tests */
3199 {800, 600, 640, 480, 0},
3200 {800, 600, 640, 480, CREATE_DEVICE_FULLSCREEN},
3201 {640, 480, 800, 600, 0},
3202 {640, 480, 800, 600, CREATE_DEVICE_FULLSCREEN},
3205 d3d9_ptr = Direct3DCreate9(D3D_SDK_VERSION);
3206 ok(!!d3d9_ptr, "Failed to create a D3D object.\n");
3208 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
3209 IDirect3DDevice9 *device_ptr = 0;
3210 HRESULT hr;
3211 HWND hwnd = 0;
3212 RECT scissorrect;
3214 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
3215 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
3217 if (scts[i].flags & CREATE_DEVICE_FULLSCREEN)
3219 scts[i].backx = registry_mode.dmPelsWidth;
3220 scts[i].backy = registry_mode.dmPelsHeight;
3223 device_desc.device_window = hwnd;
3224 device_desc.width = scts[i].backx;
3225 device_desc.height = scts[i].backy;
3226 device_desc.flags = scts[i].flags;
3227 if (!(device_ptr = create_device(d3d9_ptr, hwnd, &device_desc)))
3229 skip("Failed to create a 3D device, skipping test.\n");
3230 DestroyWindow(hwnd);
3231 goto err_out;
3234 /* Check for the default scissor rect size */
3235 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
3236 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
3237 ok(scissorrect.right == scts[i].backx && scissorrect.bottom == scts[i].backy
3238 && scissorrect.top == 0 && scissorrect.left == 0,
3239 "Scissorrect mismatch (%d, %d) should be (%d, %d)\n", scissorrect.right, scissorrect.bottom,
3240 scts[i].backx, scts[i].backy);
3242 /* check the scissorrect values after a reset */
3243 device_desc.width = registry_mode.dmPelsWidth;
3244 device_desc.height = registry_mode.dmPelsHeight;
3245 device_desc.flags = scts[i].flags;
3246 hr = reset_device(device_ptr, &device_desc);
3247 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
3248 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
3249 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
3251 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
3252 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
3253 ok(scissorrect.right == registry_mode.dmPelsWidth && scissorrect.bottom == registry_mode.dmPelsHeight
3254 && scissorrect.top == 0 && scissorrect.left == 0,
3255 "Scissorrect mismatch (%d, %d) should be (%u, %u)\n", scissorrect.right, scissorrect.bottom,
3256 registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
3258 if(device_ptr) {
3259 ULONG ref;
3261 ref = IDirect3DDevice9_Release(device_ptr);
3262 DestroyWindow(hwnd);
3263 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
3267 err_out:
3268 IDirect3D9_Release(d3d9_ptr);
3271 static void test_multi_device(void)
3273 IDirect3DDevice9 *device1, *device2;
3274 HWND window1, window2;
3275 IDirect3D9 *d3d9;
3276 ULONG refcount;
3278 window1 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3279 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3280 ok(!!window1, "Failed to create a window.\n");
3281 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3282 ok(!!d3d9, "Failed to create a D3D object.\n");
3283 if (!(device1 = create_device(d3d9, window1, NULL)))
3285 skip("Failed to create a 3D device, skipping test.\n");
3286 IDirect3D9_Release(d3d9);
3287 DestroyWindow(window1);
3288 return;
3290 IDirect3D9_Release(d3d9);
3292 window2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3293 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3294 ok(!!window2, "Failed to create a window.\n");
3295 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3296 ok(!!d3d9, "Failed to create a D3D object.\n");
3297 device2 = create_device(d3d9, window2, NULL);
3298 IDirect3D9_Release(d3d9);
3300 refcount = IDirect3DDevice9_Release(device2);
3301 ok(!refcount, "Device has %u references left.\n", refcount);
3302 refcount = IDirect3DDevice9_Release(device1);
3303 ok(!refcount, "Device has %u references left.\n", refcount);
3304 DestroyWindow(window2);
3305 DestroyWindow(window1);
3308 static HWND filter_messages;
3310 enum message_window
3312 DEVICE_WINDOW,
3313 FOCUS_WINDOW,
3316 struct message
3318 UINT message;
3319 enum message_window window;
3320 BOOL check_wparam;
3321 WPARAM expect_wparam;
3324 static const struct message *expect_messages;
3325 static HWND device_window, focus_window;
3326 static LONG windowposchanged_received, syscommand_received;
3328 struct wndproc_thread_param
3330 HWND dummy_window;
3331 HANDLE window_created;
3332 HANDLE test_finished;
3333 BOOL running_in_foreground;
3336 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3338 if (filter_messages && filter_messages == hwnd)
3340 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
3341 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
3344 if (expect_messages)
3346 HWND w;
3348 switch (expect_messages->window)
3350 case DEVICE_WINDOW:
3351 w = device_window;
3352 break;
3354 case FOCUS_WINDOW:
3355 w = focus_window;
3356 break;
3358 default:
3359 w = NULL;
3360 break;
3363 if (hwnd == w && expect_messages->message == message)
3365 if (expect_messages->check_wparam)
3366 ok(wparam == expect_messages->expect_wparam,
3367 "Got unexpected wparam %lx for message %x, expected %lx.\n",
3368 wparam, message, expect_messages->expect_wparam);
3370 ++expect_messages;
3374 /* KDE randomly does something with the hidden window during the
3375 * mode change that sometimes generates a WM_WINDOWPOSCHANGING
3376 * message. A WM_WINDOWPOSCHANGED message is not generated, so
3377 * just flag WM_WINDOWPOSCHANGED as bad. */
3378 if (message == WM_WINDOWPOSCHANGED)
3379 InterlockedIncrement(&windowposchanged_received);
3380 else if (message == WM_SYSCOMMAND)
3381 InterlockedIncrement(&syscommand_received);
3383 return DefWindowProcA(hwnd, message, wparam, lparam);
3386 static DWORD WINAPI wndproc_thread(void *param)
3388 struct wndproc_thread_param *p = param;
3389 DWORD res;
3390 BOOL ret;
3392 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3393 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
3394 registry_mode.dmPelsHeight, 0, 0, 0, 0);
3395 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
3397 ret = SetEvent(p->window_created);
3398 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
3400 for (;;)
3402 MSG msg;
3404 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
3405 res = WaitForSingleObject(p->test_finished, 100);
3406 if (res == WAIT_OBJECT_0) break;
3407 if (res != WAIT_TIMEOUT)
3409 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3410 break;
3414 DestroyWindow(p->dummy_window);
3416 return 0;
3419 static void test_wndproc(void)
3421 struct wndproc_thread_param thread_params;
3422 struct device_desc device_desc;
3423 IDirect3DDevice9 *device;
3424 WNDCLASSA wc = {0};
3425 IDirect3D9 *d3d9;
3426 HANDLE thread;
3427 LONG_PTR proc;
3428 ULONG ref;
3429 DWORD res, tid;
3430 HWND tmp;
3431 UINT i, adapter_mode_count;
3432 HRESULT hr;
3433 D3DDISPLAYMODE d3ddm;
3434 DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
3435 DEVMODEW devmode;
3436 LONG change_ret;
3437 BOOL ret;
3439 static const struct message create_messages[] =
3441 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
3442 /* Do not test wparam here. If device creation succeeds,
3443 * wparam is WA_ACTIVE. If device creation fails (testbot)
3444 * wparam is set to WA_INACTIVE on some Windows versions. */
3445 {WM_ACTIVATE, FOCUS_WINDOW, FALSE, 0},
3446 {WM_SETFOCUS, FOCUS_WINDOW, FALSE, 0},
3447 {0, 0, FALSE, 0},
3449 static const struct message focus_loss_messages[] =
3451 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
3452 * not reliable on X11 WMs. When the window focus follows the
3453 * mouse pointer the message is not sent.
3454 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
3455 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
3456 /* WM_DISPLAYCHANGE is sent to the focus window too, but the order is
3457 * not deterministic. */
3458 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
3459 /* Windows sends WM_ACTIVATE to the device window, indicating that
3460 * SW_SHOWMINIMIZED is used instead of SW_MINIMIZE. Yet afterwards
3461 * the foreground and focus window are NULL. On Wine SW_SHOWMINIMIZED
3462 * leaves the device window active, breaking re-activation in the
3463 * lost device test.
3464 * {WM_ACTIVATE, DEVICE_WINDOW, TRUE, 0x200000 | WA_ACTIVE}, */
3465 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
3466 {WM_SIZE, DEVICE_WINDOW, TRUE, SIZE_MINIMIZED},
3467 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
3468 /* WM_ACTIVATEAPP is sent to the device window too, but the order is
3469 * not deterministic. It may be sent after the focus window handling
3470 * or before. */
3471 {0, 0, FALSE, 0},
3473 static const struct message focus_loss_messages_nowc[] =
3475 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
3476 * not reliable on X11 WMs. When the window focus follows the
3477 * mouse pointer the message is not sent.
3478 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
3479 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
3480 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
3481 {0, 0, FALSE, 0},
3483 static const struct message reactivate_messages[] =
3485 {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
3486 {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
3487 /* optional WM_MOVE here if size changed */
3488 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, TRUE},
3489 {0, 0, FALSE, 0},
3491 static const struct message reactivate_messages_nowc[] =
3493 /* We're activating the device window before activating the
3494 * focus window, so no ACTIVATEAPP message is sent. */
3495 {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_ACTIVE},
3496 {0, 0, FALSE, 0},
3498 static const struct message focus_loss_messages_hidden[] =
3500 {WM_DISPLAYCHANGE, DEVICE_WINDOW, FALSE, 0},
3501 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
3502 {0, 0, FALSE, 0},
3504 static const struct message focus_loss_messages_filtered[] =
3506 /* WM_ACTIVATE is delivered to the window proc because it is
3507 * generated by SetForegroundWindow before the d3d routine
3508 * starts it work. Don't check for it due to focus-follows-mouse
3509 * WMs though. */
3510 {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
3511 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
3512 {0, 0, FALSE, 0},
3514 static const struct message reactivate_messages_filtered[] =
3516 {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, TRUE},
3517 {0, 0, FALSE, 0},
3519 static const struct message sc_restore_messages[] =
3521 /* WM_SYSCOMMAND is delivered only once, after d3d has already
3522 * processed it. Our wndproc has no way to prevent d3d from
3523 * handling the message. The second DefWindowProc call done by
3524 * our wndproc doesn't do any changes to the window because it
3525 * is already restored due to d3d's handling. */
3526 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
3527 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
3528 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_RESTORED},
3529 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_RESTORE},
3530 {0, 0, FALSE, 0},
3532 static const struct message sc_minimize_messages[] =
3534 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MINIMIZE},
3535 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
3536 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
3537 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
3538 {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_MINIMIZED},
3539 {0, 0, FALSE, 0},
3541 static const struct message sc_maximize_messages[] =
3543 {WM_SYSCOMMAND, FOCUS_WINDOW, TRUE, SC_MAXIMIZE},
3544 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW, FALSE, 0},
3545 {WM_WINDOWPOSCHANGED, FOCUS_WINDOW, FALSE, 0},
3546 {WM_MOVE, FOCUS_WINDOW, FALSE, 0},
3547 /* WM_SIZE(SIZE_MAXIMIZED) is unreliable on native. */
3548 {0, 0, FALSE, 0},
3550 static const struct
3552 DWORD create_flags;
3553 const struct message *focus_loss_messages, *reactivate_messages;
3554 BOOL iconic;
3556 tests[] =
3558 {0, focus_loss_messages, reactivate_messages, TRUE},
3559 {CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc, reactivate_messages_nowc, FALSE},
3562 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3563 ok(!!d3d9, "Failed to create a D3D object.\n");
3565 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
3566 for (i = 0; i < adapter_mode_count; ++i)
3568 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3ddm);
3569 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
3571 if (d3ddm.Width == registry_mode.dmPelsWidth && d3ddm.Height == registry_mode.dmPelsHeight)
3572 continue;
3573 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
3574 * refuses to create a device at these sizes. */
3575 if (d3ddm.Width < 640 || d3ddm.Height < 480)
3576 continue;
3578 if (!user32_width)
3580 user32_width = d3ddm.Width;
3581 user32_height = d3ddm.Height;
3582 continue;
3585 /* Make sure the d3d mode is smaller in width or height and at most
3586 * equal in the other dimension than the mode passed to
3587 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
3588 * the ChangeDisplaySettings parameters + 12. */
3589 if (d3ddm.Width == user32_width && d3ddm.Height == user32_height)
3590 continue;
3591 if (d3ddm.Width <= user32_width && d3ddm.Height <= user32_height)
3593 d3d_width = d3ddm.Width;
3594 d3d_height = d3ddm.Height;
3595 break;
3597 if (user32_width <= d3ddm.Width && user32_height <= d3ddm.Height)
3599 d3d_width = user32_width;
3600 d3d_height = user32_height;
3601 user32_width = d3ddm.Width;
3602 user32_height = d3ddm.Height;
3603 break;
3607 if (!d3d_width)
3609 skip("Could not find adequate modes, skipping mode tests.\n");
3610 IDirect3D9_Release(d3d9);
3611 return;
3614 wc.lpfnWndProc = test_proc;
3615 wc.lpszClassName = "d3d9_test_wndproc_wc";
3616 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3618 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3619 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3620 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3621 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3623 memset(&devmode, 0, sizeof(devmode));
3624 devmode.dmSize = sizeof(devmode);
3625 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
3627 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3628 devmode.dmPelsWidth = user32_width;
3629 devmode.dmPelsHeight = user32_height;
3630 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3631 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
3633 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3634 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
3635 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3636 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
3637 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3638 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3640 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3641 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3643 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3644 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3645 (LONG_PTR)test_proc, proc);
3646 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3647 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3648 (LONG_PTR)test_proc, proc);
3650 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3651 device_window, focus_window, thread_params.dummy_window);
3653 tmp = GetFocus();
3654 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3655 if (thread_params.running_in_foreground)
3657 tmp = GetForegroundWindow();
3658 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3659 thread_params.dummy_window, tmp);
3661 else
3662 skip("Not running in foreground, skip foreground window test\n");
3664 flush_events();
3666 expect_messages = create_messages;
3668 device_desc.device_window = device_window;
3669 device_desc.width = d3d_width;
3670 device_desc.height = d3d_height;
3671 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].create_flags;
3672 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3674 skip("Failed to create a D3D device, skipping tests.\n");
3675 goto done;
3678 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3679 expect_messages->message, expect_messages->window, i);
3680 expect_messages = NULL;
3682 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
3684 tmp = GetFocus();
3685 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
3686 tmp = GetForegroundWindow();
3687 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
3689 SetForegroundWindow(focus_window);
3690 flush_events();
3692 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3693 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
3694 (LONG_PTR)test_proc, proc, i);
3696 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3697 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, i=%u.\n",
3698 (LONG_PTR)test_proc, i);
3700 /* Change the mode while the device is in use and then drop focus. */
3701 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3702 devmode.dmPelsWidth = user32_width;
3703 devmode.dmPelsHeight = user32_height;
3704 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3705 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x, i=%u.\n", change_ret, i);
3707 /* Wine doesn't (yet) mark the device not reset when the mode is changed, thus the todo_wine.
3708 * But sometimes focus-follows-mouse WMs also temporarily drop window focus, which makes
3709 * mark the device lost, then not reset, causing the test to succeed for the wrong reason. */
3710 hr = IDirect3DDevice9_TestCooperativeLevel(device);
3711 todo_wine_if (hr != D3DERR_DEVICENOTRESET)
3712 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
3714 expect_messages = tests[i].focus_loss_messages;
3715 /* SetForegroundWindow is a poor replacement for the user pressing alt-tab or
3716 * manually changing the focus. It generates the same messages, but the task
3717 * bar still shows the previous foreground window as active, and the window has
3718 * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating
3719 * the device is difficult, see below. */
3720 SetForegroundWindow(GetDesktopWindow());
3721 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3722 expect_messages->message, expect_messages->window, i);
3723 expect_messages = NULL;
3724 tmp = GetFocus();
3725 ok(tmp != device_window, "The device window is active, i=%u.\n", i);
3726 ok(tmp != focus_window, "The focus window is active, i=%u.\n", i);
3728 hr = IDirect3DDevice9_TestCooperativeLevel(device);
3729 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
3731 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3732 ok(ret, "Failed to get display mode.\n");
3733 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
3734 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n",
3735 devmode.dmPelsWidth, devmode.dmPelsHeight);
3737 /* This is needed on native with D3DCREATE_NOWINDOWCHANGES, and it needs to be
3738 * done before the focus window is restored. This makes sense to some extent
3739 * because minimizing the window on focus loss is the application's job if this
3740 * flag is set. */
3741 if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3743 ShowWindow(device_window, SW_MINIMIZE);
3744 ShowWindow(device_window, SW_RESTORE);
3746 flush_events();
3748 /* I have to minimize and restore the focus window, otherwise native d3d9 fails
3749 * device::reset with D3DERR_DEVICELOST. This does not happen when the window
3750 * restore is triggered by the user. */
3751 expect_messages = tests[i].reactivate_messages;
3752 ShowWindow(focus_window, SW_MINIMIZE);
3753 ShowWindow(focus_window, SW_RESTORE);
3754 /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
3755 SetForegroundWindow(focus_window);
3756 flush_events();
3757 SetForegroundWindow(focus_window);
3758 flush_events(); /* WM_WINDOWPOSCHANGING etc arrive after SetForegroundWindow returns. */
3759 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3760 expect_messages->message, expect_messages->window, i);
3761 expect_messages = NULL;
3763 hr = IDirect3DDevice9_TestCooperativeLevel(device);
3764 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
3766 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3767 ok(ret, "Failed to get display mode.\n");
3768 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
3769 && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n",
3770 devmode.dmPelsWidth, devmode.dmPelsHeight);
3772 hr = reset_device(device, &device_desc);
3773 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3775 ShowWindow(device_window, SW_HIDE);
3776 flush_events();
3778 expect_messages = focus_loss_messages_hidden;
3779 windowposchanged_received = 0;
3780 SetForegroundWindow(GetDesktopWindow());
3781 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3782 expect_messages->message, expect_messages->window, i);
3783 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it.\n");
3784 expect_messages = NULL;
3785 flush_events();
3787 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3788 ok(ret, "Failed to get display mode.\n");
3789 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3790 ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3792 /* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
3793 * send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
3794 ShowWindow(focus_window, SW_SHOWNOACTIVATE);
3795 ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
3796 flush_events();
3798 syscommand_received = 0;
3799 expect_messages = sc_restore_messages;
3800 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
3801 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3802 expect_messages->message, expect_messages->window, i);
3803 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
3804 expect_messages = NULL;
3805 flush_events();
3807 expect_messages = sc_minimize_messages;
3808 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
3809 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3810 expect_messages->message, expect_messages->window, i);
3811 expect_messages = NULL;
3812 flush_events();
3814 expect_messages = sc_maximize_messages;
3815 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
3816 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3817 expect_messages->message, expect_messages->window, i);
3818 expect_messages = NULL;
3819 flush_events();
3821 SetForegroundWindow(GetDesktopWindow());
3822 ShowWindow(device_window, SW_MINIMIZE);
3823 ShowWindow(device_window, SW_RESTORE);
3824 ShowWindow(focus_window, SW_MINIMIZE);
3825 ShowWindow(focus_window, SW_RESTORE);
3826 SetForegroundWindow(focus_window);
3827 flush_events();
3829 /* Releasing a device in lost state breaks follow-up tests on native. */
3830 hr = reset_device(device, &device_desc);
3831 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x, i=%u.\n", hr, i);
3833 filter_messages = focus_window;
3835 ref = IDirect3DDevice9_Release(device);
3836 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3838 /* Fix up the mode until Wine's device release behavior is fixed. */
3839 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
3840 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
3842 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3843 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
3844 (LONG_PTR)test_proc, proc, i);
3846 /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
3847 * on native in the test below. It isn't needed anyways. Creating the third
3848 * device will show it again. */
3849 filter_messages = NULL;
3850 ShowWindow(device_window, SW_HIDE);
3851 /* Remove the maximized state from the SYSCOMMAND test while we're not
3852 * interfering with a device. */
3853 ShowWindow(focus_window, SW_SHOWNORMAL);
3854 filter_messages = focus_window;
3856 device_desc.device_window = focus_window;
3857 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3859 skip("Failed to create a D3D device, skipping tests.\n");
3860 goto done;
3862 filter_messages = NULL;
3863 SetForegroundWindow(focus_window); /* For KDE. */
3864 flush_events();
3866 expect_messages = focus_loss_messages_filtered;
3867 windowposchanged_received = 0;
3868 SetForegroundWindow(GetDesktopWindow());
3869 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3870 expect_messages->message, expect_messages->window, i);
3871 ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
3872 expect_messages = NULL;
3874 /* The window is iconic even though no message was sent. */
3875 ok(!IsIconic(focus_window) == !tests[i].iconic,
3876 "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
3878 hr = IDirect3DDevice9_TestCooperativeLevel(device);
3879 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
3881 if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
3882 ShowWindow(focus_window, SW_MINIMIZE);
3884 syscommand_received = 0;
3885 expect_messages = sc_restore_messages;
3886 SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
3887 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3888 expect_messages->message, expect_messages->window, i);
3889 ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
3890 expect_messages = NULL;
3891 flush_events();
3893 /* For FVWM. */
3894 ShowWindow(focus_window, SW_RESTORE);
3895 flush_events();
3897 expect_messages = sc_minimize_messages;
3898 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MINIMIZE, 0);
3899 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3900 expect_messages->message, expect_messages->window, i);
3901 expect_messages = NULL;
3902 flush_events();
3904 expect_messages = sc_maximize_messages;
3905 SendMessageA(focus_window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
3906 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3907 expect_messages->message, expect_messages->window, i);
3908 expect_messages = NULL;
3909 flush_events();
3911 /* Make sure the SetWindowPos call done by d3d9 is not a no-op. */
3912 SetWindowPos(focus_window, NULL, 10, 10, 100, 100, SWP_NOZORDER | SWP_NOACTIVATE);
3913 SetForegroundWindow(GetDesktopWindow());
3914 flush_events();
3915 SetForegroundWindow(GetDesktopWindow()); /* For FVWM. */
3916 flush_events();
3918 expect_messages = reactivate_messages_filtered;
3919 windowposchanged_received = 0;
3920 SetForegroundWindow(focus_window);
3921 flush_events();
3922 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3923 expect_messages->message, expect_messages->window, i);
3924 /* About 1 in 8 test runs receives WM_WINDOWPOSCHANGED on Vista. */
3925 ok(!windowposchanged_received || broken(1),
3926 "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
3927 expect_messages = NULL;
3929 filter_messages = focus_window;
3930 hr = IDirect3DDevice9_TestCooperativeLevel(device);
3931 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
3933 hr = reset_device(device, &device_desc);
3934 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3936 ref = IDirect3DDevice9_Release(device);
3937 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3939 device_desc.device_window = device_window;
3940 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3942 skip("Failed to create a D3D device, skipping tests.\n");
3943 goto done;
3946 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3947 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, i=%u.\n",
3948 (LONG_PTR)test_proc, i);
3950 ref = IDirect3DDevice9_Release(device);
3951 ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
3953 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3954 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx, i=%u.\n",
3955 (LONG_PTR)DefWindowProcA, proc, i);
3957 done:
3958 filter_messages = NULL;
3959 DestroyWindow(device_window);
3960 DestroyWindow(focus_window);
3961 SetEvent(thread_params.test_finished);
3962 WaitForSingleObject(thread, INFINITE);
3963 CloseHandle(thread);
3966 IDirect3D9_Release(d3d9);
3967 CloseHandle(thread_params.test_finished);
3968 CloseHandle(thread_params.window_created);
3969 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3972 static void test_wndproc_windowed(void)
3974 struct wndproc_thread_param thread_params;
3975 struct device_desc device_desc;
3976 IDirect3DDevice9 *device;
3977 WNDCLASSA wc = {0};
3978 IDirect3D9 *d3d9;
3979 HANDLE thread;
3980 LONG_PTR proc;
3981 HRESULT hr;
3982 ULONG ref;
3983 DWORD res, tid;
3984 HWND tmp;
3986 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3987 ok(!!d3d9, "Failed to create a D3D object.\n");
3989 wc.lpfnWndProc = test_proc;
3990 wc.lpszClassName = "d3d9_test_wndproc_wc";
3991 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3993 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3994 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3995 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3996 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3998 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3999 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
4000 registry_mode.dmPelsHeight, 0, 0, 0, 0);
4001 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
4002 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
4003 registry_mode.dmPelsHeight, 0, 0, 0, 0);
4004 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
4005 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
4007 res = WaitForSingleObject(thread_params.window_created, INFINITE);
4008 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
4010 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4011 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4012 (LONG_PTR)test_proc, proc);
4013 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4014 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4015 (LONG_PTR)test_proc, proc);
4017 trace("device_window %p, focus_window %p, dummy_window %p.\n",
4018 device_window, focus_window, thread_params.dummy_window);
4020 tmp = GetFocus();
4021 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
4022 if (thread_params.running_in_foreground)
4024 tmp = GetForegroundWindow();
4025 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
4026 thread_params.dummy_window, tmp);
4028 else
4029 skip("Not running in foreground, skip foreground window test\n");
4031 filter_messages = focus_window;
4033 device_desc.device_window = device_window;
4034 device_desc.width = 640;
4035 device_desc.height = 480;
4036 device_desc.flags = 0;
4037 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4039 skip("Failed to create a D3D device, skipping tests.\n");
4040 goto done;
4043 tmp = GetFocus();
4044 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
4045 tmp = GetForegroundWindow();
4046 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
4047 thread_params.dummy_window, tmp);
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);
4053 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4054 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4055 (LONG_PTR)test_proc, proc);
4057 filter_messages = NULL;
4059 device_desc.width = registry_mode.dmPelsWidth;
4060 device_desc.height = registry_mode.dmPelsHeight;
4061 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4062 hr = reset_device(device, &device_desc);
4063 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4065 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4066 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4067 (LONG_PTR)test_proc, proc);
4069 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4070 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
4072 device_desc.flags = 0;
4073 hr = reset_device(device, &device_desc);
4074 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4076 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4077 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4078 (LONG_PTR)test_proc, proc);
4080 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4081 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4082 (LONG_PTR)test_proc, proc);
4084 filter_messages = focus_window;
4086 ref = IDirect3DDevice9_Release(device);
4087 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4089 filter_messages = device_window;
4091 device_desc.device_window = focus_window;
4092 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4094 skip("Failed to create a D3D device, skipping tests.\n");
4095 goto done;
4098 filter_messages = NULL;
4100 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4101 hr = reset_device(device, &device_desc);
4102 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4104 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4105 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4106 (LONG_PTR)test_proc, proc);
4108 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4109 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
4111 device_desc.flags = 0;
4112 hr = reset_device(device, &device_desc);
4113 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4115 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4116 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4117 (LONG_PTR)test_proc, proc);
4119 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4120 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4121 (LONG_PTR)test_proc, proc);
4123 filter_messages = device_window;
4125 ref = IDirect3DDevice9_Release(device);
4126 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4128 device_desc.device_window = device_window;
4129 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4131 skip("Failed to create a D3D device, skipping tests.\n");
4132 goto done;
4135 filter_messages = NULL;
4137 device_desc.device_window = device_window;
4138 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4139 hr = reset_device(device, &device_desc);
4140 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4142 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4143 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4144 (LONG_PTR)test_proc, proc);
4146 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4147 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
4149 device_desc.flags = 0;
4150 hr = reset_device(device, &device_desc);
4151 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4153 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4154 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4155 (LONG_PTR)test_proc, proc);
4157 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4158 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4159 (LONG_PTR)test_proc, proc);
4161 filter_messages = device_window;
4163 ref = IDirect3DDevice9_Release(device);
4164 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4166 done:
4167 filter_messages = NULL;
4168 IDirect3D9_Release(d3d9);
4170 SetEvent(thread_params.test_finished);
4171 WaitForSingleObject(thread, INFINITE);
4172 CloseHandle(thread_params.test_finished);
4173 CloseHandle(thread_params.window_created);
4174 CloseHandle(thread);
4176 DestroyWindow(device_window);
4177 DestroyWindow(focus_window);
4178 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
4181 static void test_reset_fullscreen(void)
4183 WNDCLASSEXA wc = {0};
4184 IDirect3DDevice9 *device = NULL;
4185 IDirect3D9 *d3d;
4186 ATOM atom;
4187 struct device_desc device_desc;
4188 static const struct message messages[] =
4190 /* Windows usually sends wparam = TRUE, except on the testbot,
4191 * where it randomly sends FALSE. Ignore it. */
4192 {WM_ACTIVATEAPP, FOCUS_WINDOW, FALSE, 0},
4193 {0, 0, FALSE, 0},
4196 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4197 ok(!!d3d, "Failed to create a D3D object.\n");
4198 expect_messages = messages;
4200 wc.cbSize = sizeof(wc);
4201 wc.lpfnWndProc = test_proc;
4202 wc.lpszClassName = "test_reset_fullscreen";
4204 atom = RegisterClassExA(&wc);
4205 ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
4207 device_window = focus_window = CreateWindowExA(0, wc.lpszClassName, "Test Reset Fullscreen", 0,
4208 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight, NULL, NULL, NULL, NULL);
4209 ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
4212 * Create a device in windowed mode.
4213 * Since the device is windowed and we haven't called any methods that
4214 * could show the window (such as ShowWindow or SetWindowPos) yet,
4215 * WM_ACTIVATEAPP will not have been sent.
4217 if (!(device = create_device(d3d, device_window, NULL)))
4219 skip("Unable to create device. Skipping test.\n");
4220 goto cleanup;
4224 * Switch to fullscreen mode.
4225 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
4226 * message to be sent.
4228 device_desc.width = registry_mode.dmPelsWidth;
4229 device_desc.height = registry_mode.dmPelsHeight;
4230 device_desc.device_window = device_window;
4231 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4232 ok(SUCCEEDED(reset_device(device, &device_desc)), "Failed to reset device.\n");
4234 flush_events();
4235 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
4236 expect_messages = NULL;
4238 cleanup:
4239 if (device) IDirect3DDevice9_Release(device);
4240 IDirect3D9_Release(d3d);
4241 DestroyWindow(device_window);
4242 device_window = focus_window = NULL;
4243 UnregisterClassA(wc.lpszClassName, GetModuleHandleA(NULL));
4247 static inline void set_fpu_cw(WORD cw)
4249 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
4250 #define D3D9_TEST_SET_FPU_CW 1
4251 __asm__ volatile ("fnclex");
4252 __asm__ volatile ("fldcw %0" : : "m" (cw));
4253 #elif defined(__i386__) && defined(_MSC_VER)
4254 #define D3D9_TEST_SET_FPU_CW 1
4255 __asm fnclex;
4256 __asm fldcw cw;
4257 #endif
4260 static inline WORD get_fpu_cw(void)
4262 WORD cw = 0;
4263 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
4264 #define D3D9_TEST_GET_FPU_CW 1
4265 __asm__ volatile ("fnstcw %0" : "=m" (cw));
4266 #elif defined(__i386__) && defined(_MSC_VER)
4267 #define D3D9_TEST_GET_FPU_CW 1
4268 __asm fnstcw cw;
4269 #endif
4270 return cw;
4273 static WORD callback_cw, callback_set_cw;
4274 static DWORD callback_tid;
4276 static HRESULT WINAPI dummy_object_QueryInterface(IUnknown *iface, REFIID riid, void **out)
4278 *out = NULL;
4279 return E_NOINTERFACE;
4282 static ULONG WINAPI dummy_object_AddRef(IUnknown *iface)
4284 callback_cw = get_fpu_cw();
4285 set_fpu_cw(callback_set_cw);
4286 callback_tid = GetCurrentThreadId();
4287 return 2;
4290 static ULONG WINAPI dummy_object_Release(IUnknown *iface)
4292 callback_cw = get_fpu_cw();
4293 set_fpu_cw(callback_set_cw);
4294 callback_tid = GetCurrentThreadId();
4295 return 1;
4298 static const IUnknownVtbl dummy_object_vtbl =
4300 dummy_object_QueryInterface,
4301 dummy_object_AddRef,
4302 dummy_object_Release,
4305 static const GUID d3d9_private_data_test_guid =
4307 0xfdb37466,
4308 0x428f,
4309 0x4edf,
4310 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
4313 static void test_fpu_setup(void)
4315 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
4316 struct device_desc device_desc;
4317 IDirect3DDevice9 *device;
4318 HWND window = NULL;
4319 IDirect3D9 *d3d9;
4320 WORD cw;
4321 IDirect3DSurface9 *surface;
4322 HRESULT hr;
4323 IUnknown dummy_object = {&dummy_object_vtbl};
4325 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0,
4326 registry_mode.dmPelsWidth, registry_mode.dmPelsHeight, 0, 0, 0, 0);
4327 ok(!!window, "Failed to create a window.\n");
4328 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4329 ok(!!d3d9, "Failed to create a D3D object.\n");
4331 device_desc.device_window = window;
4332 device_desc.width = 640;
4333 device_desc.height = 480;
4334 device_desc.flags = 0;
4336 set_fpu_cw(0xf60);
4337 cw = get_fpu_cw();
4338 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
4340 if (!(device = create_device(d3d9, window, &device_desc)))
4342 skip("Failed to create a 3D device, skipping test.\n");
4343 set_fpu_cw(0x37f);
4344 goto done;
4347 cw = get_fpu_cw();
4348 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
4350 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
4351 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4353 callback_set_cw = 0xf60;
4354 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
4355 &dummy_object, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
4356 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
4357 ok(callback_cw == 0x7f, "Callback cw is %#x, expected 0x7f.\n", callback_cw);
4358 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
4359 cw = get_fpu_cw();
4360 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
4362 callback_cw = 0;
4363 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
4364 &dummy_object, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
4365 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
4366 ok(callback_cw == 0xf60, "Callback cw is %#x, expected 0xf60.\n", callback_cw);
4367 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
4369 callback_set_cw = 0x7f;
4370 set_fpu_cw(0x7f);
4372 IDirect3DSurface9_Release(surface);
4374 callback_cw = 0;
4375 IDirect3DDevice9_Release(device);
4376 ok(callback_cw == 0x7f, "Callback cw is %#x, expected 0x7f.\n", callback_cw);
4377 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
4379 cw = get_fpu_cw();
4380 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
4381 set_fpu_cw(0xf60);
4382 cw = get_fpu_cw();
4383 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
4385 device_desc.flags = CREATE_DEVICE_FPU_PRESERVE;
4386 device = create_device(d3d9, window, &device_desc);
4387 ok(device != NULL, "CreateDevice failed.\n");
4389 cw = get_fpu_cw();
4390 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
4392 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
4393 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4395 callback_cw = 0;
4396 callback_set_cw = 0x37f;
4397 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
4398 &dummy_object, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
4399 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
4400 ok(callback_cw == 0xf60, "Callback cw is %#x, expected 0xf60.\n", callback_cw);
4401 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
4402 cw = get_fpu_cw();
4403 ok(cw == 0x37f, "cw is %#x, expected 0x37f.\n", cw);
4405 IDirect3DSurface9_Release(surface);
4407 callback_cw = 0;
4408 IDirect3DDevice9_Release(device);
4409 ok(callback_cw == 0x37f, "Callback cw is %#x, expected 0xf60.\n", callback_cw);
4410 ok(callback_tid == GetCurrentThreadId(), "Got unexpected thread id.\n");
4412 done:
4413 IDirect3D9_Release(d3d9);
4414 DestroyWindow(window);
4415 #endif
4418 static void test_window_style(void)
4420 RECT focus_rect, device_rect, fullscreen_rect, r, r2;
4421 LONG device_style, device_exstyle;
4422 LONG focus_style, focus_exstyle;
4423 struct device_desc device_desc;
4424 LONG style, expected_style;
4425 IDirect3DDevice9 *device;
4426 IDirect3D9 *d3d9;
4427 HRESULT hr;
4428 ULONG ref;
4429 BOOL ret;
4430 static const struct
4432 DWORD device_flags;
4433 LONG style, focus_loss_style, exstyle;
4435 tests[] =
4437 {0, WS_VISIBLE, WS_MINIMIZE, WS_EX_TOPMOST},
4438 {CREATE_DEVICE_NOWINDOWCHANGES, 0, 0, 0},
4440 unsigned int i;
4442 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4443 ok(!!d3d9, "Failed to create a D3D object.\n");
4444 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
4446 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
4448 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4449 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
4450 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4451 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
4453 device_style = GetWindowLongA(device_window, GWL_STYLE);
4454 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
4455 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
4456 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
4458 GetWindowRect(focus_window, &focus_rect);
4459 GetWindowRect(device_window, &device_rect);
4461 device_desc.device_window = device_window;
4462 device_desc.width = registry_mode.dmPelsWidth;
4463 device_desc.height = registry_mode.dmPelsHeight;
4464 device_desc.flags = CREATE_DEVICE_FULLSCREEN | tests[i].device_flags;
4465 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4467 skip("Failed to create a D3D device, skipping tests.\n");
4468 DestroyWindow(device_window);
4469 DestroyWindow(focus_window);
4470 break;
4473 style = GetWindowLongA(device_window, GWL_STYLE);
4474 expected_style = device_style | tests[i].style;
4475 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
4476 expected_style, style, i);
4477 style = GetWindowLongA(device_window, GWL_EXSTYLE);
4478 expected_style = device_exstyle | tests[i].exstyle;
4479 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
4480 expected_style, style, i);
4482 style = GetWindowLongA(focus_window, GWL_STYLE);
4483 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
4484 focus_style, style, i);
4485 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
4486 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
4487 focus_exstyle, style, i);
4489 GetWindowRect(device_window, &r);
4490 if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
4491 todo_wine ok(EqualRect(&r, &device_rect), "Expected %s, got %s, i=%u.\n",
4492 wine_dbgstr_rect(&device_rect), wine_dbgstr_rect(&r), i);
4493 else
4494 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s, i=%u.\n",
4495 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r), i);
4496 GetClientRect(device_window, &r2);
4497 todo_wine ok(!EqualRect(&r, &r2), "Client rect and window rect are equal.\n");
4498 GetWindowRect(focus_window, &r);
4499 ok(EqualRect(&r, &focus_rect), "Expected %s, got %s, i=%u.\n",
4500 wine_dbgstr_rect(&focus_rect), wine_dbgstr_rect(&r), i);
4502 device_desc.flags = 0;
4503 hr = reset_device(device, &device_desc);
4504 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4506 style = GetWindowLongA(device_window, GWL_STYLE);
4507 expected_style = device_style | tests[i].style;
4508 todo_wine_if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
4509 ok(style == expected_style, "Expected device window style %#x, got %#x, i=%u.\n",
4510 expected_style, style, i);
4511 style = GetWindowLongA(device_window, GWL_EXSTYLE);
4512 expected_style = device_exstyle | tests[i].exstyle;
4513 todo_wine_if (tests[i].device_flags & CREATE_DEVICE_NOWINDOWCHANGES)
4514 ok(style == expected_style, "Expected device window extended style %#x, got %#x, i=%u.\n",
4515 expected_style, style, i);
4517 style = GetWindowLongA(focus_window, GWL_STYLE);
4518 ok(style == focus_style, "Expected focus window style %#x, got %#x, i=%u.\n",
4519 focus_style, style, i);
4520 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
4521 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x, i=%u.\n",
4522 focus_exstyle, style, i);
4524 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4525 hr = reset_device(device, &device_desc);
4526 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4527 ret = SetForegroundWindow(GetDesktopWindow());
4528 ok(ret, "Failed to set foreground window.\n");
4530 style = GetWindowLongA(device_window, GWL_STYLE);
4531 expected_style = device_style | tests[i].focus_loss_style | tests[i].style;
4532 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
4533 expected_style, style);
4534 style = GetWindowLongA(device_window, GWL_EXSTYLE);
4535 expected_style = device_exstyle | tests[i].exstyle;
4536 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
4537 expected_style, style);
4539 style = GetWindowLongA(focus_window, GWL_STYLE);
4540 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
4541 focus_style, style);
4542 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
4543 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
4544 focus_exstyle, style);
4546 /* In d3d8 follow-up tests fail on native if the device is destroyed while
4547 * lost. This doesn't happen in d3d9 on my test machine but it still seems
4548 * like a good idea to reset it first. */
4549 ShowWindow(focus_window, SW_MINIMIZE);
4550 ShowWindow(focus_window, SW_RESTORE);
4551 ret = SetForegroundWindow(focus_window);
4552 ok(ret, "Failed to set foreground window.\n");
4553 flush_events();
4554 hr = reset_device(device, &device_desc);
4555 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
4557 ref = IDirect3DDevice9_Release(device);
4558 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4560 DestroyWindow(device_window);
4561 DestroyWindow(focus_window);
4563 IDirect3D9_Release(d3d9);
4566 static const POINT *expect_pos;
4568 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
4570 if (message == WM_MOUSEMOVE)
4572 if (expect_pos && expect_pos->x && expect_pos->y)
4574 POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
4576 ClientToScreen(window, &p);
4577 if (expect_pos->x == p.x && expect_pos->y == p.y)
4578 ++expect_pos;
4582 return DefWindowProcA(window, message, wparam, lparam);
4585 static void test_cursor_pos(void)
4587 IDirect3DSurface9 *cursor;
4588 IDirect3DDevice9 *device;
4589 WNDCLASSA wc = {0};
4590 IDirect3D9 *d3d9;
4591 UINT refcount;
4592 HWND window;
4593 HRESULT hr;
4594 BOOL ret;
4596 /* Note that we don't check for movement we're not supposed to receive.
4597 * That's because it's hard to distinguish from the user accidentally
4598 * moving the mouse. */
4599 static const POINT points[] =
4601 {50, 50},
4602 {75, 75},
4603 {100, 100},
4604 {125, 125},
4605 {150, 150},
4606 {125, 125},
4607 {150, 150},
4608 {150, 150},
4609 {0, 0},
4612 wc.lpfnWndProc = test_cursor_proc;
4613 wc.lpszClassName = "d3d9_test_cursor_wc";
4614 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4615 window = CreateWindowA("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4616 0, 0, 320, 240, NULL, NULL, NULL, NULL);
4617 ShowWindow(window, SW_SHOW);
4618 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4619 ok(!!d3d9, "Failed to create a D3D object.\n");
4621 device = create_device(d3d9, window, NULL);
4622 if (!device)
4624 skip("Failed to create a D3D device, skipping tests.\n");
4625 goto done;
4628 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
4629 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
4630 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
4631 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
4632 ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#x.\n", hr);
4633 IDirect3DSurface9_Release(cursor);
4634 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
4635 ok(!ret, "Failed to show cursor, hr %#x.\n", ret);
4637 flush_events();
4638 expect_pos = points;
4640 ret = SetCursorPos(50, 50);
4641 ok(ret, "Failed to set cursor position.\n");
4642 flush_events();
4644 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
4645 flush_events();
4646 /* SetCursorPosition() eats duplicates. */
4647 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
4648 flush_events();
4650 ret = SetCursorPos(100, 100);
4651 ok(ret, "Failed to set cursor position.\n");
4652 flush_events();
4653 /* Even if the position was set with SetCursorPos(). */
4654 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
4655 flush_events();
4657 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
4658 flush_events();
4659 ret = SetCursorPos(150, 150);
4660 ok(ret, "Failed to set cursor position.\n");
4661 flush_events();
4662 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
4663 flush_events();
4665 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
4666 flush_events();
4667 /* SetCursorPos() doesn't. */
4668 ret = SetCursorPos(150, 150);
4669 ok(ret, "Failed to set cursor position.\n");
4670 flush_events();
4672 ok(!expect_pos->x && !expect_pos->y, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
4673 (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
4675 refcount = IDirect3DDevice9_Release(device);
4676 ok(!refcount, "Device has %u references left.\n", refcount);
4677 done:
4678 DestroyWindow(window);
4679 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
4680 IDirect3D9_Release(d3d9);
4683 static void test_mode_change(void)
4685 RECT d3d_rect, focus_rect, r;
4686 struct device_desc device_desc;
4687 IDirect3DSurface9 *backbuffer;
4688 IDirect3DDevice9 *device;
4689 D3DSURFACE_DESC desc;
4690 IDirect3D9 *d3d9;
4691 DEVMODEW devmode;
4692 ULONG refcount;
4693 UINT adapter_mode_count, i;
4694 HRESULT hr;
4695 DWORD ret;
4696 LONG change_ret;
4697 D3DDISPLAYMODE d3ddm;
4698 DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0;
4700 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4701 ok(!!d3d9, "Failed to create a D3D object.\n");
4703 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
4704 for (i = 0; i < adapter_mode_count; ++i)
4706 hr = IDirect3D9_EnumAdapterModes(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3ddm);
4707 ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#x.\n", hr);
4709 if (d3ddm.Width == registry_mode.dmPelsWidth && d3ddm.Height == registry_mode.dmPelsHeight)
4710 continue;
4711 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
4712 * refuses to create a device at these sizes. */
4713 if (d3ddm.Width < 640 || d3ddm.Height < 480)
4714 continue;
4716 if (!user32_width)
4718 user32_width = d3ddm.Width;
4719 user32_height = d3ddm.Height;
4720 continue;
4723 /* Make sure the d3d mode is smaller in width or height and at most
4724 * equal in the other dimension than the mode passed to
4725 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
4726 * the ChangeDisplaySettings parameters + 12. */
4727 if (d3ddm.Width == user32_width && d3ddm.Height == user32_height)
4728 continue;
4729 if (d3ddm.Width <= user32_width && d3ddm.Height <= user32_height)
4731 d3d_width = d3ddm.Width;
4732 d3d_height = d3ddm.Height;
4733 break;
4735 if (user32_width <= d3ddm.Width && user32_height <= d3ddm.Height)
4737 d3d_width = user32_width;
4738 d3d_height = user32_height;
4739 user32_width = d3ddm.Width;
4740 user32_height = d3ddm.Height;
4741 break;
4745 if (!d3d_width)
4747 skip("Could not find adequate modes, skipping mode tests.\n");
4748 IDirect3D9_Release(d3d9);
4749 return;
4752 memset(&devmode, 0, sizeof(devmode));
4753 devmode.dmSize = sizeof(devmode);
4754 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
4755 devmode.dmPelsWidth = user32_width;
4756 devmode.dmPelsHeight = user32_height;
4757 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
4758 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
4760 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4761 0, 0, user32_width / 2, user32_height / 2, 0, 0, 0, 0);
4762 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4763 0, 0, user32_width / 2, user32_height / 2, 0, 0, 0, 0);
4765 SetRect(&d3d_rect, 0, 0, d3d_width, d3d_height);
4766 GetWindowRect(focus_window, &focus_rect);
4768 device_desc.device_window = device_window;
4769 device_desc.width = d3d_width;
4770 device_desc.height = d3d_height;
4771 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4772 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4774 skip("Failed to create a D3D device, skipping tests.\n");
4775 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
4776 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
4777 goto done;
4780 devmode.dmPelsWidth = user32_width;
4781 devmode.dmPelsHeight = user32_height;
4782 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
4783 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
4785 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
4786 ok(ret, "Failed to get display mode.\n");
4787 ok(devmode.dmPelsWidth == user32_width && devmode.dmPelsHeight == user32_height,
4788 "Expected resolution %ux%u, got %ux%u.\n",
4789 user32_width, user32_height, devmode.dmPelsWidth, devmode.dmPelsHeight);
4791 GetWindowRect(device_window, &r);
4792 ok(EqualRect(&r, &d3d_rect), "Expected %s, got %s.\n",
4793 wine_dbgstr_rect(&d3d_rect), wine_dbgstr_rect(&r));
4794 GetWindowRect(focus_window, &r);
4795 ok(EqualRect(&r, &focus_rect), "Expected %s, got %s.\n",
4796 wine_dbgstr_rect(&focus_rect), wine_dbgstr_rect(&r));
4798 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
4799 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
4800 hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
4801 ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#x.\n", hr);
4802 ok(desc.Width == d3d_width, "Got unexpected backbuffer width %u, expected %u.\n",
4803 desc.Width, d3d_width);
4804 ok(desc.Height == d3d_height, "Got unexpected backbuffer height %u, expected %u.\n",
4805 desc.Height, d3d_height);
4806 IDirect3DSurface9_Release(backbuffer);
4808 refcount = IDirect3DDevice9_Release(device);
4809 ok(!refcount, "Device has %u references left.\n", refcount);
4811 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
4812 ok(ret, "Failed to get display mode.\n");
4813 todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
4814 && devmode.dmPelsHeight == registry_mode.dmPelsHeight,
4815 "Expected resolution %ux%u, got %ux%u.\n",
4816 registry_mode.dmPelsWidth, registry_mode.dmPelsHeight, devmode.dmPelsWidth, devmode.dmPelsHeight);
4818 change_ret = ChangeDisplaySettingsW(NULL, CDS_FULLSCREEN);
4819 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
4821 /* The mode restore also happens when the device was created at the original screen size. */
4823 device_desc.device_window = device_window;
4824 device_desc.width = registry_mode.dmPelsWidth;
4825 device_desc.height = registry_mode.dmPelsHeight;
4826 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4827 ok(!!(device = create_device(d3d9, focus_window, &device_desc)), "Failed to create a D3D device.\n");
4829 devmode.dmPelsWidth = user32_width;
4830 devmode.dmPelsHeight = user32_height;
4831 change_ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
4832 ok(change_ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", change_ret);
4834 refcount = IDirect3DDevice9_Release(device);
4835 ok(!refcount, "Device has %u references left.\n", refcount);
4837 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
4838 ok(ret, "Failed to get display mode.\n");
4839 ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth
4840 && devmode.dmPelsHeight == registry_mode.dmPelsHeight,
4841 "Expected resolution %ux%u, got %ux%u.\n",
4842 registry_mode.dmPelsWidth, registry_mode.dmPelsHeight, devmode.dmPelsWidth, devmode.dmPelsHeight);
4844 done:
4845 DestroyWindow(device_window);
4846 DestroyWindow(focus_window);
4847 IDirect3D9_Release(d3d9);
4850 static void test_device_window_reset(void)
4852 RECT fullscreen_rect, device_rect, r;
4853 struct device_desc device_desc;
4854 IDirect3DDevice9 *device;
4855 WNDCLASSA wc = {0};
4856 IDirect3D9 *d3d9;
4857 LONG_PTR proc;
4858 HRESULT hr;
4859 ULONG ref;
4861 wc.lpfnWndProc = test_proc;
4862 wc.lpszClassName = "d3d9_test_wndproc_wc";
4863 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4865 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4866 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
4867 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4868 0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
4869 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4870 ok(!!d3d9, "Failed to create a D3D object.\n");
4872 SetRect(&fullscreen_rect, 0, 0, registry_mode.dmPelsWidth, registry_mode.dmPelsHeight);
4873 GetWindowRect(device_window, &device_rect);
4875 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4876 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4877 (LONG_PTR)test_proc, proc);
4878 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4879 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4880 (LONG_PTR)test_proc, proc);
4882 device_desc.device_window = NULL;
4883 device_desc.width = registry_mode.dmPelsWidth;
4884 device_desc.height = registry_mode.dmPelsHeight;
4885 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
4886 if (!(device = create_device(d3d9, focus_window, &device_desc)))
4888 skip("Failed to create a D3D device, skipping tests.\n");
4889 goto done;
4892 GetWindowRect(focus_window, &r);
4893 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
4894 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
4895 GetWindowRect(device_window, &r);
4896 ok(EqualRect(&r, &device_rect), "Expected %s, got %s.\n",
4897 wine_dbgstr_rect(&device_rect), wine_dbgstr_rect(&r));
4899 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4900 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4901 (LONG_PTR)test_proc, proc);
4902 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4903 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
4905 device_desc.device_window = device_window;
4906 hr = reset_device(device, &device_desc);
4907 ok(SUCCEEDED(hr), "Failed to reset device.\n");
4909 GetWindowRect(focus_window, &r);
4910 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
4911 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
4912 GetWindowRect(device_window, &r);
4913 ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
4914 wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
4916 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4917 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4918 (LONG_PTR)test_proc, proc);
4919 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4920 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
4922 ref = IDirect3DDevice9_Release(device);
4923 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4925 done:
4926 IDirect3D9_Release(d3d9);
4927 DestroyWindow(device_window);
4928 DestroyWindow(focus_window);
4929 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
4932 static void test_reset_resources(void)
4934 IDirect3DSurface9 *surface, *rt;
4935 IDirect3DTexture9 *texture;
4936 IDirect3DDevice9 *device;
4937 IDirect3D9 *d3d9;
4938 unsigned int i;
4939 D3DCAPS9 caps;
4940 HWND window;
4941 HRESULT hr;
4942 ULONG ref;
4944 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
4945 0, 0, 640, 480, 0, 0, 0, 0);
4946 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4947 ok(!!d3d9, "Failed to create a D3D object.\n");
4949 if (!(device = create_device(d3d9, window, NULL)))
4951 skip("Failed to create a D3D device, skipping tests.\n");
4952 goto done;
4955 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4956 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4958 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128,
4959 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
4960 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
4961 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
4962 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
4963 IDirect3DSurface9_Release(surface);
4965 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
4967 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
4968 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4969 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
4970 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4971 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
4972 IDirect3DTexture9_Release(texture);
4973 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
4974 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
4975 IDirect3DSurface9_Release(surface);
4978 hr = reset_device(device, NULL);
4979 ok(SUCCEEDED(hr), "Failed to reset device.\n");
4981 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
4982 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
4983 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
4984 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4985 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
4986 IDirect3DSurface9_Release(surface);
4987 IDirect3DSurface9_Release(rt);
4989 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
4991 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
4992 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
4995 ref = IDirect3DDevice9_Release(device);
4996 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4998 done:
4999 IDirect3D9_Release(d3d9);
5000 DestroyWindow(window);
5003 static void test_set_rt_vp_scissor(void)
5005 IDirect3DStateBlock9 *stateblock;
5006 IDirect3DDevice9 *device;
5007 IDirect3DSurface9 *rt;
5008 IDirect3D9 *d3d9;
5009 D3DVIEWPORT9 vp;
5010 UINT refcount;
5011 HWND window;
5012 HRESULT hr;
5013 RECT rect;
5015 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
5016 0, 0, 640, 480, 0, 0, 0, 0);
5017 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5018 ok(!!d3d9, "Failed to create a D3D object.\n");
5019 if (!(device = create_device(d3d9, window, NULL)))
5021 skip("Failed to create a D3D device, skipping tests.\n");
5022 DestroyWindow(window);
5023 return;
5026 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
5027 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
5028 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5030 hr = IDirect3DDevice9_GetViewport(device, &vp);
5031 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
5032 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
5033 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
5034 ok(vp.Width == 640, "Got unexpected vp.Width %u.\n", vp.Width);
5035 ok(vp.Height == 480, "Got unexpected vp.Height %u.\n", vp.Height);
5036 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
5037 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
5039 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
5040 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
5041 ok(rect.left == 0 && rect.top == 0 && rect.right == 640 && rect.bottom == 480,
5042 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
5044 hr = IDirect3DDevice9_BeginStateBlock(device);
5045 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
5047 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5048 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5050 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
5051 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
5052 IDirect3DStateBlock9_Release(stateblock);
5054 hr = IDirect3DDevice9_GetViewport(device, &vp);
5055 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
5056 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
5057 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
5058 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
5059 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
5060 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
5061 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
5063 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
5064 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
5065 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
5066 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
5068 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5069 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5071 vp.X = 10;
5072 vp.Y = 20;
5073 vp.Width = 30;
5074 vp.Height = 40;
5075 vp.MinZ = 0.25f;
5076 vp.MaxZ = 0.75f;
5077 hr = IDirect3DDevice9_SetViewport(device, &vp);
5078 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
5080 SetRect(&rect, 50, 60, 70, 80);
5081 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
5082 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
5084 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5085 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5087 hr = IDirect3DDevice9_GetViewport(device, &vp);
5088 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
5089 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
5090 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
5091 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
5092 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
5093 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
5094 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
5096 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
5097 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
5098 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
5099 "Got unexpected scissor rect %s.\n", wine_dbgstr_rect(&rect));
5101 IDirect3DSurface9_Release(rt);
5102 refcount = IDirect3DDevice9_Release(device);
5103 ok(!refcount, "Device has %u references left.\n", refcount);
5104 IDirect3D9_Release(d3d9);
5105 DestroyWindow(window);
5108 static void test_volume_get_container(void)
5110 IDirect3DVolumeTexture9 *texture = NULL;
5111 IDirect3DVolume9 *volume = NULL;
5112 IDirect3DDevice9 *device;
5113 IUnknown *container;
5114 IDirect3D9 *d3d9;
5115 ULONG refcount;
5116 D3DCAPS9 caps;
5117 HWND window;
5118 HRESULT hr;
5120 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5121 0, 0, 640, 480, 0, 0, 0, 0);
5122 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5123 ok(!!d3d9, "Failed to create a D3D object.\n");
5124 if (!(device = create_device(d3d9, window, NULL)))
5126 skip("Failed to create a D3D device, skipping tests.\n");
5127 IDirect3D9_Release(d3d9);
5128 DestroyWindow(window);
5129 return;
5132 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5133 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5134 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
5136 skip("No volume texture support, skipping tests.\n");
5137 IDirect3DDevice9_Release(device);
5138 IDirect3D9_Release(d3d9);
5139 DestroyWindow(window);
5140 return;
5143 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
5144 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
5145 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5146 ok(!!texture, "Got unexpected texture %p.\n", texture);
5148 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
5149 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
5150 ok(!!volume, "Got unexpected volume %p.\n", volume);
5152 /* These should work... */
5153 container = NULL;
5154 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
5155 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
5156 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5157 IUnknown_Release(container);
5159 container = NULL;
5160 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
5161 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
5162 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5163 IUnknown_Release(container);
5165 container = NULL;
5166 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
5167 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
5168 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5169 IUnknown_Release(container);
5171 container = NULL;
5172 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
5173 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
5174 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5175 IUnknown_Release(container);
5177 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5178 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
5179 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5180 ok(!container, "Got unexpected container %p.\n", container);
5182 IDirect3DVolume9_Release(volume);
5183 IDirect3DVolumeTexture9_Release(texture);
5184 refcount = IDirect3DDevice9_Release(device);
5185 ok(!refcount, "Device has %u references left.\n", refcount);
5186 IDirect3D9_Release(d3d9);
5187 DestroyWindow(window);
5190 static void test_volume_resource(void)
5192 IDirect3DVolumeTexture9 *texture;
5193 IDirect3DResource9 *resource;
5194 IDirect3DVolume9 *volume;
5195 IDirect3DDevice9 *device;
5196 IDirect3D9 *d3d9;
5197 ULONG refcount;
5198 D3DCAPS9 caps;
5199 HWND window;
5200 HRESULT hr;
5202 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5203 0, 0, 640, 480, 0, 0, 0, 0);
5204 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5205 ok(!!d3d9, "Failed to create a D3D object.\n");
5206 if (!(device = create_device(d3d9, window, NULL)))
5208 skip("Failed to create a D3D device, skipping tests.\n");
5209 IDirect3D9_Release(d3d9);
5210 DestroyWindow(window);
5211 return;
5214 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5215 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5216 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
5218 skip("No volume texture support, skipping tests.\n");
5219 IDirect3DDevice9_Release(device);
5220 IDirect3D9_Release(d3d9);
5221 DestroyWindow(window);
5222 return;
5225 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
5226 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
5227 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5228 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
5229 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
5230 IDirect3DVolumeTexture9_Release(texture);
5232 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
5233 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5235 IDirect3DVolume9_Release(volume);
5236 refcount = IDirect3DDevice9_Release(device);
5237 ok(!refcount, "Device has %u references left.\n", refcount);
5238 IDirect3D9_Release(d3d9);
5239 DestroyWindow(window);
5242 static void test_vb_lock_flags(void)
5244 static const struct
5246 DWORD flags;
5247 const char *debug_string;
5248 HRESULT win7_result;
5250 test_data[] =
5252 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
5253 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
5254 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
5255 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
5256 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
5257 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
5258 /* Completely bogus flags aren't an error. */
5259 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
5261 IDirect3DVertexBuffer9 *buffer;
5262 IDirect3DDevice9 *device;
5263 IDirect3D9 *d3d9;
5264 unsigned int i;
5265 ULONG refcount;
5266 HWND window;
5267 HRESULT hr;
5268 void *data;
5270 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5271 0, 0, 640, 480, 0, 0, 0, 0);
5272 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5273 ok(!!d3d9, "Failed to create a D3D object.\n");
5274 if (!(device = create_device(d3d9, window, NULL)))
5276 skip("Failed to create a D3D device, skipping tests.\n");
5277 IDirect3D9_Release(d3d9);
5278 DestroyWindow(window);
5279 return;
5282 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
5283 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
5285 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
5287 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
5288 /* Windows XP always returns D3D_OK even with flags that don't make
5289 * sense. Windows 7 returns an error. At least one game (Shaiya)
5290 * depends on the Windows XP result, so mark the Windows 7 behavior as
5291 * broken. */
5292 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
5293 hr, test_data[i].debug_string);
5294 if (SUCCEEDED(hr))
5296 ok(!!data, "Got unexpected data %p.\n", data);
5297 hr = IDirect3DVertexBuffer9_Unlock(buffer);
5298 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
5302 IDirect3DVertexBuffer9_Release(buffer);
5303 refcount = IDirect3DDevice9_Release(device);
5304 ok(!refcount, "Device has %u references left.\n", refcount);
5305 IDirect3D9_Release(d3d9);
5306 DestroyWindow(window);
5309 static const char *debug_d3dpool(D3DPOOL pool)
5311 switch (pool)
5313 case D3DPOOL_DEFAULT:
5314 return "D3DPOOL_DEFAULT";
5315 case D3DPOOL_SYSTEMMEM:
5316 return "D3DPOOL_SYSTEMMEM";
5317 case D3DPOOL_SCRATCH:
5318 return "D3DPOOL_SCRATCH";
5319 case D3DPOOL_MANAGED:
5320 return "D3DPOOL_MANAGED";
5321 default:
5322 return "unknown pool";
5326 static void test_vertex_buffer_alignment(void)
5328 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
5329 static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
5330 IDirect3DVertexBuffer9 *buffer = NULL;
5331 const unsigned int align = 16;
5332 IDirect3DDevice9 *device;
5333 unsigned int i, j;
5334 IDirect3D9 *d3d9;
5335 ULONG refcount;
5336 HWND window;
5337 HRESULT hr;
5338 void *data;
5340 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5341 0, 0, 640, 480, 0, 0, 0, 0);
5342 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5343 ok(!!d3d9, "Failed to create a D3D object.\n");
5344 if (!(device = create_device(d3d9, window, NULL)))
5346 skip("Failed to create a D3D device, skipping tests.\n");
5347 IDirect3D9_Release(d3d9);
5348 DestroyWindow(window);
5349 return;
5352 for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
5354 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
5356 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
5357 if (pools[j] == D3DPOOL_SCRATCH)
5358 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
5359 else
5360 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
5361 debug_d3dpool(pools[j]), sizes[i], hr);
5362 if (FAILED(hr))
5363 continue;
5365 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
5366 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
5367 ok(!((DWORD_PTR)data & (align - 1)),
5368 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
5369 data, align, sizes[i], debug_d3dpool(pools[j]));
5370 hr = IDirect3DVertexBuffer9_Unlock(buffer);
5371 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
5372 IDirect3DVertexBuffer9_Release(buffer);
5376 refcount = IDirect3DDevice9_Release(device);
5377 ok(!refcount, "Device has %u references left.\n", refcount);
5378 IDirect3D9_Release(d3d9);
5379 DestroyWindow(window);
5382 static void test_query_support(void)
5384 static const D3DQUERYTYPE queries[] =
5386 D3DQUERYTYPE_VCACHE,
5387 D3DQUERYTYPE_RESOURCEMANAGER,
5388 D3DQUERYTYPE_VERTEXSTATS,
5389 D3DQUERYTYPE_EVENT,
5390 D3DQUERYTYPE_OCCLUSION,
5391 D3DQUERYTYPE_TIMESTAMP,
5392 D3DQUERYTYPE_TIMESTAMPDISJOINT,
5393 D3DQUERYTYPE_TIMESTAMPFREQ,
5394 D3DQUERYTYPE_PIPELINETIMINGS,
5395 D3DQUERYTYPE_INTERFACETIMINGS,
5396 D3DQUERYTYPE_VERTEXTIMINGS,
5397 D3DQUERYTYPE_PIXELTIMINGS,
5398 D3DQUERYTYPE_BANDWIDTHTIMINGS,
5399 D3DQUERYTYPE_CACHEUTILIZATION,
5401 IDirect3DQuery9 *query = NULL;
5402 IDirect3DDevice9 *device;
5403 IDirect3D9 *d3d9;
5404 unsigned int i;
5405 ULONG refcount;
5406 BOOL supported;
5407 HWND window;
5408 HRESULT hr;
5410 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5411 0, 0, 640, 480, 0, 0, 0, 0);
5412 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5413 ok(!!d3d9, "Failed to create a D3D object.\n");
5414 if (!(device = create_device(d3d9, window, NULL)))
5416 skip("Failed to create a D3D device, skipping tests.\n");
5417 IDirect3D9_Release(d3d9);
5418 DestroyWindow(window);
5419 return;
5422 for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
5424 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
5425 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
5427 supported = hr == D3D_OK;
5429 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
5430 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
5432 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
5433 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
5435 if (query)
5437 IDirect3DQuery9_Release(query);
5438 query = NULL;
5442 refcount = IDirect3DDevice9_Release(device);
5443 ok(!refcount, "Device has %u references left.\n", refcount);
5444 IDirect3D9_Release(d3d9);
5445 DestroyWindow(window);
5448 static void test_occlusion_query_states(void)
5450 static const float quad[] =
5452 -1.0f, -1.0f, 0.0f,
5453 -1.0f, 1.0f, 0.0f,
5454 1.0f, 1.0f, 0.0f,
5455 1.0f, -1.0f, 0.0f,
5457 struct device_desc device_desc;
5458 IDirect3DQuery9 *query = NULL;
5459 unsigned int data_size, i;
5460 IDirect3DDevice9 *device;
5461 IDirect3D9 *d3d9;
5462 ULONG refcount;
5463 HWND window;
5464 HRESULT hr;
5465 union
5467 WORD word[4];
5468 DWORD dword[2];
5469 } data;
5470 BOOL broken_occlusion = FALSE;
5471 DWORD expected = registry_mode.dmPelsWidth * registry_mode.dmPelsHeight;
5473 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5474 0, 0, 640, 480, 0, 0, 0, 0);
5475 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5476 ok(!!d3d9, "Failed to create a D3D object.\n");
5477 device_desc.device_window = window;
5478 device_desc.width = registry_mode.dmPelsWidth;
5479 device_desc.height = registry_mode.dmPelsHeight;
5480 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
5481 if (!(device = create_device(d3d9, window, &device_desc)))
5483 skip("Failed to create a D3D device, skipping tests.\n");
5484 IDirect3D9_Release(d3d9);
5485 DestroyWindow(window);
5486 return;
5489 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
5490 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5491 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5492 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5494 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5496 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
5497 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
5498 if (!query)
5500 skip("Occlusion queries are not supported, skipping tests.\n");
5501 IDirect3DDevice9_Release(device);
5502 IDirect3D9_Release(d3d9);
5503 DestroyWindow(window);
5504 return;
5507 data_size = IDirect3DQuery9_GetDataSize(query);
5508 ok(data_size == sizeof(DWORD), "Unexpected data size %u.\n", data_size);
5510 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
5511 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5512 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
5513 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5515 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
5516 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5517 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
5518 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5519 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
5520 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5522 data.dword[0] = 0x12345678;
5523 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
5524 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5525 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
5526 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5527 if (hr == D3D_OK)
5528 ok(!data.dword[0], "Got unexpected query result %u.\n", data.dword[0]);
5530 hr = IDirect3DDevice9_BeginScene(device);
5531 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5532 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
5533 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5534 hr = IDirect3DDevice9_EndScene(device);
5535 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5537 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
5538 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5539 for (i = 0; i < 500; ++i)
5541 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
5542 break;
5543 Sleep(10);
5545 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5547 memset(&data, 0xff, sizeof(data));
5548 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
5549 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5550 ok(data.dword[0] == expected || broken(!data.dword[0]),
5551 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
5552 if (!data.dword[0])
5554 win_skip("Occlusion query result looks broken, ignoring returned count.\n");
5555 broken_occlusion = TRUE;
5558 memset(&data, 0xff, sizeof(data));
5559 hr = IDirect3DQuery9_GetData(query, &data, sizeof(WORD), D3DGETDATA_FLUSH);
5560 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5561 if (!broken_occlusion)
5562 ok(data.word[0] == (WORD)expected,
5563 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
5564 ok(data.word[1] == 0xffff,
5565 "data was modified outside of the expected size (0x%.8x).\n", data.dword[0]);
5567 memset(&data, 0xf0, sizeof(data));
5568 hr = IDirect3DQuery9_GetData(query, &data, sizeof(data), D3DGETDATA_FLUSH);
5569 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5570 if (!broken_occlusion)
5571 ok(data.dword[0] == expected,
5572 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
5573 /* Different drivers seem to return different data in those high bytes on Windows, but they all
5574 write something there and the extra data is consistent (I've seen 0x00000000 and 0xdddddddd
5575 on AMD and Nvidia respectively). */
5576 if (0)
5578 ok(data.dword[1] != 0xf0f0f0f0, "high bytes of data were not modified (0x%.8x).\n",
5579 data.dword[1]);
5582 memset(&data, 0xff, sizeof(data));
5583 hr = IDirect3DQuery9_GetData(query, &data, 0, D3DGETDATA_FLUSH);
5584 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5585 ok(data.dword[0] == 0xffffffff, "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
5587 /* This crashes on Windows. */
5588 if (0)
5590 hr = IDirect3DQuery9_GetData(query, NULL, data_size, D3DGETDATA_FLUSH);
5591 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5594 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
5595 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5596 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
5597 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5598 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
5599 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5601 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5603 IDirect3DQuery9_Release(query);
5604 refcount = IDirect3DDevice9_Release(device);
5605 ok(!refcount, "Device has %u references left.\n", refcount);
5606 IDirect3D9_Release(d3d9);
5607 DestroyWindow(window);
5610 static void test_timestamp_query(void)
5612 static const float quad[] =
5614 -1.0f, -1.0f, 0.0f,
5615 -1.0f, 1.0f, 0.0f,
5616 1.0f, 1.0f, 0.0f,
5617 1.0f, -1.0f, 0.0f,
5619 IDirect3DQuery9 *query, *disjoint_query, *freq_query;
5620 unsigned int data_size, i;
5621 IDirect3DDevice9 *device;
5622 IDirect3D9 *d3d9;
5623 ULONG refcount;
5624 HWND window;
5625 HRESULT hr;
5626 DWORD timestamp[2], freq[2];
5627 WORD disjoint[2];
5629 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5630 0, 0, 640, 480, 0, 0, 0, 0);
5631 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
5632 ok(!!d3d9, "Failed to create a D3D object.\n");
5633 if (!(device = create_device(d3d9, window, NULL)))
5635 skip("Failed to create a D3D device, skipping tests.\n");
5636 IDirect3D9_Release(d3d9);
5637 DestroyWindow(window);
5638 return;
5641 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPFREQ, &freq_query);
5642 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
5643 if (FAILED(hr))
5645 skip("Timestamp queries are not supported, skipping tests.\n");
5646 IDirect3DDevice9_Release(device);
5647 IDirect3D9_Release(d3d9);
5648 DestroyWindow(window);
5649 return;
5651 data_size = IDirect3DQuery9_GetDataSize(freq_query);
5652 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
5654 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPDISJOINT, &disjoint_query);
5655 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5656 data_size = IDirect3DQuery9_GetDataSize(disjoint_query);
5657 ok(data_size == sizeof(BOOL), "Query data size is %u, 4 expected.\n", data_size);
5659 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMP, &query);
5660 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5661 data_size = IDirect3DQuery9_GetDataSize(query);
5662 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
5664 hr = IDirect3DQuery9_Issue(freq_query, D3DISSUE_END);
5665 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5666 for (i = 0; i < 500; ++i)
5668 if ((hr = IDirect3DQuery9_GetData(freq_query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
5669 break;
5670 Sleep(10);
5672 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5674 memset(freq, 0xff, sizeof(freq));
5675 hr = IDirect3DQuery9_GetData(freq_query, freq, sizeof(DWORD), D3DGETDATA_FLUSH);
5676 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5677 ok(freq[1] == 0xffffffff,
5678 "freq was modified outside of the expected size (0x%.8x).\n", freq[1]);
5679 hr = IDirect3DQuery9_GetData(freq_query, &freq, sizeof(freq), D3DGETDATA_FLUSH);
5680 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5681 ok(freq[1] != 0xffffffff, "high bytes of freq were not modified (0x%.8x).\n",
5682 freq[1]);
5684 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
5685 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5686 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
5687 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5689 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
5690 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5691 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
5692 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5693 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
5694 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5696 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
5697 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5699 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5700 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5701 hr = IDirect3DDevice9_BeginScene(device);
5702 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
5704 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5705 hr = IDirect3DDevice9_EndScene(device);
5706 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5708 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
5709 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5710 for (i = 0; i < 500; ++i)
5712 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
5713 break;
5714 Sleep(10);
5716 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5718 memset(timestamp, 0xff, sizeof(timestamp));
5719 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(DWORD), D3DGETDATA_FLUSH);
5720 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5721 ok(timestamp[1] == 0xffffffff,
5722 "timestamp was modified outside of the expected size (0x%.8x).\n",
5723 timestamp[1]);
5725 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
5726 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5727 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
5728 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5729 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
5730 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5732 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
5733 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5734 for (i = 0; i < 500; ++i)
5736 if ((hr = IDirect3DQuery9_GetData(disjoint_query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
5737 break;
5738 Sleep(10);
5740 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5742 memset(disjoint, 0xff, sizeof(disjoint));
5743 hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(WORD), D3DGETDATA_FLUSH);
5744 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5745 ok(disjoint[1] == 0xffff,
5746 "disjoint was modified outside of the expected size (0x%.4hx).\n", disjoint[1]);
5747 hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(disjoint), D3DGETDATA_FLUSH);
5748 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5749 ok(disjoint[1] != 0xffff, "high bytes of disjoint were not modified (0x%.4hx).\n", disjoint[1]);
5751 /* It's not strictly necessary for the TIMESTAMP query to be inside
5752 * a TIMESTAMP_DISJOINT query. */
5753 hr = IDirect3DDevice9_BeginScene(device);
5754 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5755 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
5756 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5757 hr = IDirect3DDevice9_EndScene(device);
5758 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5760 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
5761 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5762 for (i = 0; i < 500; ++i)
5764 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
5765 break;
5766 Sleep(10);
5768 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5769 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
5770 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
5772 IDirect3DQuery9_Release(query);
5773 IDirect3DQuery9_Release(disjoint_query);
5774 IDirect3DQuery9_Release(freq_query);
5775 refcount = IDirect3DDevice9_Release(device);
5776 ok(!refcount, "Device has %u references left.\n", refcount);
5777 IDirect3D9_Release(d3d9);
5778 DestroyWindow(window);
5781 static void test_get_set_vertex_shader(void)
5783 IDirect3DVertexShader9 *current_shader = NULL;
5784 IDirect3DVertexShader9 *shader = NULL;
5785 const IDirect3DVertexShader9Vtbl *shader_vtbl;
5786 IDirect3DDevice9 *device;
5787 ULONG refcount, i;
5788 IDirect3D9 *d3d;
5789 D3DCAPS9 caps;
5790 HWND window;
5791 HRESULT hr;
5793 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5794 0, 0, 640, 480, 0, 0, 0, 0);
5795 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5796 ok(!!d3d, "Failed to create a D3D object.\n");
5797 if (!(device = create_device(d3d, window, NULL)))
5799 skip("Failed to create a D3D device, skipping tests.\n");
5800 IDirect3D9_Release(d3d);
5801 DestroyWindow(window);
5802 return;
5805 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5806 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5807 if (!(caps.VertexShaderVersion & 0xffff))
5809 skip("No vertex shader support, skipping tests.\n");
5810 IDirect3DDevice9_Release(device);
5811 IDirect3D9_Release(d3d);
5812 DestroyWindow(window);
5813 return;
5816 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
5817 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
5818 ok(!!shader, "Got unexpected shader %p.\n", shader);
5820 /* SetVertexShader() should not touch the shader's refcount. */
5821 i = get_refcount((IUnknown *)shader);
5822 hr = IDirect3DDevice9_SetVertexShader(device, shader);
5823 refcount = get_refcount((IUnknown *)shader);
5824 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5825 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
5827 /* GetVertexShader() should increase the shader's refcount by one. */
5828 i = refcount + 1;
5829 hr = IDirect3DDevice9_GetVertexShader(device, &current_shader);
5830 refcount = get_refcount((IUnknown *)shader);
5831 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
5832 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
5833 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
5834 IDirect3DVertexShader9_Release(current_shader);
5836 /* SetVertexShader() with a bogus shader vtbl */
5837 shader_vtbl = shader->lpVtbl;
5838 shader->lpVtbl = (IDirect3DVertexShader9Vtbl *)0xdeadbeef;
5839 hr = IDirect3DDevice9_SetVertexShader(device, shader);
5840 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5841 shader->lpVtbl = NULL;
5842 hr = IDirect3DDevice9_SetVertexShader(device, shader);
5843 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5844 shader->lpVtbl = shader_vtbl;
5846 IDirect3DVertexShader9_Release(shader);
5847 refcount = IDirect3DDevice9_Release(device);
5848 ok(!refcount, "Device has %u references left.\n", refcount);
5849 IDirect3D9_Release(d3d);
5850 DestroyWindow(window);
5853 static void test_vertex_shader_constant(void)
5855 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};
5856 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
5857 IDirect3DDevice9 *device;
5858 IDirect3D9 *d3d;
5859 ULONG refcount;
5860 D3DCAPS9 caps;
5861 DWORD consts;
5862 HWND window;
5863 HRESULT hr;
5865 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5866 0, 0, 640, 480, 0, 0, 0, 0);
5867 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5868 ok(!!d3d, "Failed to create a D3D object.\n");
5869 if (!(device = create_device(d3d, window, NULL)))
5871 skip("Failed to create a D3D device, skipping tests.\n");
5872 IDirect3D9_Release(d3d);
5873 DestroyWindow(window);
5874 return;
5877 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5878 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5879 if (!(caps.VertexShaderVersion & 0xffff))
5881 skip("No vertex shader support, skipping tests.\n");
5882 IDirect3DDevice9_Release(device);
5883 IDirect3D9_Release(d3d);
5884 DestroyWindow(window);
5885 return;
5887 consts = caps.MaxVertexShaderConst;
5889 /* A simple check that the stuff works at all. */
5890 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
5891 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5893 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
5894 * consts from MAX - 1. */
5895 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
5896 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5897 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
5898 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5899 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
5900 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5901 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
5902 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5904 /* Constant -1. */
5905 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
5906 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5908 refcount = IDirect3DDevice9_Release(device);
5909 ok(!refcount, "Device has %u references left.\n", refcount);
5910 IDirect3D9_Release(d3d);
5911 DestroyWindow(window);
5914 static void test_get_set_pixel_shader(void)
5916 IDirect3DPixelShader9 *current_shader = NULL;
5917 IDirect3DPixelShader9 *shader = NULL;
5918 const IDirect3DPixelShader9Vtbl *shader_vtbl;
5919 IDirect3DDevice9 *device;
5920 ULONG refcount, i;
5921 IDirect3D9 *d3d;
5922 D3DCAPS9 caps;
5923 HWND window;
5924 HRESULT hr;
5926 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5927 0, 0, 640, 480, 0, 0, 0, 0);
5928 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5929 ok(!!d3d, "Failed to create a D3D object.\n");
5930 if (!(device = create_device(d3d, window, NULL)))
5932 skip("Failed to create a D3D device, skipping tests.\n");
5933 IDirect3D9_Release(d3d);
5934 DestroyWindow(window);
5935 return;
5938 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5939 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5940 if (!(caps.PixelShaderVersion & 0xffff))
5942 skip("No pixel shader support, skipping tests.\n");
5943 IDirect3DDevice9_Release(device);
5944 IDirect3D9_Release(d3d);
5945 DestroyWindow(window);
5946 return;
5949 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
5950 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
5951 ok(!!shader, "Got unexpected shader %p.\n", shader);
5953 /* SetPixelShader() should not touch the shader's refcount. */
5954 i = get_refcount((IUnknown *)shader);
5955 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5956 refcount = get_refcount((IUnknown *)shader);
5957 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5958 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
5960 /* GetPixelShader() should increase the shader's refcount by one. */
5961 i = refcount + 1;
5962 hr = IDirect3DDevice9_GetPixelShader(device, &current_shader);
5963 refcount = get_refcount((IUnknown *)shader);
5964 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
5965 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
5966 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
5967 IDirect3DPixelShader9_Release(current_shader);
5969 /* SetPixelShader() with a bogus shader vtbl */
5970 shader_vtbl = shader->lpVtbl;
5971 shader->lpVtbl = (IDirect3DPixelShader9Vtbl *)0xdeadbeef;
5972 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5973 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5974 shader->lpVtbl = NULL;
5975 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5976 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5977 shader->lpVtbl = shader_vtbl;
5979 IDirect3DPixelShader9_Release(shader);
5980 refcount = IDirect3DDevice9_Release(device);
5981 ok(!refcount, "Device has %u references left.\n", refcount);
5982 IDirect3D9_Release(d3d);
5983 DestroyWindow(window);
5986 static void test_pixel_shader_constant(void)
5988 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};
5989 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
5990 IDirect3DDevice9 *device;
5991 DWORD consts = 0;
5992 IDirect3D9 *d3d;
5993 ULONG refcount;
5994 D3DCAPS9 caps;
5995 HWND window;
5996 HRESULT hr;
5998 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5999 0, 0, 640, 480, 0, 0, 0, 0);
6000 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6001 ok(!!d3d, "Failed to create a D3D object.\n");
6002 if (!(device = create_device(d3d, window, NULL)))
6004 skip("Failed to create a D3D device, skipping tests.\n");
6005 IDirect3D9_Release(d3d);
6006 DestroyWindow(window);
6007 return;
6010 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6011 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6012 if (!(caps.PixelShaderVersion & 0xffff))
6014 skip("No pixel shader support, skipping tests.\n");
6015 IDirect3DDevice9_Release(device);
6016 IDirect3D9_Release(d3d);
6017 DestroyWindow(window);
6018 return;
6021 /* A simple check that the stuff works at all. */
6022 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
6023 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6025 /* Is there really no max pixel shader constant value??? Test how far I can go. */
6026 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
6027 consts = consts - 1;
6028 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
6030 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
6031 * pointless given the way the constant limit was determined. */
6032 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
6033 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6035 /* Constant -1. */
6036 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
6037 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6039 refcount = IDirect3DDevice9_Release(device);
6040 ok(!refcount, "Device has %u references left.\n", refcount);
6041 IDirect3D9_Release(d3d);
6042 DestroyWindow(window);
6045 static void test_unsupported_shaders(void)
6047 static const DWORD vs_3_0[] =
6049 0xfffe0300, /* vs_3_0 */
6050 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6051 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6052 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6053 0x0000ffff, /* end */
6056 #if 0
6057 float4 main(const float4 color : COLOR) : SV_TARGET
6059 float4 o;
6061 o = color;
6063 return o;
6065 #endif
6066 static const DWORD ps_4_0[] =
6068 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
6069 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
6070 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
6071 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
6072 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
6073 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
6074 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
6075 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
6076 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
6077 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
6078 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
6079 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
6080 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
6081 0x00000000, 0x00000000, 0x00000000,
6083 #if 0
6084 vs_1_1
6085 dcl_position v0
6086 def c255, 1.0, 1.0, 1.0, 1.0
6087 add r0, v0, c255
6088 mov oPos, r0
6089 #endif
6090 static const DWORD vs_1_255[] =
6092 0xfffe0101,
6093 0x0000001f, 0x80000000, 0x900f0000,
6094 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
6095 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
6096 0x00000001, 0xc00f0000, 0x80e40000,
6097 0x0000ffff
6099 #if 0
6100 vs_1_1
6101 dcl_position v0
6102 def c256, 1.0, 1.0, 1.0, 1.0
6103 add r0, v0, c256
6104 mov oPos, r0
6105 #endif
6106 static const DWORD vs_1_256[] =
6108 0xfffe0101,
6109 0x0000001f, 0x80000000, 0x900f0000,
6110 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
6111 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
6112 0x00000001, 0xc00f0000, 0x80e40000,
6113 0x0000ffff
6115 #if 0
6116 vs_3_0
6117 dcl_position v0
6118 dcl_position o0
6119 def c256, 1.0, 1.0, 1.0, 1.0
6120 add r0, v0, c256
6121 mov o0, r0
6122 #endif
6123 static const DWORD vs_3_256[] =
6125 0xfffe0300,
6126 0x0200001f, 0x80000000, 0x900f0000,
6127 0x0200001f, 0x80000000, 0xe00f0000,
6128 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
6129 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
6130 0x02000001, 0xe00f0000, 0x80e40000,
6131 0x0000ffff
6133 #if 0
6134 /* This shader source generates syntax errors with the native shader assembler
6135 * due to the constant register index values.
6136 * The bytecode was modified by hand to use the intended values. */
6137 vs_3_0
6138 dcl_position v0
6139 dcl_position o0
6140 defi i16, 1, 1, 1, 1
6141 rep i16
6142 add r0, r0, v0
6143 endrep
6144 mov o0, r0
6145 #endif
6146 static const DWORD vs_3_i16[] =
6148 0xfffe0300,
6149 0x0200001f, 0x80000000, 0x900f0000,
6150 0x0200001f, 0x80000000, 0xe00f0000,
6151 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
6152 0x01000026, 0xf0e40010,
6153 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
6154 0x00000027,
6155 0x02000001, 0xe00f0000, 0x80e40000,
6156 0x0000ffff
6158 #if 0
6159 /* This shader source generates syntax errors with the native shader assembler
6160 * due to the constant register index values.
6161 * The bytecode was modified by hand to use the intended values. */
6162 vs_3_0
6163 dcl_position v0
6164 dcl_position o0
6165 defb b16, true
6166 mov r0, v0
6167 if b16
6168 add r0, r0, v0
6169 endif
6170 mov o0, r0
6171 #endif
6172 static const DWORD vs_3_b16[] =
6174 0xfffe0300,
6175 0x0200001f, 0x80000000, 0x900f0000,
6176 0x0200001f, 0x80000000, 0xe00f0000,
6177 0x0200002f, 0xe00f0810, 0x00000001,
6178 0x02000001, 0x800f0000, 0x90e40000,
6179 0x01000028, 0xe0e40810,
6180 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
6181 0x0000002b,
6182 0x02000001, 0xe00f0000, 0x80e40000,
6183 0x0000ffff
6185 #if 0
6186 /* This shader source generates syntax errors with the native shader assembler
6187 * due to the constant register index values.
6188 * The bytecode was modified by hand to use the intended values. */
6189 ps_1_1
6190 def c8, 1.0, 1.0, 1.0, 1.0
6191 add r0, v0, c8
6192 #endif
6193 static const DWORD ps_1_8[] =
6195 0xffff0101,
6196 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
6197 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
6198 0x0000ffff
6200 #if 0
6201 /* This shader source generates syntax errors with the native shader assembler
6202 * due to the constant register index values.
6203 * The bytecode was modified by hand to use the intended values. */
6204 ps_2_0
6205 def c32, 1.0, 1.0, 1.0, 1.0
6206 add oC0, v0, c32
6207 #endif
6208 static const DWORD ps_2_32[] =
6210 0xffff0200,
6211 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
6212 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
6213 0x0000ffff
6215 #if 0
6216 /* This shader source generates syntax errors with the native shader assembler
6217 * due to the constant register index values.
6218 * The bytecode was modified by hand to use the intended values. */
6219 ps_3_0
6220 dcl_color0 v0
6221 def c224, 1.0, 1.0, 1.0, 1.0
6222 add oC0, v0, c224
6223 #endif
6224 static const DWORD ps_3_224[] =
6226 0xffff0300,
6227 0x0200001f, 0x8000000a, 0x900f0000,
6228 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
6229 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
6230 0x0000ffff
6232 #if 0
6233 /* This shader source generates syntax errors with the native shader assembler
6234 * due to the constant register index values.
6235 * The bytecode was modified by hand to use the intended values. */
6236 ps_2_0
6237 defb b0, true
6238 defi i0, 1, 1, 1, 1
6239 rep i0
6240 if b0
6241 add r0, r0, v0
6242 endif
6243 endrep
6244 mov oC0, r0
6245 #endif
6246 static const DWORD ps_2_0_boolint[] =
6248 0xffff0200,
6249 0x0200002f, 0xe00f0800, 0x00000001,
6250 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
6251 0x01000026, 0xf0e40000,
6252 0x01000028, 0xe0e40800,
6253 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
6254 0x0000002b,
6255 0x00000027,
6256 0x02000001, 0x800f0800, 0x80e40000,
6257 0x0000ffff
6260 IDirect3DVertexShader9 *vs = NULL;
6261 IDirect3DPixelShader9 *ps = NULL;
6262 IDirect3DDevice9 *device;
6263 IDirect3D9 * d3d;
6264 ULONG refcount;
6265 D3DCAPS9 caps;
6266 HWND window;
6267 HRESULT hr;
6269 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6270 0, 0, 640, 480, 0, 0, 0, 0);
6271 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6272 ok(!!d3d, "Failed to create a D3D object.\n");
6273 if (!(device = create_device(d3d, window, NULL)))
6275 skip("Failed to create a D3D device, skipping tests.\n");
6276 IDirect3D9_Release(d3d);
6277 DestroyWindow(window);
6278 return;
6281 /* These should always fail, regardless of supported shader version. */
6282 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
6283 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6284 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
6285 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6286 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
6287 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6289 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6290 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6291 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6293 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
6294 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6295 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
6297 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_255, &vs);
6298 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6300 else
6302 skip("GPU supports SM2+, skipping SM1 test.\n");
6305 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
6307 else
6309 skip("This GPU supports SM3, skipping unsupported shader test.\n");
6311 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_255, &vs);
6312 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6313 IDirect3DVertexShader9_Release(vs);
6314 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_256, &vs);
6315 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6316 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_256, &vs);
6317 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6318 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_i16, &vs);
6319 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6320 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_b16, &vs);
6321 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6324 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
6326 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
6327 goto cleanup;
6329 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_8, &ps);
6330 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6331 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_32, &ps);
6332 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6333 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_224, &ps);
6334 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6335 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_0_boolint, &ps);
6336 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6337 if (ps)
6338 IDirect3DPixelShader9_Release(ps);
6340 cleanup:
6341 refcount = IDirect3DDevice9_Release(device);
6342 ok(!refcount, "Device has %u references left.\n", refcount);
6343 IDirect3D9_Release(d3d);
6344 DestroyWindow(window);
6347 /* Test the default texture stage state values */
6348 static void test_texture_stage_states(void)
6350 IDirect3DDevice9 *device;
6351 IDirect3D9 *d3d;
6352 unsigned int i;
6353 ULONG refcount;
6354 D3DCAPS9 caps;
6355 DWORD value;
6356 HWND window;
6357 HRESULT hr;
6359 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6360 0, 0, 640, 480, 0, 0, 0, 0);
6361 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6362 ok(!!d3d, "Failed to create a D3D object.\n");
6363 if (!(device = create_device(d3d, window, NULL)))
6365 skip("Failed to create a D3D device, skipping tests.\n");
6366 IDirect3D9_Release(d3d);
6367 DestroyWindow(window);
6368 return;
6371 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6372 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6374 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
6376 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
6377 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6378 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
6379 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
6380 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
6381 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6382 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
6383 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
6384 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6385 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
6386 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
6387 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6388 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
6389 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
6390 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
6391 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6392 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
6393 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
6394 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6395 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
6396 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
6397 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6398 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
6399 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
6400 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6401 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
6402 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
6403 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6404 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
6405 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
6406 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6407 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
6408 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
6409 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6410 ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
6411 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
6412 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6413 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
6414 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
6415 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6416 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
6417 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
6418 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6419 ok(value == D3DTTFF_DISABLE,
6420 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
6421 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
6422 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6423 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
6424 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
6425 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6426 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
6427 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
6428 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6429 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value, i);
6430 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
6431 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
6432 ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
6435 refcount = IDirect3DDevice9_Release(device);
6436 ok(!refcount, "Device has %u references left.\n", refcount);
6437 IDirect3D9_Release(d3d);
6438 DestroyWindow(window);
6441 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
6443 IDirect3DCubeTexture9 *texture;
6444 IDirect3D9 *d3d;
6445 HRESULT hr;
6447 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
6448 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
6449 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6450 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
6451 IDirect3D9_Release(d3d);
6452 if (FAILED(hr))
6454 skip("No cube mipmap generation support, skipping tests.\n");
6455 return;
6458 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
6459 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6460 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6461 IDirect3DCubeTexture9_Release(texture);
6463 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
6464 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
6465 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6466 IDirect3DCubeTexture9_Release(texture);
6469 static void test_cube_texture_levels(IDirect3DDevice9 *device)
6471 IDirect3DCubeTexture9 *texture;
6472 IDirect3DSurface9 *surface;
6473 D3DSURFACE_DESC desc;
6474 DWORD levels;
6475 HRESULT hr;
6476 D3DCAPS9 caps;
6478 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6479 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6480 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
6481 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
6483 skip("Failed to create cube texture, skipping tests.\n");
6484 return;
6487 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
6488 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)
6489 ok(levels == 7, "Got unexpected levels %u.\n", levels);
6490 else
6491 ok(levels == 1, "Got unexpected levels %u.\n", levels);
6493 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
6494 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6495 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
6496 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6497 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
6498 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6500 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
6501 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6502 IDirect3DSurface9_Release(surface);
6503 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
6504 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6505 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
6506 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6508 IDirect3DCubeTexture9_Release(texture);
6511 static void test_cube_textures(void)
6513 IDirect3DCubeTexture9 *texture;
6514 IDirect3DDevice9 *device;
6515 IDirect3D9 *d3d;
6516 ULONG refcount;
6517 D3DCAPS9 caps;
6518 HWND window;
6519 HRESULT hr;
6521 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6522 0, 0, 640, 480, 0, 0, 0, 0);
6523 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6524 ok(!!d3d, "Failed to create a D3D object.\n");
6525 if (!(device = create_device(d3d, window, NULL)))
6527 skip("Failed to create a D3D device, skipping tests.\n");
6528 IDirect3D9_Release(d3d);
6529 DestroyWindow(window);
6530 return;
6533 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6534 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6536 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
6538 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6539 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
6540 IDirect3DCubeTexture9_Release(texture);
6541 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
6542 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
6543 IDirect3DCubeTexture9_Release(texture);
6544 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
6545 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
6546 IDirect3DCubeTexture9_Release(texture);
6548 else
6550 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6551 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
6552 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
6553 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
6554 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
6555 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
6557 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
6558 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
6559 IDirect3DCubeTexture9_Release(texture);
6561 test_cube_texture_mipmap_gen(device);
6562 test_cube_texture_levels(device);
6564 refcount = IDirect3DDevice9_Release(device);
6565 ok(!refcount, "Device has %u references left.\n", refcount);
6566 IDirect3D9_Release(d3d);
6567 DestroyWindow(window);
6570 static void test_mipmap_gen(void)
6572 D3DTEXTUREFILTERTYPE filter_type;
6573 IDirect3DTexture9 *texture;
6574 IDirect3DSurface9 *surface;
6575 IDirect3DDevice9 *device;
6576 D3DSURFACE_DESC desc;
6577 D3DLOCKED_RECT lr;
6578 IDirect3D9 *d3d;
6579 ULONG refcount;
6580 unsigned int i;
6581 DWORD levels;
6582 HWND window;
6583 HRESULT hr;
6585 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6586 ok(!!d3d, "Failed to create a D3D object.\n");
6588 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6589 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
6591 skip("No mipmap generation support, skipping tests.\n");
6592 IDirect3D9_Release(d3d);
6593 return;
6596 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6597 0, 0, 640, 480, 0, 0, 0, 0);
6598 if (!(device = create_device(d3d, window, NULL)))
6600 skip("Failed to create a D3D device, skipping tests.\n");
6601 IDirect3D9_Release(d3d);
6602 DestroyWindow(window);
6603 return;
6606 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
6607 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6608 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6609 IDirect3DTexture9_Release(texture);
6611 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
6612 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
6613 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6615 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
6616 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
6617 "Got unexpected filter_type %#x.\n", filter_type);
6618 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
6619 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6620 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
6621 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6622 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
6623 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
6624 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
6625 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6627 levels = IDirect3DTexture9_GetLevelCount(texture);
6628 ok(levels == 1, "Got unexpected levels %u.\n", levels);
6630 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
6632 surface = NULL;
6633 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
6634 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
6635 if (surface)
6636 IDirect3DSurface9_Release(surface);
6638 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
6639 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
6641 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
6642 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
6643 if (SUCCEEDED(hr))
6645 hr = IDirect3DTexture9_UnlockRect(texture, i);
6646 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6649 IDirect3DTexture9_Release(texture);
6651 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
6652 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
6653 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6654 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
6655 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
6656 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6658 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
6659 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
6660 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6661 levels = IDirect3DTexture9_GetLevelCount(texture);
6662 ok(levels == 1, "Got unexpected levels %u.\n", levels);
6663 IDirect3DTexture9_Release(texture);
6665 refcount = IDirect3DDevice9_Release(device);
6666 ok(!refcount, "Device has %u references left.\n", refcount);
6667 IDirect3D9_Release(d3d);
6668 DestroyWindow(window);
6671 static void test_filter(void)
6673 static const struct
6675 DWORD magfilter, minfilter, mipfilter;
6676 BOOL has_texture;
6677 HRESULT result;
6679 tests[] =
6681 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
6682 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
6683 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
6684 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
6685 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
6687 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
6688 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
6689 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
6690 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
6692 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
6693 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
6694 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
6695 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
6696 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
6698 IDirect3DTexture9 *texture;
6699 IDirect3DDevice9 *device;
6700 IDirect3D9 *d3d;
6701 unsigned int i;
6702 ULONG refcount;
6703 DWORD passes;
6704 HWND window;
6705 HRESULT hr;
6707 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6708 ok(!!d3d, "Failed to create a D3D object.\n");
6710 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6711 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
6713 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
6714 IDirect3D9_Release(d3d);
6715 return;
6718 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6719 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
6721 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
6722 IDirect3D9_Release(d3d);
6723 return;
6726 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6727 0, 0, 640, 480, 0, 0, 0, 0);
6728 if (!(device = create_device(d3d, window, NULL)))
6730 skip("Failed to create a D3D device, skipping tests.\n");
6731 IDirect3D9_Release(d3d);
6732 DestroyWindow(window);
6733 return;
6736 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
6737 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
6738 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6740 /* Needed for ValidateDevice(). */
6741 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6742 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6744 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
6746 if (tests[i].has_texture)
6748 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
6749 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6751 else
6753 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6754 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6757 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
6758 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
6759 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
6760 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
6761 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
6762 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
6764 passes = 0xdeadbeef;
6765 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
6766 ok(hr == tests[i].result,
6767 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
6768 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
6769 tests[i].mipfilter, tests[i].has_texture);
6770 if (SUCCEEDED(hr))
6771 ok(!!passes, "Got unexpected passes %#x.\n", passes);
6772 else
6773 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
6776 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6777 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6778 IDirect3DTexture9_Release(texture);
6780 refcount = IDirect3DDevice9_Release(device);
6781 ok(!refcount, "Device has %u references left.\n", refcount);
6782 IDirect3D9_Release(d3d);
6783 DestroyWindow(window);
6786 static void test_get_set_texture(void)
6788 const IDirect3DBaseTexture9Vtbl *texture_vtbl;
6789 IDirect3DBaseTexture9 *texture;
6790 IDirect3DDevice9 *device;
6791 IDirect3D9 *d3d;
6792 ULONG refcount;
6793 HWND window;
6794 HRESULT hr;
6796 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6797 0, 0, 640, 480, 0, 0, 0, 0);
6798 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6799 ok(!!d3d, "Failed to create a D3D object.\n");
6800 if (!(device = create_device(d3d, window, NULL)))
6802 skip("Failed to create a D3D device, skipping tests.\n");
6803 IDirect3D9_Release(d3d);
6804 DestroyWindow(window);
6805 return;
6808 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
6809 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6810 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6811 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
6812 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6813 ok(!texture, "Got unexpected texture %p.\n", texture);
6815 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8,
6816 D3DPOOL_MANAGED, (IDirect3DTexture9 **)&texture, NULL);
6817 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6818 texture_vtbl = texture->lpVtbl;
6819 texture->lpVtbl = (IDirect3DBaseTexture9Vtbl *)0xdeadbeef;
6820 hr = IDirect3DDevice9_SetTexture(device, 0, texture);
6821 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6822 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6823 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6824 texture->lpVtbl = NULL;
6825 hr = IDirect3DDevice9_SetTexture(device, 0, texture);
6826 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6827 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6828 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6829 texture->lpVtbl = texture_vtbl;
6830 IDirect3DBaseTexture9_Release(texture);
6832 refcount = IDirect3DDevice9_Release(device);
6833 ok(!refcount, "Device has %u references left.\n", refcount);
6834 IDirect3D9_Release(d3d);
6835 DestroyWindow(window);
6838 static void test_lod(void)
6840 IDirect3DTexture9 *texture;
6841 IDirect3DDevice9 *device;
6842 IDirect3D9 *d3d;
6843 ULONG refcount;
6844 HWND window;
6845 HRESULT hr;
6846 DWORD ret;
6848 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6849 0, 0, 640, 480, 0, 0, 0, 0);
6850 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6851 ok(!!d3d, "Failed to create a D3D object.\n");
6852 if (!(device = create_device(d3d, window, NULL)))
6854 skip("Failed to create a D3D device, skipping tests.\n");
6855 IDirect3D9_Release(d3d);
6856 DestroyWindow(window);
6857 return;
6860 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
6861 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6862 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6864 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
6865 * return a HRESULT, so it can't return a normal error. Instead, the call
6866 * is simply ignored. */
6867 ret = IDirect3DTexture9_SetLOD(texture, 0);
6868 ok(!ret, "Got unexpected ret %u.\n", ret);
6869 ret = IDirect3DTexture9_SetLOD(texture, 1);
6870 ok(!ret, "Got unexpected ret %u.\n", ret);
6871 ret = IDirect3DTexture9_SetLOD(texture, 2);
6872 ok(!ret, "Got unexpected ret %u.\n", ret);
6873 ret = IDirect3DTexture9_GetLOD(texture);
6874 ok(!ret, "Got unexpected ret %u.\n", ret);
6876 IDirect3DTexture9_Release(texture);
6877 refcount = IDirect3DDevice9_Release(device);
6878 ok(!refcount, "Device has %u references left.\n", refcount);
6879 IDirect3D9_Release(d3d);
6880 DestroyWindow(window);
6883 static void test_surface_get_container(void)
6885 IDirect3DTexture9 *texture = NULL;
6886 IDirect3DSurface9 *surface = NULL;
6887 IDirect3DDevice9 *device;
6888 IUnknown *container;
6889 IDirect3D9 *d3d;
6890 ULONG refcount;
6891 HWND window;
6892 HRESULT hr;
6894 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6895 0, 0, 640, 480, 0, 0, 0, 0);
6896 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6897 ok(!!d3d, "Failed to create a D3D object.\n");
6898 if (!(device = create_device(d3d, window, NULL)))
6900 skip("Failed to create a D3D device, skipping tests.\n");
6901 IDirect3D9_Release(d3d);
6902 DestroyWindow(window);
6903 return;
6906 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
6907 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6908 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6909 ok(!!texture, "Got unexpected texture %p.\n", texture);
6911 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6912 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
6913 ok(!!surface, "Got unexpected surface %p.\n", surface);
6915 /* These should work... */
6916 container = NULL;
6917 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
6918 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
6919 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6920 IUnknown_Release(container);
6922 container = NULL;
6923 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
6924 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
6925 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6926 IUnknown_Release(container);
6928 container = NULL;
6929 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
6930 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
6931 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6932 IUnknown_Release(container);
6934 container = NULL;
6935 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
6936 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
6937 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
6938 IUnknown_Release(container);
6940 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
6941 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
6942 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
6943 ok(!container, "Got unexpected container %p.\n", container);
6945 IDirect3DSurface9_Release(surface);
6946 IDirect3DTexture9_Release(texture);
6947 refcount = IDirect3DDevice9_Release(device);
6948 ok(!refcount, "Device has %u references left.\n", refcount);
6949 IDirect3D9_Release(d3d);
6950 DestroyWindow(window);
6953 static void test_surface_alignment(void)
6955 IDirect3DSurface9 *surface;
6956 IDirect3DDevice9 *device;
6957 D3DLOCKED_RECT lr;
6958 unsigned int i, j;
6959 IDirect3D9 *d3d;
6960 ULONG refcount;
6961 HWND window;
6962 HRESULT hr;
6964 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6965 0, 0, 640, 480, 0, 0, 0, 0);
6966 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6967 ok(!!d3d, "Failed to create a D3D object.\n");
6968 if (!(device = create_device(d3d, window, NULL)))
6970 skip("Failed to create a D3D device, skipping tests.\n");
6971 IDirect3D9_Release(d3d);
6972 DestroyWindow(window);
6973 return;
6976 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
6977 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
6978 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
6979 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6981 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6982 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6983 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
6984 /* Some applications also depend on the exact pitch, rather than just the
6985 * alignment. */
6986 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
6987 hr = IDirect3DSurface9_UnlockRect(surface);
6988 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6989 IDirect3DSurface9_Release(surface);
6991 for (i = 0; i < 5; ++i)
6993 IDirect3DTexture9 *texture;
6994 unsigned int level_count;
6995 D3DSURFACE_DESC desc;
6996 int expected_pitch;
6998 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
6999 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
7000 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7001 if (FAILED(hr))
7003 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
7004 continue;
7007 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
7008 for (j = 0; j < level_count; ++j)
7010 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
7011 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
7012 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7013 hr = IDirect3DTexture9_UnlockRect(texture, j);
7014 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7016 expected_pitch = ((desc.Width + 3) >> 2) << 3;
7017 if (i > 0)
7018 expected_pitch <<= 1;
7019 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
7020 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
7022 IDirect3DTexture9_Release(texture);
7025 refcount = IDirect3DDevice9_Release(device);
7026 ok(!refcount, "Device has %u references left.\n", refcount);
7027 IDirect3D9_Release(d3d);
7028 DestroyWindow(window);
7031 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
7032 * different from regular formats. This test verifies we return the correct
7033 * memory offsets. */
7034 static void test_lockrect_offset(void)
7036 static const struct
7038 D3DFORMAT format;
7039 const char *name;
7040 unsigned int block_width;
7041 unsigned int block_height;
7042 unsigned int block_size;
7044 dxt_formats[] =
7046 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
7047 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
7048 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
7049 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
7050 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
7051 {MAKEFOURCC('A','T','I','1'), "ATI1N", 1, 1, 1},
7052 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
7054 unsigned int expected_offset, offset, i;
7055 const RECT rect = {60, 60, 68, 68};
7056 IDirect3DSurface9 *surface;
7057 D3DLOCKED_RECT locked_rect;
7058 IDirect3DDevice9 *device;
7059 int expected_pitch;
7060 IDirect3D9 *d3d;
7061 ULONG refcount;
7062 HWND window;
7063 BYTE *base;
7064 HRESULT hr;
7066 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7067 0, 0, 640, 480, 0, 0, 0, 0);
7068 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7069 ok(!!d3d, "Failed to create a D3D object.\n");
7070 if (!(device = create_device(d3d, window, NULL)))
7072 skip("Failed to create a D3D device, skipping tests.\n");
7073 IDirect3D9_Release(d3d);
7074 DestroyWindow(window);
7075 return;
7078 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
7080 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7081 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
7083 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
7084 continue;
7087 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
7088 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
7089 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
7091 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
7092 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
7094 base = locked_rect.pBits;
7095 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
7096 * dxt_formats[i].block_size;
7097 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
7098 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
7100 hr = IDirect3DSurface9_UnlockRect(surface);
7101 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7103 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7104 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
7106 offset = (BYTE *)locked_rect.pBits - base;
7107 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
7108 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
7109 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
7110 offset, dxt_formats[i].name, expected_offset);
7112 hr = IDirect3DSurface9_UnlockRect(surface);
7113 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7115 IDirect3DSurface9_Release(surface);
7118 refcount = IDirect3DDevice9_Release(device);
7119 ok(!refcount, "Device has %u references left.\n", refcount);
7120 IDirect3D9_Release(d3d);
7121 DestroyWindow(window);
7124 static void test_lockrect_invalid(void)
7126 static const struct
7128 RECT rect;
7129 HRESULT win7_result;
7131 test_data[] =
7133 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
7134 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
7135 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
7136 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
7137 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
7138 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
7139 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
7140 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
7141 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
7142 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
7143 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
7144 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
7145 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
7147 static const RECT test_rect_2 = {0, 0, 8, 8};
7148 IDirect3DSurface9 *surface = NULL;
7149 D3DLOCKED_RECT locked_rect;
7150 IDirect3DDevice9 *device;
7151 IDirect3DTexture9 *texture;
7152 IDirect3DCubeTexture9 *cube_texture;
7153 IDirect3D9 *d3d;
7154 unsigned int i, r;
7155 ULONG refcount;
7156 HWND window;
7157 BYTE *base;
7158 HRESULT hr;
7159 static const struct
7161 D3DRESOURCETYPE type;
7162 D3DPOOL pool;
7163 const char *name;
7165 resources[] =
7167 {D3DRTYPE_SURFACE, D3DPOOL_SCRATCH, "scratch surface"},
7168 {D3DRTYPE_TEXTURE, D3DPOOL_MANAGED, "managed texture"},
7169 {D3DRTYPE_TEXTURE, D3DPOOL_SYSTEMMEM, "sysmem texture"},
7170 {D3DRTYPE_TEXTURE, D3DPOOL_SCRATCH, "scratch texture"},
7171 {D3DRTYPE_CUBETEXTURE, D3DPOOL_MANAGED, "default cube texture"},
7172 {D3DRTYPE_CUBETEXTURE, D3DPOOL_SYSTEMMEM, "sysmem cube texture"},
7173 {D3DRTYPE_CUBETEXTURE, D3DPOOL_SCRATCH, "scratch cube texture"},
7176 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7177 0, 0, 640, 480, 0, 0, 0, 0);
7178 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7179 ok(!!d3d, "Failed to create a D3D object.\n");
7180 if (!(device = create_device(d3d, window, NULL)))
7182 skip("Failed to create a D3D device, skipping tests.\n");
7183 IDirect3D9_Release(d3d);
7184 DestroyWindow(window);
7185 return;
7188 for (r = 0; r < sizeof(resources) / sizeof(*resources); ++r)
7190 texture = NULL;
7191 cube_texture = NULL;
7192 switch (resources[r].type)
7194 case D3DRTYPE_SURFACE:
7195 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
7196 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
7197 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, type %s.\n",
7198 hr, resources[r].name);
7199 break;
7201 case D3DRTYPE_TEXTURE:
7202 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
7203 resources[r].pool, &texture, NULL);
7204 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, type %s.\n",
7205 hr, resources[r].name);
7206 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7207 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x, type %s.\n",
7208 hr, resources[r].name);
7209 break;
7211 case D3DRTYPE_CUBETEXTURE:
7212 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
7213 resources[r].pool, &cube_texture, NULL);
7214 ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#x, type %s.\n",
7215 hr, resources[r].name);
7216 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture,
7217 D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface);
7218 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x, type %s.\n",
7219 hr, resources[r].name);
7220 break;
7222 default:
7223 break;
7226 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
7227 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, type %s.\n", hr, resources[r].name);
7228 base = locked_rect.pBits;
7229 hr = IDirect3DSurface9_UnlockRect(surface);
7230 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name);
7232 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
7234 unsigned int offset, expected_offset;
7235 const RECT *rect = &test_data[i].rect;
7237 locked_rect.pBits = (BYTE *)0xdeadbeef;
7238 locked_rect.Pitch = 0xdeadbeef;
7240 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
7241 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
7242 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
7243 * one broken. */
7244 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
7245 "Failed to lock surface with rect %s, hr %#x, type %s.\n",
7246 wine_dbgstr_rect(rect), hr, resources[r].name);
7247 if (FAILED(hr))
7248 continue;
7250 offset = (BYTE *)locked_rect.pBits - base;
7251 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
7252 ok(offset == expected_offset,
7253 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
7254 offset, expected_offset, wine_dbgstr_rect(rect), resources[r].name);
7256 hr = IDirect3DSurface9_UnlockRect(surface);
7257 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name);
7259 if (texture)
7261 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, rect, 0);
7262 ok(SUCCEEDED(hr),
7263 "Failed to lock texture with rect %s, hr %#x, type %s.\n",
7264 wine_dbgstr_rect(rect), hr, resources[r].name);
7265 if (FAILED(hr))
7266 continue;
7268 offset = (BYTE *)locked_rect.pBits - base;
7269 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
7270 ok(offset == expected_offset,
7271 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
7272 offset, expected_offset, wine_dbgstr_rect(rect), resources[r].name);
7274 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7275 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name);
7277 if (cube_texture)
7279 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
7280 &locked_rect, rect, 0);
7281 ok(SUCCEEDED(hr),
7282 "Failed to lock texture with rect %s, hr %#x, type %s.\n",
7283 wine_dbgstr_rect(rect), hr, resources[r].name);
7284 if (FAILED(hr))
7285 continue;
7287 offset = (BYTE *)locked_rect.pBits - base;
7288 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
7289 ok(offset == expected_offset,
7290 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
7291 offset, expected_offset, wine_dbgstr_rect(rect), resources[r].name);
7293 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0);
7294 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name);
7298 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
7299 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x, type %s.\n", hr, resources[r].name);
7300 locked_rect.pBits = (BYTE *)0xdeadbeef;
7301 locked_rect.Pitch = 1;
7302 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
7303 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name);
7304 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n",
7305 locked_rect.pBits, resources[r].name);
7306 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n",
7307 locked_rect.Pitch, resources[r].name);
7308 hr = IDirect3DSurface9_UnlockRect(surface);
7309 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name);
7311 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
7312 ok(hr == D3D_OK, "Got unexpected hr %#x for rect %s, type %s.\n",
7313 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
7314 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
7315 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect %s, type %s.\n",
7316 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
7317 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
7318 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect %s, type %s.\n",
7319 hr, wine_dbgstr_rect(&test_rect_2), resources[r].name);
7320 hr = IDirect3DSurface9_UnlockRect(surface);
7321 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name);
7323 IDirect3DSurface9_Release(surface);
7325 if (texture)
7327 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
7328 ok(SUCCEEDED(hr), "Failed to lock texture with rect NULL, hr %#x, type %s.\n",
7329 hr, resources[r].name);
7330 locked_rect.pBits = (BYTE *)0xdeadbeef;
7331 locked_rect.Pitch = 1;
7332 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
7333 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name);
7334 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n",
7335 locked_rect.pBits, resources[r].name);
7336 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n",
7337 locked_rect.Pitch, resources[r].name);
7338 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
7339 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name);
7340 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7341 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name);
7343 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_data[0].rect, 0);
7344 ok(hr == D3D_OK, "Got unexpected hr %#x for rect %s, type %s.\n",
7345 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
7346 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_data[0].rect, 0);
7347 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect %s, type %s.\n",
7348 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
7349 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_rect_2, 0);
7350 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect %s, type %s.\n",
7351 hr, wine_dbgstr_rect(&test_rect_2), resources[r].name);
7352 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7353 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name);
7355 IDirect3DTexture9_Release(texture);
7357 if (cube_texture)
7359 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
7360 &locked_rect, NULL, 0);
7361 ok(SUCCEEDED(hr), "Failed to lock texture with rect NULL, hr %#x, type %s.\n",
7362 hr, resources[r].name);
7363 locked_rect.pBits = (BYTE *)0xdeadbeef;
7364 locked_rect.Pitch = 1;
7365 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
7366 &locked_rect, NULL, 0);
7367 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name);
7368 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n",
7369 locked_rect.pBits, resources[r].name);
7370 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n",
7371 locked_rect.Pitch, resources[r].name);
7372 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
7373 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name);
7374 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0);
7375 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name);
7377 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
7378 &locked_rect, &test_data[0].rect, 0);
7379 ok(hr == D3D_OK, "Got unexpected hr %#x for rect %s, type %s.\n",
7380 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
7381 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
7382 &locked_rect, &test_data[0].rect, 0);
7383 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect %s, type %s.\n",
7384 hr, wine_dbgstr_rect(&test_data[0].rect), resources[r].name);
7385 hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0,
7386 &locked_rect, &test_rect_2, 0);
7387 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect %s, type %s.\n",
7388 hr, wine_dbgstr_rect(&test_rect_2), resources[r].name);
7389 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0);
7390 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name);
7392 IDirect3DCubeTexture9_Release(cube_texture);
7396 refcount = IDirect3DDevice9_Release(device);
7397 ok(!refcount, "Device has %u references left.\n", refcount);
7398 IDirect3D9_Release(d3d);
7399 DestroyWindow(window);
7402 static void test_private_data(void)
7404 ULONG refcount, expected_refcount;
7405 IDirect3DTexture9 *texture;
7406 IDirect3DSurface9 *surface, *surface2;
7407 IDirect3DDevice9 *device;
7408 IDirect3D9 *d3d;
7409 IUnknown *ptr;
7410 HWND window;
7411 HRESULT hr;
7412 DWORD size;
7413 DWORD data[4] = {1, 2, 3, 4};
7414 static const GUID d3d9_private_data_test_guid2 =
7416 0x2e5afac2,
7417 0x87b5,
7418 0x4c10,
7419 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
7422 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7423 0, 0, 640, 480, 0, 0, 0, 0);
7424 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7425 ok(!!d3d, "Failed to create a D3D object.\n");
7426 if (!(device = create_device(d3d, window, NULL)))
7428 skip("Failed to create a D3D device, skipping tests.\n");
7429 IDirect3D9_Release(d3d);
7430 DestroyWindow(window);
7431 return;
7434 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
7435 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
7436 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
7438 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
7439 device, 0, D3DSPD_IUNKNOWN);
7440 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7441 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
7442 device, 5, D3DSPD_IUNKNOWN);
7443 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7444 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
7445 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
7446 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7448 /* A failing SetPrivateData call does not clear the old data with the same tag. */
7449 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
7450 sizeof(device), D3DSPD_IUNKNOWN);
7451 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
7452 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
7453 sizeof(device) * 2, D3DSPD_IUNKNOWN);
7454 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7455 size = sizeof(ptr);
7456 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
7457 ok(SUCCEEDED(hr), "Failed to get private data, hr %#x.\n", hr);
7458 IUnknown_Release(ptr);
7459 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
7460 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
7462 refcount = get_refcount((IUnknown *)device);
7463 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
7464 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
7465 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7466 expected_refcount = refcount + 1;
7467 refcount = get_refcount((IUnknown *)device);
7468 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
7469 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
7470 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7471 expected_refcount = refcount - 1;
7472 refcount = get_refcount((IUnknown *)device);
7473 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
7475 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
7476 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
7477 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7478 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
7479 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
7480 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7481 refcount = get_refcount((IUnknown *)device);
7482 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
7484 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
7485 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
7486 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7487 size = 2 * sizeof(ptr);
7488 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
7489 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7490 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
7491 expected_refcount = refcount + 2;
7492 refcount = get_refcount((IUnknown *)device);
7493 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
7494 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
7495 IUnknown_Release(ptr);
7496 expected_refcount--;
7498 ptr = (IUnknown *)0xdeadbeef;
7499 size = 1;
7500 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
7501 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7502 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
7503 size = 2 * sizeof(ptr);
7504 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
7505 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7506 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
7507 refcount = get_refcount((IUnknown *)device);
7508 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
7509 size = 1;
7510 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
7511 ok(hr == D3DERR_MOREDATA, "Got unexpected hr %#x.\n", hr);
7512 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
7513 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
7514 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, NULL, NULL);
7515 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
7516 size = 0xdeadbabe;
7517 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, &ptr, &size);
7518 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
7519 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
7520 ok(size == 0xdeadbabe, "Got unexpected size %u.\n", size);
7521 /* GetPrivateData with size = NULL causes an access violation on Windows if the
7522 * requested data exists. */
7524 /* Destroying the surface frees the held reference. */
7525 IDirect3DSurface9_Release(surface);
7526 expected_refcount = refcount - 2;
7527 refcount = get_refcount((IUnknown *)device);
7528 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
7530 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH,
7531 &texture, NULL);
7532 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7533 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7534 ok(SUCCEEDED(hr), "Failed to get texture level 0, hr %#x.\n", hr);
7535 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
7536 ok(SUCCEEDED(hr), "Failed to get texture level 1, hr %#x.\n", hr);
7538 hr = IDirect3DTexture9_SetPrivateData(texture, &d3d9_private_data_test_guid, data, sizeof(data), 0);
7539 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
7541 memset(data, 0, sizeof(data));
7542 size = sizeof(data);
7543 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, data, &size);
7544 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
7545 hr = IDirect3DTexture9_GetPrivateData(texture, &d3d9_private_data_test_guid, data, &size);
7546 ok(SUCCEEDED(hr), "Failed to get private data, hr %#x.\n", hr);
7547 ok(data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4,
7548 "Got unexpected private data: %u, %u, %u, %u.\n", data[0], data[1], data[2], data[3]);
7550 hr = IDirect3DTexture9_FreePrivateData(texture, &d3d9_private_data_test_guid);
7551 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
7553 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, data, sizeof(data), 0);
7554 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
7555 hr = IDirect3DSurface9_GetPrivateData(surface2, &d3d9_private_data_test_guid, data, &size);
7556 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
7558 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
7559 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
7561 IDirect3DSurface9_Release(surface2);
7562 IDirect3DSurface9_Release(surface);
7563 IDirect3DTexture9_Release(texture);
7565 refcount = IDirect3DDevice9_Release(device);
7566 ok(!refcount, "Device has %u references left.\n", refcount);
7567 IDirect3D9_Release(d3d);
7568 DestroyWindow(window);
7571 static void test_getdc(void)
7573 static const struct
7575 const char *name;
7576 D3DFORMAT format;
7577 unsigned int bit_count;
7578 DWORD mask_r, mask_g, mask_b;
7579 BOOL getdc_supported;
7581 testdata[] =
7583 {"A8R8G8B8", D3DFMT_A8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, TRUE },
7584 {"X8R8G8B8", D3DFMT_X8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, TRUE },
7585 {"R5G6B5", D3DFMT_R5G6B5, 16, 0x0000f800, 0x000007e0, 0x0000001f, TRUE },
7586 {"X1R5G5B5", D3DFMT_X1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, TRUE },
7587 {"A1R5G5B5", D3DFMT_A1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, TRUE },
7588 {"R8G8B8", D3DFMT_R8G8B8, 24, 0x00000000, 0x00000000, 0x00000000, TRUE },
7589 {"A2R10G10B10", D3DFMT_A2R10G10B10, 32, 0x00000000, 0x00000000, 0x00000000, FALSE},
7590 {"V8U8", D3DFMT_V8U8, 16, 0x00000000, 0x00000000, 0x00000000, FALSE},
7591 {"Q8W8V8U8", D3DFMT_Q8W8V8U8, 32, 0x00000000, 0x00000000, 0x00000000, FALSE},
7592 {"A8B8G8R8", D3DFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, FALSE},
7593 {"X8B8G8R8", D3DFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, FALSE},
7594 {"R3G3B2", D3DFMT_R3G3B2, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
7595 {"P8", D3DFMT_P8, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
7596 {"L8", D3DFMT_L8, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
7597 {"A8L8", D3DFMT_A8L8, 16, 0x00000000, 0x00000000, 0x00000000, FALSE},
7598 {"DXT1", D3DFMT_DXT1, 4, 0x00000000, 0x00000000, 0x00000000, FALSE},
7599 {"DXT2", D3DFMT_DXT2, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
7600 {"DXT3", D3DFMT_DXT3, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
7601 {"DXT4", D3DFMT_DXT4, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
7602 {"DXT5", D3DFMT_DXT5, 8, 0x00000000, 0x00000000, 0x00000000, FALSE},
7604 IDirect3DSurface9 *surface, *surface2;
7605 IDirect3DCubeTexture9 *cube_texture;
7606 IDirect3DTexture9 *texture;
7607 IDirect3DDevice9 *device;
7608 D3DLOCKED_RECT map_desc;
7609 IDirect3D9 *d3d;
7610 unsigned int i;
7611 ULONG refcount;
7612 HWND window;
7613 HDC dc, dc2;
7614 HRESULT hr;
7616 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7617 0, 0, 640, 480, 0, 0, 0, 0);
7618 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7619 ok(!!d3d, "Failed to create a D3D object.\n");
7620 if (!(device = create_device(d3d, window, NULL)))
7622 skip("Failed to create a D3D device, skipping tests.\n");
7623 IDirect3D9_Release(d3d);
7624 DestroyWindow(window);
7625 return;
7628 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
7630 texture = NULL;
7631 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
7632 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
7633 if (FAILED(hr))
7635 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
7636 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
7637 if (FAILED(hr))
7639 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
7640 continue;
7642 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7643 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
7646 dc = (void *)0x1234;
7647 hr = IDirect3DSurface9_GetDC(surface, &dc);
7648 if (testdata[i].getdc_supported)
7649 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7650 else
7651 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7653 if (SUCCEEDED(hr))
7655 unsigned int width_bytes;
7656 DIBSECTION dib;
7657 HBITMAP bitmap;
7658 DWORD type;
7659 int size;
7661 type = GetObjectType(dc);
7662 ok(type == OBJ_MEMDC, "Got unexpected object type %#x for format %s.\n", type, testdata[i].name);
7663 bitmap = GetCurrentObject(dc, OBJ_BITMAP);
7664 type = GetObjectType(bitmap);
7665 ok(type == OBJ_BITMAP, "Got unexpected object type %#x for format %s.\n", type, testdata[i].name);
7667 size = GetObjectA(bitmap, sizeof(dib), &dib);
7668 ok(size == sizeof(dib), "Got unexpected size %d for format %s.\n", size, testdata[i].name);
7669 ok(!dib.dsBm.bmType, "Got unexpected type %#x for format %s.\n",
7670 dib.dsBm.bmType, testdata[i].name);
7671 ok(dib.dsBm.bmWidth == 64, "Got unexpected width %d for format %s.\n",
7672 dib.dsBm.bmWidth, testdata[i].name);
7673 ok(dib.dsBm.bmHeight == 64, "Got unexpected height %d for format %s.\n",
7674 dib.dsBm.bmHeight, testdata[i].name);
7675 width_bytes = ((dib.dsBm.bmWidth * testdata[i].bit_count + 31) >> 3) & ~3;
7676 ok(dib.dsBm.bmWidthBytes == width_bytes, "Got unexpected width bytes %d for format %s.\n",
7677 dib.dsBm.bmWidthBytes, testdata[i].name);
7678 ok(dib.dsBm.bmPlanes == 1, "Got unexpected plane count %d for format %s.\n",
7679 dib.dsBm.bmPlanes, testdata[i].name);
7680 ok(dib.dsBm.bmBitsPixel == testdata[i].bit_count,
7681 "Got unexpected bit count %d for format %s.\n",
7682 dib.dsBm.bmBitsPixel, testdata[i].name);
7683 ok(!!dib.dsBm.bmBits, "Got unexpected bits %p for format %s.\n",
7684 dib.dsBm.bmBits, testdata[i].name);
7686 ok(dib.dsBmih.biSize == sizeof(dib.dsBmih), "Got unexpected size %u for format %s.\n",
7687 dib.dsBmih.biSize, testdata[i].name);
7688 ok(dib.dsBmih.biWidth == 64, "Got unexpected width %d for format %s.\n",
7689 dib.dsBmih.biHeight, testdata[i].name);
7690 ok(dib.dsBmih.biHeight == 64, "Got unexpected height %d for format %s.\n",
7691 dib.dsBmih.biHeight, testdata[i].name);
7692 ok(dib.dsBmih.biPlanes == 1, "Got unexpected plane count %u for format %s.\n",
7693 dib.dsBmih.biPlanes, testdata[i].name);
7694 ok(dib.dsBmih.biBitCount == testdata[i].bit_count, "Got unexpected bit count %u for format %s.\n",
7695 dib.dsBmih.biBitCount, testdata[i].name);
7696 ok(dib.dsBmih.biCompression == (testdata[i].bit_count == 16 ? BI_BITFIELDS : BI_RGB),
7697 "Got unexpected compression %#x for format %s.\n",
7698 dib.dsBmih.biCompression, testdata[i].name);
7699 ok(!dib.dsBmih.biSizeImage, "Got unexpected image size %u for format %s.\n",
7700 dib.dsBmih.biSizeImage, testdata[i].name);
7701 ok(!dib.dsBmih.biXPelsPerMeter, "Got unexpected horizontal resolution %d for format %s.\n",
7702 dib.dsBmih.biXPelsPerMeter, testdata[i].name);
7703 ok(!dib.dsBmih.biYPelsPerMeter, "Got unexpected vertical resolution %d for format %s.\n",
7704 dib.dsBmih.biYPelsPerMeter, testdata[i].name);
7705 ok(!dib.dsBmih.biClrUsed, "Got unexpected used colour count %u for format %s.\n",
7706 dib.dsBmih.biClrUsed, testdata[i].name);
7707 ok(!dib.dsBmih.biClrImportant, "Got unexpected important colour count %u for format %s.\n",
7708 dib.dsBmih.biClrImportant, testdata[i].name);
7710 if (dib.dsBmih.biCompression == BI_BITFIELDS)
7712 ok(dib.dsBitfields[0] == testdata[i].mask_r && dib.dsBitfields[1] == testdata[i].mask_g
7713 && dib.dsBitfields[2] == testdata[i].mask_b,
7714 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
7715 dib.dsBitfields[0], dib.dsBitfields[1], dib.dsBitfields[2], testdata[i].name);
7717 else
7719 ok(!dib.dsBitfields[0] && !dib.dsBitfields[1] && !dib.dsBitfields[2],
7720 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
7721 dib.dsBitfields[0], dib.dsBitfields[1], dib.dsBitfields[2], testdata[i].name);
7723 ok(!dib.dshSection, "Got unexpected section %p for format %s.\n", dib.dshSection, testdata[i].name);
7724 ok(!dib.dsOffset, "Got unexpected offset %u for format %s.\n", dib.dsOffset, testdata[i].name);
7726 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7727 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
7729 else
7731 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
7734 IDirect3DSurface9_Release(surface);
7735 if (texture)
7736 IDirect3DTexture9_Release(texture);
7738 if (!testdata[i].getdc_supported)
7739 continue;
7741 if (FAILED(hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
7742 testdata[i].format, D3DPOOL_MANAGED, &cube_texture, NULL)))
7744 skip("Failed to create cube texture for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
7745 continue;
7748 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
7749 ok(SUCCEEDED(hr), "Failed to get cube surface for format %s, hr %#x.\n", testdata[i].name, hr);
7750 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_Y, 2, &surface2);
7751 ok(SUCCEEDED(hr), "Failed to get cube surface for format %s, hr %#x.\n", testdata[i].name, hr);
7753 hr = IDirect3DSurface9_GetDC(surface, &dc);
7754 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7755 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7756 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7757 hr = IDirect3DSurface9_GetDC(surface2, &dc);
7758 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7759 hr = IDirect3DSurface9_ReleaseDC(surface2, dc);
7760 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7762 hr = IDirect3DSurface9_GetDC(surface, &dc);
7763 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7764 dc2 = (void *)0x1234;
7765 hr = IDirect3DSurface9_GetDC(surface, &dc2);
7766 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7767 ok(dc2 == (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc, testdata[i].name);
7768 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7769 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7770 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7771 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7773 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
7774 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#x.\n", testdata[i].name, hr);
7775 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
7776 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7777 hr = IDirect3DSurface9_UnlockRect(surface);
7778 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7779 hr = IDirect3DSurface9_UnlockRect(surface);
7780 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7782 hr = IDirect3DSurface9_GetDC(surface, &dc);
7783 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7784 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
7785 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7786 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7787 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7789 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
7790 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#x.\n", testdata[i].name, hr);
7791 hr = IDirect3DSurface9_GetDC(surface, &dc);
7792 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7793 hr = IDirect3DSurface9_UnlockRect(surface);
7794 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7796 hr = IDirect3DSurface9_GetDC(surface, &dc);
7797 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7798 hr = IDirect3DSurface9_GetDC(surface2, &dc2);
7799 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7800 hr = IDirect3DSurface9_ReleaseDC(surface2, dc2);
7801 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7802 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7803 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7805 hr = IDirect3DSurface9_GetDC(surface2, &dc);
7806 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7807 hr = IDirect3DSurface9_GetDC(surface, &dc2);
7808 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7809 hr = IDirect3DSurface9_ReleaseDC(surface, dc2);
7810 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7811 hr = IDirect3DSurface9_ReleaseDC(surface2, dc);
7812 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7814 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
7815 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#x.\n", testdata[i].name, hr);
7816 hr = IDirect3DSurface9_LockRect(surface2, &map_desc, NULL, D3DLOCK_READONLY);
7817 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#x.\n", testdata[i].name, hr);
7818 hr = IDirect3DSurface9_UnlockRect(surface2);
7819 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7820 hr = IDirect3DSurface9_UnlockRect(surface);
7821 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7823 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
7824 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#x.\n", testdata[i].name, hr);
7825 hr = IDirect3DSurface9_GetDC(surface, &dc);
7826 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7827 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7828 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7829 hr = IDirect3DSurface9_UnlockRect(surface);
7830 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7832 hr = IDirect3DSurface9_LockRect(surface2, &map_desc, NULL, D3DLOCK_READONLY);
7833 ok(SUCCEEDED(hr), "Failed to map surface for format %s, hr %#x.\n", testdata[i].name, hr);
7834 hr = IDirect3DSurface9_GetDC(surface, &dc);
7835 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7836 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7837 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7838 hr = IDirect3DSurface9_UnlockRect(surface2);
7839 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7841 hr = IDirect3DSurface9_GetDC(surface, &dc);
7842 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7843 hr = IDirect3DSurface9_LockRect(surface2, &map_desc, NULL, D3DLOCK_READONLY);
7844 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7845 hr = IDirect3DSurface9_UnlockRect(surface2);
7846 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7847 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7848 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7850 hr = IDirect3DSurface9_GetDC(surface2, &dc);
7851 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7852 hr = IDirect3DSurface9_LockRect(surface, &map_desc, NULL, D3DLOCK_READONLY);
7853 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7854 hr = IDirect3DSurface9_UnlockRect(surface);
7855 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7856 hr = IDirect3DSurface9_ReleaseDC(surface2, dc);
7857 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7859 hr = IDirect3DSurface9_UnlockRect(surface);
7860 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7861 hr = IDirect3DSurface9_GetDC(surface2, &dc);
7862 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7863 hr = IDirect3DSurface9_UnlockRect(surface);
7864 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7865 hr = IDirect3DSurface9_ReleaseDC(surface2, dc);
7866 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7867 hr = IDirect3DSurface9_UnlockRect(surface);
7868 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7870 hr = IDirect3DSurface9_UnlockRect(surface2);
7871 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7872 hr = IDirect3DSurface9_GetDC(surface, &dc);
7873 ok(SUCCEEDED(hr), "Failed to get DC for format %s, hr %#x.\n", testdata[i].name, hr);
7874 hr = IDirect3DSurface9_UnlockRect(surface2);
7875 ok(SUCCEEDED(hr), "Failed to unmap surface for format %s, hr %#x.\n", testdata[i].name, hr);
7876 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
7877 ok(SUCCEEDED(hr), "Failed to release DC for format %s, hr %#x.\n", testdata[i].name, hr);
7878 hr = IDirect3DSurface9_UnlockRect(surface2);
7879 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
7881 IDirect3DSurface9_Release(surface2);
7882 IDirect3DSurface9_Release(surface);
7883 IDirect3DCubeTexture9_Release(cube_texture);
7886 refcount = IDirect3DDevice9_Release(device);
7887 ok(!refcount, "Device has %u references left.\n", refcount);
7888 IDirect3D9_Release(d3d);
7889 DestroyWindow(window);
7892 static void test_surface_dimensions(void)
7894 IDirect3DSurface9 *surface;
7895 IDirect3DDevice9 *device;
7896 IDirect3D9 *d3d;
7897 ULONG refcount;
7898 HWND window;
7899 HRESULT hr;
7901 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7902 0, 0, 640, 480, 0, 0, 0, 0);
7903 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7904 ok(!!d3d, "Failed to create a D3D object.\n");
7905 if (!(device = create_device(d3d, window, NULL)))
7907 skip("Failed to create a D3D device, skipping tests.\n");
7908 IDirect3D9_Release(d3d);
7909 DestroyWindow(window);
7910 return;
7913 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
7914 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
7915 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7916 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
7917 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
7918 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7920 refcount = IDirect3DDevice9_Release(device);
7921 ok(!refcount, "Device has %u references left.\n", refcount);
7922 IDirect3D9_Release(d3d);
7923 DestroyWindow(window);
7926 static void test_surface_format_null(void)
7928 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
7929 IDirect3DTexture9 *texture;
7930 IDirect3DSurface9 *surface;
7931 IDirect3DSurface9 *rt, *ds;
7932 D3DLOCKED_RECT locked_rect;
7933 IDirect3DDevice9 *device;
7934 D3DSURFACE_DESC desc;
7935 IDirect3D9 *d3d;
7936 ULONG refcount;
7937 HWND window;
7938 HRESULT hr;
7940 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7941 ok(!!d3d, "Failed to create a D3D object.\n");
7943 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7944 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
7945 if (hr != D3D_OK)
7947 skip("No D3DFMT_NULL support, skipping test.\n");
7948 IDirect3D9_Release(d3d);
7949 return;
7952 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7953 0, 0, 640, 480, 0, 0, 0, 0);
7954 if (!(device = create_device(d3d, window, NULL)))
7956 skip("Failed to create a D3D device, skipping tests.\n");
7957 IDirect3D9_Release(d3d);
7958 DestroyWindow(window);
7959 return;
7962 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7963 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
7964 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
7966 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7967 D3DFMT_NULL, D3DFMT_D24S8);
7968 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
7970 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
7971 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
7972 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7974 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
7975 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
7977 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
7978 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
7980 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
7981 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
7983 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7984 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7986 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
7987 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
7989 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
7990 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
7992 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
7993 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7995 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
7996 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
7998 IDirect3DSurface9_Release(rt);
7999 IDirect3DSurface9_Release(ds);
8001 hr = IDirect3DSurface9_GetDesc(surface, &desc);
8002 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
8003 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
8004 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
8006 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
8007 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
8008 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
8009 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
8011 hr = IDirect3DSurface9_UnlockRect(surface);
8012 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8014 IDirect3DSurface9_Release(surface);
8016 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
8017 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
8018 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8019 IDirect3DTexture9_Release(texture);
8021 refcount = IDirect3DDevice9_Release(device);
8022 ok(!refcount, "Device has %u references left.\n", refcount);
8023 IDirect3D9_Release(d3d);
8024 DestroyWindow(window);
8027 static void test_surface_double_unlock(void)
8029 static const D3DPOOL pools[] =
8031 D3DPOOL_DEFAULT,
8032 D3DPOOL_SCRATCH,
8033 D3DPOOL_SYSTEMMEM,
8035 IDirect3DSurface9 *surface;
8036 IDirect3DDevice9 *device;
8037 D3DLOCKED_RECT lr;
8038 IDirect3D9 *d3d;
8039 unsigned int i;
8040 ULONG refcount;
8041 HWND window;
8042 HRESULT hr;
8044 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8045 0, 0, 640, 480, 0, 0, 0, 0);
8046 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8047 ok(!!d3d, "Failed to create a D3D object.\n");
8048 if (!(device = create_device(d3d, window, NULL)))
8050 skip("Failed to create a D3D device, skipping tests.\n");
8051 IDirect3D9_Release(d3d);
8052 DestroyWindow(window);
8053 return;
8056 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
8058 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
8059 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
8060 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
8062 hr = IDirect3DSurface9_UnlockRect(surface);
8063 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
8064 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
8065 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
8066 hr = IDirect3DSurface9_UnlockRect(surface);
8067 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
8068 hr = IDirect3DSurface9_UnlockRect(surface);
8069 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
8071 IDirect3DSurface9_Release(surface);
8074 refcount = IDirect3DDevice9_Release(device);
8075 ok(!refcount, "Device has %u references left.\n", refcount);
8076 IDirect3D9_Release(d3d);
8077 DestroyWindow(window);
8080 static void test_surface_blocks(void)
8082 static const struct
8084 D3DFORMAT fmt;
8085 const char *name;
8086 unsigned int block_width;
8087 unsigned int block_height;
8088 BOOL broken;
8089 BOOL create_size_checked, core_fmt;
8091 formats[] =
8093 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE, TRUE, TRUE },
8094 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE, TRUE, TRUE },
8095 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE, TRUE, TRUE },
8096 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE, TRUE, TRUE },
8097 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE, TRUE, TRUE },
8098 /* ATI1N and ATI2N have 2x2 blocks on all AMD cards and Geforce 7 cards,
8099 * which doesn't match the format spec. On newer Nvidia cards
8100 * they have the correct 4x4 block size */
8101 {MAKEFOURCC('A','T','I','1'), "ATI1N", 4, 4, TRUE, FALSE, FALSE},
8102 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE, FALSE, FALSE},
8103 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE, FALSE, TRUE },
8104 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE, FALSE, TRUE },
8106 static const struct
8108 D3DPOOL pool;
8109 const char *name;
8110 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
8111 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
8112 BOOL success;
8114 pools[] =
8116 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
8117 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
8118 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
8119 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
8121 static struct
8123 D3DRESOURCETYPE rtype;
8124 const char *type_name;
8125 D3DPOOL pool;
8126 const char *pool_name;
8127 BOOL need_driver_support, need_runtime_support;
8129 create_tests[] =
8131 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
8132 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, TRUE },
8133 /* Managed offscreen plain surfaces are not supported */
8134 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
8136 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
8137 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
8138 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
8139 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
8141 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
8142 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
8143 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
8144 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
8146 IDirect3DTexture9 *texture;
8147 IDirect3DCubeTexture9 *cube_texture;
8148 IDirect3DSurface9 *surface;
8149 D3DLOCKED_RECT locked_rect;
8150 IDirect3DDevice9 *device;
8151 unsigned int i, j, k, w, h;
8152 BOOL surface_only;
8153 IDirect3D9 *d3d;
8154 ULONG refcount;
8155 HWND window;
8156 HRESULT hr;
8157 RECT rect;
8158 BOOL tex_pow2, cube_pow2;
8159 D3DCAPS9 caps;
8160 static const RECT invalid[] =
8162 {60, 60, 60, 68}, /* 0 height */
8163 {60, 60, 68, 60}, /* 0 width */
8164 {68, 60, 60, 68}, /* left > right */
8165 {60, 68, 68, 60}, /* top > bottom */
8166 {-8, 60, 0, 68}, /* left < surface */
8167 {60, -8, 68, 0}, /* top < surface */
8168 {-16, 60, -8, 68}, /* right < surface */
8169 {60, -16, 68, -8}, /* bottom < surface */
8170 {60, 60, 136, 68}, /* right > surface */
8171 {60, 60, 68, 136}, /* bottom > surface */
8172 {136, 60, 144, 68}, /* left > surface */
8173 {60, 136, 68, 144}, /* top > surface */
8176 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8177 0, 0, 640, 480, 0, 0, 0, 0);
8178 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8179 ok(!!d3d, "Failed to create a D3D object.\n");
8180 if (!(device = create_device(d3d, window, NULL)))
8182 skip("Failed to create a D3D device, skipping tests.\n");
8183 IDirect3D9_Release(d3d);
8184 DestroyWindow(window);
8185 return;
8188 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8189 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8190 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
8191 if (tex_pow2)
8192 tex_pow2 = !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
8193 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
8195 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
8197 BOOL tex_support, cube_support, surface_support, format_known, dynamic_tex_support;
8199 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8200 0, D3DRTYPE_TEXTURE, formats[i].fmt);
8201 tex_support = SUCCEEDED(hr);
8202 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8203 0, D3DRTYPE_CUBETEXTURE, formats[i].fmt);
8204 cube_support = SUCCEEDED(hr);
8205 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8206 0, D3DRTYPE_SURFACE, formats[i].fmt);
8207 surface_support = SUCCEEDED(hr);
8209 /* Scratch pool in general allows texture creation even if the driver does
8210 * not support the format. If the format is an extension format that is not
8211 * known to the runtime, like ATI2N, some driver support is required for
8212 * this to work.
8214 * It is also possible that Windows Vista and Windows 7 d3d9 runtimes know
8215 * about ATI2N. I cannot check this because all my Vista+ machines support
8216 * ATI2N in hardware, but none of my WinXP machines do. */
8217 format_known = tex_support || cube_support || surface_support;
8219 for (w = 1; w <= 8; w++)
8221 for (h = 1; h <= 8; h++)
8223 BOOL block_aligned = TRUE;
8224 BOOL size_is_pow2;
8226 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
8227 block_aligned = FALSE;
8229 size_is_pow2 = !(w & (w - 1) || h & (h - 1));
8231 for (j = 0; j < sizeof(create_tests) / sizeof(*create_tests); j++)
8233 BOOL support, pow2;
8234 HRESULT expect_hr;
8235 BOOL may_succeed = FALSE;
8236 IUnknown **check_null;
8238 if (!formats[i].core_fmt)
8240 /* AMD warns against creating ATI2N textures smaller than
8241 * the block size because the runtime cannot calculate the
8242 * correct texture size. Generalize this for all extension
8243 * formats. */
8244 if (w < formats[i].block_width || h < formats[i].block_height)
8245 continue;
8248 texture = (IDirect3DTexture9 *)0xdeadbeef;
8249 cube_texture = (IDirect3DCubeTexture9 *)0xdeadbeef;
8250 surface = (IDirect3DSurface9 *)0xdeadbeef;
8252 switch (create_tests[j].rtype)
8254 case D3DRTYPE_TEXTURE:
8255 check_null = (IUnknown **)&texture;
8256 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1, 0,
8257 formats[i].fmt, create_tests[j].pool, &texture, NULL);
8258 support = tex_support;
8259 pow2 = tex_pow2;
8260 break;
8262 case D3DRTYPE_CUBETEXTURE:
8263 if (w != h)
8264 continue;
8265 check_null = (IUnknown **)&cube_texture;
8266 hr = IDirect3DDevice9_CreateCubeTexture(device, w, 1, 0,
8267 formats[i].fmt, create_tests[j].pool, &cube_texture, NULL);
8268 support = cube_support;
8269 pow2 = cube_pow2;
8270 break;
8272 case D3DRTYPE_SURFACE:
8273 check_null = (IUnknown **)&surface;
8274 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, w, h,
8275 formats[i].fmt, create_tests[j].pool, &surface, NULL);
8276 support = surface_support;
8277 pow2 = FALSE;
8278 break;
8280 default:
8281 check_null = NULL;
8282 pow2 = FALSE;
8283 support = FALSE;
8284 break;
8287 if (create_tests[j].need_driver_support && !support)
8288 expect_hr = D3DERR_INVALIDCALL;
8289 else if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !format_known)
8290 expect_hr = D3DERR_INVALIDCALL;
8291 else if (formats[i].create_size_checked && !block_aligned)
8292 expect_hr = D3DERR_INVALIDCALL;
8293 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
8294 expect_hr = D3DERR_INVALIDCALL;
8295 else
8296 expect_hr = D3D_OK;
8298 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
8299 * does not support it. Accept scratch creation of extension formats on
8300 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
8301 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
8302 * support it. */
8303 if (!formats[i].core_fmt && !format_known && FAILED(expect_hr))
8304 may_succeed = TRUE;
8306 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
8307 "Got unexpected hr %#x for format %s, pool %s, type %s, size %ux%u.\n",
8308 hr, formats[i].name, create_tests[j].pool_name, create_tests[j].type_name, w, h);
8309 if (FAILED(hr))
8310 ok(*check_null == NULL, "Got object ptr %p, expected NULL.\n", *check_null);
8311 else
8312 IUnknown_Release(*check_null);
8317 surface_only = FALSE;
8318 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
8319 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt);
8320 dynamic_tex_support = SUCCEEDED(hr);
8321 if (!dynamic_tex_support)
8323 if (!surface_support)
8325 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
8326 continue;
8328 surface_only = TRUE;
8331 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
8333 switch (pools[j].pool)
8335 case D3DPOOL_SYSTEMMEM:
8336 case D3DPOOL_MANAGED:
8337 if (surface_only)
8338 continue;
8339 /* Fall through */
8340 case D3DPOOL_DEFAULT:
8341 if (surface_only)
8343 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
8344 formats[i].fmt, pools[j].pool, &surface, NULL);
8345 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8347 else
8349 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
8350 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
8351 formats[i].fmt, pools[j].pool, &texture, NULL);
8352 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8353 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8354 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8355 IDirect3DTexture9_Release(texture);
8357 break;
8359 case D3DPOOL_SCRATCH:
8360 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
8361 formats[i].fmt, pools[j].pool, &surface, NULL);
8362 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8363 break;
8365 default:
8366 break;
8369 if (formats[i].block_width > 1)
8371 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
8372 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
8373 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
8374 "Partial block lock %s, expected %s, format %s, pool %s.\n",
8375 SUCCEEDED(hr) ? "succeeded" : "failed",
8376 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
8377 if (SUCCEEDED(hr))
8379 hr = IDirect3DSurface9_UnlockRect(surface);
8380 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8383 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
8384 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
8385 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
8386 "Partial block lock %s, expected %s, format %s, pool %s.\n",
8387 SUCCEEDED(hr) ? "succeeded" : "failed",
8388 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
8389 if (SUCCEEDED(hr))
8391 hr = IDirect3DSurface9_UnlockRect(surface);
8392 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8396 if (formats[i].block_height > 1)
8398 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
8399 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
8400 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
8401 "Partial block lock %s, expected %s, format %s, pool %s.\n",
8402 SUCCEEDED(hr) ? "succeeded" : "failed",
8403 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
8404 if (SUCCEEDED(hr))
8406 hr = IDirect3DSurface9_UnlockRect(surface);
8407 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8410 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
8411 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
8412 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
8413 "Partial block lock %s, expected %s, format %s, pool %s.\n",
8414 SUCCEEDED(hr) ? "succeeded" : "failed",
8415 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
8416 if (SUCCEEDED(hr))
8418 hr = IDirect3DSurface9_UnlockRect(surface);
8419 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8423 for (k = 0; k < sizeof(invalid) / sizeof(*invalid); ++k)
8425 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &invalid[k], 0);
8426 ok(FAILED(hr) == !pools[j].success, "Invalid lock %s(%#x), expected %s, format %s, pool %s, case %u.\n",
8427 SUCCEEDED(hr) ? "succeeded" : "failed", hr, pools[j].success ? "success" : "failure",
8428 formats[i].name, pools[j].name, k);
8429 if (SUCCEEDED(hr))
8431 hr = IDirect3DSurface9_UnlockRect(surface);
8432 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8436 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
8437 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
8438 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
8439 hr = IDirect3DSurface9_UnlockRect(surface);
8440 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8442 IDirect3DSurface9_Release(surface);
8445 if (!dynamic_tex_support)
8447 skip("Dynamic %s textures not supported, skipping mipmap test.\n", formats[i].name);
8448 continue;
8451 if (formats[i].block_width == 1 && formats[i].block_height == 1)
8452 continue;
8453 if (!formats[i].core_fmt)
8454 continue;
8456 hr = IDirect3DDevice9_CreateTexture(device, formats[i].block_width, formats[i].block_height, 2,
8457 D3DUSAGE_DYNAMIC, formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
8458 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, format %s.\n", hr, formats[i].name);
8460 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, NULL, 0);
8461 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
8462 hr = IDirect3DTexture9_UnlockRect(texture, 1);
8463 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
8465 SetRect(&rect, 0, 0, formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1,
8466 formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1);
8467 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
8468 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
8469 hr = IDirect3DTexture9_UnlockRect(texture, 1);
8470 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
8472 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
8473 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
8474 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8475 if (SUCCEEDED(hr))
8476 IDirect3DTexture9_UnlockRect(texture, 1);
8478 IDirect3DTexture9_Release(texture);
8481 refcount = IDirect3DDevice9_Release(device);
8482 ok(!refcount, "Device has %u references left.\n", refcount);
8483 IDirect3D9_Release(d3d);
8484 DestroyWindow(window);
8487 static void test_set_palette(void)
8489 IDirect3DDevice9 *device;
8490 IDirect3D9 *d3d9;
8491 UINT refcount;
8492 HWND window;
8493 HRESULT hr;
8494 PALETTEENTRY pal[256];
8495 unsigned int i;
8496 D3DCAPS9 caps;
8498 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8499 0, 0, 640, 480, 0, 0, 0, 0);
8500 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8501 ok(!!d3d9, "Failed to create a D3D object.\n");
8502 if (!(device = create_device(d3d9, window, NULL)))
8504 skip("Failed to create a D3D device, skipping tests.\n");
8505 DestroyWindow(window);
8506 return;
8509 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
8511 pal[i].peRed = i;
8512 pal[i].peGreen = i;
8513 pal[i].peBlue = i;
8514 pal[i].peFlags = 0xff;
8516 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
8517 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
8519 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8520 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8521 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
8523 pal[i].peRed = i;
8524 pal[i].peGreen = i;
8525 pal[i].peBlue = i;
8526 pal[i].peFlags = i;
8528 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
8530 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
8531 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
8533 else
8535 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
8536 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
8539 refcount = IDirect3DDevice9_Release(device);
8540 ok(!refcount, "Device has %u references left.\n", refcount);
8541 IDirect3D9_Release(d3d9);
8542 DestroyWindow(window);
8545 static void test_swvp_buffer(void)
8547 IDirect3DDevice9 *device;
8548 IDirect3D9 *d3d9;
8549 UINT refcount;
8550 HWND window;
8551 HRESULT hr;
8552 unsigned int i;
8553 IDirect3DVertexBuffer9 *buffer;
8554 static const unsigned int bufsize = 1024;
8555 D3DVERTEXBUFFER_DESC desc;
8556 struct device_desc device_desc;
8557 struct
8559 float x, y, z;
8560 } *ptr, *ptr2;
8562 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8563 0, 0, 640, 480, 0, 0, 0, 0);
8564 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8565 ok(!!d3d9, "Failed to create a D3D object.\n");
8567 device_desc.device_window = window;
8568 device_desc.width = 640;
8569 device_desc.height = 480;
8570 device_desc.flags = CREATE_DEVICE_SWVP_ONLY;
8571 if (!(device = create_device(d3d9, window, &device_desc)))
8573 skip("Failed to create a D3D device, skipping tests.\n");
8574 DestroyWindow(window);
8575 IDirect3D9_Release(d3d9);
8576 return;
8579 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
8580 D3DPOOL_DEFAULT, &buffer, NULL);
8581 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
8582 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
8583 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
8584 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
8585 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
8586 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
8588 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
8589 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
8590 for (i = 0; i < bufsize; i++)
8592 ptr[i].x = i * 1.0f;
8593 ptr[i].y = i * 2.0f;
8594 ptr[i].z = i * 3.0f;
8596 hr = IDirect3DVertexBuffer9_Unlock(buffer);
8597 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
8599 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8600 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
8601 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
8602 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8603 hr = IDirect3DDevice9_BeginScene(device);
8604 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8605 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
8606 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8607 hr = IDirect3DDevice9_EndScene(device);
8608 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8610 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
8611 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
8612 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
8613 for (i = 0; i < bufsize; i++)
8615 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
8617 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
8618 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
8619 break;
8622 hr = IDirect3DVertexBuffer9_Unlock(buffer);
8623 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
8625 IDirect3DVertexBuffer9_Release(buffer);
8626 refcount = IDirect3DDevice9_Release(device);
8627 ok(!refcount, "Device has %u references left.\n", refcount);
8628 IDirect3D9_Release(d3d9);
8629 DestroyWindow(window);
8632 static void test_managed_buffer(void)
8634 static const unsigned int vertex_count = 1024;
8635 IDirect3DVertexBuffer9 *buffer;
8636 D3DVERTEXBUFFER_DESC desc;
8637 IDirect3DDevice9 *device;
8638 struct vec3 *ptr, *ptr2;
8639 IDirect3D9 *d3d9;
8640 unsigned int i;
8641 UINT refcount;
8642 HWND window;
8643 HRESULT hr;
8645 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8646 0, 0, 640, 480, 0, 0, 0, 0);
8647 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8648 ok(!!d3d9, "Failed to create a D3D object.\n");
8649 if (!(device = create_device(d3d9, window, NULL)))
8651 skip("Failed to create a D3D device, skipping tests.\n");
8652 IDirect3D9_Release(d3d9);
8653 DestroyWindow(window);
8654 return;
8657 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*ptr),
8658 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
8659 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
8660 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
8661 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
8662 ok(desc.Pool == D3DPOOL_MANAGED, "Got unexpected pool %#x.\n", desc.Pool);
8663 ok(!desc.Usage, "Got unexpected usage %#x.\n", desc.Usage);
8665 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
8666 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
8667 for (i = 0; i < vertex_count; ++i)
8669 ptr[i].x = i * 1.0f;
8670 ptr[i].y = i * 2.0f;
8671 ptr[i].z = i * 3.0f;
8673 hr = IDirect3DVertexBuffer9_Unlock(buffer);
8674 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
8676 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8677 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
8678 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
8679 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8680 hr = IDirect3DDevice9_BeginScene(device);
8681 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8682 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
8683 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8684 hr = IDirect3DDevice9_EndScene(device);
8685 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8687 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
8688 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
8689 ok(ptr2 == ptr, "Got unexpected ptr2 %p, expected %p.\n", ptr2, ptr);
8690 for (i = 0; i < vertex_count; ++i)
8692 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
8694 ok(FALSE, "Got unexpected vertex %u {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n",
8695 i, ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
8696 break;
8699 hr = IDirect3DVertexBuffer9_Unlock(buffer);
8700 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
8702 IDirect3DVertexBuffer9_Release(buffer);
8703 refcount = IDirect3DDevice9_Release(device);
8704 ok(!refcount, "Device has %u references left.\n", refcount);
8705 IDirect3D9_Release(d3d9);
8706 DestroyWindow(window);
8709 static void test_npot_textures(void)
8711 IDirect3DDevice9 *device = NULL;
8712 IDirect3D9 *d3d9;
8713 ULONG refcount;
8714 HWND window = NULL;
8715 HRESULT hr;
8716 D3DCAPS9 caps;
8717 IDirect3DTexture9 *texture;
8718 IDirect3DCubeTexture9 *cube_texture;
8719 IDirect3DVolumeTexture9 *volume_texture;
8720 struct
8722 D3DPOOL pool;
8723 const char *pool_name;
8724 HRESULT hr;
8726 pools[] =
8728 { D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL },
8729 { D3DPOOL_MANAGED, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL },
8730 { D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL },
8731 { D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", D3D_OK },
8733 unsigned int i, levels;
8734 BOOL tex_pow2, cube_pow2, vol_pow2;
8736 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8737 0, 0, 640, 480, 0, 0, 0, 0);
8738 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8739 ok(!!d3d9, "Failed to create a D3D object.\n");
8740 if (!(device = create_device(d3d9, window, NULL)))
8742 skip("Failed to create a D3D device, skipping tests.\n");
8743 goto done;
8746 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8747 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8748 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
8749 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
8750 vol_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
8751 ok(cube_pow2 == tex_pow2, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
8752 ok(vol_pow2 == tex_pow2, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
8754 for (i = 0; i < sizeof(pools) / sizeof(*pools); i++)
8756 for (levels = 0; levels <= 2; levels++)
8758 HRESULT expected;
8760 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, levels, 0, D3DFMT_X8R8G8B8,
8761 pools[i].pool, &texture, NULL);
8762 if (!tex_pow2)
8764 expected = D3D_OK;
8766 else if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
8768 if (levels == 1)
8769 expected = D3D_OK;
8770 else
8771 expected = pools[i].hr;
8773 else
8775 expected = pools[i].hr;
8777 ok(hr == expected, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#x, expected %#x.\n",
8778 pools[i].pool_name, levels, hr, expected);
8780 if (SUCCEEDED(hr))
8781 IDirect3DTexture9_Release(texture);
8784 hr = IDirect3DDevice9_CreateCubeTexture(device, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
8785 &cube_texture, NULL);
8786 if (tex_pow2)
8788 ok(hr == pools[i].hr, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
8789 pools[i].pool_name, hr, pools[i].hr);
8791 else
8793 ok(SUCCEEDED(hr), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
8794 pools[i].pool_name, hr, D3D_OK);
8797 if (SUCCEEDED(hr))
8798 IDirect3DCubeTexture9_Release(cube_texture);
8800 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
8801 &volume_texture, NULL);
8802 if (tex_pow2)
8804 ok(hr == pools[i].hr, "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
8805 pools[i].pool_name, hr, pools[i].hr);
8807 else
8809 ok(SUCCEEDED(hr), "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
8810 pools[i].pool_name, hr, D3D_OK);
8813 if (SUCCEEDED(hr))
8814 IDirect3DVolumeTexture9_Release(volume_texture);
8817 done:
8818 if (device)
8820 refcount = IDirect3DDevice9_Release(device);
8821 ok(!refcount, "Device has %u references left.\n", refcount);
8823 IDirect3D9_Release(d3d9);
8824 DestroyWindow(window);
8828 static void test_vidmem_accounting(void)
8830 IDirect3DDevice9 *device;
8831 IDirect3D9 *d3d9;
8832 ULONG refcount;
8833 HWND window;
8834 HRESULT hr = D3D_OK;
8835 IDirect3DTexture9 *textures[20];
8836 unsigned int i;
8837 UINT vidmem_start, vidmem_end, diff;
8839 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8840 0, 0, 640, 480, 0, 0, 0, 0);
8841 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8842 ok(!!d3d9, "Failed to create a D3D object.\n");
8843 if (!(device = create_device(d3d9, window, NULL)))
8845 skip("Failed to create a D3D device, skipping tests.\n");
8846 IDirect3D9_Release(d3d9);
8847 DestroyWindow(window);
8848 return;
8851 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
8852 memset(textures, 0, sizeof(textures));
8853 for (i = 0; i < sizeof(textures) / sizeof(*textures) && SUCCEEDED(hr); i++)
8855 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
8856 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
8857 /* D3DERR_OUTOFVIDEOMEMORY is returned when the card runs out of video memory
8858 * E_FAIL is returned on address space or system memory exhaustion */
8859 ok(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY,
8860 "Failed to create texture, hr %#x.\n", hr);
8862 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
8864 ok(vidmem_start > vidmem_end, "Expected available texture memory to decrease during texture creation.\n");
8865 diff = vidmem_start - vidmem_end;
8866 ok(diff > 1024 * 1024 * 2 * i, "Expected a video memory difference of at least %u MB, got %u MB.\n",
8867 2 * i, diff / 1024 / 1024);
8869 for (i = 0; i < sizeof(textures) / sizeof(*textures); i++)
8871 if (textures[i])
8872 IDirect3DTexture9_Release(textures[i]);
8875 refcount = IDirect3DDevice9_Release(device);
8876 ok(!refcount, "Device has %u references left.\n", refcount);
8877 IDirect3D9_Release(d3d9);
8878 DestroyWindow(window);
8881 static void test_volume_locking(void)
8883 IDirect3DDevice9 *device;
8884 IDirect3D9 *d3d9;
8885 HWND window;
8886 HRESULT hr;
8887 IDirect3DVolumeTexture9 *texture;
8888 unsigned int i;
8889 D3DLOCKED_BOX locked_box;
8890 ULONG refcount;
8891 D3DCAPS9 caps;
8892 static const struct
8894 D3DPOOL pool;
8895 DWORD usage;
8896 HRESULT create_hr, lock_hr;
8898 tests[] =
8900 { D3DPOOL_DEFAULT, 0, D3D_OK, D3DERR_INVALIDCALL },
8901 { D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
8902 { D3DPOOL_SYSTEMMEM, 0, D3D_OK, D3D_OK },
8903 { D3DPOOL_SYSTEMMEM, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
8904 { D3DPOOL_MANAGED, 0, D3D_OK, D3D_OK },
8905 { D3DPOOL_MANAGED, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
8906 { D3DPOOL_SCRATCH, 0, D3D_OK, D3D_OK },
8907 { D3DPOOL_SCRATCH, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
8910 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8911 0, 0, 640, 480, 0, 0, 0, 0);
8912 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8913 ok(!!d3d9, "Failed to create a D3D object.\n");
8914 if (!(device = create_device(d3d9, window, NULL)))
8916 skip("Failed to create a D3D device, skipping tests.\n");
8917 IDirect3D9_Release(d3d9);
8918 DestroyWindow(window);
8919 return;
8922 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8923 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8924 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
8926 skip("Volume textures not supported, skipping test.\n");
8927 goto out;
8930 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
8932 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, tests[i].usage,
8933 D3DFMT_A8R8G8B8, tests[i].pool, &texture, NULL);
8934 ok(hr == tests[i].create_hr, "Creating volume texture pool=%u, usage=%#x returned %#x, expected %#x.\n",
8935 tests[i].pool, tests[i].usage, hr, tests[i].create_hr);
8936 if (FAILED(hr))
8937 continue;
8939 locked_box.pBits = (void *)0xdeadbeef;
8940 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
8941 ok(hr == tests[i].lock_hr, "Lock returned %#x, expected %#x.\n", hr, tests[i].lock_hr);
8942 if (SUCCEEDED(hr))
8944 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8945 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8947 else
8949 ok(locked_box.pBits == NULL, "Failed lock set pBits = %p, expected NULL.\n", locked_box.pBits);
8951 IDirect3DVolumeTexture9_Release(texture);
8954 out:
8955 refcount = IDirect3DDevice9_Release(device);
8956 ok(!refcount, "Device has %u references left.\n", refcount);
8957 IDirect3D9_Release(d3d9);
8958 DestroyWindow(window);
8961 static void test_update_volumetexture(void)
8963 IDirect3DDevice9 *device;
8964 IDirect3D9 *d3d9;
8965 HWND window;
8966 HRESULT hr;
8967 IDirect3DVolumeTexture9 *src, *dst;
8968 unsigned int i;
8969 D3DLOCKED_BOX locked_box;
8970 ULONG refcount;
8971 D3DCAPS9 caps;
8972 static const struct
8974 D3DPOOL src_pool, dst_pool;
8975 HRESULT hr;
8977 tests[] =
8979 { D3DPOOL_DEFAULT, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
8980 { D3DPOOL_MANAGED, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
8981 { D3DPOOL_SYSTEMMEM, D3DPOOL_DEFAULT, D3D_OK },
8982 { D3DPOOL_SCRATCH, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
8984 { D3DPOOL_DEFAULT, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
8985 { D3DPOOL_MANAGED, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
8986 { D3DPOOL_SYSTEMMEM, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
8987 { D3DPOOL_SCRATCH, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
8989 { D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
8990 { D3DPOOL_MANAGED, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
8991 { D3DPOOL_SYSTEMMEM, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
8992 { D3DPOOL_SCRATCH, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
8994 { D3DPOOL_DEFAULT, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
8995 { D3DPOOL_MANAGED, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
8996 { D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
8997 { D3DPOOL_SCRATCH, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
8999 static const struct
9001 UINT src_size, dst_size;
9002 UINT src_lvl, dst_lvl;
9003 D3DFORMAT src_fmt, dst_fmt;
9005 tests2[] =
9007 { 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
9008 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
9009 { 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
9010 { 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
9011 { 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
9012 { 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different level count */
9013 { 4, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different size */
9014 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8 }, /* Different format */
9017 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9018 0, 0, 640, 480, 0, 0, 0, 0);
9019 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
9020 ok(!!d3d9, "Failed to create a D3D object.\n");
9021 if (!(device = create_device(d3d9, window, NULL)))
9023 skip("Failed to create a D3D device, skipping tests.\n");
9024 IDirect3D9_Release(d3d9);
9025 DestroyWindow(window);
9026 return;
9029 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9030 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9031 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
9033 skip("Volume textures not supported, skipping test.\n");
9034 goto out;
9037 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
9039 DWORD src_usage = tests[i].src_pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0;
9040 DWORD dst_usage = tests[i].dst_pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0;
9042 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, src_usage,
9043 D3DFMT_A8R8G8B8, tests[i].src_pool, &src, NULL);
9044 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
9045 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, dst_usage,
9046 D3DFMT_A8R8G8B8, tests[i].dst_pool, &dst, NULL);
9047 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
9049 hr = IDirect3DVolumeTexture9_LockBox(src, 0, &locked_box, NULL, 0);
9050 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
9051 *((DWORD *)locked_box.pBits) = 0x11223344;
9052 hr = IDirect3DVolumeTexture9_UnlockBox(src, 0);
9053 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9055 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
9056 ok(hr == tests[i].hr, "UpdateTexture returned %#x, expected %#x, src pool %x, dst pool %u.\n",
9057 hr, tests[i].hr, tests[i].src_pool, tests[i].dst_pool);
9059 if (SUCCEEDED(hr))
9061 DWORD content = *((DWORD *)locked_box.pBits);
9062 hr = IDirect3DVolumeTexture9_LockBox(dst, 0, &locked_box, NULL, 0);
9063 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
9064 ok(content == 0x11223344, "Dest texture contained %#x, expected 0x11223344.\n", content);
9065 hr = IDirect3DVolumeTexture9_UnlockBox(dst, 0);
9066 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9068 IDirect3DVolumeTexture9_Release(src);
9069 IDirect3DVolumeTexture9_Release(dst);
9072 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
9074 skip("Mipmapped volume maps not supported.\n");
9075 goto out;
9078 for (i = 0; i < sizeof(tests2) / sizeof(*tests2); i++)
9080 hr = IDirect3DDevice9_CreateVolumeTexture(device,
9081 tests2[i].src_size, tests2[i].src_size, tests2[i].src_size,
9082 tests2[i].src_lvl, 0, tests2[i].src_fmt, D3DPOOL_SYSTEMMEM, &src, NULL);
9083 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x, case %u.\n", hr, i);
9084 hr = IDirect3DDevice9_CreateVolumeTexture(device,
9085 tests2[i].dst_size, tests2[i].dst_size, tests2[i].dst_size,
9086 tests2[i].dst_lvl, 0, tests2[i].dst_fmt, D3DPOOL_DEFAULT, &dst, NULL);
9087 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x, case %u.\n", hr, i);
9089 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
9090 todo_wine_if (FAILED(hr))
9091 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u.\n", hr, i);
9093 IDirect3DVolumeTexture9_Release(src);
9094 IDirect3DVolumeTexture9_Release(dst);
9097 /* As far as I can see, UpdateTexture on non-matching texture behaves like a memcpy. The raw data
9098 * stays the same in a format change, a 2x2x1 texture is copied into the first row of a 4x4x1 texture,
9099 * etc. I could not get it to segfault, but the nonexistent 5th pixel of a 2x2x1 texture is copied into
9100 * pixel 1x2x1 of a 4x4x1 texture, demonstrating a read beyond the texture's end. I suspect any bad
9101 * memory access is silently ignored by the runtime, in the kernel or on the GPU.
9103 * I'm not adding tests for this behavior until an application needs it. */
9105 out:
9106 refcount = IDirect3DDevice9_Release(device);
9107 ok(!refcount, "Device has %u references left.\n", refcount);
9108 IDirect3D9_Release(d3d9);
9109 DestroyWindow(window);
9112 static void test_create_rt_ds_fail(void)
9114 IDirect3DDevice9 *device;
9115 HWND window;
9116 HRESULT hr;
9117 ULONG refcount;
9118 IDirect3D9 *d3d9;
9119 IDirect3DSurface9 *surface;
9121 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9122 0, 0, 640, 480, 0, 0, 0, 0);
9123 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
9124 ok(!!d3d9, "Failed to create a D3D object.\n");
9125 if (!(device = create_device(d3d9, window, NULL)))
9127 skip("Failed to create a D3D device, skipping tests.\n");
9128 IDirect3D9_Release(d3d9);
9129 DestroyWindow(window);
9130 return;
9133 /* Output pointer == NULL segfaults on Windows. */
9135 surface = (IDirect3DSurface9 *)0xdeadbeef;
9136 hr = IDirect3DDevice9_CreateRenderTarget(device, 4, 4, D3DFMT_D16,
9137 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
9138 ok(hr == D3DERR_INVALIDCALL, "Creating a D16 render target returned hr %#x.\n", hr);
9139 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
9140 if (SUCCEEDED(hr))
9141 IDirect3DSurface9_Release(surface);
9143 surface = (IDirect3DSurface9 *)0xdeadbeef;
9144 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 4, 4, D3DFMT_A8R8G8B8,
9145 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
9146 ok(hr == D3DERR_INVALIDCALL, "Creating a A8R8G8B8 depth stencil returned hr %#x.\n", hr);
9147 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
9148 if (SUCCEEDED(hr))
9149 IDirect3DSurface9_Release(surface);
9151 refcount = IDirect3DDevice9_Release(device);
9152 ok(!refcount, "Device has %u references left.\n", refcount);
9153 IDirect3D9_Release(d3d9);
9154 DestroyWindow(window);
9157 static void test_volume_blocks(void)
9159 IDirect3DDevice9 *device;
9160 IDirect3D9 *d3d9;
9161 UINT refcount;
9162 HWND window;
9163 HRESULT hr;
9164 D3DCAPS9 caps;
9165 IDirect3DVolumeTexture9 *texture;
9166 unsigned int w, h, d, i, j;
9167 static const struct
9169 D3DFORMAT fmt;
9170 const char *name;
9171 unsigned int block_width;
9172 unsigned int block_height;
9173 unsigned int block_depth;
9174 unsigned int block_size;
9175 unsigned int broken;
9176 BOOL create_size_checked, core_fmt;
9178 formats[] =
9180 /* Scratch volumes enforce DXTn block locks, unlike their surface counterparts.
9181 * ATI2N and YUV blocks are not enforced on any tested card (r200, gtx 460). */
9182 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 1, 8, 0, TRUE, TRUE },
9183 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 1, 16, 0, TRUE, TRUE },
9184 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 1, 16, 0, TRUE, TRUE },
9185 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 1, 16, 0, TRUE, TRUE },
9186 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, 0, TRUE, TRUE },
9187 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, 0, TRUE, TRUE },
9188 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
9189 * which doesn't match the format spec. On newer Nvidia cards
9190 * it has the correct 4x4 block size.
9191 * ATI1N volume textures are only supported by AMD GPUs right
9192 * now and locking offsets seem just wrong. */
9193 {MAKEFOURCC('A','T','I','1'), "ATI1N", 4, 4, 1, 8, 2, FALSE, FALSE},
9194 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, 1, 16, 1, FALSE, FALSE},
9195 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, 1, 4, 1, FALSE, TRUE },
9196 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, 1, 4, 1, FALSE, TRUE },
9198 static const struct
9200 D3DPOOL pool;
9201 const char *name;
9202 BOOL need_driver_support, need_runtime_support;
9204 create_tests[] =
9206 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
9207 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
9208 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE, FALSE},
9209 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
9211 static const struct
9213 unsigned int x, y, z, x2, y2, z2;
9215 offset_tests[] =
9217 {0, 0, 0, 8, 8, 8},
9218 {0, 0, 3, 8, 8, 8},
9219 {0, 4, 0, 8, 8, 8},
9220 {0, 4, 3, 8, 8, 8},
9221 {4, 0, 0, 8, 8, 8},
9222 {4, 0, 3, 8, 8, 8},
9223 {4, 4, 0, 8, 8, 8},
9224 {4, 4, 3, 8, 8, 8},
9226 D3DBOX box;
9227 D3DLOCKED_BOX locked_box;
9228 BYTE *base;
9229 INT expected_row_pitch, expected_slice_pitch;
9230 BOOL support;
9231 BOOL pow2;
9232 unsigned int offset, expected_offset;
9234 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9235 0, 0, 640, 480, 0, 0, 0, 0);
9236 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
9237 ok(!!d3d9, "Failed to create a D3D object.\n");
9238 if (!(device = create_device(d3d9, window, NULL)))
9240 skip("Failed to create a D3D device, skipping tests.\n");
9241 IDirect3D9_Release(d3d9);
9242 DestroyWindow(window);
9243 return;
9245 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9246 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9247 pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
9249 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
9251 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
9252 0, D3DRTYPE_VOLUMETEXTURE, formats[i].fmt);
9253 support = SUCCEEDED(hr);
9255 /* Test creation restrictions */
9256 for (w = 1; w <= 8; w++)
9258 for (h = 1; h <= 8; h++)
9260 for (d = 1; d <= 8; d++)
9262 HRESULT expect_hr;
9263 BOOL size_is_pow2;
9264 BOOL block_aligned = TRUE;
9266 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
9267 block_aligned = FALSE;
9269 size_is_pow2 = !((w & (w - 1)) || (h & (h - 1)) || (d & (d - 1)));
9271 for (j = 0; j < sizeof(create_tests) / sizeof(*create_tests); j++)
9273 BOOL may_succeed = FALSE;
9275 if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !support)
9276 expect_hr = D3DERR_INVALIDCALL;
9277 else if (formats[i].create_size_checked && !block_aligned)
9278 expect_hr = D3DERR_INVALIDCALL;
9279 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
9280 expect_hr = D3DERR_INVALIDCALL;
9281 else if (create_tests[j].need_driver_support && !support)
9282 expect_hr = D3DERR_INVALIDCALL;
9283 else
9284 expect_hr = D3D_OK;
9286 texture = (IDirect3DVolumeTexture9 *)0xdeadbeef;
9287 hr = IDirect3DDevice9_CreateVolumeTexture(device, w, h, d, 1, 0,
9288 formats[i].fmt, create_tests[j].pool, &texture, NULL);
9290 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
9291 * does not support it. Accept scratch creation of extension formats on
9292 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
9293 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
9294 * support it. */
9295 if (!formats[i].core_fmt && !support && FAILED(expect_hr))
9296 may_succeed = TRUE;
9298 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
9299 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
9300 hr, formats[i].name, create_tests[j].name, w, h, d);
9302 if (FAILED(hr))
9303 ok(texture == NULL, "Got texture ptr %p, expected NULL.\n", texture);
9304 else
9305 IDirect3DVolumeTexture9_Release(texture);
9311 if (!support && !formats[i].core_fmt)
9312 continue;
9314 hr = IDirect3DDevice9_CreateVolumeTexture(device, 24, 8, 8, 1, 0,
9315 formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
9316 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
9318 /* Test lockrect offset */
9319 for (j = 0; j < sizeof(offset_tests) / sizeof(*offset_tests); j++)
9321 unsigned int bytes_per_pixel;
9322 bytes_per_pixel = formats[i].block_size / (formats[i].block_width * formats[i].block_height);
9324 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
9325 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9327 base = locked_box.pBits;
9328 if (formats[i].broken == 1)
9330 expected_row_pitch = bytes_per_pixel * 24;
9332 else if (formats[i].broken == 2)
9334 expected_row_pitch = 24;
9336 else
9338 expected_row_pitch = (24 /* tex width */ + formats[i].block_height - 1) / formats[i].block_width
9339 * formats[i].block_size;
9341 ok(locked_box.RowPitch == expected_row_pitch, "Got unexpected row pitch %d for format %s, expected %d.\n",
9342 locked_box.RowPitch, formats[i].name, expected_row_pitch);
9344 if (formats[i].broken)
9346 expected_slice_pitch = expected_row_pitch * 8;
9348 else
9350 expected_slice_pitch = (8 /* tex height */ + formats[i].block_depth - 1) / formats[i].block_height
9351 * expected_row_pitch;
9353 ok(locked_box.SlicePitch == expected_slice_pitch,
9354 "Got unexpected slice pitch %d for format %s, expected %d.\n",
9355 locked_box.SlicePitch, formats[i].name, expected_slice_pitch);
9357 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9358 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x, j %u.\n", hr, j);
9360 box.Left = offset_tests[j].x;
9361 box.Top = offset_tests[j].y;
9362 box.Front = offset_tests[j].z;
9363 box.Right = offset_tests[j].x2;
9364 box.Bottom = offset_tests[j].y2;
9365 box.Back = offset_tests[j].z2;
9366 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
9367 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x, j %u.\n", hr, j);
9369 offset = (BYTE *)locked_box.pBits - base;
9370 if (formats[i].broken == 1)
9372 expected_offset = box.Front * expected_slice_pitch
9373 + box.Top * expected_row_pitch
9374 + box.Left * bytes_per_pixel;
9376 else if (formats[i].broken == 2)
9378 expected_offset = box.Front * expected_slice_pitch
9379 + box.Top * expected_row_pitch
9380 + box.Left;
9382 else
9384 expected_offset = (box.Front / formats[i].block_depth) * expected_slice_pitch
9385 + (box.Top / formats[i].block_height) * expected_row_pitch
9386 + (box.Left / formats[i].block_width) * formats[i].block_size;
9388 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u, box start %ux%ux%u.\n",
9389 offset, formats[i].name, expected_offset, box.Left, box.Top, box.Front);
9391 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9392 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9395 /* Test partial block locks */
9396 box.Front = 0;
9397 box.Back = 1;
9398 if (formats[i].block_width > 1)
9400 box.Left = formats[i].block_width >> 1;
9401 box.Top = 0;
9402 box.Right = formats[i].block_width;
9403 box.Bottom = formats[i].block_height;
9404 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
9405 ok(FAILED(hr) || broken(formats[i].broken),
9406 "Partial block lock succeeded, expected failure, format %s.\n",
9407 formats[i].name);
9408 if (SUCCEEDED(hr))
9410 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9411 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9414 box.Left = 0;
9415 box.Top = 0;
9416 box.Right = formats[i].block_width >> 1;
9417 box.Bottom = formats[i].block_height;
9418 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
9419 ok(FAILED(hr) || broken(formats[i].broken),
9420 "Partial block lock succeeded, expected failure, format %s.\n",
9421 formats[i].name);
9422 if (SUCCEEDED(hr))
9424 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9425 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9429 if (formats[i].block_height > 1)
9431 box.Left = 0;
9432 box.Top = formats[i].block_height >> 1;
9433 box.Right = formats[i].block_width;
9434 box.Bottom = formats[i].block_height;
9435 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
9436 ok(FAILED(hr) || broken(formats[i].broken),
9437 "Partial block lock succeeded, expected failure, format %s.\n",
9438 formats[i].name);
9439 if (SUCCEEDED(hr))
9441 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9442 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9445 box.Left = 0;
9446 box.Top = 0;
9447 box.Right = formats[i].block_width;
9448 box.Bottom = formats[i].block_height >> 1;
9449 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
9450 ok(FAILED(hr) || broken(formats[i].broken),
9451 "Partial block lock succeeded, expected failure, format %s.\n",
9452 formats[i].name);
9453 if (SUCCEEDED(hr))
9455 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9456 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9460 /* Test full block lock */
9461 box.Left = 0;
9462 box.Top = 0;
9463 box.Right = formats[i].block_width;
9464 box.Bottom = formats[i].block_height;
9465 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
9466 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
9467 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9468 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9470 IDirect3DVolumeTexture9_Release(texture);
9472 /* Test mipmap locks. Don't do this with ATI2N, AMD warns that the runtime
9473 * does not allocate surfaces smaller than the blocksize properly. */
9474 if ((formats[i].block_width > 1 || formats[i].block_height > 1) && formats[i].core_fmt)
9476 hr = IDirect3DDevice9_CreateVolumeTexture(device, formats[i].block_width, formats[i].block_height,
9477 2, 2, 0, formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
9478 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
9480 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, NULL, 0);
9481 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#x.\n", hr);
9482 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
9483 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9485 box.Left = box.Top = box.Front = 0;
9486 box.Right = formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1;
9487 box.Bottom = formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1;
9488 box.Back = 1;
9489 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
9490 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#x.\n", hr);
9491 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
9492 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9494 box.Right = formats[i].block_width;
9495 box.Bottom = formats[i].block_height;
9496 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
9497 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9498 if (SUCCEEDED(hr))
9499 IDirect3DVolumeTexture9_UnlockBox(texture, 1);
9501 IDirect3DVolumeTexture9_Release(texture);
9505 refcount = IDirect3DDevice9_Release(device);
9506 ok(!refcount, "Device has %u references left.\n", refcount);
9507 IDirect3D9_Release(d3d9);
9508 DestroyWindow(window);
9511 static void test_lockbox_invalid(void)
9513 static const struct
9515 D3DBOX box;
9516 HRESULT result;
9518 test_data[] =
9520 {{0, 0, 2, 2, 0, 1}, D3D_OK}, /* Valid */
9521 {{0, 0, 4, 4, 0, 1}, D3D_OK}, /* Valid */
9522 {{0, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* 0 height */
9523 {{0, 0, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* 0 width */
9524 {{0, 0, 4, 4, 1, 1}, D3DERR_INVALIDCALL}, /* 0 depth */
9525 {{4, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > right */
9526 {{0, 4, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* top > bottom */
9527 {{0, 0, 4, 4, 1, 0}, D3DERR_INVALIDCALL}, /* back > front */
9528 {{0, 0, 8, 4, 0, 1}, D3DERR_INVALIDCALL}, /* right > surface */
9529 {{0, 0, 4, 8, 0, 1}, D3DERR_INVALIDCALL}, /* bottom > surface */
9530 {{0, 0, 4, 4, 0, 3}, D3DERR_INVALIDCALL}, /* back > surface */
9531 {{8, 0, 16, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > surface */
9532 {{0, 8, 4, 16, 0, 1}, D3DERR_INVALIDCALL}, /* top > surface */
9533 {{0, 0, 4, 4, 2, 4}, D3DERR_INVALIDCALL}, /* top > surface */
9535 static const D3DBOX test_boxt_2 = {2, 2, 4, 4, 0, 1};
9536 IDirect3DVolumeTexture9 *texture = NULL;
9537 D3DLOCKED_BOX locked_box;
9538 IDirect3DDevice9 *device;
9539 IDirect3D9 *d3d;
9540 unsigned int i;
9541 ULONG refcount;
9542 HWND window;
9543 BYTE *base;
9544 HRESULT hr;
9546 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
9547 0, 0, 640, 480, 0, 0, 0, 0);
9548 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9549 ok(!!d3d, "Failed to create a D3D object.\n");
9550 if (!(device = create_device(d3d, window, NULL)))
9552 skip("Failed to create a D3D device, skipping tests.\n");
9553 IDirect3D9_Release(d3d);
9554 DestroyWindow(window);
9555 return;
9558 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0,
9559 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
9560 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
9561 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
9562 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
9563 base = locked_box.pBits;
9564 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9565 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9567 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
9569 unsigned int offset, expected_offset;
9570 const D3DBOX *box = &test_data[i].box;
9572 locked_box.pBits = (BYTE *)0xdeadbeef;
9573 locked_box.RowPitch = 0xdeadbeef;
9574 locked_box.SlicePitch = 0xdeadbeef;
9576 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, box, 0);
9577 /* Unlike surfaces, volumes properly check the box even in Windows XP */
9578 ok(hr == test_data[i].result,
9579 "Got unexpected hr %#x with box [%u, %u, %u]->[%u, %u, %u], expected %#x.\n",
9580 hr, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back,
9581 test_data[i].result);
9582 if (FAILED(hr))
9583 continue;
9585 offset = (BYTE *)locked_box.pBits - base;
9586 expected_offset = box->Front * locked_box.SlicePitch + box->Top * locked_box.RowPitch + box->Left * 4;
9587 ok(offset == expected_offset,
9588 "Got unexpected offset %u (expected %u) for rect [%u, %u, %u]->[%u, %u, %u].\n",
9589 offset, expected_offset, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back);
9591 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9592 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9595 /* locked_box = NULL throws an exception on Windows */
9596 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
9597 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
9598 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
9599 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9600 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9601 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9602 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9603 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9605 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
9606 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
9607 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
9608 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
9609 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
9610 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
9611 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
9612 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
9613 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_boxt_2, 0);
9614 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
9615 hr, test_boxt_2.Left, test_boxt_2.Top, test_boxt_2.Front,
9616 test_boxt_2.Right, test_boxt_2.Bottom, test_boxt_2.Back);
9617 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
9618 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
9620 IDirect3DVolumeTexture9_Release(texture);
9621 refcount = IDirect3DDevice9_Release(device);
9622 ok(!refcount, "Device has %u references left.\n", refcount);
9623 IDirect3D9_Release(d3d);
9624 DestroyWindow(window);
9627 static void test_shared_handle(void)
9629 IDirect3DDevice9 *device;
9630 IDirect3D9 *d3d;
9631 ULONG refcount;
9632 HWND window;
9633 HRESULT hr;
9634 /* Native d3d9ex refuses to create a shared texture if the texture pointer
9635 * is not initialized to NULL. Make sure this doesn't cause issues here. */
9636 IDirect3DTexture9 *texture = NULL;
9637 IDirect3DSurface9 *surface = NULL;
9638 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
9639 IDirect3DIndexBuffer9 *index_buffer = NULL;
9640 HANDLE handle = NULL;
9641 void *mem;
9642 D3DCAPS9 caps;
9644 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
9645 0, 0, 640, 480, 0, 0, 0, 0);
9646 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9647 ok(!!d3d, "Failed to create a D3D object.\n");
9648 if (!(device = create_device(d3d, window, NULL)))
9650 skip("Failed to create a D3D device, skipping tests.\n");
9651 IDirect3D9_Release(d3d);
9652 DestroyWindow(window);
9653 return;
9656 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9657 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9658 mem = HeapAlloc(GetProcessHeap(), 0, 128 * 128 * 4);
9660 /* Windows XP returns E_NOTIMPL, Windows 7 returns INVALIDCALL, except for
9661 * CreateVertexBuffer, where it returns NOTAVAILABLE. */
9662 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
9663 D3DPOOL_DEFAULT, &texture, &handle);
9664 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9665 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
9666 D3DPOOL_SYSTEMMEM, &texture, &mem);
9667 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9669 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
9670 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, &handle);
9671 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9672 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
9673 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, &mem);
9674 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9676 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
9677 &vertex_buffer, &handle);
9678 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9679 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
9680 &vertex_buffer, &mem);
9681 ok(hr == E_NOTIMPL || broken(hr == D3DERR_NOTAVAILABLE), "Got unexpected hr %#x.\n", hr);
9683 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
9684 &index_buffer, &handle);
9685 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9686 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
9687 &index_buffer, &mem);
9688 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9690 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9692 IDirect3DCubeTexture9 *cube_texture = NULL;
9693 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
9694 D3DPOOL_DEFAULT, &cube_texture, &handle);
9695 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9696 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
9697 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
9698 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9701 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
9703 IDirect3DVolumeTexture9 *volume_texture = NULL;
9704 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
9705 D3DPOOL_DEFAULT, &volume_texture, &handle);
9706 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9707 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
9708 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
9709 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9712 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9713 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
9714 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9716 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24X8,
9717 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
9718 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
9720 HeapFree(GetProcessHeap(), 0, mem);
9721 refcount = IDirect3DDevice9_Release(device);
9722 ok(!refcount, "Device has %u references left.\n", refcount);
9723 IDirect3D9_Release(d3d);
9724 DestroyWindow(window);
9727 static void test_pixel_format(void)
9729 HWND hwnd, hwnd2 = NULL;
9730 HDC hdc, hdc2 = NULL;
9731 HMODULE gl = NULL;
9732 int format, test_format;
9733 PIXELFORMATDESCRIPTOR pfd;
9734 IDirect3D9 *d3d9 = NULL;
9735 IDirect3DDevice9 *device = NULL;
9736 HRESULT hr;
9737 static const float point[3] = {0.0, 0.0, 0.0};
9739 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
9740 100, 100, 160, 160, NULL, NULL, NULL, NULL);
9741 if (!hwnd)
9743 skip("Failed to create window\n");
9744 return;
9747 hwnd2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
9748 100, 100, 160, 160, NULL, NULL, NULL, NULL);
9750 hdc = GetDC(hwnd);
9751 if (!hdc)
9753 skip("Failed to get DC\n");
9754 goto cleanup;
9757 if (hwnd2)
9758 hdc2 = GetDC(hwnd2);
9760 gl = LoadLibraryA("opengl32.dll");
9761 ok(!!gl, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
9763 format = GetPixelFormat(hdc);
9764 ok(format == 0, "new window has pixel format %d\n", format);
9766 ZeroMemory(&pfd, sizeof(pfd));
9767 pfd.nSize = sizeof(pfd);
9768 pfd.nVersion = 1;
9769 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
9770 pfd.iPixelType = PFD_TYPE_RGBA;
9771 pfd.iLayerType = PFD_MAIN_PLANE;
9772 format = ChoosePixelFormat(hdc, &pfd);
9773 if (format <= 0)
9775 skip("no pixel format available\n");
9776 goto cleanup;
9779 if (!SetPixelFormat(hdc, format, &pfd) || GetPixelFormat(hdc) != format)
9781 skip("failed to set pixel format\n");
9782 goto cleanup;
9785 if (!hdc2 || !SetPixelFormat(hdc2, format, &pfd) || GetPixelFormat(hdc2) != format)
9787 skip("failed to set pixel format on second window\n");
9788 if (hdc2)
9790 ReleaseDC(hwnd2, hdc2);
9791 hdc2 = NULL;
9795 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
9796 ok(!!d3d9, "Failed to create a D3D object.\n");
9798 test_format = GetPixelFormat(hdc);
9799 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
9801 if (!(device = create_device(d3d9, hwnd, NULL)))
9803 skip("Failed to create device\n");
9804 goto cleanup;
9807 test_format = GetPixelFormat(hdc);
9808 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
9810 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9811 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9813 test_format = GetPixelFormat(hdc);
9814 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
9816 hr = IDirect3DDevice9_BeginScene(device);
9817 ok(SUCCEEDED(hr), "BeginScene failed %#x\n", hr);
9819 test_format = GetPixelFormat(hdc);
9820 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
9822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
9823 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9825 test_format = GetPixelFormat(hdc);
9826 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
9828 hr = IDirect3DDevice9_EndScene(device);
9829 ok(SUCCEEDED(hr), "EndScene failed %#x\n", hr);
9831 test_format = GetPixelFormat(hdc);
9832 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
9834 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9835 ok(SUCCEEDED(hr), "Present failed %#x\n", hr);
9837 test_format = GetPixelFormat(hdc);
9838 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
9840 if (hdc2)
9842 hr = IDirect3DDevice9_Present(device, NULL, NULL, hwnd2, NULL);
9843 ok(SUCCEEDED(hr), "Present failed %#x\n", hr);
9845 test_format = GetPixelFormat(hdc);
9846 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
9848 test_format = GetPixelFormat(hdc2);
9849 ok(test_format == format, "second window has pixel format %d, expected %d\n", test_format, format);
9852 cleanup:
9853 if (device)
9855 UINT refcount = IDirect3DDevice9_Release(device);
9856 ok(!refcount, "Device has %u references left.\n", refcount);
9858 if (d3d9) IDirect3D9_Release(d3d9);
9859 if (gl) FreeLibrary(gl);
9860 if (hdc) ReleaseDC(hwnd, hdc);
9861 if (hdc2) ReleaseDC(hwnd2, hdc2);
9862 if (hwnd) DestroyWindow(hwnd);
9863 if (hwnd2) DestroyWindow(hwnd2);
9866 static void test_begin_end_state_block(void)
9868 IDirect3DStateBlock9 *stateblock;
9869 IDirect3DDevice9 *device;
9870 IDirect3D9 *d3d;
9871 ULONG refcount;
9872 HWND window;
9873 HRESULT hr;
9875 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9876 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9877 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9878 ok(!!d3d, "Failed to create a D3D object.\n");
9879 if (!(device = create_device(d3d, window, NULL)))
9881 skip("Failed to create a D3D device, skipping tests.\n");
9882 IDirect3D9_Release(d3d);
9883 DestroyWindow(window);
9884 return;
9887 /* Should succeed. */
9888 hr = IDirect3DDevice9_BeginStateBlock(device);
9889 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
9891 /* Calling BeginStateBlock() while recording should return
9892 * D3DERR_INVALIDCALL. */
9893 hr = IDirect3DDevice9_BeginStateBlock(device);
9894 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9896 /* Should succeed. */
9897 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
9898 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
9899 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
9900 ok(!!stateblock && stateblock != (IDirect3DStateBlock9 *)0xdeadbeef,
9901 "Got unexpected stateblock %p.\n", stateblock);
9902 IDirect3DStateBlock9_Release(stateblock);
9904 /* Calling EndStateBlock() while not recording should return
9905 * D3DERR_INVALIDCALL. stateblock should not be touched. */
9906 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
9907 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
9908 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9909 ok(stateblock == (IDirect3DStateBlock9 *)0xdeadbeef,
9910 "Got unexpected stateblock %p.\n", stateblock);
9912 refcount = IDirect3DDevice9_Release(device);
9913 ok(!refcount, "Device has %u references left.\n", refcount);
9914 IDirect3D9_Release(d3d);
9915 DestroyWindow(window);
9918 static void test_shader_constant_apply(void)
9920 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
9921 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
9922 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
9923 IDirect3DStateBlock9 *stateblock;
9924 DWORD vs_version, ps_version;
9925 IDirect3DDevice9 *device;
9926 IDirect3D9 *d3d;
9927 ULONG refcount;
9928 D3DCAPS9 caps;
9929 float ret[4];
9930 HWND window;
9931 HRESULT hr;
9933 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9934 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9935 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9936 ok(!!d3d, "Failed to create a D3D object.\n");
9937 if (!(device = create_device(d3d, window, NULL)))
9939 skip("Failed to create a D3D device, skipping tests.\n");
9940 IDirect3D9_Release(d3d);
9941 DestroyWindow(window);
9942 return;
9945 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9946 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9947 vs_version = caps.VertexShaderVersion & 0xffff;
9948 ps_version = caps.PixelShaderVersion & 0xffff;
9950 if (vs_version)
9952 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
9953 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
9954 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
9955 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
9957 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
9958 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
9959 ok(!memcmp(ret, initial, sizeof(initial)),
9960 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
9961 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
9962 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
9963 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
9964 ok(!memcmp(ret, initial, sizeof(initial)),
9965 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
9966 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
9968 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
9969 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
9971 if (ps_version)
9973 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
9974 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
9975 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
9976 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
9978 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
9979 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
9980 ok(!memcmp(ret, initial, sizeof(initial)),
9981 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
9982 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
9983 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
9984 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
9985 ok(!memcmp(ret, initial, sizeof(initial)),
9986 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
9987 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
9989 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
9990 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
9993 hr = IDirect3DDevice9_BeginStateBlock(device);
9994 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
9996 if (vs_version)
9998 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
9999 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
10001 if (ps_version)
10003 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
10004 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10007 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
10008 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
10010 if (vs_version)
10012 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
10013 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
10014 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
10015 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
10016 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
10017 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
10018 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
10019 ok(!memcmp(ret, initial, sizeof(initial)),
10020 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
10021 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
10023 if (ps_version)
10025 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
10026 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
10027 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
10028 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
10029 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
10030 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
10031 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
10032 ok(!memcmp(ret, initial, sizeof(initial)),
10033 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
10034 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
10037 /* Apply doesn't overwrite constants that aren't explicitly set on the
10038 * source stateblock. */
10039 hr = IDirect3DStateBlock9_Apply(stateblock);
10040 ok(SUCCEEDED(hr), "Failed to apply stateblock, hr %#x.\n", hr);
10042 if (vs_version)
10044 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
10045 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
10046 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
10047 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
10048 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
10049 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
10050 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
10051 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
10052 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
10053 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
10055 if (ps_version)
10057 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
10058 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
10059 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
10060 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
10061 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
10062 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
10063 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
10064 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
10065 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
10066 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
10069 IDirect3DStateBlock9_Release(stateblock);
10070 refcount = IDirect3DDevice9_Release(device);
10071 ok(!refcount, "Device has %u references left.\n", refcount);
10072 IDirect3D9_Release(d3d);
10073 DestroyWindow(window);
10076 static void test_vdecl_apply(void)
10078 IDirect3DVertexDeclaration9 *declaration, *declaration1, *declaration2;
10079 IDirect3DStateBlock9 *stateblock;
10080 IDirect3DDevice9 *device;
10081 IDirect3D9 *d3d;
10082 ULONG refcount;
10083 HWND window;
10084 HRESULT hr;
10086 static const D3DVERTEXELEMENT9 decl1[] =
10088 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10089 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10090 D3DDECL_END(),
10093 static const D3DVERTEXELEMENT9 decl2[] =
10095 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10096 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10097 {0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
10098 D3DDECL_END(),
10101 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
10102 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10103 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10104 ok(!!d3d, "Failed to create a D3D object.\n");
10105 if (!(device = create_device(d3d, window, NULL)))
10107 skip("Failed to create a D3D device, skipping tests.\n");
10108 IDirect3D9_Release(d3d);
10109 DestroyWindow(window);
10110 return;
10113 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl1, &declaration1);
10114 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
10116 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl2, &declaration2);
10117 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
10119 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10120 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10121 hr = IDirect3DDevice9_BeginStateBlock(device);
10122 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#x.\n", hr);
10123 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
10124 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10125 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
10126 ok(SUCCEEDED(hr), "EndStateBlock failed, hr %#x.\n", hr);
10127 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10128 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10129 hr = IDirect3DStateBlock9_Apply(stateblock);
10130 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10131 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10132 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10133 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
10134 declaration, declaration1);
10135 IDirect3DVertexDeclaration9_Release(declaration);
10137 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10138 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10139 hr = IDirect3DStateBlock9_Capture(stateblock);
10140 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
10141 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
10142 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10143 hr = IDirect3DStateBlock9_Apply(stateblock);
10144 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10145 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10146 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10147 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
10148 declaration, declaration2);
10149 IDirect3DVertexDeclaration9_Release(declaration);
10151 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
10152 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10153 hr = IDirect3DStateBlock9_Capture(stateblock);
10154 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
10155 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10156 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10157 hr = IDirect3DStateBlock9_Apply(stateblock);
10158 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10159 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10160 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10161 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
10162 declaration, declaration2);
10163 IDirect3DVertexDeclaration9_Release(declaration);
10165 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10166 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10167 hr = IDirect3DStateBlock9_Capture(stateblock);
10168 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
10169 hr = IDirect3DStateBlock9_Apply(stateblock);
10170 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10171 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10172 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10173 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
10175 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
10176 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10177 hr = IDirect3DStateBlock9_Capture(stateblock);
10178 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
10179 hr = IDirect3DStateBlock9_Apply(stateblock);
10180 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10181 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10182 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10183 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
10184 declaration, declaration2);
10185 IDirect3DVertexDeclaration9_Release(declaration);
10187 IDirect3DStateBlock9_Release(stateblock);
10188 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
10189 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10190 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &stateblock);
10191 ok(SUCCEEDED(hr), "CreateStateBlock failed, hr %#x.\n", hr);
10192 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10193 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10194 hr = IDirect3DStateBlock9_Apply(stateblock);
10195 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10196 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10197 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10198 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
10199 declaration, declaration1);
10200 IDirect3DVertexDeclaration9_Release(declaration);
10202 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10203 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10204 hr = IDirect3DStateBlock9_Capture(stateblock);
10205 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
10206 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
10207 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10208 hr = IDirect3DStateBlock9_Apply(stateblock);
10209 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10210 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10211 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10212 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
10213 declaration, declaration2);
10214 IDirect3DVertexDeclaration9_Release(declaration);
10216 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
10217 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10218 hr = IDirect3DStateBlock9_Capture(stateblock);
10219 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
10220 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10221 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10222 hr = IDirect3DStateBlock9_Apply(stateblock);
10223 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10224 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10225 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10226 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
10227 declaration, declaration2);
10228 IDirect3DVertexDeclaration9_Release(declaration);
10230 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10231 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10232 hr = IDirect3DStateBlock9_Capture(stateblock);
10233 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
10234 hr = IDirect3DStateBlock9_Apply(stateblock);
10235 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10236 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10237 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10238 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
10240 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
10241 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10242 hr = IDirect3DStateBlock9_Capture(stateblock);
10243 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
10244 hr = IDirect3DStateBlock9_Apply(stateblock);
10245 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
10246 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
10247 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
10248 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
10249 declaration, declaration2);
10250 IDirect3DVertexDeclaration9_Release(declaration);
10252 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
10253 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
10254 IDirect3DVertexDeclaration9_Release(declaration1);
10255 IDirect3DVertexDeclaration9_Release(declaration2);
10256 IDirect3DStateBlock9_Release(stateblock);
10257 refcount = IDirect3DDevice9_Release(device);
10258 ok(!refcount, "Device has %u references left.\n", refcount);
10259 IDirect3D9_Release(d3d);
10260 DestroyWindow(window);
10263 static void test_resource_type(void)
10265 IDirect3DDevice9 *device;
10266 IDirect3DSurface9 *surface;
10267 IDirect3DTexture9 *texture;
10268 IDirect3DCubeTexture9 *cube_texture;
10269 IDirect3DVolume9 *volume;
10270 IDirect3DVolumeTexture9 *volume_texture;
10271 D3DSURFACE_DESC surface_desc;
10272 D3DVOLUME_DESC volume_desc;
10273 D3DRESOURCETYPE type;
10274 IDirect3D9 *d3d;
10275 ULONG refcount;
10276 HWND window;
10277 HRESULT hr;
10278 D3DCAPS9 caps;
10280 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
10281 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10282 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10283 ok(!!d3d, "Failed to create a D3D object.\n");
10284 if (!(device = create_device(d3d, window, NULL)))
10286 skip("Failed to create a D3D device, skipping tests.\n");
10287 IDirect3D9_Release(d3d);
10288 DestroyWindow(window);
10289 return;
10292 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10293 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10295 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_X8R8G8B8,
10296 D3DPOOL_SYSTEMMEM, &surface, NULL);
10297 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
10298 type = IDirect3DSurface9_GetType(surface);
10299 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
10300 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
10301 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
10302 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
10303 surface_desc.Type);
10304 IDirect3DSurface9_Release(surface);
10306 hr = IDirect3DDevice9_CreateTexture(device, 2, 8, 4, 0, D3DFMT_X8R8G8B8,
10307 D3DPOOL_SYSTEMMEM, &texture, NULL);
10308 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
10309 type = IDirect3DTexture9_GetType(texture);
10310 ok(type == D3DRTYPE_TEXTURE, "Expected type D3DRTYPE_TEXTURE, got %u.\n", type);
10312 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
10313 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
10314 /* The following code crashes, for the sake of completeness:
10315 * type = texture->lpVtbl->GetType((IDirect3DTexture9 *)surface);
10316 * ok(type == D3DRTYPE_PONIES, "Expected type D3DRTYPE_PONIES, got %u.\n", type);
10318 * So applications will not depend on getting the "right" resource type - whatever it
10319 * may be - from the "wrong" vtable. */
10320 type = IDirect3DSurface9_GetType(surface);
10321 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
10322 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
10323 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
10324 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
10325 surface_desc.Type);
10326 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
10327 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
10328 hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &surface_desc);
10329 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
10330 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
10331 surface_desc.Type);
10332 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
10333 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
10334 IDirect3DSurface9_Release(surface);
10336 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
10337 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
10338 type = IDirect3DSurface9_GetType(surface);
10339 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
10340 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
10341 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
10342 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
10343 surface_desc.Type);
10344 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
10345 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
10346 hr = IDirect3DTexture9_GetLevelDesc(texture, 2, &surface_desc);
10347 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
10348 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
10349 surface_desc.Type);
10350 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
10351 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
10352 IDirect3DSurface9_Release(surface);
10353 IDirect3DTexture9_Release(texture);
10355 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10357 hr = IDirect3DDevice9_CreateCubeTexture(device, 1, 1, 0, D3DFMT_X8R8G8B8,
10358 D3DPOOL_SYSTEMMEM, &cube_texture, NULL);
10359 ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#x.\n", hr);
10360 type = IDirect3DCubeTexture9_GetType(cube_texture);
10361 ok(type == D3DRTYPE_CUBETEXTURE, "Expected type D3DRTYPE_CUBETEXTURE, got %u.\n", type);
10363 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture,
10364 D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface);
10365 ok(SUCCEEDED(hr), "Failed to get cube map surface, hr %#x.\n", hr);
10366 type = IDirect3DSurface9_GetType(surface);
10367 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
10368 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
10369 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
10370 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
10371 surface_desc.Type);
10372 hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
10373 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
10374 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
10375 surface_desc.Type);
10376 IDirect3DSurface9_Release(surface);
10377 IDirect3DCubeTexture9_Release(cube_texture);
10379 else
10380 skip("Cube maps not supported.\n");
10382 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP)
10384 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 4, 8, 4, 0, D3DFMT_X8R8G8B8,
10385 D3DPOOL_SYSTEMMEM, &volume_texture, NULL);
10386 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
10387 type = IDirect3DVolumeTexture9_GetType(volume_texture);
10388 ok(type == D3DRTYPE_VOLUMETEXTURE, "Expected type D3DRTYPE_VOLUMETEXTURE, got %u.\n", type);
10390 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
10391 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
10392 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
10393 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
10394 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#x.\n", hr);
10395 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
10396 volume_desc.Type);
10397 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
10398 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
10399 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
10400 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
10401 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
10402 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
10403 volume_desc.Type);
10404 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
10405 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
10406 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
10407 IDirect3DVolume9_Release(volume);
10409 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 2, &volume);
10410 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
10411 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
10412 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
10413 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#x.\n", hr);
10414 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
10415 volume_desc.Type);
10416 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
10417 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
10418 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
10419 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 2, &volume_desc);
10420 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
10421 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
10422 volume_desc.Type);
10423 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
10424 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
10425 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
10426 IDirect3DVolume9_Release(volume);
10427 IDirect3DVolumeTexture9_Release(volume_texture);
10429 else
10430 skip("Mipmapped volume maps not supported.\n");
10432 refcount = IDirect3DDevice9_Release(device);
10433 ok(!refcount, "Device has %u references left.\n", refcount);
10434 IDirect3D9_Release(d3d);
10435 DestroyWindow(window);
10438 static void test_mipmap_lock(void)
10440 IDirect3DDevice9 *device;
10441 IDirect3DSurface9 *surface, *surface2, *surface_dst, *surface_dst2;
10442 IDirect3DTexture9 *texture, *texture_dst;
10443 IDirect3D9 *d3d;
10444 ULONG refcount;
10445 HWND window;
10446 HRESULT hr;
10447 D3DLOCKED_RECT locked_rect;
10449 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
10450 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10451 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10452 ok(!!d3d, "Failed to create a D3D object.\n");
10453 if (!(device = create_device(d3d, window, NULL)))
10455 skip("Failed to create a D3D device, skipping tests.\n");
10456 IDirect3D9_Release(d3d);
10457 DestroyWindow(window);
10458 return;
10461 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
10462 D3DPOOL_DEFAULT, &texture_dst, NULL);
10463 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
10464 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 0, &surface_dst);
10465 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
10466 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 1, &surface_dst2);
10467 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
10469 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
10470 D3DPOOL_SYSTEMMEM, &texture, NULL);
10471 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
10472 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
10473 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
10474 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
10475 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
10477 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
10478 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
10479 hr = IDirect3DSurface9_LockRect(surface2, &locked_rect, NULL, 0);
10480 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
10481 hr = IDirect3DSurface9_UnlockRect(surface);
10482 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
10484 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, surface_dst, NULL);
10485 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
10486 hr = IDirect3DDevice9_UpdateSurface(device, surface2, NULL, surface_dst2, NULL);
10487 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
10489 /* Apparently there's no validation on the container. */
10490 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
10491 (IDirect3DBaseTexture9 *)texture_dst);
10492 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
10494 hr = IDirect3DSurface9_UnlockRect(surface2);
10495 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
10497 IDirect3DSurface9_Release(surface_dst2);
10498 IDirect3DSurface9_Release(surface_dst);
10499 IDirect3DSurface9_Release(surface2);
10500 IDirect3DSurface9_Release(surface);
10501 IDirect3DTexture9_Release(texture_dst);
10502 IDirect3DTexture9_Release(texture);
10504 refcount = IDirect3DDevice9_Release(device);
10505 ok(!refcount, "Device has %u references left.\n", refcount);
10506 IDirect3D9_Release(d3d);
10507 DestroyWindow(window);
10510 static void test_writeonly_resource(void)
10512 IDirect3D9 *d3d;
10513 IDirect3DDevice9 *device;
10514 IDirect3DVertexBuffer9 *buffer;
10515 ULONG refcount;
10516 HWND window;
10517 HRESULT hr;
10518 void *ptr;
10519 static const struct
10521 struct vec3 pos;
10523 quad[] =
10525 {{-1.0f, -1.0f, 0.0f}},
10526 {{-1.0f, 1.0f, 0.0f}},
10527 {{ 1.0f, -1.0f, 0.0f}},
10528 {{ 1.0f, 1.0f, 0.0f}}
10531 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
10532 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10533 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10534 ok(!!d3d, "Failed to create a D3D object.\n");
10535 if (!(device = create_device(d3d, window, NULL)))
10537 skip("Failed to create a D3D device, skipping tests.\n");
10538 IDirect3D9_Release(d3d);
10539 DestroyWindow(window);
10540 return;
10543 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad),
10544 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
10545 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
10547 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
10548 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10549 memcpy(ptr, quad, sizeof(quad));
10550 hr = IDirect3DVertexBuffer9_Unlock(buffer);
10551 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10552 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quad));
10553 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10554 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10555 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10557 hr = IDirect3DDevice9_BeginScene(device);
10558 ok(SUCCEEDED(hr), "Failed to begin scene %#x\n", hr);
10559 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10560 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10561 hr = IDirect3DDevice9_EndScene(device);
10562 ok(SUCCEEDED(hr), "Failed to end scene %#x\n", hr);
10564 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, 0);
10565 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10566 ok(!memcmp(ptr, quad, sizeof(quad)), "Got unexpected vertex buffer data.\n");
10567 hr = IDirect3DVertexBuffer9_Unlock(buffer);
10568 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10570 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, D3DLOCK_READONLY);
10571 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10572 ok(!memcmp(ptr, quad, sizeof(quad)), "Got unexpected vertex buffer data.\n");
10573 hr = IDirect3DVertexBuffer9_Unlock(buffer);
10574 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10576 refcount = IDirect3DVertexBuffer9_Release(buffer);
10577 ok(!refcount, "Vertex buffer has %u references left.\n", refcount);
10578 refcount = IDirect3DDevice9_Release(device);
10579 ok(!refcount, "Device has %u references left.\n", refcount);
10580 IDirect3D9_Release(d3d);
10581 DestroyWindow(window);
10584 static void test_lost_device(void)
10586 struct device_desc device_desc;
10587 IDirect3DDevice9 *device;
10588 IDirect3D9 *d3d;
10589 ULONG refcount;
10590 HWND window;
10591 HRESULT hr;
10592 BOOL ret;
10594 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
10595 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10596 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10597 ok(!!d3d, "Failed to create a D3D object.\n");
10598 device_desc.device_window = window;
10599 device_desc.width = registry_mode.dmPelsWidth;
10600 device_desc.height = registry_mode.dmPelsHeight;
10601 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
10602 if (!(device = create_device(d3d, window, &device_desc)))
10604 skip("Failed to create a D3D device, skipping tests.\n");
10605 goto done;
10608 hr = IDirect3DDevice9_TestCooperativeLevel(device);
10609 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10610 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10611 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10613 ret = SetForegroundWindow(GetDesktopWindow());
10614 ok(ret, "Failed to set foreground window.\n");
10615 hr = IDirect3DDevice9_TestCooperativeLevel(device);
10616 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
10617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10618 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
10620 ret = ShowWindow(window, SW_RESTORE);
10621 ok(ret, "Failed to restore window.\n");
10622 ret = SetForegroundWindow(window);
10623 ok(ret, "Failed to set foreground window.\n");
10624 hr = IDirect3DDevice9_TestCooperativeLevel(device);
10625 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
10626 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10627 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
10629 hr = reset_device(device, &device_desc);
10630 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10631 hr = IDirect3DDevice9_TestCooperativeLevel(device);
10632 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10633 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10634 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10636 device_desc.flags = 0;
10637 hr = reset_device(device, &device_desc);
10638 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10639 hr = IDirect3DDevice9_TestCooperativeLevel(device);
10640 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10641 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10642 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10644 ret = SetForegroundWindow(GetDesktopWindow());
10645 ok(ret, "Failed to set foreground window.\n");
10646 hr = IDirect3DDevice9_TestCooperativeLevel(device);
10647 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10648 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10649 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10651 ret = ShowWindow(window, SW_RESTORE);
10652 ok(ret, "Failed to restore window.\n");
10653 ret = SetForegroundWindow(window);
10654 ok(ret, "Failed to set foreground window.\n");
10655 hr = IDirect3DDevice9_TestCooperativeLevel(device);
10656 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10657 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10658 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10660 device_desc.flags = CREATE_DEVICE_FULLSCREEN;
10661 hr = reset_device(device, &device_desc);
10662 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10663 hr = IDirect3DDevice9_TestCooperativeLevel(device);
10664 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10665 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10666 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10668 ret = SetForegroundWindow(GetDesktopWindow());
10669 ok(ret, "Failed to set foreground window.\n");
10670 hr = reset_device(device, &device_desc);
10671 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
10672 ret = ShowWindow(window, SW_RESTORE);
10673 ok(ret, "Failed to restore window.\n");
10674 ret = SetForegroundWindow(window);
10675 ok(ret, "Failed to set foreground window.\n");
10676 hr = reset_device(device, &device_desc);
10677 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10679 refcount = IDirect3DDevice9_Release(device);
10680 ok(!refcount, "Device has %u references left.\n", refcount);
10681 done:
10682 IDirect3D9_Release(d3d);
10683 DestroyWindow(window);
10686 static void test_resource_priority(void)
10688 IDirect3DDevice9 *device;
10689 IDirect3DSurface9 *surface;
10690 IDirect3DTexture9 *texture;
10691 IDirect3DVertexBuffer9 *buffer;
10692 IDirect3D9 *d3d;
10693 ULONG refcount;
10694 HWND window;
10695 HRESULT hr;
10696 static const struct
10698 D3DPOOL pool;
10699 const char *name;
10700 BOOL can_set_priority;
10702 test_data[] =
10704 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
10705 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", FALSE},
10706 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
10707 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE}
10709 unsigned int i;
10710 DWORD priority;
10712 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
10713 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10714 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10715 ok(!!d3d, "Failed to create a D3D object.\n");
10716 if (!(device = create_device(d3d, window, NULL)))
10718 skip("Failed to create a D3D device, skipping tests.\n");
10719 IDirect3D9_Release(d3d);
10720 DestroyWindow(window);
10721 return;
10724 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); i++)
10726 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 0, 0, D3DFMT_X8R8G8B8,
10727 test_data[i].pool, &texture, NULL);
10728 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, pool %s.\n", hr, test_data[i].name);
10729 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
10730 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
10732 priority = IDirect3DTexture9_GetPriority(texture);
10733 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10734 priority = IDirect3DTexture9_SetPriority(texture, 1);
10735 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10736 priority = IDirect3DTexture9_GetPriority(texture);
10737 if (test_data[i].can_set_priority)
10739 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10740 priority = IDirect3DTexture9_SetPriority(texture, 2);
10741 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10743 else
10744 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10746 priority = IDirect3DSurface9_GetPriority(surface);
10747 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10748 priority = IDirect3DSurface9_SetPriority(surface, 1);
10749 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10750 priority = IDirect3DSurface9_GetPriority(surface);
10751 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10753 IDirect3DSurface9_Release(surface);
10754 IDirect3DTexture9_Release(texture);
10756 if (test_data[i].pool != D3DPOOL_MANAGED)
10758 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16, D3DFMT_X8R8G8B8,
10759 test_data[i].pool, &surface, NULL);
10760 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, pool %s.\n", hr, test_data[i].name);
10762 priority = IDirect3DSurface9_GetPriority(surface);
10763 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10764 priority = IDirect3DSurface9_SetPriority(surface, 1);
10765 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10766 priority = IDirect3DSurface9_GetPriority(surface);
10767 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10769 IDirect3DSurface9_Release(surface);
10772 if (test_data[i].pool != D3DPOOL_SCRATCH)
10774 hr = IDirect3DDevice9_CreateVertexBuffer(device, 256, 0, 0,
10775 test_data[i].pool, &buffer, NULL);
10776 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x, pool %s.\n", hr, test_data[i].name);
10778 priority = IDirect3DVertexBuffer9_GetPriority(buffer);
10779 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10780 priority = IDirect3DVertexBuffer9_SetPriority(buffer, 1);
10781 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10782 priority = IDirect3DVertexBuffer9_GetPriority(buffer);
10783 if (test_data[i].can_set_priority)
10785 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10786 priority = IDirect3DVertexBuffer9_SetPriority(buffer, 0);
10787 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10789 else
10790 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
10792 IDirect3DVertexBuffer9_Release(buffer);
10796 hr = IDirect3DDevice9_CreateRenderTarget(device, 16, 16, D3DFMT_X8R8G8B8,
10797 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
10799 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
10800 priority = IDirect3DSurface9_GetPriority(surface);
10801 ok(priority == 0, "Got unexpected priority %u.\n", priority);
10802 priority = IDirect3DSurface9_SetPriority(surface, 1);
10803 ok(priority == 0, "Got unexpected priority %u.\n", priority);
10804 priority = IDirect3DSurface9_GetPriority(surface);
10805 ok(priority == 0, "Got unexpected priority %u.\n", priority);
10807 IDirect3DSurface9_Release(surface);
10809 refcount = IDirect3DDevice9_Release(device);
10810 ok(!refcount, "Device has %u references left.\n", refcount);
10811 IDirect3D9_Release(d3d);
10812 DestroyWindow(window);
10815 static void test_swapchain_parameters(void)
10817 IDirect3DDevice9 *device;
10818 IDirect3D9 *d3d;
10819 HWND window;
10820 HRESULT hr;
10821 unsigned int i;
10822 D3DPRESENT_PARAMETERS present_parameters, present_parameters_windowed = {0}, present_parameters2;
10823 IDirect3DSwapChain9 *swapchain;
10824 static const struct
10826 BOOL windowed;
10827 UINT backbuffer_count;
10828 D3DSWAPEFFECT swap_effect;
10829 HRESULT hr;
10831 tests[] =
10833 /* Swap effect 0 is not allowed. */
10834 {TRUE, 1, 0, D3DERR_INVALIDCALL},
10835 {FALSE, 1, 0, D3DERR_INVALIDCALL},
10837 /* All (non-ex) swap effects are allowed in
10838 * windowed and fullscreen mode. */
10839 {TRUE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
10840 {TRUE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
10841 {FALSE, 1, D3DSWAPEFFECT_DISCARD, D3D_OK},
10842 {FALSE, 1, D3DSWAPEFFECT_FLIP, D3D_OK},
10843 {FALSE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
10845 /* Only one backbuffer in copy mode. */
10846 {TRUE, 0, D3DSWAPEFFECT_COPY, D3D_OK},
10847 {TRUE, 1, D3DSWAPEFFECT_COPY, D3D_OK},
10848 {TRUE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
10849 {FALSE, 2, D3DSWAPEFFECT_COPY, D3DERR_INVALIDCALL},
10851 /* Ok with the others, in fullscreen and windowed mode. */
10852 {TRUE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
10853 {TRUE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
10854 {FALSE, 2, D3DSWAPEFFECT_DISCARD, D3D_OK},
10855 {FALSE, 2, D3DSWAPEFFECT_FLIP, D3D_OK},
10857 /* D3D9Ex swap effects. */
10858 {TRUE, 1, D3DSWAPEFFECT_OVERLAY, D3DERR_INVALIDCALL},
10859 {TRUE, 1, D3DSWAPEFFECT_FLIPEX, D3DERR_INVALIDCALL},
10860 {TRUE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
10861 {FALSE, 1, D3DSWAPEFFECT_OVERLAY, D3DERR_INVALIDCALL},
10862 {FALSE, 1, D3DSWAPEFFECT_FLIPEX, D3DERR_INVALIDCALL},
10863 {FALSE, 1, D3DSWAPEFFECT_FLIPEX + 1, D3DERR_INVALIDCALL},
10865 /* 3 is the highest allowed backbuffer count. */
10866 {TRUE, 3, D3DSWAPEFFECT_DISCARD, D3D_OK},
10867 {TRUE, 4, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
10868 {TRUE, 4, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
10869 {FALSE, 4, D3DSWAPEFFECT_DISCARD, D3DERR_INVALIDCALL},
10870 {FALSE, 4, D3DSWAPEFFECT_FLIP, D3DERR_INVALIDCALL},
10873 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
10874 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10875 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10876 ok(!!d3d, "Failed to create a D3D object.\n");
10877 if (!(device = create_device(d3d, window, NULL)))
10879 skip("Failed to create a D3D device, skipping tests.\n");
10880 IDirect3D9_Release(d3d);
10881 DestroyWindow(window);
10882 return;
10884 IDirect3DDevice9_Release(device);
10886 present_parameters_windowed.BackBufferWidth = registry_mode.dmPelsWidth;
10887 present_parameters_windowed.BackBufferHeight = registry_mode.dmPelsHeight;
10888 present_parameters_windowed.hDeviceWindow = window;
10889 present_parameters_windowed.BackBufferFormat = D3DFMT_X8R8G8B8;
10890 present_parameters_windowed.SwapEffect = D3DSWAPEFFECT_COPY;
10891 present_parameters_windowed.Windowed = TRUE;
10892 present_parameters_windowed.BackBufferCount = 1;
10894 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
10896 memset(&present_parameters, 0, sizeof(present_parameters));
10897 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
10898 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
10899 present_parameters.hDeviceWindow = window;
10900 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
10902 present_parameters.SwapEffect = tests[i].swap_effect;
10903 present_parameters.Windowed = tests[i].windowed;
10904 present_parameters.BackBufferCount = tests[i].backbuffer_count;
10906 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
10907 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
10908 ok(hr == tests[i].hr, "Expected hr %x, got %x, test %u.\n", tests[i].hr, hr, i);
10909 if (SUCCEEDED(hr))
10911 UINT bb_count = tests[i].backbuffer_count ? tests[i].backbuffer_count : 1;
10913 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
10914 ok(SUCCEEDED(hr), "Failed to get swapchain, hr %#x, test %u.\n", hr, i);
10916 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters2);
10917 ok(SUCCEEDED(hr), "Failed to get present parameters, hr %#x, test %u.\n", hr, i);
10918 ok(present_parameters2.SwapEffect == tests[i].swap_effect, "Swap effect changed from %u to %u, test %u.\n",
10919 tests[i].swap_effect, present_parameters2.SwapEffect, i);
10920 ok(present_parameters2.BackBufferCount == bb_count, "Backbuffer count changed from %u to %u, test %u.\n",
10921 bb_count, present_parameters2.BackBufferCount, i);
10922 ok(present_parameters2.Windowed == tests[i].windowed, "Windowed changed from %u to %u, test %u.\n",
10923 tests[i].windowed, present_parameters2.Windowed, i);
10925 IDirect3DSwapChain9_Release(swapchain);
10926 IDirect3DDevice9_Release(device);
10929 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
10930 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters_windowed, &device);
10931 ok(SUCCEEDED(hr), "Failed to create device, hr %#x, test %u.\n", hr, i);
10933 memset(&present_parameters, 0, sizeof(present_parameters));
10934 present_parameters.BackBufferWidth = registry_mode.dmPelsWidth;
10935 present_parameters.BackBufferHeight = registry_mode.dmPelsHeight;
10936 present_parameters.hDeviceWindow = window;
10937 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
10939 present_parameters.SwapEffect = tests[i].swap_effect;
10940 present_parameters.Windowed = tests[i].windowed;
10941 present_parameters.BackBufferCount = tests[i].backbuffer_count;
10943 hr = IDirect3DDevice9_Reset(device, &present_parameters);
10944 ok(hr == tests[i].hr, "Expected hr %x, got %x, test %u.\n", tests[i].hr, hr, i);
10946 if (FAILED(hr))
10948 hr = IDirect3DDevice9_Reset(device, &present_parameters_windowed);
10949 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x, test %u.\n", hr, i);
10951 IDirect3DDevice9_Release(device);
10954 IDirect3D9_Release(d3d);
10955 DestroyWindow(window);
10958 static void test_check_device_format(void)
10960 IDirect3D9 *d3d;
10961 HRESULT hr;
10963 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10964 ok(!!d3d, "Failed to create a D3D object.\n");
10966 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
10967 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
10969 skip("D3DFMT_A8R8G8B8 textures with SRGBWRITE not supported.\n");
10971 else
10973 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
10974 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
10975 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10976 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
10977 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
10978 ok(FAILED(hr), "Got unexpected hr %#x.\n", hr);
10981 IDirect3D9_Release(d3d);
10984 static void test_miptree_layout(void)
10986 unsigned int pool_idx, format_idx, base_dimension, level_count, offset, i, j;
10987 IDirect3DCubeTexture9 *texture_cube;
10988 IDirect3DTexture9 *texture_2d;
10989 IDirect3DDevice9 *device;
10990 D3DLOCKED_RECT map_desc;
10991 BYTE *base = NULL;
10992 IDirect3D9 *d3d;
10993 D3DCAPS9 caps;
10994 UINT refcount;
10995 HWND window;
10996 HRESULT hr;
10998 static const struct
11000 D3DFORMAT format;
11001 const char *name;
11003 formats[] =
11005 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8"},
11006 {D3DFMT_A8, "D3DFMT_A8"},
11007 {D3DFMT_L8, "D3DFMT_L8"},
11009 static const struct
11011 D3DPOOL pool;
11012 const char *name;
11014 pools[] =
11016 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED"},
11017 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM"},
11018 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH"},
11021 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
11022 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11023 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11024 ok(!!d3d, "Failed to create a D3D object.\n");
11025 if (!(device = create_device(d3d, window, NULL)))
11027 skip("Failed to create a D3D device, skipping tests.\n");
11028 goto done;
11031 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11032 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
11034 base_dimension = 257;
11035 if (caps.TextureCaps & (D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_CUBEMAP_POW2))
11037 skip("Using power of two base dimension.\n");
11038 base_dimension = 256;
11041 for (format_idx = 0; format_idx < sizeof(formats) / sizeof(*formats); ++format_idx)
11043 if (FAILED(hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
11044 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[format_idx].format)))
11046 skip("%s textures not supported, skipping tests.\n", formats[format_idx].name);
11047 continue;
11050 for (pool_idx = 0; pool_idx < sizeof(pools) / sizeof(*pools); ++pool_idx)
11052 hr = IDirect3DDevice9_CreateTexture(device, base_dimension, base_dimension, 0, 0,
11053 formats[format_idx].format, pools[pool_idx].pool, &texture_2d, NULL);
11054 ok(SUCCEEDED(hr), "Failed to create a %s %s texture, hr %#x.\n",
11055 pools[pool_idx].name, formats[format_idx].name, hr);
11057 level_count = IDirect3DTexture9_GetLevelCount(texture_2d);
11058 for (i = 0, offset = 0; i < level_count; ++i)
11060 hr = IDirect3DTexture9_LockRect(texture_2d, i, &map_desc, NULL, 0);
11061 ok(SUCCEEDED(hr), "%s, %s: Failed to lock level %u, hr %#x.\n",
11062 pools[pool_idx].name, formats[format_idx].name, i, hr);
11064 if (!i)
11065 base = map_desc.pBits;
11066 else
11067 ok(map_desc.pBits == base + offset,
11068 "%s, %s, level %u: Got unexpected pBits %p, expected %p.\n",
11069 pools[pool_idx].name, formats[format_idx].name, i, map_desc.pBits, base + offset);
11070 offset += (base_dimension >> i) * map_desc.Pitch;
11072 hr = IDirect3DTexture9_UnlockRect(texture_2d, i);
11073 ok(SUCCEEDED(hr), "%s, %s Failed to unlock level %u, hr %#x.\n",
11074 pools[pool_idx].name, formats[format_idx].name, i, hr);
11077 IDirect3DTexture9_Release(texture_2d);
11080 if (FAILED(hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
11081 D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, formats[format_idx].format)))
11083 skip("%s cube textures not supported, skipping tests.\n", formats[format_idx].name);
11084 continue;
11087 for (pool_idx = 0; pool_idx < sizeof(pools) / sizeof(*pools); ++pool_idx)
11089 hr = IDirect3DDevice9_CreateCubeTexture(device, base_dimension, 0, 0,
11090 formats[format_idx].format, pools[pool_idx].pool, &texture_cube, NULL);
11091 ok(SUCCEEDED(hr), "Failed to create a %s %s cube texture, hr %#x.\n",
11092 pools[pool_idx].name, formats[format_idx].name, hr);
11094 level_count = IDirect3DCubeTexture9_GetLevelCount(texture_cube);
11095 for (i = 0, offset = 0; i < 6; ++i)
11097 for (j = 0; j < level_count; ++j)
11099 hr = IDirect3DCubeTexture9_LockRect(texture_cube, i, j, &map_desc, NULL, 0);
11100 ok(SUCCEEDED(hr), "%s, %s: Failed to lock face %u, level %u, hr %#x.\n",
11101 pools[pool_idx].name, formats[format_idx].name, i, j, hr);
11103 if (!i && !j)
11104 base = map_desc.pBits;
11105 else
11106 ok(map_desc.pBits == base + offset,
11107 "%s, %s, face %u, level %u: Got unexpected pBits %p, expected %p.\n",
11108 pools[pool_idx].name, formats[format_idx].name, i, j, map_desc.pBits, base + offset);
11109 offset += (base_dimension >> j) * map_desc.Pitch;
11111 hr = IDirect3DCubeTexture9_UnlockRect(texture_cube, i, j);
11112 ok(SUCCEEDED(hr), "%s, %s: Failed to unlock face %u, level %u, hr %#x.\n",
11113 pools[pool_idx].name, formats[format_idx].name, i, j, hr);
11115 offset = (offset + 15) & ~15;
11118 IDirect3DCubeTexture9_Release(texture_cube);
11122 refcount = IDirect3DDevice9_Release(device);
11123 ok(!refcount, "Device has %u references left.\n", refcount);
11124 done:
11125 IDirect3D9_Release(d3d);
11126 DestroyWindow(window);
11129 static void test_get_render_target_data(void)
11131 IDirect3DSurface9 *offscreen_surface, *render_target;
11132 IDirect3DDevice9 *device;
11133 IDirect3D9 *d3d;
11134 UINT refcount;
11135 HWND window;
11136 HRESULT hr;
11138 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
11139 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11140 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11141 ok(!!d3d, "Failed to create a D3D object.\n");
11142 if (!(device = create_device(d3d, window, NULL)))
11144 skip("Failed to create a D3D device.\n");
11145 IDirect3D9_Release(d3d);
11146 DestroyWindow(window);
11147 return;
11150 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
11151 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
11152 ok(SUCCEEDED(hr), "Failed to create offscreen surface, hr %#x.\n", hr);
11154 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
11155 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL);
11156 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
11158 hr = IDirect3DDevice9_GetRenderTargetData(device, NULL, NULL);
11159 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
11161 hr = IDirect3DDevice9_GetRenderTargetData(device, render_target, NULL);
11162 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
11164 hr = IDirect3DDevice9_GetRenderTargetData(device, NULL, offscreen_surface);
11165 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
11167 hr = IDirect3DDevice9_GetRenderTargetData(device, render_target, offscreen_surface);
11168 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
11170 IDirect3DSurface9_Release(render_target);
11171 IDirect3DSurface9_Release(offscreen_surface);
11172 refcount = IDirect3DDevice9_Release(device);
11173 ok(!refcount, "Device has %u references left.\n", refcount);
11174 IDirect3D9_Release(d3d);
11175 DestroyWindow(window);
11178 START_TEST(device)
11180 WNDCLASSA wc = {0};
11181 IDirect3D9 *d3d9;
11182 DEVMODEW current_mode;
11184 memset(&current_mode, 0, sizeof(current_mode));
11185 current_mode.dmSize = sizeof(current_mode);
11186 ok(EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &current_mode), "Failed to get display mode.\n");
11187 registry_mode.dmSize = sizeof(registry_mode);
11188 ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
11189 if (registry_mode.dmPelsWidth != current_mode.dmPelsWidth
11190 || registry_mode.dmPelsHeight != current_mode.dmPelsHeight)
11192 skip("Current mode does not match registry mode, skipping test.\n");
11193 return;
11196 if (!(d3d9 = Direct3DCreate9(D3D_SDK_VERSION)))
11198 skip("could not create D3D9 object\n");
11199 return;
11201 IDirect3D9_Release(d3d9);
11203 wc.lpfnWndProc = DefWindowProcA;
11204 wc.lpszClassName = "d3d9_test_wc";
11205 RegisterClassA(&wc);
11207 test_get_set_vertex_declaration();
11208 test_get_declaration();
11209 test_fvf_decl_conversion();
11210 test_fvf_decl_management();
11211 test_vertex_declaration_alignment();
11212 test_unused_declaration_type();
11213 test_fpu_setup();
11214 test_multi_device();
11215 test_display_formats();
11216 test_display_modes();
11217 test_swapchain();
11218 test_refcount();
11219 test_mipmap_levels();
11220 test_checkdevicemultisampletype();
11221 test_invalid_multisample();
11222 test_cursor();
11223 test_cursor_pos();
11224 test_reset_fullscreen();
11225 test_reset();
11226 test_scene();
11227 test_limits();
11228 test_depthstenciltest();
11229 test_get_rt();
11230 test_draw_primitive();
11231 test_null_stream();
11232 test_lights();
11233 test_set_stream_source();
11234 test_scissor_size();
11235 test_wndproc();
11236 test_wndproc_windowed();
11237 test_window_style();
11238 test_mode_change();
11239 test_device_window_reset();
11240 test_reset_resources();
11241 test_set_rt_vp_scissor();
11242 test_volume_get_container();
11243 test_volume_resource();
11244 test_vb_lock_flags();
11245 test_vertex_buffer_alignment();
11246 test_query_support();
11247 test_occlusion_query_states();
11248 test_timestamp_query();
11249 test_get_set_vertex_shader();
11250 test_vertex_shader_constant();
11251 test_get_set_pixel_shader();
11252 test_pixel_shader_constant();
11253 test_unsupported_shaders();
11254 test_texture_stage_states();
11255 test_cube_textures();
11256 test_mipmap_gen();
11257 test_filter();
11258 test_get_set_texture();
11259 test_lod();
11260 test_surface_get_container();
11261 test_surface_alignment();
11262 test_lockrect_offset();
11263 test_lockrect_invalid();
11264 test_private_data();
11265 test_getdc();
11266 test_surface_dimensions();
11267 test_surface_format_null();
11268 test_surface_double_unlock();
11269 test_surface_blocks();
11270 test_set_palette();
11271 test_swvp_buffer();
11272 test_managed_buffer();
11273 test_npot_textures();
11274 test_vidmem_accounting();
11275 test_volume_locking();
11276 test_update_volumetexture();
11277 test_create_rt_ds_fail();
11278 test_volume_blocks();
11279 test_lockbox_invalid();
11280 test_shared_handle();
11281 test_pixel_format();
11282 test_begin_end_state_block();
11283 test_shader_constant_apply();
11284 test_vdecl_apply();
11285 test_resource_type();
11286 test_mipmap_lock();
11287 test_writeonly_resource();
11288 test_lost_device();
11289 test_resource_priority();
11290 test_swapchain_parameters();
11291 test_check_device_format();
11292 test_miptree_layout();
11293 test_get_render_target_data();
11295 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));