d3d9/tests: Merge vertexdeclaration.c into device.c.
[wine.git] / dlls / d3d9 / tests / device.c
blob894e566743988a0f90638d7c6d34cbc41fca1cfb
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 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
30 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
32 static INT screen_width;
33 static INT screen_height;
35 static const DWORD simple_vs[] =
37 0xfffe0101, /* vs_1_1 */
38 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
39 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
40 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
41 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
42 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
43 0x0000ffff, /* end */
46 static const DWORD simple_ps[] =
48 0xffff0101, /* ps_1_1 */
49 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
50 0x00000042, 0xb00f0000, /* tex t0 */
51 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
52 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
53 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
54 0x0000ffff, /* end */
57 static int get_refcount(IUnknown *object)
59 IUnknown_AddRef( object );
60 return IUnknown_Release( object );
63 static BOOL compare_elements(IDirect3DVertexDeclaration9 *declaration, const D3DVERTEXELEMENT9 *expected_elements)
65 unsigned int element_count, i;
66 D3DVERTEXELEMENT9 *elements;
67 BOOL equal = TRUE;
68 HRESULT hr;
70 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
71 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
72 elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(*elements));
73 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
74 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
76 for (i = 0; i < element_count; ++i)
78 if (memcmp(&elements[i], &expected_elements[i], sizeof(*elements)))
80 equal = FALSE;
81 break;
85 if (!equal)
87 for (i = 0; i < element_count; ++i)
89 trace("[Element %u] stream %u, offset %u, type %#x, method %#x, usage %#x, usage index %u.\n",
90 i, elements[i].Stream, elements[i].Offset, elements[i].Type,
91 elements[i].Method, elements[i].Usage, elements[i].UsageIndex);
95 HeapFree(GetProcessHeap(), 0, elements);
96 return equal;
99 /* try to make sure pending X events have been processed before continuing */
100 static void flush_events(void)
102 MSG msg;
103 int diff = 200;
104 int min_timeout = 100;
105 DWORD time = GetTickCount() + diff;
107 while (diff > 0)
109 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
110 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
111 diff = time - GetTickCount();
115 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND device_window, HWND focus_window, BOOL windowed)
117 D3DPRESENT_PARAMETERS present_parameters = {0};
118 IDirect3DDevice9 *device;
120 present_parameters.Windowed = windowed;
121 present_parameters.hDeviceWindow = device_window;
122 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
123 present_parameters.BackBufferWidth = screen_width;
124 present_parameters.BackBufferHeight = screen_height;
125 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
126 present_parameters.EnableAutoDepthStencil = TRUE;
127 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
129 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
130 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
132 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
133 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
134 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
136 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
137 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
139 return NULL;
142 static HRESULT reset_device(IDirect3DDevice9 *device, HWND device_window, BOOL windowed)
144 D3DPRESENT_PARAMETERS present_parameters = {0};
146 present_parameters.Windowed = windowed;
147 present_parameters.hDeviceWindow = device_window;
148 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
149 present_parameters.BackBufferWidth = screen_width;
150 present_parameters.BackBufferHeight = screen_height;
151 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
152 present_parameters.EnableAutoDepthStencil = TRUE;
153 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
155 return IDirect3DDevice9_Reset(device, &present_parameters);
158 #define CHECK_CALL(r,c,d,rc) \
159 if (SUCCEEDED(r)) {\
160 int tmp1 = get_refcount( (IUnknown *)d ); \
161 int rc_new = rc; \
162 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
163 } else {\
164 trace("%s failed: %08x\n", c, r); \
167 #define CHECK_RELEASE(obj,d,rc) \
168 if (obj) { \
169 int tmp1, rc_new = rc; \
170 IUnknown_Release( (IUnknown*)obj ); \
171 tmp1 = get_refcount( (IUnknown *)d ); \
172 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
175 #define CHECK_REFCOUNT(obj,rc) \
177 int rc_new = rc; \
178 int count = get_refcount( (IUnknown *)obj ); \
179 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
182 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
184 int rc_new = rc; \
185 int count = IUnknown_Release( (IUnknown *)obj ); \
186 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
189 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
191 int rc_new = rc; \
192 int count = IUnknown_AddRef( (IUnknown *)obj ); \
193 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
196 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
198 void *container_ptr = (void *)0x1337c0d3; \
199 hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
200 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
201 "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
202 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
205 static void test_get_set_vertex_declaration(void)
207 IDirect3DVertexDeclaration9 *declaration, *tmp;
208 ULONG refcount, expected_refcount;
209 IDirect3DDevice9 *device;
210 IDirect3D9 *d3d;
211 HWND window;
212 HRESULT hr;
214 static const D3DVERTEXELEMENT9 simple_decl[] =
216 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
217 D3DDECL_END()
220 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
221 0, 0, 640, 480, NULL, NULL, NULL, NULL);
222 d3d = Direct3DCreate9(D3D_SDK_VERSION);
223 ok(!!d3d, "Failed to create a D3D object.\n");
224 if (!(device = create_device(d3d, window, window, TRUE)))
226 skip("Failed to create a D3D device, skipping tests.\n");
227 goto done;
230 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
231 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
233 /* SetVertexDeclaration() should not touch the declaration's refcount. */
234 expected_refcount = get_refcount((IUnknown *)declaration);
235 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
236 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
237 refcount = get_refcount((IUnknown *)declaration);
238 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
240 /* GetVertexDeclaration() should increase the declaration's refcount by one. */
241 tmp = NULL;
242 expected_refcount = refcount + 1;
243 hr = IDirect3DDevice9_GetVertexDeclaration(device, &tmp);
244 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
245 ok(tmp == declaration, "Got unexpected declaration %p, expected %p.\n", tmp, declaration);
246 refcount = get_refcount((IUnknown *)declaration);
247 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
248 IDirect3DVertexDeclaration9_Release(tmp);
250 IDirect3DVertexDeclaration9_Release(declaration);
251 refcount = IDirect3DDevice9_Release(device);
252 ok(!refcount, "Device has %u references left.\n", refcount);
253 done:
254 IDirect3D9_Release(d3d);
255 DestroyWindow(window);
258 static void test_get_declaration(void)
260 unsigned int element_count, expected_element_count;
261 IDirect3DVertexDeclaration9 *declaration;
262 D3DVERTEXELEMENT9 *elements;
263 IDirect3DDevice9 *device;
264 IDirect3D9 *d3d;
265 ULONG refcount;
266 HWND window;
267 HRESULT hr;
269 static const D3DVERTEXELEMENT9 simple_decl[] =
271 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
272 D3DDECL_END()
275 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
276 0, 0, 640, 480, NULL, NULL, NULL, NULL);
277 d3d = Direct3DCreate9(D3D_SDK_VERSION);
278 ok(!!d3d, "Failed to create a D3D object.\n");
279 if (!(device = create_device(d3d, window, window, TRUE)))
281 skip("Failed to create a D3D device, skipping tests.\n");
282 goto done;
285 hr = IDirect3DDevice9_CreateVertexDeclaration(device, simple_decl, &declaration);
286 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
288 /* First test only getting the number of elements. */
289 element_count = 0x1337c0de;
290 expected_element_count = sizeof(simple_decl) / sizeof(*simple_decl);
291 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
292 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
293 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
294 element_count, expected_element_count);
296 element_count = 0;
297 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, NULL, &element_count);
298 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
299 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
300 element_count, expected_element_count);
302 /* Also test the returned data. */
303 elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(simple_decl));
305 element_count = 0x1337c0de;
306 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
307 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
308 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
309 element_count, expected_element_count);
310 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
311 "Original and returned vertexdeclarations are not the same.\n");
313 memset(elements, 0, sizeof(simple_decl));
315 element_count = 0;
316 hr = IDirect3DVertexDeclaration9_GetDeclaration(declaration, elements, &element_count);
317 ok(SUCCEEDED(hr), "Failed to get declaration, hr %#x.\n", hr);
318 ok(element_count == expected_element_count, "Got unexpected element count %u, expected %u.\n",
319 element_count, expected_element_count);
320 ok(!memcmp(elements, simple_decl, element_count * sizeof(*elements)),
321 "Original and returned vertexdeclarations are not the same.\n");
323 HeapFree(GetProcessHeap(), 0, elements);
324 IDirect3DVertexDeclaration9_Release(declaration);
325 refcount = IDirect3DDevice9_Release(device);
326 ok(!refcount, "Device has %u references left.\n", refcount);
327 done:
328 IDirect3D9_Release(d3d);
329 DestroyWindow(window);
332 static void test_fvf_decl_conversion(void)
334 IDirect3DVertexDeclaration9 *default_decl;
335 IDirect3DVertexDeclaration9 *declaration;
336 IDirect3DDevice9 *device;
337 IDirect3D9 *d3d;
338 ULONG refcount;
339 unsigned int i;
340 HWND window;
341 HRESULT hr;
343 static const D3DVERTEXELEMENT9 default_elements[] =
345 {0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
346 {0, 4, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
347 D3DDECL_END()
349 /* Test conversions from vertex declaration to an FVF. For some reason
350 * those seem to occur only for POSITION/POSITIONT, otherwise the FVF is
351 * forced to 0 - maybe this is configuration specific. */
352 static const struct
354 D3DVERTEXELEMENT9 elements[7];
355 DWORD fvf;
356 BOOL todo;
358 decl_to_fvf_tests[] =
360 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}, D3DFVF_XYZ, TRUE },
361 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}, D3DFVF_XYZRHW, TRUE },
362 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
363 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
364 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
365 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END()}, 0, FALSE},
366 {{{0, 0, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0}, D3DDECL_END()}, 0, FALSE},
367 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}, 0, FALSE},
368 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}, 0, FALSE},
369 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}, 0, FALSE},
370 {{{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}, 0, FALSE},
371 /* No FVF mapping available. */
372 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 1}, D3DDECL_END()}, 0, FALSE},
373 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 1}, D3DDECL_END()}, 0, FALSE},
374 /* Try empty declaration. */
375 {{ D3DDECL_END()}, 0, FALSE},
376 /* Make sure textures of different sizes work. */
377 {{{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
378 {{{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
379 {{{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
380 {{{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()}, 0, FALSE},
381 /* Make sure the TEXCOORD index works correctly - try several textures. */
384 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
385 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
386 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
387 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
388 D3DDECL_END(),
389 }, 0, FALSE,
391 /* Now try a combination test. */
394 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITIONT, 0},
395 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
396 {0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0},
397 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
398 {0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
399 {0, 44, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1},
400 D3DDECL_END(),
401 }, 0, FALSE,
404 /* Test conversions from FVF to a vertex declaration. These seem to always
405 * occur internally. A new declaration object is created if necessary. */
406 static const struct
408 DWORD fvf;
409 D3DVERTEXELEMENT9 elements[7];
411 fvf_to_decl_tests[] =
413 {D3DFVF_XYZ, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
414 {D3DFVF_XYZW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()}},
415 {D3DFVF_XYZRHW, {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()}},
417 D3DFVF_XYZB5,
419 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
420 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
421 {0, 28, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDINDICES, 0},
422 D3DDECL_END(),
426 D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4,
428 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
429 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
430 {0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
431 D3DDECL_END(),
435 D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR,
437 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
438 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
439 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
440 D3DDECL_END(),
444 D3DFVF_XYZB1,
446 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
447 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
448 D3DDECL_END(),
452 D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4,
454 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
455 {0, 12, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
456 D3DDECL_END(),
460 D3DFVF_XYZB1 | D3DFVF_LASTBETA_D3DCOLOR,
462 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
463 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
464 D3DDECL_END(),
468 D3DFVF_XYZB2,
470 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
471 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
472 D3DDECL_END(),
476 D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4,
478 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
479 {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
480 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
481 D3DDECL_END(),
485 D3DFVF_XYZB2 | D3DFVF_LASTBETA_D3DCOLOR,
487 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
488 {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
489 {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
490 D3DDECL_END(),
494 D3DFVF_XYZB3,
496 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
497 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
498 D3DDECL_END(),
502 D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4,
504 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
505 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
506 {0, 20, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
507 D3DDECL_END(),
511 D3DFVF_XYZB3 | D3DFVF_LASTBETA_D3DCOLOR,
513 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
514 {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
515 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
516 D3DDECL_END(),
520 D3DFVF_XYZB4,
522 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
523 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
524 D3DDECL_END(),
528 D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4,
530 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
531 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
532 {0, 24, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
533 D3DDECL_END(),
537 D3DFVF_XYZB4 | D3DFVF_LASTBETA_D3DCOLOR,
539 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
540 {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
541 {0, 24, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
542 D3DDECL_END(),
545 {D3DFVF_NORMAL, {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()}},
546 {D3DFVF_PSIZE, {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0}, D3DDECL_END()}},
547 {D3DFVF_DIFFUSE, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END()}},
548 {D3DFVF_SPECULAR, {{0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1}, D3DDECL_END()}},
549 /* Make sure textures of different sizes work. */
551 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1,
552 {{0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
555 D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1,
556 {{0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
559 D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1,
560 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
563 D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1,
564 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END()},
566 /* Make sure the TEXCOORD index works correctly - try several textures. */
568 D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE2(2)
569 | D3DFVF_TEXCOORDSIZE4(3) | D3DFVF_TEX4,
571 {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
572 {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
573 {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
574 {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
575 D3DDECL_END(),
578 /* Now try a combination test. */
580 D3DFVF_XYZB4 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEXCOORDSIZE2(0)
581 | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEX2,
583 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
584 {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
585 {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
586 {0, 32, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
587 {0, 36, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0},
588 {0, 44, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
589 D3DDECL_END(),
594 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
595 0, 0, 640, 480, NULL, NULL, NULL, NULL);
596 d3d = Direct3DCreate9(D3D_SDK_VERSION);
597 ok(!!d3d, "Failed to create a D3D object.\n");
598 if (!(device = create_device(d3d, window, window, TRUE)))
600 skip("Failed to create a D3D device, skipping tests.\n");
601 goto done;
604 for (i = 0; i < sizeof(decl_to_fvf_tests) / sizeof(*decl_to_fvf_tests); ++i)
606 DWORD fvf = 0xdeadbeef;
607 HRESULT hr;
609 /* Set a default FVF of SPECULAR and DIFFUSE to make sure it is changed
610 * back to 0. */
611 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
612 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#x.\n", i, hr);
614 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_to_fvf_tests[i].elements, &declaration);
615 ok(SUCCEEDED(hr), "Test %u: Failed to create vertex declaration, hr %#x.\n", i, hr);
616 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
617 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#x.\n", i, hr);
619 /* Check the FVF. */
620 hr = IDirect3DDevice9_GetFVF(device, &fvf);
621 ok(SUCCEEDED(hr), "Test %u: Failed to get FVF, hr %#x.\n", i, hr);
623 if (decl_to_fvf_tests[i].todo)
624 todo_wine ok(fvf == decl_to_fvf_tests[i].fvf,
625 "Test %u: Got unexpected FVF %#x, expected %#x.\n",
626 i, fvf, decl_to_fvf_tests[i].fvf);
627 else
628 ok(fvf == decl_to_fvf_tests[i].fvf,
629 "Test %u: Got unexpected FVF %#x, expected %#x.\n",
630 i, fvf, decl_to_fvf_tests[i].fvf);
632 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
633 IDirect3DVertexDeclaration9_Release(declaration);
636 /* Create a default declaration and FVF that does not match any of the
637 * tests. */
638 hr = IDirect3DDevice9_CreateVertexDeclaration(device, default_elements, &default_decl);
639 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
641 for (i = 0; i < sizeof(fvf_to_decl_tests) / sizeof(*fvf_to_decl_tests); ++i)
643 /* Set a default declaration to make sure it is changed. */
644 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
645 ok(SUCCEEDED(hr), "Test %u: Failed to set vertex declaration, hr %#x.\n", i, hr);
647 hr = IDirect3DDevice9_SetFVF(device, fvf_to_decl_tests[i].fvf);
648 ok(SUCCEEDED(hr), "Test %u: Failed to set FVF, hr %#x.\n", i, hr);
650 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
651 ok(SUCCEEDED(hr), "Test %u: Failed to get vertex declaration, hr %#x.\n", i, hr);
652 ok(!!declaration && declaration != default_decl,
653 "Test %u: Got unexpected declaration %p.\n", i, declaration);
654 ok(compare_elements(declaration, fvf_to_decl_tests[i].elements),
655 "Test %u: Declaration does not match.\n", i);
656 IDirect3DVertexDeclaration9_Release(declaration);
659 /* Setting the FVF to 0 should result in no change to the default decl. */
660 hr = IDirect3DDevice9_SetVertexDeclaration(device, default_decl);
661 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
662 hr = IDirect3DDevice9_SetFVF(device, 0);
663 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
664 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
665 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
666 ok(declaration == default_decl, "Got unexpected declaration %p, expected %p.\n", declaration, default_decl);
667 IDirect3DVertexDeclaration9_Release(declaration);
669 IDirect3DVertexDeclaration9_Release(default_decl);
670 refcount = IDirect3DDevice9_Release(device);
671 ok(!refcount, "Device has %u references left.\n", refcount);
672 done:
673 IDirect3D9_Release(d3d);
674 DestroyWindow(window);
677 /* Check whether a declaration converted from FVF is shared.
678 * Check whether refcounts behave as expected. */
679 static void test_fvf_decl_management(void)
681 IDirect3DVertexDeclaration9 *declaration1;
682 IDirect3DVertexDeclaration9 *declaration2;
683 IDirect3DVertexDeclaration9 *declaration3;
684 IDirect3DVertexDeclaration9 *declaration4;
685 IDirect3DDevice9 *device;
686 IDirect3D9 *d3d;
687 ULONG refcount;
688 HWND window;
689 HRESULT hr;
691 static const D3DVERTEXELEMENT9 test_elements1[] =
692 {{0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0}, D3DDECL_END()};
693 static const D3DVERTEXELEMENT9 test_elements2[] =
694 {{0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END()};
696 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
697 0, 0, 640, 480, NULL, NULL, NULL, NULL);
698 d3d = Direct3DCreate9(D3D_SDK_VERSION);
699 ok(!!d3d, "Failed to create a D3D object.\n");
700 if (!(device = create_device(d3d, window, window, TRUE)))
702 skip("Failed to create a D3D device, skipping tests.\n");
703 goto done;
706 /* Clear down any current vertex declaration. */
707 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
708 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
709 /* Conversion. */
710 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
711 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
712 /* Get converted decl (#1). */
713 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration1);
714 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
715 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
716 /* Get converted decl again (#2). */
717 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration2);
718 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
719 ok(declaration2 == declaration1, "Got unexpected declaration2 %p, expected %p.\n", declaration2, declaration1);
721 /* Conversion. */
722 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_NORMAL);
723 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
724 /* Get converted decl (#3). */
725 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration3);
726 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
727 ok(declaration3 != declaration2, "Got unexpected declaration3 %p.\n", declaration3);
728 /* The contents should correspond to the second conversion. */
729 ok(compare_elements(declaration3, test_elements2), "Declaration does not match.\n");
730 /* Re-Check if the first decl was overwritten by the new Get(). */
731 ok(compare_elements(declaration1, test_elements1), "Declaration does not match.\n");
733 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW);
734 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
735 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration4);
736 ok(SUCCEEDED(hr), "Failed to get vertex declaration, hr %#x.\n", hr);
737 ok(declaration4 == declaration1, "Got unexpected declaration4 %p, expected %p.\n", declaration4, declaration1);
739 refcount = get_refcount((IUnknown*)declaration1);
740 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
741 refcount = get_refcount((IUnknown*)declaration2);
742 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
743 refcount = get_refcount((IUnknown*)declaration3);
744 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
745 refcount = get_refcount((IUnknown*)declaration4);
746 ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
748 IDirect3DVertexDeclaration9_Release(declaration4);
749 IDirect3DVertexDeclaration9_Release(declaration3);
750 IDirect3DVertexDeclaration9_Release(declaration2);
751 IDirect3DVertexDeclaration9_Release(declaration1);
753 refcount = IDirect3DDevice9_Release(device);
754 ok(!refcount, "Device has %u references left.\n", refcount);
755 done:
756 IDirect3D9_Release(d3d);
757 DestroyWindow(window);
760 static void test_vertex_declaration_alignment(void)
762 IDirect3DVertexDeclaration9 *declaration;
763 IDirect3DDevice9 *device;
764 IDirect3D9 *d3d;
765 unsigned int i;
766 ULONG refcount;
767 HWND window;
768 HRESULT hr;
770 static const struct
772 D3DVERTEXELEMENT9 elements[3];
773 HRESULT hr;
775 test_data[] =
779 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
780 {0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
781 D3DDECL_END(),
782 }, D3D_OK,
786 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
787 {0, 17, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
788 D3DDECL_END(),
789 }, E_FAIL,
793 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
794 {0, 18, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
795 D3DDECL_END(),
796 }, E_FAIL,
800 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
801 {0, 19, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
802 D3DDECL_END(),
803 }, E_FAIL,
807 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
808 {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
809 D3DDECL_END(),
810 }, D3D_OK,
814 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
815 0, 0, 640, 480, NULL, NULL, NULL, NULL);
816 d3d = Direct3DCreate9(D3D_SDK_VERSION);
817 ok(!!d3d, "Failed to create a D3D object.\n");
818 if (!(device = create_device(d3d, window, window, TRUE)))
820 skip("Failed to create a D3D device, skipping tests.\n");
821 goto done;
824 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
826 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_data[i].elements, &declaration);
827 ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr);
828 if (SUCCEEDED(hr))
829 IDirect3DVertexDeclaration9_Release(declaration);
832 refcount = IDirect3DDevice9_Release(device);
833 ok(!refcount, "Device has %u references left.\n", refcount);
834 done:
835 IDirect3D9_Release(d3d);
836 DestroyWindow(window);
839 static void test_unused_declaration_type(void)
841 IDirect3DVertexDeclaration9 *declaration;
842 IDirect3DDevice9 *device;
843 IDirect3D9 *d3d;
844 unsigned int i;
845 ULONG refcount;
846 HWND window;
847 HRESULT hr;
849 static const D3DVERTEXELEMENT9 test_elements[][3] =
852 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
853 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_COLOR , 0 },
854 D3DDECL_END(),
857 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
858 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 0 },
859 D3DDECL_END(),
862 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
863 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 1 },
864 D3DDECL_END(),
867 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
868 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
869 D3DDECL_END(),
872 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
873 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
874 D3DDECL_END(),
877 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
878 {0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
879 D3DDECL_END(),
882 {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
883 {1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 },
884 D3DDECL_END(),
888 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
889 0, 0, 640, 480, NULL, NULL, NULL, NULL);
890 d3d = Direct3DCreate9(D3D_SDK_VERSION);
891 ok(!!d3d, "Failed to create a D3D object.\n");
892 if (!(device = create_device(d3d, window, window, TRUE)))
894 skip("Failed to create a D3D device, skipping tests.\n");
895 goto done;
898 for (i = 0; i < sizeof(test_elements) / sizeof(*test_elements); ++i)
900 hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &declaration);
901 ok(hr == E_FAIL, "Test %u: Got unexpected hr %#x.\n", i, hr);
904 refcount = IDirect3DDevice9_Release(device);
905 ok(!refcount, "Device has %u references left.\n", refcount);
906 done:
907 IDirect3D9_Release(d3d);
908 DestroyWindow(window);
911 static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count)
913 IDirect3DBaseTexture9* texture = NULL;
914 HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0,
915 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
917 if (SUCCEEDED(hr)) {
918 DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
919 ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
920 } else
921 trace("CreateTexture failed: %08x\n", hr);
923 if (texture) IDirect3DBaseTexture9_Release( texture );
926 static void test_mipmap_levels(void)
928 IDirect3DDevice9 *device;
929 IDirect3D9 *d3d;
930 ULONG refcount;
931 HWND window;
933 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
934 0, 0, 640, 480, NULL, NULL, NULL, NULL);
935 ok(!!window, "Failed to create a window.\n");
936 d3d = Direct3DCreate9(D3D_SDK_VERSION);
937 ok(!!d3d, "Failed to create a D3D object.\n");
938 if (!(device = create_device(d3d, window, window, TRUE)))
940 skip("Failed to create a 3D device, skipping test.\n");
941 goto cleanup;
944 check_mipmap_levels(device, 32, 32, 6);
945 check_mipmap_levels(device, 256, 1, 9);
946 check_mipmap_levels(device, 1, 256, 9);
947 check_mipmap_levels(device, 1, 1, 1);
949 refcount = IDirect3DDevice9_Release(device);
950 ok(!refcount, "Device has %u references left.\n", refcount);
951 cleanup:
952 IDirect3D9_Release(d3d);
953 DestroyWindow(window);
956 static void test_checkdevicemultisampletype(void)
958 IDirect3DDevice9 *device;
959 DWORD quality_levels;
960 IDirect3D9 *d3d;
961 ULONG refcount;
962 HWND window;
963 HRESULT hr;
965 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
966 0, 0, 640, 480, NULL, NULL, NULL, NULL);
967 ok(!!window, "Failed to create a window.\n");
968 d3d = Direct3DCreate9(D3D_SDK_VERSION);
969 ok(!!d3d, "Failed to create a D3D object.\n");
970 if (!(device = create_device(d3d, window, window, TRUE)))
972 skip("Failed to create a 3D device, skipping test.\n");
973 goto cleanup;
976 quality_levels = 0;
977 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
978 D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality_levels);
979 ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
980 if (hr == D3DERR_NOTAVAILABLE)
982 skip("IDirect3D9_CheckDeviceMultiSampleType not available\n");
983 goto cleanup;
985 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
987 hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
988 D3DFMT_X8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality_levels);
989 ok(SUCCEEDED(hr), "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
990 ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels);
992 cleanup:
993 if (device)
995 refcount = IDirect3DDevice9_Release(device);
996 ok(!refcount, "Device has %u references left.\n", refcount);
998 IDirect3D9_Release(d3d);
999 DestroyWindow(window);
1002 static void test_swapchain(void)
1004 IDirect3DSwapChain9 *swapchain0;
1005 IDirect3DSwapChain9 *swapchain1;
1006 IDirect3DSwapChain9 *swapchain2;
1007 IDirect3DSwapChain9 *swapchain3;
1008 IDirect3DSwapChain9 *swapchainX;
1009 IDirect3DSurface9 *backbuffer;
1010 D3DPRESENT_PARAMETERS d3dpp;
1011 IDirect3DDevice9 *device;
1012 IDirect3D9 *d3d;
1013 ULONG refcount;
1014 HWND window;
1015 HRESULT hr;
1017 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1018 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1019 ok(!!window, "Failed to create a window.\n");
1020 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1021 ok(!!d3d, "Failed to create a D3D object.\n");
1022 if (!(device = create_device(d3d, window, window, TRUE)))
1024 skip("Failed to create a 3D device, skipping test.\n");
1025 goto cleanup;
1028 /* Get the implicit swapchain */
1029 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain0);
1030 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
1031 /* Check if the back buffer count was modified */
1032 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain0, &d3dpp);
1033 ok(d3dpp.BackBufferCount == 1, "Got unexpected back buffer count %u.\n", d3dpp.BackBufferCount);
1034 IDirect3DSwapChain9_Release(swapchain0);
1036 /* Check if there is a back buffer */
1037 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1038 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1039 ok(backbuffer != NULL, "The back buffer is NULL\n");
1040 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1042 /* Try to get a nonexistent swapchain */
1043 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1044 ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr);
1045 ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
1046 if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
1048 /* Create a bunch of swapchains */
1049 d3dpp.BackBufferCount = 0;
1050 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain1);
1051 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1052 ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
1054 d3dpp.BackBufferCount = 1;
1055 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain2);
1056 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1058 d3dpp.BackBufferCount = 2;
1059 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &swapchain3);
1060 ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
1061 if(SUCCEEDED(hr)) {
1062 /* Swapchain 3, created with backbuffercount 2 */
1063 backbuffer = (void *) 0xdeadbeef;
1064 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
1065 ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%08x)\n", hr);
1066 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1067 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1069 backbuffer = (void *) 0xdeadbeef;
1070 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
1071 ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%08x)\n", hr);
1072 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1073 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1075 backbuffer = (void *) 0xdeadbeef;
1076 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
1077 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
1078 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1079 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1081 backbuffer = (void *) 0xdeadbeef;
1082 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
1083 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1084 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1085 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1088 /* Check the back buffers of the swapchains */
1089 /* Swapchain 1, created with backbuffercount 0 */
1090 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1091 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1092 ok(backbuffer != NULL, "The back buffer is NULL (%08x)\n", hr);
1093 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
1095 backbuffer = (void *) 0xdeadbeef;
1096 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
1097 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1098 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1099 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1101 /* Swapchain 2 - created with backbuffercount 1 */
1102 backbuffer = (void *) 0xdeadbeef;
1103 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
1104 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
1105 ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
1106 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1108 backbuffer = (void *) 0xdeadbeef;
1109 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
1110 ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
1111 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1112 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1114 backbuffer = (void *) 0xdeadbeef;
1115 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
1116 ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
1117 ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
1118 if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
1120 /* Try getSwapChain on a manually created swapchain
1121 * it should fail, apparently GetSwapChain only returns implicit swapchains
1123 swapchainX = (void *) 0xdeadbeef;
1124 hr = IDirect3DDevice9_GetSwapChain(device, 1, &swapchainX);
1125 ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%08x)\n", hr);
1126 ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
1127 if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
1129 IDirect3DSwapChain9_Release(swapchain3);
1130 IDirect3DSwapChain9_Release(swapchain2);
1131 IDirect3DSwapChain9_Release(swapchain1);
1132 refcount = IDirect3DDevice9_Release(device);
1133 ok(!refcount, "Device has %u references left.\n", refcount);
1134 cleanup:
1135 IDirect3D9_Release(d3d);
1136 DestroyWindow(window);
1139 static void test_refcount(void)
1141 IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
1142 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
1143 IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
1144 IDirect3DVertexShader9 *pVertexShader = NULL;
1145 IDirect3DPixelShader9 *pPixelShader = NULL;
1146 IDirect3DCubeTexture9 *pCubeTexture = NULL;
1147 IDirect3DTexture9 *pTexture = NULL;
1148 IDirect3DVolumeTexture9 *pVolumeTexture = NULL;
1149 IDirect3DVolume9 *pVolumeLevel = NULL;
1150 IDirect3DSurface9 *pStencilSurface = NULL;
1151 IDirect3DSurface9 *pOffscreenSurface = NULL;
1152 IDirect3DSurface9 *pRenderTarget = NULL;
1153 IDirect3DSurface9 *pRenderTarget2 = NULL;
1154 IDirect3DSurface9 *pRenderTarget3 = NULL;
1155 IDirect3DSurface9 *pTextureLevel = NULL;
1156 IDirect3DSurface9 *pBackBuffer = NULL;
1157 IDirect3DStateBlock9 *pStateBlock = NULL;
1158 IDirect3DStateBlock9 *pStateBlock1 = NULL;
1159 IDirect3DSwapChain9 *pSwapChain = NULL;
1160 IDirect3DQuery9 *pQuery = NULL;
1161 D3DPRESENT_PARAMETERS d3dpp;
1162 IDirect3DDevice9 *device;
1163 ULONG refcount = 0, tmp;
1164 IDirect3D9 *d3d, *d3d2;
1165 HWND window;
1166 HRESULT hr;
1168 D3DVERTEXELEMENT9 decl[] =
1170 D3DDECL_END()
1173 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1174 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1175 ok(!!window, "Failed to create a window.\n");
1176 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1177 ok(!!d3d, "Failed to create a D3D object.\n");
1179 CHECK_REFCOUNT(d3d, 1);
1181 if (!(device = create_device(d3d, window, window, TRUE)))
1183 skip("Failed to create a 3D device, skipping test.\n");
1184 goto cleanup;
1187 refcount = get_refcount((IUnknown *)device);
1188 ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
1190 CHECK_REFCOUNT(d3d, 2);
1192 hr = IDirect3DDevice9_GetDirect3D(device, &d3d2);
1193 CHECK_CALL(hr, "GetDirect3D", device, refcount);
1195 ok(d3d2 == d3d, "Expected IDirect3D9 pointers to be equal.\n");
1196 CHECK_REFCOUNT(d3d, 3);
1197 CHECK_RELEASE_REFCOUNT(d3d, 2);
1200 * Check refcount of implicit surfaces and implicit swapchain. Findings:
1201 * - the container is the device OR swapchain
1202 * - they hold a reference to the device
1203 * - they are created with a refcount of 0 (Get/Release returns original refcount)
1204 * - they are not freed if refcount reaches 0.
1205 * - the refcount is not forwarded to the container.
1207 hr = IDirect3DDevice9_GetSwapChain(device, 0, &pSwapChain);
1208 CHECK_CALL(hr, "GetSwapChain", device, ++refcount);
1209 if (pSwapChain)
1211 CHECK_REFCOUNT( pSwapChain, 1);
1213 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1214 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1215 CHECK_REFCOUNT( pSwapChain, 1);
1216 if(pRenderTarget)
1218 CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
1219 CHECK_REFCOUNT( pRenderTarget, 1);
1221 CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
1222 CHECK_REFCOUNT(device, refcount);
1223 CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
1224 CHECK_REFCOUNT(device, refcount);
1226 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget);
1227 CHECK_CALL(hr, "GetRenderTarget", device, refcount);
1228 CHECK_REFCOUNT( pRenderTarget, 2);
1229 CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
1230 CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
1231 CHECK_REFCOUNT(device, --refcount);
1233 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
1234 CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
1235 CHECK_REFCOUNT(device, ++refcount);
1236 CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
1237 CHECK_REFCOUNT(device, --refcount);
1240 /* Render target and back buffer are identical. */
1241 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, 0, &pBackBuffer);
1242 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1243 if(pBackBuffer)
1245 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1246 ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
1247 pRenderTarget, pBackBuffer);
1248 pBackBuffer = NULL;
1250 CHECK_REFCOUNT(device, --refcount);
1252 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &pStencilSurface);
1253 CHECK_CALL(hr, "GetDepthStencilSurface", device, ++refcount);
1254 CHECK_REFCOUNT( pSwapChain, 1);
1255 if(pStencilSurface)
1257 CHECK_SURFACE_CONTAINER(pStencilSurface, IID_IDirect3DDevice9, device);
1258 CHECK_REFCOUNT( pStencilSurface, 1);
1260 CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
1261 CHECK_REFCOUNT(device, refcount);
1262 CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
1263 CHECK_REFCOUNT(device, refcount);
1265 CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
1266 CHECK_REFCOUNT(device, --refcount);
1268 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
1269 CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
1270 CHECK_REFCOUNT(device, ++refcount);
1271 CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
1272 CHECK_REFCOUNT(device, --refcount);
1273 pStencilSurface = NULL;
1276 CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
1277 CHECK_REFCOUNT(device, --refcount);
1279 /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
1280 CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
1281 CHECK_REFCOUNT(device, ++refcount);
1282 CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
1283 CHECK_REFCOUNT(device, --refcount);
1284 pSwapChain = NULL;
1287 /* Buffers */
1288 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL);
1289 CHECK_CALL(hr, "CreateIndexBuffer", device, ++refcount );
1290 if(pIndexBuffer)
1292 tmp = get_refcount( (IUnknown *)pIndexBuffer );
1294 hr = IDirect3DDevice9_SetIndices(device, pIndexBuffer);
1295 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1296 hr = IDirect3DDevice9_SetIndices(device, NULL);
1297 CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
1300 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL);
1301 CHECK_CALL(hr, "CreateVertexBuffer", device, ++refcount);
1302 if(pVertexBuffer)
1304 IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
1305 UINT offset = ~0;
1306 UINT stride = ~0;
1308 tmp = get_refcount( (IUnknown *)pVertexBuffer );
1310 hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 3 * sizeof(float));
1311 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1312 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1313 CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
1315 hr = IDirect3DDevice9_GetStreamSource(device, 0, &pVBuf, &offset, &stride);
1316 ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
1317 ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
1318 ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
1319 ok(offset==0, "offset not 0 (got %u)!\n", offset);
1321 /* Shaders */
1322 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pVertexDeclaration);
1323 CHECK_CALL(hr, "CreateVertexDeclaration", device, ++refcount);
1324 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &pVertexShader);
1325 CHECK_CALL(hr, "CreateVertexShader", device, ++refcount);
1326 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &pPixelShader);
1327 CHECK_CALL(hr, "CreatePixelShader", device, ++refcount);
1328 /* Textures */
1329 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL);
1330 CHECK_CALL(hr, "CreateTexture", device, ++refcount);
1331 if (pTexture)
1333 tmp = get_refcount( (IUnknown *)pTexture );
1335 /* SetTexture should not increase refcounts */
1336 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)pTexture);
1337 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1338 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1339 CHECK_CALL(hr, "SetTexture", pTexture, tmp);
1341 /* This should not increment device refcount */
1342 hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
1343 CHECK_CALL(hr, "GetSurfaceLevel", device, refcount);
1344 /* But should increment texture's refcount */
1345 CHECK_REFCOUNT( pTexture, tmp+1 );
1346 /* Because the texture and surface refcount are identical */
1347 if (pTextureLevel)
1349 CHECK_REFCOUNT ( pTextureLevel, tmp+1 );
1350 CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
1351 CHECK_REFCOUNT ( pTexture , tmp+2 );
1352 CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
1353 CHECK_REFCOUNT ( pTexture , tmp+1 );
1354 CHECK_RELEASE_REFCOUNT( pTexture , tmp );
1355 CHECK_REFCOUNT ( pTextureLevel, tmp );
1358 hr = IDirect3DDevice9_CreateCubeTexture(device, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL);
1359 CHECK_CALL(hr, "CreateCubeTexture", device, ++refcount);
1360 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 2, 0, 0,
1361 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL);
1362 CHECK_CALL(hr, "CreateVolumeTexture", device, ++refcount);
1363 if (pVolumeTexture)
1365 tmp = get_refcount( (IUnknown *)pVolumeTexture );
1367 /* This should not increment device refcount */
1368 hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
1369 CHECK_CALL(hr, "GetVolumeLevel", device, refcount);
1370 /* But should increment volume texture's refcount */
1371 CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
1372 /* Because the volume texture and volume refcount are identical */
1373 if (pVolumeLevel)
1375 CHECK_REFCOUNT ( pVolumeLevel , tmp+1 );
1376 CHECK_ADDREF_REFCOUNT ( pVolumeLevel , tmp+2 );
1377 CHECK_REFCOUNT ( pVolumeTexture, tmp+2 );
1378 CHECK_RELEASE_REFCOUNT( pVolumeLevel , tmp+1 );
1379 CHECK_REFCOUNT ( pVolumeTexture, tmp+1 );
1380 CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp );
1381 CHECK_REFCOUNT ( pVolumeLevel , tmp );
1384 /* Surfaces */
1385 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32,
1386 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL);
1387 CHECK_CALL(hr, "CreateDepthStencilSurface", device, ++refcount);
1388 CHECK_REFCOUNT( pStencilSurface, 1 );
1389 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1390 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL);
1391 CHECK_CALL(hr, "CreateOffscreenPlainSurface", device, ++refcount);
1392 CHECK_REFCOUNT( pOffscreenSurface, 1 );
1393 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
1394 D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL);
1395 CHECK_CALL(hr, "CreateRenderTarget", device, ++refcount);
1396 CHECK_REFCOUNT( pRenderTarget3, 1 );
1397 /* Misc */
1398 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_ALL, &pStateBlock);
1399 CHECK_CALL(hr, "CreateStateBlock", device, ++refcount);
1401 memset(&d3dpp, 0, sizeof(d3dpp));
1402 d3dpp.Windowed = TRUE;
1403 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1404 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
1405 d3dpp.EnableAutoDepthStencil = TRUE;
1406 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1407 hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &pSwapChain);
1408 CHECK_CALL(hr, "CreateAdditionalSwapChain", device, ++refcount);
1409 if(pSwapChain)
1411 /* check implicit back buffer */
1412 hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
1413 CHECK_CALL(hr, "GetBackBuffer", device, ++refcount);
1414 CHECK_REFCOUNT( pSwapChain, 1);
1415 if(pBackBuffer)
1417 CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
1418 CHECK_REFCOUNT( pBackBuffer, 1);
1419 CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
1420 CHECK_REFCOUNT(device, --refcount);
1422 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
1423 CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
1424 CHECK_REFCOUNT(device, ++refcount);
1425 CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
1426 CHECK_REFCOUNT(device, --refcount);
1427 pBackBuffer = NULL;
1429 CHECK_REFCOUNT( pSwapChain, 1);
1431 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &pQuery);
1432 CHECK_CALL(hr, "CreateQuery", device, ++refcount);
1434 hr = IDirect3DDevice9_BeginStateBlock(device);
1435 CHECK_CALL(hr, "BeginStateBlock", device, refcount);
1436 hr = IDirect3DDevice9_EndStateBlock(device, &pStateBlock1);
1437 CHECK_CALL(hr, "EndStateBlock", device, ++refcount);
1439 /* The implicit render target is not freed if refcount reaches 0.
1440 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
1441 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget2);
1442 CHECK_CALL(hr, "GetRenderTarget", device, ++refcount);
1443 if(pRenderTarget2)
1445 CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
1446 ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
1447 pRenderTarget, pRenderTarget2);
1448 CHECK_REFCOUNT(device, --refcount);
1449 pRenderTarget2 = NULL;
1451 pRenderTarget = NULL;
1453 cleanup:
1454 CHECK_RELEASE(device, device, --refcount);
1456 /* Buffers */
1457 CHECK_RELEASE(pVertexBuffer, device, --refcount);
1458 CHECK_RELEASE(pIndexBuffer, device, --refcount);
1459 /* Shaders */
1460 CHECK_RELEASE(pVertexDeclaration, device, --refcount);
1461 CHECK_RELEASE(pVertexShader, device, --refcount);
1462 CHECK_RELEASE(pPixelShader, device, --refcount);
1463 /* Textures */
1464 CHECK_RELEASE(pTextureLevel, device, --refcount);
1465 CHECK_RELEASE(pCubeTexture, device, --refcount);
1466 CHECK_RELEASE(pVolumeTexture, device, --refcount);
1467 /* Surfaces */
1468 CHECK_RELEASE(pStencilSurface, device, --refcount);
1469 CHECK_RELEASE(pOffscreenSurface, device, --refcount);
1470 CHECK_RELEASE(pRenderTarget3, device, --refcount);
1471 /* Misc */
1472 CHECK_RELEASE(pStateBlock, device, --refcount);
1473 CHECK_RELEASE(pSwapChain, device, --refcount);
1474 CHECK_RELEASE(pQuery, device, --refcount);
1475 /* This will destroy device - cannot check the refcount here */
1476 if (pStateBlock1) CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
1477 CHECK_RELEASE_REFCOUNT(d3d, 0);
1478 DestroyWindow(window);
1481 static void test_cursor(void)
1483 IDirect3DSurface9 *cursor = NULL;
1484 IDirect3DDevice9 *device;
1485 CURSORINFO info;
1486 IDirect3D9 *d3d;
1487 ULONG refcount;
1488 HCURSOR cur;
1489 HWND window;
1490 HRESULT hr;
1492 memset(&info, 0, sizeof(info));
1493 info.cbSize = sizeof(info);
1494 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1495 cur = info.hCursor;
1497 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1498 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1499 ok(!!window, "Failed to create a window.\n");
1500 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1501 ok(!!d3d, "Failed to create a D3D object.\n");
1502 if (!(device = create_device(d3d, window, window, TRUE)))
1504 skip("Failed to create a 3D device, skipping test.\n");
1505 goto cleanup;
1508 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1509 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
1510 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
1512 /* Initially hidden */
1513 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1514 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1516 /* Not enabled without a surface*/
1517 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1518 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1520 /* Fails */
1521 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, NULL);
1522 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
1524 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
1525 ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
1527 IDirect3DSurface9_Release(cursor);
1529 memset(&info, 0, sizeof(info));
1530 info.cbSize = sizeof(info);
1531 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1532 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
1533 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
1535 /* Still hidden */
1536 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1537 ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1539 /* Enabled now*/
1540 hr = IDirect3DDevice9_ShowCursor(device, TRUE);
1541 ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
1543 /* GDI cursor unchanged */
1544 memset(&info, 0, sizeof(info));
1545 info.cbSize = sizeof(info);
1546 ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
1547 ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
1548 ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
1550 refcount = IDirect3DDevice9_Release(device);
1551 ok(!refcount, "Device has %u references left.\n", refcount);
1552 cleanup:
1553 IDirect3D9_Release(d3d);
1554 DestroyWindow(window);
1557 static void test_reset(void)
1559 HRESULT hr;
1560 RECT winrect;
1561 D3DPRESENT_PARAMETERS d3dpp;
1562 D3DDISPLAYMODE d3ddm, d3ddm2;
1563 D3DVIEWPORT9 vp;
1564 DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
1565 DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
1566 IDirect3DSwapChain9 *pSwapchain;
1567 IDirect3DSurface9 *surface;
1568 IDirect3DTexture9 *texture;
1569 IDirect3DVertexShader9 *shader;
1570 UINT i, adapter_mode_count;
1571 D3DLOCKED_RECT lockrect;
1572 IDirect3DDevice9 *device1 = NULL;
1573 IDirect3DDevice9 *device2 = NULL;
1574 IDirect3D9 *d3d;
1575 D3DCAPS9 caps;
1576 DWORD value;
1577 HWND hwnd;
1578 struct
1580 UINT w;
1581 UINT h;
1582 } *modes = NULL;
1583 UINT mode_count = 0;
1585 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1586 100, 100, 160, 160, NULL, NULL, NULL, NULL);
1587 ok(!!hwnd, "Failed to create a window.\n");
1588 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1589 ok(!!d3d, "Failed to create a D3D object.\n");
1591 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
1592 adapter_mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, d3ddm.Format);
1593 modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
1594 for(i = 0; i < adapter_mode_count; ++i)
1596 UINT j;
1597 ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
1598 hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
1599 ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#x\n", hr);
1601 for (j = 0; j < mode_count; ++j)
1603 if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
1604 break;
1606 if (j == mode_count)
1608 modes[j].w = d3ddm2.Width;
1609 modes[j].h = d3ddm2.Height;
1610 ++mode_count;
1613 /* We use them as invalid modes */
1614 if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
1615 (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
1616 skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
1617 d3ddm2.Width, d3ddm2.Height);
1618 goto cleanup;
1622 if (mode_count < 2)
1624 skip("Less than 2 modes supported, skipping mode tests\n");
1625 goto cleanup;
1628 i = 0;
1629 if (modes[i].w == orig_width && modes[i].h == orig_height) ++i;
1631 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1632 d3dpp.Windowed = FALSE;
1633 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1634 d3dpp.BackBufferWidth = modes[i].w;
1635 d3dpp.BackBufferHeight = modes[i].h;
1636 d3dpp.BackBufferFormat = d3ddm.Format;
1637 d3dpp.EnableAutoDepthStencil = TRUE;
1638 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1640 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1641 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device1);
1642 if (FAILED(hr))
1644 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1645 goto cleanup;
1647 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1648 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1650 hr = IDirect3DDevice9_GetDeviceCaps(device1, &caps);
1651 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
1653 width = GetSystemMetrics(SM_CXSCREEN);
1654 height = GetSystemMetrics(SM_CYSCREEN);
1655 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1656 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1658 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1659 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1660 if(SUCCEEDED(hr))
1662 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1663 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1664 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1665 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1666 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1667 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1670 i = 1;
1671 vp.X = 10;
1672 vp.Y = 20;
1673 vp.MinZ = 2;
1674 vp.MaxZ = 3;
1675 hr = IDirect3DDevice9_SetViewport(device1, &vp);
1676 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1678 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1679 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1680 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1681 hr = IDirect3DDevice9_SetRenderState(device1, D3DRS_LIGHTING, FALSE);
1682 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1684 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1685 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1686 d3dpp.Windowed = FALSE;
1687 d3dpp.BackBufferWidth = modes[i].w;
1688 d3dpp.BackBufferHeight = modes[i].h;
1689 d3dpp.BackBufferFormat = d3ddm.Format;
1690 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1691 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1692 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1693 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1695 hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1696 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1697 ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1699 ZeroMemory(&vp, sizeof(vp));
1700 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1701 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1702 if(SUCCEEDED(hr))
1704 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1705 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1706 ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1707 ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1708 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1709 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1712 width = GetSystemMetrics(SM_CXSCREEN);
1713 height = GetSystemMetrics(SM_CYSCREEN);
1714 ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1715 ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1717 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1718 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1719 if(SUCCEEDED(hr))
1721 ZeroMemory(&d3dpp, sizeof(d3dpp));
1722 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1723 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1724 if(SUCCEEDED(hr))
1726 ok(d3dpp.BackBufferWidth == modes[i].w, "Back buffer width is %u, expected %u\n",
1727 d3dpp.BackBufferWidth, modes[i].w);
1728 ok(d3dpp.BackBufferHeight == modes[i].h, "Back buffer height is %u, expected %u\n",
1729 d3dpp.BackBufferHeight, modes[i].h);
1731 IDirect3DSwapChain9_Release(pSwapchain);
1734 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1735 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1736 d3dpp.Windowed = TRUE;
1737 d3dpp.BackBufferWidth = 400;
1738 d3dpp.BackBufferHeight = 300;
1739 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1740 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1741 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1742 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1744 width = GetSystemMetrics(SM_CXSCREEN);
1745 height = GetSystemMetrics(SM_CYSCREEN);
1746 ok(width == orig_width, "Screen width is %d\n", width);
1747 ok(height == orig_height, "Screen height is %d\n", height);
1749 ZeroMemory(&vp, sizeof(vp));
1750 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1751 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1752 if(SUCCEEDED(hr))
1754 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1755 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1756 ok(vp.Width == 400, "D3DVIEWPORT->Width = %d\n", vp.Width);
1757 ok(vp.Height == 300, "D3DVIEWPORT->Height = %d\n", vp.Height);
1758 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1759 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1762 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1763 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1764 if(SUCCEEDED(hr))
1766 ZeroMemory(&d3dpp, sizeof(d3dpp));
1767 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1768 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1769 if(SUCCEEDED(hr))
1771 ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1772 ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1774 IDirect3DSwapChain9_Release(pSwapchain);
1777 winrect.left = 0;
1778 winrect.top = 0;
1779 winrect.right = 200;
1780 winrect.bottom = 150;
1781 ok(AdjustWindowRect(&winrect, WS_OVERLAPPEDWINDOW, FALSE), "AdjustWindowRect failed\n");
1782 ok(SetWindowPos(hwnd, NULL, 0, 0,
1783 winrect.right-winrect.left,
1784 winrect.bottom-winrect.top,
1785 SWP_NOMOVE|SWP_NOZORDER),
1786 "SetWindowPos failed\n");
1788 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1789 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1790 d3dpp.Windowed = TRUE;
1791 d3dpp.BackBufferWidth = 0;
1792 d3dpp.BackBufferHeight = 0;
1793 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1794 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1795 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1796 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1798 ZeroMemory(&vp, sizeof(vp));
1799 hr = IDirect3DDevice9_GetViewport(device1, &vp);
1800 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1801 if(SUCCEEDED(hr))
1803 ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1804 ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1805 ok(vp.Width == 200, "D3DVIEWPORT->Width = %d\n", vp.Width);
1806 ok(vp.Height == 150, "D3DVIEWPORT->Height = %d\n", vp.Height);
1807 ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1808 ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1811 hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1812 ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1813 if(SUCCEEDED(hr))
1815 ZeroMemory(&d3dpp, sizeof(d3dpp));
1816 hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1817 ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1818 if(SUCCEEDED(hr))
1820 ok(d3dpp.BackBufferWidth == 200, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1821 ok(d3dpp.BackBufferHeight == 150, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1823 IDirect3DSwapChain9_Release(pSwapchain);
1826 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1827 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1828 d3dpp.Windowed = TRUE;
1829 d3dpp.BackBufferWidth = 400;
1830 d3dpp.BackBufferHeight = 300;
1832 /* _Reset fails if there is a resource in the default pool */
1833 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1834 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1835 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1836 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1837 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1838 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1839 IDirect3DSurface9_Release(surface);
1840 /* Reset again to get the device out of the lost state */
1841 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1842 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1843 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1844 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1846 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1848 IDirect3DVolumeTexture9 *volume_texture;
1850 hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
1851 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1852 ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#x.\n", hr);
1853 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1854 ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
1855 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1856 ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n",
1857 hr, D3DERR_DEVICENOTRESET);
1858 IDirect3DVolumeTexture9_Release(volume_texture);
1859 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1860 ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
1861 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1862 ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#x.\n", hr);
1864 else
1866 skip("Volume textures not supported.\n");
1869 /* Scratch, sysmem and managed pools are fine */
1870 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1871 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1872 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1873 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1874 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1875 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1876 IDirect3DSurface9_Release(surface);
1878 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1879 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1880 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1881 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1882 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1883 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1884 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1885 IDirect3DSurface9_Release(surface);
1887 /* The depth stencil should get reset to the auto depth stencil when present. */
1888 hr = IDirect3DDevice9_SetDepthStencilSurface(device1, NULL);
1889 ok(hr == D3D_OK, "SetDepthStencilSurface failed with 0x%08x\n", hr);
1891 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1892 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1893 ok(surface == NULL, "Depth stencil should be NULL\n");
1895 d3dpp.EnableAutoDepthStencil = TRUE;
1896 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1897 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1898 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1900 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1901 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1902 ok(surface != NULL, "Depth stencil should not be NULL\n");
1903 if (surface) IDirect3DSurface9_Release(surface);
1905 d3dpp.EnableAutoDepthStencil = FALSE;
1906 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1907 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1909 hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1910 ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1911 ok(surface == NULL, "Depth stencil should be NULL\n");
1913 /* Will a sysmem or scratch survive while locked */
1914 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1915 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1916 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1917 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1918 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1919 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1920 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1921 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1922 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1923 IDirect3DSurface9_UnlockRect(surface);
1924 IDirect3DSurface9_Release(surface);
1926 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1927 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1928 hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1929 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1930 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1931 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1932 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1933 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1934 IDirect3DSurface9_UnlockRect(surface);
1935 IDirect3DSurface9_Release(surface);
1937 hr = IDirect3DDevice9_CreateTexture(device1, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
1938 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
1939 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1940 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1941 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1942 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1943 IDirect3DTexture9_Release(texture);
1945 /* A reference held to an implicit surface causes failures as well */
1946 hr = IDirect3DDevice9_GetBackBuffer(device1, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1947 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr);
1948 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1949 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1950 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1951 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1952 IDirect3DSurface9_Release(surface);
1953 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1954 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1955 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1956 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1958 /* Shaders are fine as well */
1959 hr = IDirect3DDevice9_CreateVertexShader(device1, simple_vs, &shader);
1960 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
1961 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1962 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1963 IDirect3DVertexShader9_Release(shader);
1965 /* Try setting invalid modes */
1966 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1967 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1968 d3dpp.Windowed = FALSE;
1969 d3dpp.BackBufferWidth = 32;
1970 d3dpp.BackBufferHeight = 32;
1971 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1972 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr);
1973 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1974 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1976 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1977 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1978 d3dpp.Windowed = FALSE;
1979 d3dpp.BackBufferWidth = 801;
1980 d3dpp.BackBufferHeight = 600;
1981 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1982 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr);
1983 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1984 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1986 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1987 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1988 d3dpp.Windowed = FALSE;
1989 d3dpp.BackBufferWidth = 0;
1990 d3dpp.BackBufferHeight = 0;
1991 hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1992 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=0, h=0, windowed=FALSE failed with %08x\n", hr);
1993 hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1994 ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1996 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
1998 ZeroMemory( &d3dpp, sizeof(d3dpp) );
1999 d3dpp.Windowed = TRUE;
2000 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2001 d3dpp.BackBufferFormat = d3ddm.Format;
2002 d3dpp.EnableAutoDepthStencil = FALSE;
2003 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2005 if (FAILED(hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2006 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2)))
2008 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
2009 goto cleanup;
2012 hr = IDirect3DDevice9_TestCooperativeLevel(device2);
2013 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
2015 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2016 d3dpp.Windowed = TRUE;
2017 d3dpp.BackBufferWidth = 400;
2018 d3dpp.BackBufferHeight = 300;
2019 d3dpp.EnableAutoDepthStencil = TRUE;
2020 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
2022 hr = IDirect3DDevice9_Reset(device2, &d3dpp);
2023 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
2025 if (FAILED(hr)) goto cleanup;
2027 hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
2028 ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
2029 ok(surface != NULL, "Depth stencil should not be NULL\n");
2030 if (surface) IDirect3DSurface9_Release(surface);
2032 cleanup:
2033 HeapFree(GetProcessHeap(), 0, modes);
2034 if (device2)
2036 UINT refcount = IDirect3DDevice9_Release(device2);
2037 ok(!refcount, "Device has %u references left.\n", refcount);
2039 if (device1)
2041 UINT refcount = IDirect3DDevice9_Release(device1);
2042 ok(!refcount, "Device has %u references left.\n", refcount);
2044 IDirect3D9_Release(d3d);
2045 DestroyWindow(hwnd);
2048 /* Test adapter display modes */
2049 static void test_display_modes(void)
2051 D3DDISPLAYMODE dmode;
2052 IDirect3D9 *d3d;
2054 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2055 ok(!!d3d, "Failed to create a D3D object.\n");
2057 #define TEST_FMT(x,r) do { \
2058 HRESULT res = IDirect3D9_EnumAdapterModes(d3d, 0, (x), 0, &dmode); \
2059 ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
2060 } while(0)
2062 TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
2063 TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
2064 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2065 /* D3DFMT_R5G6B5 */
2066 TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
2067 TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
2068 TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
2069 TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
2070 TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
2071 TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
2072 TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
2073 TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
2074 TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
2075 TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
2076 TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
2077 TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
2079 TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
2080 TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
2082 TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
2083 TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
2084 TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
2086 TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
2087 TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
2088 TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
2089 TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
2090 TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
2091 TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
2093 TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
2094 TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
2095 TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
2096 TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
2097 TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
2098 TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
2099 TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
2100 TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
2101 TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
2102 TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
2104 TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
2105 TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
2106 TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
2107 TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
2108 TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
2109 TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
2110 TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
2111 TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
2112 TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
2113 TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
2115 TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
2116 TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
2117 TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
2118 TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
2119 /* Floating point formats */
2120 TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
2121 TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
2122 TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
2124 /* IEEE formats */
2125 TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
2126 TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
2127 TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
2129 TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
2131 TEST_FMT(0, D3DERR_INVALIDCALL);
2133 IDirect3D9_Release(d3d);
2136 static void test_scene(void)
2138 IDirect3DSurface9 *surface1, *surface2, *surface3;
2139 IDirect3DSurface9 *backBuffer, *rt, *ds;
2140 RECT rect = {0, 0, 128, 128};
2141 IDirect3DDevice9 *device;
2142 IDirect3D9 *d3d;
2143 ULONG refcount;
2144 D3DCAPS9 caps;
2145 HWND window;
2146 HRESULT hr;
2148 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2149 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2150 ok(!!window, "Failed to create a window.\n");
2151 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2152 ok(!!d3d, "Failed to create a D3D object.\n");
2153 if (!(device = create_device(d3d, window, window, TRUE)))
2155 skip("Failed to create a 3D device, skipping test.\n");
2156 goto cleanup;
2159 /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
2160 memset(&caps, 0, sizeof(caps));
2161 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2162 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
2164 /* Test an EndScene without BeginScene. Should return an error */
2165 hr = IDirect3DDevice9_EndScene(device);
2166 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2168 /* Test a normal BeginScene / EndScene pair, this should work */
2169 hr = IDirect3DDevice9_BeginScene(device);
2170 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2171 hr = IDirect3DDevice9_EndScene(device);
2172 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2174 /* Test another EndScene without having begun a new scene. Should return an error */
2175 hr = IDirect3DDevice9_EndScene(device);
2176 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2178 /* Two nested BeginScene and EndScene calls */
2179 hr = IDirect3DDevice9_BeginScene(device);
2180 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2181 hr = IDirect3DDevice9_BeginScene(device);
2182 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
2183 hr = IDirect3DDevice9_EndScene(device);
2184 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2185 hr = IDirect3DDevice9_EndScene(device);
2186 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
2188 /* Create some surfaces to test stretchrect between the scenes */
2189 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2190 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface1, NULL);
2191 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2192 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2193 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface2, NULL);
2194 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2195 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 800, 600,
2196 D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &surface3, NULL);
2197 ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
2198 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
2199 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
2200 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
2202 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
2203 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
2204 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
2205 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
2207 /* First make sure a simple StretchRect call works */
2208 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2209 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2210 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2211 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2212 if (0) /* Disabled for now because it crashes in wine */
2214 HRESULT expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
2215 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2216 ok(hr == expected, "Got unexpected hr %#x, expected %#x.\n", hr, expected);
2219 /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a
2220 * BeginScene - Endscene pair with normal surfaces and render targets, but
2221 * not depth stencil surfaces. */
2222 hr = IDirect3DDevice9_BeginScene(device);
2223 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2225 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, surface2, NULL, 0);
2226 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2227 hr = IDirect3DDevice9_StretchRect(device, backBuffer, &rect, rt, NULL, 0);
2228 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2229 /* This is supposed to fail inside a BeginScene - EndScene pair. */
2230 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, surface3, NULL, 0);
2231 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
2233 hr = IDirect3DDevice9_EndScene(device);
2234 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2236 /* Does a SetRenderTarget influence BeginScene / EndScene ?
2237 * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
2238 * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
2240 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
2241 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
2242 hr = IDirect3DDevice9_BeginScene(device);
2243 ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2244 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backBuffer);
2245 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
2246 hr = IDirect3DDevice9_EndScene(device);
2247 ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2249 IDirect3DSurface9_Release(rt);
2250 IDirect3DSurface9_Release(ds);
2251 IDirect3DSurface9_Release(backBuffer);
2252 IDirect3DSurface9_Release(surface1);
2253 IDirect3DSurface9_Release(surface2);
2254 IDirect3DSurface9_Release(surface3);
2255 refcount = IDirect3DDevice9_Release(device);
2256 ok(!refcount, "Device has %u references left.\n", refcount);
2257 cleanup:
2258 IDirect3D9_Release(d3d);
2259 DestroyWindow(window);
2262 static void test_limits(void)
2264 IDirect3DTexture9 *texture;
2265 IDirect3DDevice9 *device;
2266 IDirect3D9 *d3d;
2267 unsigned int i;
2268 ULONG refcount;
2269 HWND window;
2270 HRESULT hr;
2272 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2273 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2274 ok(!!window, "Failed to create a window.\n");
2275 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2276 ok(!!d3d, "Failed to create a D3D object.\n");
2277 if (!(device = create_device(d3d, window, window, TRUE)))
2279 skip("Failed to create a 3D device, skipping test.\n");
2280 goto cleanup;
2283 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
2284 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2286 /* There are 16 pixel samplers. We should be able to access all of them */
2287 for (i = 0; i < 16; ++i)
2289 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture);
2290 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
2291 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
2292 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
2293 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_SRGBTEXTURE, TRUE);
2294 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
2297 /* Now test all 8 textures stage states */
2298 for (i = 0; i < 8; ++i)
2300 hr = IDirect3DDevice9_SetTextureStageState(device, i, D3DTSS_COLOROP, D3DTOP_ADD);
2301 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
2304 /* Investigations show that accessing higher samplers / textures stage
2305 * states does not return an error either. Writing to too high samplers
2306 * (approximately sampler 40) causes memory corruption in Windows, so
2307 * there is no bounds checking. */
2308 IDirect3DTexture9_Release(texture);
2309 refcount = IDirect3D9_Release(device);
2310 ok(!refcount, "Device has %u references left.\n", refcount);
2311 cleanup:
2312 IDirect3D9_Release(d3d);
2313 DestroyWindow(window);
2316 static void test_depthstenciltest(void)
2318 HRESULT hr;
2319 IDirect3DDevice9 *pDevice = NULL;
2320 D3DPRESENT_PARAMETERS d3dpp;
2321 D3DDISPLAYMODE d3ddm;
2322 IDirect3DSurface9 *pDepthStencil = NULL;
2323 IDirect3DSurface9 *pDepthStencil2 = NULL;
2324 IDirect3D9 *d3d;
2325 DWORD state;
2326 HWND hwnd;
2328 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2329 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2330 ok(!!hwnd, "Failed to create a window.\n");
2331 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2332 ok(!!d3d, "Failed to create a D3D object.\n");
2334 IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
2335 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2336 d3dpp.Windowed = TRUE;
2337 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2338 d3dpp.BackBufferWidth = 800;
2339 d3dpp.BackBufferHeight = 600;
2340 d3dpp.BackBufferFormat = d3ddm.Format;
2341 d3dpp.EnableAutoDepthStencil = TRUE;
2342 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2344 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2345 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2346 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || broken(hr == D3DERR_INVALIDCALL), "IDirect3D9_CreateDevice failed with %08x\n", hr);
2347 if(!pDevice)
2349 skip("Failed to create a d3d device\n");
2350 goto cleanup;
2353 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2354 ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
2356 /* Try to clear */
2357 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2358 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2360 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
2361 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
2363 /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
2364 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
2365 ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
2366 if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
2368 /* This left the render states untouched! */
2369 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2370 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2371 ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2372 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
2373 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2374 ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
2375 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
2376 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2377 ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
2378 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
2379 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2380 ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
2382 /* This is supposed to fail now */
2383 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2384 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2386 hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
2387 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
2389 hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
2390 ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
2392 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2393 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2394 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2396 /* Now it works again */
2397 hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
2398 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2400 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2401 if(pDevice) IDirect3D9_Release(pDevice);
2403 /* Now see if autodepthstencil disable is honored. First, without a format set */
2404 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2405 d3dpp.Windowed = TRUE;
2406 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2407 d3dpp.BackBufferWidth = 800;
2408 d3dpp.BackBufferHeight = 600;
2409 d3dpp.BackBufferFormat = d3ddm.Format;
2410 d3dpp.EnableAutoDepthStencil = FALSE;
2411 d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
2413 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2414 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2415 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2416 if(!pDevice)
2418 skip("Failed to create a d3d device\n");
2419 goto cleanup;
2422 pDepthStencil = NULL;
2423 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2424 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
2425 if(pDepthStencil) {
2426 IDirect3DSurface9_Release(pDepthStencil);
2427 pDepthStencil = NULL;
2430 /* Check the depth test state */
2431 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2432 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2433 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2435 if(pDevice) IDirect3D9_Release(pDevice);
2437 /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
2438 ZeroMemory( &d3dpp, sizeof(d3dpp) );
2439 d3dpp.Windowed = TRUE;
2440 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2441 d3dpp.BackBufferWidth = 800;
2442 d3dpp.BackBufferHeight = 600;
2443 d3dpp.BackBufferFormat = d3ddm.Format;
2444 d3dpp.EnableAutoDepthStencil = FALSE;
2445 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
2447 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */,
2448 hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
2449 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2450 if(!pDevice)
2452 skip("Failed to create a d3d device\n");
2453 goto cleanup;
2456 pDepthStencil = NULL;
2457 hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
2458 ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
2459 if(pDepthStencil) {
2460 IDirect3DSurface9_Release(pDepthStencil);
2461 pDepthStencil = NULL;
2464 hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
2465 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
2466 ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
2468 cleanup:
2469 if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
2470 if (pDevice)
2472 UINT refcount = IDirect3D9_Release(pDevice);
2473 ok(!refcount, "Device has %u references left.\n", refcount);
2475 IDirect3D9_Release(d3d);
2476 DestroyWindow(hwnd);
2479 static void test_get_rt(void)
2481 IDirect3DSurface9 *backbuffer, *rt;
2482 IDirect3DDevice9 *device;
2483 IDirect3D9 *d3d9;
2484 D3DCAPS9 caps;
2485 HWND window;
2486 HRESULT hr;
2487 ULONG ref;
2488 UINT i;
2490 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2491 0, 0, 128, 128, 0, 0, 0, 0);
2492 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2493 ok(!!d3d9, "Failed to create a D3D object.\n");
2494 device = create_device(d3d9, window, window, TRUE);
2495 if (!device)
2497 skip("Failed to create a D3D device, skipping tests.\n");
2498 goto done;
2501 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
2502 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
2503 ok(!!backbuffer, "Got a NULL backbuffer.\n");
2505 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2506 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2508 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
2510 rt = backbuffer;
2511 hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
2512 ok(hr == D3DERR_NOTFOUND, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr);
2513 ok(!rt, "Got rt %p.\n", rt);
2516 IDirect3DSurface9_Release(backbuffer);
2518 ref = IDirect3DDevice9_Release(device);
2519 ok(!ref, "The device was not properly freed: refcount %u.\n", ref);
2520 done:
2521 IDirect3D9_Release(d3d9);
2522 DestroyWindow(window);
2525 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
2526 static void test_draw_indexed(void)
2528 static const struct {
2529 float position[3];
2530 DWORD color;
2531 } quad[] = {
2532 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2533 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2534 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2535 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2537 WORD indices[] = {0, 1, 2, 3, 0, 2};
2539 static const D3DVERTEXELEMENT9 decl_elements[] = {
2540 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2541 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2542 D3DDECL_END()
2545 IDirect3DVertexDeclaration9 *vertex_declaration;
2546 IDirect3DVertexBuffer9 *vertex_buffer;
2547 IDirect3DIndexBuffer9 *index_buffer;
2548 IDirect3DDevice9 *device;
2549 IDirect3D9 *d3d9;
2550 ULONG refcount;
2551 HWND window;
2552 HRESULT hr;
2553 void *ptr;
2555 window = CreateWindowA("d3d9_test_wc", "d3d9_test", 0,
2556 0, 0, 640, 480, 0, 0, 0, 0);
2557 ok(!!window, "Failed to create a window.\n");
2558 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2559 ok(!!d3d9, "Failed to create a D3D object.\n");
2560 if (!(device = create_device(d3d9, window, window, TRUE)))
2562 skip("Failed to create a 3D device, skipping test.\n");
2563 goto cleanup;
2566 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2567 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2568 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2569 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2571 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
2572 ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
2573 hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
2574 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
2575 memcpy(ptr, quad, sizeof(quad));
2576 hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
2577 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
2578 hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
2579 ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
2581 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
2582 ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
2583 hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
2584 ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
2585 memcpy(ptr, indices, sizeof(indices));
2586 hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
2587 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
2588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2589 ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
2590 hr = IDirect3DDevice9_BeginScene(device);
2591 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2593 /* NULL index buffer. Should fail */
2594 hr = IDirect3DDevice9_SetIndices(device, NULL);
2595 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
2596 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2597 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2598 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
2599 hr, D3DERR_INVALIDCALL);
2601 /* Valid index buffer, NULL vertex declaration. Should fail */
2602 hr = IDirect3DDevice9_SetIndices(device, index_buffer);
2603 ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
2604 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2605 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2606 ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
2607 hr, D3DERR_INVALIDCALL);
2609 /* Valid index buffer and vertex declaration. Should succeed */
2610 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2611 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2612 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
2613 4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
2614 ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
2616 hr = IDirect3DDevice9_EndScene(device);
2617 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2619 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2620 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2622 IDirect3DVertexBuffer9_Release(vertex_buffer);
2623 IDirect3DIndexBuffer9_Release(index_buffer);
2624 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2625 refcount = IDirect3DDevice9_Release(device);
2626 ok(!refcount, "Device has %u references left.\n", refcount);
2627 cleanup:
2628 IDirect3D9_Release(d3d9);
2629 DestroyWindow(window);
2632 static void test_null_stream(void)
2634 IDirect3DVertexBuffer9 *buffer = NULL;
2635 IDirect3DDevice9 *device;
2636 IDirect3D9 *d3d9;
2637 ULONG refcount;
2638 HWND window;
2639 HRESULT hr;
2640 IDirect3DVertexShader9 *shader = NULL;
2641 IDirect3DVertexDeclaration9 *decl = NULL;
2642 static const DWORD shader_code[] =
2644 0xfffe0101, /* vs_1_1 */
2645 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2646 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2647 0x0000ffff /* end */
2649 static const D3DVERTEXELEMENT9 decl_elements[] = {
2650 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2651 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2652 D3DDECL_END()
2655 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2656 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2657 ok(!!window, "Failed to create a window.\n");
2658 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2659 ok(!!d3d9, "Failed to create a D3D object.\n");
2660 if (!(device = create_device(d3d9, window, window, TRUE)))
2662 skip("Failed to create a 3D device, skipping test.\n");
2663 goto cleanup;
2666 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2667 if(FAILED(hr)) {
2668 skip("No vertex shader support\n");
2669 goto cleanup;
2671 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2672 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2673 if (FAILED(hr)) {
2674 skip("Vertex declaration handling not possible.\n");
2675 goto cleanup;
2677 hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
2678 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
2679 if (FAILED(hr)) {
2680 skip("Vertex buffer handling not possible.\n");
2681 goto cleanup;
2684 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
2685 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2686 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
2687 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2688 hr = IDirect3DDevice9_SetVertexShader(device, shader);
2689 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
2690 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2691 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
2693 hr = IDirect3DDevice9_BeginScene(device);
2694 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2695 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
2696 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2697 hr = IDirect3DDevice9_EndScene(device);
2698 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2700 IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2701 IDirect3DDevice9_SetVertexShader(device, NULL);
2702 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2704 cleanup:
2705 if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2706 if (decl) IDirect3DVertexDeclaration9_Release(decl);
2707 if (shader) IDirect3DVertexShader9_Release(shader);
2708 if (device)
2710 refcount = IDirect3DDevice9_Release(device);
2711 ok(!refcount, "Device has %u references left.\n", refcount);
2713 IDirect3D9_Release(d3d9);
2714 DestroyWindow(window);
2717 static void test_lights(void)
2719 IDirect3DDevice9 *device;
2720 IDirect3D9 *d3d9;
2721 ULONG refcount;
2722 HWND window;
2723 HRESULT hr;
2724 unsigned int i;
2725 BOOL enabled;
2726 D3DCAPS9 caps;
2728 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2729 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2730 ok(!!window, "Failed to create a window.\n");
2731 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2732 ok(!!d3d9, "Failed to create a D3D object.\n");
2733 if (!(device = create_device(d3d9, window, window, TRUE)))
2735 skip("Failed to create a 3D device, skipping test.\n");
2736 goto cleanup;
2739 memset(&caps, 0, sizeof(caps));
2740 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2741 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
2743 for(i = 1; i <= caps.MaxActiveLights; i++) {
2744 hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
2745 ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
2746 hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
2747 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
2748 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
2751 /* TODO: Test the rendering results in this situation */
2752 hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
2753 ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
2754 hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
2755 ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
2756 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
2757 hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
2758 ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
2760 for(i = 1; i <= caps.MaxActiveLights; i++) {
2761 hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
2762 ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
2765 refcount = IDirect3DDevice9_Release(device);
2766 ok(!refcount, "Device has %u references left.\n", refcount);
2767 cleanup:
2768 IDirect3D9_Release(d3d9);
2769 DestroyWindow(window);
2772 static void test_set_stream_source(void)
2774 IDirect3DVertexBuffer9 *vb;
2775 IDirect3DDevice9 *device;
2776 IDirect3D9 *d3d9;
2777 ULONG refcount;
2778 HWND window;
2779 HRESULT hr;
2781 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
2782 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2783 ok(!!window, "Failed to create a window.\n");
2784 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2785 ok(!!d3d9, "Failed to create a D3D object.\n");
2786 if (!(device = create_device(d3d9, window, window, TRUE)))
2788 skip("Failed to create a 3D device, skipping test.\n");
2789 goto cleanup;
2792 hr = IDirect3DDevice9_CreateVertexBuffer(device, 512, 0, 0, D3DPOOL_DEFAULT, &vb, NULL);
2793 ok(SUCCEEDED(hr), "Failed to create a vertex buffer, hr %#x.\n", hr);
2795 /* Some cards (GeForce 7400 at least) accept non-aligned offsets, others
2796 * (Radeon 9000 verified) reject them, so accept both results. Wine
2797 * currently rejects this to be able to optimize the vbo conversion, but
2798 * writes a WARN. */
2799 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, 32);
2800 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2801 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 1, 32);
2802 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2803 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 2, 32);
2804 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2805 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 3, 32);
2806 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2807 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 4, 32);
2808 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2810 /* Try to set the NULL buffer with an offset and stride 0 */
2811 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2812 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2813 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
2814 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2815 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
2816 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2817 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
2818 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2819 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
2820 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2822 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2823 ok(SUCCEEDED(hr), "Failed to set the stream source, hr %#x.\n", hr);
2825 IDirect3DVertexBuffer9_Release(vb);
2826 refcount = IDirect3DDevice9_Release(device);
2827 ok(!refcount, "Device has %u references left.\n", refcount);
2828 cleanup:
2829 IDirect3D9_Release(d3d9);
2830 DestroyWindow(window);
2833 /* Direct3D9 offers 4 display formats: R5G6B5, X1R5G5B5, X8R8G8B8 and
2834 * A2R10G10B10. Next to these there are 6 different back buffer formats. Only
2835 * a fixed number of combinations are possible in fullscreen mode. In windowed
2836 * mode more combinations are allowed due to format conversion and this is
2837 * likely driver dependent. */
2838 static void test_display_formats(void)
2840 D3DDEVTYPE device_type = D3DDEVTYPE_HAL;
2841 unsigned int backbuffer, display;
2842 unsigned int windowed;
2843 IDirect3D9 *d3d9;
2844 BOOL should_pass;
2845 BOOL has_modes;
2846 HRESULT hr;
2848 static const struct
2850 const char *name;
2851 D3DFORMAT format;
2852 D3DFORMAT alpha_format;
2853 BOOL display;
2854 BOOL windowed;
2856 formats[] =
2858 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, 0, TRUE, TRUE},
2859 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE, TRUE},
2860 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE, FALSE},
2861 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE, TRUE},
2862 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, FALSE},
2863 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, 0, TRUE, FALSE},
2864 {"D3DFMT_UNKNOWN", D3DFMT_UNKNOWN, 0, FALSE, FALSE},
2867 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
2868 ok(!!d3d9, "Failed to create a D3D object.\n");
2870 for (display = 0; display < sizeof(formats) / sizeof(*formats); ++display)
2872 has_modes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, formats[display].format);
2874 for (windowed = 0; windowed <= 1; ++windowed)
2876 for (backbuffer = 0; backbuffer < sizeof(formats) / sizeof(*formats); ++backbuffer)
2878 should_pass = FALSE;
2880 if (formats[display].display && (formats[display].windowed || !windowed) && (has_modes || windowed))
2882 D3DFORMAT backbuffer_format;
2884 if (windowed && formats[backbuffer].format == D3DFMT_UNKNOWN)
2885 backbuffer_format = formats[display].format;
2886 else
2887 backbuffer_format = formats[backbuffer].format;
2889 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, device_type, formats[display].format,
2890 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, backbuffer_format);
2891 if (hr == D3D_OK)
2893 if (windowed)
2895 hr = IDirect3D9_CheckDeviceFormatConversion(d3d9, D3DADAPTER_DEFAULT, device_type,
2896 backbuffer_format, formats[display].format);
2897 should_pass = (hr == D3D_OK);
2899 else
2900 should_pass = (formats[display].format == formats[backbuffer].format
2901 || (formats[display].alpha_format
2902 && formats[display].alpha_format == formats[backbuffer].alpha_format));
2906 hr = IDirect3D9_CheckDeviceType(d3d9, D3DADAPTER_DEFAULT, device_type,
2907 formats[display].format, formats[backbuffer].format, windowed);
2908 ok(SUCCEEDED(hr) == should_pass || broken(SUCCEEDED(hr) && !has_modes) /* Win8 64-bit */,
2909 "Got unexpected hr %#x for %s / %s, windowed %#x, should_pass %#x.\n",
2910 hr, formats[display].name, formats[backbuffer].name, windowed, should_pass);
2915 IDirect3D9_Release(d3d9);
2918 static void test_scissor_size(void)
2920 IDirect3D9 *d3d9_ptr;
2921 unsigned int i;
2922 static struct {
2923 int winx; int winy; int backx; int backy; BOOL window;
2924 } scts[] = { /* scissor tests */
2925 {800, 600, 640, 480, TRUE},
2926 {800, 600, 640, 480, FALSE},
2927 {640, 480, 800, 600, TRUE},
2928 {640, 480, 800, 600, FALSE},
2931 d3d9_ptr = Direct3DCreate9(D3D_SDK_VERSION);
2932 ok(!!d3d9_ptr, "Failed to create a D3D object.\n");
2934 for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2935 IDirect3DDevice9 *device_ptr = 0;
2936 D3DPRESENT_PARAMETERS present_parameters;
2937 HRESULT hr;
2938 HWND hwnd = 0;
2939 RECT scissorrect;
2941 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION,
2942 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
2944 if (!scts[i].window)
2946 scts[i].backx = screen_width;
2947 scts[i].backy = screen_height;
2950 ZeroMemory(&present_parameters, sizeof(present_parameters));
2951 present_parameters.Windowed = scts[i].window;
2952 present_parameters.hDeviceWindow = hwnd;
2953 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2954 present_parameters.BackBufferWidth = scts[i].backx;
2955 present_parameters.BackBufferHeight = scts[i].backy;
2956 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
2957 present_parameters.EnableAutoDepthStencil = TRUE;
2958 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
2960 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2961 if(FAILED(hr)) {
2962 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
2963 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2964 if(FAILED(hr)) {
2965 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2968 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
2970 if (!device_ptr)
2972 DestroyWindow(hwnd);
2973 skip("Creating the device failed\n");
2974 goto err_out;
2977 /* Check for the default scissor rect size */
2978 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2979 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2980 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);
2982 /* check the scissorrect values after a reset */
2983 present_parameters.BackBufferWidth = screen_width;
2984 present_parameters.BackBufferHeight = screen_height;
2985 hr = IDirect3DDevice9_Reset(device_ptr, &present_parameters);
2986 ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2987 hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
2988 ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2990 hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2991 ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2992 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);
2994 if(device_ptr) {
2995 ULONG ref;
2997 ref = IDirect3DDevice9_Release(device_ptr);
2998 DestroyWindow(hwnd);
2999 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
3003 err_out:
3004 IDirect3D9_Release(d3d9_ptr);
3007 static void test_multi_device(void)
3009 IDirect3DDevice9 *device1, *device2;
3010 HWND window1, window2;
3011 IDirect3D9 *d3d9;
3012 ULONG refcount;
3014 window1 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3015 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3016 ok(!!window1, "Failed to create a window.\n");
3017 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3018 ok(!!d3d9, "Failed to create a D3D object.\n");
3019 if (!(device1 = create_device(d3d9, window1, window1, TRUE)))
3021 skip("Failed to create a 3D device, skipping test.\n");
3022 IDirect3D9_Release(d3d9);
3023 DestroyWindow(window1);
3024 return;
3026 IDirect3D9_Release(d3d9);
3028 window2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3029 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3030 ok(!!window2, "Failed to create a window.\n");
3031 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3032 ok(!!d3d9, "Failed to create a D3D object.\n");
3033 device2 = create_device(d3d9, window2, window2, TRUE);
3034 IDirect3D9_Release(d3d9);
3036 refcount = IDirect3DDevice9_Release(device2);
3037 ok(!refcount, "Device has %u references left.\n", refcount);
3038 refcount = IDirect3DDevice9_Release(device1);
3039 ok(!refcount, "Device has %u references left.\n", refcount);
3040 DestroyWindow(window2);
3041 DestroyWindow(window1);
3044 static HWND filter_messages;
3046 enum message_window
3048 DEVICE_WINDOW,
3049 FOCUS_WINDOW,
3052 struct message
3054 UINT message;
3055 enum message_window window;
3058 static const struct message *expect_messages;
3059 static HWND device_window, focus_window;
3061 struct wndproc_thread_param
3063 HWND dummy_window;
3064 HANDLE window_created;
3065 HANDLE test_finished;
3066 BOOL running_in_foreground;
3069 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3071 if (filter_messages && filter_messages == hwnd)
3073 if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
3074 todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
3077 if (expect_messages)
3079 HWND w;
3081 switch (expect_messages->window)
3083 case DEVICE_WINDOW:
3084 w = device_window;
3085 break;
3087 case FOCUS_WINDOW:
3088 w = focus_window;
3089 break;
3091 default:
3092 w = NULL;
3093 break;
3096 if (hwnd == w && expect_messages->message == message) ++expect_messages;
3099 return DefWindowProcA(hwnd, message, wparam, lparam);
3102 static DWORD WINAPI wndproc_thread(void *param)
3104 struct wndproc_thread_param *p = param;
3105 DWORD res;
3106 BOOL ret;
3108 p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3109 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3110 p->running_in_foreground = SetForegroundWindow(p->dummy_window);
3112 ret = SetEvent(p->window_created);
3113 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
3115 for (;;)
3117 MSG msg;
3119 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
3120 res = WaitForSingleObject(p->test_finished, 100);
3121 if (res == WAIT_OBJECT_0) break;
3122 if (res != WAIT_TIMEOUT)
3124 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3125 break;
3129 DestroyWindow(p->dummy_window);
3131 return 0;
3134 static void test_wndproc(void)
3136 struct wndproc_thread_param thread_params;
3137 IDirect3DDevice9 *device;
3138 WNDCLASSA wc = {0};
3139 IDirect3D9 *d3d9;
3140 HANDLE thread;
3141 LONG_PTR proc;
3142 ULONG ref;
3143 DWORD res, tid;
3144 HWND tmp;
3146 static const struct message messages[] =
3148 {WM_WINDOWPOSCHANGING, FOCUS_WINDOW},
3149 {WM_ACTIVATE, FOCUS_WINDOW},
3150 {WM_SETFOCUS, FOCUS_WINDOW},
3151 {0, 0},
3154 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3155 ok(!!d3d9, "Failed to create a D3D object.\n");
3157 wc.lpfnWndProc = test_proc;
3158 wc.lpszClassName = "d3d9_test_wndproc_wc";
3159 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3161 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3162 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3163 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3164 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3166 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3167 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3168 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3169 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3170 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3171 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3173 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3174 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3176 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3177 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3178 (LONG_PTR)test_proc, proc);
3179 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3180 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3181 (LONG_PTR)test_proc, proc);
3183 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3184 device_window, focus_window, thread_params.dummy_window);
3186 tmp = GetFocus();
3187 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3188 if (thread_params.running_in_foreground)
3190 tmp = GetForegroundWindow();
3191 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3192 thread_params.dummy_window, tmp);
3194 else
3195 skip("Not running in foreground, skip foreground window test\n");
3197 flush_events();
3199 expect_messages = messages;
3201 device = create_device(d3d9, device_window, focus_window, FALSE);
3202 if (!device)
3204 skip("Failed to create a D3D device, skipping tests.\n");
3205 goto done;
3208 ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
3209 expect_messages->message, expect_messages->window);
3210 expect_messages = NULL;
3212 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
3214 tmp = GetFocus();
3215 ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
3216 tmp = GetForegroundWindow();
3217 ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
3219 SetForegroundWindow(focus_window);
3220 flush_events();
3222 filter_messages = focus_window;
3224 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3225 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3226 (LONG_PTR)test_proc, proc);
3228 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3229 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3230 (LONG_PTR)test_proc, proc);
3232 ref = IDirect3DDevice9_Release(device);
3233 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
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 device = create_device(d3d9, focus_window, focus_window, FALSE);
3240 if (!device)
3242 skip("Failed to create a D3D device, skipping tests.\n");
3243 goto done;
3246 ref = IDirect3DDevice9_Release(device);
3247 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3249 device = create_device(d3d9, device_window, focus_window, FALSE);
3250 if (!device)
3252 skip("Failed to create a D3D device, skipping tests.\n");
3253 goto done;
3256 proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3257 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3258 (LONG_PTR)test_proc, proc);
3260 ref = IDirect3DDevice9_Release(device);
3261 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3263 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3264 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3265 (LONG_PTR)DefWindowProcA, proc);
3267 done:
3268 filter_messages = NULL;
3269 IDirect3D9_Release(d3d9);
3271 SetEvent(thread_params.test_finished);
3272 WaitForSingleObject(thread, INFINITE);
3273 CloseHandle(thread_params.test_finished);
3274 CloseHandle(thread_params.window_created);
3275 CloseHandle(thread);
3277 DestroyWindow(device_window);
3278 DestroyWindow(focus_window);
3279 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3282 static void test_wndproc_windowed(void)
3284 struct wndproc_thread_param thread_params;
3285 IDirect3DDevice9 *device;
3286 WNDCLASSA wc = {0};
3287 IDirect3D9 *d3d9;
3288 HANDLE thread;
3289 LONG_PTR proc;
3290 HRESULT hr;
3291 ULONG ref;
3292 DWORD res, tid;
3293 HWND tmp;
3295 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3296 ok(!!d3d9, "Failed to create a D3D object.\n");
3298 wc.lpfnWndProc = test_proc;
3299 wc.lpszClassName = "d3d9_test_wndproc_wc";
3300 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3302 thread_params.window_created = CreateEventA(NULL, FALSE, FALSE, NULL);
3303 ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3304 thread_params.test_finished = CreateEventA(NULL, FALSE, FALSE, NULL);
3305 ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3307 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3308 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3309 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
3310 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3311 thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
3312 ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3314 res = WaitForSingleObject(thread_params.window_created, INFINITE);
3315 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3317 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3318 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3319 (LONG_PTR)test_proc, proc);
3320 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3321 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3322 (LONG_PTR)test_proc, proc);
3324 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3325 device_window, focus_window, thread_params.dummy_window);
3327 tmp = GetFocus();
3328 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3329 if (thread_params.running_in_foreground)
3331 tmp = GetForegroundWindow();
3332 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3333 thread_params.dummy_window, tmp);
3335 else
3336 skip("Not running in foreground, skip foreground window test\n");
3338 filter_messages = focus_window;
3340 device = create_device(d3d9, device_window, focus_window, TRUE);
3341 if (!device)
3343 skip("Failed to create a D3D device, skipping tests.\n");
3344 goto done;
3347 tmp = GetFocus();
3348 ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
3349 tmp = GetForegroundWindow();
3350 ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
3351 thread_params.dummy_window, tmp);
3353 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3354 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3355 (LONG_PTR)test_proc, proc);
3357 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3358 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3359 (LONG_PTR)test_proc, proc);
3361 filter_messages = NULL;
3363 hr = reset_device(device, device_window, FALSE);
3364 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3366 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3367 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3368 (LONG_PTR)test_proc, proc);
3370 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3371 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3372 (LONG_PTR)test_proc, proc);
3374 hr = reset_device(device, device_window, TRUE);
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 filter_messages = focus_window;
3387 ref = IDirect3DDevice9_Release(device);
3388 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3390 filter_messages = device_window;
3392 device = create_device(d3d9, focus_window, focus_window, TRUE);
3393 if (!device)
3395 skip("Failed to create a D3D device, skipping tests.\n");
3396 goto done;
3399 filter_messages = NULL;
3401 hr = reset_device(device, focus_window, FALSE);
3402 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3404 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3405 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3406 (LONG_PTR)test_proc, proc);
3408 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3409 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3410 (LONG_PTR)test_proc, proc);
3412 hr = reset_device(device, focus_window, TRUE);
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 filter_messages = device_window;
3425 ref = IDirect3DDevice9_Release(device);
3426 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3428 device = create_device(d3d9, device_window, focus_window, TRUE);
3429 if (!device)
3431 skip("Failed to create a D3D device, skipping tests.\n");
3432 goto done;
3435 filter_messages = NULL;
3437 hr = reset_device(device, device_window, FALSE);
3438 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3440 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3441 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3442 (LONG_PTR)test_proc, proc);
3444 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3445 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3446 (LONG_PTR)test_proc, proc);
3448 hr = reset_device(device, device_window, TRUE);
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 filter_messages = device_window;
3461 ref = IDirect3DDevice9_Release(device);
3462 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3464 done:
3465 filter_messages = NULL;
3466 IDirect3D9_Release(d3d9);
3468 SetEvent(thread_params.test_finished);
3469 WaitForSingleObject(thread, INFINITE);
3470 CloseHandle(thread_params.test_finished);
3471 CloseHandle(thread_params.window_created);
3472 CloseHandle(thread);
3474 DestroyWindow(device_window);
3475 DestroyWindow(focus_window);
3476 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3479 static void test_reset_fullscreen(void)
3481 WNDCLASSEXA wc = {0};
3482 IDirect3DDevice9 *device = NULL;
3483 IDirect3D9 *d3d;
3484 ATOM atom;
3485 static const struct message messages[] =
3487 {WM_ACTIVATEAPP, FOCUS_WINDOW},
3488 {0, 0},
3491 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3492 ok(!!d3d, "Failed to create a D3D object.\n");
3493 expect_messages = messages;
3495 wc.cbSize = sizeof(wc);
3496 wc.lpfnWndProc = test_proc;
3497 wc.lpszClassName = "test_reset_fullscreen";
3499 atom = RegisterClassExA(&wc);
3500 ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
3502 device_window = focus_window = CreateWindowExA(0, wc.lpszClassName, "Test Reset Fullscreen", 0,
3503 0, 0, screen_width, screen_height, NULL, NULL, NULL, NULL);
3504 ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
3507 * Create a device in windowed mode.
3508 * Since the device is windowed and we haven't called any methods that
3509 * could show the window (such as ShowWindow or SetWindowPos) yet,
3510 * WM_ACTIVATEAPP will not have been sent.
3512 device = create_device(d3d, device_window, focus_window, TRUE);
3513 if (!device)
3515 skip("Unable to create device. Skipping test.\n");
3516 goto cleanup;
3520 * Switch to fullscreen mode.
3521 * This will force the window to be shown and will cause the WM_ACTIVATEAPP
3522 * message to be sent.
3524 ok(SUCCEEDED(reset_device(device, device_window, FALSE)), "Failed to reset device.\n");
3526 flush_events();
3527 ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
3528 expect_messages = NULL;
3530 cleanup:
3531 if (device) IDirect3DDevice9_Release(device);
3532 IDirect3D9_Release(d3d);
3533 DestroyWindow(device_window);
3534 device_window = focus_window = NULL;
3535 UnregisterClassA(wc.lpszClassName, GetModuleHandleA(NULL));
3539 static inline void set_fpu_cw(WORD cw)
3541 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3542 #define D3D9_TEST_SET_FPU_CW 1
3543 __asm__ volatile ("fnclex");
3544 __asm__ volatile ("fldcw %0" : : "m" (cw));
3545 #elif defined(__i386__) && defined(_MSC_VER)
3546 #define D3D9_TEST_SET_FPU_CW 1
3547 __asm fnclex;
3548 __asm fldcw cw;
3549 #endif
3552 static inline WORD get_fpu_cw(void)
3554 WORD cw = 0;
3555 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3556 #define D3D9_TEST_GET_FPU_CW 1
3557 __asm__ volatile ("fnstcw %0" : "=m" (cw));
3558 #elif defined(__i386__) && defined(_MSC_VER)
3559 #define D3D9_TEST_GET_FPU_CW 1
3560 __asm fnstcw cw;
3561 #endif
3562 return cw;
3565 static void test_fpu_setup(void)
3567 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
3568 D3DPRESENT_PARAMETERS present_parameters;
3569 IDirect3DDevice9 *device;
3570 HWND window = NULL;
3571 IDirect3D9 *d3d9;
3572 HRESULT hr;
3573 WORD cw;
3575 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3576 ok(!!window, "Failed to create a window.\n");
3577 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3578 ok(!!d3d9, "Failed to create a D3D object.\n");
3580 memset(&present_parameters, 0, sizeof(present_parameters));
3581 present_parameters.Windowed = TRUE;
3582 present_parameters.hDeviceWindow = window;
3583 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3585 set_fpu_cw(0xf60);
3586 cw = get_fpu_cw();
3587 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3589 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3590 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
3591 if (FAILED(hr))
3593 skip("Failed to create a device, hr %#x.\n", hr);
3594 set_fpu_cw(0x37f);
3595 goto done;
3598 cw = get_fpu_cw();
3599 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3601 IDirect3DDevice9_Release(device);
3603 cw = get_fpu_cw();
3604 ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3605 set_fpu_cw(0xf60);
3606 cw = get_fpu_cw();
3607 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3609 hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3610 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &present_parameters, &device);
3611 ok(SUCCEEDED(hr), "CreateDevice failed, hr %#x.\n", hr);
3613 cw = get_fpu_cw();
3614 ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3615 set_fpu_cw(0x37f);
3617 IDirect3DDevice9_Release(device);
3619 done:
3620 IDirect3D9_Release(d3d9);
3621 DestroyWindow(window);
3622 #endif
3625 static void test_window_style(void)
3627 RECT focus_rect, fullscreen_rect, r;
3628 LONG device_style, device_exstyle;
3629 LONG focus_style, focus_exstyle;
3630 LONG style, expected_style;
3631 IDirect3DDevice9 *device;
3632 IDirect3D9 *d3d9;
3633 HRESULT hr;
3634 ULONG ref;
3636 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3637 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3638 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3639 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3640 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3641 ok(!!d3d9, "Failed to create a D3D object.\n");
3643 device_style = GetWindowLongA(device_window, GWL_STYLE);
3644 device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3645 focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3646 focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3648 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3649 GetWindowRect(focus_window, &focus_rect);
3651 device = create_device(d3d9, device_window, focus_window, FALSE);
3652 if (!device)
3654 skip("Failed to create a D3D device, skipping tests.\n");
3655 goto done;
3658 style = GetWindowLongA(device_window, GWL_STYLE);
3659 expected_style = device_style | WS_VISIBLE;
3660 todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3661 expected_style, style);
3662 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3663 expected_style = device_exstyle | WS_EX_TOPMOST;
3664 todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3665 expected_style, style);
3667 style = GetWindowLongA(focus_window, GWL_STYLE);
3668 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3669 focus_style, style);
3670 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3671 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3672 focus_exstyle, style);
3674 GetWindowRect(device_window, &r);
3675 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3676 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3677 r.left, r.top, r.right, r.bottom);
3678 GetClientRect(device_window, &r);
3679 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3680 GetWindowRect(focus_window, &r);
3681 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3682 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3683 r.left, r.top, r.right, r.bottom);
3685 hr = reset_device(device, device_window, TRUE);
3686 ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3688 style = GetWindowLongA(device_window, GWL_STYLE);
3689 expected_style = device_style | WS_VISIBLE;
3690 ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3691 expected_style, style);
3692 style = GetWindowLongA(device_window, GWL_EXSTYLE);
3693 expected_style = device_exstyle | WS_EX_TOPMOST;
3694 ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3695 expected_style, style);
3697 style = GetWindowLongA(focus_window, GWL_STYLE);
3698 ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3699 focus_style, style);
3700 style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3701 ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3702 focus_exstyle, style);
3704 ref = IDirect3DDevice9_Release(device);
3705 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3707 done:
3708 IDirect3D9_Release(d3d9);
3710 DestroyWindow(device_window);
3711 DestroyWindow(focus_window);
3714 static const POINT *expect_pos;
3716 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
3718 if (message == WM_MOUSEMOVE)
3720 if (expect_pos && expect_pos->x && expect_pos->y)
3722 POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
3724 ClientToScreen(window, &p);
3725 if (expect_pos->x == p.x && expect_pos->y == p.y)
3726 ++expect_pos;
3730 return DefWindowProcA(window, message, wparam, lparam);
3733 static void test_cursor_pos(void)
3735 IDirect3DSurface9 *cursor;
3736 IDirect3DDevice9 *device;
3737 WNDCLASSA wc = {0};
3738 IDirect3D9 *d3d9;
3739 UINT refcount;
3740 HWND window;
3741 HRESULT hr;
3742 BOOL ret;
3744 /* Note that we don't check for movement we're not supposed to receive.
3745 * That's because it's hard to distinguish from the user accidentally
3746 * moving the mouse. */
3747 static const POINT points[] =
3749 {50, 50},
3750 {75, 75},
3751 {100, 100},
3752 {125, 125},
3753 {150, 150},
3754 {125, 125},
3755 {150, 150},
3756 {150, 150},
3757 {0, 0},
3760 wc.lpfnWndProc = test_cursor_proc;
3761 wc.lpszClassName = "d3d9_test_cursor_wc";
3762 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3763 window = CreateWindowA("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3764 0, 0, 320, 240, NULL, NULL, NULL, NULL);
3765 ShowWindow(window, SW_SHOW);
3766 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3767 ok(!!d3d9, "Failed to create a D3D object.\n");
3769 device = create_device(d3d9, window, window, TRUE);
3770 if (!device)
3772 skip("Failed to create a D3D device, skipping tests.\n");
3773 goto done;
3776 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3777 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
3778 ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
3779 hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
3780 ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#x.\n", hr);
3781 IDirect3DSurface9_Release(cursor);
3782 ret = IDirect3DDevice9_ShowCursor(device, TRUE);
3783 ok(!ret, "Failed to show cursor, hr %#x.\n", ret);
3785 flush_events();
3786 expect_pos = points;
3788 ret = SetCursorPos(50, 50);
3789 ok(ret, "Failed to set cursor position.\n");
3790 flush_events();
3792 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3793 flush_events();
3794 /* SetCursorPosition() eats duplicates. */
3795 IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3796 flush_events();
3798 ret = SetCursorPos(100, 100);
3799 ok(ret, "Failed to set cursor position.\n");
3800 flush_events();
3801 /* Even if the position was set with SetCursorPos(). */
3802 IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
3803 flush_events();
3805 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3806 flush_events();
3807 ret = SetCursorPos(150, 150);
3808 ok(ret, "Failed to set cursor position.\n");
3809 flush_events();
3810 IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3811 flush_events();
3813 IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
3814 flush_events();
3815 /* SetCursorPos() doesn't. */
3816 ret = SetCursorPos(150, 150);
3817 ok(ret, "Failed to set cursor position.\n");
3818 flush_events();
3820 ok(!expect_pos->x && !expect_pos->y, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
3821 (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
3823 refcount = IDirect3DDevice9_Release(device);
3824 ok(!refcount, "Device has %u references left.\n", refcount);
3825 done:
3826 DestroyWindow(window);
3827 UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
3828 IDirect3D9_Release(d3d9);
3831 static void test_mode_change(void)
3833 RECT fullscreen_rect, focus_rect, r;
3834 IDirect3DSurface9 *backbuffer;
3835 IDirect3DDevice9 *device;
3836 D3DSURFACE_DESC desc;
3837 IDirect3D9 *d3d9;
3838 DEVMODEW devmode;
3839 UINT refcount;
3840 HRESULT hr;
3841 DWORD ret;
3843 focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3844 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3845 device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3846 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3847 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3848 ok(!!d3d9, "Failed to create a D3D object.\n");
3850 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3851 GetWindowRect(focus_window, &focus_rect);
3853 device = create_device(d3d9, device_window, focus_window, FALSE);
3854 if (!device)
3856 skip("Failed to create a D3D device, skipping tests.\n");
3857 goto done;
3860 memset(&devmode, 0, sizeof(devmode));
3861 devmode.dmSize = sizeof(devmode);
3862 devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3863 devmode.dmPelsWidth = 640;
3864 devmode.dmPelsHeight = 480;
3866 ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3867 ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
3869 memset(&devmode, 0, sizeof(devmode));
3870 devmode.dmSize = sizeof(devmode);
3871 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3872 ok(ret, "Failed to get display mode.\n");
3873 ok(devmode.dmPelsWidth == 640, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3874 ok(devmode.dmPelsHeight == 480, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3876 GetWindowRect(device_window, &r);
3877 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3878 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3879 r.left, r.top, r.right, r.bottom);
3880 GetWindowRect(focus_window, &r);
3881 ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3882 focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3883 r.left, r.top, r.right, r.bottom);
3885 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3886 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3887 hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
3888 ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#x.\n", hr);
3889 ok(desc.Width == screen_width, "Got unexpected backbuffer width %u.\n", desc.Width);
3890 ok(desc.Height == screen_height, "Got unexpected backbuffer height %u.\n", desc.Height);
3891 IDirect3DSurface9_Release(backbuffer);
3893 refcount = IDirect3DDevice9_Release(device);
3894 ok(!refcount, "Device has %u references left.\n", refcount);
3896 memset(&devmode, 0, sizeof(devmode));
3897 devmode.dmSize = sizeof(devmode);
3898 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3899 ok(ret, "Failed to get display mode.\n");
3900 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3901 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3903 done:
3904 DestroyWindow(device_window);
3905 DestroyWindow(focus_window);
3906 IDirect3D9_Release(d3d9);
3908 memset(&devmode, 0, sizeof(devmode));
3909 devmode.dmSize = sizeof(devmode);
3910 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3911 ok(ret, "Failed to get display mode.\n");
3912 ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3913 ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3916 static void test_device_window_reset(void)
3918 RECT fullscreen_rect, device_rect, r;
3919 IDirect3DDevice9 *device;
3920 WNDCLASSA wc = {0};
3921 IDirect3D9 *d3d9;
3922 LONG_PTR proc;
3923 HRESULT hr;
3924 ULONG ref;
3926 wc.lpfnWndProc = test_proc;
3927 wc.lpszClassName = "d3d9_test_wndproc_wc";
3928 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3930 focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3931 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3932 device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3933 0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3934 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3935 ok(!!d3d9, "Failed to create a D3D object.\n");
3937 SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3938 GetWindowRect(device_window, &device_rect);
3940 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3941 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3942 (LONG_PTR)test_proc, proc);
3943 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3944 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3945 (LONG_PTR)test_proc, proc);
3947 device = create_device(d3d9, NULL, focus_window, FALSE);
3948 if (!device)
3950 skip("Failed to create a D3D device, skipping tests.\n");
3951 goto done;
3954 GetWindowRect(focus_window, &r);
3955 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3956 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3957 r.left, r.top, r.right, r.bottom);
3958 GetWindowRect(device_window, &r);
3959 ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3960 device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
3961 r.left, r.top, r.right, r.bottom);
3963 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3964 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3965 (LONG_PTR)test_proc, proc);
3966 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3967 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3968 (LONG_PTR)test_proc, proc);
3970 hr = reset_device(device, device_window, FALSE);
3971 ok(SUCCEEDED(hr), "Failed to reset device.\n");
3973 GetWindowRect(focus_window, &r);
3974 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3975 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3976 r.left, r.top, r.right, r.bottom);
3977 GetWindowRect(device_window, &r);
3978 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3979 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3980 r.left, r.top, r.right, r.bottom);
3982 proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3983 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3984 (LONG_PTR)test_proc, proc);
3985 proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3986 ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3987 (LONG_PTR)test_proc, proc);
3989 ref = IDirect3DDevice9_Release(device);
3990 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3992 done:
3993 IDirect3D9_Release(d3d9);
3994 DestroyWindow(device_window);
3995 DestroyWindow(focus_window);
3996 UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3999 static void test_reset_resources(void)
4001 IDirect3DSurface9 *surface, *rt;
4002 IDirect3DTexture9 *texture;
4003 IDirect3DDevice9 *device;
4004 IDirect3D9 *d3d9;
4005 unsigned int i;
4006 D3DCAPS9 caps;
4007 HWND window;
4008 HRESULT hr;
4009 ULONG ref;
4011 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
4012 0, 0, 640, 480, 0, 0, 0, 0);
4013 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4014 ok(!!d3d9, "Failed to create a D3D object.\n");
4016 if (!(device = create_device(d3d9, window, window, TRUE)))
4018 skip("Failed to create a D3D device, skipping tests.\n");
4019 goto done;
4022 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4023 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4025 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128,
4026 D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
4027 ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
4028 hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
4029 ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
4030 IDirect3DSurface9_Release(surface);
4032 for (i = 0; i < caps.NumSimultaneousRTs; ++i)
4034 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
4035 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4036 ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
4037 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4038 ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
4039 IDirect3DTexture9_Release(texture);
4040 hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
4041 ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
4042 IDirect3DSurface9_Release(surface);
4045 hr = reset_device(device, device_window, TRUE);
4046 ok(SUCCEEDED(hr), "Failed to reset device.\n");
4048 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
4049 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
4050 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
4051 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4052 ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
4053 IDirect3DSurface9_Release(surface);
4054 IDirect3DSurface9_Release(rt);
4056 for (i = 1; i < caps.NumSimultaneousRTs; ++i)
4058 hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
4059 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
4062 ref = IDirect3DDevice9_Release(device);
4063 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
4065 done:
4066 IDirect3D9_Release(d3d9);
4067 DestroyWindow(window);
4070 static void test_set_rt_vp_scissor(void)
4072 IDirect3DStateBlock9 *stateblock;
4073 IDirect3DDevice9 *device;
4074 IDirect3DSurface9 *rt;
4075 IDirect3D9 *d3d9;
4076 D3DVIEWPORT9 vp;
4077 UINT refcount;
4078 HWND window;
4079 HRESULT hr;
4080 RECT rect;
4082 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
4083 0, 0, 640, 480, 0, 0, 0, 0);
4084 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4085 ok(!!d3d9, "Failed to create a D3D object.\n");
4086 if (!(device = create_device(d3d9, window, window, TRUE)))
4088 skip("Failed to create a D3D device, skipping tests.\n");
4089 DestroyWindow(window);
4090 return;
4093 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
4094 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
4095 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4097 hr = IDirect3DDevice9_GetViewport(device, &vp);
4098 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4099 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4100 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4101 ok(vp.Width == screen_width, "Got unexpected vp.Width %u.\n", vp.Width);
4102 ok(vp.Height == screen_height, "Got unexpected vp.Height %u.\n", vp.Height);
4103 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4104 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4106 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4107 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4108 ok(rect.left == 0 && rect.top == 0 && rect.right == screen_width && rect.bottom == screen_height,
4109 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4110 rect.left, rect.top, rect.right, rect.bottom);
4112 hr = IDirect3DDevice9_BeginStateBlock(device);
4113 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
4115 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4116 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4118 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
4119 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
4120 IDirect3DStateBlock9_Release(stateblock);
4122 hr = IDirect3DDevice9_GetViewport(device, &vp);
4123 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4124 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4125 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4126 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
4127 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
4128 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4129 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4131 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4132 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4133 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
4134 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4135 rect.left, rect.top, rect.right, rect.bottom);
4137 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4138 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4140 vp.X = 10;
4141 vp.Y = 20;
4142 vp.Width = 30;
4143 vp.Height = 40;
4144 vp.MinZ = 0.25f;
4145 vp.MaxZ = 0.75f;
4146 hr = IDirect3DDevice9_SetViewport(device, &vp);
4147 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
4149 SetRect(&rect, 50, 60, 70, 80);
4150 hr = IDirect3DDevice9_SetScissorRect(device, &rect);
4151 ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
4153 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4154 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4156 hr = IDirect3DDevice9_GetViewport(device, &vp);
4157 ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
4158 ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
4159 ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
4160 ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
4161 ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
4162 ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
4163 ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
4165 hr = IDirect3DDevice9_GetScissorRect(device, &rect);
4166 ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
4167 ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
4168 "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
4169 rect.left, rect.top, rect.right, rect.bottom);
4171 IDirect3DSurface9_Release(rt);
4172 refcount = IDirect3DDevice9_Release(device);
4173 ok(!refcount, "Device has %u references left.\n", refcount);
4174 IDirect3D9_Release(d3d9);
4175 DestroyWindow(window);
4178 static void test_volume_get_container(void)
4180 IDirect3DVolumeTexture9 *texture = NULL;
4181 IDirect3DVolume9 *volume = NULL;
4182 IDirect3DDevice9 *device;
4183 IUnknown *container;
4184 IDirect3D9 *d3d9;
4185 ULONG refcount;
4186 D3DCAPS9 caps;
4187 HWND window;
4188 HRESULT hr;
4190 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4191 0, 0, 640, 480, 0, 0, 0, 0);
4192 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4193 ok(!!d3d9, "Failed to create a D3D object.\n");
4194 if (!(device = create_device(d3d9, window, window, TRUE)))
4196 skip("Failed to create a D3D device, skipping tests.\n");
4197 IDirect3D9_Release(d3d9);
4198 DestroyWindow(window);
4199 return;
4202 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4203 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4204 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
4206 skip("No volume texture support, skipping tests.\n");
4207 IDirect3DDevice9_Release(device);
4208 IDirect3D9_Release(d3d9);
4209 DestroyWindow(window);
4210 return;
4213 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
4214 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
4215 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4216 ok(!!texture, "Got unexpected texture %p.\n", texture);
4218 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
4219 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
4220 ok(!!volume, "Got unexpected volume %p.\n", volume);
4222 /* These should work... */
4223 container = NULL;
4224 hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
4225 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4226 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4227 IUnknown_Release(container);
4229 container = NULL;
4230 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
4231 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4232 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4233 IUnknown_Release(container);
4235 container = NULL;
4236 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
4237 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4238 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4239 IUnknown_Release(container);
4241 container = NULL;
4242 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
4243 ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
4244 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
4245 IUnknown_Release(container);
4247 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
4248 hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
4249 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
4250 ok(!container, "Got unexpected container %p.\n", container);
4252 IDirect3DVolume9_Release(volume);
4253 IDirect3DVolumeTexture9_Release(texture);
4254 refcount = IDirect3DDevice9_Release(device);
4255 ok(!refcount, "Device has %u references left.\n", refcount);
4256 IDirect3D9_Release(d3d9);
4257 DestroyWindow(window);
4260 static void test_volume_resource(void)
4262 IDirect3DVolumeTexture9 *texture;
4263 IDirect3DResource9 *resource;
4264 IDirect3DVolume9 *volume;
4265 IDirect3DDevice9 *device;
4266 IDirect3D9 *d3d9;
4267 ULONG refcount;
4268 D3DCAPS9 caps;
4269 HWND window;
4270 HRESULT hr;
4272 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4273 0, 0, 640, 480, 0, 0, 0, 0);
4274 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4275 ok(!!d3d9, "Failed to create a D3D object.\n");
4276 if (!(device = create_device(d3d9, window, window, TRUE)))
4278 skip("Failed to create a D3D device, skipping tests.\n");
4279 IDirect3D9_Release(d3d9);
4280 DestroyWindow(window);
4281 return;
4284 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4285 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4286 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
4288 skip("No volume texture support, skipping tests.\n");
4289 IDirect3DDevice9_Release(device);
4290 IDirect3D9_Release(d3d9);
4291 DestroyWindow(window);
4292 return;
4295 hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
4296 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
4297 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4298 hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
4299 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
4300 IDirect3DVolumeTexture9_Release(texture);
4302 hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
4303 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
4305 IDirect3DVolume9_Release(volume);
4306 refcount = IDirect3DDevice9_Release(device);
4307 ok(!refcount, "Device has %u references left.\n", refcount);
4308 IDirect3D9_Release(d3d9);
4309 DestroyWindow(window);
4312 static void test_vb_lock_flags(void)
4314 static const struct
4316 DWORD flags;
4317 const char *debug_string;
4318 HRESULT win7_result;
4320 test_data[] =
4322 {D3DLOCK_READONLY, "D3DLOCK_READONLY", D3D_OK },
4323 {D3DLOCK_DISCARD, "D3DLOCK_DISCARD", D3D_OK },
4324 {D3DLOCK_NOOVERWRITE, "D3DLOCK_NOOVERWRITE", D3D_OK },
4325 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK },
4326 {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK },
4327 {D3DLOCK_READONLY | D3DLOCK_DISCARD, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3DERR_INVALIDCALL},
4328 /* Completely bogus flags aren't an error. */
4329 {0xdeadbeef, "0xdeadbeef", D3DERR_INVALIDCALL},
4331 IDirect3DVertexBuffer9 *buffer;
4332 IDirect3DDevice9 *device;
4333 IDirect3D9 *d3d9;
4334 unsigned int i;
4335 ULONG refcount;
4336 HWND window;
4337 HRESULT hr;
4338 void *data;
4340 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4341 0, 0, 640, 480, 0, 0, 0, 0);
4342 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4343 ok(!!d3d9, "Failed to create a D3D object.\n");
4344 if (!(device = create_device(d3d9, window, window, TRUE)))
4346 skip("Failed to create a D3D device, skipping tests.\n");
4347 IDirect3D9_Release(d3d9);
4348 DestroyWindow(window);
4349 return;
4352 hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
4353 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4355 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
4357 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
4358 /* Windows XP always returns D3D_OK even with flags that don't make
4359 * sense. Windows 7 returns an error. At least one game (Shaiya)
4360 * depends on the Windows XP result, so mark the Windows 7 behavior as
4361 * broken. */
4362 ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
4363 hr, test_data[i].debug_string);
4364 if (SUCCEEDED(hr))
4366 ok(!!data, "Got unexpected data %p.\n", data);
4367 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4368 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
4372 IDirect3DVertexBuffer9_Release(buffer);
4373 refcount = IDirect3DDevice9_Release(device);
4374 ok(!refcount, "Device has %u references left.\n", refcount);
4375 IDirect3D9_Release(d3d9);
4376 DestroyWindow(window);
4379 static const char *debug_d3dpool(D3DPOOL pool)
4381 switch (pool)
4383 case D3DPOOL_DEFAULT:
4384 return "D3DPOOL_DEFAULT";
4385 case D3DPOOL_SYSTEMMEM:
4386 return "D3DPOOL_SYSTEMMEM";
4387 case D3DPOOL_SCRATCH:
4388 return "D3DPOOL_SCRATCH";
4389 case D3DPOOL_MANAGED:
4390 return "D3DPOOL_MANAGED";
4391 default:
4392 return "unknown pool";
4396 static void test_vertex_buffer_alignment(void)
4398 static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
4399 static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
4400 IDirect3DVertexBuffer9 *buffer = NULL;
4401 const unsigned int align = 16;
4402 IDirect3DDevice9 *device;
4403 unsigned int i, j;
4404 IDirect3D9 *d3d9;
4405 ULONG refcount;
4406 HWND window;
4407 HRESULT hr;
4408 void *data;
4410 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4411 0, 0, 640, 480, 0, 0, 0, 0);
4412 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4413 ok(!!d3d9, "Failed to create a D3D object.\n");
4414 if (!(device = create_device(d3d9, window, window, TRUE)))
4416 skip("Failed to create a D3D device, skipping tests.\n");
4417 IDirect3D9_Release(d3d9);
4418 DestroyWindow(window);
4419 return;
4422 for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
4424 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
4426 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
4427 if (pools[j] == D3DPOOL_SCRATCH)
4428 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
4429 else
4430 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
4431 debug_d3dpool(pools[j]), sizes[i], hr);
4432 if (FAILED(hr))
4433 continue;
4435 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
4436 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
4437 ok(!((DWORD_PTR)data & (align - 1)),
4438 "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
4439 data, align, sizes[i], debug_d3dpool(pools[j]));
4440 hr = IDirect3DVertexBuffer9_Unlock(buffer);
4441 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
4442 IDirect3DVertexBuffer9_Release(buffer);
4446 refcount = IDirect3DDevice9_Release(device);
4447 ok(!refcount, "Device has %u references left.\n", refcount);
4448 IDirect3D9_Release(d3d9);
4449 DestroyWindow(window);
4452 static void test_query_support(void)
4454 static const D3DQUERYTYPE queries[] =
4456 D3DQUERYTYPE_VCACHE,
4457 D3DQUERYTYPE_RESOURCEMANAGER,
4458 D3DQUERYTYPE_VERTEXSTATS,
4459 D3DQUERYTYPE_EVENT,
4460 D3DQUERYTYPE_OCCLUSION,
4461 D3DQUERYTYPE_TIMESTAMP,
4462 D3DQUERYTYPE_TIMESTAMPDISJOINT,
4463 D3DQUERYTYPE_TIMESTAMPFREQ,
4464 D3DQUERYTYPE_PIPELINETIMINGS,
4465 D3DQUERYTYPE_INTERFACETIMINGS,
4466 D3DQUERYTYPE_VERTEXTIMINGS,
4467 D3DQUERYTYPE_PIXELTIMINGS,
4468 D3DQUERYTYPE_BANDWIDTHTIMINGS,
4469 D3DQUERYTYPE_CACHEUTILIZATION,
4471 IDirect3DQuery9 *query = NULL;
4472 IDirect3DDevice9 *device;
4473 IDirect3D9 *d3d9;
4474 unsigned int i;
4475 ULONG refcount;
4476 BOOL supported;
4477 HWND window;
4478 HRESULT hr;
4480 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4481 0, 0, 640, 480, 0, 0, 0, 0);
4482 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4483 ok(!!d3d9, "Failed to create a D3D object.\n");
4484 if (!(device = create_device(d3d9, window, window, TRUE)))
4486 skip("Failed to create a D3D device, skipping tests.\n");
4487 IDirect3D9_Release(d3d9);
4488 DestroyWindow(window);
4489 return;
4492 for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
4494 hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
4495 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4497 supported = hr == D3D_OK;
4499 hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
4500 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4502 ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
4503 ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
4505 if (query)
4507 IDirect3DQuery9_Release(query);
4508 query = NULL;
4512 refcount = IDirect3DDevice9_Release(device);
4513 ok(!refcount, "Device has %u references left.\n", refcount);
4514 IDirect3D9_Release(d3d9);
4515 DestroyWindow(window);
4518 static void test_occlusion_query_states(void)
4520 static const float point[3] = {0.0, 0.0, 0.0};
4521 IDirect3DQuery9 *query = NULL;
4522 unsigned int data_size, i;
4523 IDirect3DDevice9 *device;
4524 IDirect3D9 *d3d9;
4525 ULONG refcount;
4526 HWND window;
4527 HRESULT hr;
4528 BYTE *data;
4530 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4531 0, 0, 640, 480, 0, 0, 0, 0);
4532 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4533 ok(!!d3d9, "Failed to create a D3D object.\n");
4534 if (!(device = create_device(d3d9, window, window, TRUE)))
4536 skip("Failed to create a D3D device, skipping tests.\n");
4537 IDirect3D9_Release(d3d9);
4538 DestroyWindow(window);
4539 return;
4542 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4543 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4544 if (!query)
4546 skip("Occlusion queries are not supported, skipping tests.\n");
4547 IDirect3DDevice9_Release(device);
4548 IDirect3D9_Release(d3d9);
4549 DestroyWindow(window);
4550 return;
4553 data_size = IDirect3DQuery9_GetDataSize(query);
4554 data = HeapAlloc(GetProcessHeap(), 0, data_size);
4556 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4557 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4558 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4559 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4561 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4562 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4563 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4564 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4565 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4566 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4568 *((DWORD *)data) = 0x12345678;
4569 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4570 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4571 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4572 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4573 if (hr == D3D_OK)
4574 ok(!*(DWORD *)data, "Got unexpected query result %u.\n", *(DWORD *)data);
4576 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4577 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4578 hr = IDirect3DDevice9_BeginScene(device);
4579 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
4581 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4582 hr = IDirect3DDevice9_EndScene(device);
4583 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4585 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4586 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4587 for (i = 0; i < 500; ++i)
4589 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4590 break;
4591 Sleep(10);
4593 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4595 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4596 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4597 hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4598 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4600 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4601 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4602 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4603 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4604 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4605 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4607 HeapFree(GetProcessHeap(), 0, data);
4608 IDirect3DQuery9_Release(query);
4609 refcount = IDirect3DDevice9_Release(device);
4610 ok(!refcount, "Device has %u references left.\n", refcount);
4611 IDirect3D9_Release(d3d9);
4612 DestroyWindow(window);
4615 static void test_timestamp_query(void)
4617 static const float point[3] = {0.0, 0.0, 0.0};
4618 IDirect3DQuery9 *query, *disjoint_query, *freq_query;
4619 unsigned int data_size, i;
4620 IDirect3DDevice9 *device;
4621 IDirect3D9 *d3d9;
4622 ULONG refcount;
4623 HWND window;
4624 HRESULT hr;
4625 UINT64 timestamp, freq;
4626 BOOL disjoint;
4628 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4629 0, 0, 640, 480, 0, 0, 0, 0);
4630 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
4631 ok(!!d3d9, "Failed to create a D3D object.\n");
4632 if (!(device = create_device(d3d9, window, window, TRUE)))
4634 skip("Failed to create a D3D device, skipping tests.\n");
4635 IDirect3D9_Release(d3d9);
4636 DestroyWindow(window);
4637 return;
4640 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPFREQ, &freq_query);
4641 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4642 if (FAILED(hr))
4644 skip("Timestamp queries are not supported, skipping tests.\n");
4645 IDirect3DDevice9_Release(device);
4646 IDirect3D9_Release(d3d9);
4647 DestroyWindow(window);
4648 return;
4650 data_size = IDirect3DQuery9_GetDataSize(freq_query);
4651 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
4653 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMPDISJOINT, &disjoint_query);
4654 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4655 data_size = IDirect3DQuery9_GetDataSize(disjoint_query);
4656 ok(data_size == sizeof(BOOL), "Query data size is %u, 4 expected.\n", data_size);
4658 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_TIMESTAMP, &query);
4659 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4660 data_size = IDirect3DQuery9_GetDataSize(query);
4661 ok(data_size == sizeof(UINT64), "Query data size is %u, 8 expected.\n", data_size);
4663 hr = IDirect3DQuery9_Issue(freq_query, D3DISSUE_END);
4664 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4665 for (i = 0; i < 500; ++i)
4667 if ((hr = IDirect3DQuery9_GetData(freq_query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4668 break;
4669 Sleep(10);
4671 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4672 hr = IDirect3DQuery9_GetData(freq_query, &freq, sizeof(freq), D3DGETDATA_FLUSH);
4673 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4675 hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4676 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4677 hr = IDirect3DQuery9_GetData(query, &timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4678 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4680 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
4681 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4682 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
4683 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4684 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_BEGIN);
4685 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4687 hr = IDirect3DQuery9_GetData(query, &timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4688 ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4690 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4691 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4692 hr = IDirect3DDevice9_BeginScene(device);
4693 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
4695 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4696 hr = IDirect3DDevice9_EndScene(device);
4697 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4699 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4700 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4701 for (i = 0; i < 500; ++i)
4703 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4704 break;
4705 Sleep(10);
4707 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4709 hr = IDirect3DQuery9_GetData(query, &timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4710 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4711 hr = IDirect3DQuery9_GetData(query, &timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4712 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4714 hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4715 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4716 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4717 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4718 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4719 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4721 hr = IDirect3DQuery9_Issue(disjoint_query, D3DISSUE_END);
4722 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4723 for (i = 0; i < 500; ++i)
4725 if ((hr = IDirect3DQuery9_GetData(disjoint_query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4726 break;
4727 Sleep(10);
4729 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4730 hr = IDirect3DQuery9_GetData(disjoint_query, &disjoint, sizeof(disjoint), D3DGETDATA_FLUSH);
4731 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4733 /* It's not strictly necessary for the TIMESTAMP query to be inside
4734 * a TIMESTAMP_DISJOINT query. */
4735 hr = IDirect3DDevice9_BeginScene(device);
4736 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
4738 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4739 hr = IDirect3DDevice9_EndScene(device);
4740 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4742 hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4743 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4744 for (i = 0; i < 500; ++i)
4746 if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4747 break;
4748 Sleep(10);
4750 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4751 hr = IDirect3DQuery9_GetData(query, &timestamp, sizeof(timestamp), D3DGETDATA_FLUSH);
4752 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4754 IDirect3DQuery9_Release(query);
4755 IDirect3DQuery9_Release(disjoint_query);
4756 IDirect3DQuery9_Release(freq_query);
4757 refcount = IDirect3DDevice9_Release(device);
4758 ok(!refcount, "Device has %u references left.\n", refcount);
4759 IDirect3D9_Release(d3d9);
4760 DestroyWindow(window);
4763 static void test_get_set_vertex_shader(void)
4765 IDirect3DVertexShader9 *current_shader = NULL;
4766 IDirect3DVertexShader9 *shader = NULL;
4767 IDirect3DDevice9 *device;
4768 ULONG refcount, i;
4769 IDirect3D9 *d3d;
4770 D3DCAPS9 caps;
4771 HWND window;
4772 HRESULT hr;
4774 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4775 0, 0, 640, 480, 0, 0, 0, 0);
4776 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4777 ok(!!d3d, "Failed to create a D3D object.\n");
4778 if (!(device = create_device(d3d, window, window, TRUE)))
4780 skip("Failed to create a D3D device, skipping tests.\n");
4781 IDirect3D9_Release(d3d);
4782 DestroyWindow(window);
4783 return;
4786 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4787 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4788 if (!(caps.VertexShaderVersion & 0xffff))
4790 skip("No vertex shader support, skipping tests.\n");
4791 IDirect3DDevice9_Release(device);
4792 IDirect3D9_Release(d3d);
4793 DestroyWindow(window);
4794 return;
4797 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
4798 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4799 ok(!!shader, "Got unexpected shader %p.\n", shader);
4801 /* SetVertexShader() should not touch the shader's refcount. */
4802 i = get_refcount((IUnknown *)shader);
4803 hr = IDirect3DDevice9_SetVertexShader(device, shader);
4804 refcount = get_refcount((IUnknown *)shader);
4805 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4806 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4808 /* GetVertexShader() should increase the shader's refcount by one. */
4809 i = refcount + 1;
4810 hr = IDirect3DDevice9_GetVertexShader(device, &current_shader);
4811 refcount = get_refcount((IUnknown *)shader);
4812 ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
4813 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4814 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4815 IDirect3DVertexShader9_Release(current_shader);
4817 IDirect3DVertexShader9_Release(shader);
4818 refcount = IDirect3DDevice9_Release(device);
4819 ok(!refcount, "Device has %u references left.\n", refcount);
4820 IDirect3D9_Release(d3d);
4821 DestroyWindow(window);
4824 static void test_vertex_shader_constant(void)
4826 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};
4827 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4828 IDirect3DDevice9 *device;
4829 IDirect3D9 *d3d;
4830 ULONG refcount;
4831 D3DCAPS9 caps;
4832 DWORD consts;
4833 HWND window;
4834 HRESULT hr;
4836 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4837 0, 0, 640, 480, 0, 0, 0, 0);
4838 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4839 ok(!!d3d, "Failed to create a D3D object.\n");
4840 if (!(device = create_device(d3d, window, window, TRUE)))
4842 skip("Failed to create a D3D device, skipping tests.\n");
4843 IDirect3D9_Release(d3d);
4844 DestroyWindow(window);
4845 return;
4848 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4849 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4850 if (!(caps.VertexShaderVersion & 0xffff))
4852 skip("No vertex shader support, skipping tests.\n");
4853 IDirect3DDevice9_Release(device);
4854 IDirect3D9_Release(d3d);
4855 DestroyWindow(window);
4856 return;
4858 consts = caps.MaxVertexShaderConst;
4860 /* A simple check that the stuff works at all. */
4861 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
4862 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4864 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
4865 * consts from MAX - 1. */
4866 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
4867 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4868 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
4869 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4870 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
4871 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4872 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
4873 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4875 /* Constant -1. */
4876 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
4877 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4879 refcount = IDirect3DDevice9_Release(device);
4880 ok(!refcount, "Device has %u references left.\n", refcount);
4881 IDirect3D9_Release(d3d);
4882 DestroyWindow(window);
4885 static void test_get_set_pixel_shader(void)
4887 IDirect3DPixelShader9 *current_shader = NULL;
4888 IDirect3DPixelShader9 *shader = NULL;
4889 IDirect3DDevice9 *device;
4890 ULONG refcount, i;
4891 IDirect3D9 *d3d;
4892 D3DCAPS9 caps;
4893 HWND window;
4894 HRESULT hr;
4896 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4897 0, 0, 640, 480, 0, 0, 0, 0);
4898 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4899 ok(!!d3d, "Failed to create a D3D object.\n");
4900 if (!(device = create_device(d3d, window, window, TRUE)))
4902 skip("Failed to create a D3D device, skipping tests.\n");
4903 IDirect3D9_Release(d3d);
4904 DestroyWindow(window);
4905 return;
4908 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4909 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4910 if (!(caps.PixelShaderVersion & 0xffff))
4912 skip("No pixel shader support, skipping tests.\n");
4913 IDirect3DDevice9_Release(device);
4914 IDirect3D9_Release(d3d);
4915 DestroyWindow(window);
4916 return;
4919 hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
4920 ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4921 ok(!!shader, "Got unexpected shader %p.\n", shader);
4923 /* SetPixelShader() should not touch the shader's refcount. */
4924 i = get_refcount((IUnknown *)shader);
4925 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4926 refcount = get_refcount((IUnknown *)shader);
4927 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4928 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4930 /* GetPixelShader() should increase the shader's refcount by one. */
4931 i = refcount + 1;
4932 hr = IDirect3DDevice9_GetPixelShader(device, &current_shader);
4933 refcount = get_refcount((IUnknown *)shader);
4934 ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
4935 ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4936 ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4937 IDirect3DPixelShader9_Release(current_shader);
4939 IDirect3DPixelShader9_Release(shader);
4940 refcount = IDirect3DDevice9_Release(device);
4941 ok(!refcount, "Device has %u references left.\n", refcount);
4942 IDirect3D9_Release(d3d);
4943 DestroyWindow(window);
4946 static void test_pixel_shader_constant(void)
4948 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};
4949 static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4950 IDirect3DDevice9 *device;
4951 DWORD consts = 0;
4952 IDirect3D9 *d3d;
4953 ULONG refcount;
4954 D3DCAPS9 caps;
4955 HWND window;
4956 HRESULT hr;
4958 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4959 0, 0, 640, 480, 0, 0, 0, 0);
4960 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4961 ok(!!d3d, "Failed to create a D3D object.\n");
4962 if (!(device = create_device(d3d, window, window, TRUE)))
4964 skip("Failed to create a D3D device, skipping tests.\n");
4965 IDirect3D9_Release(d3d);
4966 DestroyWindow(window);
4967 return;
4970 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4971 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4972 if (!(caps.PixelShaderVersion & 0xffff))
4974 skip("No pixel shader support, skipping tests.\n");
4975 IDirect3DDevice9_Release(device);
4976 IDirect3D9_Release(d3d);
4977 DestroyWindow(window);
4978 return;
4981 /* A simple check that the stuff works at all. */
4982 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
4983 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4985 /* Is there really no max pixel shader constant value??? Test how far I can go. */
4986 while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
4987 consts = consts - 1;
4988 trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
4990 /* Test corner cases: Write 4 consts from MAX - 1, everything else is
4991 * pointless given the way the constant limit was determined. */
4992 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
4993 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4995 /* Constant -1. */
4996 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
4997 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4999 refcount = IDirect3DDevice9_Release(device);
5000 ok(!refcount, "Device has %u references left.\n", refcount);
5001 IDirect3D9_Release(d3d);
5002 DestroyWindow(window);
5005 static void test_wrong_shader(void)
5007 static const DWORD vs_3_0[] =
5009 0xfffe0300, /* vs_3_0 */
5010 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5011 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5012 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5013 0x0000ffff, /* end */
5016 #if 0
5017 float4 main(const float4 color : COLOR) : SV_TARGET
5019 float4 o;
5021 o = color;
5023 return o;
5025 #endif
5026 static const DWORD ps_4_0[] =
5028 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
5029 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
5030 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
5031 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
5032 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
5033 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
5034 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
5035 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
5036 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
5037 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
5038 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
5039 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5040 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5041 0x00000000, 0x00000000, 0x00000000,
5044 IDirect3DVertexShader9 *vs = NULL;
5045 IDirect3DPixelShader9 *ps = NULL;
5046 IDirect3DDevice9 *device;
5047 IDirect3D9 * d3d;
5048 ULONG refcount;
5049 D3DCAPS9 caps;
5050 HWND window;
5051 HRESULT hr;
5053 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5054 0, 0, 640, 480, 0, 0, 0, 0);
5055 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5056 ok(!!d3d, "Failed to create a D3D object.\n");
5057 if (!(device = create_device(d3d, window, window, TRUE)))
5059 skip("Failed to create a D3D device, skipping tests.\n");
5060 IDirect3D9_Release(d3d);
5061 DestroyWindow(window);
5062 return;
5065 /* These should always fail, regardless of supported shader version. */
5066 hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
5067 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5068 hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
5069 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5070 hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
5071 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5073 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5074 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5075 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
5077 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
5078 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5080 else
5081 skip("This GPU supports SM3, skipping unsupported shader test.\n");
5083 refcount = IDirect3DDevice9_Release(device);
5084 ok(!refcount, "Device has %u references left.\n", refcount);
5085 IDirect3D9_Release(d3d);
5086 DestroyWindow(window);
5089 /* Test the default texture stage state values */
5090 static void test_texture_stage_states(void)
5092 IDirect3DDevice9 *device;
5093 IDirect3D9 *d3d;
5094 unsigned int i;
5095 ULONG refcount;
5096 D3DCAPS9 caps;
5097 DWORD value;
5098 HWND window;
5099 HRESULT hr;
5101 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5102 0, 0, 640, 480, 0, 0, 0, 0);
5103 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5104 ok(!!d3d, "Failed to create a D3D object.\n");
5105 if (!(device = create_device(d3d, window, window, TRUE)))
5107 skip("Failed to create a D3D device, skipping tests.\n");
5108 IDirect3D9_Release(d3d);
5109 DestroyWindow(window);
5110 return;
5113 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5114 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5116 for (i = 0; i < caps.MaxTextureBlendStages; ++i)
5118 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
5119 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5120 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
5121 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
5122 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
5123 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5124 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
5125 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
5126 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5127 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
5128 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
5129 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5130 ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
5131 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
5132 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
5133 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5134 ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
5135 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
5136 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5137 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
5138 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
5139 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5140 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
5141 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
5142 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5143 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
5144 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
5145 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5146 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
5147 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
5148 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5149 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
5150 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
5151 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5152 ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
5153 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
5154 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5155 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
5156 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
5157 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5158 ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
5159 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
5160 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5161 ok(value == D3DTTFF_DISABLE,
5162 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
5163 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
5164 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5165 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
5166 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
5167 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5168 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
5169 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
5170 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5171 ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value, i);
5172 hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
5173 ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
5174 ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
5177 refcount = IDirect3DDevice9_Release(device);
5178 ok(!refcount, "Device has %u references left.\n", refcount);
5179 IDirect3D9_Release(d3d);
5180 DestroyWindow(window);
5183 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
5185 IDirect3DCubeTexture9 *texture;
5186 IDirect3D9 *d3d;
5187 HRESULT hr;
5189 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
5190 ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
5191 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5192 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
5193 IDirect3D9_Release(d3d);
5194 if (FAILED(hr))
5196 skip("No cube mipmap generation support, skipping tests.\n");
5197 return;
5200 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
5201 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5202 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5203 IDirect3DCubeTexture9_Release(texture);
5205 hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
5206 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5207 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5208 IDirect3DCubeTexture9_Release(texture);
5211 static void test_cube_texture_levels(IDirect3DDevice9 *device)
5213 IDirect3DCubeTexture9 *texture;
5214 IDirect3DSurface9 *surface;
5215 D3DSURFACE_DESC desc;
5216 DWORD levels;
5217 HRESULT hr;
5218 D3DCAPS9 caps;
5220 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5221 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5222 if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
5223 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
5225 skip("Failed to create cube texture, skipping tests.\n");
5226 return;
5229 levels = IDirect3DCubeTexture9_GetLevelCount(texture);
5230 if (caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)
5231 ok(levels == 7, "Got unexpected levels %u.\n", levels);
5232 else
5233 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5235 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
5236 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5237 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
5238 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5239 hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
5240 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5242 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
5243 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5244 IDirect3DSurface9_Release(surface);
5245 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
5246 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5247 hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
5248 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5250 IDirect3DCubeTexture9_Release(texture);
5253 static void test_cube_textures(void)
5255 IDirect3DCubeTexture9 *texture;
5256 IDirect3DDevice9 *device;
5257 IDirect3D9 *d3d;
5258 ULONG refcount;
5259 D3DCAPS9 caps;
5260 HWND window;
5261 HRESULT hr;
5263 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5264 0, 0, 640, 480, 0, 0, 0, 0);
5265 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5266 ok(!!d3d, "Failed to create a D3D object.\n");
5267 if (!(device = create_device(d3d, window, window, TRUE)))
5269 skip("Failed to create a D3D device, skipping tests.\n");
5270 IDirect3D9_Release(d3d);
5271 DestroyWindow(window);
5272 return;
5275 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5276 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5278 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
5280 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5281 ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
5282 IDirect3DCubeTexture9_Release(texture);
5283 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5284 ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
5285 IDirect3DCubeTexture9_Release(texture);
5286 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
5287 ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
5288 IDirect3DCubeTexture9_Release(texture);
5290 else
5292 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5293 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
5294 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5295 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
5296 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
5297 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
5299 hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
5300 ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
5301 IDirect3DCubeTexture9_Release(texture);
5303 test_cube_texture_mipmap_gen(device);
5304 test_cube_texture_levels(device);
5306 refcount = IDirect3DDevice9_Release(device);
5307 ok(!refcount, "Device has %u references left.\n", refcount);
5308 IDirect3D9_Release(d3d);
5309 DestroyWindow(window);
5312 static void test_mipmap_gen(void)
5314 D3DTEXTUREFILTERTYPE filter_type;
5315 IDirect3DTexture9 *texture;
5316 IDirect3DSurface9 *surface;
5317 IDirect3DDevice9 *device;
5318 D3DSURFACE_DESC desc;
5319 D3DLOCKED_RECT lr;
5320 IDirect3D9 *d3d;
5321 ULONG refcount;
5322 unsigned int i;
5323 DWORD levels;
5324 HWND window;
5325 HRESULT hr;
5327 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5328 ok(!!d3d, "Failed to create a D3D object.\n");
5330 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5331 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
5333 skip("No mipmap generation support, skipping tests.\n");
5334 IDirect3D9_Release(d3d);
5335 return;
5338 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5339 0, 0, 640, 480, 0, 0, 0, 0);
5340 if (!(device = create_device(d3d, window, window, TRUE)))
5342 skip("Failed to create a D3D device, skipping tests.\n");
5343 IDirect3D9_Release(d3d);
5344 DestroyWindow(window);
5345 return;
5348 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
5349 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5350 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5351 IDirect3DTexture9_Release(texture);
5353 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
5354 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
5355 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5357 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
5358 ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
5359 "Got unexpected filter_type %#x.\n", filter_type);
5360 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
5361 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5362 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
5363 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5364 filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
5365 ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
5366 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
5367 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5369 levels = IDirect3DTexture9_GetLevelCount(texture);
5370 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5372 for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
5374 surface = NULL;
5375 hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
5376 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5377 if (surface)
5378 IDirect3DSurface9_Release(surface);
5380 hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
5381 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5383 hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
5384 ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
5385 if (SUCCEEDED(hr))
5387 hr = IDirect3DTexture9_UnlockRect(texture, i);
5388 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5391 IDirect3DTexture9_Release(texture);
5393 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
5394 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5395 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5396 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
5397 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5398 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5400 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
5401 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5402 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5403 levels = IDirect3DTexture9_GetLevelCount(texture);
5404 ok(levels == 1, "Got unexpected levels %u.\n", levels);
5405 IDirect3DTexture9_Release(texture);
5407 refcount = IDirect3DDevice9_Release(device);
5408 ok(!refcount, "Device has %u references left.\n", refcount);
5409 IDirect3D9_Release(d3d);
5410 DestroyWindow(window);
5413 static void test_filter(void)
5415 static const struct
5417 DWORD magfilter, minfilter, mipfilter;
5418 BOOL has_texture;
5419 HRESULT result;
5421 tests[] =
5423 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5424 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5425 {D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5426 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, FALSE, D3D_OK },
5427 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, FALSE, D3D_OK },
5429 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5430 {D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5431 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, D3D_OK },
5432 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT, TRUE, D3D_OK },
5434 {D3DTEXF_NONE, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5435 {D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_NONE, TRUE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
5436 {D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_NONE, TRUE, E_FAIL },
5437 {D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_NONE, TRUE, E_FAIL },
5438 {D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_LINEAR, TRUE, E_FAIL },
5440 IDirect3DTexture9 *texture;
5441 IDirect3DDevice9 *device;
5442 IDirect3D9 *d3d;
5443 unsigned int i;
5444 ULONG refcount;
5445 DWORD passes;
5446 HWND window;
5447 HRESULT hr;
5449 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5450 ok(!!d3d, "Failed to create a D3D object.\n");
5452 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5453 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
5455 skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
5456 IDirect3D9_Release(d3d);
5457 return;
5460 if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5461 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
5463 skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
5464 IDirect3D9_Release(d3d);
5465 return;
5468 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5469 0, 0, 640, 480, 0, 0, 0, 0);
5470 if (!(device = create_device(d3d, window, window, TRUE)))
5472 skip("Failed to create a D3D device, skipping tests.\n");
5473 IDirect3D9_Release(d3d);
5474 DestroyWindow(window);
5475 return;
5478 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
5479 D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
5480 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5482 /* Needed for ValidateDevice(). */
5483 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5484 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5486 for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
5488 if (tests[i].has_texture)
5490 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
5491 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5493 else
5495 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5496 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5499 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
5500 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5501 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
5502 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5503 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
5504 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
5506 passes = 0xdeadbeef;
5507 hr = IDirect3DDevice9_ValidateDevice(device, &passes);
5508 ok(hr == tests[i].result,
5509 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
5510 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
5511 tests[i].mipfilter, tests[i].has_texture);
5512 if (SUCCEEDED(hr))
5513 ok(!!passes, "Got unexpected passes %#x.\n", passes);
5514 else
5515 ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
5518 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5519 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5520 IDirect3DTexture9_Release(texture);
5522 refcount = IDirect3DDevice9_Release(device);
5523 ok(!refcount, "Device has %u references left.\n", refcount);
5524 IDirect3D9_Release(d3d);
5525 DestroyWindow(window);
5528 static void test_get_texture(void)
5530 IDirect3DBaseTexture9 *texture;
5531 IDirect3DDevice9 *device;
5532 IDirect3D9 *d3d;
5533 ULONG refcount;
5534 HWND window;
5535 HRESULT hr;
5537 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5538 0, 0, 640, 480, 0, 0, 0, 0);
5539 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5540 ok(!!d3d, "Failed to create a D3D object.\n");
5541 if (!(device = create_device(d3d, window, window, TRUE)))
5543 skip("Failed to create a D3D device, skipping tests.\n");
5544 IDirect3D9_Release(d3d);
5545 DestroyWindow(window);
5546 return;
5549 texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
5550 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5551 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5552 hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
5553 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5554 ok(!texture, "Got unexpected texture %p.\n", texture);
5556 refcount = IDirect3DDevice9_Release(device);
5557 ok(!refcount, "Device has %u references left.\n", refcount);
5558 IDirect3D9_Release(d3d);
5559 DestroyWindow(window);
5562 static void test_lod(void)
5564 IDirect3DTexture9 *texture;
5565 IDirect3DDevice9 *device;
5566 IDirect3D9 *d3d;
5567 ULONG refcount;
5568 HWND window;
5569 HRESULT hr;
5570 DWORD ret;
5572 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5573 0, 0, 640, 480, 0, 0, 0, 0);
5574 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5575 ok(!!d3d, "Failed to create a D3D object.\n");
5576 if (!(device = create_device(d3d, window, window, TRUE)))
5578 skip("Failed to create a D3D device, skipping tests.\n");
5579 IDirect3D9_Release(d3d);
5580 DestroyWindow(window);
5581 return;
5584 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5585 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5586 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5588 /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5589 * return a HRESULT, so it can't return a normal error. Instead, the call
5590 * is simply ignored. */
5591 ret = IDirect3DTexture9_SetLOD(texture, 0);
5592 ok(!ret, "Got unexpected ret %u.\n", ret);
5593 ret = IDirect3DTexture9_SetLOD(texture, 1);
5594 ok(!ret, "Got unexpected ret %u.\n", ret);
5595 ret = IDirect3DTexture9_SetLOD(texture, 2);
5596 ok(!ret, "Got unexpected ret %u.\n", ret);
5597 ret = IDirect3DTexture9_GetLOD(texture);
5598 ok(!ret, "Got unexpected ret %u.\n", ret);
5600 IDirect3DTexture9_Release(texture);
5601 refcount = IDirect3DDevice9_Release(device);
5602 ok(!refcount, "Device has %u references left.\n", refcount);
5603 IDirect3D9_Release(d3d);
5604 DestroyWindow(window);
5607 static void test_surface_get_container(void)
5609 IDirect3DTexture9 *texture = NULL;
5610 IDirect3DSurface9 *surface = NULL;
5611 IDirect3DDevice9 *device;
5612 IUnknown *container;
5613 IDirect3D9 *d3d;
5614 ULONG refcount;
5615 HWND window;
5616 HRESULT hr;
5618 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5619 0, 0, 640, 480, 0, 0, 0, 0);
5620 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5621 ok(!!d3d, "Failed to create a D3D object.\n");
5622 if (!(device = create_device(d3d, window, window, TRUE)))
5624 skip("Failed to create a D3D device, skipping tests.\n");
5625 IDirect3D9_Release(d3d);
5626 DestroyWindow(window);
5627 return;
5630 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
5631 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5632 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5633 ok(!!texture, "Got unexpected texture %p.\n", texture);
5635 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5636 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5637 ok(!!surface, "Got unexpected surface %p.\n", surface);
5639 /* These should work... */
5640 container = NULL;
5641 hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
5642 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5643 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5644 IUnknown_Release(container);
5646 container = NULL;
5647 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
5648 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5649 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5650 IUnknown_Release(container);
5652 container = NULL;
5653 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
5654 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5655 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5656 IUnknown_Release(container);
5658 container = NULL;
5659 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
5660 ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5661 ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5662 IUnknown_Release(container);
5664 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5665 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
5666 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5667 ok(!container, "Got unexpected container %p.\n", container);
5669 IDirect3DSurface9_Release(surface);
5670 IDirect3DTexture9_Release(texture);
5671 refcount = IDirect3DDevice9_Release(device);
5672 ok(!refcount, "Device has %u references left.\n", refcount);
5673 IDirect3D9_Release(d3d);
5674 DestroyWindow(window);
5677 static void test_surface_alignment(void)
5679 IDirect3DSurface9 *surface;
5680 IDirect3DDevice9 *device;
5681 D3DLOCKED_RECT lr;
5682 unsigned int i, j;
5683 IDirect3D9 *d3d;
5684 ULONG refcount;
5685 HWND window;
5686 HRESULT hr;
5688 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5689 0, 0, 640, 480, 0, 0, 0, 0);
5690 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5691 ok(!!d3d, "Failed to create a D3D object.\n");
5692 if (!(device = create_device(d3d, window, window, TRUE)))
5694 skip("Failed to create a D3D device, skipping tests.\n");
5695 IDirect3D9_Release(d3d);
5696 DestroyWindow(window);
5697 return;
5700 /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
5701 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
5702 D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
5703 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5705 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5706 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5707 ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
5708 /* Some applications also depend on the exact pitch, rather than just the
5709 * alignment. */
5710 ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
5711 hr = IDirect3DSurface9_UnlockRect(surface);
5712 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5713 IDirect3DSurface9_Release(surface);
5715 for (i = 0; i < 5; ++i)
5717 IDirect3DTexture9 *texture;
5718 unsigned int level_count;
5719 D3DSURFACE_DESC desc;
5720 int expected_pitch;
5722 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
5723 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
5724 ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5725 if (FAILED(hr))
5727 skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
5728 continue;
5731 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
5732 for (j = 0; j < level_count; ++j)
5734 IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
5735 hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
5736 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5737 hr = IDirect3DTexture9_UnlockRect(texture, j);
5738 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5740 expected_pitch = ((desc.Width + 3) >> 2) << 3;
5741 if (i > 0)
5742 expected_pitch <<= 1;
5743 ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
5744 lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
5746 IDirect3DTexture9_Release(texture);
5749 refcount = IDirect3DDevice9_Release(device);
5750 ok(!refcount, "Device has %u references left.\n", refcount);
5751 IDirect3D9_Release(d3d);
5752 DestroyWindow(window);
5755 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
5756 * different from regular formats. This test verifies we return the correct
5757 * memory offsets. */
5758 static void test_lockrect_offset(void)
5760 static const struct
5762 D3DFORMAT format;
5763 const char *name;
5764 unsigned int block_width;
5765 unsigned int block_height;
5766 unsigned int block_size;
5768 dxt_formats[] =
5770 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 8},
5771 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 16},
5772 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 16},
5773 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 16},
5774 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 16},
5775 {MAKEFOURCC('A','T','I','2'), "ATI2N", 1, 1, 1},
5777 unsigned int expected_offset, offset, i;
5778 const RECT rect = {60, 60, 68, 68};
5779 IDirect3DSurface9 *surface;
5780 D3DLOCKED_RECT locked_rect;
5781 IDirect3DDevice9 *device;
5782 int expected_pitch;
5783 IDirect3D9 *d3d;
5784 ULONG refcount;
5785 HWND window;
5786 BYTE *base;
5787 HRESULT hr;
5789 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5790 0, 0, 640, 480, 0, 0, 0, 0);
5791 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5792 ok(!!d3d, "Failed to create a D3D object.\n");
5793 if (!(device = create_device(d3d, window, window, TRUE)))
5795 skip("Failed to create a D3D device, skipping tests.\n");
5796 IDirect3D9_Release(d3d);
5797 DestroyWindow(window);
5798 return;
5801 for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
5803 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5804 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
5806 skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
5807 continue;
5810 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5811 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
5812 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5814 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5815 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5817 base = locked_rect.pBits;
5818 expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
5819 * dxt_formats[i].block_size;
5820 ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
5821 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
5823 hr = IDirect3DSurface9_UnlockRect(surface);
5824 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5826 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5827 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5829 offset = (BYTE *)locked_rect.pBits - base;
5830 expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
5831 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
5832 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
5833 offset, dxt_formats[i].name, expected_offset);
5835 hr = IDirect3DSurface9_UnlockRect(surface);
5836 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5838 IDirect3DSurface9_Release(surface);
5841 refcount = IDirect3DDevice9_Release(device);
5842 ok(!refcount, "Device has %u references left.\n", refcount);
5843 IDirect3D9_Release(d3d);
5844 DestroyWindow(window);
5847 static void test_lockrect_invalid(void)
5849 static const struct
5851 RECT rect;
5852 HRESULT win7_result;
5854 test_data[] =
5856 {{60, 60, 68, 68}, D3D_OK}, /* Valid */
5857 {{60, 60, 60, 68}, D3DERR_INVALIDCALL}, /* 0 height */
5858 {{60, 60, 68, 60}, D3DERR_INVALIDCALL}, /* 0 width */
5859 {{68, 60, 60, 68}, D3DERR_INVALIDCALL}, /* left > right */
5860 {{60, 68, 68, 60}, D3DERR_INVALIDCALL}, /* top > bottom */
5861 {{-8, 60, 0, 68}, D3DERR_INVALIDCALL}, /* left < surface */
5862 {{60, -8, 68, 0}, D3DERR_INVALIDCALL}, /* top < surface */
5863 {{-16, 60, -8, 68}, D3DERR_INVALIDCALL}, /* right < surface */
5864 {{60, -16, 68, -8}, D3DERR_INVALIDCALL}, /* bottom < surface */
5865 {{60, 60, 136, 68}, D3DERR_INVALIDCALL}, /* right > surface */
5866 {{60, 60, 68, 136}, D3DERR_INVALIDCALL}, /* bottom > surface */
5867 {{136, 60, 144, 68}, D3DERR_INVALIDCALL}, /* left > surface */
5868 {{60, 136, 68, 144}, D3DERR_INVALIDCALL}, /* top > surface */
5870 static const RECT test_rect_2 = {0, 0, 8, 8};
5871 IDirect3DSurface9 *surface = NULL;
5872 D3DLOCKED_RECT locked_rect;
5873 IDirect3DDevice9 *device;
5874 IDirect3D9 *d3d;
5875 unsigned int i;
5876 ULONG refcount;
5877 HWND window;
5878 BYTE *base;
5879 HRESULT hr;
5881 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5882 0, 0, 640, 480, 0, 0, 0, 0);
5883 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5884 ok(!!d3d, "Failed to create a D3D object.\n");
5885 if (!(device = create_device(d3d, window, window, TRUE)))
5887 skip("Failed to create a D3D device, skipping tests.\n");
5888 IDirect3D9_Release(d3d);
5889 DestroyWindow(window);
5890 return;
5893 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5894 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5895 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5896 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5897 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5898 base = locked_rect.pBits;
5899 hr = IDirect3DSurface9_UnlockRect(surface);
5900 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5902 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
5904 unsigned int offset, expected_offset;
5905 const RECT *rect = &test_data[i].rect;
5907 locked_rect.pBits = (BYTE *)0xdeadbeef;
5908 locked_rect.Pitch = 0xdeadbeef;
5910 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
5911 /* Windows XP accepts invalid locking rectangles, windows 7 rejects
5912 * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
5913 * one broken. */
5914 ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
5915 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
5916 rect->left, rect->top, rect->right, rect->bottom, hr);
5917 if (FAILED(hr))
5918 continue;
5920 offset = (BYTE *)locked_rect.pBits - base;
5921 expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
5922 ok(offset == expected_offset,
5923 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
5924 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
5926 hr = IDirect3DSurface9_UnlockRect(surface);
5927 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5930 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5931 ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
5932 locked_rect.pBits = (BYTE *)0xdeadbeef;
5933 locked_rect.Pitch = 1;
5934 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5935 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5936 ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p\n",
5937 locked_rect.pBits);
5938 ok(locked_rect.Pitch == 1, "Got unexpected pitch %d\n", locked_rect.Pitch);
5939 hr = IDirect3DSurface9_UnlockRect(surface);
5940 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5942 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5943 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5944 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5945 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5946 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5947 hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5948 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
5949 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5950 hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
5951 hr = IDirect3DSurface9_UnlockRect(surface);
5952 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5954 IDirect3DSurface9_Release(surface);
5955 refcount = IDirect3DDevice9_Release(device);
5956 ok(!refcount, "Device has %u references left.\n", refcount);
5957 IDirect3D9_Release(d3d);
5958 DestroyWindow(window);
5961 static void test_private_data(void)
5963 ULONG refcount, expected_refcount;
5964 IDirect3DTexture9 *texture;
5965 IDirect3DSurface9 *surface, *surface2;
5966 IDirect3DDevice9 *device;
5967 IDirect3D9 *d3d;
5968 IUnknown *ptr;
5969 HWND window;
5970 HRESULT hr;
5971 DWORD size;
5972 DWORD data[4] = {1, 2, 3, 4};
5973 static const GUID d3d9_private_data_test_guid =
5975 0xfdb37466,
5976 0x428f,
5977 0x4edf,
5978 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
5980 static const GUID d3d9_private_data_test_guid2 =
5982 0x2e5afac2,
5983 0x87b5,
5984 0x4c10,
5985 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
5988 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5989 0, 0, 640, 480, 0, 0, 0, 0);
5990 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5991 ok(!!d3d, "Failed to create a D3D object.\n");
5992 if (!(device = create_device(d3d, window, window, TRUE)))
5994 skip("Failed to create a D3D device, skipping tests.\n");
5995 IDirect3D9_Release(d3d);
5996 DestroyWindow(window);
5997 return;
6000 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
6001 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6002 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6004 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6005 device, 0, D3DSPD_IUNKNOWN);
6006 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6007 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6008 device, 5, D3DSPD_IUNKNOWN);
6009 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6010 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6011 device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
6012 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6014 /* A failing SetPrivateData call does not clear the old data with the same tag. */
6015 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
6016 sizeof(device), D3DSPD_IUNKNOWN);
6017 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6018 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, device,
6019 sizeof(device) * 2, D3DSPD_IUNKNOWN);
6020 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6021 size = sizeof(ptr);
6022 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6023 ok(SUCCEEDED(hr), "Failed to get private data, hr %#x.\n", hr);
6024 IUnknown_Release(ptr);
6025 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6026 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6028 refcount = get_refcount((IUnknown *)device);
6029 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6030 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6031 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6032 expected_refcount = refcount + 1;
6033 refcount = get_refcount((IUnknown *)device);
6034 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6035 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6036 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6037 expected_refcount = refcount - 1;
6038 refcount = get_refcount((IUnknown *)device);
6039 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6041 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6042 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6043 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6044 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6045 surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6046 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6047 refcount = get_refcount((IUnknown *)device);
6048 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6050 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid,
6051 device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
6052 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6053 size = 2 * sizeof(ptr);
6054 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6055 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6056 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6057 expected_refcount = refcount + 2;
6058 refcount = get_refcount((IUnknown *)device);
6059 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6060 ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
6061 IUnknown_Release(ptr);
6062 expected_refcount--;
6064 ptr = (IUnknown *)0xdeadbeef;
6065 size = 1;
6066 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
6067 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6068 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6069 size = 2 * sizeof(ptr);
6070 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, NULL, &size);
6071 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
6072 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6073 refcount = get_refcount((IUnknown *)device);
6074 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6075 size = 1;
6076 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, &ptr, &size);
6077 ok(hr == D3DERR_MOREDATA, "Got unexpected hr %#x.\n", hr);
6078 ok(size == sizeof(device), "Got unexpected size %u.\n", size);
6079 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
6080 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, NULL, NULL);
6081 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6082 size = 0xdeadbabe;
6083 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid2, &ptr, &size);
6084 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6085 ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
6086 ok(size == 0xdeadbabe, "Got unexpected size %u.\n", size);
6087 /* GetPrivateData with size = NULL causes an access violation on Windows if the
6088 * requested data exists. */
6090 /* Destroying the surface frees the held reference. */
6091 IDirect3DSurface9_Release(surface);
6092 expected_refcount = refcount - 2;
6093 refcount = get_refcount((IUnknown *)device);
6094 ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
6096 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH,
6097 &texture, NULL);
6098 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6099 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6100 ok(SUCCEEDED(hr), "Failed to get texture level 0, hr %#x.\n", hr);
6101 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
6102 ok(SUCCEEDED(hr), "Failed to get texture level 1, hr %#x.\n", hr);
6104 hr = IDirect3DTexture9_SetPrivateData(texture, &d3d9_private_data_test_guid, data, sizeof(data), 0);
6105 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6107 memset(data, 0, sizeof(data));
6108 size = sizeof(data);
6109 hr = IDirect3DSurface9_GetPrivateData(surface, &d3d9_private_data_test_guid, data, &size);
6110 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6111 hr = IDirect3DTexture9_GetPrivateData(texture, &d3d9_private_data_test_guid, data, &size);
6112 ok(SUCCEEDED(hr), "Failed to get private data, hr %#x.\n", hr);
6113 ok(data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4,
6114 "Got unexpected private data: %u, %u, %u, %u.\n", data[0], data[1], data[2], data[3]);
6116 hr = IDirect3DTexture9_FreePrivateData(texture, &d3d9_private_data_test_guid);
6117 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6119 hr = IDirect3DSurface9_SetPrivateData(surface, &d3d9_private_data_test_guid, data, sizeof(data), 0);
6120 ok(SUCCEEDED(hr), "Failed to set private data, hr %#x.\n", hr);
6121 hr = IDirect3DSurface9_GetPrivateData(surface2, &d3d9_private_data_test_guid, data, &size);
6122 ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
6124 hr = IDirect3DSurface9_FreePrivateData(surface, &d3d9_private_data_test_guid);
6125 ok(SUCCEEDED(hr), "Failed to free private data, hr %#x.\n", hr);
6127 IDirect3DSurface9_Release(surface2);
6128 IDirect3DSurface9_Release(surface);
6129 IDirect3DTexture9_Release(texture);
6131 refcount = IDirect3DDevice9_Release(device);
6132 ok(!refcount, "Device has %u references left.\n", refcount);
6133 IDirect3D9_Release(d3d);
6134 DestroyWindow(window);
6137 static void test_getdc(void)
6139 static const struct
6141 const char *name;
6142 D3DFORMAT format;
6143 BOOL getdc_supported;
6145 testdata[] =
6147 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8, TRUE },
6148 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8, TRUE },
6149 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5, TRUE },
6150 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5, TRUE },
6151 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5, TRUE },
6152 {"D3DFMT_R8G8B8", D3DFMT_R8G8B8, TRUE },
6153 {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
6154 {"D3DFMT_V8U8", D3DFMT_V8U8, FALSE},
6155 {"D3DFMT_Q8W8V8U8", D3DFMT_Q8W8V8U8, FALSE},
6156 {"D3DFMT_A8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
6157 {"D3DFMT_X8B8G8R8", D3DFMT_A8B8G8R8, FALSE},
6158 {"D3DFMT_R3G3B2", D3DFMT_R3G3B2, FALSE},
6159 {"D3DFMT_P8", D3DFMT_P8, FALSE},
6160 {"D3DFMT_L8", D3DFMT_L8, FALSE},
6161 {"D3DFMT_A8L8", D3DFMT_A8L8, FALSE},
6162 {"D3DFMT_DXT1", D3DFMT_DXT1, FALSE},
6163 {"D3DFMT_DXT2", D3DFMT_DXT2, FALSE},
6164 {"D3DFMT_DXT3", D3DFMT_DXT3, FALSE},
6165 {"D3DFMT_DXT4", D3DFMT_DXT4, FALSE},
6166 {"D3DFMT_DXT5", D3DFMT_DXT5, FALSE},
6168 IDirect3DTexture9 *texture;
6169 IDirect3DSurface9 *surface;
6170 IDirect3DDevice9 *device;
6171 IDirect3D9 *d3d;
6172 unsigned int i;
6173 ULONG refcount;
6174 HWND window;
6175 HRESULT hr;
6176 HDC dc;
6178 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6179 0, 0, 640, 480, 0, 0, 0, 0);
6180 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6181 ok(!!d3d, "Failed to create a D3D object.\n");
6182 if (!(device = create_device(d3d, window, window, TRUE)))
6184 skip("Failed to create a D3D device, skipping tests.\n");
6185 IDirect3D9_Release(d3d);
6186 DestroyWindow(window);
6187 return;
6190 for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
6192 texture = NULL;
6193 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
6194 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
6195 if (FAILED(hr))
6197 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
6198 testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
6199 if (FAILED(hr))
6201 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
6202 continue;
6204 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6205 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
6208 dc = (void *)0x1234;
6209 hr = IDirect3DSurface9_GetDC(surface, &dc);
6210 if (testdata[i].getdc_supported)
6211 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
6212 else
6213 ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
6215 if (SUCCEEDED(hr))
6217 hr = IDirect3DSurface9_ReleaseDC(surface, dc);
6218 ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
6220 else
6222 ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
6225 IDirect3DSurface9_Release(surface);
6226 if (texture)
6227 IDirect3DTexture9_Release(texture);
6230 refcount = IDirect3DDevice9_Release(device);
6231 ok(!refcount, "Device has %u references left.\n", refcount);
6232 IDirect3D9_Release(d3d);
6233 DestroyWindow(window);
6236 static void test_surface_dimensions(void)
6238 IDirect3DSurface9 *surface;
6239 IDirect3DDevice9 *device;
6240 IDirect3D9 *d3d;
6241 ULONG refcount;
6242 HWND window;
6243 HRESULT hr;
6245 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6246 0, 0, 640, 480, 0, 0, 0, 0);
6247 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6248 ok(!!d3d, "Failed to create a D3D object.\n");
6249 if (!(device = create_device(d3d, window, window, TRUE)))
6251 skip("Failed to create a D3D device, skipping tests.\n");
6252 IDirect3D9_Release(d3d);
6253 DestroyWindow(window);
6254 return;
6257 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
6258 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6259 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6260 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
6261 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
6262 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6264 refcount = IDirect3DDevice9_Release(device);
6265 ok(!refcount, "Device has %u references left.\n", refcount);
6266 IDirect3D9_Release(d3d);
6267 DestroyWindow(window);
6270 static void test_surface_format_null(void)
6272 static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
6273 IDirect3DTexture9 *texture;
6274 IDirect3DSurface9 *surface;
6275 IDirect3DSurface9 *rt, *ds;
6276 D3DLOCKED_RECT locked_rect;
6277 IDirect3DDevice9 *device;
6278 D3DSURFACE_DESC desc;
6279 IDirect3D9 *d3d;
6280 ULONG refcount;
6281 HWND window;
6282 HRESULT hr;
6284 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6285 ok(!!d3d, "Failed to create a D3D object.\n");
6287 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6288 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
6289 if (hr != D3D_OK)
6291 skip("No D3DFMT_NULL support, skipping test.\n");
6292 IDirect3D9_Release(d3d);
6293 return;
6296 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6297 0, 0, 640, 480, 0, 0, 0, 0);
6298 if (!(device = create_device(d3d, window, window, TRUE)))
6300 skip("Failed to create a D3D device, skipping tests.\n");
6301 IDirect3D9_Release(d3d);
6302 DestroyWindow(window);
6303 return;
6306 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6307 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
6308 ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
6310 hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6311 D3DFMT_NULL, D3DFMT_D24S8);
6312 ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
6314 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
6315 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
6316 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
6318 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
6319 ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
6321 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
6322 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
6324 hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
6325 ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
6327 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
6328 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6330 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
6331 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
6333 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
6334 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
6336 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
6337 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6339 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
6340 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
6342 IDirect3DSurface9_Release(rt);
6343 IDirect3DSurface9_Release(ds);
6345 hr = IDirect3DSurface9_GetDesc(surface, &desc);
6346 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
6347 ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
6348 ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
6350 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
6351 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6352 ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
6353 ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
6355 hr = IDirect3DSurface9_UnlockRect(surface);
6356 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6358 IDirect3DSurface9_Release(surface);
6360 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
6361 D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
6362 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6363 IDirect3DTexture9_Release(texture);
6365 refcount = IDirect3DDevice9_Release(device);
6366 ok(!refcount, "Device has %u references left.\n", refcount);
6367 IDirect3D9_Release(d3d);
6368 DestroyWindow(window);
6371 static void test_surface_double_unlock(void)
6373 static const D3DPOOL pools[] =
6375 D3DPOOL_DEFAULT,
6376 D3DPOOL_SCRATCH,
6377 D3DPOOL_SYSTEMMEM,
6379 IDirect3DSurface9 *surface;
6380 IDirect3DDevice9 *device;
6381 D3DLOCKED_RECT lr;
6382 IDirect3D9 *d3d;
6383 unsigned int i;
6384 ULONG refcount;
6385 HWND window;
6386 HRESULT hr;
6388 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6389 0, 0, 640, 480, 0, 0, 0, 0);
6390 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6391 ok(!!d3d, "Failed to create a D3D object.\n");
6392 if (!(device = create_device(d3d, window, window, TRUE)))
6394 skip("Failed to create a D3D device, skipping tests.\n");
6395 IDirect3D9_Release(d3d);
6396 DestroyWindow(window);
6397 return;
6400 for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
6402 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
6403 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
6404 ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
6406 hr = IDirect3DSurface9_UnlockRect(surface);
6407 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
6408 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6409 ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
6410 hr = IDirect3DSurface9_UnlockRect(surface);
6411 ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
6412 hr = IDirect3DSurface9_UnlockRect(surface);
6413 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
6415 IDirect3DSurface9_Release(surface);
6418 refcount = IDirect3DDevice9_Release(device);
6419 ok(!refcount, "Device has %u references left.\n", refcount);
6420 IDirect3D9_Release(d3d);
6421 DestroyWindow(window);
6424 static void test_surface_blocks(void)
6426 static const struct
6428 D3DFORMAT fmt;
6429 const char *name;
6430 unsigned int block_width;
6431 unsigned int block_height;
6432 BOOL broken;
6433 BOOL create_size_checked, core_fmt;
6435 formats[] =
6437 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, FALSE, TRUE, TRUE },
6438 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, FALSE, TRUE, TRUE },
6439 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, FALSE, TRUE, TRUE },
6440 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, FALSE, TRUE, TRUE },
6441 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, FALSE, TRUE, TRUE },
6442 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
6443 * which doesn't match the format spec. On newer Nvidia cards
6444 * it has the correct 4x4 block size */
6445 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE, FALSE, FALSE},
6446 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, FALSE, FALSE, TRUE },
6447 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, FALSE, FALSE, TRUE },
6449 static const struct
6451 D3DPOOL pool;
6452 const char *name;
6453 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
6454 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
6455 BOOL success;
6457 pools[] =
6459 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", FALSE},
6460 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", TRUE},
6461 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE},
6462 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE},
6464 static struct
6466 D3DRESOURCETYPE rtype;
6467 const char *type_name;
6468 D3DPOOL pool;
6469 const char *pool_name;
6470 BOOL need_driver_support, need_runtime_support;
6472 create_tests[] =
6474 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6475 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, TRUE },
6476 /* Managed offscreen plain surfaces are not supported */
6477 {D3DRTYPE_SURFACE, "D3DRTYPE_SURFACE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6479 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6480 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
6481 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
6482 {D3DRTYPE_TEXTURE, "D3DRTYPE_TEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6484 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
6485 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", TRUE, FALSE},
6486 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
6487 {D3DRTYPE_CUBETEXTURE, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
6489 IDirect3DTexture9 *texture;
6490 IDirect3DCubeTexture9 *cube_texture;
6491 IDirect3DSurface9 *surface;
6492 D3DLOCKED_RECT locked_rect;
6493 IDirect3DDevice9 *device;
6494 unsigned int i, j, w, h;
6495 BOOL surface_only;
6496 IDirect3D9 *d3d;
6497 ULONG refcount;
6498 HWND window;
6499 HRESULT hr;
6500 RECT rect;
6501 BOOL tex_pow2, cube_pow2;
6502 D3DCAPS9 caps;
6504 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
6505 0, 0, 640, 480, 0, 0, 0, 0);
6506 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6507 ok(!!d3d, "Failed to create a D3D object.\n");
6508 if (!(device = create_device(d3d, window, window, TRUE)))
6510 skip("Failed to create a D3D device, skipping tests.\n");
6511 IDirect3D9_Release(d3d);
6512 DestroyWindow(window);
6513 return;
6516 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6517 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6518 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
6519 if (tex_pow2)
6520 tex_pow2 = !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
6521 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
6523 for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
6525 BOOL tex_support, cube_support, surface_support, format_known, dynamic_tex_support;
6527 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6528 0, D3DRTYPE_TEXTURE, formats[i].fmt);
6529 tex_support = SUCCEEDED(hr);
6530 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6531 0, D3DRTYPE_CUBETEXTURE, formats[i].fmt);
6532 cube_support = SUCCEEDED(hr);
6533 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6534 0, D3DRTYPE_SURFACE, formats[i].fmt);
6535 surface_support = SUCCEEDED(hr);
6537 /* Scratch pool in general allows texture creation even if the driver does
6538 * not support the format. If the format is an extension format that is not
6539 * known to the runtime, like ATI2N, some driver support is required for
6540 * this to work.
6542 * It is also possible that Windows Vista and Windows 7 d3d9 runtimes know
6543 * about ATI2N. I cannot check this because all my Vista+ machines support
6544 * ATI2N in hardware, but none of my WinXP machines do. */
6545 format_known = tex_support || cube_support || surface_support;
6547 for (w = 1; w <= 8; w++)
6549 for (h = 1; h <= 8; h++)
6551 BOOL block_aligned = TRUE;
6552 BOOL size_is_pow2;
6554 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
6555 block_aligned = FALSE;
6557 size_is_pow2 = !(w & (w - 1) || h & (h - 1));
6559 for (j = 0; j < sizeof(create_tests) / sizeof(*create_tests); j++)
6561 BOOL support, pow2;
6562 HRESULT expect_hr;
6563 BOOL may_succeed = FALSE;
6564 IUnknown **check_null;
6566 if (!formats[i].core_fmt)
6568 /* AMD warns against creating ATI2N textures smaller than
6569 * the block size because the runtime cannot calculate the
6570 * correct texture size. Generalize this for all extension
6571 * formats. */
6572 if (w < formats[i].block_width || h < formats[i].block_height)
6573 continue;
6576 texture = (IDirect3DTexture9 *)0xdeadbeef;
6577 cube_texture = (IDirect3DCubeTexture9 *)0xdeadbeef;
6578 surface = (IDirect3DSurface9 *)0xdeadbeef;
6580 switch (create_tests[j].rtype)
6582 case D3DRTYPE_TEXTURE:
6583 check_null = (IUnknown **)&texture;
6584 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1, 0,
6585 formats[i].fmt, create_tests[j].pool, &texture, NULL);
6586 support = tex_support;
6587 pow2 = tex_pow2;
6588 break;
6590 case D3DRTYPE_CUBETEXTURE:
6591 if (w != h)
6592 continue;
6593 check_null = (IUnknown **)&cube_texture;
6594 hr = IDirect3DDevice9_CreateCubeTexture(device, w, 1, 0,
6595 formats[i].fmt, create_tests[j].pool, &cube_texture, NULL);
6596 support = cube_support;
6597 pow2 = cube_pow2;
6598 break;
6600 case D3DRTYPE_SURFACE:
6601 check_null = (IUnknown **)&surface;
6602 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, w, h,
6603 formats[i].fmt, create_tests[j].pool, &surface, NULL);
6604 support = surface_support;
6605 pow2 = FALSE;
6606 break;
6608 default:
6609 check_null = NULL;
6610 pow2 = FALSE;
6611 support = FALSE;
6612 break;
6615 if (create_tests[j].need_driver_support && !support)
6616 expect_hr = D3DERR_INVALIDCALL;
6617 else if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !format_known)
6618 expect_hr = D3DERR_INVALIDCALL;
6619 else if (formats[i].create_size_checked && !block_aligned)
6620 expect_hr = D3DERR_INVALIDCALL;
6621 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
6622 expect_hr = D3DERR_INVALIDCALL;
6623 else
6624 expect_hr = D3D_OK;
6626 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
6627 * does not support it. Accept scratch creation of extension formats on
6628 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
6629 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
6630 * support it. */
6631 if (!formats[i].core_fmt && !format_known && FAILED(expect_hr))
6632 may_succeed = TRUE;
6634 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
6635 "Got unexpected hr %#x for format %s, pool %s, type %s, size %ux%u.\n",
6636 hr, formats[i].name, create_tests[j].pool_name, create_tests[j].type_name, w, h);
6637 if (FAILED(hr))
6638 ok(*check_null == NULL, "Got object ptr %p, expected NULL.\n", *check_null);
6639 else
6640 IUnknown_Release(*check_null);
6645 surface_only = FALSE;
6646 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6647 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt);
6648 dynamic_tex_support = SUCCEEDED(hr);
6649 if (!dynamic_tex_support)
6651 if (!surface_support)
6653 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
6654 continue;
6656 surface_only = TRUE;
6659 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
6661 switch (pools[j].pool)
6663 case D3DPOOL_SYSTEMMEM:
6664 case D3DPOOL_MANAGED:
6665 if (surface_only)
6666 continue;
6667 /* Fall through */
6668 case D3DPOOL_DEFAULT:
6669 if (surface_only)
6671 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
6672 formats[i].fmt, pools[j].pool, &surface, NULL);
6673 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6675 else
6677 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
6678 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
6679 formats[i].fmt, pools[j].pool, &texture, NULL);
6680 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6681 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6682 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
6683 IDirect3DTexture9_Release(texture);
6685 break;
6687 case D3DPOOL_SCRATCH:
6688 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
6689 formats[i].fmt, pools[j].pool, &surface, NULL);
6690 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6691 break;
6693 default:
6694 break;
6697 if (formats[i].block_width > 1)
6699 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
6700 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
6701 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
6702 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6703 SUCCEEDED(hr) ? "succeeded" : "failed",
6704 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
6705 if (SUCCEEDED(hr))
6707 hr = IDirect3DSurface9_UnlockRect(surface);
6708 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6711 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
6712 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
6713 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
6714 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6715 SUCCEEDED(hr) ? "succeeded" : "failed",
6716 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
6717 if (SUCCEEDED(hr))
6719 hr = IDirect3DSurface9_UnlockRect(surface);
6720 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6724 if (formats[i].block_height > 1)
6726 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
6727 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
6728 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
6729 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6730 SUCCEEDED(hr) ? "succeeded" : "failed",
6731 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
6732 if (SUCCEEDED(hr))
6734 hr = IDirect3DSurface9_UnlockRect(surface);
6735 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6738 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
6739 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
6740 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
6741 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6742 SUCCEEDED(hr) ? "succeeded" : "failed",
6743 pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
6744 if (SUCCEEDED(hr))
6746 hr = IDirect3DSurface9_UnlockRect(surface);
6747 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6751 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
6752 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
6753 ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
6754 hr = IDirect3DSurface9_UnlockRect(surface);
6755 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6757 IDirect3DSurface9_Release(surface);
6760 if (!dynamic_tex_support)
6762 skip("Dynamic %s textures not supported, skipping mipmap test.\n", formats[i].name);
6763 continue;
6766 if (formats[i].block_width == 1 && formats[i].block_height == 1)
6767 continue;
6768 if (!formats[i].core_fmt)
6769 continue;
6771 hr = IDirect3DDevice9_CreateTexture(device, formats[i].block_width, formats[i].block_height, 2,
6772 D3DUSAGE_DYNAMIC, formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
6773 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, format %s.\n", hr, formats[i].name);
6775 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, NULL, 0);
6776 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
6777 hr = IDirect3DTexture9_UnlockRect(texture, 1);
6778 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
6780 rect.left = 0;
6781 rect.top = 0;
6782 rect.right = formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1;
6783 rect.bottom = formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1;
6784 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
6785 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
6786 hr = IDirect3DTexture9_UnlockRect(texture, 1);
6787 ok(SUCCEEDED(hr), "Failed lock texture, hr %#x.\n", hr);
6789 rect.right = formats[i].block_width;
6790 rect.bottom = formats[i].block_height;
6791 hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0);
6792 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6793 if (SUCCEEDED(hr))
6794 IDirect3DTexture9_UnlockRect(texture, 1);
6796 IDirect3DTexture9_Release(texture);
6799 refcount = IDirect3DDevice9_Release(device);
6800 ok(!refcount, "Device has %u references left.\n", refcount);
6801 IDirect3D9_Release(d3d);
6802 DestroyWindow(window);
6805 static void test_set_palette(void)
6807 IDirect3DDevice9 *device;
6808 IDirect3D9 *d3d9;
6809 UINT refcount;
6810 HWND window;
6811 HRESULT hr;
6812 PALETTEENTRY pal[256];
6813 unsigned int i;
6814 D3DCAPS9 caps;
6816 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6817 0, 0, 640, 480, 0, 0, 0, 0);
6818 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6819 ok(!!d3d9, "Failed to create a D3D object.\n");
6820 if (!(device = create_device(d3d9, window, window, TRUE)))
6822 skip("Failed to create a D3D device, skipping tests.\n");
6823 DestroyWindow(window);
6824 return;
6827 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6829 pal[i].peRed = i;
6830 pal[i].peGreen = i;
6831 pal[i].peBlue = i;
6832 pal[i].peFlags = 0xff;
6834 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6835 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6837 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6838 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6839 for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6841 pal[i].peRed = i;
6842 pal[i].peGreen = i;
6843 pal[i].peBlue = i;
6844 pal[i].peFlags = i;
6846 if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
6848 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6849 ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6851 else
6853 hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6854 ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
6857 refcount = IDirect3DDevice9_Release(device);
6858 ok(!refcount, "Device has %u references left.\n", refcount);
6859 IDirect3D9_Release(d3d9);
6860 DestroyWindow(window);
6863 static void test_swvp_buffer(void)
6865 IDirect3DDevice9 *device;
6866 IDirect3D9 *d3d9;
6867 UINT refcount;
6868 HWND window;
6869 HRESULT hr;
6870 unsigned int i;
6871 IDirect3DVertexBuffer9 *buffer;
6872 static const unsigned int bufsize = 1024;
6873 D3DVERTEXBUFFER_DESC desc;
6874 D3DPRESENT_PARAMETERS present_parameters = {0};
6875 struct
6877 float x, y, z;
6878 } *ptr, *ptr2;
6880 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6881 0, 0, 640, 480, 0, 0, 0, 0);
6882 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6883 ok(!!d3d9, "Failed to create a D3D object.\n");
6885 present_parameters.Windowed = TRUE;
6886 present_parameters.hDeviceWindow = window;
6887 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
6888 present_parameters.BackBufferWidth = screen_width;
6889 present_parameters.BackBufferHeight = screen_height;
6890 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
6891 present_parameters.EnableAutoDepthStencil = FALSE;
6892 if (FAILED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
6893 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
6895 skip("Failed to create a D3D device, skipping tests.\n");
6896 DestroyWindow(window);
6897 IDirect3D9_Release(d3d9);
6898 return;
6901 hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
6902 D3DPOOL_DEFAULT, &buffer, NULL);
6903 ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6904 hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
6905 ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
6906 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
6907 ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
6908 "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
6910 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
6911 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6912 for (i = 0; i < bufsize; i++)
6914 ptr[i].x = i * 1.0f;
6915 ptr[i].y = i * 2.0f;
6916 ptr[i].z = i * 3.0f;
6918 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6919 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6921 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6922 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6923 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
6924 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6925 hr = IDirect3DDevice9_BeginScene(device);
6926 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6927 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
6928 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6929 hr = IDirect3DDevice9_EndScene(device);
6930 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6932 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
6933 ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6934 ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
6935 for (i = 0; i < bufsize; i++)
6937 if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
6939 ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
6940 ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
6941 break;
6944 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6945 ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6947 IDirect3DVertexBuffer9_Release(buffer);
6948 refcount = IDirect3DDevice9_Release(device);
6949 ok(!refcount, "Device has %u references left.\n", refcount);
6950 IDirect3D9_Release(d3d9);
6951 DestroyWindow(window);
6954 static void test_npot_textures(void)
6956 IDirect3DDevice9 *device = NULL;
6957 IDirect3D9 *d3d9;
6958 ULONG refcount;
6959 HWND window = NULL;
6960 HRESULT hr;
6961 D3DCAPS9 caps;
6962 IDirect3DTexture9 *texture;
6963 IDirect3DCubeTexture9 *cube_texture;
6964 IDirect3DVolumeTexture9 *volume_texture;
6965 struct
6967 D3DPOOL pool;
6968 const char *pool_name;
6969 HRESULT hr;
6971 pools[] =
6973 { D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL },
6974 { D3DPOOL_MANAGED, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL },
6975 { D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL },
6976 { D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", D3D_OK },
6978 unsigned int i, levels;
6979 BOOL tex_pow2, cube_pow2, vol_pow2;
6981 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6982 0, 0, 640, 480, 0, 0, 0, 0);
6983 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6984 ok(!!d3d9, "Failed to create a D3D object.\n");
6985 if (!(device = create_device(d3d9, window, window, TRUE)))
6987 skip("Failed to create a D3D device, skipping tests.\n");
6988 goto done;
6991 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6992 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6993 tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
6994 cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
6995 vol_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
6996 ok(cube_pow2 == tex_pow2, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
6997 ok(vol_pow2 == tex_pow2, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
6999 for (i = 0; i < sizeof(pools) / sizeof(*pools); i++)
7001 for (levels = 0; levels <= 2; levels++)
7003 HRESULT expected;
7005 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, levels, 0, D3DFMT_X8R8G8B8,
7006 pools[i].pool, &texture, NULL);
7007 if (!tex_pow2)
7009 expected = D3D_OK;
7011 else if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
7013 if (levels == 1)
7014 expected = D3D_OK;
7015 else
7016 expected = pools[i].hr;
7018 else
7020 expected = pools[i].hr;
7022 ok(hr == expected, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#x, expected %#x.\n",
7023 pools[i].pool_name, levels, hr, expected);
7025 if (SUCCEEDED(hr))
7026 IDirect3DTexture9_Release(texture);
7029 hr = IDirect3DDevice9_CreateCubeTexture(device, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
7030 &cube_texture, NULL);
7031 if (tex_pow2)
7033 ok(hr == pools[i].hr, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
7034 pools[i].pool_name, hr, pools[i].hr);
7036 else
7038 ok(SUCCEEDED(hr), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
7039 pools[i].pool_name, hr, D3D_OK);
7042 if (SUCCEEDED(hr))
7043 IDirect3DCubeTexture9_Release(cube_texture);
7045 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
7046 &volume_texture, NULL);
7047 if (tex_pow2)
7049 ok(hr == pools[i].hr, "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
7050 pools[i].pool_name, hr, pools[i].hr);
7052 else
7054 ok(SUCCEEDED(hr), "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
7055 pools[i].pool_name, hr, D3D_OK);
7058 if (SUCCEEDED(hr))
7059 IDirect3DVolumeTexture9_Release(volume_texture);
7062 done:
7063 if (device)
7065 refcount = IDirect3DDevice9_Release(device);
7066 ok(!refcount, "Device has %u references left.\n", refcount);
7068 IDirect3D9_Release(d3d9);
7069 DestroyWindow(window);
7073 static void test_vidmem_accounting(void)
7075 IDirect3DDevice9 *device;
7076 IDirect3D9 *d3d9;
7077 ULONG refcount;
7078 HWND window;
7079 HRESULT hr = D3D_OK;
7080 IDirect3DTexture9 *textures[20];
7081 unsigned int i;
7082 UINT vidmem_start, vidmem_end, diff;
7084 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7085 0, 0, 640, 480, 0, 0, 0, 0);
7086 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7087 ok(!!d3d9, "Failed to create a D3D object.\n");
7088 if (!(device = create_device(d3d9, window, window, TRUE)))
7090 skip("Failed to create a D3D device, skipping tests.\n");
7091 IDirect3D9_Release(d3d9);
7092 DestroyWindow(window);
7093 return;
7096 vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device);
7097 memset(textures, 0, sizeof(textures));
7098 for (i = 0; i < sizeof(textures) / sizeof(*textures) && SUCCEEDED(hr); i++)
7100 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, D3DUSAGE_RENDERTARGET,
7101 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textures[i], NULL);
7102 /* D3DERR_OUTOFVIDEOMEMORY is returned when the card runs out of video memory
7103 * E_FAIL is returned on address space or system memory exhaustion */
7104 ok(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY,
7105 "Failed to create texture, hr %#x.\n", hr);
7107 vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
7109 ok(vidmem_start > vidmem_end, "Expected available texture memory to decrease during texture creation.\n");
7110 diff = vidmem_start - vidmem_end;
7111 ok(diff > 1024 * 1024 * 2 * i, "Expected a video memory difference of at least %u MB, got %u MB.\n",
7112 2 * i, diff / 1024 / 1024);
7114 for (i = 0; i < sizeof(textures) / sizeof(*textures); i++)
7116 if (textures[i])
7117 IDirect3DTexture9_Release(textures[i]);
7120 refcount = IDirect3DDevice9_Release(device);
7121 ok(!refcount, "Device has %u references left.\n", refcount);
7122 IDirect3D9_Release(d3d9);
7123 DestroyWindow(window);
7126 static void test_volume_locking(void)
7128 IDirect3DDevice9 *device;
7129 IDirect3D9 *d3d9;
7130 HWND window;
7131 HRESULT hr;
7132 IDirect3DVolumeTexture9 *texture;
7133 unsigned int i;
7134 D3DLOCKED_BOX locked_box;
7135 ULONG refcount;
7136 D3DCAPS9 caps;
7137 static const struct
7139 D3DPOOL pool;
7140 DWORD usage;
7141 HRESULT create_hr, lock_hr;
7143 tests[] =
7145 { D3DPOOL_DEFAULT, 0, D3D_OK, D3DERR_INVALIDCALL },
7146 { D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
7147 { D3DPOOL_SYSTEMMEM, 0, D3D_OK, D3D_OK },
7148 { D3DPOOL_SYSTEMMEM, D3DUSAGE_DYNAMIC, D3D_OK, D3D_OK },
7149 { D3DPOOL_MANAGED, 0, D3D_OK, D3D_OK },
7150 { D3DPOOL_MANAGED, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
7151 { D3DPOOL_SCRATCH, 0, D3D_OK, D3D_OK },
7152 { D3DPOOL_SCRATCH, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL, D3D_OK },
7155 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7156 0, 0, 640, 480, 0, 0, 0, 0);
7157 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7158 ok(!!d3d9, "Failed to create a D3D object.\n");
7159 if (!(device = create_device(d3d9, window, window, TRUE)))
7161 skip("Failed to create a D3D device, skipping tests.\n");
7162 IDirect3D9_Release(d3d9);
7163 DestroyWindow(window);
7164 return;
7167 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7168 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7169 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
7171 skip("Volume textures not supported, skipping test.\n");
7172 goto out;
7175 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
7177 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, tests[i].usage,
7178 D3DFMT_A8R8G8B8, tests[i].pool, &texture, NULL);
7179 ok(hr == tests[i].create_hr, "Creating volume texture pool=%u, usage=%#x returned %#x, expected %#x.\n",
7180 tests[i].pool, tests[i].usage, hr, tests[i].create_hr);
7181 if (FAILED(hr))
7182 continue;
7184 locked_box.pBits = (void *)0xdeadbeef;
7185 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7186 ok(hr == tests[i].lock_hr, "Lock returned %#x, expected %#x.\n", hr, tests[i].lock_hr);
7187 if (SUCCEEDED(hr))
7189 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7190 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7192 else
7194 ok (locked_box.pBits == NULL, "Failed lock set pBits = %p, expected NULL.\n", locked_box.pBits);
7196 IDirect3DVolumeTexture9_Release(texture);
7199 out:
7200 refcount = IDirect3DDevice9_Release(device);
7201 ok(!refcount, "Device has %u references left.\n", refcount);
7202 IDirect3D9_Release(d3d9);
7203 DestroyWindow(window);
7206 static void test_update_volumetexture(void)
7208 IDirect3DDevice9 *device;
7209 IDirect3D9 *d3d9;
7210 HWND window;
7211 HRESULT hr;
7212 IDirect3DVolumeTexture9 *src, *dst;
7213 unsigned int i;
7214 D3DLOCKED_BOX locked_box;
7215 ULONG refcount;
7216 D3DCAPS9 caps;
7217 static const struct
7219 D3DPOOL src_pool, dst_pool;
7220 HRESULT hr;
7222 tests[] =
7224 { D3DPOOL_DEFAULT, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7225 { D3DPOOL_MANAGED, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7226 { D3DPOOL_SYSTEMMEM, D3DPOOL_DEFAULT, D3D_OK },
7227 { D3DPOOL_SCRATCH, D3DPOOL_DEFAULT, D3DERR_INVALIDCALL },
7229 { D3DPOOL_DEFAULT, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7230 { D3DPOOL_MANAGED, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7231 { D3DPOOL_SYSTEMMEM, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7232 { D3DPOOL_SCRATCH, D3DPOOL_MANAGED, D3DERR_INVALIDCALL },
7234 { D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7235 { D3DPOOL_MANAGED, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7236 { D3DPOOL_SYSTEMMEM, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7237 { D3DPOOL_SCRATCH, D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL },
7239 { D3DPOOL_DEFAULT, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7240 { D3DPOOL_MANAGED, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7241 { D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7242 { D3DPOOL_SCRATCH, D3DPOOL_SCRATCH, D3DERR_INVALIDCALL },
7244 static const struct
7246 UINT src_size, dst_size;
7247 UINT src_lvl, dst_lvl;
7248 D3DFORMAT src_fmt, dst_fmt;
7250 tests2[] =
7252 { 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7253 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7254 { 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7255 { 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7256 { 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 },
7257 { 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different level count */
7258 { 4, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8 }, /* Different size */
7259 { 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8 }, /* Different format */
7262 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7263 0, 0, 640, 480, 0, 0, 0, 0);
7264 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7265 ok(!!d3d9, "Failed to create a D3D object.\n");
7266 if (!(device = create_device(d3d9, window, window, TRUE)))
7268 skip("Failed to create a D3D device, skipping tests.\n");
7269 IDirect3D9_Release(d3d9);
7270 DestroyWindow(window);
7271 return;
7274 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7275 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7276 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
7278 skip("Volume textures not supported, skipping test.\n");
7279 goto out;
7282 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
7284 DWORD src_usage = tests[i].src_pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0;
7285 DWORD dst_usage = tests[i].dst_pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0;
7287 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, src_usage,
7288 D3DFMT_A8R8G8B8, tests[i].src_pool, &src, NULL);
7289 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7290 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, dst_usage,
7291 D3DFMT_A8R8G8B8, tests[i].dst_pool, &dst, NULL);
7292 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7294 hr = IDirect3DVolumeTexture9_LockBox(src, 0, &locked_box, NULL, 0);
7295 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7296 *((DWORD *)locked_box.pBits) = 0x11223344;
7297 hr = IDirect3DVolumeTexture9_UnlockBox(src, 0);
7298 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7300 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
7301 ok(hr == tests[i].hr, "UpdateTexture returned %#x, expected %#x, src pool %x, dst pool %u.\n",
7302 hr, tests[i].hr, tests[i].src_pool, tests[i].dst_pool);
7304 if (SUCCEEDED(hr))
7306 DWORD content = *((DWORD *)locked_box.pBits);
7307 hr = IDirect3DVolumeTexture9_LockBox(dst, 0, &locked_box, NULL, 0);
7308 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7309 ok(content == 0x11223344, "Dest texture contained %#x, expected 0x11223344.\n", content);
7310 hr = IDirect3DVolumeTexture9_UnlockBox(dst, 0);
7311 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7313 IDirect3DVolumeTexture9_Release(src);
7314 IDirect3DVolumeTexture9_Release(dst);
7317 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
7319 skip("Mipmapped volume maps not supported.\n");
7320 goto out;
7323 for (i = 0; i < sizeof(tests2) / sizeof(*tests2); i++)
7325 hr = IDirect3DDevice9_CreateVolumeTexture(device,
7326 tests2[i].src_size, tests2[i].src_size, tests2[i].src_size,
7327 tests2[i].src_lvl, 0, tests2[i].src_fmt, D3DPOOL_SYSTEMMEM, &src, NULL);
7328 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x, case %u.\n", hr, i);
7329 hr = IDirect3DDevice9_CreateVolumeTexture(device,
7330 tests2[i].dst_size, tests2[i].dst_size, tests2[i].dst_size,
7331 tests2[i].dst_lvl, 0, tests2[i].dst_fmt, D3DPOOL_DEFAULT, &dst, NULL);
7332 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x, case %u.\n", hr, i);
7334 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)src, (IDirect3DBaseTexture9 *)dst);
7335 if (FAILED(hr))
7336 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u.\n", hr, i);
7337 else
7338 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u.\n", hr, i);
7340 IDirect3DVolumeTexture9_Release(src);
7341 IDirect3DVolumeTexture9_Release(dst);
7344 /* As far as I can see, UpdateTexture on non-matching texture behaves like a memcpy. The raw data
7345 * stays the same in a format change, a 2x2x1 texture is copied into the first row of a 4x4x1 texture,
7346 * etc. I could not get it to segfault, but the nonexistent 5th pixel of a 2x2x1 texture is copied into
7347 * pixel 1x2x1 of a 4x4x1 texture, demonstrating a read beyond the texture's end. I suspect any bad
7348 * memory access is silently ignored by the runtime, in the kernel or on the GPU.
7350 * I'm not adding tests for this behavior until an application needs it. */
7352 out:
7353 refcount = IDirect3DDevice9_Release(device);
7354 ok(!refcount, "Device has %u references left.\n", refcount);
7355 IDirect3D9_Release(d3d9);
7356 DestroyWindow(window);
7359 static void test_create_rt_ds_fail(void)
7361 IDirect3DDevice9 *device;
7362 HWND window;
7363 HRESULT hr;
7364 ULONG refcount;
7365 IDirect3D9 *d3d9;
7366 IDirect3DSurface9 *surface;
7368 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7369 0, 0, 640, 480, 0, 0, 0, 0);
7370 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7371 ok(!!d3d9, "Failed to create a D3D object.\n");
7372 if (!(device = create_device(d3d9, window, window, TRUE)))
7374 skip("Failed to create a D3D device, skipping tests.\n");
7375 IDirect3D9_Release(d3d9);
7376 DestroyWindow(window);
7377 return;
7380 /* Output pointer == NULL segfaults on Windows. */
7382 surface = (IDirect3DSurface9 *)0xdeadbeef;
7383 hr = IDirect3DDevice9_CreateRenderTarget(device, 4, 4, D3DFMT_D16,
7384 D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
7385 ok(hr == D3DERR_INVALIDCALL, "Creating a D16 render target returned hr %#x.\n", hr);
7386 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
7387 if (SUCCEEDED(hr))
7388 IDirect3DSurface9_Release(surface);
7390 surface = (IDirect3DSurface9 *)0xdeadbeef;
7391 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 4, 4, D3DFMT_A8R8G8B8,
7392 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
7393 ok(hr == D3DERR_INVALIDCALL, "Creating a A8R8G8B8 depth stencil returned hr %#x.\n", hr);
7394 ok(surface == NULL, "Got pointer %p, expected NULL.\n", surface);
7395 if (SUCCEEDED(hr))
7396 IDirect3DSurface9_Release(surface);
7398 refcount = IDirect3DDevice9_Release(device);
7399 ok(!refcount, "Device has %u references left.\n", refcount);
7400 IDirect3D9_Release(d3d9);
7401 DestroyWindow(window);
7404 static void test_volume_blocks(void)
7406 IDirect3DDevice9 *device;
7407 IDirect3D9 *d3d9;
7408 UINT refcount;
7409 HWND window;
7410 HRESULT hr;
7411 D3DCAPS9 caps;
7412 IDirect3DVolumeTexture9 *texture;
7413 unsigned int w, h, d, i, j;
7414 static const struct
7416 D3DFORMAT fmt;
7417 const char *name;
7418 unsigned int block_width;
7419 unsigned int block_height;
7420 unsigned int block_depth;
7421 unsigned int block_size;
7422 BOOL broken;
7423 BOOL create_size_checked, core_fmt;
7425 formats[] =
7427 /* Scratch volumes enforce DXTn block locks, unlike their surface counterparts.
7428 * ATI2N and YUV blocks are not enforced on any tested card (r200, gtx 460). */
7429 {D3DFMT_DXT1, "D3DFMT_DXT1", 4, 4, 1, 8, FALSE, TRUE, TRUE },
7430 {D3DFMT_DXT2, "D3DFMT_DXT2", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7431 {D3DFMT_DXT3, "D3DFMT_DXT3", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7432 {D3DFMT_DXT4, "D3DFMT_DXT4", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7433 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7434 {D3DFMT_DXT5, "D3DFMT_DXT5", 4, 4, 1, 16, FALSE, TRUE, TRUE },
7435 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
7436 * which doesn't match the format spec. On newer Nvidia cards
7437 * it has the correct 4x4 block size */
7438 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, 1, 16, TRUE, FALSE, FALSE},
7439 {D3DFMT_YUY2, "D3DFMT_YUY2", 2, 1, 1, 4, TRUE, FALSE, TRUE },
7440 {D3DFMT_UYVY, "D3DFMT_UYVY", 2, 1, 1, 4, TRUE, FALSE, TRUE },
7442 static const struct
7444 D3DPOOL pool;
7445 const char *name;
7446 BOOL need_driver_support, need_runtime_support;
7448 create_tests[] =
7450 {D3DPOOL_DEFAULT, "D3DPOOL_DEFAULT", TRUE, FALSE},
7451 {D3DPOOL_SCRATCH, "D3DPOOL_SCRATCH", FALSE, TRUE },
7452 {D3DPOOL_SYSTEMMEM, "D3DPOOL_SYSTEMMEM",TRUE, FALSE},
7453 {D3DPOOL_MANAGED, "D3DPOOL_MANAGED", TRUE, FALSE},
7455 static const struct
7457 unsigned int x, y, z, x2, y2, z2;
7459 offset_tests[] =
7461 {0, 0, 0, 8, 8, 8},
7462 {0, 0, 3, 8, 8, 8},
7463 {0, 4, 0, 8, 8, 8},
7464 {0, 4, 3, 8, 8, 8},
7465 {4, 0, 0, 8, 8, 8},
7466 {4, 0, 3, 8, 8, 8},
7467 {4, 4, 0, 8, 8, 8},
7468 {4, 4, 3, 8, 8, 8},
7470 D3DBOX box;
7471 D3DLOCKED_BOX locked_box;
7472 BYTE *base;
7473 INT expected_row_pitch, expected_slice_pitch;
7474 BOOL support, support_2d;
7475 BOOL pow2;
7476 unsigned int offset, expected_offset;
7478 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
7479 0, 0, 640, 480, 0, 0, 0, 0);
7480 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7481 ok(!!d3d9, "Failed to create a D3D object.\n");
7482 if (!(device = create_device(d3d9, window, window, TRUE)))
7484 skip("Failed to create a D3D device, skipping tests.\n");
7485 IDirect3D9_Release(d3d9);
7486 DestroyWindow(window);
7487 return;
7489 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7490 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7491 pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
7493 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
7495 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7496 0, D3DRTYPE_VOLUMETEXTURE, formats[i].fmt);
7497 support = SUCCEEDED(hr);
7498 hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7499 0, D3DRTYPE_TEXTURE, formats[i].fmt);
7500 support_2d = SUCCEEDED(hr);
7502 /* Test creation restrictions */
7503 for (w = 1; w <= 8; w++)
7505 for (h = 1; h <= 8; h++)
7507 for (d = 1; d <= 8; d++)
7509 HRESULT expect_hr;
7510 BOOL size_is_pow2;
7511 BOOL block_aligned = TRUE;
7513 if (w & (formats[i].block_width - 1) || h & (formats[i].block_height - 1))
7514 block_aligned = FALSE;
7516 size_is_pow2 = !((w & (w - 1)) || (h & (h - 1)) || (d & (d - 1)));
7518 for (j = 0; j < sizeof(create_tests) / sizeof(*create_tests); j++)
7520 BOOL may_succeed = FALSE;
7521 BOOL todo = FALSE;
7523 if (create_tests[j].need_runtime_support && !formats[i].core_fmt && !support)
7524 expect_hr = D3DERR_INVALIDCALL;
7525 else if (formats[i].create_size_checked && !block_aligned)
7526 expect_hr = D3DERR_INVALIDCALL;
7527 else if (pow2 && !size_is_pow2 && create_tests[j].need_driver_support)
7528 expect_hr = D3DERR_INVALIDCALL;
7529 else if (create_tests[j].need_driver_support && !support)
7531 todo = support_2d;
7532 expect_hr = D3DERR_INVALIDCALL;
7534 else
7535 expect_hr = D3D_OK;
7537 texture = (IDirect3DVolumeTexture9 *)0xdeadbeef;
7538 hr = IDirect3DDevice9_CreateVolumeTexture(device, w, h, d, 1, 0,
7539 formats[i].fmt, create_tests[j].pool, &texture, NULL);
7541 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
7542 * does not support it. Accept scratch creation of extension formats on
7543 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
7544 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
7545 * support it. */
7546 if (!formats[i].core_fmt && !support && FAILED(expect_hr))
7547 may_succeed = TRUE;
7549 if (todo)
7551 todo_wine ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
7552 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
7553 hr, formats[i].name, create_tests[j].name, w, h, d);
7555 else
7557 ok(hr == expect_hr || ((SUCCEEDED(hr) && may_succeed)),
7558 "Got unexpected hr %#x for format %s, pool %s, size %ux%ux%u.\n",
7559 hr, formats[i].name, create_tests[j].name, w, h, d);
7562 if (FAILED(hr))
7563 ok(texture == NULL, "Got texture ptr %p, expected NULL.\n", texture);
7564 else
7565 IDirect3DVolumeTexture9_Release(texture);
7571 if (!support && !formats[i].core_fmt)
7572 continue;
7574 hr = IDirect3DDevice9_CreateVolumeTexture(device, 24, 8, 8, 1, 0,
7575 formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
7576 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7578 /* Test lockrect offset */
7579 for (j = 0; j < sizeof(offset_tests) / sizeof(*offset_tests); j++)
7581 unsigned int bytes_per_pixel;
7582 bytes_per_pixel = formats[i].block_size / (formats[i].block_width * formats[i].block_height);
7584 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7585 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7587 base = locked_box.pBits;
7588 if (formats[i].broken)
7590 expected_row_pitch = bytes_per_pixel * 24;
7592 else
7594 expected_row_pitch = (24 /* tex width */ + formats[i].block_height - 1) / formats[i].block_width
7595 * formats[i].block_size;
7597 ok(locked_box.RowPitch == expected_row_pitch, "Got unexpected row pitch %d for format %s, expected %d.\n",
7598 locked_box.RowPitch, formats[i].name, expected_row_pitch);
7600 if (formats[i].broken)
7602 expected_slice_pitch = expected_row_pitch * 8;
7604 else
7606 expected_slice_pitch = (8 /* tex height */ + formats[i].block_depth - 1) / formats[i].block_height
7607 * expected_row_pitch;
7609 ok(locked_box.SlicePitch == expected_slice_pitch,
7610 "Got unexpected slice pitch %d for format %s, expected %d.\n",
7611 locked_box.SlicePitch, formats[i].name, expected_slice_pitch);
7613 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7614 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x, j %u.\n", hr, j);
7616 box.Left = offset_tests[j].x;
7617 box.Top = offset_tests[j].y;
7618 box.Front = offset_tests[j].z;
7619 box.Right = offset_tests[j].x2;
7620 box.Bottom = offset_tests[j].y2;
7621 box.Back = offset_tests[j].z2;
7622 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7623 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x, j %u.\n", hr, j);
7625 offset = (BYTE *)locked_box.pBits - base;
7626 if (formats[i].broken)
7628 expected_offset = box.Front * expected_slice_pitch
7629 + box.Top * expected_row_pitch
7630 + box.Left * bytes_per_pixel;
7632 else
7634 expected_offset = (box.Front / formats[i].block_depth) * expected_slice_pitch
7635 + (box.Top / formats[i].block_height) * expected_row_pitch
7636 + (box.Left / formats[i].block_width) * formats[i].block_size;
7638 ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u, box start %ux%ux%u.\n",
7639 offset, formats[i].name, expected_offset, box.Left, box.Top, box.Front);
7641 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7642 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7645 /* Test partial block locks */
7646 box.Front = 0;
7647 box.Back = 1;
7648 if (formats[i].block_width > 1)
7650 box.Left = formats[i].block_width >> 1;
7651 box.Top = 0;
7652 box.Right = formats[i].block_width;
7653 box.Bottom = formats[i].block_height;
7654 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7655 ok(FAILED(hr) || broken(formats[i].broken),
7656 "Partial block lock succeeded, expected failure, format %s.\n",
7657 formats[i].name);
7658 if (SUCCEEDED(hr))
7660 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7661 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7664 box.Left = 0;
7665 box.Top = 0;
7666 box.Right = formats[i].block_width >> 1;
7667 box.Bottom = formats[i].block_height;
7668 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7669 ok(FAILED(hr) || broken(formats[i].broken),
7670 "Partial block lock succeeded, expected failure, format %s.\n",
7671 formats[i].name);
7672 if (SUCCEEDED(hr))
7674 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7675 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7679 if (formats[i].block_height > 1)
7681 box.Left = 0;
7682 box.Top = formats[i].block_height >> 1;
7683 box.Right = formats[i].block_width;
7684 box.Bottom = formats[i].block_height;
7685 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7686 ok(FAILED(hr) || broken(formats[i].broken),
7687 "Partial block lock succeeded, expected failure, format %s.\n",
7688 formats[i].name);
7689 if (SUCCEEDED(hr))
7691 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7692 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7695 box.Left = 0;
7696 box.Top = 0;
7697 box.Right = formats[i].block_width;
7698 box.Bottom = formats[i].block_height >> 1;
7699 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7700 ok(FAILED(hr) || broken(formats[i].broken),
7701 "Partial block lock succeeded, expected failure, format %s.\n",
7702 formats[i].name);
7703 if (SUCCEEDED(hr))
7705 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7706 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7710 /* Test full block lock */
7711 box.Left = 0;
7712 box.Top = 0;
7713 box.Right = formats[i].block_width;
7714 box.Bottom = formats[i].block_height;
7715 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &box, 0);
7716 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7717 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7718 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7720 IDirect3DVolumeTexture9_Release(texture);
7722 /* Test mipmap locks. Don't do this with ATI2N, AMD warns that the runtime
7723 * does not allocate surfaces smaller than the blocksize properly. */
7724 if ((formats[i].block_width > 1 || formats[i].block_height > 1) && formats[i].core_fmt)
7726 hr = IDirect3DDevice9_CreateVolumeTexture(device, formats[i].block_width, formats[i].block_height,
7727 2, 2, 0, formats[i].fmt, D3DPOOL_SCRATCH, &texture, NULL);
7729 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, NULL, 0);
7730 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#x.\n", hr);
7731 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
7732 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7734 box.Left = box.Top = box.Front = 0;
7735 box.Right = formats[i].block_width == 1 ? 1 : formats[i].block_width >> 1;
7736 box.Bottom = formats[i].block_height == 1 ? 1 : formats[i].block_height >> 1;
7737 box.Back = 1;
7738 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
7739 ok(SUCCEEDED(hr), "Failed to lock volume texture mipmap, hr %#x.\n", hr);
7740 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 1);
7741 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7743 box.Right = formats[i].block_width;
7744 box.Bottom = formats[i].block_height;
7745 hr = IDirect3DVolumeTexture9_LockBox(texture, 1, &locked_box, &box, 0);
7746 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7747 if (SUCCEEDED(hr))
7748 IDirect3DVolumeTexture9_UnlockBox(texture, 1);
7750 IDirect3DVolumeTexture9_Release(texture);
7754 refcount = IDirect3DDevice9_Release(device);
7755 ok(!refcount, "Device has %u references left.\n", refcount);
7756 IDirect3D9_Release(d3d9);
7757 DestroyWindow(window);
7760 static void test_lockbox_invalid(void)
7762 static const struct
7764 D3DBOX box;
7765 HRESULT result;
7767 test_data[] =
7769 {{0, 0, 2, 2, 0, 1}, D3D_OK}, /* Valid */
7770 {{0, 0, 4, 4, 0, 1}, D3D_OK}, /* Valid */
7771 {{0, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* 0 height */
7772 {{0, 0, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* 0 width */
7773 {{0, 0, 4, 4, 1, 1}, D3DERR_INVALIDCALL}, /* 0 depth */
7774 {{4, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > right */
7775 {{0, 4, 4, 0, 0, 1}, D3DERR_INVALIDCALL}, /* top > bottom */
7776 {{0, 0, 4, 4, 1, 0}, D3DERR_INVALIDCALL}, /* back > front */
7777 {{0, 0, 8, 4, 0, 1}, D3DERR_INVALIDCALL}, /* right > surface */
7778 {{0, 0, 4, 8, 0, 1}, D3DERR_INVALIDCALL}, /* bottom > surface */
7779 {{0, 0, 4, 4, 0, 3}, D3DERR_INVALIDCALL}, /* back > surface */
7780 {{8, 0, 16, 4, 0, 1}, D3DERR_INVALIDCALL}, /* left > surface */
7781 {{0, 8, 4, 16, 0, 1}, D3DERR_INVALIDCALL}, /* top > surface */
7782 {{0, 0, 4, 4, 2, 4}, D3DERR_INVALIDCALL}, /* top > surface */
7784 static const D3DBOX test_boxt_2 = {2, 2, 4, 4, 0, 1};
7785 IDirect3DVolumeTexture9 *texture = NULL;
7786 D3DLOCKED_BOX locked_box;
7787 IDirect3DDevice9 *device;
7788 IDirect3D9 *d3d;
7789 unsigned int i;
7790 ULONG refcount;
7791 HWND window;
7792 BYTE *base;
7793 HRESULT hr;
7795 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7796 0, 0, 640, 480, 0, 0, 0, 0);
7797 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7798 ok(!!d3d, "Failed to create a D3D object.\n");
7799 if (!(device = create_device(d3d, window, window, TRUE)))
7801 skip("Failed to create a D3D device, skipping tests.\n");
7802 IDirect3D9_Release(d3d);
7803 DestroyWindow(window);
7804 return;
7807 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0,
7808 D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
7809 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
7810 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7811 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7812 base = locked_box.pBits;
7813 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7814 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7816 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
7818 unsigned int offset, expected_offset;
7819 const D3DBOX *box = &test_data[i].box;
7821 locked_box.pBits = (BYTE *)0xdeadbeef;
7822 locked_box.RowPitch = 0xdeadbeef;
7823 locked_box.SlicePitch = 0xdeadbeef;
7825 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, box, 0);
7826 /* Unlike surfaces, volumes properly check the box even in Windows XP */
7827 ok(hr == test_data[i].result,
7828 "Got unexpected hr %#x with box [%u, %u, %u]->[%u, %u, %u], expected %#x.\n",
7829 hr, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back,
7830 test_data[i].result);
7831 if (FAILED(hr))
7832 continue;
7834 offset = (BYTE *)locked_box.pBits - base;
7835 expected_offset = box->Front * locked_box.SlicePitch + box->Top * locked_box.RowPitch + box->Left * 4;
7836 ok(offset == expected_offset,
7837 "Got unexpected offset %u (expected %u) for rect [%u, %u, %u]->[%u, %u, %u].\n",
7838 offset, expected_offset, box->Left, box->Top, box->Front, box->Right, box->Bottom, box->Back);
7840 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7841 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7844 /* locked_box = NULL throws an exception on Windows */
7845 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7846 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
7847 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, NULL, 0);
7848 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7849 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7850 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7851 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7852 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7854 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
7855 ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
7856 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
7857 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
7858 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_data[0].box, 0);
7859 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
7860 hr, test_data[0].box.Left, test_data[0].box.Top, test_data[0].box.Front,
7861 test_data[0].box.Right, test_data[0].box.Bottom, test_data[0].box.Back);
7862 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &locked_box, &test_boxt_2, 0);
7863 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%u, %u, %u]->[%u, %u, %u].\n",
7864 hr, test_boxt_2.Left, test_boxt_2.Top, test_boxt_2.Front,
7865 test_boxt_2.Right, test_boxt_2.Bottom, test_boxt_2.Back);
7866 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
7867 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
7869 IDirect3DVolumeTexture9_Release(texture);
7870 refcount = IDirect3DDevice9_Release(device);
7871 ok(!refcount, "Device has %u references left.\n", refcount);
7872 IDirect3D9_Release(d3d);
7873 DestroyWindow(window);
7876 static void test_shared_handle(void)
7878 IDirect3DDevice9 *device;
7879 IDirect3D9 *d3d;
7880 ULONG refcount;
7881 HWND window;
7882 HRESULT hr;
7883 /* Native d3d9ex refuses to create a shared texture if the texture pointer
7884 * is not initialized to NULL. Make sure this doesn't cause issues here. */
7885 IDirect3DTexture9 *texture = NULL;
7886 IDirect3DSurface9 *surface = NULL;
7887 IDirect3DVertexBuffer9 *vertex_buffer = NULL;
7888 IDirect3DIndexBuffer9 *index_buffer = NULL;
7889 HANDLE handle = NULL;
7890 void *mem;
7891 D3DCAPS9 caps;
7893 window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7894 0, 0, 640, 480, 0, 0, 0, 0);
7895 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7896 ok(!!d3d, "Failed to create a D3D object.\n");
7897 if (!(device = create_device(d3d, window, window, TRUE)))
7899 skip("Failed to create a D3D device, skipping tests.\n");
7900 IDirect3D9_Release(d3d);
7901 DestroyWindow(window);
7902 return;
7905 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7906 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7907 mem = HeapAlloc(GetProcessHeap(), 0, 128 * 128 * 4);
7909 /* Windows XP returns E_NOTIMPL, Windows 7 returns INVALIDCALL, except for
7910 * CreateVertexBuffer, where it returns NOTAVAILABLE. */
7911 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
7912 D3DPOOL_DEFAULT, &texture, &handle);
7913 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7914 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
7915 D3DPOOL_SYSTEMMEM, &texture, &mem);
7916 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7918 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
7919 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, &handle);
7920 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7921 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
7922 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, &mem);
7923 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7925 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
7926 &vertex_buffer, &handle);
7927 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7928 hr = IDirect3DDevice9_CreateVertexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
7929 &vertex_buffer, &mem);
7930 ok(hr == E_NOTIMPL || broken(hr == D3DERR_NOTAVAILABLE), "Got unexpected hr %#x.\n", hr);
7932 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_DEFAULT,
7933 &index_buffer, &handle);
7934 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7935 hr = IDirect3DDevice9_CreateIndexBuffer(device, 16, 0, 0, D3DPOOL_SYSTEMMEM,
7936 &index_buffer, &mem);
7937 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7939 if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
7941 IDirect3DCubeTexture9 *cube_texture = NULL;
7942 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
7943 D3DPOOL_DEFAULT, &cube_texture, &handle);
7944 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7945 hr = IDirect3DDevice9_CreateCubeTexture(device, 8, 0, 0, D3DFMT_A8R8G8B8,
7946 D3DPOOL_SYSTEMMEM, &cube_texture, &mem);
7947 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7950 if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
7952 IDirect3DVolumeTexture9 *volume_texture = NULL;
7953 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
7954 D3DPOOL_DEFAULT, &volume_texture, &handle);
7955 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7956 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 0, 0, D3DFMT_A8R8G8B8,
7957 D3DPOOL_SYSTEMMEM, &volume_texture, &mem);
7958 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7961 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7962 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
7963 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7965 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128, D3DFMT_D24X8,
7966 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, &handle);
7967 ok(hr == E_NOTIMPL || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
7969 HeapFree(GetProcessHeap(), 0, mem);
7970 refcount = IDirect3DDevice9_Release(device);
7971 ok(!refcount, "Device has %u references left.\n", refcount);
7972 IDirect3D9_Release(d3d);
7973 DestroyWindow(window);
7976 static void test_pixel_format(void)
7978 HWND hwnd, hwnd2 = NULL;
7979 HDC hdc, hdc2 = NULL;
7980 HMODULE gl = NULL;
7981 int format, test_format;
7982 PIXELFORMATDESCRIPTOR pfd;
7983 IDirect3D9 *d3d9 = NULL;
7984 IDirect3DDevice9 *device = NULL;
7985 HRESULT hr;
7986 static const float point[3] = {0.0, 0.0, 0.0};
7988 hwnd = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7989 100, 100, 160, 160, NULL, NULL, NULL, NULL);
7990 if (!hwnd)
7992 skip("Failed to create window\n");
7993 return;
7996 hwnd2 = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
7997 100, 100, 160, 160, NULL, NULL, NULL, NULL);
7999 hdc = GetDC(hwnd);
8000 if (!hdc)
8002 skip("Failed to get DC\n");
8003 goto cleanup;
8006 if (hwnd2)
8007 hdc2 = GetDC(hwnd2);
8009 gl = LoadLibraryA("opengl32.dll");
8010 ok(!!gl, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
8012 format = GetPixelFormat(hdc);
8013 ok(format == 0, "new window has pixel format %d\n", format);
8015 ZeroMemory(&pfd, sizeof(pfd));
8016 pfd.nSize = sizeof(pfd);
8017 pfd.nVersion = 1;
8018 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
8019 pfd.iPixelType = PFD_TYPE_RGBA;
8020 pfd.iLayerType = PFD_MAIN_PLANE;
8021 format = ChoosePixelFormat(hdc, &pfd);
8022 if (format <= 0)
8024 skip("no pixel format available\n");
8025 goto cleanup;
8028 if (!SetPixelFormat(hdc, format, &pfd) || GetPixelFormat(hdc) != format)
8030 skip("failed to set pixel format\n");
8031 goto cleanup;
8034 if (!hdc2 || !SetPixelFormat(hdc2, format, &pfd) || GetPixelFormat(hdc2) != format)
8036 skip("failed to set pixel format on second window\n");
8037 if (hdc2)
8039 ReleaseDC(hwnd2, hdc2);
8040 hdc2 = NULL;
8044 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
8045 ok(!!d3d9, "Failed to create a D3D object.\n");
8047 test_format = GetPixelFormat(hdc);
8048 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8050 if (!(device = create_device(d3d9, hwnd, hwnd, TRUE)))
8052 skip("Failed to create device\n");
8053 goto cleanup;
8056 test_format = GetPixelFormat(hdc);
8057 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8059 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8060 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8062 test_format = GetPixelFormat(hdc);
8063 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8065 hr = IDirect3DDevice9_BeginScene(device);
8066 ok(SUCCEEDED(hr), "BeginScene failed %#x\n", hr);
8068 test_format = GetPixelFormat(hdc);
8069 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8071 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
8072 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8074 test_format = GetPixelFormat(hdc);
8075 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8077 hr = IDirect3DDevice9_EndScene(device);
8078 ok(SUCCEEDED(hr), "EndScene failed %#x\n", hr);
8080 test_format = GetPixelFormat(hdc);
8081 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8083 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8084 ok(SUCCEEDED(hr), "Present failed %#x\n", hr);
8086 test_format = GetPixelFormat(hdc);
8087 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8089 if (hdc2)
8091 hr = IDirect3DDevice9_Present(device, NULL, NULL, hwnd2, NULL);
8092 ok(SUCCEEDED(hr), "Present failed %#x\n", hr);
8094 test_format = GetPixelFormat(hdc);
8095 ok(test_format == format, "window has pixel format %d, expected %d\n", test_format, format);
8097 test_format = GetPixelFormat(hdc2);
8098 ok(test_format == format, "second window has pixel format %d, expected %d\n", test_format, format);
8101 cleanup:
8102 if (device)
8104 UINT refcount = IDirect3DDevice9_Release(device);
8105 ok(!refcount, "Device has %u references left.\n", refcount);
8107 if (d3d9) IDirect3D9_Release(d3d9);
8108 if (gl) FreeLibrary(gl);
8109 if (hdc) ReleaseDC(hwnd, hdc);
8110 if (hdc2) ReleaseDC(hwnd2, hdc2);
8111 if (hwnd) DestroyWindow(hwnd);
8112 if (hwnd2) DestroyWindow(hwnd2);
8115 static void test_begin_end_state_block(void)
8117 IDirect3DStateBlock9 *stateblock;
8118 IDirect3DDevice9 *device;
8119 IDirect3D9 *d3d;
8120 ULONG refcount;
8121 HWND window;
8122 HRESULT hr;
8124 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8125 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8126 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8127 ok(!!d3d, "Failed to create a D3D object.\n");
8128 if (!(device = create_device(d3d, window, window, TRUE)))
8130 skip("Failed to create a D3D device, skipping tests.\n");
8131 IDirect3D9_Release(d3d);
8132 DestroyWindow(window);
8133 return;
8136 /* Should succeed. */
8137 hr = IDirect3DDevice9_BeginStateBlock(device);
8138 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
8140 /* Calling BeginStateBlock() while recording should return
8141 * D3DERR_INVALIDCALL. */
8142 hr = IDirect3DDevice9_BeginStateBlock(device);
8143 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8145 /* Should succeed. */
8146 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
8147 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8148 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
8149 ok(!!stateblock && stateblock != (IDirect3DStateBlock9 *)0xdeadbeef,
8150 "Got unexpected stateblock %p.\n", stateblock);
8151 IDirect3DStateBlock9_Release(stateblock);
8153 /* Calling EndStateBlock() while not recording should return
8154 * D3DERR_INVALIDCALL. stateblock should not be touched. */
8155 stateblock = (IDirect3DStateBlock9 *)0xdeadbeef;
8156 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8157 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8158 ok(stateblock == (IDirect3DStateBlock9 *)0xdeadbeef,
8159 "Got unexpected stateblock %p.\n", stateblock);
8161 refcount = IDirect3DDevice9_Release(device);
8162 ok(!refcount, "Device has %u references left.\n", refcount);
8163 IDirect3D9_Release(d3d);
8164 DestroyWindow(window);
8167 static void test_shader_constant_apply(void)
8169 static const float vs_const[] = {1.0f, 2.0f, 3.0f, 4.0f};
8170 static const float ps_const[] = {5.0f, 6.0f, 7.0f, 8.0f};
8171 static const float initial[] = {0.0f, 0.0f, 0.0f, 0.0f};
8172 IDirect3DStateBlock9 *stateblock;
8173 DWORD vs_version, ps_version;
8174 IDirect3DDevice9 *device;
8175 IDirect3D9 *d3d;
8176 ULONG refcount;
8177 D3DCAPS9 caps;
8178 float ret[4];
8179 HWND window;
8180 HRESULT hr;
8182 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8183 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8184 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8185 ok(!!d3d, "Failed to create a D3D object.\n");
8186 if (!(device = create_device(d3d, window, window, TRUE)))
8188 skip("Failed to create a D3D device, skipping tests.\n");
8189 IDirect3D9_Release(d3d);
8190 DestroyWindow(window);
8191 return;
8194 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8195 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8196 vs_version = caps.VertexShaderVersion & 0xffff;
8197 ps_version = caps.PixelShaderVersion & 0xffff;
8199 if (vs_version)
8201 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, initial, 1);
8202 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8203 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, initial, 1);
8204 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8206 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8207 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8208 ok(!memcmp(ret, initial, sizeof(initial)),
8209 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8210 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8211 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8212 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8213 ok(!memcmp(ret, initial, sizeof(initial)),
8214 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8215 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8217 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, vs_const, 1);
8218 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8220 if (ps_version)
8222 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, initial, 1);
8223 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8224 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, initial, 1);
8225 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8227 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8228 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8229 ok(!memcmp(ret, initial, sizeof(initial)),
8230 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8231 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8232 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8233 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8234 ok(!memcmp(ret, initial, sizeof(initial)),
8235 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8236 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8238 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, ps_const, 1);
8239 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8242 hr = IDirect3DDevice9_BeginStateBlock(device);
8243 ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
8245 if (vs_version)
8247 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, vs_const, 1);
8248 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8250 if (ps_version)
8252 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, ps_const, 1);
8253 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
8256 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8257 ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
8259 if (vs_version)
8261 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8262 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8263 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8264 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8265 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8266 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8267 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8268 ok(!memcmp(ret, initial, sizeof(initial)),
8269 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8270 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8272 if (ps_version)
8274 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8275 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8276 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8277 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8278 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8279 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8280 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8281 ok(!memcmp(ret, initial, sizeof(initial)),
8282 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8283 ret[0], ret[1], ret[2], ret[3], initial[0], initial[1], initial[2], initial[3]);
8286 /* Apply doesn't overwrite constants that aren't explicitly set on the
8287 * source stateblock. */
8288 hr = IDirect3DStateBlock9_Apply(stateblock);
8289 ok(SUCCEEDED(hr), "Failed to apply stateblock, hr %#x.\n", hr);
8291 if (vs_version)
8293 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, ret, 1);
8294 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8295 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8296 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8297 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8298 hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 1, ret, 1);
8299 ok(SUCCEEDED(hr), "Failed to get vertex shader constant, hr %#x.\n", hr);
8300 ok(!memcmp(ret, vs_const, sizeof(vs_const)),
8301 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8302 ret[0], ret[1], ret[2], ret[3], vs_const[0], vs_const[1], vs_const[2], vs_const[3]);
8304 if (ps_version)
8306 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, ret, 1);
8307 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8308 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8309 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8310 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8311 hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 1, ret, 1);
8312 ok(SUCCEEDED(hr), "Failed to get pixel shader constant, hr %#x.\n", hr);
8313 ok(!memcmp(ret, ps_const, sizeof(ps_const)),
8314 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8315 ret[0], ret[1], ret[2], ret[3], ps_const[0], ps_const[1], ps_const[2], ps_const[3]);
8318 IDirect3DStateBlock9_Release(stateblock);
8319 refcount = IDirect3DDevice9_Release(device);
8320 ok(!refcount, "Device has %u references left.\n", refcount);
8321 IDirect3D9_Release(d3d);
8322 DestroyWindow(window);
8325 static void test_vdecl_apply(void)
8327 IDirect3DVertexDeclaration9 *declaration, *declaration1, *declaration2;
8328 IDirect3DStateBlock9 *stateblock;
8329 IDirect3DDevice9 *device;
8330 IDirect3D9 *d3d;
8331 ULONG refcount;
8332 HWND window;
8333 HRESULT hr;
8335 static const D3DVERTEXELEMENT9 decl1[] =
8337 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8338 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8339 D3DDECL_END(),
8342 static const D3DVERTEXELEMENT9 decl2[] =
8344 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8345 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8346 {0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
8347 D3DDECL_END(),
8350 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8351 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8352 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8353 ok(!!d3d, "Failed to create a D3D object.\n");
8354 if (!(device = create_device(d3d, window, window, TRUE)))
8356 skip("Failed to create a D3D device, skipping tests.\n");
8357 IDirect3D9_Release(d3d);
8358 DestroyWindow(window);
8359 return;
8362 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl1, &declaration1);
8363 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
8365 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl2, &declaration2);
8366 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x.\n", hr);
8368 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8369 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8370 hr = IDirect3DDevice9_BeginStateBlock(device);
8371 ok(SUCCEEDED(hr), "BeginStateBlock failed, hr %#x.\n", hr);
8372 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
8373 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8374 hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
8375 ok(SUCCEEDED(hr), "EndStateBlock failed, hr %#x.\n", hr);
8376 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8377 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8378 hr = IDirect3DStateBlock9_Apply(stateblock);
8379 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8380 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8381 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8382 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
8383 declaration, declaration1);
8384 IDirect3DVertexDeclaration9_Release(declaration);
8386 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8387 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8388 hr = IDirect3DStateBlock9_Capture(stateblock);
8389 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8390 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8391 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8392 hr = IDirect3DStateBlock9_Apply(stateblock);
8393 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8394 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8395 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8396 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8397 declaration, declaration2);
8398 IDirect3DVertexDeclaration9_Release(declaration);
8400 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8401 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8402 hr = IDirect3DStateBlock9_Capture(stateblock);
8403 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8404 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8405 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8406 hr = IDirect3DStateBlock9_Apply(stateblock);
8407 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8408 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8409 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8410 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8411 declaration, declaration2);
8412 IDirect3DVertexDeclaration9_Release(declaration);
8414 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8415 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8416 hr = IDirect3DStateBlock9_Capture(stateblock);
8417 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8418 hr = IDirect3DStateBlock9_Apply(stateblock);
8419 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8420 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8421 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8422 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
8424 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8425 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8426 hr = IDirect3DStateBlock9_Capture(stateblock);
8427 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8428 hr = IDirect3DStateBlock9_Apply(stateblock);
8429 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8430 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8431 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8432 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8433 declaration, declaration2);
8434 IDirect3DVertexDeclaration9_Release(declaration);
8436 IDirect3DStateBlock9_Release(stateblock);
8437 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration1);
8438 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8439 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &stateblock);
8440 ok(SUCCEEDED(hr), "CreateStateBlock failed, hr %#x.\n", hr);
8441 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8442 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8443 hr = IDirect3DStateBlock9_Apply(stateblock);
8444 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8445 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8446 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8447 ok(declaration == declaration1, "Got unexpected vertex declaration %p, expected %p.\n",
8448 declaration, declaration1);
8449 IDirect3DVertexDeclaration9_Release(declaration);
8451 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8452 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8453 hr = IDirect3DStateBlock9_Capture(stateblock);
8454 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8455 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8456 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8457 hr = IDirect3DStateBlock9_Apply(stateblock);
8458 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8459 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8460 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8461 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8462 declaration, declaration2);
8463 IDirect3DVertexDeclaration9_Release(declaration);
8465 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8466 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8467 hr = IDirect3DStateBlock9_Capture(stateblock);
8468 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8469 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8470 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8471 hr = IDirect3DStateBlock9_Apply(stateblock);
8472 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8473 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8474 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8475 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8476 declaration, declaration2);
8477 IDirect3DVertexDeclaration9_Release(declaration);
8479 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8480 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8481 hr = IDirect3DStateBlock9_Capture(stateblock);
8482 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8483 hr = IDirect3DStateBlock9_Apply(stateblock);
8484 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8485 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8486 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8487 ok(!declaration, "Got unexpected vertex declaration %p.\n", declaration);
8489 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration2);
8490 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8491 hr = IDirect3DStateBlock9_Capture(stateblock);
8492 ok(SUCCEEDED(hr), "Capture failed, hr %#x.\n", hr);
8493 hr = IDirect3DStateBlock9_Apply(stateblock);
8494 ok(SUCCEEDED(hr), "Apply failed, hr %#x.\n", hr);
8495 hr = IDirect3DDevice9_GetVertexDeclaration(device, &declaration);
8496 ok(SUCCEEDED(hr), "GetVertexDeclaration failed, hr %#x.\n", hr);
8497 ok(declaration == declaration2, "Got unexpected vertex declaration %p, expected %p.\n",
8498 declaration, declaration2);
8499 IDirect3DVertexDeclaration9_Release(declaration);
8501 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8502 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x.\n", hr);
8503 IDirect3DVertexDeclaration9_Release(declaration1);
8504 IDirect3DVertexDeclaration9_Release(declaration2);
8505 IDirect3DStateBlock9_Release(stateblock);
8506 refcount = IDirect3DDevice9_Release(device);
8507 ok(!refcount, "Device has %u references left.\n", refcount);
8508 IDirect3D9_Release(d3d);
8509 DestroyWindow(window);
8512 static void test_resource_type(void)
8514 IDirect3DDevice9 *device;
8515 IDirect3DSurface9 *surface;
8516 IDirect3DTexture9 *texture;
8517 IDirect3DCubeTexture9 *cube_texture;
8518 IDirect3DVolume9 *volume;
8519 IDirect3DVolumeTexture9 *volume_texture;
8520 D3DSURFACE_DESC surface_desc;
8521 D3DVOLUME_DESC volume_desc;
8522 D3DRESOURCETYPE type;
8523 IDirect3D9 *d3d;
8524 ULONG refcount;
8525 HWND window;
8526 HRESULT hr;
8528 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8529 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8530 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8531 ok(!!d3d, "Failed to create a D3D object.\n");
8532 if (!(device = create_device(d3d, window, window, TRUE)))
8534 skip("Failed to create a D3D device, skipping tests.\n");
8535 IDirect3D9_Release(d3d);
8536 DestroyWindow(window);
8537 return;
8540 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_X8R8G8B8,
8541 D3DPOOL_SYSTEMMEM, &surface, NULL);
8542 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8543 type = IDirect3DSurface9_GetType(surface);
8544 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8545 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8546 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8547 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8548 surface_desc.Type);
8549 IDirect3DSurface9_Release(surface);
8551 hr = IDirect3DDevice9_CreateTexture(device, 2, 8, 4, 0, D3DFMT_X8R8G8B8,
8552 D3DPOOL_SYSTEMMEM, &texture, NULL);
8553 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8554 type = IDirect3DTexture9_GetType(texture);
8555 ok(type == D3DRTYPE_TEXTURE, "Expected type D3DRTYPE_TEXTURE, got %u.\n", type);
8557 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8558 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8559 /* The following code crashes, for the sake of completeness:
8560 * type = texture->lpVtbl->GetType((IDirect3DTexture9 *)surface);
8561 * ok(type == D3DRTYPE_PONIES, "Expected type D3DRTYPE_PONIES, got %u.\n", type);
8563 * So applications will not depend on getting the "right" resource type - whatever it
8564 * may be - from the "wrong" vtable. */
8565 type = IDirect3DSurface9_GetType(surface);
8566 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8567 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8568 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8569 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8570 surface_desc.Type);
8571 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
8572 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
8573 hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &surface_desc);
8574 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8575 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8576 surface_desc.Type);
8577 ok(surface_desc.Width == 2, "Expected width 2, got %u.\n", surface_desc.Width);
8578 ok(surface_desc.Height == 8, "Expected height 8, got %u.\n", surface_desc.Height);
8579 IDirect3DSurface9_Release(surface);
8581 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
8582 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8583 type = IDirect3DSurface9_GetType(surface);
8584 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8585 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8586 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8587 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8588 surface_desc.Type);
8589 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
8590 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
8591 hr = IDirect3DTexture9_GetLevelDesc(texture, 2, &surface_desc);
8592 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8593 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8594 surface_desc.Type);
8595 ok(surface_desc.Width == 1, "Expected width 1, got %u.\n", surface_desc.Width);
8596 ok(surface_desc.Height == 2, "Expected height 2, got %u.\n", surface_desc.Height);
8597 IDirect3DSurface9_Release(surface);
8598 IDirect3DTexture9_Release(texture);
8600 hr = IDirect3DDevice9_CreateCubeTexture(device, 1, 1, 0, D3DFMT_X8R8G8B8,
8601 D3DPOOL_SYSTEMMEM, &cube_texture, NULL);
8602 ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#x.\n", hr);
8603 type = IDirect3DCubeTexture9_GetType(cube_texture);
8604 ok(type == D3DRTYPE_CUBETEXTURE, "Expected type D3DRTYPE_CUBETEXTURE, got %u.\n", type);
8606 hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture,
8607 D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface);
8608 ok(SUCCEEDED(hr), "Failed to get cube map surface, hr %#x.\n", hr);
8609 type = IDirect3DSurface9_GetType(surface);
8610 ok(type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n", type);
8611 hr = IDirect3DSurface9_GetDesc(surface, &surface_desc);
8612 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
8613 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8614 surface_desc.Type);
8615 hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
8616 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8617 ok(surface_desc.Type == D3DRTYPE_SURFACE, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8618 surface_desc.Type);
8619 IDirect3DSurface9_Release(surface);
8620 IDirect3DCubeTexture9_Release(cube_texture);
8622 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 4, 8, 4, 0, D3DFMT_X8R8G8B8,
8623 D3DPOOL_SYSTEMMEM, &volume_texture, NULL);
8624 type = IDirect3DVolumeTexture9_GetType(volume_texture);
8625 ok(type == D3DRTYPE_VOLUMETEXTURE, "Expected type D3DRTYPE_VOLUMETEXTURE, got %u.\n", type);
8627 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
8628 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
8629 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
8630 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
8631 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#x.\n", hr);
8632 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8633 volume_desc.Type);
8634 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
8635 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
8636 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
8637 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
8638 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8639 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8640 volume_desc.Type);
8641 ok(volume_desc.Width == 2, "Expected width 2, got %u.\n", volume_desc.Width);
8642 ok(volume_desc.Height == 4, "Expected height 4, got %u.\n", volume_desc.Height);
8643 ok(volume_desc.Depth == 8, "Expected depth 8, got %u.\n", volume_desc.Depth);
8644 IDirect3DVolume9_Release(volume);
8646 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 2, &volume);
8647 ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
8648 /* IDirect3DVolume9 is not an IDirect3DResource9 and has no GetType method. */
8649 hr = IDirect3DVolume9_GetDesc(volume, &volume_desc);
8650 ok(SUCCEEDED(hr), "Failed to get volume description, hr %#x.\n", hr);
8651 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8652 volume_desc.Type);
8653 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
8654 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
8655 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
8656 hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 2, &volume_desc);
8657 ok(SUCCEEDED(hr), "Failed to get level description, hr %#x.\n", hr);
8658 ok(volume_desc.Type == D3DRTYPE_VOLUME, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8659 volume_desc.Type);
8660 ok(volume_desc.Width == 1, "Expected width 1, got %u.\n", volume_desc.Width);
8661 ok(volume_desc.Height == 1, "Expected height 1, got %u.\n", volume_desc.Height);
8662 ok(volume_desc.Depth == 2, "Expected depth 2, got %u.\n", volume_desc.Depth);
8663 IDirect3DVolume9_Release(volume);
8664 IDirect3DVolumeTexture9_Release(volume_texture);
8666 refcount = IDirect3DDevice9_Release(device);
8667 ok(!refcount, "Device has %u references left.\n", refcount);
8668 IDirect3D9_Release(d3d);
8669 DestroyWindow(window);
8672 static void test_mipmap_lock(void)
8674 IDirect3DDevice9 *device;
8675 IDirect3DSurface9 *surface, *surface2, *surface_dst, *surface_dst2;
8676 IDirect3DTexture9 *texture, *texture_dst;
8677 IDirect3D9 *d3d;
8678 ULONG refcount;
8679 HWND window;
8680 HRESULT hr;
8681 D3DLOCKED_RECT locked_rect;
8683 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
8684 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8685 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8686 ok(!!d3d, "Failed to create a D3D object.\n");
8687 if (!(device = create_device(d3d, window, window, TRUE)))
8689 skip("Failed to create a D3D device, skipping tests.\n");
8690 IDirect3D9_Release(d3d);
8691 DestroyWindow(window);
8692 return;
8695 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
8696 D3DPOOL_DEFAULT, &texture_dst, NULL);
8697 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8698 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 0, &surface_dst);
8699 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8700 hr = IDirect3DTexture9_GetSurfaceLevel(texture_dst, 1, &surface_dst2);
8701 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8703 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 2, 0, D3DFMT_X8R8G8B8,
8704 D3DPOOL_SYSTEMMEM, &texture, NULL);
8705 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8706 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8707 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8708 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface2);
8709 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
8711 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
8712 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
8713 hr = IDirect3DSurface9_LockRect(surface2, &locked_rect, NULL, 0);
8714 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
8715 hr = IDirect3DSurface9_UnlockRect(surface);
8716 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8718 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, surface_dst, NULL);
8719 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
8720 hr = IDirect3DDevice9_UpdateSurface(device, surface2, NULL, surface_dst2, NULL);
8721 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8723 /* Apparently there's no validation on the container. */
8724 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
8725 (IDirect3DBaseTexture9 *)texture_dst);
8726 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
8728 hr = IDirect3DSurface9_UnlockRect(surface2);
8729 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
8731 IDirect3DSurface9_Release(surface_dst2);
8732 IDirect3DSurface9_Release(surface_dst);
8733 IDirect3DSurface9_Release(surface2);
8734 IDirect3DSurface9_Release(surface);
8735 IDirect3DTexture9_Release(texture_dst);
8736 IDirect3DTexture9_Release(texture);
8738 refcount = IDirect3DDevice9_Release(device);
8739 ok(!refcount, "Device has %u references left.\n", refcount);
8740 IDirect3D9_Release(d3d);
8741 DestroyWindow(window);
8744 START_TEST(device)
8746 WNDCLASSA wc = {0};
8747 IDirect3D9 *d3d9;
8749 if (!(d3d9 = Direct3DCreate9(D3D_SDK_VERSION)))
8751 skip("could not create D3D9 object\n");
8752 return;
8754 IDirect3D9_Release(d3d9);
8756 wc.lpfnWndProc = DefWindowProcA;
8757 wc.lpszClassName = "d3d9_test_wc";
8758 RegisterClassA(&wc);
8760 screen_width = GetSystemMetrics(SM_CXSCREEN);
8761 screen_height = GetSystemMetrics(SM_CYSCREEN);
8763 test_get_set_vertex_declaration();
8764 test_get_declaration();
8765 test_fvf_decl_conversion();
8766 test_fvf_decl_management();
8767 test_vertex_declaration_alignment();
8768 test_unused_declaration_type();
8769 test_fpu_setup();
8770 test_multi_device();
8771 test_display_formats();
8772 test_display_modes();
8773 test_swapchain();
8774 test_refcount();
8775 test_mipmap_levels();
8776 test_checkdevicemultisampletype();
8777 test_cursor();
8778 test_cursor_pos();
8779 test_reset_fullscreen();
8780 test_reset();
8781 test_scene();
8782 test_limits();
8783 test_depthstenciltest();
8784 test_get_rt();
8785 test_draw_indexed();
8786 test_null_stream();
8787 test_lights();
8788 test_set_stream_source();
8789 test_scissor_size();
8790 test_wndproc();
8791 test_wndproc_windowed();
8792 test_window_style();
8793 test_mode_change();
8794 test_device_window_reset();
8795 test_reset_resources();
8796 test_set_rt_vp_scissor();
8797 test_volume_get_container();
8798 test_volume_resource();
8799 test_vb_lock_flags();
8800 test_vertex_buffer_alignment();
8801 test_query_support();
8802 test_occlusion_query_states();
8803 test_timestamp_query();
8804 test_get_set_vertex_shader();
8805 test_vertex_shader_constant();
8806 test_get_set_pixel_shader();
8807 test_pixel_shader_constant();
8808 test_wrong_shader();
8809 test_texture_stage_states();
8810 test_cube_textures();
8811 test_mipmap_gen();
8812 test_filter();
8813 test_get_texture();
8814 test_lod();
8815 test_surface_get_container();
8816 test_surface_alignment();
8817 test_lockrect_offset();
8818 test_lockrect_invalid();
8819 test_private_data();
8820 test_getdc();
8821 test_surface_dimensions();
8822 test_surface_format_null();
8823 test_surface_double_unlock();
8824 test_surface_blocks();
8825 test_set_palette();
8826 test_swvp_buffer();
8827 test_npot_textures();
8828 test_vidmem_accounting();
8829 test_volume_locking();
8830 test_update_volumetexture();
8831 test_create_rt_ds_fail();
8832 test_volume_blocks();
8833 test_lockbox_invalid();
8834 test_shared_handle();
8835 test_pixel_format();
8836 test_begin_end_state_block();
8837 test_shader_constant_apply();
8838 test_vdecl_apply();
8839 test_resource_type();
8840 test_mipmap_lock();
8842 UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));