mshtml: Wine Gecko 2.34-beta2 release.
[wine/wine-gecko.git] / dlls / d3d9 / tests / device.c
blob8d0f6b7dfdd1fdf9a6dfd9be71bca2f0907eb361
1 /*
2 * Copyright (C) 2006 Ivan Gyurdiev
3 * Copyright (C) 2006 Vitaliy Margolen
4 * Copyright (C) 2006 Chris Robinson
5 * Copyright 2006-2008, 2010-2011, 2013 Stefan Dösinger for CodeWeavers
6 * Copyright 2005, 2006, 2007 Henri Verbeet
7 * Copyright 2013-2014 Henri Verbeet for CodeWeavers
8 * Copyright (C) 2008 Rico Schüller
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define COBJMACROS
26 #include <d3d9.h>
27 #include "wine/test.h"
29 struct vec3
31 float x, y, z;
34 struct device_desc
36 HWND device_window;
37 unsigned int width;
38 unsigned int height;
39 BOOL windowed;
42 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
43 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
45 static INT screen_width;
46 static INT screen_height;
48 static const DWORD simple_vs[] =
50 0xfffe0101, /* vs_1_1 */
51 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
52 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
53 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
54 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
55 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
56 0x0000ffff, /* end */
59 static const DWORD simple_ps[] =
61 0xffff0101, /* ps_1_1 */
62 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
63 0x00000042, 0xb00f0000, /* tex t0 */
64 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
65 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
66 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
67 0x0000ffff, /* end */
70 static int get_refcount(IUnknown *object)
72 IUnknown_AddRef( object );
73 return IUnknown_Release( object );
76 static BOOL compare_elements(IDirect3DVertexDeclaration9 *declaration, const D3DVERTEXELEMENT9 *expected_elements)
78 unsigned int element_count, i;
79 D3DVERTEXELEMENT9 *elements;
80 BOOL equal = TRUE;
81 HRESULT hr;
83 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
84 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
85 elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(*elements));
86 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
87 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
89 for (i = 0; i < element_count; ++i)
91 if (memcmp(&elements[i], &expected_elements[i], sizeof(*elements)))
93 equal = FALSE;
94 break;
98 if (!equal)
100 for (i = 0; i < element_count; ++i)
102 trace("[Element %u] stream %u, offset %u, type %#x, method %#x, usage %#x, usage index %u.\n",
103 i, elements[i].Stream, elements[i].Offset, elements[i].Type,
104 elements[i].Method, elements[i].Usage, elements[i].UsageIndex);
108 HeapFree(GetProcessHeap(), 0, elements);
109 return equal;
112 /* try to make sure pending X events have been processed before continuing */
113 static void flush_events(void)
115 MSG msg;
116 int diff = 200;
117 int min_timeout = 100;
118 DWORD time = GetTickCount() + diff;
120 while (diff > 0)
122 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
123 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
124 diff = time - GetTickCount();
128 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window, const struct device_desc *desc)
130 D3DPRESENT_PARAMETERS present_parameters = {0};
131 IDirect3DDevice9 *device;
133 present_parameters.BackBufferWidth = 640;
134 present_parameters.BackBufferHeight = 480;
135 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
136 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
137 present_parameters.hDeviceWindow = focus_window;
138 present_parameters.Windowed = TRUE;
139 present_parameters.EnableAutoDepthStencil = TRUE;
140 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
142 if (desc)
144 present_parameters.BackBufferWidth = desc->width;
145 present_parameters.BackBufferHeight = desc->height;
146 present_parameters.hDeviceWindow = desc->device_window;
147 present_parameters.Windowed = desc->windowed;
150 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
151 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
153 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
154 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
155 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
157 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
158 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
160 return NULL;
163 static HRESULT reset_device(IDirect3DDevice9 *device, HWND device_window, BOOL windowed)
165 D3DPRESENT_PARAMETERS present_parameters = {0};
167 present_parameters.Windowed = windowed;
168 present_parameters.hDeviceWindow = device_window;
169 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
170 present_parameters.BackBufferWidth = screen_width;
171 present_parameters.BackBufferHeight = screen_height;
172 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
173 present_parameters.EnableAutoDepthStencil = TRUE;
174 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
176 return IDirect3DDevice9_Reset(device, &present_parameters);
179 #define CHECK_CALL(r,c,d,rc) \
180 if (SUCCEEDED(r)) {\
181 int tmp1 = get_refcount( (IUnknown *)d ); \
182 int rc_new = rc; \
183 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
184 } else {\
185 trace("%s failed: %08x\n", c, r); \
188 #define CHECK_RELEASE(obj,d,rc) \
189 if (obj) { \
190 int tmp1, rc_new = rc; \
191 IUnknown_Release( (IUnknown*)obj ); \
192 tmp1 = get_refcount( (IUnknown *)d ); \
193 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
196 #define CHECK_REFCOUNT(obj,rc) \
198 int rc_new = rc; \
199 int count = get_refcount( (IUnknown *)obj ); \
200 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
203 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
205 int rc_new = rc; \
206 int count = IUnknown_Release( (IUnknown *)obj ); \
207 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
210 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
212 int rc_new = rc; \
213 int count = IUnknown_AddRef( (IUnknown *)obj ); \
214 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
217 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
219 void *container_ptr = (void *)0x1337c0d3; \
220 hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
221 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
222 "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
223 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
226 static void test_get_set_vertex_declaration(void)
228 IDirect3DVertexDeclaration9 *declaration, *tmp;
229 ULONG refcount, expected_refcount;
230 IDirect3DDevice9 *device;
231 IDirect3D9 *d3d;
232 HWND window;
233 HRESULT hr;
235 static const D3DVERTEXELEMENT9 simple_decl[] =
237 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
238 D3DDECL_END()
241 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
242 0, 0, 640, 480, NULL, NULL, NULL, NULL);
243 d3d = Direct3DCreate9(D3D_SDK_VERSION);
244 ok(!!d3d, "Failed to create a D3D object.\n");
245 if (!(device = create_device(d3d, window, NULL)))
247 skip("Failed to create a D3D device, skipping tests.\n");
248 goto done;
251 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
252 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
254 /* SetVertexDeclaration() should not touch the declaration's refcount. */
255 expected_refcount = get_refcount((IUnknown *)declaration);
256 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
257 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
258 refcount = get_refcount((IUnknown *)declaration);
259 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
261 /* GetVertexDeclaration() should increase the declaration's refcount by one. */
262 tmp = NULL;
263 expected_refcount = refcount + 1;
264 hr = IDirect3DDevice9_GetVertexDeclaration(device, &tmp);
265 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
266 ok(tmp == declaration, "Got unexpected declaration %p, expected %p.\n", tmp, declaration);
267 refcount = get_refcount((IUnknown *)declaration);
268 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
269 IDirect3DVertexDeclaration9_Release(tmp);
271 IDirect3DVertexDeclaration9_Release(declaration);
272 refcount = IDirect3DDevice9_Release(device);
273 ok(!refcount, "Device has %u references left.\n", refcount);
274 done:
275 IDirect3D9_Release(d3d);
276 DestroyWindow(window);
279 static void test_get_declaration(void)
281 unsigned int element_count, expected_element_count;
282 IDirect3DVertexDeclaration9 *declaration;
283 D3DVERTEXELEMENT9 *elements;
284 IDirect3DDevice9 *device;
285 IDirect3D9 *d3d;
286 ULONG refcount;
287 HWND window;
288 HRESULT hr;
290 static const D3DVERTEXELEMENT9 simple_decl[] =
292 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
293 D3DDECL_END()
296 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
297 0, 0, 640, 480, NULL, NULL, NULL, NULL);
298 d3d = Direct3DCreate9(D3D_SDK_VERSION);
299 ok(!!d3d, "Failed to create a D3D object.\n");
300 if (!(device = create_device(d3d, window, NULL)))
302 skip("Failed to create a D3D device, skipping tests.\n");
303 goto done;
306 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
307 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
309 /* First test only getting the number of elements. */
310 element_count = 0x1337c0de;
311 expected_element_count = sizeof(simple_decl) / sizeof(*simple_decl);
312 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
313 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
314 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
315 element_count, expected_element_count);
317 element_count = 0;
318 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
319 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
320 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
321 element_count, expected_element_count);
323 /* Also test the returned data. */
324 elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(simple_decl));
326 element_count = 0x1337c0de;
327 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
328 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
329 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
330 element_count, expected_element_count);
331 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
332 "Original and returned vertexdeclarations are not the same.\n");
334 memset(elements, 0, sizeof(simple_decl));
336 element_count = 0;
337 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
338 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
339 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
340 element_count, expected_element_count);
341 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
342 "Original and returned vertexdeclarations are not the same.\n");
344 HeapFree(GetProcessHeap(), 0, elements);
345 IDirect3DVertexDeclaration9_Release(declaration);
346 refcount = IDirect3DDevice9_Release(device);
347 ok(!refcount, "Device has %u references left.\n", refcount);
348 done:
349 IDirect3D9_Release(d3d);
350 DestroyWindow(window);
353 static void test_fvf_decl_conversion(void)
355 IDirect3DVertexDeclaration9 *default_decl;
356 IDirect3DVertexDeclaration9 *declaration;
357 IDirect3DDevice9 *device;
358 IDirect3D9 *d3d;
359 ULONG refcount;
360 unsigned int i;
361 HWND window;
362 HRESULT hr;
364 static const D3DVERTEXELEMENT9 default_elements[] =
366 {0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
367 {0, 4, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
368 D3DDECL_END()
370 /* Test conversions from vertex declaration to an FVF. For some reason
371 * those seem to occur only for POSITION/POSITIONT, otherwise the FVF is
372 * forced to 0 - maybe this is configuration specific. */
373 static const struct
375 D3DVERTEXELEMENT9 elements[7];
376 DWORD fvf;
377 BOOL todo;
379 decl_to_fvf_tests[] =
381 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}, D3DFVF_XYZ, TRUE },
382 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}, D3DFVF_XYZRHW, TRUE },
383 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
384 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
385 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
386 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
387 {{{0, 0, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0}, D3DDECL_END()}, 0, FALSE},
388 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}, 0, FALSE},
389 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}, 0, FALSE},
390 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}, 0, FALSE},
391 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}, 0, FALSE},
392 /* No FVF mapping available. */
393 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 1}, D3DDECL_END()}, 0, FALSE},
394 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 1}, D3DDECL_END()}, 0, FALSE},
395 /* Try empty declaration. */
396 {{ D3DDECL_END()}, 0, FALSE},
397 /* Make sure textures of different sizes work. */
398 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
399 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
400 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
401 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
402 /* Make sure the TEXCOORD index works correctly - try several textures. */
405 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
406 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
407 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
408 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
409 D3DDECL_END(),
410 }, 0, FALSE,
412 /* Now try a combination test. */
415 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITIONT, 0},
416 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
417 {0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0},
418 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
419 {0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
420 {0, 44, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1},
421 D3DDECL_END(),
422 }, 0, FALSE,
425 /* Test conversions from FVF to a vertex declaration. These seem to always
426 * occur internally. A new declaration object is created if necessary. */
427 static const struct
429 DWORD fvf;
430 D3DVERTEXELEMENT9 elements[7];
432 fvf_to_decl_tests[] =
434 {D3DFVF_XYZ, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
435 {D3DFVF_XYZW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
436 {D3DFVF_XYZRHW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}},
438 D3DFVF_XYZB5,
440 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
441 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
442 {0, 28, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDINDICES, 0},
443 D3DDECL_END(),
447 D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4,
449 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
450 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
451 {0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
452 D3DDECL_END(),
456 D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR,
458 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
459 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
460 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
461 D3DDECL_END(),
465 D3DFVF_XYZB1,
467 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
468 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
469 D3DDECL_END(),
473 D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4,
475 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
476 {0, 12, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
477 D3DDECL_END(),
481 D3DFVF_XYZB1 | D3DFVF_LASTBETA_D3DCOLOR,
483 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
484 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
485 D3DDECL_END(),
489 D3DFVF_XYZB2,
491 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
492 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
493 D3DDECL_END(),
497 D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4,
499 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
500 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
501 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
502 D3DDECL_END(),
506 D3DFVF_XYZB2 | D3DFVF_LASTBETA_D3DCOLOR,
508 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
509 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
510 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
511 D3DDECL_END(),
515 D3DFVF_XYZB3,
517 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
518 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
519 D3DDECL_END(),
523 D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4,
525 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
526 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
527 {0, 20, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
528 D3DDECL_END(),
532 D3DFVF_XYZB3 | D3DFVF_LASTBETA_D3DCOLOR,
534 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
535 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
536 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
537 D3DDECL_END(),
541 D3DFVF_XYZB4,
543 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
544 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
545 D3DDECL_END(),
549 D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4,
551 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
552 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
553 {0, 24, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
554 D3DDECL_END(),
558 D3DFVF_XYZB4 | D3DFVF_LASTBETA_D3DCOLOR,
560 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
561 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
562 {0, 24, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
563 D3DDECL_END(),
566 {D3DFVF_NORMAL, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}},
567 {D3DFVF_PSIZE, {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}},
568 {D3DFVF_DIFFUSE, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}},
569 {D3DFVF_SPECULAR, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}},
570 /* Make sure textures of different sizes work. */
572 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1,
573 {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
576 D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1,
577 {{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
580 D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1,
581 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
584 D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1,
585 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
587 /* Make sure the TEXCOORD index works correctly - try several textures. */
589 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE2(2)
590 | D3DFVF_TEXCOORDSIZE4(3) | D3DFVF_TEX4,
592 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
593 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
594 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
595 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
596 D3DDECL_END(),
599 /* Now try a combination test. */
601 D3DFVF_XYZB4 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEXCOORDSIZE2(0)
602 | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEX2,
604 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
605 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
606 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
607 {0, 32, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
608 {0, 36, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0},
609 {0, 44, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
610 D3DDECL_END(),
615 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
616 0, 0, 640, 480, NULL, NULL, NULL, NULL);
617 d3d = Direct3DCreate9(D3D_SDK_VERSION);
618 ok(!!d3d, "Failed to create a D3D object.\n");
619 if (!(device = create_device(d3d, window, NULL)))
621 skip("Failed to create a D3D device, skipping tests.\n");
622 goto done;
625 for (i = 0; i < sizeof(decl_to_fvf_tests) / sizeof(*decl_to_fvf_tests); ++i)
627 DWORD fvf = 0xdeadbeef;
628 HRESULT hr;
630 /* Set a default FVF of SPECULAR and DIFFUSE to make sure it is changed
631 * back to 0. */
632 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
633 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#x.\n", i, hr);
635 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_to_fvf_tests[i].elements, &declaration);
636 ok(SUCCEEDED(hr), "Test %u: Failed to create vertex declaration, hr %#x.\n", i, hr);
637 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
638 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#x.\n", i, hr);
640 /* Check the FVF. */
641 hr = IDirect3DDevice9_GetFVF(device, &fvf);
642 ok(SUCCEEDED(hr), "Test %u: Failed to get FVF, hr %#x.\n", i, hr);
644 if (decl_to_fvf_tests[i].todo)
645 todo_wine ok(fvf == decl_to_fvf_tests[i].fvf,
646 "Test %u: Got unexpected FVF %#x, expected %#x.\n",
647 i, fvf, decl_to_fvf_tests[i].fvf);
648 else
649 ok(fvf == decl_to_fvf_tests[i].fvf,
650 "Test %u: Got unexpected FVF %#x, expected %#x.\n",
651 i, fvf, decl_to_fvf_tests[i].fvf);
653 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
654 IDirect3DVertexDeclaration9_Release(declaration);
657 /* Create a default declaration and FVF that does not match any of the
658 * tests. */
659 hr = IDirect3DDevice9_CreateVertexDeclaration(device, default_elements, &default_decl);
660 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
662 for (i = 0; i < sizeof(fvf_to_decl_tests) / sizeof(*fvf_to_decl_tests); ++i)
664 /* Set a default declaration to make sure it is changed. */
665 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
666 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#x.\n", i, hr);
668 hr = IDirect3DDevice9_SetFVF(device, fvf_to_decl_tests[i].fvf);
669 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#x.\n", i, hr);
671 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
672 ok(SUCCEEDED(hr), "Test %u: Failed to get vertex declaration, hr %#x.\n", i, hr);
673 ok(!!declaration && declaration != default_decl,
674 "Test %u: Got unexpected declaration %p.\n", i, declaration);
675 ok(compare_elements(declaration, fvf_to_decl_tests[i].elements),
676 "Test %u: Declaration does not match.\n", i);
677 IDirect3DVertexDeclaration9_Release(declaration);
680 /* Setting the FVF to 0 should result in no change to the default decl. */
681 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
682 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
683 hr = IDirect3DDevice9_SetFVF(device, 0);
684 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
685 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
686 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
687 ok(declaration == default_decl, "Got unexpected declaration %p, expected %p.\n", declaration, default_decl);
688 IDirect3DVertexDeclaration9_Release(declaration);
690 IDirect3DVertexDeclaration9_Release(default_decl);
691 refcount = IDirect3DDevice9_Release(device);
692 ok(!refcount, "Device has %u references left.\n", refcount);
693 done:
694 IDirect3D9_Release(d3d);
695 DestroyWindow(window);
698 /* Check whether a declaration converted from FVF is shared.
699 * Check whether refcounts behave as expected. */
700 static void test_fvf_decl_management(void)
702 IDirect3DVertexDeclaration9 *declaration1;
703 IDirect3DVertexDeclaration9 *declaration2;
704 IDirect3DVertexDeclaration9 *declaration3;
705 IDirect3DVertexDeclaration9 *declaration4;
706 IDirect3DDevice9 *device;
707 IDirect3D9 *d3d;
708 ULONG refcount;
709 HWND window;
710 HRESULT hr;
712 static const D3DVERTEXELEMENT9 test_elements1[] =
713 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()};
714 static const D3DVERTEXELEMENT9 test_elements2[] =
715 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()};
717 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
718 0, 0, 640, 480, NULL, NULL, NULL, NULL);
719 d3d = Direct3DCreate9(D3D_SDK_VERSION);
720 ok(!!d3d, "Failed to create a D3D object.\n");
721 if (!(device = create_device(d3d, window, NULL)))
723 skip("Failed to create a D3D device, skipping tests.\n");
724 goto done;
727 /* Clear down any current vertex declaration. */
728 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
729 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
730 /* Conversion. */
731 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
732 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
733 /* Get converted decl (#1). */
734 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration1);
735 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
736 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
737 /* Get converted decl again (#2). */
738 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration2);
739 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
740 ok(declaration2 == declaration1, "Got unexpected declaration2 %p, expected %p.\n", declaration2, declaration1);
742 /* Conversion. */
743 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_NORMAL);
744 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
745 /* Get converted decl (#3). */
746 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration3);
747 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
748 ok(declaration3 != declaration2, "Got unexpected declaration3 %p.\n", declaration3);
749 /* The contents should correspond to the second conversion. */
750 ok(compare_elements(declaration3, test_elements2), "Declaration does not match.\n");
751 /* Re-Check if the first decl was overwritten by the new Get(). */
752 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
754 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
755 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
756 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration4);
757 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
758 ok(declaration4 == declaration1, "Got unexpected declaration4 %p, expected %p.\n", declaration4, declaration1);
760 refcount = get_refcount((IUnknown*)declaration1);
761 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
762 refcount = get_refcount((IUnknown*)declaration2);
763 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
764 refcount = get_refcount((IUnknown*)declaration3);
765 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
766 refcount = get_refcount((IUnknown*)declaration4);
767 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
769 IDirect3DVertexDeclaration9_Release(declaration4);
770 IDirect3DVertexDeclaration9_Release(declaration3);
771 IDirect3DVertexDeclaration9_Release(declaration2);
772 IDirect3DVertexDeclaration9_Release(declaration1);
774 refcount = IDirect3DDevice9_Release(device);
775 ok(!refcount, "Device has %u references left.\n", refcount);
776 done:
777 IDirect3D9_Release(d3d);
778 DestroyWindow(window);
781 static void test_vertex_declaration_alignment(void)
783 IDirect3DVertexDeclaration9 *declaration;
784 IDirect3DDevice9 *device;
785 IDirect3D9 *d3d;
786 unsigned int i;
787 ULONG refcount;
788 HWND window;
789 HRESULT hr;
791 static const struct
793 D3DVERTEXELEMENT9 elements[3];
794 HRESULT hr;
796 test_data[] =
800 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
801 {0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
802 D3DDECL_END(),
803 }, D3D_OK,
807 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
808 {0, 17, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
809 D3DDECL_END(),
810 }, E_FAIL,
814 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
815 {0, 18, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
816 D3DDECL_END(),
817 }, E_FAIL,
821 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
822 {0, 19, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
823 D3DDECL_END(),
824 }, E_FAIL,
828 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
829 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
830 D3DDECL_END(),
831 }, D3D_OK,
835 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
836 0, 0, 640, 480, NULL, NULL, NULL, NULL);
837 d3d = Direct3DCreate9(D3D_SDK_VERSION);
838 ok(!!d3d, "Failed to create a D3D object.\n");
839 if (!(device = create_device(d3d, window, NULL)))
841 skip("Failed to create a D3D device, skipping tests.\n");
842 goto done;
845 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
847 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_data[i].elements, &declaration);
848 ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr);
849 if (SUCCEEDED(hr))
850 IDirect3DVertexDeclaration9_Release(declaration);
853 refcount = IDirect3DDevice9_Release(device);
854 ok(!refcount, "Device has %u references left.\n", refcount);
855 done:
856 IDirect3D9_Release(d3d);
857 DestroyWindow(window);
860 static void test_unused_declaration_type(void)
862 IDirect3DVertexDeclaration9 *declaration;
863 IDirect3DDevice9 *device;
864 IDirect3D9 *d3d;
865 unsigned int i;
866 ULONG refcount;
867 HWND window;
868 HRESULT hr;
870 static const D3DVERTEXELEMENT9 test_elements[][3] =
873 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
874 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_COLOR , 0 },
875 D3DDECL_END(),
878 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
879 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 0 },
880 D3DDECL_END(),
883 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
884 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 1 },
885 D3DDECL_END(),
888 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
889 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
890 D3DDECL_END(),
893 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
894 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
895 D3DDECL_END(),
898 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
899 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
900 D3DDECL_END(),
903 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
904 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
905 D3DDECL_END(),
909 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
910 0, 0, 640, 480, NULL, NULL, NULL, NULL);
911 d3d = Direct3DCreate9(D3D_SDK_VERSION);
912 ok(!!d3d, "Failed to create a D3D object.\n");
913 if (!(device = create_device(d3d, window, NULL)))
915 skip("Failed to create a D3D device, skipping tests.\n");
916 goto done;
919 for (i = 0; i < sizeof(test_elements) / sizeof(*test_elements); ++i)
921 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &declaration);
922 ok(hr == E_FAIL, "Test %u: Got unexpected hr %#x.\n", i, hr);
925 refcount = IDirect3DDevice9_Release(device);
926 ok(!refcount, "Device has %u references left.\n", refcount);
927 done:
928 IDirect3D9_Release(d3d);
929 DestroyWindow(window);
932 static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count)
934 IDirect3DBaseTexture9* texture = NULL;
935 HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0,
936 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
938 if (SUCCEEDED(hr)) {
939 DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
940 ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
941 } else
942 trace("CreateTexture failed: %08x\n", hr);
944 if (texture) IDirect3DBaseTexture9_Release( texture );
947 static void test_mipmap_levels(void)
949 IDirect3DDevice9 *device;
950 IDirect3D9 *d3d;
951 ULONG refcount;
952 HWND window;
954 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
955 0, 0, 640, 480, NULL, NULL, NULL, NULL);
956 ok(!!window, "Failed to create a window.\n");
957 d3d = Direct3DCreate9(D3D_SDK_VERSION);
958 ok(!!d3d, "Failed to create a D3D object.\n");
959 if (!(device = create_device(d3d, window, NULL)))
961 skip("Failed to create a 3D device, skipping test.\n");
962 goto cleanup;
965 check_mipmap_levels(device, 32, 32, 6);
966 check_mipmap_levels(device, 256, 1, 9);
967 check_mipmap_levels(device, 1, 256, 9);
968 check_mipmap_levels(device, 1, 1, 1);
970 refcount = IDirect3DDevice9_Release(device);
971 ok(!refcount, "Device has %u references left.\n", refcount);
972 cleanup:
973 IDirect3D9_Release(d3d);
974 DestroyWindow(window);
977 static void test_checkdevicemultisampletype(void)
979 IDirect3DDevice9 *device;
980 DWORD quality_levels;
981 IDirect3D9 *d3d;
982 ULONG refcount;
983 HWND window;
984 HRESULT hr;
986 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
987 0, 0, 640, 480, NULL, NULL, NULL, NULL);
988 ok(!!window, "Failed to create a window.\n");
989 d3d = Direct3DCreate9(D3D_SDK_VERSION);
990 ok(!!d3d, "Failed to create a D3D object.\n");
991 if (!(device = create_device(d3d, window, NULL)))
993 skip("Failed to create a 3D device, skipping test.\n");
994 goto cleanup;
997 quality_levels = 0;
998 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
999 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality_levels);
1000 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
1001 if (hr == D3DERR_NOTAVAILABLE)
1003 skip("IDirect3D9_CheckDeviceMultiSampleType not available\n");
1004 goto cleanup;
1006 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
1008 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1009 D3DFMT_X8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality_levels);
1010 ok(SUCCEEDED(hr), "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
1011 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
1013 cleanup:
1014 if (device)
1016 refcount = IDirect3DDevice9_Release(device);
1017 ok(!refcount, "Device has %u references left.\n", refcount);
1019 IDirect3D9_Release(d3d);
1020 DestroyWindow(window);
1023 static void test_swapchain(void)
1025 IDirect3DSwapChain9 *swapchain0;
1026 IDirect3DSwapChain9 *swapchain1;
1027 IDirect3DSwapChain9 *swapchain2;
1028 IDirect3DSwapChain9 *swapchain3;
1029 IDirect3DSwapChain9 *swapchainX;
1030 IDirect3DSurface9 *backbuffer;
1031 D3DPRESENT_PARAMETERS d3dpp;
1032 IDirect3DDevice9 *device;
1033 IDirect3D9 *d3d;
1034 ULONG refcount;
1035 HWND window;
1036 HRESULT hr;
1038 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1039 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1040 ok(!!window, "Failed to create a window.\n");
1041 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1042 ok(!!d3d, "Failed to create a D3D object.\n");
1043 if (!(device = create_device(d3d, window, NULL)))
1045 skip("Failed to create a 3D device, skipping test.\n");
1046 goto cleanup;
1049 /* Get the implicit swapchain */
1050 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain0);
1051 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
1052 /* Check if the back buffer count was modified */
1053 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain0, &d3dpp);
1054 ok(d3dpp.BackBufferCount == 1, "Got unexpected back buffer count %u.\n", d3dpp.BackBufferCount);
1055 IDirect3DSwapChain9_Release(swapchain0);
1057 /* Check if there is a back buffer */
1058 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1059 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1060 ok(backbuffer != NULL, "The back buffer is NULL\n");
1061 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1063 /* Try to get a nonexistent swapchain */
1064 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1065 ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr);
1066 ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
1067 if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
1069 /* Create a bunch of swapchains */
1070 d3dpp.BackBufferCount = 0;
1071 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1072 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1073 ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
1075 d3dpp.BackBufferCount = 1;
1076 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain2);
1077 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1079 d3dpp.BackBufferCount = 2;
1080 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain3);
1081 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1082 if(SUCCEEDED(hr)) {
1083 /* Swapchain 3, created with backbuffercount 2 */
1084 backbuffer = (void *) 0xdeadbeef;
1085 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
1086 ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%08x)\n", hr);
1087 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1088 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1090 backbuffer = (void *) 0xdeadbeef;
1091 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
1092 ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%08x)\n", hr);
1093 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1094 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1096 backbuffer = (void *) 0xdeadbeef;
1097 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
1098 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
1099 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1100 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1102 backbuffer = (void *) 0xdeadbeef;
1103 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
1104 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1105 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1106 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1109 /* Check the back buffers of the swapchains */
1110 /* Swapchain 1, created with backbuffercount 0 */
1111 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1112 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1113 ok(backbuffer != NULL, "The back buffer is NULL (%08x)\n", hr);
1114 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1116 backbuffer = (void *) 0xdeadbeef;
1117 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
1118 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1119 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1120 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1122 /* Swapchain 2 - created with backbuffercount 1 */
1123 backbuffer = (void *) 0xdeadbeef;
1124 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
1125 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1126 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1127 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1129 backbuffer = (void *) 0xdeadbeef;
1130 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
1131 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
1132 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1133 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1135 backbuffer = (void *) 0xdeadbeef;
1136 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
1137 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1138 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1139 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1141 /* Try getSwapChain on a manually created swapchain
1142 * it should fail, apparently GetSwapChain only returns implicit swapchains
1144 swapchainX = (void *) 0xdeadbeef;
1145 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1146 ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%08x)\n", hr);
1147 ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
1148 if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
1150 IDirect3DSwapChain9_Release(swapchain3);
1151 IDirect3DSwapChain9_Release(swapchain2);
1152 IDirect3DSwapChain9_Release(swapchain1);
1153 refcount = IDirect3DDevice9_Release(device);
1154 ok(!refcount, "Device has %u references left.\n", refcount);
1155 cleanup:
1156 IDirect3D9_Release(d3d);
1157 DestroyWindow(window);
1160 static void test_refcount(void)
1162 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
1163 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
1164 IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
1165 IDirect3DVertexShader9 *pVertexShader = NULL;
1166 IDirect3DPixelShader9 *pPixelShader = NULL;
1167 IDirect3DCubeTexture9 *pCubeTexture = NULL;
1168 IDirect3DTexture9 *pTexture = NULL;
1169 IDirect3DVolumeTexture9 *pVolumeTexture = NULL;
1170 IDirect3DVolume9 *pVolumeLevel = NULL;
1171 IDirect3DSurface9 *pStencilSurface = NULL;
1172 IDirect3DSurface9 *pOffscreenSurface = NULL;
1173 IDirect3DSurface9 *pRenderTarget = NULL;
1174 IDirect3DSurface9 *pRenderTarget2 = NULL;
1175 IDirect3DSurface9 *pRenderTarget3 = NULL;
1176 IDirect3DSurface9 *pTextureLevel = NULL;
1177 IDirect3DSurface9 *pBackBuffer = NULL;
1178 IDirect3DStateBlock9 *pStateBlock = NULL;
1179 IDirect3DStateBlock9 *pStateBlock1 = NULL;
1180 IDirect3DSwapChain9 *pSwapChain = NULL;
1181 IDirect3DQuery9 *pQuery = NULL;
1182 D3DPRESENT_PARAMETERS d3dpp;
1183 IDirect3DDevice9 *device;
1184 ULONG refcount = 0, tmp;
1185 IDirect3D9 *d3d, *d3d2;
1186 HWND window;
1187 HRESULT hr;
1189 D3DVERTEXELEMENT9 decl[] =
1191 D3DDECL_END()
1194 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1195 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1196 ok(!!window, "Failed to create a window.\n");
1197 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1198 ok(!!d3d, "Failed to create a D3D object.\n");
1200 CHECK_REFCOUNT(d3d, 1);
1202 if (!(device = create_device(d3d, window, NULL)))
1204 skip("Failed to create a 3D device, skipping test.\n");
1205 goto cleanup;
1208 refcount = get_refcount((IUnknown *)device);
1209 ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
1211 CHECK_REFCOUNT(d3d, 2);
1213 hr = IDirect3DDevice9_GetDirect3D(device, &d3d2);
1214 CHECK_CALL(hr, "GetDirect3D", device, refcount);
1216 ok(d3d2 == d3d, "Expected IDirect3D9 pointers to be equal.\n");
1217 CHECK_REFCOUNT(d3d, 3);
1218 CHECK_RELEASE_REFCOUNT(d3d, 2);
1221 * Check refcount of implicit surfaces and implicit swapchain. Findings:
1222 * - the container is the device OR swapchain
1223 * - they hold a reference to the device
1224 * - they are created with a refcount of 0 (Get/Release returns original refcount)
1225 * - they are not freed if refcount reaches 0.
1226 * - the refcount is not forwarded to the container.
1228 hr = IDirect3DDevice9_GetSwapChain(device, 0, &pSwapChain);
1229 CHECK_CALL(hr, "GetSwapChain", device, ++refcount);
1230 if (pSwapChain)
1232 CHECK_REFCOUNT( pSwapChain, 1);
1234 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1235 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1236 CHECK_REFCOUNT( pSwapChain, 1);
1237 if(pRenderTarget)
1239 CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
1240 CHECK_REFCOUNT( pRenderTarget, 1);
1242 CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
1243 CHECK_REFCOUNT(device, refcount);
1244 CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
1245 CHECK_REFCOUNT(device, refcount);
1247 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1248 CHECK_CALL(hr, "GetRenderTarget", device, refcount);
1249 CHECK_REFCOUNT( pRenderTarget, 2);
1250 CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
1251 CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
1252 CHECK_REFCOUNT(device, --refcount);
1254 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
1255 CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
1256 CHECK_REFCOUNT(device, ++refcount);
1257 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
1258 CHECK_REFCOUNT(device, --refcount);
1261 /* Render target and back buffer are identical. */
1262 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, 0, &pBackBuffer);
1263 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1264 if(pBackBuffer)
1266 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1267 ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
1268 pRenderTarget, pBackBuffer);
1269 pBackBuffer = NULL;
1271 CHECK_REFCOUNT(device, --refcount);
1273 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &pStencilSurface);
1274 CHECK_CALL(hr, "GetDepthStencilSurface", device, ++refcount);
1275 CHECK_REFCOUNT( pSwapChain, 1);
1276 if(pStencilSurface)
1278 CHECK_SURFACE_CONTAINER(pStencilSurface, IID_IDirect3DDevice9, device);
1279 CHECK_REFCOUNT( pStencilSurface, 1);
1281 CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
1282 CHECK_REFCOUNT(device, refcount);
1283 CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
1284 CHECK_REFCOUNT(device, refcount);
1286 CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
1287 CHECK_REFCOUNT(device, --refcount);
1289 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
1290 CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
1291 CHECK_REFCOUNT(device, ++refcount);
1292 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
1293 CHECK_REFCOUNT(device, --refcount);
1294 pStencilSurface = NULL;
1297 CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
1298 CHECK_REFCOUNT(device, --refcount);
1300 /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
1301 CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
1302 CHECK_REFCOUNT(device, ++refcount);
1303 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1304 CHECK_REFCOUNT(device, --refcount);
1305 pSwapChain = NULL;
1308 /* Buffers */
1309 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL);
1310 CHECK_CALL(hr, "CreateIndexBuffer", device, ++refcount );
1311 if(pIndexBuffer)
1313 tmp = get_refcount( (IUnknown *)pIndexBuffer );
1315 hr = IDirect3DDevice9_SetIndices(device, pIndexBuffer);
1316 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1317 hr = IDirect3DDevice9_SetIndices(device, NULL);
1318 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1321 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL);
1322 CHECK_CALL(hr, "CreateVertexBuffer", device, ++refcount);
1323 if(pVertexBuffer)
1325 IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
1326 UINT offset = ~0;
1327 UINT stride = ~0;
1329 tmp = get_refcount( (IUnknown *)pVertexBuffer );
1331 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 3 * sizeof(float));
1332 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1333 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1334 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1336 hr = IDirect3DDevice9_GetStreamSource(device, 0, &pVBuf, &offset, &stride);
1337 ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
1338 ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
1339 ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
1340 ok(offset==0, "offset not 0 (got %u)!\n", offset);
1342 /* Shaders */
1343 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pVertexDeclaration);
1344 CHECK_CALL(hr, "CreateVertexDeclaration", device, ++refcount);
1345 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &pVertexShader);
1346 CHECK_CALL(hr, "CreateVertexShader", device, ++refcount);
1347 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &pPixelShader);
1348 CHECK_CALL(hr, "CreatePixelShader", device, ++refcount);
1349 /* Textures */
1350 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL);
1351 CHECK_CALL(hr, "CreateTexture", device, ++refcount);
1352 if (pTexture)
1354 tmp = get_refcount( (IUnknown *)pTexture );
1356 /* SetTexture should not increase refcounts */
1357 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)pTexture);
1358 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1359 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1360 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1362 /* This should not increment device refcount */
1363 hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
1364 CHECK_CALL(hr, "GetSurfaceLevel", device, refcount);
1365 /* But should increment texture's refcount */
1366 CHECK_REFCOUNT( pTexture, tmp+1 );
1367 /* Because the texture and surface refcount are identical */
1368 if (pTextureLevel)
1370 CHECK_REFCOUNT ( pTextureLevel, tmp+1 );
1371 CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
1372 CHECK_REFCOUNT ( pTexture , tmp+2 );
1373 CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
1374 CHECK_REFCOUNT ( pTexture , tmp+1 );
1375 CHECK_RELEASE_REFCOUNT( pTexture , tmp );
1376 CHECK_REFCOUNT ( pTextureLevel, tmp );
1379 hr = IDirect3DDevice9_CreateCubeTexture(device, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL);
1380 CHECK_CALL(hr, "CreateCubeTexture", device, ++refcount);
1381 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 2, 0, 0,
1382 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL);
1383 CHECK_CALL(hr, "CreateVolumeTexture", device, ++refcount);
1384 if (pVolumeTexture)
1386 tmp = get_refcount( (IUnknown *)pVolumeTexture );
1388 /* This should not increment device refcount */
1389 hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
1390 CHECK_CALL(hr, "GetVolumeLevel", device, refcount);
1391 /* But should increment volume texture's refcount */
1392 CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
1393 /* Because the volume texture and volume refcount are identical */
1394 if (pVolumeLevel)
1396 CHECK_REFCOUNT ( pVolumeLevel , tmp+1 );
1397 CHECK_ADDREF_REFCOUNT ( pVolumeLevel , tmp+2 );
1398 CHECK_REFCOUNT ( pVolumeTexture, tmp+2 );
1399 CHECK_RELEASE_REFCOUNT( pVolumeLevel , tmp+1 );
1400 CHECK_REFCOUNT ( pVolumeTexture, tmp+1 );
1401 CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp );
1402 CHECK_REFCOUNT ( pVolumeLevel , tmp );
1405 /* Surfaces */
1406 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32,
1407 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL);
1408 CHECK_CALL(hr, "CreateDepthStencilSurface", device, ++refcount);
1409 CHECK_REFCOUNT( pStencilSurface, 1 );
1410 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1411 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL);
1412 CHECK_CALL(hr, "CreateOffscreenPlainSurface", device, ++refcount);
1413 CHECK_REFCOUNT( pOffscreenSurface, 1 );
1414 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
1415 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL);
1416 CHECK_CALL(hr, "CreateRenderTarget", device, ++refcount);
1417 CHECK_REFCOUNT( pRenderTarget3, 1 );
1418 /* Misc */
1419 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &pStateBlock);
1420 CHECK_CALL(hr, "CreateStateBlock", device, ++refcount);
1422 memset(&d3dpp, 0, sizeof(d3dpp));
1423 d3dpp.Windowed = TRUE;
1424 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1425 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1426 d3dpp.EnableAutoDepthStencil = TRUE;
1427 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1428 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &pSwapChain);
1429 CHECK_CALL(hr, "CreateAdditionalSwapChain", device, ++refcount);
1430 if(pSwapChain)
1432 /* check implicit back buffer */
1433 hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
1434 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1435 CHECK_REFCOUNT( pSwapChain, 1);
1436 if(pBackBuffer)
1438 CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
1439 CHECK_REFCOUNT( pBackBuffer, 1);
1440 CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
1441 CHECK_REFCOUNT(device, --refcount);
1443 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
1444 CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
1445 CHECK_REFCOUNT(device, ++refcount);
1446 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1447 CHECK_REFCOUNT(device, --refcount);
1448 pBackBuffer = NULL;
1450 CHECK_REFCOUNT( pSwapChain, 1);
1452 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &pQuery);
1453 CHECK_CALL(hr, "CreateQuery", device, ++refcount);
1455 hr = IDirect3DDevice9_BeginStateBlock(device);
1456 CHECK_CALL(hr, "BeginStateBlock", device, refcount);
1457 hr = IDirect3DDevice9_EndStateBlock(device, &pStateBlock1);
1458 CHECK_CALL(hr, "EndStateBlock", device, ++refcount);
1460 /* The implicit render target is not freed if refcount reaches 0.
1461 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
1462 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget2);
1463 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1464 if(pRenderTarget2)
1466 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
1467 ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
1468 pRenderTarget, pRenderTarget2);
1469 CHECK_REFCOUNT(device, --refcount);
1470 pRenderTarget2 = NULL;
1472 pRenderTarget = NULL;
1474 cleanup:
1475 CHECK_RELEASE(device, device, --refcount);
1477 /* Buffers */
1478 CHECK_RELEASE(pVertexBuffer, device, --refcount);
1479 CHECK_RELEASE(pIndexBuffer, device, --refcount);
1480 /* Shaders */
1481 CHECK_RELEASE(pVertexDeclaration, device, --refcount);
1482 CHECK_RELEASE(pVertexShader, device, --refcount);
1483 CHECK_RELEASE(pPixelShader, device, --refcount);
1484 /* Textures */
1485 CHECK_RELEASE(pTextureLevel, device, --refcount);
1486 CHECK_RELEASE(pCubeTexture, device, --refcount);
1487 CHECK_RELEASE(pVolumeTexture, device, --refcount);
1488 /* Surfaces */
1489 CHECK_RELEASE(pStencilSurface, device, --refcount);
1490 CHECK_RELEASE(pOffscreenSurface, device, --refcount);
1491 CHECK_RELEASE(pRenderTarget3, device, --refcount);
1492 /* Misc */
1493 CHECK_RELEASE(pStateBlock, device, --refcount);
1494 CHECK_RELEASE(pSwapChain, device, --refcount);
1495 CHECK_RELEASE(pQuery, device, --refcount);
1496 /* This will destroy device - cannot check the refcount here */
1497 if (pStateBlock1) CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
1498 CHECK_RELEASE_REFCOUNT(d3d, 0);
1499 DestroyWindow(window);
1502 static void test_cursor(void)
1504 IDirect3DSurface9 *cursor = NULL;
1505 IDirect3DDevice9 *device;
1506 CURSORINFO info;
1507 IDirect3D9 *d3d;
1508 ULONG refcount;
1509 HCURSOR cur;
1510 HWND window;
1511 HRESULT hr;
1513 memset(&info, 0, sizeof(info));
1514 info.cbSize = sizeof(info);
1515 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1516 cur = info.hCursor;
1518 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1519 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1520 ok(!!window, "Failed to create a window.\n");
1521 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1522 ok(!!d3d, "Failed to create a D3D object.\n");
1523 if (!(device = create_device(d3d, window, NULL)))
1525 skip("Failed to create a 3D device, skipping test.\n");
1526 goto cleanup;
1529 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1530 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
1531 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
1533 /* Initially hidden */
1534 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1535 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1537 /* Not enabled without a surface*/
1538 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1539 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1541 /* Fails */
1542 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, NULL);
1543 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
1545 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
1546 ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
1548 IDirect3DSurface9_Release(cursor);
1550 memset(&info, 0, sizeof(info));
1551 info.cbSize = sizeof(info);
1552 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1553 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
1554 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
1556 /* Still hidden */
1557 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1558 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1560 /* Enabled now*/
1561 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1562 ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1564 /* GDI cursor unchanged */
1565 memset(&info, 0, sizeof(info));
1566 info.cbSize = sizeof(info);
1567 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1568 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
1569 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
1571 refcount = IDirect3DDevice9_Release(device);
1572 ok(!refcount, "Device has %u references left.\n", refcount);
1573 cleanup:
1574 IDirect3D9_Release(d3d);
1575 DestroyWindow(window);
1578 static void test_reset(void)
1580 HRESULT hr;
1581 RECT winrect;
1582 D3DPRESENT_PARAMETERS d3dpp;
1583 D3DDISPLAYMODE d3ddm, d3ddm2;
1584 D3DVIEWPORT9 vp;
1585 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
1586 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
1587 IDirect3DSwapChain9 *pSwapchain;
1588 IDirect3DSurface9 *surface;
1589 IDirect3DTexture9 *texture;
1590 IDirect3DVertexShader9 *shader;
1591 UINT i, adapter_mode_count;
1592 D3DLOCKED_RECT lockrect;
1593 IDirect3DDevice9 *device1 = NULL;
1594 IDirect3DDevice9 *device2 = NULL;
1595 IDirect3D9 *d3d;
1596 D3DCAPS9 caps;
1597 DWORD value;
1598 HWND hwnd;
1599 struct
1601 UINT w;
1602 UINT h;
1603 } *modes = NULL;
1604 UINT mode_count = 0;
1606 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1607 100, 100, 160, 160, NULL, NULL, NULL, NULL);
1608 ok(!!hwnd, "Failed to create a window.\n");
1609 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1610 ok(!!d3d, "Failed to create a D3D object.\n");
1612 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
1613 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, d3ddm.Format);
1614 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
1615 for(i = 0; i < adapter_mode_count; ++i)
1617 UINT j;
1618 ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
1619 hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
1620 ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#x\n", hr);
1622 for (j = 0; j < mode_count; ++j)
1624 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
1625 break;
1627 if (j == mode_count)
1629 modes[j].w = d3ddm2.Width;
1630 modes[j].h = d3ddm2.Height;
1631 ++mode_count;
1634 /* We use them as invalid modes */
1635 if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
1636 (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
1637 skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
1638 d3ddm2.Width, d3ddm2.Height);
1639 goto cleanup;
1643 if (mode_count < 2)
1645 skip("Less than 2 modes supported, skipping mode tests\n");
1646 goto cleanup;
1649 i = 0;
1650 if (modes[i].w == orig_width && modes[i].h == orig_height) ++i;
1652 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1653 d3dpp.Windowed = FALSE;
1654 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1655 d3dpp.BackBufferWidth = modes[i].w;
1656 d3dpp.BackBufferHeight = modes[i].h;
1657 d3dpp.BackBufferFormat = d3ddm.Format;
1658 d3dpp.EnableAutoDepthStencil = TRUE;
1659 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1661 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1662 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device1);
1663 if (FAILED(hr))
1665 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1666 goto cleanup;
1668 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1669 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1671 hr = IDirect3DDevice9_GetDeviceCaps(device1, &caps);
1672 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
1674 width = GetSystemMetrics(SM_CXSCREEN);
1675 height = GetSystemMetrics(SM_CYSCREEN);
1676 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1677 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1679 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1680 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1681 if(SUCCEEDED(hr))
1683 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1684 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1685 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1686 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1687 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1688 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1691 i = 1;
1692 vp.X = 10;
1693 vp.Y = 20;
1694 vp.MinZ = 2;
1695 vp.MaxZ = 3;
1696 hr = IDirect3DDevice9_SetViewport(device1, &vp);
1697 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1699 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1700 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1701 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1702 hr = IDirect3DDevice9_SetRenderState(device1, D3DRS_LIGHTING, FALSE);
1703 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1705 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1706 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1707 d3dpp.Windowed = FALSE;
1708 d3dpp.BackBufferWidth = modes[i].w;
1709 d3dpp.BackBufferHeight = modes[i].h;
1710 d3dpp.BackBufferFormat = d3ddm.Format;
1711 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1712 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1713 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1714 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1716 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1717 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1718 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1720 ZeroMemory(&vp, sizeof(vp));
1721 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1722 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1723 if(SUCCEEDED(hr))
1725 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1726 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1727 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1728 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1729 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1730 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1733 width = GetSystemMetrics(SM_CXSCREEN);
1734 height = GetSystemMetrics(SM_CYSCREEN);
1735 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1736 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1738 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1739 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1740 if(SUCCEEDED(hr))
1742 ZeroMemory(&d3dpp, sizeof(d3dpp));
1743 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1744 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1745 if(SUCCEEDED(hr))
1747 ok(d3dpp.BackBufferWidth == modes[i].w, "Back buffer width is %u, expected %u\n",
1748 d3dpp.BackBufferWidth, modes[i].w);
1749 ok(d3dpp.BackBufferHeight == modes[i].h, "Back buffer height is %u, expected %u\n",
1750 d3dpp.BackBufferHeight, modes[i].h);
1752 IDirect3DSwapChain9_Release(pSwapchain);
1755 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1756 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1757 d3dpp.Windowed = TRUE;
1758 d3dpp.BackBufferWidth = 400;
1759 d3dpp.BackBufferHeight = 300;
1760 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1761 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1762 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1763 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1765 width = GetSystemMetrics(SM_CXSCREEN);
1766 height = GetSystemMetrics(SM_CYSCREEN);
1767 ok(width == orig_width, "Screen width is %d\n", width);
1768 ok(height == orig_height, "Screen height is %d\n", height);
1770 ZeroMemory(&vp, sizeof(vp));
1771 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1772 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1773 if(SUCCEEDED(hr))
1775 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1776 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1777 ok(vp.Width == 400, "D3DVIEWPORT->Width = %d\n", vp.Width);
1778 ok(vp.Height == 300, "D3DVIEWPORT->Height = %d\n", vp.Height);
1779 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1780 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1783 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1784 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1785 if(SUCCEEDED(hr))
1787 ZeroMemory(&d3dpp, sizeof(d3dpp));
1788 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1789 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1790 if(SUCCEEDED(hr))
1792 ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1793 ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1795 IDirect3DSwapChain9_Release(pSwapchain);
1798 winrect.left = 0;
1799 winrect.top = 0;
1800 winrect.right = 200;
1801 winrect.bottom = 150;
1802 ok(AdjustWindowRect(&winrect, WS_OVERLAPPEDWINDOW, FALSE), "AdjustWindowRect failed\n");
1803 ok(SetWindowPos(hwnd, NULL, 0, 0,
1804 winrect.right-winrect.left,
1805 winrect.bottom-winrect.top,
1806 SWP_NOMOVE|SWP_NOZORDER),
1807 "SetWindowPos failed\n");
1809 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1810 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1811 d3dpp.Windowed = TRUE;
1812 d3dpp.BackBufferWidth = 0;
1813 d3dpp.BackBufferHeight = 0;
1814 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1815 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1816 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1817 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1819 ZeroMemory(&vp, sizeof(vp));
1820 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1821 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1822 if(SUCCEEDED(hr))
1824 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1825 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1826 ok(vp.Width == 200, "D3DVIEWPORT->Width = %d\n", vp.Width);
1827 ok(vp.Height == 150, "D3DVIEWPORT->Height = %d\n", vp.Height);
1828 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1829 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1832 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1833 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1834 if(SUCCEEDED(hr))
1836 ZeroMemory(&d3dpp, sizeof(d3dpp));
1837 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1838 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1839 if(SUCCEEDED(hr))
1841 ok(d3dpp.BackBufferWidth == 200, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1842 ok(d3dpp.BackBufferHeight == 150, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1844 IDirect3DSwapChain9_Release(pSwapchain);
1847 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1848 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1849 d3dpp.Windowed = TRUE;
1850 d3dpp.BackBufferWidth = 400;
1851 d3dpp.BackBufferHeight = 300;
1853 /* _Reset fails if there is a resource in the default pool */
1854 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1855 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1856 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1857 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1858 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1859 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1860 IDirect3DSurface9_Release(surface);
1861 /* Reset again to get the device out of the lost state */
1862 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1863 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1864 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1865 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1867 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1869 IDirect3DVolumeTexture9 *volume_texture;
1871 hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
1872 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1873 ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#x.\n", hr);
1874 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1875 ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
1876 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1877 ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n",
1878 hr, D3DERR_DEVICENOTRESET);
1879 IDirect3DVolumeTexture9_Release(volume_texture);
1880 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1881 ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
1882 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1883 ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#x.\n", hr);
1885 else
1887 skip("Volume textures not supported.\n");
1890 /* Scratch, sysmem and managed pools are fine */
1891 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1893 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1894 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1895 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1896 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1897 IDirect3DSurface9_Release(surface);
1899 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1900 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1901 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1902 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1903 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1904 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1905 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1906 IDirect3DSurface9_Release(surface);
1908 /* The depth stencil should get reset to the auto depth stencil when present. */
1909 hr = IDirect3DDevice9_SetDepthStencilSurface(device1, NULL);
1910 ok(hr == D3D_OK, "SetDepthStencilSurface failed with 0x%08x\n", hr);
1912 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1913 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1914 ok(surface == NULL, "Depth stencil should be NULL\n");
1916 d3dpp.EnableAutoDepthStencil = TRUE;
1917 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1918 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1919 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1921 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1922 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1923 ok(surface != NULL, "Depth stencil should not be NULL\n");
1924 if (surface) IDirect3DSurface9_Release(surface);
1926 d3dpp.EnableAutoDepthStencil = FALSE;
1927 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1928 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1930 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1931 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1932 ok(surface == NULL, "Depth stencil should be NULL\n");
1934 /* Will a sysmem or scratch survive while locked */
1935 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1936 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1937 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1938 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1939 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1940 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1941 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1942 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1943 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1944 IDirect3DSurface9_UnlockRect(surface);
1945 IDirect3DSurface9_Release(surface);
1947 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1948 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1949 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1950 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1951 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1952 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1953 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1954 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1955 IDirect3DSurface9_UnlockRect(surface);
1956 IDirect3DSurface9_Release(surface);
1958 hr = IDirect3DDevice9_CreateTexture(device1, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
1959 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
1960 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1961 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1962 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1963 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1964 IDirect3DTexture9_Release(texture);
1966 /* A reference held to an implicit surface causes failures as well */
1967 hr = IDirect3DDevice9_GetBackBuffer(device1, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1968 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr);
1969 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1970 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1971 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1972 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1973 IDirect3DSurface9_Release(surface);
1974 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1975 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1976 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1977 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1979 /* Shaders are fine as well */
1980 hr = IDirect3DDevice9_CreateVertexShader(device1, simple_vs, &shader);
1981 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
1982 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1983 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1984 IDirect3DVertexShader9_Release(shader);
1986 /* Try setting invalid modes */
1987 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1988 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1989 d3dpp.Windowed = FALSE;
1990 d3dpp.BackBufferWidth = 32;
1991 d3dpp.BackBufferHeight = 32;
1992 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1993 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr);
1994 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1995 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1997 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1998 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1999 d3dpp.Windowed = FALSE;
2000 d3dpp.BackBufferWidth = 801;
2001 d3dpp.BackBufferHeight = 600;
2002 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2003 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr);
2004 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2005 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2007 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2008 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2009 d3dpp.Windowed = FALSE;
2010 d3dpp.BackBufferWidth = 0;
2011 d3dpp.BackBufferHeight = 0;
2012 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
2013 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=0, h=0, windowed=FALSE failed with %08x\n", hr);
2014 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
2015 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
2017 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2019 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2020 d3dpp.Windowed = TRUE;
2021 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2022 d3dpp.BackBufferFormat = d3ddm.Format;
2023 d3dpp.EnableAutoDepthStencil = FALSE;
2024 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2026 if (FAILED(hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2027 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2)))
2029 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
2030 goto cleanup;
2033 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
2034 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
2036 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2037 d3dpp.Windowed = TRUE;
2038 d3dpp.BackBufferWidth = 400;
2039 d3dpp.BackBufferHeight = 300;
2040 d3dpp.EnableAutoDepthStencil = TRUE;
2041 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2043 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
2044 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
2046 if (FAILED(hr)) goto cleanup;
2048 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
2049 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
2050 ok(surface != NULL, "Depth stencil should not be NULL\n");
2051 if (surface) IDirect3DSurface9_Release(surface);
2053 cleanup:
2054 HeapFree(GetProcessHeap(), 0, modes);
2055 if (device2)
2057 UINT refcount = IDirect3DDevice9_Release(device2);
2058 ok(!refcount, "Device has %u references left.\n", refcount);
2060 if (device1)
2062 UINT refcount = IDirect3DDevice9_Release(device1);
2063 ok(!refcount, "Device has %u references left.\n", refcount);
2065 IDirect3D9_Release(d3d);
2066 DestroyWindow(hwnd);
2069 /* Test adapter display modes */
2070 static void test_display_modes(void)
2072 D3DDISPLAYMODE dmode;
2073 IDirect3D9 *d3d;
2075 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2076 ok(!!d3d, "Failed to create a D3D object.\n");
2078 #define TEST_FMT(x,r) do { \
2079 HRESULT res = IDirect3D9_EnumAdapterModes(d3d, 0, (x), 0, &dmode); \
2080 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
2081 } while(0)
2083 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
2084 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
2085 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2086 /* D3DFMT_R5G6B5 */
2087 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
2088 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
2089 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
2090 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
2091 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
2092 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
2093 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
2094 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
2095 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
2096 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2097 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
2098 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
2100 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
2101 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
2103 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
2104 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
2105 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
2107 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
2108 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
2109 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
2110 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
2111 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
2112 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
2114 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
2115 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
2116 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
2117 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
2118 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
2119 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
2120 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
2121 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
2122 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
2123 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
2125 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
2126 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
2127 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
2128 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
2129 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
2130 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
2131 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
2132 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
2133 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
2134 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
2136 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
2137 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
2138 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
2139 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
2140 /* Floating point formats */
2141 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
2142 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
2143 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
2145 /* IEEE formats */
2146 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
2147 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
2148 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
2150 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
2152 TEST_FMT(0, D3DERR_INVALIDCALL);
2154 IDirect3D9_Release(d3d);
2157 static void test_scene(void)
2159 IDirect3DSurface9 *surface1, *surface2, *surface3;
2160 IDirect3DSurface9 *backBuffer, *rt, *ds;
2161 RECT rect = {0, 0, 128, 128};
2162 IDirect3DDevice9 *device;
2163 IDirect3D9 *d3d;
2164 ULONG refcount;
2165 D3DCAPS9 caps;
2166 HWND window;
2167 HRESULT hr;
2169 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2170 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2171 ok(!!window, "Failed to create a window.\n");
2172 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2173 ok(!!d3d, "Failed to create a D3D object.\n");
2174 if (!(device = create_device(d3d, window, NULL)))
2176 skip("Failed to create a 3D device, skipping test.\n");
2177 goto cleanup;
2180 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
2181 memset(&caps, 0, sizeof(caps));
2182 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2183 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
2185 /* Test an EndScene without BeginScene. Should return an error */
2186 hr = IDirect3DDevice9_EndScene(device);
2187 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2189 /* Test a normal BeginScene / EndScene pair, this should work */
2190 hr = IDirect3DDevice9_BeginScene(device);
2191 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2192 hr = IDirect3DDevice9_EndScene(device);
2193 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2195 /* Test another EndScene without having begun a new scene. Should return an error */
2196 hr = IDirect3DDevice9_EndScene(device);
2197 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2199 /* Two nested BeginScene and EndScene calls */
2200 hr = IDirect3DDevice9_BeginScene(device);
2201 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2202 hr = IDirect3DDevice9_BeginScene(device);
2203 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
2204 hr = IDirect3DDevice9_EndScene(device);
2205 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2206 hr = IDirect3DDevice9_EndScene(device);
2207 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2209 /* Create some surfaces to test stretchrect between the scenes */
2210 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2211 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface1, NULL);
2212 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2213 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2214 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface2, NULL);
2215 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2216 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 800, 600,
2217 D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &surface3, NULL);
2218 ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
2219 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
2220 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
2221 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
2223 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
2224 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
2225 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
2226 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
2228 /* First make sure a simple StretchRect call works */
2229 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2230 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2231 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2232 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2233 if (0) /* Disabled for now because it crashes in wine */
2235 HRESULT expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
2236 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2237 ok(hr == expected, "Got unexpected hr %#x, expected %#x.\n", hr, expected);
2240 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a
2241 * BeginScene - Endscene pair with normal surfaces and render targets, but
2242 * not depth stencil surfaces. */
2243 hr = IDirect3DDevice9_BeginScene(device);
2244 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2246 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2247 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2248 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2249 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2250 /* This is supposed to fail inside a BeginScene - EndScene pair. */
2251 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2252 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
2254 hr = IDirect3DDevice9_EndScene(device);
2255 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2257 /* Does a SetRenderTarget influence BeginScene / EndScene ?
2258 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
2259 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
2261 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
2262 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
2263 hr = IDirect3DDevice9_BeginScene(device);
2264 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2265 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backBuffer);
2266 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
2267 hr = IDirect3DDevice9_EndScene(device);
2268 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2270 IDirect3DSurface9_Release(rt);
2271 IDirect3DSurface9_Release(ds);
2272 IDirect3DSurface9_Release(backBuffer);
2273 IDirect3DSurface9_Release(surface1);
2274 IDirect3DSurface9_Release(surface2);
2275 IDirect3DSurface9_Release(surface3);
2276 refcount = IDirect3DDevice9_Release(device);
2277 ok(!refcount, "Device has %u references left.\n", refcount);
2278 cleanup:
2279 IDirect3D9_Release(d3d);
2280 DestroyWindow(window);
2283 static void test_limits(void)
2285 IDirect3DTexture9 *texture;
2286 IDirect3DDevice9 *device;
2287 IDirect3D9 *d3d;
2288 unsigned int i;
2289 ULONG refcount;
2290 HWND window;
2291 HRESULT hr;
2293 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2294 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2295 ok(!!window, "Failed to create a window.\n");
2296 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2297 ok(!!d3d, "Failed to create a D3D object.\n");
2298 if (!(device = create_device(d3d, window, NULL)))
2300 skip("Failed to create a 3D device, skipping test.\n");
2301 goto cleanup;
2304 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
2305 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2307 /* There are 16 pixel samplers. We should be able to access all of them */
2308 for (i = 0; i < 16; ++i)
2310 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture);
2311 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
2312 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2313 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
2314 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_SRGBTEXTURE, TRUE);
2315 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
2318 /* Now test all 8 textures stage states */
2319 for (i = 0; i < 8; ++i)
2321 hr = IDirect3DDevice9_SetTextureStageState(device, i, D3DTSS_COLOROP, D3DTOP_ADD);
2322 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
2325 /* Investigations show that accessing higher samplers / textures stage
2326 * states does not return an error either. Writing to too high samplers
2327 * (approximately sampler 40) causes memory corruption in Windows, so
2328 * there is no bounds checking. */
2329 IDirect3DTexture9_Release(texture);
2330 refcount = IDirect3D9_Release(device);
2331 ok(!refcount, "Device has %u references left.\n", refcount);
2332 cleanup:
2333 IDirect3D9_Release(d3d);
2334 DestroyWindow(window);
2337 static void test_depthstenciltest(void)
2339 HRESULT hr;
2340 IDirect3DDevice9 *pDevice = NULL;
2341 D3DPRESENT_PARAMETERS d3dpp;
2342 D3DDISPLAYMODE d3ddm;
2343 IDirect3DSurface9 *pDepthStencil = NULL;
2344 IDirect3DSurface9 *pDepthStencil2 = NULL;
2345 IDirect3D9 *d3d;
2346 DWORD state;
2347 HWND hwnd;
2349 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2350 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2351 ok(!!hwnd, "Failed to create a window.\n");
2352 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2353 ok(!!d3d, "Failed to create a D3D object.\n");
2355 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2356 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2357 d3dpp.Windowed = TRUE;
2358 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2359 d3dpp.BackBufferWidth = 800;
2360 d3dpp.BackBufferHeight = 600;
2361 d3dpp.BackBufferFormat = d3ddm.Format;
2362 d3dpp.EnableAutoDepthStencil = TRUE;
2363 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2365 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2366 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2367 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || broken(hr == D3DERR_INVALIDCALL), "IDirect3D9_CreateDevice failed with %08x\n", hr);
2368 if(!pDevice)
2370 skip("Failed to create a d3d device\n");
2371 goto cleanup;
2374 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2375 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
2377 /* Try to clear */
2378 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2379 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2381 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
2382 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
2384 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
2385 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
2386 ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
2387 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
2389 /* This left the render states untouched! */
2390 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2391 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2392 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2393 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
2394 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2395 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
2396 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
2397 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2398 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
2399 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
2400 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2401 ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
2403 /* This is supposed to fail now */
2404 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2405 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2407 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
2408 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
2410 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
2411 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
2413 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2414 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2415 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2417 /* Now it works again */
2418 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2419 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2421 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2422 if(pDevice) IDirect3D9_Release(pDevice);
2424 /* Now see if autodepthstencil disable is honored. First, without a format set */
2425 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2426 d3dpp.Windowed = TRUE;
2427 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2428 d3dpp.BackBufferWidth = 800;
2429 d3dpp.BackBufferHeight = 600;
2430 d3dpp.BackBufferFormat = d3ddm.Format;
2431 d3dpp.EnableAutoDepthStencil = FALSE;
2432 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2434 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2435 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2436 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2437 if(!pDevice)
2439 skip("Failed to create a d3d device\n");
2440 goto cleanup;
2443 pDepthStencil = NULL;
2444 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2445 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
2446 if(pDepthStencil) {
2447 IDirect3DSurface9_Release(pDepthStencil);
2448 pDepthStencil = NULL;
2451 /* Check the depth test state */
2452 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2453 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2454 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2456 if(pDevice) IDirect3D9_Release(pDevice);
2458 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
2459 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2460 d3dpp.Windowed = TRUE;
2461 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2462 d3dpp.BackBufferWidth = 800;
2463 d3dpp.BackBufferHeight = 600;
2464 d3dpp.BackBufferFormat = d3ddm.Format;
2465 d3dpp.EnableAutoDepthStencil = FALSE;
2466 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2468 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2469 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2470 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2471 if(!pDevice)
2473 skip("Failed to create a d3d device\n");
2474 goto cleanup;
2477 pDepthStencil = NULL;
2478 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2479 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
2480 if(pDepthStencil) {
2481 IDirect3DSurface9_Release(pDepthStencil);
2482 pDepthStencil = NULL;
2485 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2486 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2487 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2489 cleanup:
2490 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2491 if (pDevice)
2493 UINT refcount = IDirect3D9_Release(pDevice);
2494 ok(!refcount, "Device has %u references left.\n", refcount);
2496 IDirect3D9_Release(d3d);
2497 DestroyWindow(hwnd);
2500 static void test_get_rt(void)
2502 IDirect3DSurface9 *backbuffer, *rt;
2503 IDirect3DDevice9 *device;
2504 IDirect3D9 *d3d9;
2505 D3DCAPS9 caps;
2506 HWND window;
2507 HRESULT hr;
2508 ULONG ref;
2509 UINT i;
2511 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2512 0, 0, 128, 128, 0, 0, 0, 0);
2513 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2514 ok(!!d3d9, "Failed to create a D3D object.\n");
2515 device = create_device(d3d9, window, NULL);
2516 if (!device)
2518 skip("Failed to create a D3D device, skipping tests.\n");
2519 goto done;
2522 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
2523 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
2524 ok(!!backbuffer, "Got a NULL backbuffer.\n");
2526 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2527 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2529 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
2531 rt = backbuffer;
2532 hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
2533 ok(hr == D3DERR_NOTFOUND, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr);
2534 ok(!rt, "Got rt %p.\n", rt);
2537 IDirect3DSurface9_Release(backbuffer);
2539 ref = IDirect3DDevice9_Release(device);
2540 ok(!ref, "The device was not properly freed: refcount %u.\n", ref);
2541 done:
2542 IDirect3D9_Release(d3d9);
2543 DestroyWindow(window);
2546 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
2547 static void test_draw_indexed(void)
2549 static const struct {
2550 float position[3];
2551 DWORD color;
2552 } quad[] = {
2553 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2554 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2555 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2556 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2558 WORD indices[] = {0, 1, 2, 3, 0, 2};
2560 static const D3DVERTEXELEMENT9 decl_elements[] = {
2561 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2562 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2563 D3DDECL_END()
2566 IDirect3DVertexDeclaration9 *vertex_declaration;
2567 IDirect3DVertexBuffer9 *vertex_buffer;
2568 IDirect3DIndexBuffer9 *index_buffer;
2569 IDirect3DDevice9 *device;
2570 IDirect3D9 *d3d9;
2571 ULONG refcount;
2572 HWND window;
2573 HRESULT hr;
2574 void *ptr;
2576 window = CreateWindowA("d3d9_test_wc", "d3d9_test", 0,
2577 0, 0, 640, 480, 0, 0, 0, 0);
2578 ok(!!window, "Failed to create a window.\n");
2579 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2580 ok(!!d3d9, "Failed to create a D3D object.\n");
2581 if (!(device = create_device(d3d9, window, NULL)))
2583 skip("Failed to create a 3D device, skipping test.\n");
2584 goto cleanup;
2587 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2588 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2589 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2590 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2592 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
2593 ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
2594 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
2595 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
2596 memcpy(ptr, quad, sizeof(quad));
2597 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
2598 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
2599 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
2600 ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
2602 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
2603 ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
2604 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
2605 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
2606 memcpy(ptr, indices, sizeof(indices));
2607 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
2608 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
2609 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2610 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
2611 hr = IDirect3DDevice9_BeginScene(device);
2612 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2614 /* NULL index buffer. Should fail */
2615 hr = IDirect3DDevice9_SetIndices(device, NULL);
2616 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
2617 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2618 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2619 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
2620 hr, D3DERR_INVALIDCALL);
2622 /* Valid index buffer, NULL vertex declaration. Should fail */
2623 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
2624 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
2625 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2626 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2627 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
2628 hr, D3DERR_INVALIDCALL);
2630 /* Valid index buffer and vertex declaration. Should succeed */
2631 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2632 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2633 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2634 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2635 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
2637 hr = IDirect3DDevice9_EndScene(device);
2638 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2640 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2641 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2643 IDirect3DVertexBuffer9_Release(vertex_buffer);
2644 IDirect3DIndexBuffer9_Release(index_buffer);
2645 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2646 refcount = IDirect3DDevice9_Release(device);
2647 ok(!refcount, "Device has %u references left.\n", refcount);
2648 cleanup:
2649 IDirect3D9_Release(d3d9);
2650 DestroyWindow(window);
2653 static void test_null_stream(void)
2655 IDirect3DVertexBuffer9 *buffer = NULL;
2656 IDirect3DDevice9 *device;
2657 IDirect3D9 *d3d9;
2658 ULONG refcount;
2659 HWND window;
2660 HRESULT hr;
2661 IDirect3DVertexShader9 *shader = NULL;
2662 IDirect3DVertexDeclaration9 *decl = NULL;
2663 static const DWORD shader_code[] =
2665 0xfffe0101, /* vs_1_1 */
2666 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2667 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2668 0x0000ffff /* end */
2670 static const D3DVERTEXELEMENT9 decl_elements[] = {
2671 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2672 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2673 D3DDECL_END()
2676 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2677 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2678 ok(!!window, "Failed to create a window.\n");
2679 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2680 ok(!!d3d9, "Failed to create a D3D object.\n");
2681 if (!(device = create_device(d3d9, window, NULL)))
2683 skip("Failed to create a 3D device, skipping test.\n");
2684 goto cleanup;
2687 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2688 if(FAILED(hr)) {
2689 skip("No vertex shader support\n");
2690 goto cleanup;
2692 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2693 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2694 if (FAILED(hr)) {
2695 skip("Vertex declaration handling not possible.\n");
2696 goto cleanup;
2698 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
2699 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
2700 if (FAILED(hr)) {
2701 skip("Vertex buffer handling not possible.\n");
2702 goto cleanup;
2705 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
2706 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2707 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
2708 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2709 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2710 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
2711 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2712 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
2714 hr = IDirect3DDevice9_BeginScene(device);
2715 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2716 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
2717 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2718 hr = IDirect3DDevice9_EndScene(device);
2719 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2721 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2722 IDirect3DDevice9_SetVertexShader(device, NULL);
2723 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2725 cleanup:
2726 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2727 if (decl) IDirect3DVertexDeclaration9_Release(decl);
2728 if (shader) IDirect3DVertexShader9_Release(shader);
2729 if (device)
2731 refcount = IDirect3DDevice9_Release(device);
2732 ok(!refcount, "Device has %u references left.\n", refcount);
2734 IDirect3D9_Release(d3d9);
2735 DestroyWindow(window);
2738 static void test_lights(void)
2740 IDirect3DDevice9 *device;
2741 IDirect3D9 *d3d9;
2742 ULONG refcount;
2743 HWND window;
2744 HRESULT hr;
2745 unsigned int i;
2746 BOOL enabled;
2747 D3DCAPS9 caps;
2749 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2750 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2751 ok(!!window, "Failed to create a window.\n");
2752 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2753 ok(!!d3d9, "Failed to create a D3D object.\n");
2754 if (!(device = create_device(d3d9, window, NULL)))
2756 skip("Failed to create a 3D device, skipping test.\n");
2757 goto cleanup;
2760 memset(&caps, 0, sizeof(caps));
2761 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2762 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
2764 for(i = 1; i <= caps.MaxActiveLights; i++) {
2765 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
2766 ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
2767 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
2768 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
2769 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
2772 /* TODO: Test the rendering results in this situation */
2773 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
2774 ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
2775 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
2776 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
2777 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
2778 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
2779 ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
2781 for(i = 1; i <= caps.MaxActiveLights; i++) {
2782 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
2783 ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
2786 refcount = IDirect3DDevice9_Release(device);
2787 ok(!refcount, "Device has %u references left.\n", refcount);
2788 cleanup:
2789 IDirect3D9_Release(d3d9);
2790 DestroyWindow(window);
2793 static void test_set_stream_source(void)
2795 IDirect3DVertexBuffer9 *vb;
2796 IDirect3DDevice9 *device;
2797 IDirect3D9 *d3d9;
2798 ULONG refcount;
2799 HWND window;
2800 HRESULT hr;
2802 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2803 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2804 ok(!!window, "Failed to create a window.\n");
2805 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2806 ok(!!d3d9, "Failed to create a D3D object.\n");
2807 if (!(device = create_device(d3d9, window, NULL)))
2809 skip("Failed to create a 3D device, skipping test.\n");
2810 goto cleanup;
2813 hr = IDirect3DDevice9_CreateVertexBuffer(device, 512, 0, 0, D3DPOOL_DEFAULT, &vb, NULL);
2814 ok(SUCCEEDED(hr), "Failed to create a vertex buffer, hr %#x.\n", hr);
2816 /* Some cards (GeForce 7400 at least) accept non-aligned offsets, others
2817 * (Radeon 9000 verified) reject them, so accept both results. Wine
2818 * currently rejects this to be able to optimize the vbo conversion, but
2819 * writes a WARN. */
2820 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, 32);
2821 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2822 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 1, 32);
2823 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2824 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 2, 32);
2825 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2826 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 3, 32);
2827 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2828 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 4, 32);
2829 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2831 /* Try to set the NULL buffer with an offset and stride 0 */
2832 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2833 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2834 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
2835 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2836 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
2837 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2838 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
2839 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2840 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
2841 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2843 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2844 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2846 IDirect3DVertexBuffer9_Release(vb);
2847 refcount = IDirect3DDevice9_Release(device);
2848 ok(!refcount, "Device has %u references left.\n", refcount);
2849 cleanup:
2850 IDirect3D9_Release(d3d9);
2851 DestroyWindow(window);
2854 /* Direct3D9 offers 4 display formats: R5G6B5, X1R5G5B5, X8R8G8B8 and
2855 * A2R10G10B10. Next to these there are 6 different back buffer formats. Only
2856 * a fixed number of combinations are possible in fullscreen mode. In windowed
2857 * mode more combinations are allowed due to format conversion and this is
2858 * likely driver dependent. */
2859 static void test_display_formats(void)
2861 D3DDEVTYPE device_type = D3DDEVTYPE_HAL;
2862 unsigned int backbuffer, display;
2863 unsigned int windowed;
2864 IDirect3D9 *d3d9;
2865 BOOL should_pass;
2866 BOOL has_modes;
2867 HRESULT hr;
2869 static const struct
2871 const char *name;
2872 D3DFORMAT format;
2873 D3DFORMAT alpha_format;
2874 BOOL display;
2875 BOOL windowed;
2877 formats[] =
2879 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, 0, TRUE, TRUE},
2880 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE, TRUE},
2881 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE, FALSE},
2882 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE, TRUE},
2883 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, FALSE},
2884 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, 0, TRUE, FALSE},
2885 {"D3DFMT_UNKNOWN", D3DFMT_UNKNOWN, 0, FALSE, FALSE},
2888 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2889 ok(!!d3d9, "Failed to create a D3D object.\n");
2891 for (display = 0; display < sizeof(formats) / sizeof(*formats); ++display)
2893 has_modes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, formats[display].format);
2895 for (windowed = 0; windowed <= 1; ++windowed)
2897 for (backbuffer = 0; backbuffer < sizeof(formats) / sizeof(*formats); ++backbuffer)
2899 should_pass = FALSE;
2901 if (formats[display].display && (formats[display].windowed || !windowed) && (has_modes || windowed))
2903 D3DFORMAT backbuffer_format;
2905 if (windowed && formats[backbuffer].format == D3DFMT_UNKNOWN)
2906 backbuffer_format = formats[display].format;
2907 else
2908 backbuffer_format = formats[backbuffer].format;
2910 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, device_type, formats[display].format,
2911 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, backbuffer_format);
2912 if (hr == D3D_OK)
2914 if (windowed)
2916 hr = IDirect3D9_CheckDeviceFormatConversion(d3d9, D3DADAPTER_DEFAULT, device_type,
2917 backbuffer_format, formats[display].format);
2918 should_pass = (hr == D3D_OK);
2920 else
2921 should_pass = (formats[display].format == formats[backbuffer].format
2922 || (formats[display].alpha_format
2923 && formats[display].alpha_format == formats[backbuffer].alpha_format));
2927 hr = IDirect3D9_CheckDeviceType(d3d9, D3DADAPTER_DEFAULT, device_type,
2928 formats[display].format, formats[backbuffer].format, windowed);
2929 ok(SUCCEEDED(hr) == should_pass || broken(SUCCEEDED(hr) && !has_modes) /* Win8 64-bit */,
2930 "Got unexpected hr %#x for %s / %s, windowed %#x, should_pass %#x.\n",
2931 hr, formats[display].name, formats[backbuffer].name, windowed, should_pass);
2936 IDirect3D9_Release(d3d9);
2939 static void test_scissor_size(void)
2941 struct device_desc device_desc;
2942 IDirect3D9 *d3d9_ptr;
2943 unsigned int i;
2944 static struct {
2945 int winx; int winy; int backx; int backy; BOOL window;
2946 } scts[] = { /* scissor tests */
2947 {800, 600, 640, 480, TRUE},
2948 {800, 600, 640, 480, FALSE},
2949 {640, 480, 800, 600, TRUE},
2950 {640, 480, 800, 600, FALSE},
2953 d3d9_ptr = Direct3DCreate9(D3D_SDK_VERSION);
2954 ok(!!d3d9_ptr, "Failed to create a D3D object.\n");
2956 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2957 IDirect3DDevice9 *device_ptr = 0;
2958 HRESULT hr;
2959 HWND hwnd = 0;
2960 RECT scissorrect;
2962 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
2963 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
2965 if (!scts[i].window)
2967 scts[i].backx = screen_width;
2968 scts[i].backy = screen_height;
2971 device_desc.device_window = hwnd;
2972 device_desc.width = scts[i].backx;
2973 device_desc.height = scts[i].backy;
2974 device_desc.windowed = scts[i].window;
2975 if (!(device_ptr = create_device(d3d9_ptr, hwnd, &device_desc)))
2977 skip("Failed to create a 3D device, skipping test.\n");
2978 DestroyWindow(hwnd);
2979 goto err_out;
2982 /* Check for the default scissor rect size */
2983 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2984 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2985 ok(scissorrect.right == scts[i].backx && scissorrect.bottom == scts[i].backy && scissorrect.top == 0 && scissorrect.left == 0, "Scissorrect missmatch (%d, %d) should be (%d, %d)\n", scissorrect.right, scissorrect.bottom, scts[i].backx, scts[i].backy);
2987 /* check the scissorrect values after a reset */
2988 hr = reset_device(device_ptr, hwnd, scts[i].window);
2989 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2990 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
2991 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2993 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2994 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2995 ok(scissorrect.right == screen_width && scissorrect.bottom == screen_height && scissorrect.top == 0 && scissorrect.left == 0, "Scissorrect missmatch (%d, %d) should be (%d, %d)\n", scissorrect.right, scissorrect.bottom, screen_width, screen_height);
2997 if(device_ptr) {
2998 ULONG ref;
3000 ref = IDirect3DDevice9_Release(device_ptr);
3001 DestroyWindow(hwnd);
3002 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
3006 err_out:
3007 IDirect3D9_Release(d3d9_ptr);
3010 static void test_multi_device(void)
3012 IDirect3DDevice9 *device1, *device2;
3013 HWND window1, window2;
3014 IDirect3D9 *d3d9;
3015 ULONG refcount;
3017 window1 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3018 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3019 ok(!!window1, "Failed to create a window.\n");
3020 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3021 ok(!!d3d9, "Failed to create a D3D object.\n");
3022 if (!(device1 = create_device(d3d9, window1, NULL)))
3024 skip("Failed to create a 3D device, skipping test.\n");
3025 IDirect3D9_Release(d3d9);
3026 DestroyWindow(window1);
3027 return;
3029 IDirect3D9_Release(d3d9);
3031 window2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3032 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3033 ok(!!window2, "Failed to create a window.\n");
3034 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3035 ok(!!d3d9, "Failed to create a D3D object.\n");
3036 device2 = create_device(d3d9, window2, NULL);
3037 IDirect3D9_Release(d3d9);
3039 refcount = IDirect3DDevice9_Release(device2);
3040 ok(!refcount, "Device has %u references left.\n", refcount);
3041 refcount = IDirect3DDevice9_Release(device1);
3042 ok(!refcount, "Device has %u references left.\n", refcount);
3043 DestroyWindow(window2);
3044 DestroyWindow(window1);
3047 static HWND filter_messages;
3049 enum message_window
3051 DEVICE_WINDOW,
3052 FOCUS_WINDOW,
3055 struct message
3057 UINT message;
3058 enum message_window window;
3061 static const struct message *expect_messages;
3062 static HWND device_window, focus_window;
3064 struct wndproc_thread_param
3066 HWND dummy_window;
3067 HANDLE window_created;
3068 HANDLE test_finished;
3069 BOOL running_in_foreground;
3072 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3074 if (filter_messages && filter_messages == hwnd)
3076 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
3077 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
3080 if (expect_messages)
3082 HWND w;
3084 switch (expect_messages->window)
3086 case DEVICE_WINDOW:
3087 w = device_window;
3088 break;
3090 case FOCUS_WINDOW:
3091 w = focus_window;
3092 break;
3094 default:
3095 w = NULL;
3096 break;
3099 if (hwnd == w && expect_messages->message == message) ++expect_messages;
3102 return DefWindowProcA(hwnd, message, wparam, lparam);
3105 static DWORD WINAPI wndproc_thread(void *param)
3107 struct wndproc_thread_param *p = param;
3108 DWORD res;
3109 BOOL ret;
3111 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3112 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3113 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
3115 ret = SetEvent(p->window_created);
3116 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
3118 for (;;)
3120 MSG msg;
3122 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
3123 res = WaitForSingleObject(p->test_finished, 100);
3124 if (res == WAIT_OBJECT_0) break;
3125 if (res != WAIT_TIMEOUT)
3127 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3128 break;
3132 DestroyWindow(p->dummy_window);
3134 return 0;
3137 static void test_wndproc(void)
3139 struct wndproc_thread_param thread_params;
3140 struct device_desc device_desc;
3141 IDirect3DDevice9 *device;
3142 WNDCLASSA wc = {0};
3143 IDirect3D9 *d3d9;
3144 HANDLE thread;
3145 LONG_PTR proc;
3146 ULONG ref;
3147 DWORD res, tid;
3148 HWND tmp;
3150 static const struct message messages[] =
3152 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
3153 {WM_ACTIVATE, FOCUS_WINDOW},
3154 {WM_SETFOCUS, FOCUS_WINDOW},
3155 {0, 0},
3158 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3159 ok(!!d3d9, "Failed to create a D3D object.\n");
3161 wc.lpfnWndProc = test_proc;
3162 wc.lpszClassName = "d3d9_test_wndproc_wc";
3163 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3165 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3166 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3167 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3168 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3170 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3171 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3172 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3173 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3174 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3175 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3177 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3178 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3180 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3181 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3182 (LONG_PTR)test_proc, proc);
3183 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3184 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3185 (LONG_PTR)test_proc, proc);
3187 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3188 device_window, focus_window, thread_params.dummy_window);
3190 tmp = GetFocus();
3191 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3192 if (thread_params.running_in_foreground)
3194 tmp = GetForegroundWindow();
3195 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3196 thread_params.dummy_window, tmp);
3198 else
3199 skip("Not running in foreground, skip foreground window test\n");
3201 flush_events();
3203 expect_messages = messages;
3205 device_desc.device_window = device_window;
3206 device_desc.width = screen_width;
3207 device_desc.height = screen_height;
3208 device_desc.windowed = FALSE;
3209 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3211 skip("Failed to create a D3D device, skipping tests.\n");
3212 goto done;
3215 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
3216 expect_messages->message, expect_messages->window);
3217 expect_messages = NULL;
3219 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
3221 tmp = GetFocus();
3222 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
3223 tmp = GetForegroundWindow();
3224 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
3226 SetForegroundWindow(focus_window);
3227 flush_events();
3229 filter_messages = focus_window;
3231 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3232 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3233 (LONG_PTR)test_proc, proc);
3235 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3236 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3237 (LONG_PTR)test_proc, proc);
3239 ref = IDirect3DDevice9_Release(device);
3240 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3242 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3243 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3244 (LONG_PTR)test_proc, proc);
3246 device_desc.device_window = focus_window;
3247 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3249 skip("Failed to create a D3D device, skipping tests.\n");
3250 goto done;
3253 ref = IDirect3DDevice9_Release(device);
3254 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3256 device_desc.device_window = device_window;
3257 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3259 skip("Failed to create a D3D device, skipping tests.\n");
3260 goto done;
3263 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3264 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3265 (LONG_PTR)test_proc, proc);
3267 ref = IDirect3DDevice9_Release(device);
3268 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3270 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3271 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3272 (LONG_PTR)DefWindowProcA, proc);
3274 done:
3275 filter_messages = NULL;
3276 IDirect3D9_Release(d3d9);
3278 SetEvent(thread_params.test_finished);
3279 WaitForSingleObject(thread, INFINITE);
3280 CloseHandle(thread_params.test_finished);
3281 CloseHandle(thread_params.window_created);
3282 CloseHandle(thread);
3284 DestroyWindow(device_window);
3285 DestroyWindow(focus_window);
3286 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3289 static void test_wndproc_windowed(void)
3291 struct wndproc_thread_param thread_params;
3292 struct device_desc device_desc;
3293 IDirect3DDevice9 *device;
3294 WNDCLASSA wc = {0};
3295 IDirect3D9 *d3d9;
3296 HANDLE thread;
3297 LONG_PTR proc;
3298 HRESULT hr;
3299 ULONG ref;
3300 DWORD res, tid;
3301 HWND tmp;
3303 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3304 ok(!!d3d9, "Failed to create a D3D object.\n");
3306 wc.lpfnWndProc = test_proc;
3307 wc.lpszClassName = "d3d9_test_wndproc_wc";
3308 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3310 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3311 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3312 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3313 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3315 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3316 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3317 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3318 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3319 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3320 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3322 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3323 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3325 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3326 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3327 (LONG_PTR)test_proc, proc);
3328 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3329 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3330 (LONG_PTR)test_proc, proc);
3332 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3333 device_window, focus_window, thread_params.dummy_window);
3335 tmp = GetFocus();
3336 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3337 if (thread_params.running_in_foreground)
3339 tmp = GetForegroundWindow();
3340 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3341 thread_params.dummy_window, tmp);
3343 else
3344 skip("Not running in foreground, skip foreground window test\n");
3346 filter_messages = focus_window;
3348 device_desc.device_window = device_window;
3349 device_desc.width = 640;
3350 device_desc.height = 480;
3351 device_desc.windowed = TRUE;
3352 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3354 skip("Failed to create a D3D device, skipping tests.\n");
3355 goto done;
3358 tmp = GetFocus();
3359 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3360 tmp = GetForegroundWindow();
3361 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3362 thread_params.dummy_window, tmp);
3364 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3365 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3366 (LONG_PTR)test_proc, proc);
3368 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3369 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3370 (LONG_PTR)test_proc, proc);
3372 filter_messages = NULL;
3374 hr = reset_device(device, device_window, FALSE);
3375 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3377 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3378 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3379 (LONG_PTR)test_proc, proc);
3381 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3382 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3383 (LONG_PTR)test_proc, proc);
3385 hr = reset_device(device, device_window, TRUE);
3386 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3388 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3389 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3390 (LONG_PTR)test_proc, proc);
3392 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3393 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3394 (LONG_PTR)test_proc, proc);
3396 filter_messages = focus_window;
3398 ref = IDirect3DDevice9_Release(device);
3399 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3401 filter_messages = device_window;
3403 device_desc.device_window = focus_window;
3404 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3406 skip("Failed to create a D3D device, skipping tests.\n");
3407 goto done;
3410 filter_messages = NULL;
3412 hr = reset_device(device, focus_window, FALSE);
3413 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3415 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3416 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3417 (LONG_PTR)test_proc, proc);
3419 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3420 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3421 (LONG_PTR)test_proc, proc);
3423 hr = reset_device(device, focus_window, TRUE);
3424 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3426 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3427 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3428 (LONG_PTR)test_proc, proc);
3430 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3431 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3432 (LONG_PTR)test_proc, proc);
3434 filter_messages = device_window;
3436 ref = IDirect3DDevice9_Release(device);
3437 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3439 device_desc.device_window = device_window;
3440 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3442 skip("Failed to create a D3D device, skipping tests.\n");
3443 goto done;
3446 filter_messages = NULL;
3448 hr = reset_device(device, device_window, FALSE);
3449 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3451 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3452 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3453 (LONG_PTR)test_proc, proc);
3455 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3456 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3457 (LONG_PTR)test_proc, proc);
3459 hr = reset_device(device, device_window, TRUE);
3460 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3462 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3463 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3464 (LONG_PTR)test_proc, proc);
3466 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3467 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3468 (LONG_PTR)test_proc, proc);
3470 filter_messages = device_window;
3472 ref = IDirect3DDevice9_Release(device);
3473 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3475 done:
3476 filter_messages = NULL;
3477 IDirect3D9_Release(d3d9);
3479 SetEvent(thread_params.test_finished);
3480 WaitForSingleObject(thread, INFINITE);
3481 CloseHandle(thread_params.test_finished);
3482 CloseHandle(thread_params.window_created);
3483 CloseHandle(thread);
3485 DestroyWindow(device_window);
3486 DestroyWindow(focus_window);
3487 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3490 static void test_reset_fullscreen(void)
3492 WNDCLASSEXA wc = {0};
3493 IDirect3DDevice9 *device = NULL;
3494 IDirect3D9 *d3d;
3495 ATOM atom;
3496 static const struct message messages[] =
3498 {WM_ACTIVATEAPP, FOCUS_WINDOW},
3499 {0, 0},
3502 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3503 ok(!!d3d, "Failed to create a D3D object.\n");
3504 expect_messages = messages;
3506 wc.cbSize = sizeof(wc);
3507 wc.lpfnWndProc = test_proc;
3508 wc.lpszClassName = "test_reset_fullscreen";
3510 atom = RegisterClassExA(&wc);
3511 ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
3513 device_window = focus_window = CreateWindowExA(0, wc.lpszClassName, "Test Reset Fullscreen", 0,
3514 0, 0, screen_width, screen_height, NULL, NULL, NULL, NULL);
3515 ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
3518 * Create a device in windowed mode.
3519 * Since the device is windowed and we haven't called any methods that
3520 * could show the window (such as ShowWindow or SetWindowPos) yet,
3521 * WM_ACTIVATEAPP will not have been sent.
3523 if (!(device = create_device(d3d, device_window, NULL)))
3525 skip("Unable to create device. Skipping test.\n");
3526 goto cleanup;
3530 * Switch to fullscreen mode.
3531 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
3532 * message to be sent.
3534 ok(SUCCEEDED(reset_device(device, device_window, FALSE)), "Failed to reset device.\n");
3536 flush_events();
3537 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
3538 expect_messages = NULL;
3540 cleanup:
3541 if (device) IDirect3DDevice9_Release(device);
3542 IDirect3D9_Release(d3d);
3543 DestroyWindow(device_window);
3544 device_window = focus_window = NULL;
3545 UnregisterClassA(wc.lpszClassName, GetModuleHandleA(NULL));
3549 static inline void set_fpu_cw(WORD cw)
3551 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3552 #define D3D9_TEST_SET_FPU_CW 1
3553 __asm__ volatile ("fnclex");
3554 __asm__ volatile ("fldcw %0" : : "m" (cw));
3555 #elif defined(__i386__) && defined(_MSC_VER)
3556 #define D3D9_TEST_SET_FPU_CW 1
3557 __asm fnclex;
3558 __asm fldcw cw;
3559 #endif
3562 static inline WORD get_fpu_cw(void)
3564 WORD cw = 0;
3565 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3566 #define D3D9_TEST_GET_FPU_CW 1
3567 __asm__ volatile ("fnstcw %0" : "=m" (cw));
3568 #elif defined(__i386__) && defined(_MSC_VER)
3569 #define D3D9_TEST_GET_FPU_CW 1
3570 __asm fnstcw cw;
3571 #endif
3572 return cw;
3575 static void test_fpu_setup(void)
3577 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
3578 D3DPRESENT_PARAMETERS present_parameters;
3579 IDirect3DDevice9 *device;
3580 HWND window = NULL;
3581 IDirect3D9 *d3d9;
3582 HRESULT hr;
3583 WORD cw;
3585 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3586 ok(!!window, "Failed to create a window.\n");
3587 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3588 ok(!!d3d9, "Failed to create a D3D object.\n");
3590 memset(&present_parameters, 0, sizeof(present_parameters));
3591 present_parameters.Windowed = TRUE;
3592 present_parameters.hDeviceWindow = window;
3593 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3595 set_fpu_cw(0xf60);
3596 cw = get_fpu_cw();
3597 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3599 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3600 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
3601 if (FAILED(hr))
3603 skip("Failed to create a device, hr %#x.\n", hr);
3604 set_fpu_cw(0x37f);
3605 goto done;
3608 cw = get_fpu_cw();
3609 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3611 IDirect3DDevice9_Release(device);
3613 cw = get_fpu_cw();
3614 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3615 set_fpu_cw(0xf60);
3616 cw = get_fpu_cw();
3617 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3619 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3620 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &present_parameters, &device);
3621 ok(SUCCEEDED(hr), "CreateDevice failed, hr %#x.\n", hr);
3623 cw = get_fpu_cw();
3624 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3625 set_fpu_cw(0x37f);
3627 IDirect3DDevice9_Release(device);
3629 done:
3630 IDirect3D9_Release(d3d9);
3631 DestroyWindow(window);
3632 #endif
3635 static void test_window_style(void)
3637 RECT focus_rect, fullscreen_rect, r;
3638 LONG device_style, device_exstyle;
3639 LONG focus_style, focus_exstyle;
3640 struct device_desc device_desc;
3641 LONG style, expected_style;
3642 IDirect3DDevice9 *device;
3643 IDirect3D9 *d3d9;
3644 HRESULT hr;
3645 ULONG ref;
3647 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3648 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3649 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3650 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3651 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3652 ok(!!d3d9, "Failed to create a D3D object.\n");
3654 device_style = GetWindowLongA(device_window, GWL_STYLE);
3655 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3656 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3657 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3659 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3660 GetWindowRect(focus_window, &focus_rect);
3662 device_desc.device_window = device_window;
3663 device_desc.width = screen_width;
3664 device_desc.height = screen_height;
3665 device_desc.windowed = FALSE;
3666 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3668 skip("Failed to create a D3D device, skipping tests.\n");
3669 goto done;
3672 style = GetWindowLongA(device_window, GWL_STYLE);
3673 expected_style = device_style | WS_VISIBLE;
3674 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3675 expected_style, style);
3676 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3677 expected_style = device_exstyle | WS_EX_TOPMOST;
3678 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3679 expected_style, style);
3681 style = GetWindowLongA(focus_window, GWL_STYLE);
3682 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3683 focus_style, style);
3684 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3685 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3686 focus_exstyle, style);
3688 GetWindowRect(device_window, &r);
3689 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3690 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3691 r.left, r.top, r.right, r.bottom);
3692 GetClientRect(device_window, &r);
3693 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3694 GetWindowRect(focus_window, &r);
3695 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3696 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3697 r.left, r.top, r.right, r.bottom);
3699 hr = reset_device(device, device_window, TRUE);
3700 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3702 style = GetWindowLongA(device_window, GWL_STYLE);
3703 expected_style = device_style | WS_VISIBLE;
3704 ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3705 expected_style, style);
3706 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3707 expected_style = device_exstyle | WS_EX_TOPMOST;
3708 ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3709 expected_style, style);
3711 style = GetWindowLongA(focus_window, GWL_STYLE);
3712 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3713 focus_style, style);
3714 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3715 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3716 focus_exstyle, style);
3718 ref = IDirect3DDevice9_Release(device);
3719 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3721 done:
3722 IDirect3D9_Release(d3d9);
3724 DestroyWindow(device_window);
3725 DestroyWindow(focus_window);
3728 static const POINT *expect_pos;
3730 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
3732 if (message == WM_MOUSEMOVE)
3734 if (expect_pos && expect_pos->x && expect_pos->y)
3736 POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
3738 ClientToScreen(window, &p);
3739 if (expect_pos->x == p.x && expect_pos->y == p.y)
3740 ++expect_pos;
3744 return DefWindowProcA(window, message, wparam, lparam);
3747 static void test_cursor_pos(void)
3749 IDirect3DSurface9 *cursor;
3750 IDirect3DDevice9 *device;
3751 WNDCLASSA wc = {0};
3752 IDirect3D9 *d3d9;
3753 UINT refcount;
3754 HWND window;
3755 HRESULT hr;
3756 BOOL ret;
3758 /* Note that we don't check for movement we're not supposed to receive.
3759 * That's because it's hard to distinguish from the user accidentally
3760 * moving the mouse. */
3761 static const POINT points[] =
3763 {50, 50},
3764 {75, 75},
3765 {100, 100},
3766 {125, 125},
3767 {150, 150},
3768 {125, 125},
3769 {150, 150},
3770 {150, 150},
3771 {0, 0},
3774 wc.lpfnWndProc = test_cursor_proc;
3775 wc.lpszClassName = "d3d9_test_cursor_wc";
3776 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3777 window = CreateWindowA("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3778 0, 0, 320, 240, NULL, NULL, NULL, NULL);
3779 ShowWindow(window, SW_SHOW);
3780 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3781 ok(!!d3d9, "Failed to create a D3D object.\n");
3783 device = create_device(d3d9, window, NULL);
3784 if (!device)
3786 skip("Failed to create a D3D device, skipping tests.\n");
3787 goto done;
3790 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3791 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
3792 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
3793 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
3794 ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#x.\n", hr);
3795 IDirect3DSurface9_Release(cursor);
3796 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
3797 ok(!ret, "Failed to show cursor, hr %#x.\n", ret);
3799 flush_events();
3800 expect_pos = points;
3802 ret = SetCursorPos(50, 50);
3803 ok(ret, "Failed to set cursor position.\n");
3804 flush_events();
3806 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3807 flush_events();
3808 /* SetCursorPosition() eats duplicates. */
3809 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3810 flush_events();
3812 ret = SetCursorPos(100, 100);
3813 ok(ret, "Failed to set cursor position.\n");
3814 flush_events();
3815 /* Even if the position was set with SetCursorPos(). */
3816 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
3817 flush_events();
3819 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3820 flush_events();
3821 ret = SetCursorPos(150, 150);
3822 ok(ret, "Failed to set cursor position.\n");
3823 flush_events();
3824 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3825 flush_events();
3827 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
3828 flush_events();
3829 /* SetCursorPos() doesn't. */
3830 ret = SetCursorPos(150, 150);
3831 ok(ret, "Failed to set cursor position.\n");
3832 flush_events();
3834 ok(!expect_pos->x && !expect_pos->y, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
3835 (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
3837 refcount = IDirect3DDevice9_Release(device);
3838 ok(!refcount, "Device has %u references left.\n", refcount);
3839 done:
3840 DestroyWindow(window);
3841 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
3842 IDirect3D9_Release(d3d9);
3845 static void test_mode_change(void)
3847 RECT fullscreen_rect, focus_rect, r;
3848 struct device_desc device_desc;
3849 IDirect3DSurface9 *backbuffer;
3850 IDirect3DDevice9 *device;
3851 D3DSURFACE_DESC desc;
3852 IDirect3D9 *d3d9;
3853 DEVMODEW devmode;
3854 UINT refcount;
3855 HRESULT hr;
3856 DWORD ret;
3858 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3859 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3860 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3861 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3862 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3863 ok(!!d3d9, "Failed to create a D3D object.\n");
3865 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3866 GetWindowRect(focus_window, &focus_rect);
3868 device_desc.device_window = device_window;
3869 device_desc.width = screen_width;
3870 device_desc.height = screen_height;
3871 device_desc.windowed = FALSE;
3872 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3874 skip("Failed to create a D3D device, skipping tests.\n");
3875 goto done;
3878 memset(&devmode, 0, sizeof(devmode));
3879 devmode.dmSize = sizeof(devmode);
3880 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3881 devmode.dmPelsWidth = 640;
3882 devmode.dmPelsHeight = 480;
3884 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3885 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
3887 memset(&devmode, 0, sizeof(devmode));
3888 devmode.dmSize = sizeof(devmode);
3889 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3890 ok(ret, "Failed to get display mode.\n");
3891 ok(devmode.dmPelsWidth == 640, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3892 ok(devmode.dmPelsHeight == 480, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3894 GetWindowRect(device_window, &r);
3895 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3896 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3897 r.left, r.top, r.right, r.bottom);
3898 GetWindowRect(focus_window, &r);
3899 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3900 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3901 r.left, r.top, r.right, r.bottom);
3903 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3904 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3905 hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
3906 ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#x.\n", hr);
3907 ok(desc.Width == screen_width, "Got unexpected backbuffer width %u.\n", desc.Width);
3908 ok(desc.Height == screen_height, "Got unexpected backbuffer height %u.\n", desc.Height);
3909 IDirect3DSurface9_Release(backbuffer);
3911 refcount = IDirect3DDevice9_Release(device);
3912 ok(!refcount, "Device has %u references left.\n", refcount);
3914 memset(&devmode, 0, sizeof(devmode));
3915 devmode.dmSize = sizeof(devmode);
3916 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3917 ok(ret, "Failed to get display mode.\n");
3918 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3919 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3921 done:
3922 DestroyWindow(device_window);
3923 DestroyWindow(focus_window);
3924 IDirect3D9_Release(d3d9);
3926 memset(&devmode, 0, sizeof(devmode));
3927 devmode.dmSize = sizeof(devmode);
3928 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3929 ok(ret, "Failed to get display mode.\n");
3930 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3931 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3934 static void test_device_window_reset(void)
3936 RECT fullscreen_rect, device_rect, r;
3937 struct device_desc device_desc;
3938 IDirect3DDevice9 *device;
3939 WNDCLASSA wc = {0};
3940 IDirect3D9 *d3d9;
3941 LONG_PTR proc;
3942 HRESULT hr;
3943 ULONG ref;
3945 wc.lpfnWndProc = test_proc;
3946 wc.lpszClassName = "d3d9_test_wndproc_wc";
3947 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3949 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3950 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3951 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3952 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3953 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3954 ok(!!d3d9, "Failed to create a D3D object.\n");
3956 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3957 GetWindowRect(device_window, &device_rect);
3959 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3960 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3961 (LONG_PTR)test_proc, proc);
3962 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3963 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3964 (LONG_PTR)test_proc, proc);
3966 device_desc.device_window = NULL;
3967 device_desc.width = screen_width;
3968 device_desc.height = screen_height;
3969 device_desc.windowed = FALSE;
3970 if (!(device = create_device(d3d9, focus_window, &device_desc)))
3972 skip("Failed to create a D3D device, skipping tests.\n");
3973 goto done;
3976 GetWindowRect(focus_window, &r);
3977 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3978 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3979 r.left, r.top, r.right, r.bottom);
3980 GetWindowRect(device_window, &r);
3981 ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3982 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
3983 r.left, r.top, r.right, r.bottom);
3985 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3986 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3987 (LONG_PTR)test_proc, proc);
3988 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3989 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3990 (LONG_PTR)test_proc, proc);
3992 hr = reset_device(device, device_window, FALSE);
3993 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3995 GetWindowRect(focus_window, &r);
3996 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3997 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3998 r.left, r.top, r.right, r.bottom);
3999 GetWindowRect(device_window, &r);
4000 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4001 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4002 r.left, r.top, r.right, r.bottom);
4004 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
4005 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4006 (LONG_PTR)test_proc, proc);
4007 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
4008 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
4009 (LONG_PTR)test_proc, proc);
4011 ref = IDirect3DDevice9_Release(device);
4012 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4014 done:
4015 IDirect3D9_Release(d3d9);
4016 DestroyWindow(device_window);
4017 DestroyWindow(focus_window);
4018 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
4021 static void test_reset_resources(void)
4023 IDirect3DSurface9 *surface, *rt;
4024 IDirect3DTexture9 *texture;
4025 IDirect3DDevice9 *device;
4026 IDirect3D9 *d3d9;
4027 unsigned int i;
4028 D3DCAPS9 caps;
4029 HWND window;
4030 HRESULT hr;
4031 ULONG ref;
4033 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
4034 0, 0, 640, 480, 0, 0, 0, 0);
4035 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4036 ok(!!d3d9, "Failed to create a D3D object.\n");
4038 if (!(device = create_device(d3d9, window, NULL)))
4040 skip("Failed to create a D3D device, skipping tests.\n");
4041 goto done;
4044 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4045 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4047 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128,
4048 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
4049 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
4050 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
4051 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
4052 IDirect3DSurface9_Release(surface);
4054 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
4056 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
4057 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4058 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
4059 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4060 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
4061 IDirect3DTexture9_Release(texture);
4062 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
4063 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
4064 IDirect3DSurface9_Release(surface);
4067 hr = reset_device(device, device_window, TRUE);
4068 ok(SUCCEEDED(hr), "Failed to reset device.\n");
4070 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
4071 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
4072 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
4073 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4074 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
4075 IDirect3DSurface9_Release(surface);
4076 IDirect3DSurface9_Release(rt);
4078 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
4080 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
4081 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
4084 ref = IDirect3DDevice9_Release(device);
4085 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4087 done:
4088 IDirect3D9_Release(d3d9);
4089 DestroyWindow(window);
4092 static void test_set_rt_vp_scissor(void)
4094 IDirect3DStateBlock9 *stateblock;
4095 IDirect3DDevice9 *device;
4096 IDirect3DSurface9 *rt;
4097 IDirect3D9 *d3d9;
4098 D3DVIEWPORT9 vp;
4099 UINT refcount;
4100 HWND window;
4101 HRESULT hr;
4102 RECT rect;
4104 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
4105 0, 0, 640, 480, 0, 0, 0, 0);
4106 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4107 ok(!!d3d9, "Failed to create a D3D object.\n");
4108 if (!(device = create_device(d3d9, window, NULL)))
4110 skip("Failed to create a D3D device, skipping tests.\n");
4111 DestroyWindow(window);
4112 return;
4115 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
4116 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
4117 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4119 hr = IDirect3DDevice9_GetViewport(device, &vp);
4120 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4121 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4122 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4123 ok(vp.Width == 640, "Got unexpected vp.Width %u.\n", vp.Width);
4124 ok(vp.Height == 480, "Got unexpected vp.Height %u.\n", vp.Height);
4125 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4126 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4128 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4129 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4130 ok(rect.left == 0 && rect.top == 0 && rect.right == 640 && rect.bottom == 480,
4131 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4132 rect.left, rect.top, rect.right, rect.bottom);
4134 hr = IDirect3DDevice9_BeginStateBlock(device);
4135 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
4137 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4138 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4140 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
4141 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
4142 IDirect3DStateBlock9_Release(stateblock);
4144 hr = IDirect3DDevice9_GetViewport(device, &vp);
4145 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4146 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4147 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4148 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
4149 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
4150 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4151 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4153 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4154 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4155 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
4156 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4157 rect.left, rect.top, rect.right, rect.bottom);
4159 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4160 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4162 vp.X = 10;
4163 vp.Y = 20;
4164 vp.Width = 30;
4165 vp.Height = 40;
4166 vp.MinZ = 0.25f;
4167 vp.MaxZ = 0.75f;
4168 hr = IDirect3DDevice9_SetViewport(device, &vp);
4169 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
4171 SetRect(&rect, 50, 60, 70, 80);
4172 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
4173 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
4175 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4176 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4178 hr = IDirect3DDevice9_GetViewport(device, &vp);
4179 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4180 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4181 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4182 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
4183 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
4184 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4185 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4187 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4188 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4189 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
4190 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4191 rect.left, rect.top, rect.right, rect.bottom);
4193 IDirect3DSurface9_Release(rt);
4194 refcount = IDirect3DDevice9_Release(device);
4195 ok(!refcount, "Device has %u references left.\n", refcount);
4196 IDirect3D9_Release(d3d9);
4197 DestroyWindow(window);
4200 static void test_volume_get_container(void)
4202 IDirect3DVolumeTexture9 *texture = NULL;
4203 IDirect3DVolume9 *volume = NULL;
4204 IDirect3DDevice9 *device;
4205 IUnknown *container;
4206 IDirect3D9 *d3d9;
4207 ULONG refcount;
4208 D3DCAPS9 caps;
4209 HWND window;
4210 HRESULT hr;
4212 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4213 0, 0, 640, 480, 0, 0, 0, 0);
4214 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4215 ok(!!d3d9, "Failed to create a D3D object.\n");
4216 if (!(device = create_device(d3d9, window, NULL)))
4218 skip("Failed to create a D3D device, skipping tests.\n");
4219 IDirect3D9_Release(d3d9);
4220 DestroyWindow(window);
4221 return;
4224 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4225 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4226 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
4228 skip("No volume texture support, skipping tests.\n");
4229 IDirect3DDevice9_Release(device);
4230 IDirect3D9_Release(d3d9);
4231 DestroyWindow(window);
4232 return;
4235 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
4236 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
4237 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4238 ok(!!texture, "Got unexpected texture %p.\n", texture);
4240 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
4241 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
4242 ok(!!volume, "Got unexpected volume %p.\n", volume);
4244 /* These should work... */
4245 container = NULL;
4246 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
4247 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4248 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4249 IUnknown_Release(container);
4251 container = NULL;
4252 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
4253 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4254 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4255 IUnknown_Release(container);
4257 container = NULL;
4258 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
4259 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4260 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4261 IUnknown_Release(container);
4263 container = NULL;
4264 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
4265 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4266 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4267 IUnknown_Release(container);
4269 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
4270 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
4271 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
4272 ok(!container, "Got unexpected container %p.\n", container);
4274 IDirect3DVolume9_Release(volume);
4275 IDirect3DVolumeTexture9_Release(texture);
4276 refcount = IDirect3DDevice9_Release(device);
4277 ok(!refcount, "Device has %u references left.\n", refcount);
4278 IDirect3D9_Release(d3d9);
4279 DestroyWindow(window);
4282 static void test_volume_resource(void)
4284 IDirect3DVolumeTexture9 *texture;
4285 IDirect3DResource9 *resource;
4286 IDirect3DVolume9 *volume;
4287 IDirect3DDevice9 *device;
4288 IDirect3D9 *d3d9;
4289 ULONG refcount;
4290 D3DCAPS9 caps;
4291 HWND window;
4292 HRESULT hr;
4294 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4295 0, 0, 640, 480, 0, 0, 0, 0);
4296 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4297 ok(!!d3d9, "Failed to create a D3D object.\n");
4298 if (!(device = create_device(d3d9, window, NULL)))
4300 skip("Failed to create a D3D device, skipping tests.\n");
4301 IDirect3D9_Release(d3d9);
4302 DestroyWindow(window);
4303 return;
4306 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4307 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4308 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
4310 skip("No volume texture support, skipping tests.\n");
4311 IDirect3DDevice9_Release(device);
4312 IDirect3D9_Release(d3d9);
4313 DestroyWindow(window);
4314 return;
4317 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
4318 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
4319 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4320 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
4321 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
4322 IDirect3DVolumeTexture9_Release(texture);
4324 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
4325 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
4327 IDirect3DVolume9_Release(volume);
4328 refcount = IDirect3DDevice9_Release(device);
4329 ok(!refcount, "Device has %u references left.\n", refcount);
4330 IDirect3D9_Release(d3d9);
4331 DestroyWindow(window);
4334 static void test_vb_lock_flags(void)
4336 static const struct
4338 DWORD flags;
4339 const char *debug_string;
4340 HRESULT win7_result;
4342 test_data[] =
4344 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
4345 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
4346 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
4347 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
4348 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
4349 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
4350 /* Completely bogus flags aren't an error. */
4351 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
4353 IDirect3DVertexBuffer9 *buffer;
4354 IDirect3DDevice9 *device;
4355 IDirect3D9 *d3d9;
4356 unsigned int i;
4357 ULONG refcount;
4358 HWND window;
4359 HRESULT hr;
4360 void *data;
4362 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4363 0, 0, 640, 480, 0, 0, 0, 0);
4364 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4365 ok(!!d3d9, "Failed to create a D3D object.\n");
4366 if (!(device = create_device(d3d9, window, NULL)))
4368 skip("Failed to create a D3D device, skipping tests.\n");
4369 IDirect3D9_Release(d3d9);
4370 DestroyWindow(window);
4371 return;
4374 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
4375 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4377 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
4379 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
4380 /* Windows XP always returns D3D_OK even with flags that don't make
4381 * sense. Windows 7 returns an error. At least one game (Shaiya)
4382 * depends on the Windows XP result, so mark the Windows 7 behavior as
4383 * broken. */
4384 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
4385 hr, test_data[i].debug_string);
4386 if (SUCCEEDED(hr))
4388 ok(!!data, "Got unexpected data %p.\n", data);
4389 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4390 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
4394 IDirect3DVertexBuffer9_Release(buffer);
4395 refcount = IDirect3DDevice9_Release(device);
4396 ok(!refcount, "Device has %u references left.\n", refcount);
4397 IDirect3D9_Release(d3d9);
4398 DestroyWindow(window);
4401 static const char *debug_d3dpool(D3DPOOL pool)
4403 switch (pool)
4405 case D3DPOOL_DEFAULT:
4406 return "D3DPOOL_DEFAULT";
4407 case D3DPOOL_SYSTEMMEM:
4408 return "D3DPOOL_SYSTEMMEM";
4409 case D3DPOOL_SCRATCH:
4410 return "D3DPOOL_SCRATCH";
4411 case D3DPOOL_MANAGED:
4412 return "D3DPOOL_MANAGED";
4413 default:
4414 return "unknown pool";
4418 static void test_vertex_buffer_alignment(void)
4420 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
4421 static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
4422 IDirect3DVertexBuffer9 *buffer = NULL;
4423 const unsigned int align = 16;
4424 IDirect3DDevice9 *device;
4425 unsigned int i, j;
4426 IDirect3D9 *d3d9;
4427 ULONG refcount;
4428 HWND window;
4429 HRESULT hr;
4430 void *data;
4432 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4433 0, 0, 640, 480, 0, 0, 0, 0);
4434 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4435 ok(!!d3d9, "Failed to create a D3D object.\n");
4436 if (!(device = create_device(d3d9, window, NULL)))
4438 skip("Failed to create a D3D device, skipping tests.\n");
4439 IDirect3D9_Release(d3d9);
4440 DestroyWindow(window);
4441 return;
4444 for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
4446 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
4448 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
4449 if (pools[j] == D3DPOOL_SCRATCH)
4450 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
4451 else
4452 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
4453 debug_d3dpool(pools[j]), sizes[i], hr);
4454 if (FAILED(hr))
4455 continue;
4457 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
4458 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
4459 ok(!((DWORD_PTR)data & (align - 1)),
4460 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
4461 data, align, sizes[i], debug_d3dpool(pools[j]));
4462 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4463 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
4464 IDirect3DVertexBuffer9_Release(buffer);
4468 refcount = IDirect3DDevice9_Release(device);
4469 ok(!refcount, "Device has %u references left.\n", refcount);
4470 IDirect3D9_Release(d3d9);
4471 DestroyWindow(window);
4474 static void test_query_support(void)
4476 static const D3DQUERYTYPE queries[] =
4478 D3DQUERYTYPE_VCACHE,
4479 D3DQUERYTYPE_RESOURCEMANAGER,
4480 D3DQUERYTYPE_VERTEXSTATS,
4481 D3DQUERYTYPE_EVENT,
4482 D3DQUERYTYPE_OCCLUSION,
4483 D3DQUERYTYPE_TIMESTAMP,
4484 D3DQUERYTYPE_TIMESTAMPDISJOINT,
4485 D3DQUERYTYPE_TIMESTAMPFREQ,
4486 D3DQUERYTYPE_PIPELINETIMINGS,
4487 D3DQUERYTYPE_INTERFACETIMINGS,
4488 D3DQUERYTYPE_VERTEXTIMINGS,
4489 D3DQUERYTYPE_PIXELTIMINGS,
4490 D3DQUERYTYPE_BANDWIDTHTIMINGS,
4491 D3DQUERYTYPE_CACHEUTILIZATION,
4493 IDirect3DQuery9 *query = NULL;
4494 IDirect3DDevice9 *device;
4495 IDirect3D9 *d3d9;
4496 unsigned int i;
4497 ULONG refcount;
4498 BOOL supported;
4499 HWND window;
4500 HRESULT hr;
4502 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4503 0, 0, 640, 480, 0, 0, 0, 0);
4504 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4505 ok(!!d3d9, "Failed to create a D3D object.\n");
4506 if (!(device = create_device(d3d9, window, NULL)))
4508 skip("Failed to create a D3D device, skipping tests.\n");
4509 IDirect3D9_Release(d3d9);
4510 DestroyWindow(window);
4511 return;
4514 for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
4516 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
4517 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4519 supported = hr == D3D_OK;
4521 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
4522 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4524 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
4525 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
4527 if (query)
4529 IDirect3DQuery9_Release(query);
4530 query = NULL;
4534 refcount = IDirect3DDevice9_Release(device);
4535 ok(!refcount, "Device has %u references left.\n", refcount);
4536 IDirect3D9_Release(d3d9);
4537 DestroyWindow(window);
4540 static void test_occlusion_query_states(void)
4542 static const float quad[] =
4544 -1.0f, -1.0f, 0.0f,
4545 -1.0f, 1.0f, 0.0f,
4546 1.0f, 1.0f, 0.0f,
4547 1.0f, -1.0f, 0.0f,
4549 struct device_desc device_desc;
4550 IDirect3DQuery9 *query = NULL;
4551 unsigned int data_size, i;
4552 IDirect3DDevice9 *device;
4553 IDirect3D9 *d3d9;
4554 ULONG refcount;
4555 HWND window;
4556 HRESULT hr;
4557 union
4559 WORD word[4];
4560 DWORD dword[2];
4561 } data;
4562 BOOL broken_occlusion = FALSE;
4563 DWORD expected = screen_width * screen_height;
4565 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4566 0, 0, 640, 480, 0, 0, 0, 0);
4567 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4568 ok(!!d3d9, "Failed to create a D3D object.\n");
4569 device_desc.device_window = window;
4570 device_desc.width = screen_width;
4571 device_desc.height = screen_height;
4572 device_desc.windowed = FALSE;
4573 if (!(device = create_device(d3d9, window, &device_desc)))
4575 skip("Failed to create a D3D device, skipping tests.\n");
4576 IDirect3D9_Release(d3d9);
4577 DestroyWindow(window);
4578 return;
4581 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
4582 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4583 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4585 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4586 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4588 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4589 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4590 if (!query)
4592 skip("Occlusion queries are not supported, skipping tests.\n");
4593 IDirect3DDevice9_Release(device);
4594 IDirect3D9_Release(d3d9);
4595 DestroyWindow(window);
4596 return;
4599 data_size = IDirect3DQuery9_GetDataSize(query);
4600 ok(data_size == sizeof(DWORD), "Unexpected data size %u.\n", data_size);
4602 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4603 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4604 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
4605 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4607 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4608 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4609 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4610 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4611 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4612 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4614 data.dword[0] = 0x12345678;
4615 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4616 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4617 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
4618 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4619 if (hr == D3D_OK)
4620 ok(!data.dword[0], "Got unexpected query result %u.\n", data.dword[0]);
4622 hr = IDirect3DDevice9_BeginScene(device);
4623 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
4625 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4626 hr = IDirect3DDevice9_EndScene(device);
4627 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4629 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4630 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4631 for (i = 0; i < 500; ++i)
4633 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4634 break;
4635 Sleep(10);
4637 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4639 memset(&data, 0xff, sizeof(data));
4640 hr = IDirect3DQuery9_GetData(query, &data, data_size, D3DGETDATA_FLUSH);
4641 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4642 ok(data.dword[0] == expected || broken(!data.dword[0]),
4643 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
4644 if (!data.dword[0])
4646 win_skip("Occlusion query result looks broken, ignoring returned count.\n");
4647 broken_occlusion = TRUE;
4650 memset(&data, 0xff, sizeof(data));
4651 hr = IDirect3DQuery9_GetData(query, &data, sizeof(WORD), D3DGETDATA_FLUSH);
4652 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4653 if (!broken_occlusion)
4654 ok(data.word[0] == (WORD)expected,
4655 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
4656 ok(data.word[1] == 0xffff,
4657 "data was modified outside of the expected size (0x%.8x).\n", data.dword[0]);
4659 memset(&data, 0xf0, sizeof(data));
4660 hr = IDirect3DQuery9_GetData(query, &data, sizeof(data), D3DGETDATA_FLUSH);
4661 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4662 if (!broken_occlusion)
4663 ok(data.dword[0] == expected,
4664 "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
4665 /* Different drivers seem to return different data in those high bytes on Windows, but they all
4666 write something there and the extra data is consistent (I've seen 0x00000000 and 0xdddddddd
4667 on AMD and Nvidia respectively). */
4668 if (0)
4670 ok(data.dword[1] != 0xf0f0f0f0, "high bytes of data were not modified (0x%.8x).\n",
4671 data.dword[1]);
4674 memset(&data, 0xff, sizeof(data));
4675 hr = IDirect3DQuery9_GetData(query, &data, 0, D3DGETDATA_FLUSH);
4676 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4677 ok(data.dword[0] == 0xffffffff, "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
4679 /* This crashes on Windows. */
4680 if (0)
4682 hr = IDirect3DQuery9_GetData(query, NULL, data_size, D3DGETDATA_FLUSH);
4683 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4686 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4687 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4688 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4689 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4690 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4691 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4693 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4695 IDirect3DQuery9_Release(query);
4696 refcount = IDirect3DDevice9_Release(device);
4697 ok(!refcount, "Device has %u references left.\n", refcount);
4698 IDirect3D9_Release(d3d9);
4699 DestroyWindow(window);
4702 static void test_timestamp_query(void)
4704 static const float quad[] =
4706 -1.0f, -1.0f, 0.0f,
4707 -1.0f, 1.0f, 0.0f,
4708 1.0f, 1.0f, 0.0f,
4709 1.0f, -1.0f, 0.0f,
4711 IDirect3DQuery9 *query, *disjoint_query, *freq_query;
4712 unsigned int data_size, i;
4713 IDirect3DDevice9 *device;
4714 IDirect3D9 *d3d9;
4715 ULONG refcount;
4716 HWND window;
4717 HRESULT hr;
4718 DWORD timestamp[2], freq[2];
4719 WORD disjoint[2];
4721 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4722 0, 0, 640, 480, 0, 0, 0, 0);
4723 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4724 ok(!!d3d9, "Failed to create a D3D object.\n");
4725 if (!(device = create_device(d3d9, window, NULL)))
4727 skip("Failed to create a D3D device, skipping tests.\n");
4728 IDirect3D9_Release(d3d9);
4729 DestroyWindow(window);
4730 return;
4733 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPFREQ, &freq_query);
4734 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4735 if (FAILED(hr))
4737 skip("Timestamp queries are not supported, skipping tests.\n");
4738 IDirect3DDevice9_Release(device);
4739 IDirect3D9_Release(d3d9);
4740 DestroyWindow(window);
4741 return;
4743 data_size = IDirect3DQuery9_GetDataSize(freq_query);
4744 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
4746 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPDISJOINT, &disjoint_query);
4747 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4748 data_size = IDirect3DQuery9_GetDataSize(disjoint_query);
4749 ok(data_size == sizeof(BOOL), "Query data size is %u, 4 expected.\n", data_size);
4751 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMP, &query);
4752 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4753 data_size = IDirect3DQuery9_GetDataSize(query);
4754 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
4756 hr = IDirect3DQuery9_Issue(freq_query, D3DISSUE_END);
4757 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4758 for (i = 0; i < 500; ++i)
4760 if ((hr = IDirect3DQuery9_GetData(freq_query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4761 break;
4762 Sleep(10);
4764 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4766 memset(freq, 0xff, sizeof(freq));
4767 hr = IDirect3DQuery9_GetData(freq_query, freq, sizeof(DWORD), D3DGETDATA_FLUSH);
4768 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4769 ok(freq[1] == 0xffffffff,
4770 "freq was modified outside of the expected size (0x%.8x).\n", freq[1]);
4771 hr = IDirect3DQuery9_GetData(freq_query, &freq, sizeof(freq), D3DGETDATA_FLUSH);
4772 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4773 ok(freq[1] != 0xffffffff, "high bytes of freq were not modified (0x%.8x).\n",
4774 freq[1]);
4776 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4777 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4778 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4779 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4781 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
4782 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4783 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
4784 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4785 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
4786 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4788 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4789 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4791 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4792 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4793 hr = IDirect3DDevice9_BeginScene(device);
4794 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4795 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
4796 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4797 hr = IDirect3DDevice9_EndScene(device);
4798 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4800 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4801 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4802 for (i = 0; i < 500; ++i)
4804 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4805 break;
4806 Sleep(10);
4808 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4810 memset(timestamp, 0xff, sizeof(timestamp));
4811 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(DWORD), D3DGETDATA_FLUSH);
4812 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4813 ok(timestamp[1] == 0xffffffff,
4814 "timestamp was modified outside of the expected size (0x%.8x).\n",
4815 timestamp[1]);
4817 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4818 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4819 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4820 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4821 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4822 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4824 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
4825 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4826 for (i = 0; i < 500; ++i)
4828 if ((hr = IDirect3DQuery9_GetData(disjoint_query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4829 break;
4830 Sleep(10);
4832 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4834 memset(disjoint, 0xff, sizeof(disjoint));
4835 hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(WORD), D3DGETDATA_FLUSH);
4836 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4837 ok(disjoint[1] == 0xffff,
4838 "disjoint was modified outside of the expected size (0x%.4hx).\n", disjoint[1]);
4839 hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(disjoint), D3DGETDATA_FLUSH);
4840 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4841 ok(disjoint[1] != 0xffff, "high bytes of disjoint were not modified (0x%.4hx).\n", disjoint[1]);
4843 /* It's not strictly necessary for the TIMESTAMP query to be inside
4844 * a TIMESTAMP_DISJOINT query. */
4845 hr = IDirect3DDevice9_BeginScene(device);
4846 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4847 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, 2, quad, 3 * sizeof(float));
4848 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4849 hr = IDirect3DDevice9_EndScene(device);
4850 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4852 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4853 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4854 for (i = 0; i < 500; ++i)
4856 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4857 break;
4858 Sleep(10);
4860 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4861 hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4862 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4864 IDirect3DQuery9_Release(query);
4865 IDirect3DQuery9_Release(disjoint_query);
4866 IDirect3DQuery9_Release(freq_query);
4867 refcount = IDirect3DDevice9_Release(device);
4868 ok(!refcount, "Device has %u references left.\n", refcount);
4869 IDirect3D9_Release(d3d9);
4870 DestroyWindow(window);
4873 static void test_get_set_vertex_shader(void)
4875 IDirect3DVertexShader9 *current_shader = NULL;
4876 IDirect3DVertexShader9 *shader = NULL;
4877 IDirect3DDevice9 *device;
4878 ULONG refcount, i;
4879 IDirect3D9 *d3d;
4880 D3DCAPS9 caps;
4881 HWND window;
4882 HRESULT hr;
4884 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4885 0, 0, 640, 480, 0, 0, 0, 0);
4886 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4887 ok(!!d3d, "Failed to create a D3D object.\n");
4888 if (!(device = create_device(d3d, window, NULL)))
4890 skip("Failed to create a D3D device, skipping tests.\n");
4891 IDirect3D9_Release(d3d);
4892 DestroyWindow(window);
4893 return;
4896 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4897 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4898 if (!(caps.VertexShaderVersion & 0xffff))
4900 skip("No vertex shader support, skipping tests.\n");
4901 IDirect3DDevice9_Release(device);
4902 IDirect3D9_Release(d3d);
4903 DestroyWindow(window);
4904 return;
4907 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
4908 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4909 ok(!!shader, "Got unexpected shader %p.\n", shader);
4911 /* SetVertexShader() should not touch the shader's refcount. */
4912 i = get_refcount((IUnknown *)shader);
4913 hr = IDirect3DDevice9_SetVertexShader(device, shader);
4914 refcount = get_refcount((IUnknown *)shader);
4915 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4916 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4918 /* GetVertexShader() should increase the shader's refcount by one. */
4919 i = refcount + 1;
4920 hr = IDirect3DDevice9_GetVertexShader(device, &current_shader);
4921 refcount = get_refcount((IUnknown *)shader);
4922 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
4923 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4924 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4925 IDirect3DVertexShader9_Release(current_shader);
4927 IDirect3DVertexShader9_Release(shader);
4928 refcount = IDirect3DDevice9_Release(device);
4929 ok(!refcount, "Device has %u references left.\n", refcount);
4930 IDirect3D9_Release(d3d);
4931 DestroyWindow(window);
4934 static void test_vertex_shader_constant(void)
4936 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};
4937 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4938 IDirect3DDevice9 *device;
4939 IDirect3D9 *d3d;
4940 ULONG refcount;
4941 D3DCAPS9 caps;
4942 DWORD consts;
4943 HWND window;
4944 HRESULT hr;
4946 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4947 0, 0, 640, 480, 0, 0, 0, 0);
4948 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4949 ok(!!d3d, "Failed to create a D3D object.\n");
4950 if (!(device = create_device(d3d, window, NULL)))
4952 skip("Failed to create a D3D device, skipping tests.\n");
4953 IDirect3D9_Release(d3d);
4954 DestroyWindow(window);
4955 return;
4958 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4959 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4960 if (!(caps.VertexShaderVersion & 0xffff))
4962 skip("No vertex shader support, skipping tests.\n");
4963 IDirect3DDevice9_Release(device);
4964 IDirect3D9_Release(d3d);
4965 DestroyWindow(window);
4966 return;
4968 consts = caps.MaxVertexShaderConst;
4970 /* A simple check that the stuff works at all. */
4971 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
4972 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4974 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
4975 * consts from MAX - 1. */
4976 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
4977 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4978 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
4979 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4980 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
4981 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4982 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
4983 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4985 /* Constant -1. */
4986 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
4987 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4989 refcount = IDirect3DDevice9_Release(device);
4990 ok(!refcount, "Device has %u references left.\n", refcount);
4991 IDirect3D9_Release(d3d);
4992 DestroyWindow(window);
4995 static void test_get_set_pixel_shader(void)
4997 IDirect3DPixelShader9 *current_shader = NULL;
4998 IDirect3DPixelShader9 *shader = NULL;
4999 IDirect3DDevice9 *device;
5000 ULONG refcount, i;
5001 IDirect3D9 *d3d;
5002 D3DCAPS9 caps;
5003 HWND window;
5004 HRESULT hr;
5006 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5007 0, 0, 640, 480, 0, 0, 0, 0);
5008 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5009 ok(!!d3d, "Failed to create a D3D object.\n");
5010 if (!(device = create_device(d3d, window, NULL)))
5012 skip("Failed to create a D3D device, skipping tests.\n");
5013 IDirect3D9_Release(d3d);
5014 DestroyWindow(window);
5015 return;
5018 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5019 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5020 if (!(caps.PixelShaderVersion & 0xffff))
5022 skip("No pixel shader support, skipping tests.\n");
5023 IDirect3DDevice9_Release(device);
5024 IDirect3D9_Release(d3d);
5025 DestroyWindow(window);
5026 return;
5029 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
5030 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
5031 ok(!!shader, "Got unexpected shader %p.\n", shader);
5033 /* SetPixelShader() should not touch the shader's refcount. */
5034 i = get_refcount((IUnknown *)shader);
5035 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5036 refcount = get_refcount((IUnknown *)shader);
5037 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5038 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
5040 /* GetPixelShader() should increase the shader's refcount by one. */
5041 i = refcount + 1;
5042 hr = IDirect3DDevice9_GetPixelShader(device, &current_shader);
5043 refcount = get_refcount((IUnknown *)shader);
5044 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
5045 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
5046 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
5047 IDirect3DPixelShader9_Release(current_shader);
5049 IDirect3DPixelShader9_Release(shader);
5050 refcount = IDirect3DDevice9_Release(device);
5051 ok(!refcount, "Device has %u references left.\n", refcount);
5052 IDirect3D9_Release(d3d);
5053 DestroyWindow(window);
5056 static void test_pixel_shader_constant(void)
5058 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};
5059 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
5060 IDirect3DDevice9 *device;
5061 DWORD consts = 0;
5062 IDirect3D9 *d3d;
5063 ULONG refcount;
5064 D3DCAPS9 caps;
5065 HWND window;
5066 HRESULT hr;
5068 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5069 0, 0, 640, 480, 0, 0, 0, 0);
5070 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5071 ok(!!d3d, "Failed to create a D3D object.\n");
5072 if (!(device = create_device(d3d, window, NULL)))
5074 skip("Failed to create a D3D device, skipping tests.\n");
5075 IDirect3D9_Release(d3d);
5076 DestroyWindow(window);
5077 return;
5080 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5081 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5082 if (!(caps.PixelShaderVersion & 0xffff))
5084 skip("No pixel shader support, skipping tests.\n");
5085 IDirect3DDevice9_Release(device);
5086 IDirect3D9_Release(d3d);
5087 DestroyWindow(window);
5088 return;
5091 /* A simple check that the stuff works at all. */
5092 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
5093 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5095 /* Is there really no max pixel shader constant value??? Test how far I can go. */
5096 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
5097 consts = consts - 1;
5098 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
5100 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
5101 * pointless given the way the constant limit was determined. */
5102 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
5103 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5105 /* Constant -1. */
5106 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
5107 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5109 refcount = IDirect3DDevice9_Release(device);
5110 ok(!refcount, "Device has %u references left.\n", refcount);
5111 IDirect3D9_Release(d3d);
5112 DestroyWindow(window);
5115 static void test_wrong_shader(void)
5117 static const DWORD vs_3_0[] =
5119 0xfffe0300, /* vs_3_0 */
5120 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5121 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5122 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5123 0x0000ffff, /* end */
5126 #if 0
5127 float4 main(const float4 color : COLOR) : SV_TARGET
5129 float4 o;
5131 o = color;
5133 return o;
5135 #endif
5136 static const DWORD ps_4_0[] =
5138 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
5139 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
5140 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
5141 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
5142 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
5143 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
5144 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
5145 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
5146 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
5147 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
5148 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
5149 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5150 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5151 0x00000000, 0x00000000, 0x00000000,
5153 #if 0
5154 vs_1_1
5155 dcl_position v0
5156 def c255, 1.0, 1.0, 1.0, 1.0
5157 add r0, v0, c255
5158 mov oPos, r0
5159 #endif
5160 static const DWORD vs_1_255[] =
5162 0xfffe0101,
5163 0x0000001f, 0x80000000, 0x900f0000,
5164 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5165 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
5166 0x00000001, 0xc00f0000, 0x80e40000,
5167 0x0000ffff
5169 #if 0
5170 vs_1_1
5171 dcl_position v0
5172 def c256, 1.0, 1.0, 1.0, 1.0
5173 add r0, v0, c256
5174 mov oPos, r0
5175 #endif
5176 static const DWORD vs_1_256[] =
5178 0xfffe0101,
5179 0x0000001f, 0x80000000, 0x900f0000,
5180 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5181 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
5182 0x00000001, 0xc00f0000, 0x80e40000,
5183 0x0000ffff
5185 #if 0
5186 vs_3_0
5187 dcl_position v0
5188 dcl_position o0
5189 def c256, 1.0, 1.0, 1.0, 1.0
5190 add r0, v0, c256
5191 mov o0, r0
5192 #endif
5193 static const DWORD vs_3_256[] =
5195 0xfffe0300,
5196 0x0200001f, 0x80000000, 0x900f0000,
5197 0x0200001f, 0x80000000, 0xe00f0000,
5198 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5199 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40100,
5200 0x02000001, 0xe00f0000, 0x80e40000,
5201 0x0000ffff
5203 #if 0
5204 /* This shader source generates syntax errors with the native shader assembler
5205 * due to the constant register index values.
5206 * The bytecode was modified by hand to use the intended values. */
5207 vs_3_0
5208 dcl_position v0
5209 dcl_position o0
5210 defi i16, 1, 1, 1, 1
5211 rep i16
5212 add r0, r0, v0
5213 endrep
5214 mov o0, r0
5215 #endif
5216 static const DWORD vs_3_i16[] =
5218 0xfffe0300,
5219 0x0200001f, 0x80000000, 0x900f0000,
5220 0x0200001f, 0x80000000, 0xe00f0000,
5221 0x05000030, 0xf00f0010, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
5222 0x01000026, 0xf0e40010,
5223 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
5224 0x00000027,
5225 0x02000001, 0xe00f0000, 0x80e40000,
5226 0x0000ffff
5228 #if 0
5229 /* This shader source generates syntax errors with the native shader assembler
5230 * due to the constant register index values.
5231 * The bytecode was modified by hand to use the intended values. */
5232 vs_3_0
5233 dcl_position v0
5234 dcl_position o0
5235 defb b16, true
5236 mov r0, v0
5237 if b16
5238 add r0, r0, v0
5239 endif
5240 mov o0, r0
5241 #endif
5242 static const DWORD vs_3_b16[] =
5244 0xfffe0300,
5245 0x0200001f, 0x80000000, 0x900f0000,
5246 0x0200001f, 0x80000000, 0xe00f0000,
5247 0x0200002f, 0xe00f0810, 0x00000001,
5248 0x02000001, 0x800f0000, 0x90e40000,
5249 0x01000028, 0xe0e40810,
5250 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
5251 0x0000002b,
5252 0x02000001, 0xe00f0000, 0x80e40000,
5253 0x0000ffff
5255 #if 0
5256 /* This shader source generates syntax errors with the native shader assembler
5257 * due to the constant register index values.
5258 * The bytecode was modified by hand to use the intended values. */
5259 ps_1_1
5260 def c8, 1.0, 1.0, 1.0, 1.0
5261 add r0, v0, c8
5262 #endif
5263 static const DWORD ps_1_8[] =
5265 0xffff0101,
5266 0x00000051, 0xa00f0008, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5267 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40008,
5268 0x0000ffff
5270 #if 0
5271 /* This shader source generates syntax errors with the native shader assembler
5272 * due to the constant register index values.
5273 * The bytecode was modified by hand to use the intended values. */
5274 ps_2_0
5275 def c32, 1.0, 1.0, 1.0, 1.0
5276 add oC0, v0, c32
5277 #endif
5278 static const DWORD ps_2_32[] =
5280 0xffff0200,
5281 0x05000051, 0xa00f0020, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5282 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40020,
5283 0x0000ffff
5285 #if 0
5286 /* This shader source generates syntax errors with the native shader assembler
5287 * due to the constant register index values.
5288 * The bytecode was modified by hand to use the intended values. */
5289 ps_3_0
5290 dcl_color0 v0
5291 def c224, 1.0, 1.0, 1.0, 1.0
5292 add oC0, v0, c224
5293 #endif
5294 static const DWORD ps_3_224[] =
5296 0xffff0300,
5297 0x0200001f, 0x8000000a, 0x900f0000,
5298 0x05000051, 0xa00f00e0, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
5299 0x03000002, 0x800f0800, 0x90e40000, 0xa0e400e0,
5300 0x0000ffff
5302 #if 0
5303 /* This shader source generates syntax errors with the native shader assembler
5304 * due to the constant register index values.
5305 * The bytecode was modified by hand to use the intended values. */
5306 ps_2_0
5307 defb b0, true
5308 defi i0, 1, 1, 1, 1
5309 rep i0
5310 if b0
5311 add r0, r0, v0
5312 endif
5313 endrep
5314 mov oC0, r0
5315 #endif
5316 static const DWORD ps_2_0_boolint[] =
5318 0xffff0200,
5319 0x0200002f, 0xe00f0800, 0x00000001,
5320 0x05000030, 0xf00f0000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
5321 0x01000026, 0xf0e40000,
5322 0x01000028, 0xe0e40800,
5323 0x03000002, 0x800f0000, 0x80e40000, 0x90e40000,
5324 0x0000002b,
5325 0x00000027,
5326 0x02000001, 0x800f0800, 0x80e40000,
5327 0x0000ffff
5330 IDirect3DVertexShader9 *vs = NULL;
5331 IDirect3DPixelShader9 *ps = NULL;
5332 IDirect3DDevice9 *device;
5333 IDirect3D9 * d3d;
5334 ULONG refcount;
5335 D3DCAPS9 caps;
5336 HWND window;
5337 HRESULT hr;
5339 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5340 0, 0, 640, 480, 0, 0, 0, 0);
5341 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5342 ok(!!d3d, "Failed to create a D3D object.\n");
5343 if (!(device = create_device(d3d, window, NULL)))
5345 skip("Failed to create a D3D device, skipping tests.\n");
5346 IDirect3D9_Release(d3d);
5347 DestroyWindow(window);
5348 return;
5351 /* These should always fail, regardless of supported shader version. */
5352 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
5353 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5354 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
5355 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5356 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
5357 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5359 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5360 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5361 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
5363 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
5364 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5365 if (caps.VertexShaderVersion <= D3DVS_VERSION(1, 1) && caps.MaxVertexShaderConst < 256)
5367 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_255, &vs);
5368 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5370 else
5372 skip("GPU supports SM2+, skipping SM1 test.\n");
5375 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
5377 else
5379 skip("This GPU supports SM3, skipping unsupported shader test.\n");
5381 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_255, &vs);
5382 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5383 IDirect3DVertexShader9_Release(vs);
5384 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_256, &vs);
5385 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5386 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_256, &vs);
5387 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5388 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_i16, &vs);
5389 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5390 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_b16, &vs);
5391 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5394 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
5396 skip("This GPU doesn't support SM3, skipping test with shader using unsupported constants.\n");
5397 goto cleanup;
5399 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_8, &ps);
5400 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5401 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_32, &ps);
5402 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5403 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_224, &ps);
5404 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5405 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_0_boolint, &ps);
5406 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5407 if (ps)
5408 IDirect3DPixelShader9_Release(ps);
5410 cleanup:
5411 refcount = IDirect3DDevice9_Release(device);
5412 ok(!refcount, "Device has %u references left.\n", refcount);
5413 IDirect3D9_Release(d3d);
5414 DestroyWindow(window);
5417 /* Test the default texture stage state values */
5418 static void test_texture_stage_states(void)
5420 IDirect3DDevice9 *device;
5421 IDirect3D9 *d3d;
5422 unsigned int i;
5423 ULONG refcount;
5424 D3DCAPS9 caps;
5425 DWORD value;
5426 HWND window;
5427 HRESULT hr;
5429 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5430 0, 0, 640, 480, 0, 0, 0, 0);
5431 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5432 ok(!!d3d, "Failed to create a D3D object.\n");
5433 if (!(device = create_device(d3d, window, NULL)))
5435 skip("Failed to create a D3D device, skipping tests.\n");
5436 IDirect3D9_Release(d3d);
5437 DestroyWindow(window);
5438 return;
5441 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5442 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5444 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
5446 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
5447 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5448 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
5449 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
5450 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
5451 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5452 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
5453 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
5454 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5455 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
5456 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
5457 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5458 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
5459 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
5460 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
5461 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5462 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
5463 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
5464 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5465 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
5466 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
5467 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5468 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
5469 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
5470 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5471 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
5472 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
5473 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5474 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
5475 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
5476 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5477 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
5478 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
5479 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5480 ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
5481 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
5482 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5483 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
5484 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
5485 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5486 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
5487 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
5488 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5489 ok(value == D3DTTFF_DISABLE,
5490 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
5491 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
5492 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5493 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
5494 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
5495 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5496 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
5497 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
5498 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5499 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value, i);
5500 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
5501 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5502 ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
5505 refcount = IDirect3DDevice9_Release(device);
5506 ok(!refcount, "Device has %u references left.\n", refcount);
5507 IDirect3D9_Release(d3d);
5508 DestroyWindow(window);
5511 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
5513 IDirect3DCubeTexture9 *texture;
5514 IDirect3D9 *d3d;
5515 HRESULT hr;
5517 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
5518 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
5519 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5520 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
5521 IDirect3D9_Release(d3d);
5522 if (FAILED(hr))
5524 skip("No cube mipmap generation support, skipping tests.\n");
5525 return;
5528 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
5529 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5530 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5531 IDirect3DCubeTexture9_Release(texture);
5533 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
5534 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5535 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5536 IDirect3DCubeTexture9_Release(texture);
5539 static void test_cube_texture_levels(IDirect3DDevice9 *device)
5541 IDirect3DCubeTexture9 *texture;
5542 IDirect3DSurface9 *surface;
5543 D3DSURFACE_DESC desc;
5544 DWORD levels;
5545 HRESULT hr;
5546 D3DCAPS9 caps;
5548 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5549 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5550 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
5551 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
5553 skip("Failed to create cube texture, skipping tests.\n");
5554 return;
5557 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
5558 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)
5559 ok(levels == 7, "Got unexpected levels %u.\n", levels);
5560 else
5561 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5563 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
5564 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5565 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
5566 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5567 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
5568 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5570 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
5571 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5572 IDirect3DSurface9_Release(surface);
5573 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
5574 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5575 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
5576 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5578 IDirect3DCubeTexture9_Release(texture);
5581 static void test_cube_textures(void)
5583 IDirect3DCubeTexture9 *texture;
5584 IDirect3DDevice9 *device;
5585 IDirect3D9 *d3d;
5586 ULONG refcount;
5587 D3DCAPS9 caps;
5588 HWND window;
5589 HRESULT hr;
5591 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5592 0, 0, 640, 480, 0, 0, 0, 0);
5593 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5594 ok(!!d3d, "Failed to create a D3D object.\n");
5595 if (!(device = create_device(d3d, window, NULL)))
5597 skip("Failed to create a D3D device, skipping tests.\n");
5598 IDirect3D9_Release(d3d);
5599 DestroyWindow(window);
5600 return;
5603 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5604 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5606 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
5608 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5609 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
5610 IDirect3DCubeTexture9_Release(texture);
5611 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5612 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
5613 IDirect3DCubeTexture9_Release(texture);
5614 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
5615 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
5616 IDirect3DCubeTexture9_Release(texture);
5618 else
5620 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5621 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
5622 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5623 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
5624 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
5625 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
5627 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
5628 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
5629 IDirect3DCubeTexture9_Release(texture);
5631 test_cube_texture_mipmap_gen(device);
5632 test_cube_texture_levels(device);
5634 refcount = IDirect3DDevice9_Release(device);
5635 ok(!refcount, "Device has %u references left.\n", refcount);
5636 IDirect3D9_Release(d3d);
5637 DestroyWindow(window);
5640 static void test_mipmap_gen(void)
5642 D3DTEXTUREFILTERTYPE filter_type;
5643 IDirect3DTexture9 *texture;
5644 IDirect3DSurface9 *surface;
5645 IDirect3DDevice9 *device;
5646 D3DSURFACE_DESC desc;
5647 D3DLOCKED_RECT lr;
5648 IDirect3D9 *d3d;
5649 ULONG refcount;
5650 unsigned int i;
5651 DWORD levels;
5652 HWND window;
5653 HRESULT hr;
5655 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5656 ok(!!d3d, "Failed to create a D3D object.\n");
5658 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5659 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
5661 skip("No mipmap generation support, skipping tests.\n");
5662 IDirect3D9_Release(d3d);
5663 return;
5666 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5667 0, 0, 640, 480, 0, 0, 0, 0);
5668 if (!(device = create_device(d3d, window, NULL)))
5670 skip("Failed to create a D3D device, skipping tests.\n");
5671 IDirect3D9_Release(d3d);
5672 DestroyWindow(window);
5673 return;
5676 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
5677 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5678 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5679 IDirect3DTexture9_Release(texture);
5681 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
5682 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5683 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5685 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
5686 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
5687 "Got unexpected filter_type %#x.\n", filter_type);
5688 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
5689 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5690 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
5691 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5692 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
5693 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
5694 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
5695 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5697 levels = IDirect3DTexture9_GetLevelCount(texture);
5698 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5700 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
5702 surface = NULL;
5703 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
5704 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5705 if (surface)
5706 IDirect3DSurface9_Release(surface);
5708 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
5709 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5711 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
5712 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5713 if (SUCCEEDED(hr))
5715 hr = IDirect3DTexture9_UnlockRect(texture, i);
5716 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5719 IDirect3DTexture9_Release(texture);
5721 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
5722 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5723 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5724 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
5725 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5726 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5728 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
5729 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5730 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5731 levels = IDirect3DTexture9_GetLevelCount(texture);
5732 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5733 IDirect3DTexture9_Release(texture);
5735 refcount = IDirect3DDevice9_Release(device);
5736 ok(!refcount, "Device has %u references left.\n", refcount);
5737 IDirect3D9_Release(d3d);
5738 DestroyWindow(window);
5741 static void test_filter(void)
5743 static const struct
5745 DWORD magfilter, minfilter, mipfilter;
5746 BOOL has_texture;
5747 HRESULT result;
5749 tests[] =
5751 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5752 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5753 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5754 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
5755 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
5757 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5758 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5759 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
5760 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
5762 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5763 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5764 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
5765 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
5766 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
5768 IDirect3DTexture9 *texture;
5769 IDirect3DDevice9 *device;
5770 IDirect3D9 *d3d;
5771 unsigned int i;
5772 ULONG refcount;
5773 DWORD passes;
5774 HWND window;
5775 HRESULT hr;
5777 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5778 ok(!!d3d, "Failed to create a D3D object.\n");
5780 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5781 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
5783 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
5784 IDirect3D9_Release(d3d);
5785 return;
5788 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5789 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
5791 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
5792 IDirect3D9_Release(d3d);
5793 return;
5796 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5797 0, 0, 640, 480, 0, 0, 0, 0);
5798 if (!(device = create_device(d3d, window, NULL)))
5800 skip("Failed to create a D3D device, skipping tests.\n");
5801 IDirect3D9_Release(d3d);
5802 DestroyWindow(window);
5803 return;
5806 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
5807 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
5808 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5810 /* Needed for ValidateDevice(). */
5811 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5812 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5814 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
5816 if (tests[i].has_texture)
5818 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
5819 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5821 else
5823 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5824 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5827 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
5828 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5829 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
5830 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5831 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
5832 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5834 passes = 0xdeadbeef;
5835 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
5836 ok(hr == tests[i].result,
5837 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
5838 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
5839 tests[i].mipfilter, tests[i].has_texture);
5840 if (SUCCEEDED(hr))
5841 ok(!!passes, "Got unexpected passes %#x.\n", passes);
5842 else
5843 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
5846 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5847 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5848 IDirect3DTexture9_Release(texture);
5850 refcount = IDirect3DDevice9_Release(device);
5851 ok(!refcount, "Device has %u references left.\n", refcount);
5852 IDirect3D9_Release(d3d);
5853 DestroyWindow(window);
5856 static void test_get_texture(void)
5858 IDirect3DBaseTexture9 *texture;
5859 IDirect3DDevice9 *device;
5860 IDirect3D9 *d3d;
5861 ULONG refcount;
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 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
5878 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5879 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5880 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
5881 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5882 ok(!texture, "Got unexpected texture %p.\n", texture);
5884 refcount = IDirect3DDevice9_Release(device);
5885 ok(!refcount, "Device has %u references left.\n", refcount);
5886 IDirect3D9_Release(d3d);
5887 DestroyWindow(window);
5890 static void test_lod(void)
5892 IDirect3DTexture9 *texture;
5893 IDirect3DDevice9 *device;
5894 IDirect3D9 *d3d;
5895 ULONG refcount;
5896 HWND window;
5897 HRESULT hr;
5898 DWORD ret;
5900 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5901 0, 0, 640, 480, 0, 0, 0, 0);
5902 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5903 ok(!!d3d, "Failed to create a D3D object.\n");
5904 if (!(device = create_device(d3d, window, NULL)))
5906 skip("Failed to create a D3D device, skipping tests.\n");
5907 IDirect3D9_Release(d3d);
5908 DestroyWindow(window);
5909 return;
5912 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5913 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5914 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5916 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5917 * return a HRESULT, so it can't return a normal error. Instead, the call
5918 * is simply ignored. */
5919 ret = IDirect3DTexture9_SetLOD(texture, 0);
5920 ok(!ret, "Got unexpected ret %u.\n", ret);
5921 ret = IDirect3DTexture9_SetLOD(texture, 1);
5922 ok(!ret, "Got unexpected ret %u.\n", ret);
5923 ret = IDirect3DTexture9_SetLOD(texture, 2);
5924 ok(!ret, "Got unexpected ret %u.\n", ret);
5925 ret = IDirect3DTexture9_GetLOD(texture);
5926 ok(!ret, "Got unexpected ret %u.\n", ret);
5928 IDirect3DTexture9_Release(texture);
5929 refcount = IDirect3DDevice9_Release(device);
5930 ok(!refcount, "Device has %u references left.\n", refcount);
5931 IDirect3D9_Release(d3d);
5932 DestroyWindow(window);
5935 static void test_surface_get_container(void)
5937 IDirect3DTexture9 *texture = NULL;
5938 IDirect3DSurface9 *surface = NULL;
5939 IDirect3DDevice9 *device;
5940 IUnknown *container;
5941 IDirect3D9 *d3d;
5942 ULONG refcount;
5943 HWND window;
5944 HRESULT hr;
5946 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5947 0, 0, 640, 480, 0, 0, 0, 0);
5948 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5949 ok(!!d3d, "Failed to create a D3D object.\n");
5950 if (!(device = create_device(d3d, window, NULL)))
5952 skip("Failed to create a D3D device, skipping tests.\n");
5953 IDirect3D9_Release(d3d);
5954 DestroyWindow(window);
5955 return;
5958 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
5959 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5960 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5961 ok(!!texture, "Got unexpected texture %p.\n", texture);
5963 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5964 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5965 ok(!!surface, "Got unexpected surface %p.\n", surface);
5967 /* These should work... */
5968 container = NULL;
5969 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
5970 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5971 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5972 IUnknown_Release(container);
5974 container = NULL;
5975 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
5976 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5977 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5978 IUnknown_Release(container);
5980 container = NULL;
5981 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
5982 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5983 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5984 IUnknown_Release(container);
5986 container = NULL;
5987 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
5988 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5989 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5990 IUnknown_Release(container);
5992 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5993 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
5994 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5995 ok(!container, "Got unexpected container %p.\n", container);
5997 IDirect3DSurface9_Release(surface);
5998 IDirect3DTexture9_Release(texture);
5999 refcount = IDirect3DDevice9_Release(device);
6000 ok(!refcount, "Device has %u references left.\n", refcount);
6001 IDirect3D9_Release(d3d);
6002 DestroyWindow(window);
6005 static void test_surface_alignment(void)
6007 IDirect3DSurface9 *surface;
6008 IDirect3DDevice9 *device;
6009 D3DLOCKED_RECT lr;
6010 unsigned int i, j;
6011 IDirect3D9 *d3d;
6012 ULONG refcount;
6013 HWND window;
6014 HRESULT hr;
6016 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6017 0, 0, 640, 480, 0, 0, 0, 0);
6018 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6019 ok(!!d3d, "Failed to create a D3D object.\n");
6020 if (!(device = create_device(d3d, window, NULL)))
6022 skip("Failed to create a D3D device, skipping tests.\n");
6023 IDirect3D9_Release(d3d);
6024 DestroyWindow(window);
6025 return;
6028 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
6029 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
6030 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
6031 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6033 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6034 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6035 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
6036 /* Some applications also depend on the exact pitch, rather than just the
6037 * alignment. */
6038 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
6039 hr = IDirect3DSurface9_UnlockRect(surface);
6040 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6041 IDirect3DSurface9_Release(surface);
6043 for (i = 0; i < 5; ++i)
6045 IDirect3DTexture9 *texture;
6046 unsigned int level_count;
6047 D3DSURFACE_DESC desc;
6048 int expected_pitch;
6050 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
6051 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
6052 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6053 if (FAILED(hr))
6055 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
6056 continue;
6059 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
6060 for (j = 0; j < level_count; ++j)
6062 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
6063 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
6064 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6065 hr = IDirect3DTexture9_UnlockRect(texture, j);
6066 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6068 expected_pitch = ((desc.Width + 3) >> 2) << 3;
6069 if (i > 0)
6070 expected_pitch <<= 1;
6071 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
6072 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
6074 IDirect3DTexture9_Release(texture);
6077 refcount = IDirect3DDevice9_Release(device);
6078 ok(!refcount, "Device has %u references left.\n", refcount);
6079 IDirect3D9_Release(d3d);
6080 DestroyWindow(window);
6083 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
6084 * different from regular formats. This test verifies we return the correct
6085 * memory offsets. */
6086 static void test_lockrect_offset(void)
6088 static const struct
6090 D3DFORMAT format;
6091 const char *name;
6092 unsigned int block_width;
6093 unsigned int block_height;
6094 unsigned int block_size;
6096 dxt_formats[] =
6098 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
6099 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
6100 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
6101 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
6102 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
6103 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
6105 unsigned int expected_offset, offset, i;
6106 const RECT rect = {60, 60, 68, 68};
6107 IDirect3DSurface9 *surface;
6108 D3DLOCKED_RECT locked_rect;
6109 IDirect3DDevice9 *device;
6110 int expected_pitch;
6111 IDirect3D9 *d3d;
6112 ULONG refcount;
6113 HWND window;
6114 BYTE *base;
6115 HRESULT hr;
6117 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6118 0, 0, 640, 480, 0, 0, 0, 0);
6119 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6120 ok(!!d3d, "Failed to create a D3D object.\n");
6121 if (!(device = create_device(d3d, window, NULL)))
6123 skip("Failed to create a D3D device, skipping tests.\n");
6124 IDirect3D9_Release(d3d);
6125 DestroyWindow(window);
6126 return;
6129 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
6131 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6132 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
6134 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
6135 continue;
6138 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
6139 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
6140 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6142 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6143 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6145 base = locked_rect.pBits;
6146 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
6147 * dxt_formats[i].block_size;
6148 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
6149 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
6151 hr = IDirect3DSurface9_UnlockRect(surface);
6152 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6154 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
6155 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6157 offset = (BYTE *)locked_rect.pBits - base;
6158 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
6159 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
6160 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
6161 offset, dxt_formats[i].name, expected_offset);
6163 hr = IDirect3DSurface9_UnlockRect(surface);
6164 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6166 IDirect3DSurface9_Release(surface);
6169 refcount = IDirect3DDevice9_Release(device);
6170 ok(!refcount, "Device has %u references left.\n", refcount);
6171 IDirect3D9_Release(d3d);
6172 DestroyWindow(window);
6175 static void test_lockrect_invalid(void)
6177 static const struct
6179 RECT rect;
6180 HRESULT win7_result;
6182 test_data[] =
6184 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
6185 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
6186 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
6187 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
6188 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
6189 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
6190 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
6191 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
6192 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
6193 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
6194 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
6195 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
6196 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
6198 static const RECT test_rect_2 = {0, 0, 8, 8};
6199 IDirect3DSurface9 *surface = NULL;
6200 D3DLOCKED_RECT locked_rect;
6201 IDirect3DDevice9 *device;
6202 IDirect3D9 *d3d;
6203 unsigned int i;
6204 ULONG refcount;
6205 HWND window;
6206 BYTE *base;
6207 HRESULT hr;
6209 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6210 0, 0, 640, 480, 0, 0, 0, 0);
6211 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6212 ok(!!d3d, "Failed to create a D3D object.\n");
6213 if (!(device = create_device(d3d, window, NULL)))
6215 skip("Failed to create a D3D device, skipping tests.\n");
6216 IDirect3D9_Release(d3d);
6217 DestroyWindow(window);
6218 return;
6221 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
6222 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6223 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6224 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6225 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6226 base = locked_rect.pBits;
6227 hr = IDirect3DSurface9_UnlockRect(surface);
6228 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6230 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
6232 unsigned int offset, expected_offset;
6233 const RECT *rect = &test_data[i].rect;
6235 locked_rect.pBits = (BYTE *)0xdeadbeef;
6236 locked_rect.Pitch = 0xdeadbeef;
6238 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
6239 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
6240 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
6241 * one broken. */
6242 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
6243 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
6244 rect->left, rect->top, rect->right, rect->bottom, hr);
6245 if (FAILED(hr))
6246 continue;
6248 offset = (BYTE *)locked_rect.pBits - base;
6249 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
6250 ok(offset == expected_offset,
6251 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
6252 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
6254 hr = IDirect3DSurface9_UnlockRect(surface);
6255 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6258 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6259 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
6260 locked_rect.pBits = (BYTE *)0xdeadbeef;
6261 locked_rect.Pitch = 1;
6262 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6263 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6264 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p\n",
6265 locked_rect.pBits);
6266 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d\n", locked_rect.Pitch);
6267 hr = IDirect3DSurface9_UnlockRect(surface);
6268 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6270 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
6271 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
6272 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
6273 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
6274 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
6275 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
6276 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
6277 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
6278 hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
6279 hr = IDirect3DSurface9_UnlockRect(surface);
6280 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6282 IDirect3DSurface9_Release(surface);
6283 refcount = IDirect3DDevice9_Release(device);
6284 ok(!refcount, "Device has %u references left.\n", refcount);
6285 IDirect3D9_Release(d3d);
6286 DestroyWindow(window);
6289 static void test_private_data(void)
6291 ULONG refcount, expected_refcount;
6292 IDirect3DTexture9 *texture;
6293 IDirect3DSurface9 *surface, *surface2;
6294 IDirect3DDevice9 *device;
6295 IDirect3D9 *d3d;
6296 IUnknown *ptr;
6297 HWND window;
6298 HRESULT hr;
6299 DWORD size;
6300 DWORD data[4] = {1, 2, 3, 4};
6301 static const GUID d3d9_private_data_test_guid =
6303 0xfdb37466,
6304 0x428f,
6305 0x4edf,
6306 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
6308 static const GUID d3d9_private_data_test_guid2 =
6310 0x2e5afac2,
6311 0x87b5,
6312 0x4c10,
6313 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
6316 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6317 0, 0, 640, 480, 0, 0, 0, 0);
6318 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6319 ok(!!d3d, "Failed to create a D3D object.\n");
6320 if (!(device = create_device(d3d, window, NULL)))
6322 skip("Failed to create a D3D device, skipping tests.\n");
6323 IDirect3D9_Release(d3d);
6324 DestroyWindow(window);
6325 return;
6328 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
6329 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6330 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6332 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6333 device, 0, D3DSPD_IUNKNOWN);
6334 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6335 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6336 device, 5, D3DSPD_IUNKNOWN);
6337 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6338 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6339 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
6340 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6342 /* A failing SetPrivateData call does not clear the old data with the same tag. */
6343 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
6344 sizeof(device), D3DSPD_IUNKNOWN);
6345 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6346 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
6347 sizeof(device) * 2, D3DSPD_IUNKNOWN);
6348 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6349 size = sizeof(ptr);
6350 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6351 ok(SUCCEEDED(hr), "Failed to get private data, hr %#x.\n", hr);
6352 IUnknown_Release(ptr);
6353 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6354 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6356 refcount = get_refcount((IUnknown *)device);
6357 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6358 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6359 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6360 expected_refcount = refcount + 1;
6361 refcount = get_refcount((IUnknown *)device);
6362 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6363 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6364 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6365 expected_refcount = refcount - 1;
6366 refcount = get_refcount((IUnknown *)device);
6367 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6369 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6370 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6371 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6372 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6373 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6374 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6375 refcount = get_refcount((IUnknown *)device);
6376 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6378 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6379 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6380 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6381 size = 2 * sizeof(ptr);
6382 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6383 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6384 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6385 expected_refcount = refcount + 2;
6386 refcount = get_refcount((IUnknown *)device);
6387 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6388 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
6389 IUnknown_Release(ptr);
6390 expected_refcount--;
6392 ptr = (IUnknown *)0xdeadbeef;
6393 size = 1;
6394 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
6395 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6396 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6397 size = 2 * sizeof(ptr);
6398 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
6399 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6400 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6401 refcount = get_refcount((IUnknown *)device);
6402 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6403 size = 1;
6404 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6405 ok(hr == D3DERR_MOREDATA, "Got unexpected hr %#x.\n", hr);
6406 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6407 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
6408 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, NULL, NULL);
6409 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6410 size = 0xdeadbabe;
6411 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, &ptr, &size);
6412 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6413 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
6414 ok(size == 0xdeadbabe, "Got unexpected size %u.\n", size);
6415 /* GetPrivateData with size = NULL causes an access violation on Windows if the
6416 * requested data exists. */
6418 /* Destroying the surface frees the held reference. */
6419 IDirect3DSurface9_Release(surface);
6420 expected_refcount = refcount - 2;
6421 refcount = get_refcount((IUnknown *)device);
6422 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6424 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH,
6425 &texture, NULL);
6426 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6427 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6428 ok(SUCCEEDED(hr), "Failed to get texture level 0, hr %#x.\n", hr);
6429 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
6430 ok(SUCCEEDED(hr), "Failed to get texture level 1, hr %#x.\n", hr);
6432 hr = IDirect3DTexture9_SetPrivateData(texture, &d3d9_private_data_test_guid, data, sizeof(data), 0);
6433 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6435 memset(data, 0, sizeof(data));
6436 size = sizeof(data);
6437 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, data, &size);
6438 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6439 hr = IDirect3DTexture9_GetPrivateData(texture, &d3d9_private_data_test_guid, data, &size);
6440 ok(SUCCEEDED(hr), "Failed to get private data, hr %#x.\n", hr);
6441 ok(data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4,
6442 "Got unexpected private data: %u, %u, %u, %u.\n", data[0], data[1], data[2], data[3]);
6444 hr = IDirect3DTexture9_FreePrivateData(texture, &d3d9_private_data_test_guid);
6445 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6447 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, data, sizeof(data), 0);
6448 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6449 hr = IDirect3DSurface9_GetPrivateData(surface2, &d3d9_private_data_test_guid, data, &size);
6450 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6452 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6453 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6455 IDirect3DSurface9_Release(surface2);
6456 IDirect3DSurface9_Release(surface);
6457 IDirect3DTexture9_Release(texture);
6459 refcount = IDirect3DDevice9_Release(device);
6460 ok(!refcount, "Device has %u references left.\n", refcount);
6461 IDirect3D9_Release(d3d);
6462 DestroyWindow(window);
6465 static void test_getdc(void)
6467 static const struct
6469 const char *name;
6470 D3DFORMAT format;
6471 BOOL getdc_supported;
6473 testdata[] =
6475 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, TRUE },
6476 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, TRUE },
6477 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, TRUE },
6478 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, TRUE },
6479 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, TRUE },
6480 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8, TRUE },
6481 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
6482 {"D3DFMT_V8U8", D3DFMT_V8U8, FALSE},
6483 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8, FALSE},
6484 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
6485 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
6486 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2, FALSE},
6487 {"D3DFMT_P8", D3DFMT_P8, FALSE},
6488 {"D3DFMT_L8", D3DFMT_L8, FALSE},
6489 {"D3DFMT_A8L8", D3DFMT_A8L8, FALSE},
6490 {"D3DFMT_DXT1", D3DFMT_DXT1, FALSE},
6491 {"D3DFMT_DXT2", D3DFMT_DXT2, FALSE},
6492 {"D3DFMT_DXT3", D3DFMT_DXT3, FALSE},
6493 {"D3DFMT_DXT4", D3DFMT_DXT4, FALSE},
6494 {"D3DFMT_DXT5", D3DFMT_DXT5, FALSE},
6496 IDirect3DTexture9 *texture;
6497 IDirect3DSurface9 *surface;
6498 IDirect3DDevice9 *device;
6499 IDirect3D9 *d3d;
6500 unsigned int i;
6501 ULONG refcount;
6502 HWND window;
6503 HRESULT hr;
6504 HDC dc;
6506 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6507 0, 0, 640, 480, 0, 0, 0, 0);
6508 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6509 ok(!!d3d, "Failed to create a D3D object.\n");
6510 if (!(device = create_device(d3d, window, NULL)))
6512 skip("Failed to create a D3D device, skipping tests.\n");
6513 IDirect3D9_Release(d3d);
6514 DestroyWindow(window);
6515 return;
6518 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
6520 texture = NULL;
6521 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
6522 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
6523 if (FAILED(hr))
6525 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
6526 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
6527 if (FAILED(hr))
6529 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
6530 continue;
6532 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6533 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
6536 dc = (void *)0x1234;
6537 hr = IDirect3DSurface9_GetDC(surface, &dc);
6538 if (testdata[i].getdc_supported)
6539 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
6540 else
6541 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
6543 if (SUCCEEDED(hr))
6545 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
6546 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
6548 else
6550 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
6553 IDirect3DSurface9_Release(surface);
6554 if (texture)
6555 IDirect3DTexture9_Release(texture);
6558 refcount = IDirect3DDevice9_Release(device);
6559 ok(!refcount, "Device has %u references left.\n", refcount);
6560 IDirect3D9_Release(d3d);
6561 DestroyWindow(window);
6564 static void test_surface_dimensions(void)
6566 IDirect3DSurface9 *surface;
6567 IDirect3DDevice9 *device;
6568 IDirect3D9 *d3d;
6569 ULONG refcount;
6570 HWND window;
6571 HRESULT hr;
6573 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6574 0, 0, 640, 480, 0, 0, 0, 0);
6575 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6576 ok(!!d3d, "Failed to create a D3D object.\n");
6577 if (!(device = create_device(d3d, window, NULL)))
6579 skip("Failed to create a D3D device, skipping tests.\n");
6580 IDirect3D9_Release(d3d);
6581 DestroyWindow(window);
6582 return;
6585 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
6586 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6587 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6588 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
6589 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6590 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6592 refcount = IDirect3DDevice9_Release(device);
6593 ok(!refcount, "Device has %u references left.\n", refcount);
6594 IDirect3D9_Release(d3d);
6595 DestroyWindow(window);
6598 static void test_surface_format_null(void)
6600 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
6601 IDirect3DTexture9 *texture;
6602 IDirect3DSurface9 *surface;
6603 IDirect3DSurface9 *rt, *ds;
6604 D3DLOCKED_RECT locked_rect;
6605 IDirect3DDevice9 *device;
6606 D3DSURFACE_DESC desc;
6607 IDirect3D9 *d3d;
6608 ULONG refcount;
6609 HWND window;
6610 HRESULT hr;
6612 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6613 ok(!!d3d, "Failed to create a D3D object.\n");
6615 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6616 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
6617 if (hr != D3D_OK)
6619 skip("No D3DFMT_NULL support, skipping test.\n");
6620 IDirect3D9_Release(d3d);
6621 return;
6624 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6625 0, 0, 640, 480, 0, 0, 0, 0);
6626 if (!(device = create_device(d3d, window, NULL)))
6628 skip("Failed to create a D3D device, skipping tests.\n");
6629 IDirect3D9_Release(d3d);
6630 DestroyWindow(window);
6631 return;
6634 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6635 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
6636 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
6638 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6639 D3DFMT_NULL, D3DFMT_D24S8);
6640 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
6642 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
6643 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
6644 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
6646 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
6647 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
6649 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
6650 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
6652 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
6653 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
6655 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
6656 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6658 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
6659 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
6661 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
6662 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
6664 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
6665 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6667 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
6668 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
6670 IDirect3DSurface9_Release(rt);
6671 IDirect3DSurface9_Release(ds);
6673 hr = IDirect3DSurface9_GetDesc(surface, &desc);
6674 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
6675 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
6676 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
6678 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6679 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6680 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
6681 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
6683 hr = IDirect3DSurface9_UnlockRect(surface);
6684 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6686 IDirect3DSurface9_Release(surface);
6688 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
6689 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
6690 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6691 IDirect3DTexture9_Release(texture);
6693 refcount = IDirect3DDevice9_Release(device);
6694 ok(!refcount, "Device has %u references left.\n", refcount);
6695 IDirect3D9_Release(d3d);
6696 DestroyWindow(window);
6699 static void test_surface_double_unlock(void)
6701 static const D3DPOOL pools[] =
6703 D3DPOOL_DEFAULT,
6704 D3DPOOL_SCRATCH,
6705 D3DPOOL_SYSTEMMEM,
6707 IDirect3DSurface9 *surface;
6708 IDirect3DDevice9 *device;
6709 D3DLOCKED_RECT lr;
6710 IDirect3D9 *d3d;
6711 unsigned int i;
6712 ULONG refcount;
6713 HWND window;
6714 HRESULT hr;
6716 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6717 0, 0, 640, 480, 0, 0, 0, 0);
6718 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6719 ok(!!d3d, "Failed to create a D3D object.\n");
6720 if (!(device = create_device(d3d, window, NULL)))
6722 skip("Failed to create a D3D device, skipping tests.\n");
6723 IDirect3D9_Release(d3d);
6724 DestroyWindow(window);
6725 return;
6728 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
6730 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
6731 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
6732 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
6734 hr = IDirect3DSurface9_UnlockRect(surface);
6735 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
6736 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6737 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
6738 hr = IDirect3DSurface9_UnlockRect(surface);
6739 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
6740 hr = IDirect3DSurface9_UnlockRect(surface);
6741 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
6743 IDirect3DSurface9_Release(surface);
6746 refcount = IDirect3DDevice9_Release(device);
6747 ok(!refcount, "Device has %u references left.\n", refcount);
6748 IDirect3D9_Release(d3d);
6749 DestroyWindow(window);
6752 static void test_surface_blocks(void)
6754 static const struct
6756 D3DFORMAT fmt;
6757 const char *name;
6758 unsigned int block_width;
6759 unsigned int block_height;
6760 BOOL broken;
6761 BOOL create_size_checked, core_fmt;
6763 formats[] =
6765 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE, TRUE, TRUE },
6766 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE, TRUE, TRUE },
6767 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE, TRUE, TRUE },
6768 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE, TRUE, TRUE },
6769 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE, TRUE, TRUE },
6770 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
6771 * which doesn't match the format spec. On newer Nvidia cards
6772 * it has the correct 4x4 block size */
6773 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE, FALSE, FALSE},
6774 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE, FALSE, TRUE },
6775 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE, FALSE, TRUE },
6777 static const struct
6779 D3DPOOL pool;
6780 const char *name;
6781 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
6782 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
6783 BOOL success;
6785 pools[] =
6787 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
6788 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
6789 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
6790 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
6792 static struct
6794 D3DRESOURCETYPE rtype;
6795 const char *type_name;
6796 D3DPOOL pool;
6797 const char *pool_name;
6798 BOOL need_driver_support, need_runtime_support;
6800 create_tests[] =
6802 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6803 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, TRUE },
6804 /* Managed offscreen plain surfaces are not supported */
6805 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6807 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6808 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
6809 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
6810 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6812 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6813 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
6814 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
6815 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6817 IDirect3DTexture9 *texture;
6818 IDirect3DCubeTexture9 *cube_texture;
6819 IDirect3DSurface9 *surface;
6820 D3DLOCKED_RECT locked_rect;
6821 IDirect3DDevice9 *device;
6822 unsigned int i, j, w, h;
6823 BOOL surface_only;
6824 IDirect3D9 *d3d;
6825 ULONG refcount;
6826 HWND window;
6827 HRESULT hr;
6828 RECT rect;
6829 BOOL tex_pow2, cube_pow2;
6830 D3DCAPS9 caps;
6832 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6833 0, 0, 640, 480, 0, 0, 0, 0);
6834 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6835 ok(!!d3d, "Failed to create a D3D object.\n");
6836 if (!(device = create_device(d3d, window, NULL)))
6838 skip("Failed to create a D3D device, skipping tests.\n");
6839 IDirect3D9_Release(d3d);
6840 DestroyWindow(window);
6841 return;
6844 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6845 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6846 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
6847 if (tex_pow2)
6848 tex_pow2 = !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
6849 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
6851 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
6853 BOOL tex_support, cube_support, surface_support, format_known, dynamic_tex_support;
6855 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6856 0, D3DRTYPE_TEXTURE, formats[i].fmt);
6857 tex_support = SUCCEEDED(hr);
6858 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6859 0, D3DRTYPE_CUBETEXTURE, formats[i].fmt);
6860 cube_support = SUCCEEDED(hr);
6861 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6862 0, D3DRTYPE_SURFACE, formats[i].fmt);
6863 surface_support = SUCCEEDED(hr);
6865 /* Scratch pool in general allows texture creation even if the driver does
6866 * not support the format. If the format is an extension format that is not
6867 * known to the runtime, like ATI2N, some driver support is required for
6868 * this to work.
6870 * It is also possible that Windows Vista and Windows 7 d3d9 runtimes know
6871 * about ATI2N. I cannot check this because all my Vista+ machines support
6872 * ATI2N in hardware, but none of my WinXP machines do. */
6873 format_known = tex_support || cube_support || surface_support;
6875 for (w = 1; w <= 8; w++)
6877 for (h = 1; h <= 8; h++)
6879 BOOL block_aligned = TRUE;
6880 BOOL size_is_pow2;
6882 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
6883 block_aligned = FALSE;
6885 size_is_pow2 = !(w & (w - 1) || h & (h - 1));
6887 for (j = 0; j < sizeof(create_tests) / sizeof(*create_tests); j++)
6889 BOOL support, pow2;
6890 HRESULT expect_hr;
6891 BOOL may_succeed = FALSE;
6892 IUnknown **check_null;
6894 if (!formats[i].core_fmt)
6896 /* AMD warns against creating ATI2N textures smaller than
6897 * the block size because the runtime cannot calculate the
6898 * correct texture size. Generalize this for all extension
6899 * formats. */
6900 if (w < formats[i].block_width || h < formats[i].block_height)
6901 continue;
6904 texture = (IDirect3DTexture9 *)0xdeadbeef;
6905 cube_texture = (IDirect3DCubeTexture9 *)0xdeadbeef;
6906 surface = (IDirect3DSurface9 *)0xdeadbeef;
6908 switch (create_tests[j].rtype)
6910 case D3DRTYPE_TEXTURE:
6911 check_null = (IUnknown **)&texture;
6912 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1, 0,
6913 formats[i].fmt, create_tests[j].pool, &texture, NULL);
6914 support = tex_support;
6915 pow2 = tex_pow2;
6916 break;
6918 case D3DRTYPE_CUBETEXTURE:
6919 if (w != h)
6920 continue;
6921 check_null = (IUnknown **)&cube_texture;
6922 hr = IDirect3DDevice9_CreateCubeTexture(device, w, 1, 0,
6923 formats[i].fmt, create_tests[j].pool, &cube_texture, NULL);
6924 support = cube_support;
6925 pow2 = cube_pow2;
6926 break;
6928 case D3DRTYPE_SURFACE:
6929 check_null = (IUnknown **)&surface;
6930 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, w, h,
6931 formats[i].fmt, create_tests[j].pool, &surface, NULL);
6932 support = surface_support;
6933 pow2 = FALSE;
6934 break;
6936 default:
6937 check_null = NULL;
6938 pow2 = FALSE;
6939 support = FALSE;
6940 break;
6943 if (create_tests[j].need_driver_support && !support)
6944 expect_hr = D3DERR_INVALIDCALL;
6945 else if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !format_known)
6946 expect_hr = D3DERR_INVALIDCALL;
6947 else if (formats[i].create_size_checked && !block_aligned)
6948 expect_hr = D3DERR_INVALIDCALL;
6949 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
6950 expect_hr = D3DERR_INVALIDCALL;
6951 else
6952 expect_hr = D3D_OK;
6954 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
6955 * does not support it. Accept scratch creation of extension formats on
6956 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
6957 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
6958 * support it. */
6959 if (!formats[i].core_fmt && !format_known && FAILED(expect_hr))
6960 may_succeed = TRUE;
6962 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
6963 "Got unexpected hr %#x for format %s, pool %s, type %s, size %ux%u.\n",
6964 hr, formats[i].name, create_tests[j].pool_name, create_tests[j].type_name, w, h);
6965 if (FAILED(hr))
6966 ok(*check_null == NULL, "Got object ptr %p, expected NULL.\n", *check_null);
6967 else
6968 IUnknown_Release(*check_null);
6973 surface_only = FALSE;
6974 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6975 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt);
6976 dynamic_tex_support = SUCCEEDED(hr);
6977 if (!dynamic_tex_support)
6979 if (!surface_support)
6981 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
6982 continue;
6984 surface_only = TRUE;
6987 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
6989 switch (pools[j].pool)
6991 case D3DPOOL_SYSTEMMEM:
6992 case D3DPOOL_MANAGED:
6993 if (surface_only)
6994 continue;
6995 /* Fall through */
6996 case D3DPOOL_DEFAULT:
6997 if (surface_only)
6999 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
7000 formats[i].fmt, pools[j].pool, &surface, NULL);
7001 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
7003 else
7005 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
7006 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
7007 formats[i].fmt, pools[j].pool, &texture, NULL);
7008 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7009 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7010 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
7011 IDirect3DTexture9_Release(texture);
7013 break;
7015 case D3DPOOL_SCRATCH:
7016 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
7017 formats[i].fmt, pools[j].pool, &surface, NULL);
7018 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
7019 break;
7021 default:
7022 break;
7025 if (formats[i].block_width > 1)
7027 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
7028 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7029 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
7030 "Partial block lock %s, expected %s, format %s, pool %s.\n",
7031 SUCCEEDED(hr) ? "succeeded" : "failed",
7032 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
7033 if (SUCCEEDED(hr))
7035 hr = IDirect3DSurface9_UnlockRect(surface);
7036 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7039 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
7040 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7041 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
7042 "Partial block lock %s, expected %s, format %s, pool %s.\n",
7043 SUCCEEDED(hr) ? "succeeded" : "failed",
7044 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
7045 if (SUCCEEDED(hr))
7047 hr = IDirect3DSurface9_UnlockRect(surface);
7048 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7052 if (formats[i].block_height > 1)
7054 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
7055 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7056 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
7057 "Partial block lock %s, expected %s, format %s, pool %s.\n",
7058 SUCCEEDED(hr) ? "succeeded" : "failed",
7059 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
7060 if (SUCCEEDED(hr))
7062 hr = IDirect3DSurface9_UnlockRect(surface);
7063 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7066 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
7067 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7068 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
7069 "Partial block lock %s, expected %s, format %s, pool %s.\n",
7070 SUCCEEDED(hr) ? "succeeded" : "failed",
7071 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
7072 if (SUCCEEDED(hr))
7074 hr = IDirect3DSurface9_UnlockRect(surface);
7075 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7079 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
7080 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
7081 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
7082 hr = IDirect3DSurface9_UnlockRect(surface);
7083 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
7085 IDirect3DSurface9_Release(surface);
7088 if (!dynamic_tex_support)
7090 skip("Dynamic %s textures not supported, skipping mipmap test.\n", formats[i].name);
7091 continue;
7094 if (formats[i].block_width == 1 && formats[i].block_height == 1)
7095 continue;
7096 if (!formats[i].core_fmt)
7097 continue;
7099 hr = IDirect3DDevice9_CreateTexture(device, formats[i].block_width, formats[i].block_height, 2,
7100 D3DUSAGE_DYNAMIC, formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
7101 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, format %s.\n", hr, formats[i].name);
7103 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, NULL, 0);
7104 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
7105 hr = IDirect3DTexture9_UnlockRect(texture, 1);
7106 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
7108 rect.left = 0;
7109 rect.top = 0;
7110 rect.right = formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1;
7111 rect.bottom = formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1;
7112 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
7113 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
7114 hr = IDirect3DTexture9_UnlockRect(texture, 1);
7115 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
7117 rect.right = formats[i].block_width;
7118 rect.bottom = formats[i].block_height;
7119 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
7120 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7121 if (SUCCEEDED(hr))
7122 IDirect3DTexture9_UnlockRect(texture, 1);
7124 IDirect3DTexture9_Release(texture);
7127 refcount = IDirect3DDevice9_Release(device);
7128 ok(!refcount, "Device has %u references left.\n", refcount);
7129 IDirect3D9_Release(d3d);
7130 DestroyWindow(window);
7133 static void test_set_palette(void)
7135 IDirect3DDevice9 *device;
7136 IDirect3D9 *d3d9;
7137 UINT refcount;
7138 HWND window;
7139 HRESULT hr;
7140 PALETTEENTRY pal[256];
7141 unsigned int i;
7142 D3DCAPS9 caps;
7144 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7145 0, 0, 640, 480, 0, 0, 0, 0);
7146 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7147 ok(!!d3d9, "Failed to create a D3D object.\n");
7148 if (!(device = create_device(d3d9, window, NULL)))
7150 skip("Failed to create a D3D device, skipping tests.\n");
7151 DestroyWindow(window);
7152 return;
7155 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
7157 pal[i].peRed = i;
7158 pal[i].peGreen = i;
7159 pal[i].peBlue = i;
7160 pal[i].peFlags = 0xff;
7162 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
7163 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
7165 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7166 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7167 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
7169 pal[i].peRed = i;
7170 pal[i].peGreen = i;
7171 pal[i].peBlue = i;
7172 pal[i].peFlags = i;
7174 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
7176 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
7177 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
7179 else
7181 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
7182 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
7185 refcount = IDirect3DDevice9_Release(device);
7186 ok(!refcount, "Device has %u references left.\n", refcount);
7187 IDirect3D9_Release(d3d9);
7188 DestroyWindow(window);
7191 static void test_swvp_buffer(void)
7193 IDirect3DDevice9 *device;
7194 IDirect3D9 *d3d9;
7195 UINT refcount;
7196 HWND window;
7197 HRESULT hr;
7198 unsigned int i;
7199 IDirect3DVertexBuffer9 *buffer;
7200 static const unsigned int bufsize = 1024;
7201 D3DVERTEXBUFFER_DESC desc;
7202 D3DPRESENT_PARAMETERS present_parameters = {0};
7203 struct
7205 float x, y, z;
7206 } *ptr, *ptr2;
7208 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7209 0, 0, 640, 480, 0, 0, 0, 0);
7210 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7211 ok(!!d3d9, "Failed to create a D3D object.\n");
7213 present_parameters.Windowed = TRUE;
7214 present_parameters.hDeviceWindow = window;
7215 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
7216 present_parameters.BackBufferWidth = screen_width;
7217 present_parameters.BackBufferHeight = screen_height;
7218 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
7219 present_parameters.EnableAutoDepthStencil = FALSE;
7220 if (FAILED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
7221 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
7223 skip("Failed to create a D3D device, skipping tests.\n");
7224 DestroyWindow(window);
7225 IDirect3D9_Release(d3d9);
7226 return;
7229 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
7230 D3DPOOL_DEFAULT, &buffer, NULL);
7231 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
7232 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
7233 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
7234 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
7235 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
7236 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
7238 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
7239 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
7240 for (i = 0; i < bufsize; i++)
7242 ptr[i].x = i * 1.0f;
7243 ptr[i].y = i * 2.0f;
7244 ptr[i].z = i * 3.0f;
7246 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7247 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
7249 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7250 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
7251 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
7252 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
7253 hr = IDirect3DDevice9_BeginScene(device);
7254 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7255 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
7256 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7257 hr = IDirect3DDevice9_EndScene(device);
7258 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7260 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
7261 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
7262 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
7263 for (i = 0; i < bufsize; i++)
7265 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
7267 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
7268 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
7269 break;
7272 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7273 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
7275 IDirect3DVertexBuffer9_Release(buffer);
7276 refcount = IDirect3DDevice9_Release(device);
7277 ok(!refcount, "Device has %u references left.\n", refcount);
7278 IDirect3D9_Release(d3d9);
7279 DestroyWindow(window);
7282 static void test_npot_textures(void)
7284 IDirect3DDevice9 *device = NULL;
7285 IDirect3D9 *d3d9;
7286 ULONG refcount;
7287 HWND window = NULL;
7288 HRESULT hr;
7289 D3DCAPS9 caps;
7290 IDirect3DTexture9 *texture;
7291 IDirect3DCubeTexture9 *cube_texture;
7292 IDirect3DVolumeTexture9 *volume_texture;
7293 struct
7295 D3DPOOL pool;
7296 const char *pool_name;
7297 HRESULT hr;
7299 pools[] =
7301 { D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL },
7302 { D3DPOOL_MANAGED, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL },
7303 { D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL },
7304 { D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", D3D_OK },
7306 unsigned int i, levels;
7307 BOOL tex_pow2, cube_pow2, vol_pow2;
7309 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7310 0, 0, 640, 480, 0, 0, 0, 0);
7311 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7312 ok(!!d3d9, "Failed to create a D3D object.\n");
7313 if (!(device = create_device(d3d9, window, NULL)))
7315 skip("Failed to create a D3D device, skipping tests.\n");
7316 goto done;
7319 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7320 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7321 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
7322 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
7323 vol_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
7324 ok(cube_pow2 == tex_pow2, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
7325 ok(vol_pow2 == tex_pow2, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
7327 for (i = 0; i < sizeof(pools) / sizeof(*pools); i++)
7329 for (levels = 0; levels <= 2; levels++)
7331 HRESULT expected;
7333 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, levels, 0, D3DFMT_X8R8G8B8,
7334 pools[i].pool, &texture, NULL);
7335 if (!tex_pow2)
7337 expected = D3D_OK;
7339 else if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7341 if (levels == 1)
7342 expected = D3D_OK;
7343 else
7344 expected = pools[i].hr;
7346 else
7348 expected = pools[i].hr;
7350 ok(hr == expected, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#x, expected %#x.\n",
7351 pools[i].pool_name, levels, hr, expected);
7353 if (SUCCEEDED(hr))
7354 IDirect3DTexture9_Release(texture);
7357 hr = IDirect3DDevice9_CreateCubeTexture(device, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
7358 &cube_texture, NULL);
7359 if (tex_pow2)
7361 ok(hr == pools[i].hr, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
7362 pools[i].pool_name, hr, pools[i].hr);
7364 else
7366 ok(SUCCEEDED(hr), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
7367 pools[i].pool_name, hr, D3D_OK);
7370 if (SUCCEEDED(hr))
7371 IDirect3DCubeTexture9_Release(cube_texture);
7373 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
7374 &volume_texture, NULL);
7375 if (tex_pow2)
7377 ok(hr == pools[i].hr, "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
7378 pools[i].pool_name, hr, pools[i].hr);
7380 else
7382 ok(SUCCEEDED(hr), "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
7383 pools[i].pool_name, hr, D3D_OK);
7386 if (SUCCEEDED(hr))
7387 IDirect3DVolumeTexture9_Release(volume_texture);
7390 done:
7391 if (device)
7393 refcount = IDirect3DDevice9_Release(device);
7394 ok(!refcount, "Device has %u references left.\n", refcount);
7396 IDirect3D9_Release(d3d9);
7397 DestroyWindow(window);
7401 static void test_vidmem_accounting(void)
7403 IDirect3DDevice9 *device;
7404 IDirect3D9 *d3d9;
7405 ULONG refcount;
7406 HWND window;
7407 HRESULT hr = D3D_OK;
7408 IDirect3DTexture9 *textures[20];
7409 unsigned int i;
7410 UINT vidmem_start, vidmem_end, diff;
7412 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7413 0, 0, 640, 480, 0, 0, 0, 0);
7414 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7415 ok(!!d3d9, "Failed to create a D3D object.\n");
7416 if (!(device = create_device(d3d9, window, NULL)))
7418 skip("Failed to create a D3D device, skipping tests.\n");
7419 IDirect3D9_Release(d3d9);
7420 DestroyWindow(window);
7421 return;
7424 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
7425 memset(textures, 0, sizeof(textures));
7426 for (i = 0; i < sizeof(textures) / sizeof(*textures) && SUCCEEDED(hr); i++)
7428 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
7429 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
7430 /* D3DERR_OUTOFVIDEOMEMORY is returned when the card runs out of video memory
7431 * E_FAIL is returned on address space or system memory exhaustion */
7432 ok(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY,
7433 "Failed to create texture, hr %#x.\n", hr);
7435 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
7437 ok(vidmem_start > vidmem_end, "Expected available texture memory to decrease during texture creation.\n");
7438 diff = vidmem_start - vidmem_end;
7439 ok(diff > 1024 * 1024 * 2 * i, "Expected a video memory difference of at least %u MB, got %u MB.\n",
7440 2 * i, diff / 1024 / 1024);
7442 for (i = 0; i < sizeof(textures) / sizeof(*textures); i++)
7444 if (textures[i])
7445 IDirect3DTexture9_Release(textures[i]);
7448 refcount = IDirect3DDevice9_Release(device);
7449 ok(!refcount, "Device has %u references left.\n", refcount);
7450 IDirect3D9_Release(d3d9);
7451 DestroyWindow(window);
7454 static void test_volume_locking(void)
7456 IDirect3DDevice9 *device;
7457 IDirect3D9 *d3d9;
7458 HWND window;
7459 HRESULT hr;
7460 IDirect3DVolumeTexture9 *texture;
7461 unsigned int i;
7462 D3DLOCKED_BOX locked_box;
7463 ULONG refcount;
7464 D3DCAPS9 caps;
7465 static const struct
7467 D3DPOOL pool;
7468 DWORD usage;
7469 HRESULT create_hr, lock_hr;
7471 tests[] =
7473 { D3DPOOL_DEFAULT, 0, D3D_OK, D3DERR_INVALIDCALL },
7474 { D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
7475 { D3DPOOL_SYSTEMMEM, 0, D3D_OK, D3D_OK },
7476 { D3DPOOL_SYSTEMMEM, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
7477 { D3DPOOL_MANAGED, 0, D3D_OK, D3D_OK },
7478 { D3DPOOL_MANAGED, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
7479 { D3DPOOL_SCRATCH, 0, D3D_OK, D3D_OK },
7480 { D3DPOOL_SCRATCH, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
7483 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7484 0, 0, 640, 480, 0, 0, 0, 0);
7485 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7486 ok(!!d3d9, "Failed to create a D3D object.\n");
7487 if (!(device = create_device(d3d9, window, NULL)))
7489 skip("Failed to create a D3D device, skipping tests.\n");
7490 IDirect3D9_Release(d3d9);
7491 DestroyWindow(window);
7492 return;
7495 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7496 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7497 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
7499 skip("Volume textures not supported, skipping test.\n");
7500 goto out;
7503 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
7505 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, tests[i].usage,
7506 D3DFMT_A8R8G8B8, tests[i].pool, &texture, NULL);
7507 ok(hr == tests[i].create_hr, "Creating volume texture pool=%u, usage=%#x returned %#x, expected %#x.\n",
7508 tests[i].pool, tests[i].usage, hr, tests[i].create_hr);
7509 if (FAILED(hr))
7510 continue;
7512 locked_box.pBits = (void *)0xdeadbeef;
7513 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7514 ok(hr == tests[i].lock_hr, "Lock returned %#x, expected %#x.\n", hr, tests[i].lock_hr);
7515 if (SUCCEEDED(hr))
7517 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7518 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7520 else
7522 ok(locked_box.pBits == NULL, "Failed lock set pBits = %p, expected NULL.\n", locked_box.pBits);
7524 IDirect3DVolumeTexture9_Release(texture);
7527 out:
7528 refcount = IDirect3DDevice9_Release(device);
7529 ok(!refcount, "Device has %u references left.\n", refcount);
7530 IDirect3D9_Release(d3d9);
7531 DestroyWindow(window);
7534 static void test_update_volumetexture(void)
7536 IDirect3DDevice9 *device;
7537 IDirect3D9 *d3d9;
7538 HWND window;
7539 HRESULT hr;
7540 IDirect3DVolumeTexture9 *src, *dst;
7541 unsigned int i;
7542 D3DLOCKED_BOX locked_box;
7543 ULONG refcount;
7544 D3DCAPS9 caps;
7545 static const struct
7547 D3DPOOL src_pool, dst_pool;
7548 HRESULT hr;
7550 tests[] =
7552 { D3DPOOL_DEFAULT, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7553 { D3DPOOL_MANAGED, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7554 { D3DPOOL_SYSTEMMEM, D3DPOOL_DEFAULT, D3D_OK },
7555 { D3DPOOL_SCRATCH, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7557 { D3DPOOL_DEFAULT, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7558 { D3DPOOL_MANAGED, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7559 { D3DPOOL_SYSTEMMEM, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7560 { D3DPOOL_SCRATCH, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7562 { D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7563 { D3DPOOL_MANAGED, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7564 { D3DPOOL_SYSTEMMEM, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7565 { D3DPOOL_SCRATCH, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7567 { D3DPOOL_DEFAULT, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7568 { D3DPOOL_MANAGED, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7569 { D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7570 { D3DPOOL_SCRATCH, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7572 static const struct
7574 UINT src_size, dst_size;
7575 UINT src_lvl, dst_lvl;
7576 D3DFORMAT src_fmt, dst_fmt;
7578 tests2[] =
7580 { 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7581 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7582 { 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7583 { 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7584 { 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7585 { 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different level count */
7586 { 4, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different size */
7587 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8 }, /* Different format */
7590 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7591 0, 0, 640, 480, 0, 0, 0, 0);
7592 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7593 ok(!!d3d9, "Failed to create a D3D object.\n");
7594 if (!(device = create_device(d3d9, window, NULL)))
7596 skip("Failed to create a D3D device, skipping tests.\n");
7597 IDirect3D9_Release(d3d9);
7598 DestroyWindow(window);
7599 return;
7602 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7603 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7604 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
7606 skip("Volume textures not supported, skipping test.\n");
7607 goto out;
7610 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
7612 DWORD src_usage = tests[i].src_pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0;
7613 DWORD dst_usage = tests[i].dst_pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0;
7615 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, src_usage,
7616 D3DFMT_A8R8G8B8, tests[i].src_pool, &src, NULL);
7617 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7618 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, dst_usage,
7619 D3DFMT_A8R8G8B8, tests[i].dst_pool, &dst, NULL);
7620 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7622 hr = IDirect3DVolumeTexture9_LockBox(src, 0, &locked_box, NULL, 0);
7623 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7624 *((DWORD *)locked_box.pBits) = 0x11223344;
7625 hr = IDirect3DVolumeTexture9_UnlockBox(src, 0);
7626 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7628 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
7629 ok(hr == tests[i].hr, "UpdateTexture returned %#x, expected %#x, src pool %x, dst pool %u.\n",
7630 hr, tests[i].hr, tests[i].src_pool, tests[i].dst_pool);
7632 if (SUCCEEDED(hr))
7634 DWORD content = *((DWORD *)locked_box.pBits);
7635 hr = IDirect3DVolumeTexture9_LockBox(dst, 0, &locked_box, NULL, 0);
7636 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7637 ok(content == 0x11223344, "Dest texture contained %#x, expected 0x11223344.\n", content);
7638 hr = IDirect3DVolumeTexture9_UnlockBox(dst, 0);
7639 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7641 IDirect3DVolumeTexture9_Release(src);
7642 IDirect3DVolumeTexture9_Release(dst);
7645 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
7647 skip("Mipmapped volume maps not supported.\n");
7648 goto out;
7651 for (i = 0; i < sizeof(tests2) / sizeof(*tests2); i++)
7653 hr = IDirect3DDevice9_CreateVolumeTexture(device,
7654 tests2[i].src_size, tests2[i].src_size, tests2[i].src_size,
7655 tests2[i].src_lvl, 0, tests2[i].src_fmt, D3DPOOL_SYSTEMMEM, &src, NULL);
7656 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x, case %u.\n", hr, i);
7657 hr = IDirect3DDevice9_CreateVolumeTexture(device,
7658 tests2[i].dst_size, tests2[i].dst_size, tests2[i].dst_size,
7659 tests2[i].dst_lvl, 0, tests2[i].dst_fmt, D3DPOOL_DEFAULT, &dst, NULL);
7660 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x, case %u.\n", hr, i);
7662 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
7663 if (FAILED(hr))
7664 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u.\n", hr, i);
7665 else
7666 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u.\n", hr, i);
7668 IDirect3DVolumeTexture9_Release(src);
7669 IDirect3DVolumeTexture9_Release(dst);
7672 /* As far as I can see, UpdateTexture on non-matching texture behaves like a memcpy. The raw data
7673 * stays the same in a format change, a 2x2x1 texture is copied into the first row of a 4x4x1 texture,
7674 * etc. I could not get it to segfault, but the nonexistent 5th pixel of a 2x2x1 texture is copied into
7675 * pixel 1x2x1 of a 4x4x1 texture, demonstrating a read beyond the texture's end. I suspect any bad
7676 * memory access is silently ignored by the runtime, in the kernel or on the GPU.
7678 * I'm not adding tests for this behavior until an application needs it. */
7680 out:
7681 refcount = IDirect3DDevice9_Release(device);
7682 ok(!refcount, "Device has %u references left.\n", refcount);
7683 IDirect3D9_Release(d3d9);
7684 DestroyWindow(window);
7687 static void test_create_rt_ds_fail(void)
7689 IDirect3DDevice9 *device;
7690 HWND window;
7691 HRESULT hr;
7692 ULONG refcount;
7693 IDirect3D9 *d3d9;
7694 IDirect3DSurface9 *surface;
7696 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7697 0, 0, 640, 480, 0, 0, 0, 0);
7698 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7699 ok(!!d3d9, "Failed to create a D3D object.\n");
7700 if (!(device = create_device(d3d9, window, NULL)))
7702 skip("Failed to create a D3D device, skipping tests.\n");
7703 IDirect3D9_Release(d3d9);
7704 DestroyWindow(window);
7705 return;
7708 /* Output pointer == NULL segfaults on Windows. */
7710 surface = (IDirect3DSurface9 *)0xdeadbeef;
7711 hr = IDirect3DDevice9_CreateRenderTarget(device, 4, 4, D3DFMT_D16,
7712 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
7713 ok(hr == D3DERR_INVALIDCALL, "Creating a D16 render target returned hr %#x.\n", hr);
7714 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
7715 if (SUCCEEDED(hr))
7716 IDirect3DSurface9_Release(surface);
7718 surface = (IDirect3DSurface9 *)0xdeadbeef;
7719 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 4, 4, D3DFMT_A8R8G8B8,
7720 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
7721 ok(hr == D3DERR_INVALIDCALL, "Creating a A8R8G8B8 depth stencil returned hr %#x.\n", hr);
7722 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
7723 if (SUCCEEDED(hr))
7724 IDirect3DSurface9_Release(surface);
7726 refcount = IDirect3DDevice9_Release(device);
7727 ok(!refcount, "Device has %u references left.\n", refcount);
7728 IDirect3D9_Release(d3d9);
7729 DestroyWindow(window);
7732 static void test_volume_blocks(void)
7734 IDirect3DDevice9 *device;
7735 IDirect3D9 *d3d9;
7736 UINT refcount;
7737 HWND window;
7738 HRESULT hr;
7739 D3DCAPS9 caps;
7740 IDirect3DVolumeTexture9 *texture;
7741 unsigned int w, h, d, i, j;
7742 static const struct
7744 D3DFORMAT fmt;
7745 const char *name;
7746 unsigned int block_width;
7747 unsigned int block_height;
7748 unsigned int block_depth;
7749 unsigned int block_size;
7750 BOOL broken;
7751 BOOL create_size_checked, core_fmt;
7753 formats[] =
7755 /* Scratch volumes enforce DXTn block locks, unlike their surface counterparts.
7756 * ATI2N and YUV blocks are not enforced on any tested card (r200, gtx 460). */
7757 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 1, 8, FALSE, TRUE, TRUE },
7758 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7759 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7760 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7761 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7762 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7763 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
7764 * which doesn't match the format spec. On newer Nvidia cards
7765 * it has the correct 4x4 block size */
7766 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, 1, 16, TRUE, FALSE, FALSE},
7767 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, 1, 4, TRUE, FALSE, TRUE },
7768 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, 1, 4, TRUE, FALSE, TRUE },
7770 static const struct
7772 D3DPOOL pool;
7773 const char *name;
7774 BOOL need_driver_support, need_runtime_support;
7776 create_tests[] =
7778 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
7779 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
7780 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE, FALSE},
7781 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
7783 static const struct
7785 unsigned int x, y, z, x2, y2, z2;
7787 offset_tests[] =
7789 {0, 0, 0, 8, 8, 8},
7790 {0, 0, 3, 8, 8, 8},
7791 {0, 4, 0, 8, 8, 8},
7792 {0, 4, 3, 8, 8, 8},
7793 {4, 0, 0, 8, 8, 8},
7794 {4, 0, 3, 8, 8, 8},
7795 {4, 4, 0, 8, 8, 8},
7796 {4, 4, 3, 8, 8, 8},
7798 D3DBOX box;
7799 D3DLOCKED_BOX locked_box;
7800 BYTE *base;
7801 INT expected_row_pitch, expected_slice_pitch;
7802 BOOL support, support_2d;
7803 BOOL pow2;
7804 unsigned int offset, expected_offset;
7806 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7807 0, 0, 640, 480, 0, 0, 0, 0);
7808 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7809 ok(!!d3d9, "Failed to create a D3D object.\n");
7810 if (!(device = create_device(d3d9, window, NULL)))
7812 skip("Failed to create a D3D device, skipping tests.\n");
7813 IDirect3D9_Release(d3d9);
7814 DestroyWindow(window);
7815 return;
7817 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7818 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7819 pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
7821 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
7823 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7824 0, D3DRTYPE_VOLUMETEXTURE, formats[i].fmt);
7825 support = SUCCEEDED(hr);
7826 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7827 0, D3DRTYPE_TEXTURE, formats[i].fmt);
7828 support_2d = SUCCEEDED(hr);
7830 /* Test creation restrictions */
7831 for (w = 1; w <= 8; w++)
7833 for (h = 1; h <= 8; h++)
7835 for (d = 1; d <= 8; d++)
7837 HRESULT expect_hr;
7838 BOOL size_is_pow2;
7839 BOOL block_aligned = TRUE;
7841 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
7842 block_aligned = FALSE;
7844 size_is_pow2 = !((w & (w - 1)) || (h & (h - 1)) || (d & (d - 1)));
7846 for (j = 0; j < sizeof(create_tests) / sizeof(*create_tests); j++)
7848 BOOL may_succeed = FALSE;
7849 BOOL todo = FALSE;
7851 if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !support)
7852 expect_hr = D3DERR_INVALIDCALL;
7853 else if (formats[i].create_size_checked && !block_aligned)
7854 expect_hr = D3DERR_INVALIDCALL;
7855 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
7856 expect_hr = D3DERR_INVALIDCALL;
7857 else if (create_tests[j].need_driver_support && !support)
7859 todo = support_2d;
7860 expect_hr = D3DERR_INVALIDCALL;
7862 else
7863 expect_hr = D3D_OK;
7865 texture = (IDirect3DVolumeTexture9 *)0xdeadbeef;
7866 hr = IDirect3DDevice9_CreateVolumeTexture(device, w, h, d, 1, 0,
7867 formats[i].fmt, create_tests[j].pool, &texture, NULL);
7869 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
7870 * does not support it. Accept scratch creation of extension formats on
7871 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
7872 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
7873 * support it. */
7874 if (!formats[i].core_fmt && !support && FAILED(expect_hr))
7875 may_succeed = TRUE;
7877 if (todo)
7879 todo_wine ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
7880 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
7881 hr, formats[i].name, create_tests[j].name, w, h, d);
7883 else
7885 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
7886 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
7887 hr, formats[i].name, create_tests[j].name, w, h, d);
7890 if (FAILED(hr))
7891 ok(texture == NULL, "Got texture ptr %p, expected NULL.\n", texture);
7892 else
7893 IDirect3DVolumeTexture9_Release(texture);
7899 if (!support && !formats[i].core_fmt)
7900 continue;
7902 hr = IDirect3DDevice9_CreateVolumeTexture(device, 24, 8, 8, 1, 0,
7903 formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
7904 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7906 /* Test lockrect offset */
7907 for (j = 0; j < sizeof(offset_tests) / sizeof(*offset_tests); j++)
7909 unsigned int bytes_per_pixel;
7910 bytes_per_pixel = formats[i].block_size / (formats[i].block_width * formats[i].block_height);
7912 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7913 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7915 base = locked_box.pBits;
7916 if (formats[i].broken)
7918 expected_row_pitch = bytes_per_pixel * 24;
7920 else
7922 expected_row_pitch = (24 /* tex width */ + formats[i].block_height - 1) / formats[i].block_width
7923 * formats[i].block_size;
7925 ok(locked_box.RowPitch == expected_row_pitch, "Got unexpected row pitch %d for format %s, expected %d.\n",
7926 locked_box.RowPitch, formats[i].name, expected_row_pitch);
7928 if (formats[i].broken)
7930 expected_slice_pitch = expected_row_pitch * 8;
7932 else
7934 expected_slice_pitch = (8 /* tex height */ + formats[i].block_depth - 1) / formats[i].block_height
7935 * expected_row_pitch;
7937 ok(locked_box.SlicePitch == expected_slice_pitch,
7938 "Got unexpected slice pitch %d for format %s, expected %d.\n",
7939 locked_box.SlicePitch, formats[i].name, expected_slice_pitch);
7941 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7942 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x, j %u.\n", hr, j);
7944 box.Left = offset_tests[j].x;
7945 box.Top = offset_tests[j].y;
7946 box.Front = offset_tests[j].z;
7947 box.Right = offset_tests[j].x2;
7948 box.Bottom = offset_tests[j].y2;
7949 box.Back = offset_tests[j].z2;
7950 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7951 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x, j %u.\n", hr, j);
7953 offset = (BYTE *)locked_box.pBits - base;
7954 if (formats[i].broken)
7956 expected_offset = box.Front * expected_slice_pitch
7957 + box.Top * expected_row_pitch
7958 + box.Left * bytes_per_pixel;
7960 else
7962 expected_offset = (box.Front / formats[i].block_depth) * expected_slice_pitch
7963 + (box.Top / formats[i].block_height) * expected_row_pitch
7964 + (box.Left / formats[i].block_width) * formats[i].block_size;
7966 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u, box start %ux%ux%u.\n",
7967 offset, formats[i].name, expected_offset, box.Left, box.Top, box.Front);
7969 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7970 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7973 /* Test partial block locks */
7974 box.Front = 0;
7975 box.Back = 1;
7976 if (formats[i].block_width > 1)
7978 box.Left = formats[i].block_width >> 1;
7979 box.Top = 0;
7980 box.Right = formats[i].block_width;
7981 box.Bottom = formats[i].block_height;
7982 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7983 ok(FAILED(hr) || broken(formats[i].broken),
7984 "Partial block lock succeeded, expected failure, format %s.\n",
7985 formats[i].name);
7986 if (SUCCEEDED(hr))
7988 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7989 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7992 box.Left = 0;
7993 box.Top = 0;
7994 box.Right = formats[i].block_width >> 1;
7995 box.Bottom = formats[i].block_height;
7996 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7997 ok(FAILED(hr) || broken(formats[i].broken),
7998 "Partial block lock succeeded, expected failure, format %s.\n",
7999 formats[i].name);
8000 if (SUCCEEDED(hr))
8002 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8003 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8007 if (formats[i].block_height > 1)
8009 box.Left = 0;
8010 box.Top = formats[i].block_height >> 1;
8011 box.Right = formats[i].block_width;
8012 box.Bottom = formats[i].block_height;
8013 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
8014 ok(FAILED(hr) || broken(formats[i].broken),
8015 "Partial block lock succeeded, expected failure, format %s.\n",
8016 formats[i].name);
8017 if (SUCCEEDED(hr))
8019 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8020 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8023 box.Left = 0;
8024 box.Top = 0;
8025 box.Right = formats[i].block_width;
8026 box.Bottom = formats[i].block_height >> 1;
8027 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
8028 ok(FAILED(hr) || broken(formats[i].broken),
8029 "Partial block lock succeeded, expected failure, format %s.\n",
8030 formats[i].name);
8031 if (SUCCEEDED(hr))
8033 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8034 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8038 /* Test full block lock */
8039 box.Left = 0;
8040 box.Top = 0;
8041 box.Right = formats[i].block_width;
8042 box.Bottom = formats[i].block_height;
8043 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
8044 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
8045 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8046 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8048 IDirect3DVolumeTexture9_Release(texture);
8050 /* Test mipmap locks. Don't do this with ATI2N, AMD warns that the runtime
8051 * does not allocate surfaces smaller than the blocksize properly. */
8052 if ((formats[i].block_width > 1 || formats[i].block_height > 1) && formats[i].core_fmt)
8054 hr = IDirect3DDevice9_CreateVolumeTexture(device, formats[i].block_width, formats[i].block_height,
8055 2, 2, 0, formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
8057 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, NULL, 0);
8058 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#x.\n", hr);
8059 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
8060 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8062 box.Left = box.Top = box.Front = 0;
8063 box.Right = formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1;
8064 box.Bottom = formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1;
8065 box.Back = 1;
8066 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
8067 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#x.\n", hr);
8068 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
8069 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8071 box.Right = formats[i].block_width;
8072 box.Bottom = formats[i].block_height;
8073 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
8074 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8075 if (SUCCEEDED(hr))
8076 IDirect3DVolumeTexture9_UnlockBox(texture, 1);
8078 IDirect3DVolumeTexture9_Release(texture);
8082 refcount = IDirect3DDevice9_Release(device);
8083 ok(!refcount, "Device has %u references left.\n", refcount);
8084 IDirect3D9_Release(d3d9);
8085 DestroyWindow(window);
8088 static void test_lockbox_invalid(void)
8090 static const struct
8092 D3DBOX box;
8093 HRESULT result;
8095 test_data[] =
8097 {{0, 0, 2, 2, 0, 1}, D3D_OK}, /* Valid */
8098 {{0, 0, 4, 4, 0, 1}, D3D_OK}, /* Valid */
8099 {{0, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* 0 height */
8100 {{0, 0, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* 0 width */
8101 {{0, 0, 4, 4, 1, 1}, D3DERR_INVALIDCALL}, /* 0 depth */
8102 {{4, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > right */
8103 {{0, 4, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* top > bottom */
8104 {{0, 0, 4, 4, 1, 0}, D3DERR_INVALIDCALL}, /* back > front */
8105 {{0, 0, 8, 4, 0, 1}, D3DERR_INVALIDCALL}, /* right > surface */
8106 {{0, 0, 4, 8, 0, 1}, D3DERR_INVALIDCALL}, /* bottom > surface */
8107 {{0, 0, 4, 4, 0, 3}, D3DERR_INVALIDCALL}, /* back > surface */
8108 {{8, 0, 16, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > surface */
8109 {{0, 8, 4, 16, 0, 1}, D3DERR_INVALIDCALL}, /* top > surface */
8110 {{0, 0, 4, 4, 2, 4}, D3DERR_INVALIDCALL}, /* top > surface */
8112 static const D3DBOX test_boxt_2 = {2, 2, 4, 4, 0, 1};
8113 IDirect3DVolumeTexture9 *texture = NULL;
8114 D3DLOCKED_BOX locked_box;
8115 IDirect3DDevice9 *device;
8116 IDirect3D9 *d3d;
8117 unsigned int i;
8118 ULONG refcount;
8119 HWND window;
8120 BYTE *base;
8121 HRESULT hr;
8123 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8124 0, 0, 640, 480, 0, 0, 0, 0);
8125 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8126 ok(!!d3d, "Failed to create a D3D object.\n");
8127 if (!(device = create_device(d3d, window, NULL)))
8129 skip("Failed to create a D3D device, skipping tests.\n");
8130 IDirect3D9_Release(d3d);
8131 DestroyWindow(window);
8132 return;
8135 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0,
8136 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
8137 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
8138 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
8139 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
8140 base = locked_box.pBits;
8141 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8142 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8144 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
8146 unsigned int offset, expected_offset;
8147 const D3DBOX *box = &test_data[i].box;
8149 locked_box.pBits = (BYTE *)0xdeadbeef;
8150 locked_box.RowPitch = 0xdeadbeef;
8151 locked_box.SlicePitch = 0xdeadbeef;
8153 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, box, 0);
8154 /* Unlike surfaces, volumes properly check the box even in Windows XP */
8155 ok(hr == test_data[i].result,
8156 "Got unexpected hr %#x with box [%u, %u, %u]->[%u, %u, %u], expected %#x.\n",
8157 hr, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back,
8158 test_data[i].result);
8159 if (FAILED(hr))
8160 continue;
8162 offset = (BYTE *)locked_box.pBits - base;
8163 expected_offset = box->Front * locked_box.SlicePitch + box->Top * locked_box.RowPitch + box->Left * 4;
8164 ok(offset == expected_offset,
8165 "Got unexpected offset %u (expected %u) for rect [%u, %u, %u]->[%u, %u, %u].\n",
8166 offset, expected_offset, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back);
8168 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8169 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8172 /* locked_box = NULL throws an exception on Windows */
8173 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
8174 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
8175 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
8176 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8177 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8178 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8179 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8180 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8182 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
8183 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
8184 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
8185 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
8186 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
8187 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
8188 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
8189 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
8190 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_boxt_2, 0);
8191 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
8192 hr, test_boxt_2.Left, test_boxt_2.Top, test_boxt_2.Front,
8193 test_boxt_2.Right, test_boxt_2.Bottom, test_boxt_2.Back);
8194 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
8195 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
8197 IDirect3DVolumeTexture9_Release(texture);
8198 refcount = IDirect3DDevice9_Release(device);
8199 ok(!refcount, "Device has %u references left.\n", refcount);
8200 IDirect3D9_Release(d3d);
8201 DestroyWindow(window);
8204 static void test_shared_handle(void)
8206 IDirect3DDevice9 *device;
8207 IDirect3D9 *d3d;
8208 ULONG refcount;
8209 HWND window;
8210 HRESULT hr;
8211 /* Native d3d9ex refuses to create a shared texture if the texture pointer
8212 * is not initialized to NULL. Make sure this doesn't cause issues here. */
8213 IDirect3DTexture9 *texture = NULL;
8214 IDirect3DSurface9 *surface = NULL;
8215 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
8216 IDirect3DIndexBuffer9 *index_buffer = NULL;
8217 HANDLE handle = NULL;
8218 void *mem;
8219 D3DCAPS9 caps;
8221 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8222 0, 0, 640, 480, 0, 0, 0, 0);
8223 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8224 ok(!!d3d, "Failed to create a D3D object.\n");
8225 if (!(device = create_device(d3d, window, NULL)))
8227 skip("Failed to create a D3D device, skipping tests.\n");
8228 IDirect3D9_Release(d3d);
8229 DestroyWindow(window);
8230 return;
8233 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8234 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8235 mem = HeapAlloc(GetProcessHeap(), 0, 128 * 128 * 4);
8237 /* Windows XP returns E_NOTIMPL, Windows 7 returns INVALIDCALL, except for
8238 * CreateVertexBuffer, where it returns NOTAVAILABLE. */
8239 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
8240 D3DPOOL_DEFAULT, &texture, &handle);
8241 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8242 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
8243 D3DPOOL_SYSTEMMEM, &texture, &mem);
8244 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8246 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
8247 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, &handle);
8248 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8249 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
8250 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, &mem);
8251 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8253 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
8254 &vertex_buffer, &handle);
8255 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8256 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
8257 &vertex_buffer, &mem);
8258 ok(hr == E_NOTIMPL || broken(hr == D3DERR_NOTAVAILABLE), "Got unexpected hr %#x.\n", hr);
8260 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
8261 &index_buffer, &handle);
8262 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8263 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
8264 &index_buffer, &mem);
8265 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8267 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
8269 IDirect3DCubeTexture9 *cube_texture = NULL;
8270 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
8271 D3DPOOL_DEFAULT, &cube_texture, &handle);
8272 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8273 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
8274 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
8275 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8278 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
8280 IDirect3DVolumeTexture9 *volume_texture = NULL;
8281 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
8282 D3DPOOL_DEFAULT, &volume_texture, &handle);
8283 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8284 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
8285 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
8286 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8289 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8290 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
8291 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8293 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24X8,
8294 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
8295 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
8297 HeapFree(GetProcessHeap(), 0, mem);
8298 refcount = IDirect3DDevice9_Release(device);
8299 ok(!refcount, "Device has %u references left.\n", refcount);
8300 IDirect3D9_Release(d3d);
8301 DestroyWindow(window);
8304 static void test_pixel_format(void)
8306 HWND hwnd, hwnd2 = NULL;
8307 HDC hdc, hdc2 = NULL;
8308 HMODULE gl = NULL;
8309 int format, test_format;
8310 PIXELFORMATDESCRIPTOR pfd;
8311 IDirect3D9 *d3d9 = NULL;
8312 IDirect3DDevice9 *device = NULL;
8313 HRESULT hr;
8314 static const float point[3] = {0.0, 0.0, 0.0};
8316 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8317 100, 100, 160, 160, NULL, NULL, NULL, NULL);
8318 if (!hwnd)
8320 skip("Failed to create window\n");
8321 return;
8324 hwnd2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
8325 100, 100, 160, 160, NULL, NULL, NULL, NULL);
8327 hdc = GetDC(hwnd);
8328 if (!hdc)
8330 skip("Failed to get DC\n");
8331 goto cleanup;
8334 if (hwnd2)
8335 hdc2 = GetDC(hwnd2);
8337 gl = LoadLibraryA("opengl32.dll");
8338 ok(!!gl, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
8340 format = GetPixelFormat(hdc);
8341 ok(format == 0, "new window has pixel format %d\n", format);
8343 ZeroMemory(&pfd, sizeof(pfd));
8344 pfd.nSize = sizeof(pfd);
8345 pfd.nVersion = 1;
8346 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
8347 pfd.iPixelType = PFD_TYPE_RGBA;
8348 pfd.iLayerType = PFD_MAIN_PLANE;
8349 format = ChoosePixelFormat(hdc, &pfd);
8350 if (format <= 0)
8352 skip("no pixel format available\n");
8353 goto cleanup;
8356 if (!SetPixelFormat(hdc, format, &pfd) || GetPixelFormat(hdc) != format)
8358 skip("failed to set pixel format\n");
8359 goto cleanup;
8362 if (!hdc2 || !SetPixelFormat(hdc2, format, &pfd) || GetPixelFormat(hdc2) != format)
8364 skip("failed to set pixel format on second window\n");
8365 if (hdc2)
8367 ReleaseDC(hwnd2, hdc2);
8368 hdc2 = NULL;
8372 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8373 ok(!!d3d9, "Failed to create a D3D object.\n");
8375 test_format = GetPixelFormat(hdc);
8376 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8378 if (!(device = create_device(d3d9, hwnd, NULL)))
8380 skip("Failed to create device\n");
8381 goto cleanup;
8384 test_format = GetPixelFormat(hdc);
8385 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8387 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8388 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8390 test_format = GetPixelFormat(hdc);
8391 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8393 hr = IDirect3DDevice9_BeginScene(device);
8394 ok(SUCCEEDED(hr), "BeginScene failed %#x\n", hr);
8396 test_format = GetPixelFormat(hdc);
8397 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
8400 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8402 test_format = GetPixelFormat(hdc);
8403 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8405 hr = IDirect3DDevice9_EndScene(device);
8406 ok(SUCCEEDED(hr), "EndScene failed %#x\n", hr);
8408 test_format = GetPixelFormat(hdc);
8409 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8411 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8412 ok(SUCCEEDED(hr), "Present failed %#x\n", hr);
8414 test_format = GetPixelFormat(hdc);
8415 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8417 if (hdc2)
8419 hr = IDirect3DDevice9_Present(device, NULL, NULL, hwnd2, NULL);
8420 ok(SUCCEEDED(hr), "Present failed %#x\n", hr);
8422 test_format = GetPixelFormat(hdc);
8423 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8425 test_format = GetPixelFormat(hdc2);
8426 ok(test_format == format, "second window has pixel format %d, expected %d\n", test_format, format);
8429 cleanup:
8430 if (device)
8432 UINT refcount = IDirect3DDevice9_Release(device);
8433 ok(!refcount, "Device has %u references left.\n", refcount);
8435 if (d3d9) IDirect3D9_Release(d3d9);
8436 if (gl) FreeLibrary(gl);
8437 if (hdc) ReleaseDC(hwnd, hdc);
8438 if (hdc2) ReleaseDC(hwnd2, hdc2);
8439 if (hwnd) DestroyWindow(hwnd);
8440 if (hwnd2) DestroyWindow(hwnd2);
8443 static void test_begin_end_state_block(void)
8445 IDirect3DStateBlock9 *stateblock;
8446 IDirect3DDevice9 *device;
8447 IDirect3D9 *d3d;
8448 ULONG refcount;
8449 HWND window;
8450 HRESULT hr;
8452 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8453 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8454 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8455 ok(!!d3d, "Failed to create a D3D object.\n");
8456 if (!(device = create_device(d3d, window, NULL)))
8458 skip("Failed to create a D3D device, skipping tests.\n");
8459 IDirect3D9_Release(d3d);
8460 DestroyWindow(window);
8461 return;
8464 /* Should succeed. */
8465 hr = IDirect3DDevice9_BeginStateBlock(device);
8466 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
8468 /* Calling BeginStateBlock() while recording should return
8469 * D3DERR_INVALIDCALL. */
8470 hr = IDirect3DDevice9_BeginStateBlock(device);
8471 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8473 /* Should succeed. */
8474 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
8475 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8476 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
8477 ok(!!stateblock && stateblock != (IDirect3DStateBlock9 *)0xdeadbeef,
8478 "Got unexpected stateblock %p.\n", stateblock);
8479 IDirect3DStateBlock9_Release(stateblock);
8481 /* Calling EndStateBlock() while not recording should return
8482 * D3DERR_INVALIDCALL. stateblock should not be touched. */
8483 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
8484 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8485 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8486 ok(stateblock == (IDirect3DStateBlock9 *)0xdeadbeef,
8487 "Got unexpected stateblock %p.\n", stateblock);
8489 refcount = IDirect3DDevice9_Release(device);
8490 ok(!refcount, "Device has %u references left.\n", refcount);
8491 IDirect3D9_Release(d3d);
8492 DestroyWindow(window);
8495 static void test_shader_constant_apply(void)
8497 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
8498 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
8499 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
8500 IDirect3DStateBlock9 *stateblock;
8501 DWORD vs_version, ps_version;
8502 IDirect3DDevice9 *device;
8503 IDirect3D9 *d3d;
8504 ULONG refcount;
8505 D3DCAPS9 caps;
8506 float ret[4];
8507 HWND window;
8508 HRESULT hr;
8510 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8511 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8512 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8513 ok(!!d3d, "Failed to create a D3D object.\n");
8514 if (!(device = create_device(d3d, window, NULL)))
8516 skip("Failed to create a D3D device, skipping tests.\n");
8517 IDirect3D9_Release(d3d);
8518 DestroyWindow(window);
8519 return;
8522 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8523 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8524 vs_version = caps.VertexShaderVersion & 0xffff;
8525 ps_version = caps.PixelShaderVersion & 0xffff;
8527 if (vs_version)
8529 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
8530 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8531 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
8532 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8534 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8535 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8536 ok(!memcmp(ret, initial, sizeof(initial)),
8537 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8538 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8539 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8540 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8541 ok(!memcmp(ret, initial, sizeof(initial)),
8542 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8543 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8545 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
8546 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8548 if (ps_version)
8550 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
8551 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8552 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
8553 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8555 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8556 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8557 ok(!memcmp(ret, initial, sizeof(initial)),
8558 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8559 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8560 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8561 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8562 ok(!memcmp(ret, initial, sizeof(initial)),
8563 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8564 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8566 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
8567 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8570 hr = IDirect3DDevice9_BeginStateBlock(device);
8571 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
8573 if (vs_version)
8575 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
8576 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8578 if (ps_version)
8580 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
8581 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8584 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8585 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
8587 if (vs_version)
8589 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8590 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8591 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8592 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8593 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8594 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8595 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8596 ok(!memcmp(ret, initial, sizeof(initial)),
8597 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8598 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8600 if (ps_version)
8602 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8603 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8604 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8605 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8606 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8607 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8608 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8609 ok(!memcmp(ret, initial, sizeof(initial)),
8610 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8611 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8614 /* Apply doesn't overwrite constants that aren't explicitly set on the
8615 * source stateblock. */
8616 hr = IDirect3DStateBlock9_Apply(stateblock);
8617 ok(SUCCEEDED(hr), "Failed to apply stateblock, hr %#x.\n", hr);
8619 if (vs_version)
8621 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8622 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8623 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8624 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8625 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8626 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8627 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8628 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8629 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8630 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8632 if (ps_version)
8634 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8635 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8636 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8637 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8638 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8639 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8640 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8641 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8642 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8643 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8646 IDirect3DStateBlock9_Release(stateblock);
8647 refcount = IDirect3DDevice9_Release(device);
8648 ok(!refcount, "Device has %u references left.\n", refcount);
8649 IDirect3D9_Release(d3d);
8650 DestroyWindow(window);
8653 static void test_vdecl_apply(void)
8655 IDirect3DVertexDeclaration9 *declaration, *declaration1, *declaration2;
8656 IDirect3DStateBlock9 *stateblock;
8657 IDirect3DDevice9 *device;
8658 IDirect3D9 *d3d;
8659 ULONG refcount;
8660 HWND window;
8661 HRESULT hr;
8663 static const D3DVERTEXELEMENT9 decl1[] =
8665 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8666 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8667 D3DDECL_END(),
8670 static const D3DVERTEXELEMENT9 decl2[] =
8672 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8673 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8674 {0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
8675 D3DDECL_END(),
8678 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8679 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8680 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8681 ok(!!d3d, "Failed to create a D3D object.\n");
8682 if (!(device = create_device(d3d, window, NULL)))
8684 skip("Failed to create a D3D device, skipping tests.\n");
8685 IDirect3D9_Release(d3d);
8686 DestroyWindow(window);
8687 return;
8690 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl1, &declaration1);
8691 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
8693 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl2, &declaration2);
8694 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
8696 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8697 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8698 hr = IDirect3DDevice9_BeginStateBlock(device);
8699 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#x.\n", hr);
8700 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
8701 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8702 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8703 ok(SUCCEEDED(hr), "EndStateBlock failed, hr %#x.\n", hr);
8704 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8705 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8706 hr = IDirect3DStateBlock9_Apply(stateblock);
8707 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8708 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8709 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8710 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
8711 declaration, declaration1);
8712 IDirect3DVertexDeclaration9_Release(declaration);
8714 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8715 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8716 hr = IDirect3DStateBlock9_Capture(stateblock);
8717 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8718 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8719 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8720 hr = IDirect3DStateBlock9_Apply(stateblock);
8721 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8722 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8723 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8724 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8725 declaration, declaration2);
8726 IDirect3DVertexDeclaration9_Release(declaration);
8728 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8729 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8730 hr = IDirect3DStateBlock9_Capture(stateblock);
8731 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8732 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8733 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8734 hr = IDirect3DStateBlock9_Apply(stateblock);
8735 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8736 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8737 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8738 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8739 declaration, declaration2);
8740 IDirect3DVertexDeclaration9_Release(declaration);
8742 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8743 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8744 hr = IDirect3DStateBlock9_Capture(stateblock);
8745 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8746 hr = IDirect3DStateBlock9_Apply(stateblock);
8747 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8748 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8749 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8750 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
8752 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8753 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8754 hr = IDirect3DStateBlock9_Capture(stateblock);
8755 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8756 hr = IDirect3DStateBlock9_Apply(stateblock);
8757 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8758 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8759 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8760 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8761 declaration, declaration2);
8762 IDirect3DVertexDeclaration9_Release(declaration);
8764 IDirect3DStateBlock9_Release(stateblock);
8765 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
8766 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8767 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &stateblock);
8768 ok(SUCCEEDED(hr), "CreateStateBlock failed, hr %#x.\n", hr);
8769 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8770 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8771 hr = IDirect3DStateBlock9_Apply(stateblock);
8772 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8773 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8774 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8775 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
8776 declaration, declaration1);
8777 IDirect3DVertexDeclaration9_Release(declaration);
8779 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8780 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8781 hr = IDirect3DStateBlock9_Capture(stateblock);
8782 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8783 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8784 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8785 hr = IDirect3DStateBlock9_Apply(stateblock);
8786 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8787 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8788 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8789 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8790 declaration, declaration2);
8791 IDirect3DVertexDeclaration9_Release(declaration);
8793 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8794 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8795 hr = IDirect3DStateBlock9_Capture(stateblock);
8796 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8797 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8798 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8799 hr = IDirect3DStateBlock9_Apply(stateblock);
8800 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8801 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8802 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8803 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8804 declaration, declaration2);
8805 IDirect3DVertexDeclaration9_Release(declaration);
8807 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8808 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8809 hr = IDirect3DStateBlock9_Capture(stateblock);
8810 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8811 hr = IDirect3DStateBlock9_Apply(stateblock);
8812 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8813 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8814 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8815 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
8817 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8818 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8819 hr = IDirect3DStateBlock9_Capture(stateblock);
8820 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8821 hr = IDirect3DStateBlock9_Apply(stateblock);
8822 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8823 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8824 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8825 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8826 declaration, declaration2);
8827 IDirect3DVertexDeclaration9_Release(declaration);
8829 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8830 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8831 IDirect3DVertexDeclaration9_Release(declaration1);
8832 IDirect3DVertexDeclaration9_Release(declaration2);
8833 IDirect3DStateBlock9_Release(stateblock);
8834 refcount = IDirect3DDevice9_Release(device);
8835 ok(!refcount, "Device has %u references left.\n", refcount);
8836 IDirect3D9_Release(d3d);
8837 DestroyWindow(window);
8840 static void test_resource_type(void)
8842 IDirect3DDevice9 *device;
8843 IDirect3DSurface9 *surface;
8844 IDirect3DTexture9 *texture;
8845 IDirect3DCubeTexture9 *cube_texture;
8846 IDirect3DVolume9 *volume;
8847 IDirect3DVolumeTexture9 *volume_texture;
8848 D3DSURFACE_DESC surface_desc;
8849 D3DVOLUME_DESC volume_desc;
8850 D3DRESOURCETYPE type;
8851 IDirect3D9 *d3d;
8852 ULONG refcount;
8853 HWND window;
8854 HRESULT hr;
8856 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8857 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8858 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8859 ok(!!d3d, "Failed to create a D3D object.\n");
8860 if (!(device = create_device(d3d, window, NULL)))
8862 skip("Failed to create a D3D device, skipping tests.\n");
8863 IDirect3D9_Release(d3d);
8864 DestroyWindow(window);
8865 return;
8868 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_X8R8G8B8,
8869 D3DPOOL_SYSTEMMEM, &surface, NULL);
8870 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8871 type = IDirect3DSurface9_GetType(surface);
8872 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8873 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8874 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8875 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8876 surface_desc.Type);
8877 IDirect3DSurface9_Release(surface);
8879 hr = IDirect3DDevice9_CreateTexture(device, 2, 8, 4, 0, D3DFMT_X8R8G8B8,
8880 D3DPOOL_SYSTEMMEM, &texture, NULL);
8881 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8882 type = IDirect3DTexture9_GetType(texture);
8883 ok(type == D3DRTYPE_TEXTURE, "Expected type D3DRTYPE_TEXTURE, got %u.\n", type);
8885 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8886 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8887 /* The following code crashes, for the sake of completeness:
8888 * type = texture->lpVtbl->GetType((IDirect3DTexture9 *)surface);
8889 * ok(type == D3DRTYPE_PONIES, "Expected type D3DRTYPE_PONIES, got %u.\n", type);
8891 * So applications will not depend on getting the "right" resource type - whatever it
8892 * may be - from the "wrong" vtable. */
8893 type = IDirect3DSurface9_GetType(surface);
8894 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8895 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8896 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8897 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8898 surface_desc.Type);
8899 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
8900 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
8901 hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &surface_desc);
8902 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8903 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8904 surface_desc.Type);
8905 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
8906 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
8907 IDirect3DSurface9_Release(surface);
8909 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
8910 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8911 type = IDirect3DSurface9_GetType(surface);
8912 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8913 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8914 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8915 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8916 surface_desc.Type);
8917 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
8918 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
8919 hr = IDirect3DTexture9_GetLevelDesc(texture, 2, &surface_desc);
8920 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8921 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8922 surface_desc.Type);
8923 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
8924 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
8925 IDirect3DSurface9_Release(surface);
8926 IDirect3DTexture9_Release(texture);
8928 hr = IDirect3DDevice9_CreateCubeTexture(device, 1, 1, 0, D3DFMT_X8R8G8B8,
8929 D3DPOOL_SYSTEMMEM, &cube_texture, NULL);
8930 ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#x.\n", hr);
8931 type = IDirect3DCubeTexture9_GetType(cube_texture);
8932 ok(type == D3DRTYPE_CUBETEXTURE, "Expected type D3DRTYPE_CUBETEXTURE, got %u.\n", type);
8934 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture,
8935 D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface);
8936 ok(SUCCEEDED(hr), "Failed to get cube map surface, hr %#x.\n", hr);
8937 type = IDirect3DSurface9_GetType(surface);
8938 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8939 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8940 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8941 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8942 surface_desc.Type);
8943 hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
8944 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8945 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8946 surface_desc.Type);
8947 IDirect3DSurface9_Release(surface);
8948 IDirect3DCubeTexture9_Release(cube_texture);
8950 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 4, 8, 4, 0, D3DFMT_X8R8G8B8,
8951 D3DPOOL_SYSTEMMEM, &volume_texture, NULL);
8952 type = IDirect3DVolumeTexture9_GetType(volume_texture);
8953 ok(type == D3DRTYPE_VOLUMETEXTURE, "Expected type D3DRTYPE_VOLUMETEXTURE, got %u.\n", type);
8955 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
8956 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
8957 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
8958 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
8959 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#x.\n", hr);
8960 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8961 volume_desc.Type);
8962 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
8963 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
8964 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
8965 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
8966 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8967 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8968 volume_desc.Type);
8969 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
8970 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
8971 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
8972 IDirect3DVolume9_Release(volume);
8974 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 2, &volume);
8975 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
8976 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
8977 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
8978 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#x.\n", hr);
8979 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8980 volume_desc.Type);
8981 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
8982 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
8983 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
8984 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 2, &volume_desc);
8985 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8986 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8987 volume_desc.Type);
8988 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
8989 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
8990 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
8991 IDirect3DVolume9_Release(volume);
8992 IDirect3DVolumeTexture9_Release(volume_texture);
8994 refcount = IDirect3DDevice9_Release(device);
8995 ok(!refcount, "Device has %u references left.\n", refcount);
8996 IDirect3D9_Release(d3d);
8997 DestroyWindow(window);
9000 static void test_mipmap_lock(void)
9002 IDirect3DDevice9 *device;
9003 IDirect3DSurface9 *surface, *surface2, *surface_dst, *surface_dst2;
9004 IDirect3DTexture9 *texture, *texture_dst;
9005 IDirect3D9 *d3d;
9006 ULONG refcount;
9007 HWND window;
9008 HRESULT hr;
9009 D3DLOCKED_RECT locked_rect;
9011 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9012 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9013 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9014 ok(!!d3d, "Failed to create a D3D object.\n");
9015 if (!(device = create_device(d3d, window, NULL)))
9017 skip("Failed to create a D3D device, skipping tests.\n");
9018 IDirect3D9_Release(d3d);
9019 DestroyWindow(window);
9020 return;
9023 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
9024 D3DPOOL_DEFAULT, &texture_dst, NULL);
9025 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
9026 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 0, &surface_dst);
9027 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9028 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 1, &surface_dst2);
9029 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9031 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
9032 D3DPOOL_SYSTEMMEM, &texture, NULL);
9033 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
9034 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9035 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9036 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
9037 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9039 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
9040 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
9041 hr = IDirect3DSurface9_LockRect(surface2, &locked_rect, NULL, 0);
9042 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
9043 hr = IDirect3DSurface9_UnlockRect(surface);
9044 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
9046 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, surface_dst, NULL);
9047 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
9048 hr = IDirect3DDevice9_UpdateSurface(device, surface2, NULL, surface_dst2, NULL);
9049 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9051 /* Apparently there's no validation on the container. */
9052 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
9053 (IDirect3DBaseTexture9 *)texture_dst);
9054 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
9056 hr = IDirect3DSurface9_UnlockRect(surface2);
9057 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
9059 IDirect3DSurface9_Release(surface_dst2);
9060 IDirect3DSurface9_Release(surface_dst);
9061 IDirect3DSurface9_Release(surface2);
9062 IDirect3DSurface9_Release(surface);
9063 IDirect3DTexture9_Release(texture_dst);
9064 IDirect3DTexture9_Release(texture);
9066 refcount = IDirect3DDevice9_Release(device);
9067 ok(!refcount, "Device has %u references left.\n", refcount);
9068 IDirect3D9_Release(d3d);
9069 DestroyWindow(window);
9072 static void test_writeonly_resource(void)
9074 IDirect3D9 *d3d;
9075 IDirect3DDevice9 *device;
9076 IDirect3DVertexBuffer9 *buffer;
9077 ULONG refcount;
9078 HWND window;
9079 HRESULT hr;
9080 void *ptr;
9081 static const struct
9083 struct vec3 pos;
9085 quad[] =
9087 {{-1.0f, -1.0f, 0.0f}},
9088 {{-1.0f, 1.0f, 0.0f}},
9089 {{ 1.0f, -1.0f, 0.0f}},
9090 {{ 1.0f, 1.0f, 0.0f}}
9093 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9094 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9095 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9096 ok(!!d3d, "Failed to create a D3D object.\n");
9097 if (!(device = create_device(d3d, window, NULL)))
9099 skip("Failed to create a D3D device, skipping tests.\n");
9100 IDirect3D9_Release(d3d);
9101 DestroyWindow(window);
9102 return;
9105 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad),
9106 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
9107 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
9109 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
9110 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9111 memcpy(ptr, quad, sizeof(quad));
9112 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9113 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9114 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quad));
9115 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9116 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9117 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9119 hr = IDirect3DDevice9_BeginScene(device);
9120 ok(SUCCEEDED(hr), "Failed to begin scene %#x\n", hr);
9121 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9122 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9123 hr = IDirect3DDevice9_EndScene(device);
9124 ok(SUCCEEDED(hr), "Failed to end scene %#x\n", hr);
9126 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, 0);
9127 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9128 ok(!memcmp(ptr, quad, sizeof(quad)), "Got unexpected vertex buffer data.\n");
9129 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9130 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9132 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &ptr, D3DLOCK_READONLY);
9133 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9134 ok(!memcmp(ptr, quad, sizeof(quad)), "Got unexpected vertex buffer data.\n");
9135 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9136 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9138 refcount = IDirect3DVertexBuffer9_Release(buffer);
9139 ok(!refcount, "Vertex buffer has %u references left.\n", refcount);
9140 refcount = IDirect3DDevice9_Release(device);
9141 ok(!refcount, "Device has %u references left.\n", refcount);
9142 IDirect3D9_Release(d3d);
9143 DestroyWindow(window);
9146 static void test_lost_device(void)
9148 struct device_desc device_desc;
9149 IDirect3DDevice9 *device;
9150 IDirect3D9 *d3d;
9151 ULONG refcount;
9152 HWND window;
9153 HRESULT hr;
9154 BOOL ret;
9156 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9157 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9158 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9159 ok(!!d3d, "Failed to create a D3D object.\n");
9160 device_desc.device_window = window;
9161 device_desc.width = screen_width;
9162 device_desc.height = screen_height;
9163 device_desc.windowed = FALSE;
9164 if (!(device = create_device(d3d, window, &device_desc)))
9166 skip("Failed to create a D3D device, skipping tests.\n");
9167 goto done;
9170 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9171 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9172 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9173 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9175 ret = SetForegroundWindow(GetDesktopWindow());
9176 ok(ret, "Failed to set foreground window.\n");
9177 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9178 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
9179 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9180 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
9182 ret = ShowWindow(window, SW_RESTORE);
9183 ok(ret, "Failed to restore window.\n");
9184 ret = SetForegroundWindow(window);
9185 ok(ret, "Failed to set foreground window.\n");
9186 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9187 ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
9188 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9189 ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
9191 hr = reset_device(device, window, FALSE);
9192 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9193 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9194 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9195 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9196 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9198 hr = reset_device(device, window, TRUE);
9199 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9200 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9201 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9202 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9203 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9205 ret = SetForegroundWindow(GetDesktopWindow());
9206 ok(ret, "Failed to set foreground window.\n");
9207 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9208 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9209 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9210 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9212 ret = ShowWindow(window, SW_RESTORE);
9213 ok(ret, "Failed to restore window.\n");
9214 ret = SetForegroundWindow(window);
9215 ok(ret, "Failed to set foreground window.\n");
9216 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9217 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9218 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9219 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9221 hr = reset_device(device, window, FALSE);
9222 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9223 hr = IDirect3DDevice9_TestCooperativeLevel(device);
9224 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9225 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9226 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
9228 refcount = IDirect3DDevice9_Release(device);
9229 ok(!refcount, "Device has %u references left.\n", refcount);
9230 done:
9231 IDirect3D9_Release(d3d);
9232 DestroyWindow(window);
9235 static void test_resource_priority(void)
9237 IDirect3DDevice9 *device;
9238 IDirect3DSurface9 *surface;
9239 IDirect3DTexture9 *texture;
9240 IDirect3DVertexBuffer9 *buffer;
9241 IDirect3D9 *d3d;
9242 ULONG refcount;
9243 HWND window;
9244 HRESULT hr;
9245 static const struct
9247 D3DPOOL pool;
9248 const char *name;
9249 BOOL can_set_priority;
9251 test_data[] =
9253 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
9254 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", FALSE},
9255 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
9256 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE}
9258 unsigned int i;
9259 DWORD priority;
9261 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
9262 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9263 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9264 ok(!!d3d, "Failed to create a D3D object.\n");
9265 if (!(device = create_device(d3d, window, NULL)))
9267 skip("Failed to create a D3D device, skipping tests.\n");
9268 IDirect3D9_Release(d3d);
9269 DestroyWindow(window);
9270 return;
9273 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); i++)
9275 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 0, 0, D3DFMT_X8R8G8B8,
9276 test_data[i].pool, &texture, NULL);
9277 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, pool %s.\n", hr, test_data[i].name);
9278 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9279 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
9281 priority = IDirect3DTexture9_GetPriority(texture);
9282 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9283 priority = IDirect3DTexture9_SetPriority(texture, 1);
9284 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9285 priority = IDirect3DTexture9_GetPriority(texture);
9286 if (test_data[i].can_set_priority)
9288 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9289 priority = IDirect3DTexture9_SetPriority(texture, 2);
9290 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9292 else
9293 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9295 priority = IDirect3DSurface9_GetPriority(surface);
9296 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9297 priority = IDirect3DSurface9_SetPriority(surface, 1);
9298 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9299 priority = IDirect3DSurface9_GetPriority(surface);
9300 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9302 IDirect3DSurface9_Release(surface);
9303 IDirect3DTexture9_Release(texture);
9305 if (test_data[i].pool != D3DPOOL_MANAGED)
9307 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16, D3DFMT_X8R8G8B8,
9308 test_data[i].pool, &surface, NULL);
9309 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, pool %s.\n", hr, test_data[i].name);
9311 priority = IDirect3DSurface9_GetPriority(surface);
9312 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9313 priority = IDirect3DSurface9_SetPriority(surface, 1);
9314 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9315 priority = IDirect3DSurface9_GetPriority(surface);
9316 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9318 IDirect3DSurface9_Release(surface);
9321 if (test_data[i].pool != D3DPOOL_SCRATCH)
9323 hr = IDirect3DDevice9_CreateVertexBuffer(device, 256, 0, 0,
9324 test_data[i].pool, &buffer, NULL);
9325 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x, pool %s.\n", hr, test_data[i].name);
9327 priority = IDirect3DVertexBuffer9_GetPriority(buffer);
9328 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9329 priority = IDirect3DVertexBuffer9_SetPriority(buffer, 1);
9330 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9331 priority = IDirect3DVertexBuffer9_GetPriority(buffer);
9332 if (test_data[i].can_set_priority)
9334 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9335 priority = IDirect3DVertexBuffer9_SetPriority(buffer, 0);
9336 ok(priority == 1, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9338 else
9339 ok(priority == 0, "Got unexpected priority %u, pool %s.\n", priority, test_data[i].name);
9341 IDirect3DVertexBuffer9_Release(buffer);
9345 hr = IDirect3DDevice9_CreateRenderTarget(device, 16, 16, D3DFMT_X8R8G8B8,
9346 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
9348 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
9349 priority = IDirect3DSurface9_GetPriority(surface);
9350 ok(priority == 0, "Got unexpected priority %u.\n", priority);
9351 priority = IDirect3DSurface9_SetPriority(surface, 1);
9352 ok(priority == 0, "Got unexpected priority %u.\n", priority);
9353 priority = IDirect3DSurface9_GetPriority(surface);
9354 ok(priority == 0, "Got unexpected priority %u.\n", priority);
9356 IDirect3DSurface9_Release(surface);
9358 refcount = IDirect3DDevice9_Release(device);
9359 ok(!refcount, "Device has %u references left.\n", refcount);
9360 IDirect3D9_Release(d3d);
9361 DestroyWindow(window);
9364 START_TEST(device)
9366 WNDCLASSA wc = {0};
9367 IDirect3D9 *d3d9;
9369 if (!(d3d9 = Direct3DCreate9(D3D_SDK_VERSION)))
9371 skip("could not create D3D9 object\n");
9372 return;
9374 IDirect3D9_Release(d3d9);
9376 wc.lpfnWndProc = DefWindowProcA;
9377 wc.lpszClassName = "d3d9_test_wc";
9378 RegisterClassA(&wc);
9380 screen_width = GetSystemMetrics(SM_CXSCREEN);
9381 screen_height = GetSystemMetrics(SM_CYSCREEN);
9383 test_get_set_vertex_declaration();
9384 test_get_declaration();
9385 test_fvf_decl_conversion();
9386 test_fvf_decl_management();
9387 test_vertex_declaration_alignment();
9388 test_unused_declaration_type();
9389 test_fpu_setup();
9390 test_multi_device();
9391 test_display_formats();
9392 test_display_modes();
9393 test_swapchain();
9394 test_refcount();
9395 test_mipmap_levels();
9396 test_checkdevicemultisampletype();
9397 test_cursor();
9398 test_cursor_pos();
9399 test_reset_fullscreen();
9400 test_reset();
9401 test_scene();
9402 test_limits();
9403 test_depthstenciltest();
9404 test_get_rt();
9405 test_draw_indexed();
9406 test_null_stream();
9407 test_lights();
9408 test_set_stream_source();
9409 test_scissor_size();
9410 test_wndproc();
9411 test_wndproc_windowed();
9412 test_window_style();
9413 test_mode_change();
9414 test_device_window_reset();
9415 test_reset_resources();
9416 test_set_rt_vp_scissor();
9417 test_volume_get_container();
9418 test_volume_resource();
9419 test_vb_lock_flags();
9420 test_vertex_buffer_alignment();
9421 test_query_support();
9422 test_occlusion_query_states();
9423 test_timestamp_query();
9424 test_get_set_vertex_shader();
9425 test_vertex_shader_constant();
9426 test_get_set_pixel_shader();
9427 test_pixel_shader_constant();
9428 test_wrong_shader();
9429 test_texture_stage_states();
9430 test_cube_textures();
9431 test_mipmap_gen();
9432 test_filter();
9433 test_get_texture();
9434 test_lod();
9435 test_surface_get_container();
9436 test_surface_alignment();
9437 test_lockrect_offset();
9438 test_lockrect_invalid();
9439 test_private_data();
9440 test_getdc();
9441 test_surface_dimensions();
9442 test_surface_format_null();
9443 test_surface_double_unlock();
9444 test_surface_blocks();
9445 test_set_palette();
9446 test_swvp_buffer();
9447 test_npot_textures();
9448 test_vidmem_accounting();
9449 test_volume_locking();
9450 test_update_volumetexture();
9451 test_create_rt_ds_fail();
9452 test_volume_blocks();
9453 test_lockbox_invalid();
9454 test_shared_handle();
9455 test_pixel_format();
9456 test_begin_end_state_block();
9457 test_shader_constant_apply();
9458 test_vdecl_apply();
9459 test_resource_type();
9460 test_mipmap_lock();
9461 test_writeonly_resource();
9462 test_lost_device();
9463 test_resource_priority();
9465 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));