d3d9/tests: Test NPOT texture creation.
[wine] / dlls / d3d9 / tests / device.c
1 /*
2  * Copyright (C) 2006 Vitaliy Margolen
3  * Copyright (C) 2006 Chris Robinson
4  * Copyright 2006-2008, 2010-2011, 2013 Stefan Dösinger for CodeWeavers
5  * Copyright 2005, 2006, 2007 Henri Verbeet
6  * Copyright 2013 Henri Verbeet for CodeWeavers
7  * Copyright (C) 2008 Rico Schüller
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 #define COBJMACROS
25 #include <windowsx.h>
26 #include <d3d9.h>
27 #include "wine/test.h"
28
29 static INT screen_width;
30 static INT screen_height;
31
32 static IDirect3D9 *(WINAPI *pDirect3DCreate9)(UINT);
33
34 static const DWORD simple_vs[] =
35 {
36     0xfffe0101,                                                             /* vs_1_1                       */
37     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position0 v0             */
38     0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000,                         /* dp4 oPos.x, v0, c0           */
39     0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001,                         /* dp4 oPos.y, v0, c1           */
40     0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002,                         /* dp4 oPos.z, v0, c2           */
41     0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003,                         /* dp4 oPos.w, v0, c3           */
42     0x0000ffff,                                                             /* end                          */
43 };
44
45 static DWORD simple_ps[] =
46 {
47     0xffff0101,                                                             /* ps_1_1                       */
48     0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0  */
49     0x00000042, 0xb00f0000,                                                 /* tex t0                       */
50     0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000,                         /* dp3 r0, c1, c0               */
51     0x00000005, 0x800f0000, 0x90e40000, 0x80e40000,                         /* mul r0, v0, r0               */
52     0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000,                         /* mul r0, t0, r0               */
53     0x0000ffff,                                                             /* end                          */
54 };
55
56 static int get_refcount(IUnknown *object)
57 {
58     IUnknown_AddRef( object );
59     return IUnknown_Release( object );
60 }
61
62 /* try to make sure pending X events have been processed before continuing */
63 static void flush_events(void)
64 {
65     MSG msg;
66     int diff = 200;
67     int min_timeout = 100;
68     DWORD time = GetTickCount() + diff;
69
70     while (diff > 0)
71     {
72         if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
73         while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
74         diff = time - GetTickCount();
75     }
76 }
77
78 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND device_window, HWND focus_window, BOOL windowed)
79 {
80     D3DPRESENT_PARAMETERS present_parameters = {0};
81     IDirect3DDevice9 *device;
82
83     present_parameters.Windowed = windowed;
84     present_parameters.hDeviceWindow = device_window;
85     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
86     present_parameters.BackBufferWidth = screen_width;
87     present_parameters.BackBufferHeight = screen_height;
88     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
89     present_parameters.EnableAutoDepthStencil = TRUE;
90     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
91
92     if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
93             D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
94
95     present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
96     if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
97             D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
98
99     if (SUCCEEDED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
100             D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device))) return device;
101
102     return NULL;
103 }
104
105 static HRESULT reset_device(IDirect3DDevice9 *device, HWND device_window, BOOL windowed)
106 {
107     D3DPRESENT_PARAMETERS present_parameters = {0};
108
109     present_parameters.Windowed = windowed;
110     present_parameters.hDeviceWindow = device_window;
111     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
112     present_parameters.BackBufferWidth = screen_width;
113     present_parameters.BackBufferHeight = screen_height;
114     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
115     present_parameters.EnableAutoDepthStencil = TRUE;
116     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
117
118     return IDirect3DDevice9_Reset(device, &present_parameters);
119 }
120
121 #define CHECK_CALL(r,c,d,rc) \
122     if (SUCCEEDED(r)) {\
123         int tmp1 = get_refcount( (IUnknown *)d ); \
124         int rc_new = rc; \
125         ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
126     } else {\
127         trace("%s failed: %08x\n", c, r); \
128     }
129
130 #define CHECK_RELEASE(obj,d,rc) \
131     if (obj) { \
132         int tmp1, rc_new = rc; \
133         IUnknown_Release( (IUnknown*)obj ); \
134         tmp1 = get_refcount( (IUnknown *)d ); \
135         ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
136     }
137
138 #define CHECK_REFCOUNT(obj,rc) \
139     { \
140         int rc_new = rc; \
141         int count = get_refcount( (IUnknown *)obj ); \
142         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
143     }
144
145 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
146     { \
147         int rc_new = rc; \
148         int count = IUnknown_Release( (IUnknown *)obj ); \
149         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
150     }
151
152 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
153     { \
154         int rc_new = rc; \
155         int count = IUnknown_AddRef( (IUnknown *)obj ); \
156         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
157     }
158
159 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
160     { \
161         void *container_ptr = (void *)0x1337c0d3; \
162         hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
163         ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
164             "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
165         if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
166     }
167
168 static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count)
169 {
170     IDirect3DBaseTexture9* texture = NULL;
171     HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0,
172             D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
173
174     if (SUCCEEDED(hr)) {
175         DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
176         ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
177     } else
178         trace("CreateTexture failed: %08x\n", hr);
179
180     if (texture) IDirect3DBaseTexture9_Release( texture );
181 }
182
183 static void test_mipmap_levels(void)
184 {
185
186     HRESULT               hr;
187     HWND                  hwnd = NULL;
188
189     IDirect3D9            *pD3d = NULL;
190     IDirect3DDevice9      *pDevice = NULL;
191     D3DPRESENT_PARAMETERS d3dpp;
192     D3DDISPLAYMODE        d3ddm;
193
194     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
195     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
196     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
197     ok(hwnd != NULL, "Failed to create window\n");
198     if (!pD3d || !hwnd) goto cleanup;
199
200     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
201     ZeroMemory( &d3dpp, sizeof(d3dpp) );
202     d3dpp.Windowed         = TRUE;
203     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
204     d3dpp.BackBufferFormat = d3ddm.Format;
205
206     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
207                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
208     ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%08x)\n", hr);
209     if (FAILED(hr)) {
210         skip("failed to create a d3d device\n");
211         goto cleanup;
212     }
213
214     check_mipmap_levels(pDevice, 32, 32, 6);
215     check_mipmap_levels(pDevice, 256, 1, 9);
216     check_mipmap_levels(pDevice, 1, 256, 9);
217     check_mipmap_levels(pDevice, 1, 1, 1);
218
219 cleanup:
220     if (pDevice)
221     {
222         UINT refcount = IDirect3DDevice9_Release( pDevice );
223         ok(!refcount, "Device has %u references left.\n", refcount);
224     }
225     if (pD3d) IDirect3D9_Release( pD3d );
226     DestroyWindow( hwnd );
227 }
228
229 static void test_checkdevicemultisampletype(void)
230 {
231
232     HRESULT               hr;
233     HWND                  hwnd = NULL;
234
235     IDirect3D9            *pD3d = NULL;
236     IDirect3DDevice9      *pDevice = NULL;
237     D3DPRESENT_PARAMETERS d3dpp;
238     D3DDISPLAYMODE        d3ddm;
239     DWORD                 qualityLevels;
240
241     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
242     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
243     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
244     ok(hwnd != NULL, "Failed to create window\n");
245     if (!pD3d || !hwnd) goto cleanup;
246
247     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
248     ZeroMemory( &d3dpp, sizeof(d3dpp) );
249     d3dpp.Windowed         = TRUE;
250     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
251     d3dpp.BackBufferFormat = d3ddm.Format;
252
253     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
254                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
255     ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "Failed to create IDirect3D9Device (%08x)\n", hr);
256     if (FAILED(hr)) {
257         skip("failed to create a d3d device\n");
258         goto cleanup;
259     }
260
261     qualityLevels = 0;
262
263     hr = IDirect3D9_CheckDeviceMultiSampleType(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE,
264     D3DMULTISAMPLE_NONE, &qualityLevels);
265     ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
266     if(hr == D3DERR_NOTAVAILABLE)
267     {
268         skip("IDirect3D9_CheckDeviceMultiSampleType not available\n");
269         goto cleanup;
270     }
271     ok(qualityLevels == 1,"qualitylevel is not 1 but %d\n",qualityLevels);
272
273     hr = IDirect3D9_CheckDeviceMultiSampleType(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, FALSE,
274     D3DMULTISAMPLE_NONE, &qualityLevels);
275     ok(SUCCEEDED(hr), "CheckDeviceMultiSampleType failed with (%08x)\n", hr);
276     ok(qualityLevels == 1,"qualitylevel is not 1 but %d\n",qualityLevels);
277
278 cleanup:
279     if (pDevice)
280     {
281         UINT refcount = IDirect3DDevice9_Release( pDevice );
282         ok(!refcount, "Device has %u references left.\n", refcount);
283     }
284     if (pD3d) IDirect3D9_Release( pD3d );
285     DestroyWindow( hwnd );
286 }
287
288 static void test_swapchain(void)
289 {
290     HRESULT                      hr;
291     HWND                         hwnd               = NULL;
292     IDirect3D9                  *pD3d               = NULL;
293     IDirect3DDevice9            *pDevice            = NULL;
294     IDirect3DSwapChain9         *swapchain0         = NULL;
295     IDirect3DSwapChain9         *swapchain1         = NULL;
296     IDirect3DSwapChain9         *swapchain2         = NULL;
297     IDirect3DSwapChain9         *swapchain3         = NULL;
298     IDirect3DSwapChain9         *swapchainX         = NULL;
299     IDirect3DSurface9           *backbuffer         = NULL;
300     D3DPRESENT_PARAMETERS        d3dpp;
301     D3DDISPLAYMODE               d3ddm;
302
303     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
304     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
305     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
306     ok(hwnd != NULL, "Failed to create window\n");
307     if (!pD3d || !hwnd) goto cleanup;
308
309     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
310     ZeroMemory( &d3dpp, sizeof(d3dpp) );
311     d3dpp.Windowed         = TRUE;
312     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
313     d3dpp.BackBufferFormat = d3ddm.Format;
314     d3dpp.BackBufferCount  = 0;
315
316     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
317                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
318     ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
319        "Failed to create IDirect3D9Device (%08x)\n", hr);
320     if (FAILED(hr)) goto cleanup;
321
322     /* Check if the back buffer count was modified */
323     ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
324
325     /* Get the implicit swapchain */
326     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &swapchain0);
327     ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
328     if(swapchain0) IDirect3DSwapChain9_Release(swapchain0);
329
330     /* Check if there is a back buffer */
331     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
332     ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
333     ok(backbuffer != NULL, "The back buffer is NULL\n");
334     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
335
336     /* Try to get a nonexistent swapchain */
337     hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
338     ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr);
339     ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
340     if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
341
342     /* Create a bunch of swapchains */
343     d3dpp.BackBufferCount = 0;
344     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain1);
345     ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
346     ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
347
348     d3dpp.BackBufferCount  = 1;
349     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain2);
350     ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
351
352     d3dpp.BackBufferCount  = 2;
353     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3);
354     ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
355     if(SUCCEEDED(hr)) {
356         /* Swapchain 3, created with backbuffercount 2 */
357         backbuffer = (void *) 0xdeadbeef;
358         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
359         ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%08x)\n", hr);
360         ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
361         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
362
363         backbuffer = (void *) 0xdeadbeef;
364         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
365         ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%08x)\n", hr);
366         ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
367         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
368
369         backbuffer = (void *) 0xdeadbeef;
370         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
371         ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
372         ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
373         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
374
375         backbuffer = (void *) 0xdeadbeef;
376         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
377         ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
378         ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
379         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
380     }
381
382     /* Check the back buffers of the swapchains */
383     /* Swapchain 1, created with backbuffercount 0 */
384     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
385     ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
386     ok(backbuffer != NULL, "The back buffer is NULL (%08x)\n", hr);
387     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
388
389     backbuffer = (void *) 0xdeadbeef;
390     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
391     ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
392     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
393     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
394
395     /* Swapchain 2 - created with backbuffercount 1 */
396     backbuffer = (void *) 0xdeadbeef;
397     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
398     ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
399     ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
400     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
401
402     backbuffer = (void *) 0xdeadbeef;
403     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
404     ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
405     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
406     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
407
408     backbuffer = (void *) 0xdeadbeef;
409     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
410     ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
411     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
412     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
413
414     /* Try getSwapChain on a manually created swapchain
415      * it should fail, apparently GetSwapChain only returns implicit swapchains
416      */
417     swapchainX = (void *) 0xdeadbeef;
418     hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
419     ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%08x)\n", hr);
420     ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
421     if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
422
423 cleanup:
424     if(swapchain1) IDirect3DSwapChain9_Release(swapchain1);
425     if(swapchain2) IDirect3DSwapChain9_Release(swapchain2);
426     if(swapchain3) IDirect3DSwapChain9_Release(swapchain3);
427     if (pDevice)
428     {
429         UINT refcount = IDirect3DDevice9_Release(pDevice);
430         ok(!refcount, "Device has %u references left.\n", refcount);
431     }
432     if (pD3d) IDirect3D9_Release(pD3d);
433     DestroyWindow( hwnd );
434 }
435
436 static void test_refcount(void)
437 {
438     HRESULT                      hr;
439     HWND                         hwnd               = NULL;
440     IDirect3D9                  *pD3d               = NULL;
441     IDirect3D9                  *pD3d2              = NULL;
442     IDirect3DDevice9            *pDevice            = NULL;
443     IDirect3DVertexBuffer9      *pVertexBuffer      = NULL;
444     IDirect3DIndexBuffer9       *pIndexBuffer       = NULL;
445     IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
446     IDirect3DVertexShader9      *pVertexShader      = NULL;
447     IDirect3DPixelShader9       *pPixelShader       = NULL;
448     IDirect3DCubeTexture9       *pCubeTexture       = NULL;
449     IDirect3DTexture9           *pTexture           = NULL;
450     IDirect3DVolumeTexture9     *pVolumeTexture     = NULL;
451     IDirect3DVolume9            *pVolumeLevel       = NULL;
452     IDirect3DSurface9           *pStencilSurface    = NULL;
453     IDirect3DSurface9           *pOffscreenSurface  = NULL;
454     IDirect3DSurface9           *pRenderTarget      = NULL;
455     IDirect3DSurface9           *pRenderTarget2     = NULL;
456     IDirect3DSurface9           *pRenderTarget3     = NULL;
457     IDirect3DSurface9           *pTextureLevel      = NULL;
458     IDirect3DSurface9           *pBackBuffer        = NULL;
459     IDirect3DStateBlock9        *pStateBlock        = NULL;
460     IDirect3DStateBlock9        *pStateBlock1       = NULL;
461     IDirect3DSwapChain9         *pSwapChain         = NULL;
462     IDirect3DQuery9             *pQuery             = NULL;
463     D3DPRESENT_PARAMETERS        d3dpp;
464     D3DDISPLAYMODE               d3ddm;
465     int                          refcount = 0, tmp;
466
467     D3DVERTEXELEMENT9 decl[] =
468     {
469         D3DDECL_END()
470     };
471
472     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
473     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
474     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
475     ok(hwnd != NULL, "Failed to create window\n");
476     if (!pD3d || !hwnd) goto cleanup;
477
478     CHECK_REFCOUNT( pD3d, 1 );
479
480     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
481     ZeroMemory( &d3dpp, sizeof(d3dpp) );
482     d3dpp.Windowed         = TRUE;
483     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
484     d3dpp.BackBufferFormat = d3ddm.Format;
485     d3dpp.EnableAutoDepthStencil = TRUE;
486     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
487
488     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
489                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
490     ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
491        "Failed to create IDirect3D9Device (%08x)\n", hr);
492     if (FAILED(hr)) goto cleanup;
493
494     refcount = get_refcount( (IUnknown *)pDevice );
495     ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
496
497     CHECK_REFCOUNT( pD3d, 2 );
498
499     hr = IDirect3DDevice9_GetDirect3D(pDevice, &pD3d2);
500     CHECK_CALL( hr, "GetDirect3D", pDevice, refcount );
501
502     ok(pD3d2 == pD3d, "Expected IDirect3D9 pointers to be equal\n");
503     CHECK_REFCOUNT( pD3d, 3 );
504     CHECK_RELEASE_REFCOUNT( pD3d, 2 );
505
506     /**
507      * Check refcount of implicit surfaces and implicit swapchain. Findings:
508      *   - the container is the device OR swapchain
509      *   - they hold a reference to the device
510      *   - they are created with a refcount of 0 (Get/Release returns original refcount)
511      *   - they are not freed if refcount reaches 0.
512      *   - the refcount is not forwarded to the container.
513      */
514     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapChain);
515     CHECK_CALL( hr, "GetSwapChain", pDevice, ++refcount);
516     if (pSwapChain)
517     {
518         CHECK_REFCOUNT( pSwapChain, 1);
519
520         hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
521         CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
522         CHECK_REFCOUNT( pSwapChain, 1);
523         if(pRenderTarget)
524         {
525             CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
526             CHECK_REFCOUNT( pRenderTarget, 1);
527
528             CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
529             CHECK_REFCOUNT(pDevice, refcount);
530             CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
531             CHECK_REFCOUNT(pDevice, refcount);
532
533             hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
534             CHECK_CALL( hr, "GetRenderTarget", pDevice, refcount);
535             CHECK_REFCOUNT( pRenderTarget, 2);
536             CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
537             CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
538             CHECK_REFCOUNT( pDevice, --refcount);
539
540             /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
541             CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
542             CHECK_REFCOUNT(pDevice, ++refcount);
543             CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
544             CHECK_REFCOUNT(pDevice, --refcount);
545         }
546
547         /* Render target and back buffer are identical. */
548         hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, 0, &pBackBuffer);
549         CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
550         if(pBackBuffer)
551         {
552             CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
553             ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
554             pRenderTarget, pBackBuffer);
555             pBackBuffer = NULL;
556         }
557         CHECK_REFCOUNT( pDevice, --refcount);
558
559         hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pStencilSurface);
560         CHECK_CALL( hr, "GetDepthStencilSurface", pDevice, ++refcount);
561         CHECK_REFCOUNT( pSwapChain, 1);
562         if(pStencilSurface)
563         {
564             CHECK_SURFACE_CONTAINER( pStencilSurface, IID_IDirect3DDevice9, pDevice);
565             CHECK_REFCOUNT( pStencilSurface, 1);
566
567             CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
568             CHECK_REFCOUNT(pDevice, refcount);
569             CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
570             CHECK_REFCOUNT(pDevice, refcount);
571
572             CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
573             CHECK_REFCOUNT( pDevice, --refcount);
574
575             /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
576             CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
577             CHECK_REFCOUNT(pDevice, ++refcount);
578             CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
579             CHECK_REFCOUNT(pDevice, --refcount);
580             pStencilSurface = NULL;
581         }
582
583         CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
584         CHECK_REFCOUNT( pDevice, --refcount);
585
586         /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
587         CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
588         CHECK_REFCOUNT(pDevice, ++refcount);
589         CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
590         CHECK_REFCOUNT(pDevice, --refcount);
591         pSwapChain = NULL;
592     }
593
594     /* Buffers */
595     hr = IDirect3DDevice9_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL );
596     CHECK_CALL( hr, "CreateIndexBuffer", pDevice, ++refcount );
597     if(pIndexBuffer)
598     {
599         tmp = get_refcount( (IUnknown *)pIndexBuffer );
600
601         hr = IDirect3DDevice9_SetIndices(pDevice, pIndexBuffer);
602         CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
603         hr = IDirect3DDevice9_SetIndices(pDevice, NULL);
604         CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
605     }
606
607     hr = IDirect3DDevice9_CreateVertexBuffer( pDevice, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
608     CHECK_CALL( hr, "CreateVertexBuffer", pDevice, ++refcount );
609     if(pVertexBuffer)
610     {
611         IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
612         UINT offset = ~0;
613         UINT stride = ~0;
614
615         tmp = get_refcount( (IUnknown *)pVertexBuffer );
616
617         hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, pVertexBuffer, 0, 3 * sizeof(float));
618         CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
619         hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, NULL, 0, 0);
620         CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
621
622         hr = IDirect3DDevice9_GetStreamSource(pDevice, 0, &pVBuf, &offset, &stride);
623         ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
624         ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
625         ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
626         ok(offset==0, "offset not 0 (got %u)!\n", offset);
627     }
628     /* Shaders */
629     hr = IDirect3DDevice9_CreateVertexDeclaration( pDevice, decl, &pVertexDeclaration );
630     CHECK_CALL( hr, "CreateVertexDeclaration", pDevice, ++refcount );
631     hr = IDirect3DDevice9_CreateVertexShader( pDevice, simple_vs, &pVertexShader );
632     CHECK_CALL( hr, "CreateVertexShader", pDevice, ++refcount );
633     hr = IDirect3DDevice9_CreatePixelShader( pDevice, simple_ps, &pPixelShader );
634     CHECK_CALL( hr, "CreatePixelShader", pDevice, ++refcount );
635     /* Textures */
636     hr = IDirect3DDevice9_CreateTexture( pDevice, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL );
637     CHECK_CALL( hr, "CreateTexture", pDevice, ++refcount );
638     if (pTexture)
639     {
640         tmp = get_refcount( (IUnknown *)pTexture );
641
642         /* SetTexture should not increase refcounts */
643         hr = IDirect3DDevice9_SetTexture(pDevice, 0, (IDirect3DBaseTexture9 *) pTexture);
644         CHECK_CALL( hr, "SetTexture", pTexture, tmp);
645         hr = IDirect3DDevice9_SetTexture(pDevice, 0, NULL);
646         CHECK_CALL( hr, "SetTexture", pTexture, tmp);
647
648         /* This should not increment device refcount */
649         hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
650         CHECK_CALL( hr, "GetSurfaceLevel", pDevice, refcount );
651         /* But should increment texture's refcount */
652         CHECK_REFCOUNT( pTexture, tmp+1 );
653         /* Because the texture and surface refcount are identical */
654         if (pTextureLevel)
655         {
656             CHECK_REFCOUNT        ( pTextureLevel, tmp+1 );
657             CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
658             CHECK_REFCOUNT        ( pTexture     , tmp+2 );
659             CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
660             CHECK_REFCOUNT        ( pTexture     , tmp+1 );
661             CHECK_RELEASE_REFCOUNT( pTexture     , tmp   );
662             CHECK_REFCOUNT        ( pTextureLevel, tmp   );
663         }
664     }
665     hr = IDirect3DDevice9_CreateCubeTexture( pDevice, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL );
666     CHECK_CALL( hr, "CreateCubeTexture", pDevice, ++refcount );
667     hr = IDirect3DDevice9_CreateVolumeTexture( pDevice, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL );
668     CHECK_CALL( hr, "CreateVolumeTexture", pDevice, ++refcount );
669     if (pVolumeTexture)
670     {
671         tmp = get_refcount( (IUnknown *)pVolumeTexture );
672
673         /* This should not increment device refcount */
674         hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
675         CHECK_CALL( hr, "GetVolumeLevel", pDevice, refcount );
676         /* But should increment volume texture's refcount */
677         CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
678         /* Because the volume texture and volume refcount are identical */
679         if (pVolumeLevel)
680         {
681             CHECK_REFCOUNT        ( pVolumeLevel  , tmp+1 );
682             CHECK_ADDREF_REFCOUNT ( pVolumeLevel  , tmp+2 );
683             CHECK_REFCOUNT        ( pVolumeTexture, tmp+2 );
684             CHECK_RELEASE_REFCOUNT( pVolumeLevel  , tmp+1 );
685             CHECK_REFCOUNT        ( pVolumeTexture, tmp+1 );
686             CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp   );
687             CHECK_REFCOUNT        ( pVolumeLevel  , tmp   );
688         }
689     }
690     /* Surfaces */
691     hr = IDirect3DDevice9_CreateDepthStencilSurface( pDevice, 32, 32, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL );
692     CHECK_CALL( hr, "CreateDepthStencilSurface", pDevice, ++refcount );
693     CHECK_REFCOUNT( pStencilSurface, 1 );
694     hr = IDirect3DDevice9_CreateOffscreenPlainSurface( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL );
695     CHECK_CALL( hr, "CreateOffscreenPlainSurface", pDevice, ++refcount );
696     CHECK_REFCOUNT( pOffscreenSurface, 1 );
697     hr = IDirect3DDevice9_CreateRenderTarget( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL );
698     CHECK_CALL( hr, "CreateRenderTarget", pDevice, ++refcount );
699     CHECK_REFCOUNT( pRenderTarget3, 1 );
700     /* Misc */
701     hr = IDirect3DDevice9_CreateStateBlock( pDevice, D3DSBT_ALL, &pStateBlock );
702     CHECK_CALL( hr, "CreateStateBlock", pDevice, ++refcount );
703     hr = IDirect3DDevice9_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
704     CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, ++refcount );
705     if(pSwapChain)
706     {
707         /* check implicit back buffer */
708         hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
709         CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
710         CHECK_REFCOUNT( pSwapChain, 1);
711         if(pBackBuffer)
712         {
713             CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
714             CHECK_REFCOUNT( pBackBuffer, 1);
715             CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
716             CHECK_REFCOUNT( pDevice, --refcount);
717
718             /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
719             CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
720             CHECK_REFCOUNT(pDevice, ++refcount);
721             CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
722             CHECK_REFCOUNT(pDevice, --refcount);
723             pBackBuffer = NULL;
724         }
725         CHECK_REFCOUNT( pSwapChain, 1);
726     }
727     hr = IDirect3DDevice9_CreateQuery( pDevice, D3DQUERYTYPE_EVENT, &pQuery );
728     CHECK_CALL( hr, "CreateQuery", pDevice, ++refcount );
729
730     hr = IDirect3DDevice9_BeginStateBlock( pDevice );
731     CHECK_CALL( hr, "BeginStateBlock", pDevice, refcount );
732     hr = IDirect3DDevice9_EndStateBlock( pDevice, &pStateBlock1 );
733     CHECK_CALL( hr, "EndStateBlock", pDevice, ++refcount );
734
735     /* The implicit render target is not freed if refcount reaches 0.
736      * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
737     hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget2);
738     CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
739     if(pRenderTarget2)
740     {
741         CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
742         ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
743            pRenderTarget, pRenderTarget2);
744         CHECK_REFCOUNT( pDevice, --refcount);
745         pRenderTarget2 = NULL;
746     }
747     pRenderTarget = NULL;
748
749 cleanup:
750     CHECK_RELEASE(pDevice,              pDevice, --refcount);
751
752     /* Buffers */
753     CHECK_RELEASE(pVertexBuffer,        pDevice, --refcount);
754     CHECK_RELEASE(pIndexBuffer,         pDevice, --refcount);
755     /* Shaders */
756     CHECK_RELEASE(pVertexDeclaration,   pDevice, --refcount);
757     CHECK_RELEASE(pVertexShader,        pDevice, --refcount);
758     CHECK_RELEASE(pPixelShader,         pDevice, --refcount);
759     /* Textures */
760     CHECK_RELEASE(pTextureLevel,        pDevice, --refcount);
761     CHECK_RELEASE(pCubeTexture,         pDevice, --refcount);
762     CHECK_RELEASE(pVolumeTexture,       pDevice, --refcount);
763     /* Surfaces */
764     CHECK_RELEASE(pStencilSurface,      pDevice, --refcount);
765     CHECK_RELEASE(pOffscreenSurface,    pDevice, --refcount);
766     CHECK_RELEASE(pRenderTarget3,       pDevice, --refcount);
767     /* Misc */
768     CHECK_RELEASE(pStateBlock,          pDevice, --refcount);
769     CHECK_RELEASE(pSwapChain,           pDevice, --refcount);
770     CHECK_RELEASE(pQuery,               pDevice, --refcount);
771     /* This will destroy device - cannot check the refcount here */
772     if (pStateBlock1)         CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
773
774     if (pD3d)                 CHECK_RELEASE_REFCOUNT( pD3d, 0);
775
776     DestroyWindow( hwnd );
777 }
778
779 static void test_cursor(void)
780 {
781     HRESULT                      hr;
782     HWND                         hwnd               = NULL;
783     IDirect3D9                  *pD3d               = NULL;
784     IDirect3DDevice9            *pDevice            = NULL;
785     D3DPRESENT_PARAMETERS        d3dpp;
786     D3DDISPLAYMODE               d3ddm;
787     CURSORINFO                   info;
788     IDirect3DSurface9 *cursor = NULL;
789     HCURSOR cur;
790
791     memset(&info, 0, sizeof(info));
792     info.cbSize = sizeof(info);
793     ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
794     cur = info.hCursor;
795
796     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
797     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
798     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
799     ok(hwnd != NULL, "Failed to create window\n");
800     if (!pD3d || !hwnd) goto cleanup;
801
802     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
803     ZeroMemory( &d3dpp, sizeof(d3dpp) );
804     d3dpp.Windowed         = TRUE;
805     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
806     d3dpp.BackBufferFormat = d3ddm.Format;
807
808     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
809                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
810     ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
811        "Failed to create IDirect3D9Device (%08x)\n", hr);
812     if (FAILED(hr)) goto cleanup;
813
814     IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, 0);
815     ok(cursor != NULL, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
816
817     /* Initially hidden */
818     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
819     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
820
821     /* Not enabled without a surface*/
822     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
823     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
824
825     /* Fails */
826     hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, NULL);
827     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
828
829     hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, cursor);
830     ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
831
832     IDirect3DSurface9_Release(cursor);
833
834     memset(&info, 0, sizeof(info));
835     info.cbSize = sizeof(info);
836     ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
837     ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
838     ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
839
840     /* Still hidden */
841     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
842     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
843
844     /* Enabled now*/
845     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
846     ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
847
848     /* GDI cursor unchanged */
849     memset(&info, 0, sizeof(info));
850     info.cbSize = sizeof(info);
851     ok(GetCursorInfo(&info), "GetCursorInfo failed\n");
852     ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
853     ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
854
855 cleanup:
856     if (pDevice)
857     {
858         UINT refcount = IDirect3DDevice9_Release(pDevice);
859         ok(!refcount, "Device has %u references left.\n", refcount);
860     }
861     if (pD3d) IDirect3D9_Release(pD3d);
862     DestroyWindow( hwnd );
863 }
864
865 static void test_reset(void)
866 {
867     HRESULT                      hr;
868     HWND                         hwnd               = NULL;
869     RECT                         winrect;
870     IDirect3D9                  *pD3d               = NULL;
871     D3DPRESENT_PARAMETERS        d3dpp;
872     D3DDISPLAYMODE               d3ddm, d3ddm2;
873     D3DVIEWPORT9                 vp;
874     DWORD                        width, orig_width = GetSystemMetrics(SM_CXSCREEN);
875     DWORD                        height, orig_height = GetSystemMetrics(SM_CYSCREEN);
876     IDirect3DSwapChain9          *pSwapchain;
877     IDirect3DSurface9            *surface;
878     IDirect3DTexture9            *texture;
879     IDirect3DVertexShader9       *shader;
880     UINT                         i, adapter_mode_count;
881     D3DLOCKED_RECT               lockrect;
882     IDirect3DDevice9 *device1 = NULL;
883     IDirect3DDevice9 *device2 = NULL;
884     D3DCAPS9 caps;
885     DWORD value;
886     struct
887     {
888         UINT w;
889         UINT h;
890     } *modes = NULL;
891     UINT mode_count = 0;
892
893     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
894     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
895     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
896     ok(hwnd != NULL, "Failed to create window\n");
897     if (!pD3d || !hwnd) goto cleanup;
898
899     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
900     adapter_mode_count = IDirect3D9_GetAdapterModeCount(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format);
901     modes = HeapAlloc(GetProcessHeap(), 0, sizeof(*modes) * adapter_mode_count);
902     for(i = 0; i < adapter_mode_count; ++i)
903     {
904         UINT j;
905         ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
906         hr = IDirect3D9_EnumAdapterModes(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
907         ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#x\n", hr);
908
909         for (j = 0; j < mode_count; ++j)
910         {
911             if (modes[j].w == d3ddm2.Width && modes[j].h == d3ddm2.Height)
912                 break;
913         }
914         if (j == mode_count)
915         {
916             modes[j].w = d3ddm2.Width;
917             modes[j].h = d3ddm2.Height;
918             ++mode_count;
919         }
920
921         /* We use them as invalid modes */
922         if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
923            (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
924             skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
925                  d3ddm2.Width, d3ddm2.Height);
926             goto cleanup;
927         }
928     }
929
930     if (mode_count < 2)
931     {
932         skip("Less than 2 modes supported, skipping mode tests\n");
933         goto cleanup;
934     }
935
936     i = 0;
937     if (modes[i].w == orig_width && modes[i].h == orig_height) ++i;
938
939     ZeroMemory( &d3dpp, sizeof(d3dpp) );
940     d3dpp.Windowed         = FALSE;
941     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
942     d3dpp.BackBufferWidth  = modes[i].w;
943     d3dpp.BackBufferHeight = modes[i].h;
944     d3dpp.BackBufferFormat = d3ddm.Format;
945     d3dpp.EnableAutoDepthStencil = TRUE;
946     d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
947
948     hr = IDirect3D9_CreateDevice(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
949             hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device1);
950     if (FAILED(hr))
951     {
952         skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
953         goto cleanup;
954     }
955     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
956     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
957
958     hr = IDirect3DDevice9_GetDeviceCaps(device1, &caps);
959     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
960
961     width = GetSystemMetrics(SM_CXSCREEN);
962     height = GetSystemMetrics(SM_CYSCREEN);
963     ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
964     ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
965
966     hr = IDirect3DDevice9_GetViewport(device1, &vp);
967     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
968     if(SUCCEEDED(hr))
969     {
970         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
971         ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
972         ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
973         ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
974         ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
975         ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
976     }
977
978     i = 1;
979     vp.X = 10;
980     vp.Y = 20;
981     vp.MinZ = 2;
982     vp.MaxZ = 3;
983     hr = IDirect3DDevice9_SetViewport(device1, &vp);
984     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
985
986     hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
987     ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
988     ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
989     hr = IDirect3DDevice9_SetRenderState(device1, D3DRS_LIGHTING, FALSE);
990     ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
991
992     ZeroMemory( &d3dpp, sizeof(d3dpp) );
993     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
994     d3dpp.Windowed         = FALSE;
995     d3dpp.BackBufferWidth  = modes[i].w;
996     d3dpp.BackBufferHeight = modes[i].h;
997     d3dpp.BackBufferFormat = d3ddm.Format;
998     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
999     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1000     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1001     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1002
1003     hr = IDirect3DDevice9_GetRenderState(device1, D3DRS_LIGHTING, &value);
1004     ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1005     ok(!!value, "Got unexpected value %#x for D3DRS_LIGHTING.\n", value);
1006
1007     ZeroMemory(&vp, sizeof(vp));
1008     hr = IDirect3DDevice9_GetViewport(device1, &vp);
1009     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1010     if(SUCCEEDED(hr))
1011     {
1012         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1013         ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1014         ok(vp.Width == modes[i].w, "D3DVIEWPORT->Width = %u, expected %u\n", vp.Width, modes[i].w);
1015         ok(vp.Height == modes[i].h, "D3DVIEWPORT->Height = %u, expected %u\n", vp.Height, modes[i].h);
1016         ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1017         ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1018     }
1019
1020     width = GetSystemMetrics(SM_CXSCREEN);
1021     height = GetSystemMetrics(SM_CYSCREEN);
1022     ok(width == modes[i].w, "Screen width is %u, expected %u\n", width, modes[i].w);
1023     ok(height == modes[i].h, "Screen height is %u, expected %u\n", height, modes[i].h);
1024
1025     hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1026     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1027     if(SUCCEEDED(hr))
1028     {
1029         ZeroMemory(&d3dpp, sizeof(d3dpp));
1030         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1031         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1032         if(SUCCEEDED(hr))
1033         {
1034             ok(d3dpp.BackBufferWidth == modes[i].w, "Back buffer width is %u, expected %u\n",
1035                     d3dpp.BackBufferWidth, modes[i].w);
1036             ok(d3dpp.BackBufferHeight == modes[i].h, "Back buffer height is %u, expected %u\n",
1037                     d3dpp.BackBufferHeight, modes[i].h);
1038         }
1039         IDirect3DSwapChain9_Release(pSwapchain);
1040     }
1041
1042     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1043     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1044     d3dpp.Windowed         = TRUE;
1045     d3dpp.BackBufferWidth  = 400;
1046     d3dpp.BackBufferHeight = 300;
1047     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1048     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1049     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1050     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1051
1052     width = GetSystemMetrics(SM_CXSCREEN);
1053     height = GetSystemMetrics(SM_CYSCREEN);
1054     ok(width == orig_width, "Screen width is %d\n", width);
1055     ok(height == orig_height, "Screen height is %d\n", height);
1056
1057     ZeroMemory(&vp, sizeof(vp));
1058     hr = IDirect3DDevice9_GetViewport(device1, &vp);
1059     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1060     if(SUCCEEDED(hr))
1061     {
1062         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1063         ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1064         ok(vp.Width == 400, "D3DVIEWPORT->Width = %d\n", vp.Width);
1065         ok(vp.Height == 300, "D3DVIEWPORT->Height = %d\n", vp.Height);
1066         ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1067         ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1068     }
1069
1070     hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1071     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1072     if(SUCCEEDED(hr))
1073     {
1074         ZeroMemory(&d3dpp, sizeof(d3dpp));
1075         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1076         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1077         if(SUCCEEDED(hr))
1078         {
1079             ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1080             ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1081         }
1082         IDirect3DSwapChain9_Release(pSwapchain);
1083     }
1084
1085     winrect.left = 0;
1086     winrect.top = 0;
1087     winrect.right = 200;
1088     winrect.bottom = 150;
1089     ok(AdjustWindowRect(&winrect, WS_OVERLAPPEDWINDOW, FALSE), "AdjustWindowRect failed\n");
1090     ok(SetWindowPos(hwnd, NULL, 0, 0,
1091                     winrect.right-winrect.left,
1092                     winrect.bottom-winrect.top,
1093                     SWP_NOMOVE|SWP_NOZORDER),
1094        "SetWindowPos failed\n");
1095
1096     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1097     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1098     d3dpp.Windowed         = TRUE;
1099     d3dpp.BackBufferWidth  = 0;
1100     d3dpp.BackBufferHeight = 0;
1101     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1102     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1103     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1104     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1105
1106     ZeroMemory(&vp, sizeof(vp));
1107     hr = IDirect3DDevice9_GetViewport(device1, &vp);
1108     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1109     if(SUCCEEDED(hr))
1110     {
1111         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
1112         ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
1113         ok(vp.Width == 200, "D3DVIEWPORT->Width = %d\n", vp.Width);
1114         ok(vp.Height == 150, "D3DVIEWPORT->Height = %d\n", vp.Height);
1115         ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
1116         ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
1117     }
1118
1119     hr = IDirect3DDevice9_GetSwapChain(device1, 0, &pSwapchain);
1120     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
1121     if(SUCCEEDED(hr))
1122     {
1123         ZeroMemory(&d3dpp, sizeof(d3dpp));
1124         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
1125         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
1126         if(SUCCEEDED(hr))
1127         {
1128             ok(d3dpp.BackBufferWidth == 200, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
1129             ok(d3dpp.BackBufferHeight == 150, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
1130         }
1131         IDirect3DSwapChain9_Release(pSwapchain);
1132     }
1133
1134     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1135     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1136     d3dpp.Windowed         = TRUE;
1137     d3dpp.BackBufferWidth  = 400;
1138     d3dpp.BackBufferHeight = 300;
1139
1140     /* _Reset fails if there is a resource in the default pool */
1141     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
1142     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1143     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1144     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1145     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1146     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1147     IDirect3DSurface9_Release(surface);
1148     /* Reset again to get the device out of the lost state */
1149     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1150     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1151     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1152     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1153
1154     if (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP)
1155     {
1156         IDirect3DVolumeTexture9 *volume_texture;
1157
1158         hr = IDirect3DDevice9_CreateVolumeTexture(device1, 16, 16, 4, 1, 0,
1159                 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &volume_texture, NULL);
1160         ok(SUCCEEDED(hr), "CreateVolumeTexture failed, hr %#x.\n", hr);
1161         hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1162         ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
1163         hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1164         ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n",
1165                 hr, D3DERR_DEVICENOTRESET);
1166         IDirect3DVolumeTexture9_Release(volume_texture);
1167         hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1168         ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
1169         hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1170         ok(SUCCEEDED(hr), "TestCooperativeLevel failed, hr %#x.\n", hr);
1171     }
1172     else
1173     {
1174         skip("Volume textures not supported.\n");
1175     }
1176
1177     /* Scratch, sysmem and managed pools are fine */
1178     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1179     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1180     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1181     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1182     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1183     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1184     IDirect3DSurface9_Release(surface);
1185
1186     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1187             D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1188     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1189     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1190     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1191     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1192     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1193     IDirect3DSurface9_Release(surface);
1194
1195     /* The depth stencil should get reset to the auto depth stencil when present. */
1196     hr = IDirect3DDevice9_SetDepthStencilSurface(device1, NULL);
1197     ok(hr == D3D_OK, "SetDepthStencilSurface failed with 0x%08x\n", hr);
1198
1199     hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1200     ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1201     ok(surface == NULL, "Depth stencil should be NULL\n");
1202
1203     d3dpp.EnableAutoDepthStencil = TRUE;
1204     d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1205     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1206     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1207
1208     hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1209     ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1210     ok(surface != NULL, "Depth stencil should not be NULL\n");
1211     if (surface) IDirect3DSurface9_Release(surface);
1212
1213     d3dpp.EnableAutoDepthStencil = FALSE;
1214     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1215     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1216
1217     hr = IDirect3DDevice9_GetDepthStencilSurface(device1, &surface);
1218     ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr);
1219     ok(surface == NULL, "Depth stencil should be NULL\n");
1220
1221     /* Will a sysmem or scratch survive while locked */
1222     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16,
1223             D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
1224     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1225     hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1226     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1227     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1228     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1229     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1230     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1231     IDirect3DSurface9_UnlockRect(surface);
1232     IDirect3DSurface9_Release(surface);
1233
1234     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device1, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
1235     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
1236     hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
1237     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
1238     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1239     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1240     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1241     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1242     IDirect3DSurface9_UnlockRect(surface);
1243     IDirect3DSurface9_Release(surface);
1244
1245     hr = IDirect3DDevice9_CreateTexture(device1, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
1246     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
1247     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1248     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1249     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1250     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1251     IDirect3DTexture9_Release(texture);
1252
1253     /* A reference held to an implicit surface causes failures as well */
1254     hr = IDirect3DDevice9_GetBackBuffer(device1, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1255     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr);
1256     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1257     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1258     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1259     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1260     IDirect3DSurface9_Release(surface);
1261     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1262     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1263     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1264     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
1265
1266     /* Shaders are fine as well */
1267     hr = IDirect3DDevice9_CreateVertexShader(device1, simple_vs, &shader);
1268     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
1269     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1270     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
1271     IDirect3DVertexShader9_Release(shader);
1272
1273     /* Try setting invalid modes */
1274     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1275     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1276     d3dpp.Windowed         = FALSE;
1277     d3dpp.BackBufferWidth  = 32;
1278     d3dpp.BackBufferHeight = 32;
1279     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1280     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr);
1281     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1282     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1283
1284     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1285     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1286     d3dpp.Windowed         = FALSE;
1287     d3dpp.BackBufferWidth  = 801;
1288     d3dpp.BackBufferHeight = 600;
1289     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1290     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr);
1291     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1292     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1293
1294     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1295     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1296     d3dpp.Windowed         = FALSE;
1297     d3dpp.BackBufferWidth  = 0;
1298     d3dpp.BackBufferHeight = 0;
1299     hr = IDirect3DDevice9_Reset(device1, &d3dpp);
1300     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=0, h=0, windowed=FALSE failed with %08x\n", hr);
1301     hr = IDirect3DDevice9_TestCooperativeLevel(device1);
1302     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
1303
1304     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1305
1306     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1307     d3dpp.Windowed         = TRUE;
1308     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1309     d3dpp.BackBufferFormat = d3ddm.Format;
1310     d3dpp.EnableAutoDepthStencil = FALSE;
1311     d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1312
1313     hr = IDirect3D9_CreateDevice(pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1314             hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device2);
1315     if (FAILED(hr))
1316     {
1317         skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
1318         goto cleanup;
1319     }
1320
1321     hr = IDirect3DDevice9_TestCooperativeLevel(device2);
1322     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
1323
1324     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1325     d3dpp.Windowed         = TRUE;
1326     d3dpp.BackBufferWidth  = 400;
1327     d3dpp.BackBufferHeight = 300;
1328     d3dpp.EnableAutoDepthStencil = TRUE;
1329     d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
1330
1331     hr = IDirect3DDevice9_Reset(device2, &d3dpp);
1332     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr);
1333
1334     if (FAILED(hr)) goto cleanup;
1335
1336     hr = IDirect3DDevice9_GetDepthStencilSurface(device2, &surface);
1337     ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr);
1338     ok(surface != NULL, "Depth stencil should not be NULL\n");
1339     if (surface) IDirect3DSurface9_Release(surface);
1340
1341 cleanup:
1342     HeapFree(GetProcessHeap(), 0, modes);
1343     if (device2)
1344     {
1345         UINT refcount = IDirect3DDevice9_Release(device2);
1346         ok(!refcount, "Device has %u references left.\n", refcount);
1347     }
1348     if (device1)
1349     {
1350         UINT refcount = IDirect3DDevice9_Release(device1);
1351         ok(!refcount, "Device has %u references left.\n", refcount);
1352     }
1353     if (pD3d) IDirect3D9_Release(pD3d);
1354     if (hwnd) DestroyWindow(hwnd);
1355 }
1356
1357 /* Test adapter display modes */
1358 static void test_display_modes(void)
1359 {
1360     D3DDISPLAYMODE dmode;
1361     IDirect3D9 *pD3d;
1362
1363     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1364     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1365     if(!pD3d) return;
1366
1367 #define TEST_FMT(x,r) do { \
1368     HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
1369     ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
1370 } while(0)
1371
1372     TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
1373     TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
1374     TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1375     /* D3DFMT_R5G6B5 */
1376     TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
1377     TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
1378     TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
1379     TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
1380     TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
1381     TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
1382     TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
1383     TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
1384     TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
1385     TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1386     TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
1387     TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
1388
1389     TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
1390     TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
1391
1392     TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
1393     TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
1394     TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
1395
1396     TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
1397     TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
1398     TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
1399     TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
1400     TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
1401     TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
1402
1403     TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
1404     TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
1405     TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
1406     TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
1407     TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
1408     TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
1409     TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
1410     TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
1411     TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
1412     TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
1413
1414     TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
1415     TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
1416     TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
1417     TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
1418     TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
1419     TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
1420     TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
1421     TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
1422     TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
1423     TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
1424
1425     TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
1426     TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
1427     TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
1428     TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
1429     /* Floating point formats */
1430     TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
1431     TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
1432     TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
1433
1434     /* IEEE formats */
1435     TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
1436     TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
1437     TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
1438
1439     TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
1440
1441     TEST_FMT(0, D3DERR_INVALIDCALL);
1442
1443     IDirect3D9_Release(pD3d);
1444 }
1445
1446 static void test_scene(void)
1447 {
1448     HRESULT                      hr;
1449     HWND                         hwnd               = NULL;
1450     IDirect3D9                  *pD3d               = NULL;
1451     IDirect3DDevice9            *pDevice            = NULL;
1452     D3DPRESENT_PARAMETERS        d3dpp;
1453     D3DDISPLAYMODE               d3ddm;
1454     IDirect3DSurface9            *pSurface1 = NULL, *pSurface2 = NULL, *pSurface3 = NULL, *pRenderTarget = NULL;
1455     IDirect3DSurface9            *pBackBuffer = NULL, *pDepthStencil = NULL;
1456     RECT rect = {0, 0, 128, 128};
1457     D3DCAPS9                     caps;
1458
1459     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1460     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1461     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1462     ok(hwnd != NULL, "Failed to create window\n");
1463     if (!pD3d || !hwnd) goto cleanup;
1464
1465     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1466     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1467     d3dpp.Windowed         = TRUE;
1468     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1469     d3dpp.BackBufferWidth  = 800;
1470     d3dpp.BackBufferHeight = 600;
1471     d3dpp.BackBufferFormat = d3ddm.Format;
1472     d3dpp.EnableAutoDepthStencil = TRUE;
1473     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1474
1475     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1476                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1477     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1478     if(!pDevice)
1479     {
1480         skip("Failed to create a d3d device\n");
1481         goto cleanup;
1482     }
1483
1484     /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
1485     memset(&caps, 0, sizeof(caps));
1486     hr = IDirect3DDevice9_GetDeviceCaps(pDevice, &caps);
1487     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
1488     if(FAILED(hr)) goto cleanup;
1489
1490     /* Test an EndScene without BeginScene. Should return an error */
1491     hr = IDirect3DDevice9_EndScene(pDevice);
1492     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1493
1494     /* Test a normal BeginScene / EndScene pair, this should work */
1495     hr = IDirect3DDevice9_BeginScene(pDevice);
1496     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1497     if(SUCCEEDED(hr))
1498     {
1499         hr = IDirect3DDevice9_EndScene(pDevice);
1500         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1501     }
1502
1503     /* Test another EndScene without having begun a new scene. Should return an error */
1504     hr = IDirect3DDevice9_EndScene(pDevice);
1505     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1506
1507     /* Two nested BeginScene and EndScene calls */
1508     hr = IDirect3DDevice9_BeginScene(pDevice);
1509     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1510     hr = IDirect3DDevice9_BeginScene(pDevice);
1511     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
1512     hr = IDirect3DDevice9_EndScene(pDevice);
1513     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1514     hr = IDirect3DDevice9_EndScene(pDevice);
1515     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1516
1517     /* Create some surfaces to test stretchrect between the scenes */
1518     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface1, NULL);
1519     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1520     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface2, NULL);
1521     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1522     hr = IDirect3DDevice9_CreateDepthStencilSurface(pDevice, 800, 600, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface3, NULL);
1523     ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
1524     hr = IDirect3DDevice9_CreateRenderTarget(pDevice, 128, 128, d3ddm.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pRenderTarget, NULL);
1525     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
1526
1527     hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
1528     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1529     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1530     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1531
1532     /* First make sure a simple StretchRect call works */
1533     if(pSurface1 && pSurface2) {
1534         hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1535         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1536     }
1537     if(pBackBuffer && pRenderTarget) {
1538         hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1539         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1540     }
1541     if(pDepthStencil && pSurface3) {
1542         HRESULT expected;
1543         if(0) /* Disabled for now because it crashes in wine */ {
1544             expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
1545             hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1546             ok( hr == expected, "IDirect3DDevice9_StretchRect returned %08x, expected %08x\n", hr, expected);
1547         }
1548     }
1549
1550     /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1551      * with normal surfaces and render targets, but not depth stencil surfaces.
1552      */
1553     hr = IDirect3DDevice9_BeginScene(pDevice);
1554     ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1555
1556     if(pSurface1 && pSurface2)
1557     {
1558         hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1559         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1560     }
1561     if(pBackBuffer && pRenderTarget)
1562     {
1563         hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1564         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1565     }
1566     if(pDepthStencil && pSurface3)
1567     {
1568         /* This is supposed to fail inside a BeginScene - EndScene pair. */
1569         hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1570         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
1571     }
1572
1573     hr = IDirect3DDevice9_EndScene(pDevice);
1574     ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1575
1576     /* Does a SetRenderTarget influence BeginScene / EndScene ?
1577      * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1578      * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1579      */
1580     hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pRenderTarget);
1581     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1582     hr = IDirect3DDevice9_BeginScene(pDevice);
1583     ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1584     hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pBackBuffer);
1585     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1586     hr = IDirect3DDevice9_EndScene(pDevice);
1587     ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1588
1589 cleanup:
1590     if(pRenderTarget) IDirect3DSurface9_Release(pRenderTarget);
1591     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1592     if(pBackBuffer) IDirect3DSurface9_Release(pBackBuffer);
1593     if(pSurface1) IDirect3DSurface9_Release(pSurface1);
1594     if(pSurface2) IDirect3DSurface9_Release(pSurface2);
1595     if(pSurface3) IDirect3DSurface9_Release(pSurface3);
1596     if (pDevice)
1597     {
1598         UINT refcount = IDirect3DDevice9_Release(pDevice);
1599         ok(!refcount, "Device has %u references left.\n", refcount);
1600     }
1601     if (pD3d) IDirect3D9_Release(pD3d);
1602     if(hwnd) DestroyWindow(hwnd);
1603 }
1604
1605 static void test_limits(void)
1606 {
1607     HRESULT                      hr;
1608     HWND                         hwnd               = NULL;
1609     IDirect3D9                  *pD3d               = NULL;
1610     IDirect3DDevice9            *pDevice            = NULL;
1611     D3DPRESENT_PARAMETERS        d3dpp;
1612     D3DDISPLAYMODE               d3ddm;
1613     IDirect3DTexture9           *pTexture           = NULL;
1614     int i;
1615
1616     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1617     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1618     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1619     ok(hwnd != NULL, "Failed to create window\n");
1620     if (!pD3d || !hwnd) goto cleanup;
1621
1622     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1623     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1624     d3dpp.Windowed         = TRUE;
1625     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1626     d3dpp.BackBufferWidth  = 800;
1627     d3dpp.BackBufferHeight = 600;
1628     d3dpp.BackBufferFormat = d3ddm.Format;
1629     d3dpp.EnableAutoDepthStencil = TRUE;
1630     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1631
1632     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1633                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1634     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1635     if(!pDevice)
1636     {
1637         skip("Failed to create a d3d device\n");
1638         goto cleanup;
1639     }
1640
1641     hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
1642     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
1643     if(!pTexture) goto cleanup;
1644
1645     /* There are 16 pixel samplers. We should be able to access all of them */
1646     for(i = 0; i < 16; i++) {
1647         hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
1648         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1649         hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
1650         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1651         hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
1652         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
1653     }
1654
1655     /* Now test all 8 textures stage states */
1656     for(i = 0; i < 8; i++) {
1657         hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
1658         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
1659     }
1660
1661     /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1662      * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1663      * but how do I test that?
1664      */
1665 cleanup:
1666     if(pTexture) IDirect3DTexture9_Release(pTexture);
1667     if (pDevice)
1668     {
1669         UINT refcount = IDirect3D9_Release(pDevice);
1670         ok(!refcount, "Device has %u references left.\n", refcount);
1671     }
1672     if (pD3d) IDirect3D9_Release(pD3d);
1673     if(hwnd) DestroyWindow(hwnd);
1674 }
1675
1676 static void test_depthstenciltest(void)
1677 {
1678     HRESULT                      hr;
1679     HWND                         hwnd               = NULL;
1680     IDirect3D9                  *pD3d               = NULL;
1681     IDirect3DDevice9            *pDevice            = NULL;
1682     D3DPRESENT_PARAMETERS        d3dpp;
1683     D3DDISPLAYMODE               d3ddm;
1684     IDirect3DSurface9           *pDepthStencil           = NULL;
1685     IDirect3DSurface9           *pDepthStencil2          = NULL;
1686     DWORD                        state;
1687
1688     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1689     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1690     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1691     ok(hwnd != NULL, "Failed to create window\n");
1692     if (!pD3d || !hwnd) goto cleanup;
1693
1694     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1695     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1696     d3dpp.Windowed         = TRUE;
1697     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1698     d3dpp.BackBufferWidth  = 800;
1699     d3dpp.BackBufferHeight = 600;
1700     d3dpp.BackBufferFormat = d3ddm.Format;
1701     d3dpp.EnableAutoDepthStencil = TRUE;
1702     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1703
1704     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1705                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1706     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1707     if(!pDevice)
1708     {
1709         skip("Failed to create a d3d device\n");
1710         goto cleanup;
1711     }
1712
1713     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1714     ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1715
1716     /* Try to clear */
1717     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1718     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1719
1720     hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
1721     ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1722
1723     /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
1724     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
1725     ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1726     if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
1727
1728     /* This left the render states untouched! */
1729     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1730     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1731     ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1732     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
1733     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1734     ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
1735     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
1736     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1737     ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
1738     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
1739     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1740     ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
1741
1742     /* This is supposed to fail now */
1743     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1744     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1745
1746     hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
1747     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1748
1749     hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
1750     ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1751
1752     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1753     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1754     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1755
1756     /* Now it works again */
1757     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1758     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1759
1760     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1761     if(pDevice) IDirect3D9_Release(pDevice);
1762
1763     /* Now see if autodepthstencil disable is honored. First, without a format set */
1764     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1765     d3dpp.Windowed         = TRUE;
1766     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1767     d3dpp.BackBufferWidth  = 800;
1768     d3dpp.BackBufferHeight = 600;
1769     d3dpp.BackBufferFormat = d3ddm.Format;
1770     d3dpp.EnableAutoDepthStencil = FALSE;
1771     d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1772
1773     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1774                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1775     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1776     if(!pDevice)
1777     {
1778         skip("Failed to create a d3d device\n");
1779         goto cleanup;
1780     }
1781
1782     pDepthStencil = NULL;
1783     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1784     ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1785     if(pDepthStencil) {
1786         IDirect3DSurface9_Release(pDepthStencil);
1787         pDepthStencil = NULL;
1788     }
1789
1790     /* Check the depth test state */
1791     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1792     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1793     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1794
1795     if(pDevice) IDirect3D9_Release(pDevice);
1796
1797     /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
1798     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1799     d3dpp.Windowed         = TRUE;
1800     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1801     d3dpp.BackBufferWidth  = 800;
1802     d3dpp.BackBufferHeight = 600;
1803     d3dpp.BackBufferFormat = d3ddm.Format;
1804     d3dpp.EnableAutoDepthStencil = FALSE;
1805     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1806
1807     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1808                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1809     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1810     if(!pDevice)
1811     {
1812         skip("Failed to create a d3d device\n");
1813         goto cleanup;
1814     }
1815
1816     pDepthStencil = NULL;
1817     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1818     ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1819     if(pDepthStencil) {
1820         IDirect3DSurface9_Release(pDepthStencil);
1821         pDepthStencil = NULL;
1822     }
1823
1824     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1825     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1826     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1827
1828 cleanup:
1829     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1830     if (pDevice)
1831     {
1832         UINT refcount = IDirect3D9_Release(pDevice);
1833         ok(!refcount, "Device has %u references left.\n", refcount);
1834     }
1835     if (pD3d) IDirect3D9_Release(pD3d);
1836     if(hwnd) DestroyWindow(hwnd);
1837 }
1838
1839 static void test_get_rt(void)
1840 {
1841     IDirect3DSurface9 *backbuffer, *rt;
1842     IDirect3DDevice9 *device;
1843     IDirect3D9 *d3d9;
1844     D3DCAPS9 caps;
1845     HWND window;
1846     HRESULT hr;
1847     ULONG ref;
1848     UINT i;
1849
1850     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
1851     {
1852         skip("Failed to create IDirect3D9 object, skipping tests.\n");
1853         return;
1854     }
1855
1856     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
1857             0, 0, 128, 128, 0, 0, 0, 0);
1858     device = create_device(d3d9, window, window, TRUE);
1859     if (!device)
1860     {
1861         skip("Failed to create a D3D device, skipping tests.\n");
1862         goto done;
1863     }
1864
1865     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
1866     ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1867     ok(!!backbuffer, "Got a NULL backbuffer.\n");
1868
1869     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1870     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1871
1872     for (i = 1; i < caps.NumSimultaneousRTs; ++i)
1873     {
1874         rt = backbuffer;
1875         hr = IDirect3DDevice9_GetRenderTarget(device, i, &rt);
1876         ok(hr == D3DERR_NOTFOUND, "IDirect3DDevice9_GetRenderTarget returned %#x.\n", hr);
1877         ok(!rt, "Got rt %p.\n", rt);
1878     }
1879
1880     IDirect3DSurface9_Release(backbuffer);
1881
1882     ref = IDirect3DDevice9_Release(device);
1883     ok(!ref, "The device was not properly freed: refcount %u.\n", ref);
1884 done:
1885     IDirect3D9_Release(d3d9);
1886     DestroyWindow(window);
1887 }
1888
1889 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
1890 static void test_draw_indexed(void)
1891 {
1892     static const struct {
1893         float position[3];
1894         DWORD color;
1895     } quad[] = {
1896         {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1897         {{-1.0f,  1.0f, 0.0f}, 0xffff0000},
1898         {{ 1.0f,  1.0f, 0.0f}, 0xffff0000},
1899         {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1900     };
1901     WORD indices[] = {0, 1, 2, 3, 0, 2};
1902
1903     static const D3DVERTEXELEMENT9 decl_elements[] = {
1904         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1905         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1906         D3DDECL_END()
1907     };
1908
1909     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1910     IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1911     IDirect3DIndexBuffer9 *index_buffer = NULL;
1912     D3DPRESENT_PARAMETERS present_parameters;
1913     IDirect3DDevice9 *device = NULL;
1914     IDirect3D9 *d3d9;
1915     HRESULT hr;
1916     HWND hwnd;
1917     void *ptr;
1918
1919     hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
1920             0, 0, 0, 10, 10, 0, 0, 0, 0);
1921     if (!hwnd)
1922     {
1923         skip("Failed to create window\n");
1924         return;
1925     }
1926
1927     d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
1928     if (!d3d9)
1929     {
1930         skip("Failed to create IDirect3D9 object\n");
1931         goto cleanup;
1932     }
1933
1934     ZeroMemory(&present_parameters, sizeof(present_parameters));
1935     present_parameters.Windowed = TRUE;
1936     present_parameters.hDeviceWindow = hwnd;
1937     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1938
1939     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1940             NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
1941     if (FAILED(hr) || !device)
1942     {
1943         skip("Failed to create device\n");
1944         goto cleanup;
1945     }
1946
1947     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1948     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1949     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1950     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1951
1952     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
1953     ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
1954     hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1955     ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1956     memcpy(ptr, quad, sizeof(quad));
1957     hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
1958     ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1959     hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
1960     ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
1961
1962     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
1963     ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
1964     hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1965     ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1966     memcpy(ptr, indices, sizeof(indices));
1967     hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
1968     ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1969     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1970     ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
1971     hr = IDirect3DDevice9_BeginScene(device);
1972     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1973
1974     /* NULL index buffer. Should fail */
1975     hr = IDirect3DDevice9_SetIndices(device, NULL);
1976     ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1977     hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1978             4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1979     ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1980             hr, D3DERR_INVALIDCALL);
1981
1982     /* Valid index buffer, NULL vertex declaration. Should fail */
1983     hr = IDirect3DDevice9_SetIndices(device, index_buffer);
1984     ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1985     hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1986             4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1987     ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1988             hr, D3DERR_INVALIDCALL);
1989
1990     /* Valid index buffer and vertex declaration. Should succeed */
1991     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1992     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1993     hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1994             4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1995     ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
1996
1997     hr = IDirect3DDevice9_EndScene(device);
1998     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1999
2000     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2001     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2002
2003     IDirect3DVertexBuffer9_Release(vertex_buffer);
2004     IDirect3DIndexBuffer9_Release(index_buffer);
2005     IDirect3DVertexDeclaration9_Release(vertex_declaration);
2006
2007 cleanup:
2008     if (device)
2009     {
2010         UINT refcount = IDirect3DDevice9_Release(device);
2011         ok(!refcount, "Device has %u references left.\n", refcount);
2012     }
2013     if (d3d9) IDirect3D9_Release(d3d9);
2014     if (hwnd) DestroyWindow(hwnd);
2015 }
2016
2017 static void test_null_stream(void)
2018 {
2019     IDirect3DVertexBuffer9 *buffer = NULL;
2020     D3DPRESENT_PARAMETERS present_parameters;
2021     IDirect3DDevice9 *device = NULL;
2022     IDirect3D9 *d3d9;
2023     HWND hwnd;
2024     HRESULT hr;
2025     IDirect3DVertexShader9 *shader = NULL;
2026     IDirect3DVertexDeclaration9 *decl = NULL;
2027     DWORD shader_code[] = {
2028         0xfffe0101,                             /* vs_1_1           */
2029         0x0000001f, 0x80000000, 0x900f0000,     /* dcl_position v0  */
2030         0x00000001, 0xc00f0000, 0x90e40000,     /* mov oPos, v0     */
2031         0x0000ffff                              /* end              */
2032     };
2033     static const D3DVERTEXELEMENT9 decl_elements[] = {
2034         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2035         {1, 0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
2036         D3DDECL_END()
2037     };
2038
2039     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2040     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2041     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2042     ok(hwnd != NULL, "Failed to create window\n");
2043     if (!d3d9 || !hwnd) goto cleanup;
2044
2045     ZeroMemory(&present_parameters, sizeof(present_parameters));
2046     present_parameters.Windowed = TRUE;
2047     present_parameters.hDeviceWindow = hwnd;
2048     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2049
2050     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
2051                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
2052     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
2053     if(!device)
2054     {
2055         skip("Failed to create a d3d device\n");
2056         goto cleanup;
2057     }
2058
2059     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2060     if(FAILED(hr)) {
2061         skip("No vertex shader support\n");
2062         goto cleanup;
2063     }
2064     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2065     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
2066     if (FAILED(hr)) {
2067         skip("Vertex declaration handling not possible.\n");
2068         goto cleanup;
2069     }
2070     hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
2071     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
2072     if (FAILED(hr)) {
2073         skip("Vertex buffer handling not possible.\n");
2074         goto cleanup;
2075     }
2076
2077     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
2078     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2079     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
2080     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
2081     hr = IDirect3DDevice9_SetVertexShader(device, shader);
2082     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
2083     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2084     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
2085
2086     hr = IDirect3DDevice9_BeginScene(device);
2087     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr);
2088     if(SUCCEEDED(hr)) {
2089         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
2090         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr);
2091
2092         hr = IDirect3DDevice9_EndScene(device);
2093         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr);
2094     }
2095
2096     IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2097     IDirect3DDevice9_SetVertexShader(device, NULL);
2098     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2099
2100 cleanup:
2101     if (buffer) IDirect3DVertexBuffer9_Release(buffer);
2102     if(decl) IDirect3DVertexDeclaration9_Release(decl);
2103     if(shader) IDirect3DVertexShader9_Release(shader);
2104     if (device)
2105     {
2106         UINT refcount = IDirect3DDevice9_Release(device);
2107         ok(!refcount, "Device has %u references left.\n", refcount);
2108     }
2109     if(d3d9) IDirect3D9_Release(d3d9);
2110 }
2111
2112 static void test_lights(void)
2113 {
2114     D3DPRESENT_PARAMETERS present_parameters;
2115     IDirect3DDevice9 *device = NULL;
2116     IDirect3D9 *d3d9;
2117     HWND hwnd;
2118     HRESULT hr;
2119     unsigned int i;
2120     BOOL enabled;
2121     D3DCAPS9 caps;
2122
2123     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2124     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2125     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2126     ok(hwnd != NULL, "Failed to create window\n");
2127     if (!d3d9 || !hwnd) goto cleanup;
2128
2129     ZeroMemory(&present_parameters, sizeof(present_parameters));
2130     present_parameters.Windowed = TRUE;
2131     present_parameters.hDeviceWindow = hwnd;
2132     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2133
2134     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2135                                   D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2136     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2137        "IDirect3D9_CreateDevice failed with %08x\n", hr);
2138     if(!device)
2139     {
2140         skip("Failed to create a d3d device\n");
2141         goto cleanup;
2142     }
2143
2144     memset(&caps, 0, sizeof(caps));
2145     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2146     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
2147
2148     for(i = 1; i <= caps.MaxActiveLights; i++) {
2149         hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
2150         ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
2151         hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
2152         ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
2153         ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
2154     }
2155
2156     /* TODO: Test the rendering results in this situation */
2157     hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
2158     ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
2159     hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
2160     ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
2161     ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
2162     hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
2163     ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
2164
2165     for(i = 1; i <= caps.MaxActiveLights; i++) {
2166         hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
2167         ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
2168     }
2169
2170 cleanup:
2171     if (device)
2172     {
2173         UINT refcount = IDirect3DDevice9_Release(device);
2174         ok(!refcount, "Device has %u references left.\n", refcount);
2175     }
2176     if(d3d9) IDirect3D9_Release(d3d9);
2177 }
2178
2179 static void test_set_stream_source(void)
2180 {
2181     D3DPRESENT_PARAMETERS present_parameters;
2182     IDirect3DDevice9 *device = NULL;
2183     IDirect3D9 *d3d9;
2184     HWND hwnd;
2185     HRESULT hr;
2186     IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
2187
2188     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2189     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2190     hwnd = CreateWindow( "d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2191     ok(hwnd != NULL, "Failed to create window\n");
2192     if (!d3d9 || !hwnd) goto cleanup;
2193
2194     ZeroMemory(&present_parameters, sizeof(present_parameters));
2195     present_parameters.Windowed = TRUE;
2196     present_parameters.hDeviceWindow = hwnd;
2197     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2198
2199     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
2200                                   D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2201     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2202        "IDirect3D9_CreateDevice failed with %08x\n", hr);
2203     if(!device)
2204     {
2205         hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd,
2206                                       D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
2207         ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
2208            "IDirect3D9_CreateDevice failed with %08x\n", hr);
2209         if(!device)
2210         {
2211             skip("Failed to create a d3d device\n");
2212             goto cleanup;
2213         }
2214     }
2215
2216     hr = IDirect3DDevice9_CreateVertexBuffer( device, 512, 0, 0, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
2217     ok(hr == D3D_OK, "Failed to create a vertex buffer, hr = %08x\n", hr);
2218     if (SUCCEEDED(hr)) {
2219         /* Some cards(Geforce 7400 at least) accept non-aligned offsets, others(radeon 9000 verified) reject it,
2220          * so accept both results. Wine currently rejects this to be able to optimize the vbo conversion, but writes
2221          * a WARN
2222          */
2223         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 32);
2224         ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2225         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 1, 32);
2226         ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2227         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 2, 32);
2228         ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2229         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 3, 32);
2230         ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2231         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 4, 32);
2232         ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2233     }
2234     /* Try to set the NULL buffer with an offset and stride 0 */
2235     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2236     ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
2237     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
2238     ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
2239     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
2240     ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
2241     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
2242     ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
2243     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
2244     ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2245
2246     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2247     ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
2248
2249 cleanup:
2250     if (pVertexBuffer) IDirect3DVertexBuffer9_Release(pVertexBuffer);
2251     if (device)
2252     {
2253         UINT refcount = IDirect3DDevice9_Release(device);
2254         ok(!refcount, "Device has %u references left.\n", refcount);
2255     }
2256     if(d3d9) IDirect3D9_Release(d3d9);
2257 }
2258
2259 struct formats {
2260     D3DFORMAT DisplayFormat;
2261     D3DFORMAT BackBufferFormat;
2262     BOOL shouldPass;
2263 };
2264
2265 static const struct formats r5g6b5_format_list[] =
2266 {
2267     { D3DFMT_R5G6B5, D3DFMT_R5G6B5, TRUE },
2268     { D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, FALSE },
2269     { D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, FALSE },
2270     { D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, FALSE },
2271     { D3DFMT_R5G6B5, D3DFMT_A8R8G8B8, FALSE },
2272     { 0, 0, 0}
2273 };
2274
2275 static const struct formats x1r5g5b5_format_list[] =
2276 {
2277     { D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, FALSE },
2278     { D3DFMT_X1R5G5B5, D3DFMT_X1R5G5B5, TRUE },
2279     { D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE },
2280     { D3DFMT_X1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2281     { D3DFMT_X1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2282
2283     /* A1R5G5B5 should not be usable as a display format, it is backbuffer-only */
2284     { D3DFMT_A1R5G5B5, D3DFMT_R5G6B5, FALSE },
2285     { D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5, FALSE },
2286     { D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE },
2287     { D3DFMT_A1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
2288     { D3DFMT_A1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
2289     { 0, 0, 0}
2290 };
2291
2292 static const struct formats x8r8g8b8_format_list[] =
2293 {
2294     { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, FALSE },
2295     { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2296     { D3DFMT_X8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2297     { D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, TRUE },
2298     { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE },
2299
2300     /* A1R8G8B8 should not be usable as a display format, it is backbuffer-only */
2301     { D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, FALSE },
2302     { D3DFMT_A8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
2303     { D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
2304     { D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE },
2305     { D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE },
2306     { 0, 0, 0}
2307 };
2308
2309 static void test_display_formats(void)
2310 {
2311     /* Direct3D9 offers 4 display formats R5G6B5, X1R5G5B5, X8R8G8B8 and A2R10G10B10.
2312      * Next to these there are 6 different backbuffer formats. Only a fixed number of
2313      * combinations are possible in FULLSCREEN mode. In windowed mode more combinations are
2314      * allowed due to depth conversion and this is likely driver dependent.
2315      * This test checks which combinations are possible in fullscreen mode and this should not be driver dependent.
2316      * TODO: handle A2R10G10B10 but what hardware supports it? Parhelia? It is very rare. */
2317
2318     UINT Adapter = D3DADAPTER_DEFAULT;
2319     D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
2320     int i, nmodes;
2321     HRESULT hr;
2322
2323     IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
2324     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
2325     if(!d3d9) return;
2326
2327     nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_R5G6B5);
2328     if(!nmodes) {
2329         skip("Display format R5G6B5 not supported, skipping\n");
2330     } else {
2331         trace("Testing display format R5G6B5\n");
2332         for(i=0; r5g6b5_format_list[i].DisplayFormat != 0; i++)
2333         {
2334             hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, FALSE);
2335
2336             if(r5g6b5_format_list[i].shouldPass)
2337                 ok(hr == D3D_OK ||
2338                    broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver */,
2339                    "format %d %d didn't pass with hr=%#08x\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, hr);
2340             else
2341                 ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat);
2342         }
2343     }
2344
2345     nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X1R5G5B5);
2346     if(!nmodes) {
2347         skip("Display format X1R5G5B5 not supported, skipping\n");
2348     } else {
2349         trace("Testing display format X1R5G5B5\n");
2350         for(i=0; x1r5g5b5_format_list[i].DisplayFormat != 0; i++)
2351         {
2352             hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, FALSE);
2353
2354             if(x1r5g5b5_format_list[i].shouldPass)
2355                 ok(hr == D3D_OK ||
2356                    broken(hr == D3DERR_NOTAVAILABLE) /* Spice QXL driver */,
2357                    "format %d %d didn't pass with hr=%#08x\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, hr);
2358             else
2359                 ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat);
2360         }
2361     }
2362
2363     nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
2364     if(!nmodes) {
2365         skip("Display format X8R8G8B8 not supported, skipping\n");
2366     } else {
2367         trace("Testing display format X8R8G8B8\n");
2368         for(i=0; x8r8g8b8_format_list[i].DisplayFormat != 0; i++)
2369         {
2370             hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, FALSE);
2371             trace("CheckDeviceType(%d %d) = %08x shouldPass = %d\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr, x8r8g8b8_format_list[i].shouldPass);
2372
2373             if(x8r8g8b8_format_list[i].shouldPass)
2374                 ok(hr == D3D_OK ||
2375                    broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver */,
2376                    "format %d %d didn't pass with hr=%#08x\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr);
2377             else
2378                 ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat);
2379         }
2380     }
2381
2382     if(d3d9) IDirect3D9_Release(d3d9);
2383 }
2384
2385 static void test_scissor_size(void)
2386 {
2387     IDirect3D9 *d3d9_ptr = 0;
2388     unsigned int i;
2389     static struct {
2390         int winx; int winy; int backx; int backy; BOOL window;
2391     } scts[] = { /* scissor tests */
2392         {800, 600, 640, 480, TRUE},
2393         {800, 600, 640, 480, FALSE},
2394         {640, 480, 800, 600, TRUE},
2395         {640, 480, 800, 600, FALSE},
2396     };
2397
2398     d3d9_ptr = pDirect3DCreate9(D3D_SDK_VERSION);
2399     ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
2400     if (!d3d9_ptr){
2401         skip("Failed to create IDirect3D9 object\n");
2402         return;
2403     }
2404
2405     for(i=0; i<sizeof(scts)/sizeof(scts[0]); i++) {
2406         IDirect3DDevice9 *device_ptr = 0;
2407         D3DPRESENT_PARAMETERS present_parameters;
2408         HRESULT hr;
2409         HWND hwnd = 0;
2410         RECT scissorrect;
2411
2412         hwnd = CreateWindow("d3d9_test_wc", "d3d9_test",
2413                         WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, scts[i].winx, scts[i].winy, 0, 0, 0, 0);
2414
2415         if (!scts[i].window)
2416         {
2417             scts[i].backx = screen_width;
2418             scts[i].backy = screen_height;
2419         }
2420
2421         ZeroMemory(&present_parameters, sizeof(present_parameters));
2422         present_parameters.Windowed = scts[i].window;
2423         present_parameters.hDeviceWindow = hwnd;
2424         present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2425         present_parameters.BackBufferWidth = scts[i].backx;
2426         present_parameters.BackBufferHeight = scts[i].backy;
2427         present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
2428         present_parameters.EnableAutoDepthStencil = TRUE;
2429         present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
2430
2431         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2432         if(FAILED(hr)) {
2433             present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
2434             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2435             if(FAILED(hr)) {
2436                 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
2437             }
2438         }
2439         ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
2440
2441         if (!device_ptr)
2442         {
2443             DestroyWindow(hwnd);
2444             skip("Creating the device failed\n");
2445             goto err_out;
2446         }
2447
2448         /* Check for the default scissor rect size */
2449         hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2450         ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2451         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);
2452
2453         /* check the scissorrect values after a reset */
2454         present_parameters.BackBufferWidth = screen_width;
2455         present_parameters.BackBufferHeight = screen_height;
2456         hr = IDirect3DDevice9_Reset(device_ptr, &present_parameters);
2457         ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
2458         hr = IDirect3DDevice9_TestCooperativeLevel(device_ptr);
2459         ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
2460
2461         hr = IDirect3DDevice9_GetScissorRect(device_ptr, &scissorrect);
2462         ok(hr == D3D_OK, "IDirect3DDevice9_GetScissorRect failed with: %08x\n", hr);
2463         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);
2464
2465         if(device_ptr) {
2466             ULONG ref;
2467
2468             ref = IDirect3DDevice9_Release(device_ptr);
2469             DestroyWindow(hwnd);
2470             ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
2471         }
2472     }
2473
2474 err_out:
2475     if(d3d9_ptr) IDirect3D9_Release(d3d9_ptr);
2476     return;
2477 }
2478
2479 static void test_multi_device(void)
2480 {
2481     IDirect3DDevice9 *device1 = NULL, *device2 = NULL;
2482     D3DPRESENT_PARAMETERS present_parameters;
2483     HWND hwnd1 = NULL, hwnd2 = NULL;
2484     IDirect3D9 *d3d9;
2485     ULONG refcount;
2486     HRESULT hr;
2487
2488     d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2489     ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2490     if (!d3d9) goto fail;
2491
2492     hwnd1 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2493     ok(hwnd1 != NULL, "Failed to create a window.\n");
2494     if (!hwnd1) goto fail;
2495
2496     memset(&present_parameters, 0, sizeof(present_parameters));
2497     present_parameters.Windowed = TRUE;
2498     present_parameters.hDeviceWindow = hwnd1;
2499     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2500
2501     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd1,
2502             D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device1);
2503     IDirect3D9_Release(d3d9);
2504     d3d9 = NULL;
2505     if (FAILED(hr)) {
2506         skip("Failed to create a device\n");
2507         goto fail;
2508     }
2509
2510     d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
2511     ok(d3d9 != NULL, "Failed to create a d3d9 object.\n");
2512     if (!d3d9) goto fail;
2513
2514     hwnd2 = CreateWindow("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2515     ok(hwnd2 != NULL, "Failed to create a window.\n");
2516     if (!hwnd2) goto fail;
2517
2518     memset(&present_parameters, 0, sizeof(present_parameters));
2519     present_parameters.Windowed = TRUE;
2520     present_parameters.hDeviceWindow = hwnd2;
2521     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
2522
2523     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd2,
2524             D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device2);
2525     ok(SUCCEEDED(hr), "Failed to create a device, hr %#x\n", hr);
2526     IDirect3D9_Release(d3d9);
2527     d3d9 = NULL;
2528     if (FAILED(hr)) goto fail;
2529
2530 fail:
2531     if (d3d9) IDirect3D9_Release(d3d9);
2532     if (device1)
2533     {
2534         refcount = IDirect3DDevice9_Release(device1);
2535         ok(!refcount, "Device has %u references left.\n", refcount);
2536     }
2537     if (device2)
2538     {
2539         refcount = IDirect3DDevice9_Release(device2);
2540         ok(!refcount, "Device has %u references left.\n", refcount);
2541     }
2542     if (hwnd1) DestroyWindow(hwnd1);
2543     if (hwnd2) DestroyWindow(hwnd2);
2544 }
2545
2546 static HWND filter_messages;
2547
2548 enum message_window
2549 {
2550     DEVICE_WINDOW,
2551     FOCUS_WINDOW,
2552 };
2553
2554 struct message
2555 {
2556     UINT message;
2557     enum message_window window;
2558 };
2559
2560 static const struct message *expect_messages;
2561 static HWND device_window, focus_window;
2562
2563 struct wndproc_thread_param
2564 {
2565     HWND dummy_window;
2566     HANDLE window_created;
2567     HANDLE test_finished;
2568     BOOL running_in_foreground;
2569 };
2570
2571 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2572 {
2573     if (filter_messages && filter_messages == hwnd)
2574     {
2575         if (message != WM_DISPLAYCHANGE && message != WM_IME_NOTIFY)
2576             todo_wine ok( 0, "Received unexpected message %#x for window %p.\n", message, hwnd);
2577     }
2578
2579     if (expect_messages)
2580     {
2581         HWND w;
2582
2583         switch (expect_messages->window)
2584         {
2585             case DEVICE_WINDOW:
2586                 w = device_window;
2587                 break;
2588
2589             case FOCUS_WINDOW:
2590                 w = focus_window;
2591                 break;
2592
2593             default:
2594                 w = NULL;
2595                 break;
2596         };
2597
2598         if (hwnd == w && expect_messages->message == message) ++expect_messages;
2599     }
2600
2601     return DefWindowProcA(hwnd, message, wparam, lparam);
2602 }
2603
2604 static DWORD WINAPI wndproc_thread(void *param)
2605 {
2606     struct wndproc_thread_param *p = param;
2607     DWORD res;
2608     BOOL ret;
2609
2610     p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2611             WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2612     p->running_in_foreground = SetForegroundWindow(p->dummy_window);
2613
2614     ret = SetEvent(p->window_created);
2615     ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
2616
2617     for (;;)
2618     {
2619         MSG msg;
2620
2621         while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
2622         res = WaitForSingleObject(p->test_finished, 100);
2623         if (res == WAIT_OBJECT_0) break;
2624         if (res != WAIT_TIMEOUT)
2625         {
2626             ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2627             break;
2628         }
2629     }
2630
2631     DestroyWindow(p->dummy_window);
2632
2633     return 0;
2634 }
2635
2636 static void test_wndproc(void)
2637 {
2638     struct wndproc_thread_param thread_params;
2639     IDirect3DDevice9 *device;
2640     WNDCLASSA wc = {0};
2641     IDirect3D9 *d3d9;
2642     HANDLE thread;
2643     LONG_PTR proc;
2644     ULONG ref;
2645     DWORD res, tid;
2646     HWND tmp;
2647
2648     static const struct message messages[] =
2649     {
2650         {WM_WINDOWPOSCHANGING,  FOCUS_WINDOW},
2651         {WM_ACTIVATE,           FOCUS_WINDOW},
2652         {WM_SETFOCUS,           FOCUS_WINDOW},
2653         {0,                     0},
2654     };
2655
2656     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2657     {
2658         skip("Failed to create IDirect3D9 object, skipping tests.\n");
2659         return;
2660     }
2661
2662     wc.lpfnWndProc = test_proc;
2663     wc.lpszClassName = "d3d9_test_wndproc_wc";
2664     ok(RegisterClassA(&wc), "Failed to register window class.\n");
2665
2666     thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2667     ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2668     thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2669     ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2670
2671     focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2672             WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2673     device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2674             WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2675     thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2676     ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2677
2678     res = WaitForSingleObject(thread_params.window_created, INFINITE);
2679     ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2680
2681     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2682     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2683             (LONG_PTR)test_proc, proc);
2684     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2685     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2686             (LONG_PTR)test_proc, proc);
2687
2688     trace("device_window %p, focus_window %p, dummy_window %p.\n",
2689             device_window, focus_window, thread_params.dummy_window);
2690
2691     tmp = GetFocus();
2692     ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2693     if (thread_params.running_in_foreground)
2694     {
2695         tmp = GetForegroundWindow();
2696         ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2697                 thread_params.dummy_window, tmp);
2698     }
2699     else
2700         skip("Not running in foreground, skip foreground window test\n");
2701
2702     flush_events();
2703
2704     expect_messages = messages;
2705
2706     device = create_device(d3d9, device_window, focus_window, FALSE);
2707     if (!device)
2708     {
2709         skip("Failed to create a D3D device, skipping tests.\n");
2710         goto done;
2711     }
2712
2713     ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
2714             expect_messages->message, expect_messages->window);
2715     expect_messages = NULL;
2716
2717     if (0) /* Disabled until we can make this work in a reliable way on Wine. */
2718     {
2719         tmp = GetFocus();
2720         ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
2721         tmp = GetForegroundWindow();
2722         ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
2723     }
2724     SetForegroundWindow(focus_window);
2725     flush_events();
2726
2727     filter_messages = focus_window;
2728
2729     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2730     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2731             (LONG_PTR)test_proc, proc);
2732
2733     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2734     ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2735             (LONG_PTR)test_proc, proc);
2736
2737     ref = IDirect3DDevice9_Release(device);
2738     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2739
2740     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2741     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2742             (LONG_PTR)test_proc, proc);
2743
2744     device = create_device(d3d9, focus_window, focus_window, FALSE);
2745     if (!device)
2746     {
2747         skip("Failed to create a D3D device, skipping tests.\n");
2748         goto done;
2749     }
2750
2751     ref = IDirect3DDevice9_Release(device);
2752     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2753
2754     device = create_device(d3d9, device_window, focus_window, FALSE);
2755     if (!device)
2756     {
2757         skip("Failed to create a D3D device, skipping tests.\n");
2758         goto done;
2759     }
2760
2761     proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2762     ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2763             (LONG_PTR)test_proc, proc);
2764
2765     ref = IDirect3DDevice9_Release(device);
2766     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2767
2768     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2769     ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2770             (LONG_PTR)DefWindowProcA, proc);
2771
2772 done:
2773     filter_messages = NULL;
2774     IDirect3D9_Release(d3d9);
2775
2776     SetEvent(thread_params.test_finished);
2777     WaitForSingleObject(thread, INFINITE);
2778     CloseHandle(thread_params.test_finished);
2779     CloseHandle(thread_params.window_created);
2780     CloseHandle(thread);
2781
2782     DestroyWindow(device_window);
2783     DestroyWindow(focus_window);
2784     UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2785 }
2786
2787 static void test_wndproc_windowed(void)
2788 {
2789     struct wndproc_thread_param thread_params;
2790     IDirect3DDevice9 *device;
2791     WNDCLASSA wc = {0};
2792     IDirect3D9 *d3d9;
2793     HANDLE thread;
2794     LONG_PTR proc;
2795     HRESULT hr;
2796     ULONG ref;
2797     DWORD res, tid;
2798     HWND tmp;
2799
2800     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
2801     {
2802         skip("Failed to create IDirect3D9 object, skipping tests.\n");
2803         return;
2804     }
2805
2806     wc.lpfnWndProc = test_proc;
2807     wc.lpszClassName = "d3d9_test_wndproc_wc";
2808     ok(RegisterClassA(&wc), "Failed to register window class.\n");
2809
2810     thread_params.window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
2811     ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
2812     thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
2813     ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
2814
2815     focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2816             WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2817     device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
2818             WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
2819     thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
2820     ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
2821
2822     res = WaitForSingleObject(thread_params.window_created, INFINITE);
2823     ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
2824
2825     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2826     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2827             (LONG_PTR)test_proc, proc);
2828     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2829     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2830             (LONG_PTR)test_proc, proc);
2831
2832     trace("device_window %p, focus_window %p, dummy_window %p.\n",
2833             device_window, focus_window, thread_params.dummy_window);
2834
2835     tmp = GetFocus();
2836     ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2837     if (thread_params.running_in_foreground)
2838     {
2839         tmp = GetForegroundWindow();
2840         ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2841                 thread_params.dummy_window, tmp);
2842     }
2843     else
2844         skip("Not running in foreground, skip foreground window test\n");
2845
2846     filter_messages = focus_window;
2847
2848     device = create_device(d3d9, device_window, focus_window, TRUE);
2849     if (!device)
2850     {
2851         skip("Failed to create a D3D device, skipping tests.\n");
2852         goto done;
2853     }
2854
2855     tmp = GetFocus();
2856     ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
2857     tmp = GetForegroundWindow();
2858     ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
2859             thread_params.dummy_window, tmp);
2860
2861     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2862     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2863             (LONG_PTR)test_proc, proc);
2864
2865     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2866     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2867             (LONG_PTR)test_proc, proc);
2868
2869     filter_messages = NULL;
2870
2871     hr = reset_device(device, device_window, FALSE);
2872     ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2873
2874     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2875     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2876             (LONG_PTR)test_proc, proc);
2877
2878     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2879     ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2880             (LONG_PTR)test_proc, proc);
2881
2882     hr = reset_device(device, device_window, TRUE);
2883     ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2884
2885     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2886     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2887             (LONG_PTR)test_proc, proc);
2888
2889     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2890     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2891             (LONG_PTR)test_proc, proc);
2892
2893     filter_messages = focus_window;
2894
2895     ref = IDirect3DDevice9_Release(device);
2896     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2897
2898     filter_messages = device_window;
2899
2900     device = create_device(d3d9, focus_window, focus_window, TRUE);
2901     if (!device)
2902     {
2903         skip("Failed to create a D3D device, skipping tests.\n");
2904         goto done;
2905     }
2906
2907     filter_messages = NULL;
2908
2909     hr = reset_device(device, focus_window, FALSE);
2910     ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2911
2912     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2913     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2914             (LONG_PTR)test_proc, proc);
2915
2916     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2917     ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2918             (LONG_PTR)test_proc, proc);
2919
2920     hr = reset_device(device, focus_window, TRUE);
2921     ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2922
2923     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2924     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2925             (LONG_PTR)test_proc, proc);
2926
2927     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2928     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2929             (LONG_PTR)test_proc, proc);
2930
2931     filter_messages = device_window;
2932
2933     ref = IDirect3DDevice9_Release(device);
2934     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2935
2936     device = create_device(d3d9, device_window, focus_window, TRUE);
2937     if (!device)
2938     {
2939         skip("Failed to create a D3D device, skipping tests.\n");
2940         goto done;
2941     }
2942
2943     filter_messages = NULL;
2944
2945     hr = reset_device(device, device_window, FALSE);
2946     ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2947
2948     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2949     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2950             (LONG_PTR)test_proc, proc);
2951
2952     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2953     ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2954             (LONG_PTR)test_proc, proc);
2955
2956     hr = reset_device(device, device_window, TRUE);
2957     ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
2958
2959     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
2960     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2961             (LONG_PTR)test_proc, proc);
2962
2963     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
2964     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2965             (LONG_PTR)test_proc, proc);
2966
2967     filter_messages = device_window;
2968
2969     ref = IDirect3DDevice9_Release(device);
2970     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
2971
2972 done:
2973     filter_messages = NULL;
2974     IDirect3D9_Release(d3d9);
2975
2976     SetEvent(thread_params.test_finished);
2977     WaitForSingleObject(thread, INFINITE);
2978     CloseHandle(thread_params.test_finished);
2979     CloseHandle(thread_params.window_created);
2980     CloseHandle(thread);
2981
2982     DestroyWindow(device_window);
2983     DestroyWindow(focus_window);
2984     UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
2985 }
2986
2987 static void test_reset_fullscreen(void)
2988 {
2989     WNDCLASSEX wc = {0};
2990     IDirect3DDevice9 *device = NULL;
2991     IDirect3D9 *d3d = NULL;
2992     ATOM atom;
2993     static const struct message messages[] =
2994     {
2995         {WM_ACTIVATEAPP,    FOCUS_WINDOW},
2996         {0,                     0},
2997     };
2998
2999     d3d = pDirect3DCreate9(D3D_SDK_VERSION);
3000     ok(d3d != NULL, "Failed to create an IDirect3D object.\n");
3001     expect_messages = messages;
3002
3003     wc.cbSize = sizeof(WNDCLASSEX);
3004     wc.lpfnWndProc = test_proc;
3005     wc.lpszClassName = "test_reset_fullscreen";
3006
3007     atom = RegisterClassEx(&wc);
3008     ok(atom, "Failed to register a new window class. GetLastError:%d\n", GetLastError());
3009
3010     device_window = focus_window = CreateWindowEx(0, wc.lpszClassName, "Test Reset Fullscreen", 0, 0, 0, screen_width, screen_height, NULL, NULL, NULL, NULL);
3011     ok(device_window != NULL, "Failed to create a window. GetLastError:%d\n", GetLastError());
3012
3013     /*
3014      * Create a device in windowed mode.
3015      * Since the device is windowed and we haven't called any methods that
3016      * could show the window (such as ShowWindow or SetWindowPos) yet,
3017      * WM_ACTIVATEAPP will not have been sent.
3018      */
3019     device = create_device(d3d, device_window, focus_window, TRUE);
3020     if (!device)
3021     {
3022         skip("Unable to create device.  Skipping test.\n");
3023         goto cleanup;
3024     }
3025
3026     /*
3027      * Switch to fullscreen mode.
3028      * This will force the window to be shown and will cause the WM_ACTIVATEAPP
3029      * message to be sent.
3030      */
3031     ok(SUCCEEDED(reset_device(device, device_window, FALSE)), "Failed to reset device.\n");
3032
3033     flush_events();
3034     ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message);
3035     expect_messages = NULL;
3036
3037 cleanup:
3038     if (device) IDirect3DDevice9_Release(device);
3039     if (d3d) IDirect3D9_Release(d3d);
3040     DestroyWindow(device_window);
3041     device_window = focus_window = NULL;
3042     UnregisterClass(wc.lpszClassName, GetModuleHandle(NULL));
3043 }
3044
3045
3046 static inline void set_fpu_cw(WORD cw)
3047 {
3048 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3049 #define D3D9_TEST_SET_FPU_CW 1
3050     __asm__ volatile ("fnclex");
3051     __asm__ volatile ("fldcw %0" : : "m" (cw));
3052 #elif defined(__i386__) && defined(_MSC_VER)
3053 #define D3D9_TEST_SET_FPU_CW 1
3054     __asm fnclex;
3055     __asm fldcw cw;
3056 #endif
3057 }
3058
3059 static inline WORD get_fpu_cw(void)
3060 {
3061     WORD cw = 0;
3062 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3063 #define D3D9_TEST_GET_FPU_CW 1
3064     __asm__ volatile ("fnstcw %0" : "=m" (cw));
3065 #elif defined(__i386__) && defined(_MSC_VER)
3066 #define D3D9_TEST_GET_FPU_CW 1
3067     __asm fnstcw cw;
3068 #endif
3069     return cw;
3070 }
3071
3072 static void test_fpu_setup(void)
3073 {
3074 #if defined(D3D9_TEST_SET_FPU_CW) && defined(D3D9_TEST_GET_FPU_CW)
3075     D3DPRESENT_PARAMETERS present_parameters;
3076     IDirect3DDevice9 *device;
3077     HWND window = NULL;
3078     IDirect3D9 *d3d9;
3079     HRESULT hr;
3080     WORD cw;
3081
3082     d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
3083     ok(!!d3d9, "Failed to create a d3d9 object.\n");
3084     if (!d3d9) return;
3085
3086     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_CAPTION, 0, 0, screen_width, screen_height, 0, 0, 0, 0);
3087     ok(!!window, "Failed to create a window.\n");
3088     if (!window) goto done;
3089
3090     memset(&present_parameters, 0, sizeof(present_parameters));
3091     present_parameters.Windowed = TRUE;
3092     present_parameters.hDeviceWindow = window;
3093     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
3094
3095     set_fpu_cw(0xf60);
3096     cw = get_fpu_cw();
3097     ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3098
3099     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3100             D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
3101     if (FAILED(hr))
3102     {
3103         skip("Failed to create a device, hr %#x.\n", hr);
3104         set_fpu_cw(0x37f);
3105         goto done;
3106     }
3107
3108     cw = get_fpu_cw();
3109     ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3110
3111     IDirect3DDevice9_Release(device);
3112
3113     cw = get_fpu_cw();
3114     ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
3115     set_fpu_cw(0xf60);
3116     cw = get_fpu_cw();
3117     ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3118
3119     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
3120             D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &present_parameters, &device);
3121     ok(SUCCEEDED(hr), "CreateDevice failed, hr %#x.\n", hr);
3122
3123     cw = get_fpu_cw();
3124     ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
3125     set_fpu_cw(0x37f);
3126
3127     IDirect3DDevice9_Release(device);
3128
3129 done:
3130     if (window) DestroyWindow(window);
3131     if (d3d9) IDirect3D9_Release(d3d9);
3132 #endif
3133 }
3134
3135 static void test_window_style(void)
3136 {
3137     RECT focus_rect, fullscreen_rect, r;
3138     LONG device_style, device_exstyle;
3139     LONG focus_style, focus_exstyle;
3140     LONG style, expected_style;
3141     IDirect3DDevice9 *device;
3142     IDirect3D9 *d3d9;
3143     HRESULT hr;
3144     ULONG ref;
3145
3146
3147     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3148     {
3149         skip("Failed to create IDirect3D9 object, skipping tests.\n");
3150         return;
3151     }
3152
3153     focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3154             0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3155     device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3156             0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3157
3158     device_style = GetWindowLongA(device_window, GWL_STYLE);
3159     device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
3160     focus_style = GetWindowLongA(focus_window, GWL_STYLE);
3161     focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
3162
3163     SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3164     GetWindowRect(focus_window, &focus_rect);
3165
3166     device = create_device(d3d9, device_window, focus_window, FALSE);
3167     if (!device)
3168     {
3169         skip("Failed to create a D3D device, skipping tests.\n");
3170         goto done;
3171     }
3172
3173     style = GetWindowLongA(device_window, GWL_STYLE);
3174     expected_style = device_style | WS_VISIBLE;
3175     todo_wine ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3176             expected_style, style);
3177     style = GetWindowLongA(device_window, GWL_EXSTYLE);
3178     expected_style = device_exstyle | WS_EX_TOPMOST;
3179     todo_wine ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3180             expected_style, style);
3181
3182     style = GetWindowLongA(focus_window, GWL_STYLE);
3183     ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3184             focus_style, style);
3185     style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3186     ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3187             focus_exstyle, style);
3188
3189     GetWindowRect(device_window, &r);
3190     ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3191             fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3192             r.left, r.top, r.right, r.bottom);
3193     GetClientRect(device_window, &r);
3194     todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
3195     GetWindowRect(focus_window, &r);
3196     ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3197             focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3198             r.left, r.top, r.right, r.bottom);
3199
3200     hr = reset_device(device, device_window, TRUE);
3201     ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
3202
3203     style = GetWindowLongA(device_window, GWL_STYLE);
3204     expected_style = device_style | WS_VISIBLE;
3205     ok(style == expected_style, "Expected device window style %#x, got %#x.\n",
3206             expected_style, style);
3207     style = GetWindowLongA(device_window, GWL_EXSTYLE);
3208     expected_style = device_exstyle | WS_EX_TOPMOST;
3209     ok(style == expected_style, "Expected device window extended style %#x, got %#x.\n",
3210             expected_style, style);
3211
3212     style = GetWindowLongA(focus_window, GWL_STYLE);
3213     ok(style == focus_style, "Expected focus window style %#x, got %#x.\n",
3214             focus_style, style);
3215     style = GetWindowLongA(focus_window, GWL_EXSTYLE);
3216     ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n",
3217             focus_exstyle, style);
3218
3219     ref = IDirect3DDevice9_Release(device);
3220     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3221
3222 done:
3223     IDirect3D9_Release(d3d9);
3224
3225     DestroyWindow(device_window);
3226     DestroyWindow(focus_window);
3227 }
3228
3229 static const POINT *expect_pos;
3230
3231 static LRESULT CALLBACK test_cursor_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
3232 {
3233     if (message == WM_MOUSEMOVE)
3234     {
3235         if (expect_pos && expect_pos->x && expect_pos->y)
3236         {
3237             POINT p = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
3238
3239             ClientToScreen(window, &p);
3240             if (expect_pos->x == p.x && expect_pos->y == p.y)
3241                 ++expect_pos;
3242         }
3243     }
3244
3245     return DefWindowProcA(window, message, wparam, lparam);
3246 }
3247
3248 static void test_cursor_pos(void)
3249 {
3250     IDirect3DSurface9 *cursor;
3251     IDirect3DDevice9 *device;
3252     WNDCLASSA wc = {0};
3253     IDirect3D9 *d3d9;
3254     UINT refcount;
3255     HWND window;
3256     HRESULT hr;
3257     BOOL ret;
3258
3259     /* Note that we don't check for movement we're not supposed to receive.
3260      * That's because it's hard to distinguish from the user accidentally
3261      * moving the mouse. */
3262     static const POINT points[] =
3263     {
3264         {50, 50},
3265         {75, 75},
3266         {100, 100},
3267         {125, 125},
3268         {150, 150},
3269         {125, 125},
3270         {150, 150},
3271         {150, 150},
3272         {0, 0},
3273     };
3274
3275     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3276     {
3277         skip("Failed to create IDirect3D9 object, skipping cursor tests.\n");
3278         return;
3279     }
3280
3281     wc.lpfnWndProc = test_cursor_proc;
3282     wc.lpszClassName = "d3d9_test_cursor_wc";
3283     ok(RegisterClassA(&wc), "Failed to register window class.\n");
3284     window = CreateWindow("d3d9_test_cursor_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3285             0, 0, 320, 240, NULL, NULL, NULL, NULL);
3286     ShowWindow(window, SW_SHOW);
3287
3288     device = create_device(d3d9, window, window, TRUE);
3289     if (!device)
3290     {
3291         skip("Failed to create a D3D device, skipping tests.\n");
3292         goto done;
3293     }
3294
3295     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3296             D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, NULL);
3297     ok(SUCCEEDED(hr), "Failed to create cursor surface, hr %#x.\n", hr);
3298     hr = IDirect3DDevice9_SetCursorProperties(device, 0, 0, cursor);
3299     ok(SUCCEEDED(hr), "Failed to set cursor properties, hr %#x.\n", hr);
3300     IDirect3DSurface9_Release(cursor);
3301     ret = IDirect3DDevice9_ShowCursor(device, TRUE);
3302     ok(!ret, "Failed to show cursor, hr %#x.\n", ret);
3303
3304     flush_events();
3305     expect_pos = points;
3306
3307     ret = SetCursorPos(50, 50);
3308     ok(ret, "Failed to set cursor position.\n");
3309     flush_events();
3310
3311     IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3312     flush_events();
3313     /* SetCursorPosition() eats duplicates. */
3314     IDirect3DDevice9_SetCursorPosition(device, 75, 75, 0);
3315     flush_events();
3316
3317     ret = SetCursorPos(100, 100);
3318     ok(ret, "Failed to set cursor position.\n");
3319     flush_events();
3320     /* Even if the position was set with SetCursorPos(). */
3321     IDirect3DDevice9_SetCursorPosition(device, 100, 100, 0);
3322     flush_events();
3323
3324     IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3325     flush_events();
3326     ret = SetCursorPos(150, 150);
3327     ok(ret, "Failed to set cursor position.\n");
3328     flush_events();
3329     IDirect3DDevice9_SetCursorPosition(device, 125, 125, 0);
3330     flush_events();
3331
3332     IDirect3DDevice9_SetCursorPosition(device, 150, 150, 0);
3333     flush_events();
3334     /* SetCursorPos() doesn't. */
3335     ret = SetCursorPos(150, 150);
3336     ok(ret, "Failed to set cursor position.\n");
3337     flush_events();
3338
3339     ok(!expect_pos->x && !expect_pos->y, "Didn't receive MOUSEMOVE %u (%d, %d).\n",
3340        (unsigned)(expect_pos - points), expect_pos->x, expect_pos->y);
3341
3342     refcount = IDirect3DDevice9_Release(device);
3343     ok(!refcount, "Device has %u references left.\n", refcount);
3344 done:
3345     DestroyWindow(window);
3346     UnregisterClassA("d3d9_test_cursor_wc", GetModuleHandleA(NULL));
3347     if (d3d9)
3348         IDirect3D9_Release(d3d9);
3349 }
3350
3351 static void test_mode_change(void)
3352 {
3353     RECT fullscreen_rect, focus_rect, r;
3354     IDirect3DSurface9 *backbuffer;
3355     IDirect3DDevice9 *device;
3356     D3DSURFACE_DESC desc;
3357     IDirect3D9 *d3d9;
3358     DEVMODEW devmode;
3359     UINT refcount;
3360     HRESULT hr;
3361     DWORD ret;
3362
3363     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3364     {
3365         skip("Failed to create IDirect3D9 object, skipping mode change tests.\n");
3366         return;
3367     }
3368
3369     focus_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3370             0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3371     device_window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3372             0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3373
3374     SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3375     GetWindowRect(focus_window, &focus_rect);
3376
3377     device = create_device(d3d9, device_window, focus_window, FALSE);
3378     if (!device)
3379     {
3380         skip("Failed to create a D3D device, skipping tests.\n");
3381         goto done;
3382     }
3383
3384     memset(&devmode, 0, sizeof(devmode));
3385     devmode.dmSize = sizeof(devmode);
3386     devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
3387     devmode.dmPelsWidth = 640;
3388     devmode.dmPelsHeight = 480;
3389
3390     ret = ChangeDisplaySettingsW(&devmode, CDS_FULLSCREEN);
3391     ok(ret == DISP_CHANGE_SUCCESSFUL, "Failed to change display mode, ret %#x.\n", ret);
3392
3393     memset(&devmode, 0, sizeof(devmode));
3394     devmode.dmSize = sizeof(devmode);
3395     ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3396     ok(ret, "Failed to get display mode.\n");
3397     ok(devmode.dmPelsWidth == 640, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3398     ok(devmode.dmPelsHeight == 480, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3399
3400     GetWindowRect(device_window, &r);
3401     ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3402             fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3403             r.left, r.top, r.right, r.bottom);
3404     GetWindowRect(focus_window, &r);
3405     ok(EqualRect(&r, &focus_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3406             focus_rect.left, focus_rect.top, focus_rect.right, focus_rect.bottom,
3407             r.left, r.top, r.right, r.bottom);
3408
3409     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3410     ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
3411     hr = IDirect3DSurface9_GetDesc(backbuffer, &desc);
3412     ok(SUCCEEDED(hr), "Failed to get backbuffer desc, hr %#x.\n", hr);
3413     ok(desc.Width == screen_width, "Got unexpected backbuffer width %u.\n", desc.Width);
3414     ok(desc.Height == screen_height, "Got unexpected backbuffer height %u.\n", desc.Height);
3415     IDirect3DSurface9_Release(backbuffer);
3416
3417     refcount = IDirect3DDevice9_Release(device);
3418     ok(!refcount, "Device has %u references left.\n", refcount);
3419
3420     memset(&devmode, 0, sizeof(devmode));
3421     devmode.dmSize = sizeof(devmode);
3422     ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3423     ok(ret, "Failed to get display mode.\n");
3424     ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3425     ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3426
3427 done:
3428     DestroyWindow(device_window);
3429     DestroyWindow(focus_window);
3430     if (d3d9)
3431         IDirect3D9_Release(d3d9);
3432
3433     memset(&devmode, 0, sizeof(devmode));
3434     devmode.dmSize = sizeof(devmode);
3435     ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3436     ok(ret, "Failed to get display mode.\n");
3437     ok(devmode.dmPelsWidth == screen_width, "Got unexpect width %u.\n", devmode.dmPelsWidth);
3438     ok(devmode.dmPelsHeight == screen_height, "Got unexpect height %u.\n", devmode.dmPelsHeight);
3439 }
3440
3441 static void test_device_window_reset(void)
3442 {
3443     RECT fullscreen_rect, device_rect, r;
3444     IDirect3DDevice9 *device;
3445     WNDCLASSA wc = {0};
3446     IDirect3D9 *d3d9;
3447     LONG_PTR proc;
3448     HRESULT hr;
3449     ULONG ref;
3450
3451     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3452     {
3453         skip("Failed to create IDirect3D9 object, skipping tests.\n");
3454         return;
3455     }
3456
3457     wc.lpfnWndProc = test_proc;
3458     wc.lpszClassName = "d3d9_test_wndproc_wc";
3459     ok(RegisterClassA(&wc), "Failed to register window class.\n");
3460
3461     focus_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3462             0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3463     device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3464             0, 0, screen_width / 2, screen_height / 2, 0, 0, 0, 0);
3465
3466     SetRect(&fullscreen_rect, 0, 0, screen_width, screen_height);
3467     GetWindowRect(device_window, &device_rect);
3468
3469     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3470     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3471             (LONG_PTR)test_proc, proc);
3472     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3473     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3474             (LONG_PTR)test_proc, proc);
3475
3476     device = create_device(d3d9, NULL, focus_window, FALSE);
3477     if (!device)
3478     {
3479         skip("Failed to create a D3D device, skipping tests.\n");
3480         goto done;
3481     }
3482
3483     GetWindowRect(focus_window, &r);
3484     ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3485             fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3486             r.left, r.top, r.right, r.bottom);
3487     GetWindowRect(device_window, &r);
3488     ok(EqualRect(&r, &device_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3489             device_rect.left, device_rect.top, device_rect.right, device_rect.bottom,
3490             r.left, r.top, r.right, r.bottom);
3491
3492     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3493     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3494             (LONG_PTR)test_proc, proc);
3495     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3496     ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3497             (LONG_PTR)test_proc, proc);
3498
3499     hr = reset_device(device, device_window, FALSE);
3500     ok(SUCCEEDED(hr), "Failed to reset device.\n");
3501
3502     GetWindowRect(focus_window, &r);
3503     ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3504             fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3505             r.left, r.top, r.right, r.bottom);
3506     GetWindowRect(device_window, &r);
3507     ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
3508             fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
3509             r.left, r.top, r.right, r.bottom);
3510
3511     proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
3512     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3513             (LONG_PTR)test_proc, proc);
3514     proc = GetWindowLongPtrA(focus_window, GWLP_WNDPROC);
3515     ok(proc != (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3516             (LONG_PTR)test_proc, proc);
3517
3518     ref = IDirect3DDevice9_Release(device);
3519     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3520
3521 done:
3522     IDirect3D9_Release(d3d9);
3523     DestroyWindow(device_window);
3524     DestroyWindow(focus_window);
3525     UnregisterClassA("d3d9_test_wndproc_wc", GetModuleHandleA(NULL));
3526 }
3527
3528 static void test_reset_resources(void)
3529 {
3530     IDirect3DSurface9 *surface, *rt;
3531     IDirect3DTexture9 *texture;
3532     IDirect3DDevice9 *device;
3533     IDirect3D9 *d3d9;
3534     unsigned int i;
3535     D3DCAPS9 caps;
3536     HWND window;
3537     HRESULT hr;
3538     ULONG ref;
3539
3540     window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3541             0, 0, 640, 480, 0, 0, 0, 0);
3542
3543     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3544     {
3545         skip("Failed to create IDirect3D9 object, skipping tests.\n");
3546         DestroyWindow(window);
3547         return;
3548     }
3549
3550     if (!(device = create_device(d3d9, window, window, TRUE)))
3551     {
3552         skip("Failed to create a D3D device, skipping tests.\n");
3553         goto done;
3554     }
3555
3556     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3557     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3558
3559     hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 128, 128,
3560             D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
3561     ok(SUCCEEDED(hr), "Failed to create depth/stencil surface, hr %#x.\n", hr);
3562     hr = IDirect3DDevice9_SetDepthStencilSurface(device, surface);
3563     ok(SUCCEEDED(hr), "Failed to set depth/stencil surface, hr %#x.\n", hr);
3564     IDirect3DSurface9_Release(surface);
3565
3566     for (i = 0; i < caps.NumSimultaneousRTs; ++i)
3567     {
3568         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
3569                 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
3570         ok(SUCCEEDED(hr), "Failed to create render target texture %u, hr %#x.\n", i, hr);
3571         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3572         ok(SUCCEEDED(hr), "Failed to get surface %u, hr %#x.\n", i, hr);
3573         IDirect3DTexture9_Release(texture);
3574         hr = IDirect3DDevice9_SetRenderTarget(device, i, surface);
3575         ok(SUCCEEDED(hr), "Failed to set render target surface %u, hr %#x.\n", i, hr);
3576         IDirect3DSurface9_Release(surface);
3577     }
3578
3579     hr = reset_device(device, device_window, TRUE);
3580     ok(SUCCEEDED(hr), "Failed to reset device.\n");
3581
3582     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
3583     ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3584     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &surface);
3585     ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
3586     ok(surface == rt, "Got unexpected surface %p for render target.\n", surface);
3587     IDirect3DSurface9_Release(surface);
3588     IDirect3DSurface9_Release(rt);
3589
3590     for (i = 1; i < caps.NumSimultaneousRTs; ++i)
3591     {
3592         hr = IDirect3DDevice9_GetRenderTarget(device, i, &surface);
3593         ok(hr == D3DERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
3594     }
3595
3596     ref = IDirect3DDevice9_Release(device);
3597     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
3598
3599 done:
3600     IDirect3D9_Release(d3d9);
3601     DestroyWindow(window);
3602 }
3603
3604 static void test_set_rt_vp_scissor(void)
3605 {
3606     IDirect3DStateBlock9 *stateblock;
3607     IDirect3DDevice9 *device;
3608     IDirect3DSurface9 *rt;
3609     IDirect3D9 *d3d9;
3610     D3DVIEWPORT9 vp;
3611     UINT refcount;
3612     HWND window;
3613     HRESULT hr;
3614     RECT rect;
3615
3616     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3617     {
3618         skip("Failed to create IDirect3D9 object, skipping tests.\n");
3619         return;
3620     }
3621
3622     window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
3623             0, 0, 640, 480, 0, 0, 0, 0);
3624     if (!(device = create_device(d3d9, window, window, TRUE)))
3625     {
3626         skip("Failed to create a D3D device, skipping tests.\n");
3627         DestroyWindow(window);
3628         return;
3629     }
3630
3631     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
3632             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
3633     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3634
3635     hr = IDirect3DDevice9_GetViewport(device, &vp);
3636     ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3637     ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3638     ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3639     ok(vp.Width == screen_width, "Got unexpected vp.Width %u.\n", vp.Width);
3640     ok(vp.Height == screen_height, "Got unexpected vp.Height %u.\n", vp.Height);
3641     ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3642     ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3643
3644     hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3645     ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3646     ok(rect.left == 0 && rect.top == 0 && rect.right == screen_width && rect.bottom == screen_height,
3647             "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3648             rect.left, rect.top, rect.right, rect.bottom);
3649
3650     hr = IDirect3DDevice9_BeginStateBlock(device);
3651     ok(SUCCEEDED(hr), "Failed to begin stateblock, hr %#x.\n", hr);
3652
3653     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3654     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3655
3656     hr = IDirect3DDevice9_EndStateBlock(device, &stateblock);
3657     ok(SUCCEEDED(hr), "Failed to end stateblock, hr %#x.\n", hr);
3658     IDirect3DStateBlock9_Release(stateblock);
3659
3660     hr = IDirect3DDevice9_GetViewport(device, &vp);
3661     ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3662     ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3663     ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3664     ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3665     ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3666     ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3667     ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3668
3669     hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3670     ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3671     ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3672             "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3673             rect.left, rect.top, rect.right, rect.bottom);
3674
3675     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3676     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3677
3678     vp.X = 10;
3679     vp.Y = 20;
3680     vp.Width = 30;
3681     vp.Height = 40;
3682     vp.MinZ = 0.25f;
3683     vp.MaxZ = 0.75f;
3684     hr = IDirect3DDevice9_SetViewport(device, &vp);
3685     ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
3686
3687     SetRect(&rect, 50, 60, 70, 80);
3688     hr = IDirect3DDevice9_SetScissorRect(device, &rect);
3689     ok(SUCCEEDED(hr), "Failed to set scissor rect, hr %#x.\n", hr);
3690
3691     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
3692     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
3693
3694     hr = IDirect3DDevice9_GetViewport(device, &vp);
3695     ok(SUCCEEDED(hr), "Failed to get viewport, hr %#x.\n", hr);
3696     ok(!vp.X, "Got unexpected vp.X %u.\n", vp.X);
3697     ok(!vp.Y, "Got unexpected vp.Y %u.\n", vp.Y);
3698     ok(vp.Width == 128, "Got unexpected vp.Width %u.\n", vp.Width);
3699     ok(vp.Height == 128, "Got unexpected vp.Height %u.\n", vp.Height);
3700     ok(vp.MinZ == 0.0f, "Got unexpected vp.MinZ %.8e.\n", vp.MinZ);
3701     ok(vp.MaxZ == 1.0f, "Got unexpected vp.MaxZ %.8e.\n", vp.MaxZ);
3702
3703     hr = IDirect3DDevice9_GetScissorRect(device, &rect);
3704     ok(SUCCEEDED(hr), "Failed to get scissor rect, hr %#x.\n", hr);
3705     ok(rect.left == 0 && rect.top == 0 && rect.right == 128 && rect.bottom == 128,
3706             "Got unexpected scissor rect {%d, %d, %d, %d}.\n",
3707             rect.left, rect.top, rect.right, rect.bottom);
3708
3709     IDirect3DSurface9_Release(rt);
3710     refcount = IDirect3DDevice9_Release(device);
3711     ok(!refcount, "Device has %u references left.\n", refcount);
3712     IDirect3D9_Release(d3d9);
3713     DestroyWindow(window);
3714 }
3715
3716 static void test_volume_get_container(void)
3717 {
3718     IDirect3DVolumeTexture9 *texture = NULL;
3719     IDirect3DVolume9 *volume = NULL;
3720     IDirect3DDevice9 *device;
3721     IUnknown *container;
3722     IDirect3D9 *d3d9;
3723     ULONG refcount;
3724     D3DCAPS9 caps;
3725     HWND window;
3726     HRESULT hr;
3727
3728     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3729     {
3730         skip("Failed to create d3d9 object, skipping tests.\n");
3731         return;
3732     }
3733
3734     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3735             0, 0, 640, 480, 0, 0, 0, 0);
3736     if (!(device = create_device(d3d9, window, window, TRUE)))
3737     {
3738         skip("Failed to create a D3D device, skipping tests.\n");
3739         IDirect3D9_Release(d3d9);
3740         DestroyWindow(window);
3741         return;
3742     }
3743
3744     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3745     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3746     if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3747     {
3748         skip("No volume texture support, skipping tests.\n");
3749         IDirect3DDevice9_Release(device);
3750         IDirect3D9_Release(d3d9);
3751         DestroyWindow(window);
3752         return;
3753     }
3754
3755     hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3756             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3757     ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3758     ok(!!texture, "Got unexpected texture %p.\n", texture);
3759
3760     hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3761     ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3762     ok(!!volume, "Got unexpected volume %p.\n", volume);
3763
3764     /* These should work... */
3765     container = NULL;
3766     hr = IDirect3DVolume9_GetContainer(volume, &IID_IUnknown, (void **)&container);
3767     ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3768     ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3769     IUnknown_Release(container);
3770
3771     container = NULL;
3772     hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DResource9, (void **)&container);
3773     ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3774     ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3775     IUnknown_Release(container);
3776
3777     container = NULL;
3778     hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DBaseTexture9, (void **)&container);
3779     ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3780     ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3781     IUnknown_Release(container);
3782
3783     container = NULL;
3784     hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolumeTexture9, (void **)&container);
3785     ok(SUCCEEDED(hr), "Failed to get volume container, hr %#x.\n", hr);
3786     ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
3787     IUnknown_Release(container);
3788
3789     /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
3790     hr = IDirect3DVolume9_GetContainer(volume, &IID_IDirect3DVolume9, (void **)&container);
3791     ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3792     ok(!container, "Got unexpected container %p.\n", container);
3793
3794     IDirect3DVolume9_Release(volume);
3795     IDirect3DVolumeTexture9_Release(texture);
3796     refcount = IDirect3DDevice9_Release(device);
3797     ok(!refcount, "Device has %u references left.\n", refcount);
3798     IDirect3D9_Release(d3d9);
3799     DestroyWindow(window);
3800 }
3801
3802 static void test_volume_resource(void)
3803 {
3804     IDirect3DVolumeTexture9 *texture;
3805     IDirect3DResource9 *resource;
3806     IDirect3DVolume9 *volume;
3807     IDirect3DDevice9 *device;
3808     IDirect3D9 *d3d9;
3809     ULONG refcount;
3810     D3DCAPS9 caps;
3811     HWND window;
3812     HRESULT hr;
3813
3814     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3815     {
3816         skip("Failed to create d3d9 object, skipping tests.\n");
3817         return;
3818     }
3819
3820     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3821             0, 0, 640, 480, 0, 0, 0, 0);
3822     if (!(device = create_device(d3d9, window, window, TRUE)))
3823     {
3824         skip("Failed to create a D3D device, skipping tests.\n");
3825         IDirect3D9_Release(d3d9);
3826         DestroyWindow(window);
3827         return;
3828     }
3829
3830     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3831     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3832     if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
3833     {
3834         skip("No volume texture support, skipping tests.\n");
3835         IDirect3DDevice9_Release(device);
3836         IDirect3D9_Release(d3d9);
3837         DestroyWindow(window);
3838         return;
3839     }
3840
3841     hr = IDirect3DDevice9_CreateVolumeTexture(device, 128, 128, 128, 1, 0,
3842             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
3843     ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
3844     hr = IDirect3DVolumeTexture9_GetVolumeLevel(texture, 0, &volume);
3845     ok(SUCCEEDED(hr), "Failed to get volume level, hr %#x.\n", hr);
3846     IDirect3DVolumeTexture9_Release(texture);
3847
3848     hr = IDirect3DVolume9_QueryInterface(volume, &IID_IDirect3DResource9, (void **)&resource);
3849     ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
3850
3851     IDirect3DVolume9_Release(volume);
3852     refcount = IDirect3DDevice9_Release(device);
3853     ok(!refcount, "Device has %u references left.\n", refcount);
3854     IDirect3D9_Release(d3d9);
3855     DestroyWindow(window);
3856 }
3857
3858 static void test_vb_lock_flags(void)
3859 {
3860     static const struct
3861     {
3862         DWORD flags;
3863         const char *debug_string;
3864         HRESULT win7_result;
3865     }
3866     test_data[] =
3867     {
3868         {D3DLOCK_READONLY,                          "D3DLOCK_READONLY",                         D3D_OK            },
3869         {D3DLOCK_DISCARD,                           "D3DLOCK_DISCARD",                          D3D_OK            },
3870         {D3DLOCK_NOOVERWRITE,                       "D3DLOCK_NOOVERWRITE",                      D3D_OK            },
3871         {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD,     "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD",    D3D_OK            },
3872         {D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY,    "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY",   D3D_OK            },
3873         {D3DLOCK_READONLY | D3DLOCK_DISCARD,        "D3DLOCK_READONLY | D3DLOCK_DISCARD",       D3DERR_INVALIDCALL},
3874         /* Completely bogus flags aren't an error. */
3875         {0xdeadbeef,                                "0xdeadbeef",                               D3DERR_INVALIDCALL},
3876     };
3877     IDirect3DVertexBuffer9 *buffer;
3878     IDirect3DDevice9 *device;
3879     IDirect3D9 *d3d9;
3880     unsigned int i;
3881     ULONG refcount;
3882     HWND window;
3883     HRESULT hr;
3884     void *data;
3885
3886     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3887     {
3888         skip("Failed to create d3d9 object, skipping tests.\n");
3889         return;
3890     }
3891
3892     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3893             0, 0, 640, 480, 0, 0, 0, 0);
3894     if (!(device = create_device(d3d9, window, window, TRUE)))
3895     {
3896         skip("Failed to create a D3D device, skipping tests.\n");
3897         IDirect3D9_Release(d3d9);
3898         DestroyWindow(window);
3899         return;
3900     }
3901
3902     hr = IDirect3DDevice9_CreateVertexBuffer(device, 1024, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &buffer, NULL);
3903     ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
3904
3905     for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
3906     {
3907         hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, test_data[i].flags);
3908         /* Windows XP always returns D3D_OK even with flags that don't make
3909          * sense. Windows 7 returns an error. At least one game (Shaiya)
3910          * depends on the Windows XP result, so mark the Windows 7 behavior as
3911          * broken. */
3912         ok(hr == D3D_OK || broken(hr == test_data[i].win7_result), "Got unexpected hr %#x for %s.\n",
3913                 hr, test_data[i].debug_string);
3914         if (SUCCEEDED(hr))
3915         {
3916             ok(!!data, "Got unexpected data %p.\n", data);
3917             hr = IDirect3DVertexBuffer9_Unlock(buffer);
3918             ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3919         }
3920     }
3921
3922     IDirect3DVertexBuffer9_Release(buffer);
3923     refcount = IDirect3DDevice9_Release(device);
3924     ok(!refcount, "Device has %u references left.\n", refcount);
3925     IDirect3D9_Release(d3d9);
3926     DestroyWindow(window);
3927 }
3928
3929 static const char *debug_d3dpool(D3DPOOL pool)
3930 {
3931     switch (pool)
3932     {
3933         case D3DPOOL_DEFAULT:
3934             return "D3DPOOL_DEFAULT";
3935         case D3DPOOL_SYSTEMMEM:
3936             return "D3DPOOL_SYSTEMMEM";
3937         case D3DPOOL_SCRATCH:
3938             return "D3DPOOL_SCRATCH";
3939         case D3DPOOL_MANAGED:
3940             return "D3DPOOL_MANAGED";
3941         default:
3942             return "unknown pool";
3943     }
3944 }
3945
3946 static void test_vertex_buffer_alignment(void)
3947 {
3948     static const D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
3949     static const DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
3950     IDirect3DVertexBuffer9 *buffer = NULL;
3951     const unsigned int align = 16;
3952     IDirect3DDevice9 *device;
3953     unsigned int i, j;
3954     IDirect3D9 *d3d9;
3955     ULONG refcount;
3956     HWND window;
3957     HRESULT hr;
3958     void *data;
3959
3960     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
3961     {
3962         skip("Failed to create d3d9 object, skipping tests.\n");
3963         return;
3964     }
3965
3966     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
3967             0, 0, 640, 480, 0, 0, 0, 0);
3968     if (!(device = create_device(d3d9, window, window, TRUE)))
3969     {
3970         skip("Failed to create a D3D device, skipping tests.\n");
3971         IDirect3D9_Release(d3d9);
3972         DestroyWindow(window);
3973         return;
3974     }
3975
3976     for (i = 0; i < (sizeof(sizes) / sizeof(*sizes)); ++i)
3977     {
3978         for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
3979         {
3980             hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
3981             if (pools[j] == D3DPOOL_SCRATCH)
3982                 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x trying to create a D3DPOOL_SCRATCH buffer.\n", hr);
3983             else
3984                 ok(SUCCEEDED(hr), "Failed to create vertex buffer in pool %s with size %u, hr %#x.\n",
3985                         debug_d3dpool(pools[j]), sizes[i], hr);
3986             if (FAILED(hr))
3987                 continue;
3988
3989             hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, 0);
3990             ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
3991             ok(!((DWORD_PTR)data & (align - 1)),
3992                     "Vertex buffer start address %p is not %u byte aligned (size %u, pool %s).\n",
3993                     data, align, sizes[i], debug_d3dpool(pools[j]));
3994             hr = IDirect3DVertexBuffer9_Unlock(buffer);
3995             ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
3996             IDirect3DVertexBuffer9_Release(buffer);
3997         }
3998     }
3999
4000     refcount = IDirect3DDevice9_Release(device);
4001     ok(!refcount, "Device has %u references left.\n", refcount);
4002     IDirect3D9_Release(d3d9);
4003     DestroyWindow(window);
4004 }
4005
4006 static void test_query_support(void)
4007 {
4008     static const D3DQUERYTYPE queries[] =
4009     {
4010         D3DQUERYTYPE_VCACHE,
4011         D3DQUERYTYPE_RESOURCEMANAGER,
4012         D3DQUERYTYPE_VERTEXSTATS,
4013         D3DQUERYTYPE_EVENT,
4014         D3DQUERYTYPE_OCCLUSION,
4015         D3DQUERYTYPE_TIMESTAMP,
4016         D3DQUERYTYPE_TIMESTAMPDISJOINT,
4017         D3DQUERYTYPE_TIMESTAMPFREQ,
4018         D3DQUERYTYPE_PIPELINETIMINGS,
4019         D3DQUERYTYPE_INTERFACETIMINGS,
4020         D3DQUERYTYPE_VERTEXTIMINGS,
4021         D3DQUERYTYPE_PIXELTIMINGS,
4022         D3DQUERYTYPE_BANDWIDTHTIMINGS,
4023         D3DQUERYTYPE_CACHEUTILIZATION,
4024     };
4025     IDirect3DQuery9 *query = NULL;
4026     IDirect3DDevice9 *device;
4027     IDirect3D9 *d3d9;
4028     unsigned int i;
4029     ULONG refcount;
4030     BOOL supported;
4031     HWND window;
4032     HRESULT hr;
4033
4034     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4035     {
4036         skip("Failed to create d3d9 object, skipping tests.\n");
4037         return;
4038     }
4039
4040     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4041             0, 0, 640, 480, 0, 0, 0, 0);
4042     if (!(device = create_device(d3d9, window, window, TRUE)))
4043     {
4044         skip("Failed to create a D3D device, skipping tests.\n");
4045         IDirect3D9_Release(d3d9);
4046         DestroyWindow(window);
4047         return;
4048     }
4049
4050     for (i = 0; i < sizeof(queries) / sizeof(*queries); ++i)
4051     {
4052         hr = IDirect3DDevice9_CreateQuery(device, queries[i], NULL);
4053         ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4054
4055         supported = hr == D3D_OK;
4056
4057         hr = IDirect3DDevice9_CreateQuery(device, queries[i], &query);
4058         ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x for query %#x.\n", hr, queries[i]);
4059
4060         ok(!supported || query, "Query %#x was claimed to be supported, but can't be created.\n", queries[i]);
4061         ok(supported || !query, "Query %#x was claimed not to be supported, but can be created.\n", queries[i]);
4062
4063         if (query)
4064         {
4065             IDirect3DQuery9_Release(query);
4066             query = NULL;
4067         }
4068     }
4069
4070     refcount = IDirect3DDevice9_Release(device);
4071     ok(!refcount, "Device has %u references left.\n", refcount);
4072     IDirect3D9_Release(d3d9);
4073     DestroyWindow(window);
4074 }
4075
4076 static void test_occlusion_query_states(void)
4077 {
4078     static const float point[3] = {0.0, 0.0, 0.0};
4079     IDirect3DQuery9 *query = NULL;
4080     unsigned int data_size, i;
4081     IDirect3DDevice9 *device;
4082     IDirect3D9 *d3d9;
4083     ULONG refcount;
4084     HWND window;
4085     HRESULT hr;
4086     BYTE *data;
4087
4088     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
4089     {
4090         skip("Failed to create d3d9 object, skipping tests.\n");
4091         return;
4092     }
4093
4094     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4095             0, 0, 640, 480, 0, 0, 0, 0);
4096     if (!(device = create_device(d3d9, window, window, TRUE)))
4097     {
4098         skip("Failed to create a D3D device, skipping tests.\n");
4099         IDirect3D9_Release(d3d9);
4100         DestroyWindow(window);
4101         return;
4102     }
4103
4104     hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_OCCLUSION, &query);
4105     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
4106     if (!query)
4107     {
4108         skip("Occlusion queries are not supported, skipping tests.\n");
4109         IDirect3DDevice9_Release(device);
4110         IDirect3D9_Release(d3d9);
4111         DestroyWindow(window);
4112         return;
4113     }
4114
4115     data_size = IDirect3DQuery9_GetDataSize(query);
4116     data = HeapAlloc(GetProcessHeap(), 0, data_size);
4117
4118     hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4119     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4120     hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4121     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4122
4123     hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4124     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4125     hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4126     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4127     hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4128     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4129
4130     *((DWORD *)data) = 0x12345678;
4131     hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH);
4132     ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4133     hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4134     ok(hr == S_FALSE || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4135     if (hr == D3D_OK)
4136         ok(!*(DWORD *)data, "Got unexpected query result %u.\n", *(DWORD *)data);
4137
4138     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4139     ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4140     hr = IDirect3DDevice9_BeginScene(device);
4141     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4142     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, point, 3 * sizeof(float));
4143     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4144     hr = IDirect3DDevice9_EndScene(device);
4145     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4146
4147     hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4148     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4149     for (i = 0; i < 500; ++i)
4150     {
4151         if ((hr = IDirect3DQuery9_GetData(query, NULL, 0, D3DGETDATA_FLUSH)) != S_FALSE)
4152             break;
4153         Sleep(10);
4154     }
4155     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4156
4157     hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4158     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4159     hr = IDirect3DQuery9_GetData(query, data, data_size, D3DGETDATA_FLUSH);
4160     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
4161
4162     hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN);
4163     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4164     hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4165     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4166     hr = IDirect3DQuery9_Issue(query, D3DISSUE_END);
4167     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4168
4169     HeapFree(GetProcessHeap(), 0, data);
4170     IDirect3DQuery9_Release(query);
4171     refcount = IDirect3DDevice9_Release(device);
4172     ok(!refcount, "Device has %u references left.\n", refcount);
4173     IDirect3D9_Release(d3d9);
4174     DestroyWindow(window);
4175 }
4176
4177 static void test_get_set_vertex_shader(void)
4178 {
4179     IDirect3DVertexShader9 *current_shader = NULL;
4180     IDirect3DVertexShader9 *shader = NULL;
4181     IDirect3DDevice9 *device;
4182     ULONG refcount, i;
4183     IDirect3D9 *d3d;
4184     D3DCAPS9 caps;
4185     HWND window;
4186     HRESULT hr;
4187
4188     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4189     {
4190         skip("Failed to create D3D object, skipping tests.\n");
4191         return;
4192     }
4193
4194     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4195             0, 0, 640, 480, 0, 0, 0, 0);
4196     if (!(device = create_device(d3d, window, window, TRUE)))
4197     {
4198         skip("Failed to create a D3D device, skipping tests.\n");
4199         IDirect3D9_Release(d3d);
4200         DestroyWindow(window);
4201         return;
4202     }
4203
4204     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4205     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4206     if (!(caps.VertexShaderVersion & 0xffff))
4207     {
4208         skip("No vertex shader support, skipping tests.\n");
4209         IDirect3DDevice9_Release(device);
4210         IDirect3D9_Release(d3d);
4211         DestroyWindow(window);
4212         return;
4213     }
4214
4215     hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
4216     ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4217     ok(!!shader, "Got unexpected shader %p.\n", shader);
4218
4219     /* SetVertexShader() should not touch the shader's refcount. */
4220     i = get_refcount((IUnknown *)shader);
4221     hr = IDirect3DDevice9_SetVertexShader(device, shader);
4222     refcount = get_refcount((IUnknown *)shader);
4223     ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4224     ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4225
4226     /* GetVertexShader() should increase the shader's refcount by one. */
4227     i = refcount + 1;
4228     hr = IDirect3DDevice9_GetVertexShader(device, &current_shader);
4229     refcount = get_refcount((IUnknown *)shader);
4230     ok(SUCCEEDED(hr), "Failed to get vertex shader, hr %#x.\n", hr);
4231     ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4232     ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4233     IDirect3DVertexShader9_Release(current_shader);
4234
4235     IDirect3DVertexShader9_Release(shader);
4236     refcount = IDirect3DDevice9_Release(device);
4237     ok(!refcount, "Device has %u references left.\n", refcount);
4238     IDirect3D9_Release(d3d);
4239     DestroyWindow(window);
4240 }
4241
4242 static void test_vertex_shader_constant(void)
4243 {
4244     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};
4245     static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4246     IDirect3DDevice9 *device;
4247     IDirect3D9 *d3d;
4248     ULONG refcount;
4249     D3DCAPS9 caps;
4250     DWORD consts;
4251     HWND window;
4252     HRESULT hr;
4253
4254     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4255     {
4256         skip("Failed to create D3D object, skipping tests.\n");
4257         return;
4258     }
4259
4260     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4261             0, 0, 640, 480, 0, 0, 0, 0);
4262     if (!(device = create_device(d3d, window, window, TRUE)))
4263     {
4264         skip("Failed to create a D3D device, skipping tests.\n");
4265         IDirect3D9_Release(d3d);
4266         DestroyWindow(window);
4267         return;
4268     }
4269
4270     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4271     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4272     if (!(caps.VertexShaderVersion & 0xffff))
4273     {
4274         skip("No vertex shader support, skipping tests.\n");
4275         IDirect3DDevice9_Release(device);
4276         IDirect3D9_Release(d3d);
4277         DestroyWindow(window);
4278         return;
4279     }
4280     consts = caps.MaxVertexShaderConst;
4281
4282     /* A simple check that the stuff works at all. */
4283     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c, 1);
4284     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4285
4286     /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4
4287      * consts from MAX - 1. */
4288     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, c, 1);
4289     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4290     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 0, c, 1);
4291     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4292     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts + 1, c, 1);
4293     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4294     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, consts - 1, d, 4);
4295     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4296
4297     /* Constant -1. */
4298     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, -1, c, 1);
4299     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4300
4301     refcount = IDirect3DDevice9_Release(device);
4302     ok(!refcount, "Device has %u references left.\n", refcount);
4303     IDirect3D9_Release(d3d);
4304     DestroyWindow(window);
4305 }
4306
4307 static void test_get_set_pixel_shader(void)
4308 {
4309     IDirect3DPixelShader9 *current_shader = NULL;
4310     IDirect3DPixelShader9 *shader = NULL;
4311     IDirect3DDevice9 *device;
4312     ULONG refcount, i;
4313     IDirect3D9 *d3d;
4314     D3DCAPS9 caps;
4315     HWND window;
4316     HRESULT hr;
4317
4318     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4319     {
4320         skip("Failed to create D3D object, skipping tests.\n");
4321         return;
4322     }
4323
4324     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4325             0, 0, 640, 480, 0, 0, 0, 0);
4326     if (!(device = create_device(d3d, window, window, TRUE)))
4327     {
4328         skip("Failed to create a D3D device, skipping tests.\n");
4329         IDirect3D9_Release(d3d);
4330         DestroyWindow(window);
4331         return;
4332     }
4333
4334     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4335     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4336     if (!(caps.PixelShaderVersion & 0xffff))
4337     {
4338         skip("No pixel shader support, skipping tests.\n");
4339         IDirect3DDevice9_Release(device);
4340         IDirect3D9_Release(d3d);
4341         DestroyWindow(window);
4342         return;
4343     }
4344
4345     hr = IDirect3DDevice9_CreatePixelShader(device, simple_ps, &shader);
4346     ok(SUCCEEDED(hr), "Failed to create shader, hr %#x.\n", hr);
4347     ok(!!shader, "Got unexpected shader %p.\n", shader);
4348
4349     /* SetPixelShader() should not touch the shader's refcount. */
4350     i = get_refcount((IUnknown *)shader);
4351     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4352     refcount = get_refcount((IUnknown *)shader);
4353     ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4354     ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4355
4356     /* GetPixelShader() should increase the shader's refcount by one. */
4357     i = refcount + 1;
4358     hr = IDirect3DDevice9_GetPixelShader(device, &current_shader);
4359     refcount = get_refcount((IUnknown *)shader);
4360     ok(SUCCEEDED(hr), "Failed to get pixel shader, hr %#x.\n", hr);
4361     ok(refcount == i, "Got unexpected refcount %u, expected %u.\n", refcount, i);
4362     ok(current_shader == shader, "Got unexpected shader %p, expected %p.\n", current_shader, shader);
4363     IDirect3DPixelShader9_Release(current_shader);
4364
4365     IDirect3DPixelShader9_Release(shader);
4366     refcount = IDirect3DDevice9_Release(device);
4367     ok(!refcount, "Device has %u references left.\n", refcount);
4368     IDirect3D9_Release(d3d);
4369     DestroyWindow(window);
4370 }
4371
4372 static void test_pixel_shader_constant(void)
4373 {
4374     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};
4375     static const float c[4] = {0.0, 0.0, 0.0, 0.0};
4376     IDirect3DDevice9 *device;
4377     DWORD consts = 0;
4378     IDirect3D9 *d3d;
4379     ULONG refcount;
4380     D3DCAPS9 caps;
4381     HWND window;
4382     HRESULT hr;
4383
4384     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4385     {
4386         skip("Failed to create D3D object, skipping tests.\n");
4387         return;
4388     }
4389
4390     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4391             0, 0, 640, 480, 0, 0, 0, 0);
4392     if (!(device = create_device(d3d, window, window, TRUE)))
4393     {
4394         skip("Failed to create a D3D device, skipping tests.\n");
4395         IDirect3D9_Release(d3d);
4396         DestroyWindow(window);
4397         return;
4398     }
4399
4400     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4401     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4402     if (!(caps.PixelShaderVersion & 0xffff))
4403     {
4404         skip("No pixel shader support, skipping tests.\n");
4405         IDirect3DDevice9_Release(device);
4406         IDirect3D9_Release(d3d);
4407         DestroyWindow(window);
4408         return;
4409     }
4410
4411     /* A simple check that the stuff works at all. */
4412     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, c, 1);
4413     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4414
4415     /* Is there really no max pixel shader constant value??? Test how far I can go. */
4416     while (SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device, consts++, c, 1)));
4417     consts = consts - 1;
4418     trace("SetPixelShaderConstantF was able to set %u shader constants.\n", consts);
4419
4420     /* Test corner cases: Write 4 consts from MAX - 1, everything else is
4421      * pointless given the way the constant limit was determined. */
4422     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, consts - 1, d, 4);
4423     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4424
4425     /* Constant -1. */
4426     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, -1, c, 1);
4427     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4428
4429     refcount = IDirect3DDevice9_Release(device);
4430     ok(!refcount, "Device has %u references left.\n", refcount);
4431     IDirect3D9_Release(d3d);
4432     DestroyWindow(window);
4433 }
4434
4435 static void test_wrong_shader(void)
4436 {
4437     static const DWORD vs_3_0[] =
4438     {
4439         0xfffe0300,                             /* vs_3_0               */
4440         0x0200001f, 0x80000000, 0x900f0000,     /* dcl_position v0      */
4441         0x0200001f, 0x80000000, 0xe00f0000,     /* dcl_position o0      */
4442         0x02000001, 0xe00f0000, 0x90e40000,     /* mov o0, v0           */
4443         0x0000ffff,                             /* end                  */
4444     };
4445
4446 #if 0
4447 float4 main(const float4 color : COLOR) : SV_TARGET
4448 {
4449     float4 o;
4450
4451     o = color;
4452
4453     return o;
4454 }
4455 #endif
4456     static const DWORD ps_4_0[] =
4457     {
4458         0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac, 0x00000005,
4459         0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452, 0x00000050, 0x00000000,
4460         0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
4461         0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e,
4462         0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
4463         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
4464         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
4465         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
4466         0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x001020f2,
4467         0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
4468         0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
4469         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4470         0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4471         0x00000000, 0x00000000, 0x00000000,
4472     };
4473
4474     IDirect3DVertexShader9 *vs = NULL;
4475     IDirect3DPixelShader9 *ps = NULL;
4476     IDirect3DDevice9 *device;
4477     IDirect3D9 * d3d;
4478     ULONG refcount;
4479     D3DCAPS9 caps;
4480     HWND window;
4481     HRESULT hr;
4482
4483     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4484     {
4485         skip("Failed to create D3D object, skipping tests.\n");
4486         return;
4487     }
4488
4489     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4490             0, 0, 640, 480, 0, 0, 0, 0);
4491     if (!(device = create_device(d3d, window, window, TRUE)))
4492     {
4493         skip("Failed to create a D3D device, skipping tests.\n");
4494         IDirect3D9_Release(d3d);
4495         DestroyWindow(window);
4496         return;
4497     }
4498
4499     /* These should always fail, regardless of supported shader version. */
4500     hr = IDirect3DDevice9_CreateVertexShader(device, simple_ps, &vs);
4501     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4502     hr = IDirect3DDevice9_CreatePixelShader(device, simple_vs, &ps);
4503     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4504     hr = IDirect3DDevice9_CreatePixelShader(device, ps_4_0, &ps);
4505     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4506
4507     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4508     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4509     if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
4510     {
4511         hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_0, &vs);
4512         ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4513     }
4514     else
4515         skip("This GPU supports SM3, skipping unsupported shader test.\n");
4516
4517     refcount = IDirect3DDevice9_Release(device);
4518     ok(!refcount, "Device has %u references left.\n", refcount);
4519     IDirect3D9_Release(d3d);
4520     DestroyWindow(window);
4521 }
4522
4523 /* Test the default texture stage state values */
4524 static void test_texture_stage_states(void)
4525 {
4526     IDirect3DDevice9 *device;
4527     IDirect3D9 *d3d;
4528     unsigned int i;
4529     ULONG refcount;
4530     D3DCAPS9 caps;
4531     DWORD value;
4532     HWND window;
4533     HRESULT hr;
4534
4535     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4536     {
4537         skip("Failed to create D3D object, skipping tests.\n");
4538         return;
4539     }
4540
4541     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4542             0, 0, 640, 480, 0, 0, 0, 0);
4543     if (!(device = create_device(d3d, window, window, TRUE)))
4544     {
4545         skip("Failed to create a D3D device, skipping tests.\n");
4546         IDirect3D9_Release(d3d);
4547         DestroyWindow(window);
4548         return;
4549     }
4550
4551     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4552     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4553
4554     for (i = 0; i < caps.MaxTextureBlendStages; ++i)
4555     {
4556         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLOROP, &value);
4557         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4558         ok(value == (i ? D3DTOP_DISABLE : D3DTOP_MODULATE),
4559                 "Got unexpected value %#x for D3DTSS_COLOROP, stage %u.\n", value, i);
4560         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG1, &value);
4561         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4562         ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_COLORARG1, stage %u.\n", value, i);
4563         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG2, &value);
4564         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4565         ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG2, stage %u.\n", value, i);
4566         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAOP, &value);
4567         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4568         ok(value == (i ? D3DTOP_DISABLE : D3DTOP_SELECTARG1),
4569                 "Got unexpected value %#x for D3DTSS_ALPHAOP, stage %u.\n", value, i);
4570         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG1, &value);
4571         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4572         ok(value == D3DTA_TEXTURE, "Got unexpected value %#x for D3DTSS_ALPHAARG1, stage %u.\n", value, i);
4573         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG2, &value);
4574         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4575         ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG2, stage %u.\n", value, i);
4576         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT00, &value);
4577         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4578         ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT00, stage %u.\n", value, i);
4579         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT01, &value);
4580         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4581         ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT01, stage %u.\n", value, i);
4582         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT10, &value);
4583         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4584         ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT10, stage %u.\n", value, i);
4585         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVMAT11, &value);
4586         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4587         ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVMAT11, stage %u.\n", value, i);
4588         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXCOORDINDEX, &value);
4589         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4590         ok(value == i, "Got unexpected value %#x for D3DTSS_TEXCOORDINDEX, stage %u.\n", value, i);
4591         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLSCALE, &value);
4592         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4593         ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLSCALE, stage %u.\n", value, i);
4594         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_BUMPENVLOFFSET, &value);
4595         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4596         ok(!value, "Got unexpected value %#x for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value, i);
4597         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4598         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4599         ok(value == D3DTTFF_DISABLE,
4600                 "Got unexpected value %#x for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value, i);
4601         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_COLORARG0, &value);
4602         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4603         ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_COLORARG0, stage %u.\n", value, i);
4604         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_ALPHAARG0, &value);
4605         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4606         ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_ALPHAARG0, stage %u.\n", value, i);
4607         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_RESULTARG, &value);
4608         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4609         ok(value == D3DTA_CURRENT, "Got unexpected value %#x for D3DTSS_RESULTARG, stage %u.\n", value, i);
4610         hr = IDirect3DDevice9_GetTextureStageState(device, i, D3DTSS_CONSTANT, &value);
4611         ok(SUCCEEDED(hr), "Failed to get texture stage state, hr %#x.\n", hr);
4612         ok(!value, "Got unexpected value %#x for D3DTSS_CONSTANT, stage %u.\n", value, i);
4613     }
4614
4615     refcount = IDirect3DDevice9_Release(device);
4616     ok(!refcount, "Device has %u references left.\n", refcount);
4617     IDirect3D9_Release(d3d);
4618     DestroyWindow(window);
4619 }
4620
4621 static void test_cube_texture_mipmap_gen(IDirect3DDevice9 *device)
4622 {
4623     IDirect3DCubeTexture9 *texture;
4624     IDirect3D9 *d3d;
4625     HRESULT hr;
4626
4627     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
4628     ok(SUCCEEDED(hr), "Failed to get D3D, hr %#x.\n", hr);
4629     hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4630             D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_CUBETEXTURE, D3DFMT_X8R8G8B8);
4631     IDirect3D9_Release(d3d);
4632     if (FAILED(hr))
4633     {
4634         skip("No cube mipmap generation support, skipping tests.\n");
4635         return;
4636     }
4637
4638     hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4639             D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4640     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4641     IDirect3DCubeTexture9_Release(texture);
4642
4643     hr = IDirect3DDevice9_CreateCubeTexture(device, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4644             D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4645     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4646     IDirect3DCubeTexture9_Release(texture);
4647 }
4648
4649 static void test_cube_texture_levels(IDirect3DDevice9 *device)
4650 {
4651     IDirect3DCubeTexture9 *texture;
4652     IDirect3DSurface9 *surface;
4653     D3DSURFACE_DESC desc;
4654     DWORD levels;
4655     HRESULT hr;
4656
4657     if (FAILED(IDirect3DDevice9_CreateCubeTexture(device, 64, 0, 0,
4658             D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL)))
4659     {
4660         skip("Failed to create cube texture, skipping tests.\n");
4661         return;
4662     }
4663
4664     levels = IDirect3DCubeTexture9_GetLevelCount(texture);
4665     ok(levels == 7, "Got unexpected levels %u.\n", levels);
4666
4667     hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels - 1, &desc);
4668     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4669     hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels, &desc);
4670     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4671     hr = IDirect3DCubeTexture9_GetLevelDesc(texture, levels + 1, &desc);
4672     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4673
4674     hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
4675     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4676     IDirect3DSurface9_Release(surface);
4677     hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_NEGATIVE_Z + 1, 0, &surface);
4678     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4679     hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, D3DCUBEMAP_FACE_POSITIVE_X - 1, 0, &surface);
4680     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4681
4682     IDirect3DCubeTexture9_Release(texture);
4683 }
4684
4685 static void test_cube_textures(void)
4686 {
4687     IDirect3DCubeTexture9 *texture;
4688     IDirect3DDevice9 *device;
4689     IDirect3D9 *d3d;
4690     ULONG refcount;
4691     D3DCAPS9 caps;
4692     HWND window;
4693     HRESULT hr;
4694
4695     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4696     {
4697         skip("Failed to create D3D object, skipping tests.\n");
4698         return;
4699     }
4700
4701     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4702             0, 0, 640, 480, 0, 0, 0, 0);
4703     if (!(device = create_device(d3d, window, window, TRUE)))
4704     {
4705         skip("Failed to create a D3D device, skipping tests.\n");
4706         IDirect3D9_Release(d3d);
4707         DestroyWindow(window);
4708         return;
4709     }
4710
4711     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4712     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4713
4714     if (caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
4715     {
4716         hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4717         ok(hr == D3D_OK, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#x.\n", hr);
4718         IDirect3DCubeTexture9_Release(texture);
4719         hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4720         ok(hr == D3D_OK, "Failed to create D3DPOOL_MANAGED cube texture, hr %#x.\n", hr);
4721         IDirect3DCubeTexture9_Release(texture);
4722         hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4723         ok(hr == D3D_OK, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#x.\n", hr);
4724         IDirect3DCubeTexture9_Release(texture);
4725     }
4726     else
4727     {
4728         hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4729         ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_DEFAULT cube texture.\n", hr);
4730         hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4731         ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_MANAGED cube texture.\n", hr);
4732         hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
4733         ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for D3DPOOL_SYSTEMMEM cube texture.\n", hr);
4734     }
4735     hr = IDirect3DDevice9_CreateCubeTexture(device, 512, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH, &texture, NULL);
4736     ok(hr == D3D_OK, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#x.\n", hr);
4737     IDirect3DCubeTexture9_Release(texture);
4738
4739     test_cube_texture_mipmap_gen(device);
4740     test_cube_texture_levels(device);
4741
4742     refcount = IDirect3DDevice9_Release(device);
4743     ok(!refcount, "Device has %u references left.\n", refcount);
4744     IDirect3D9_Release(d3d);
4745     DestroyWindow(window);
4746 }
4747
4748 static void test_mipmap_gen(void)
4749 {
4750     D3DTEXTUREFILTERTYPE filter_type;
4751     IDirect3DTexture9 *texture;
4752     IDirect3DSurface9 *surface;
4753     IDirect3DDevice9 *device;
4754     D3DSURFACE_DESC desc;
4755     D3DLOCKED_RECT lr;
4756     IDirect3D9 *d3d;
4757     ULONG refcount;
4758     unsigned int i;
4759     DWORD levels;
4760     HWND window;
4761     HRESULT hr;
4762
4763     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4764     {
4765         skip("Failed to create D3D object, skipping tests.\n");
4766         return;
4767     }
4768
4769     if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4770             D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)))
4771     {
4772         skip("No mipmap generation support, skipping tests.\n");
4773         IDirect3D9_Release(d3d);
4774         return;
4775     }
4776
4777     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4778             0, 0, 640, 480, 0, 0, 0, 0);
4779     if (!(device = create_device(d3d, window, window, TRUE)))
4780     {
4781         skip("Failed to create a D3D device, skipping tests.\n");
4782         IDirect3D9_Release(d3d);
4783         DestroyWindow(window);
4784         return;
4785     }
4786
4787     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP),
4788             D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
4789     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4790     IDirect3DTexture9_Release(texture);
4791
4792     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP,
4793             D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4794     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4795
4796     filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4797     ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
4798             "Got unexpected filter_type %#x.\n", filter_type);
4799     hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
4800     todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4801     hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
4802     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4803     filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
4804     ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type);
4805     hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
4806     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4807
4808     levels = IDirect3DTexture9_GetLevelCount(texture);
4809     ok(levels == 1, "Got unexpected levels %u.\n", levels);
4810
4811     for (i = 0; i < 6 /* 64 = 2 ^ 6 */; ++i)
4812     {
4813         surface = NULL;
4814         hr = IDirect3DTexture9_GetSurfaceLevel(texture, i, &surface);
4815         ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4816         if (surface)
4817             IDirect3DSurface9_Release(surface);
4818
4819         hr = IDirect3DTexture9_GetLevelDesc(texture, i, &desc);
4820         ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4821
4822         hr = IDirect3DTexture9_LockRect(texture, i, &lr, NULL, 0);
4823         ok(hr == (i ? D3DERR_INVALIDCALL : D3D_OK), "Got unexpected hr %#x for level %u.\n", hr, i);
4824         if (SUCCEEDED(hr))
4825         {
4826             hr = IDirect3DTexture9_UnlockRect(texture, i);
4827             ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
4828         }
4829     }
4830     IDirect3DTexture9_Release(texture);
4831
4832     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 2, D3DUSAGE_AUTOGENMIPMAP,
4833             D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4834     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4835     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 6, D3DUSAGE_AUTOGENMIPMAP,
4836             D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4837     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4838
4839     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_AUTOGENMIPMAP,
4840             D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4841     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4842     levels = IDirect3DTexture9_GetLevelCount(texture);
4843     ok(levels == 1, "Got unexpected levels %u.\n", levels);
4844     IDirect3DTexture9_Release(texture);
4845
4846     refcount = IDirect3DDevice9_Release(device);
4847     ok(!refcount, "Device has %u references left.\n", refcount);
4848     IDirect3D9_Release(d3d);
4849     DestroyWindow(window);
4850 }
4851
4852 static void test_filter(void)
4853 {
4854     static const struct
4855     {
4856         DWORD magfilter, minfilter, mipfilter;
4857         BOOL has_texture;
4858         HRESULT result;
4859     }
4860     tests[] =
4861     {
4862         {D3DTEXF_NONE,   D3DTEXF_NONE,   D3DTEXF_NONE,   FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4863         {D3DTEXF_POINT,  D3DTEXF_NONE,   D3DTEXF_NONE,   FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4864         {D3DTEXF_NONE,   D3DTEXF_POINT,  D3DTEXF_NONE,   FALSE, D3DERR_UNSUPPORTEDTEXTUREFILTER},
4865         {D3DTEXF_POINT,  D3DTEXF_POINT,  D3DTEXF_NONE,   FALSE, D3D_OK                         },
4866         {D3DTEXF_POINT,  D3DTEXF_POINT,  D3DTEXF_POINT,  FALSE, D3D_OK                         },
4867
4868         {D3DTEXF_NONE,   D3DTEXF_NONE,   D3DTEXF_NONE,   TRUE,  D3DERR_UNSUPPORTEDTEXTUREFILTER},
4869         {D3DTEXF_POINT,  D3DTEXF_NONE,   D3DTEXF_NONE,   TRUE,  D3DERR_UNSUPPORTEDTEXTUREFILTER},
4870         {D3DTEXF_POINT,  D3DTEXF_POINT,  D3DTEXF_NONE,   TRUE,  D3D_OK                         },
4871         {D3DTEXF_POINT,  D3DTEXF_POINT,  D3DTEXF_POINT,  TRUE,  D3D_OK                         },
4872
4873         {D3DTEXF_NONE,   D3DTEXF_NONE,   D3DTEXF_NONE,   TRUE,  D3DERR_UNSUPPORTEDTEXTUREFILTER},
4874         {D3DTEXF_LINEAR, D3DTEXF_NONE,   D3DTEXF_NONE,   TRUE,  D3DERR_UNSUPPORTEDTEXTUREFILTER},
4875         {D3DTEXF_LINEAR, D3DTEXF_POINT,  D3DTEXF_NONE,   TRUE,  E_FAIL                         },
4876         {D3DTEXF_POINT,  D3DTEXF_LINEAR, D3DTEXF_NONE,   TRUE,  E_FAIL                         },
4877         {D3DTEXF_POINT,  D3DTEXF_POINT,  D3DTEXF_LINEAR, TRUE,  E_FAIL                         },
4878     };
4879     IDirect3DTexture9 *texture;
4880     IDirect3DDevice9 *device;
4881     IDirect3D9 *d3d;
4882     unsigned int i;
4883     ULONG refcount;
4884     DWORD passes;
4885     HWND window;
4886     HRESULT hr;
4887
4888     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4889     {
4890         skip("Failed to create D3D object, skipping tests.\n");
4891         return;
4892     }
4893
4894     if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4895             0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4896     {
4897         skip("D3DFMT_A32B32G32R32F not supported, skipping tests.\n");
4898         IDirect3D9_Release(d3d);
4899         return;
4900     }
4901
4902     if (SUCCEEDED(hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4903             D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)))
4904     {
4905         skip("D3DFMT_A32B32G32R32F supports filtering, skipping tests.\n");
4906         IDirect3D9_Release(d3d);
4907         return;
4908     }
4909
4910     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4911             0, 0, 640, 480, 0, 0, 0, 0);
4912     if (!(device = create_device(d3d, window, window, TRUE)))
4913     {
4914         skip("Failed to create a D3D device, skipping tests.\n");
4915         IDirect3D9_Release(d3d);
4916         DestroyWindow(window);
4917         return;
4918     }
4919
4920     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, 0,
4921             D3DFMT_A32B32G32R32F, D3DPOOL_MANAGED, &texture, NULL);
4922     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4923
4924     /* Needed for ValidateDevice(). */
4925     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4926     ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4927
4928     for (i = 0; i < (sizeof(tests) / sizeof(*tests)); ++i)
4929     {
4930         if (tests[i].has_texture)
4931         {
4932             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4933             ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4934         }
4935         else
4936         {
4937             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4938             ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4939         }
4940
4941         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, tests[i].magfilter);
4942         ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4943         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, tests[i].minfilter);
4944         ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4945         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, tests[i].mipfilter);
4946         ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4947
4948         passes = 0xdeadbeef;
4949         hr = IDirect3DDevice9_ValidateDevice(device, &passes);
4950         ok(hr == tests[i].result,
4951                 "Got unexpected hr %#x, expected %#x (mag %#x, min %#x, mip %#x, has_texture %#x).\n",
4952                 hr, tests[i].result, tests[i].magfilter, tests[i].minfilter,
4953                 tests[i].mipfilter, tests[i].has_texture);
4954         if (SUCCEEDED(hr))
4955             ok(!!passes, "Got unexpected passes %#x.\n", passes);
4956         else
4957             ok(passes == 0xdeadbeef, "Got unexpected passes %#x.\n", passes);
4958     }
4959
4960     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4961     ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4962     IDirect3DTexture9_Release(texture);
4963
4964     refcount = IDirect3DDevice9_Release(device);
4965     ok(!refcount, "Device has %u references left.\n", refcount);
4966     IDirect3D9_Release(d3d);
4967     DestroyWindow(window);
4968 }
4969
4970 static void test_get_texture(void)
4971 {
4972     IDirect3DBaseTexture9 *texture;
4973     IDirect3DDevice9 *device;
4974     IDirect3D9 *d3d;
4975     ULONG refcount;
4976     HWND window;
4977     HRESULT hr;
4978
4979     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
4980     {
4981         skip("Failed to create D3D object, skipping tests.\n");
4982         return;
4983     }
4984
4985     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
4986             0, 0, 640, 480, 0, 0, 0, 0);
4987     if (!(device = create_device(d3d, window, window, TRUE)))
4988     {
4989         skip("Failed to create a D3D device, skipping tests.\n");
4990         IDirect3D9_Release(d3d);
4991         DestroyWindow(window);
4992         return;
4993     }
4994
4995     texture = (IDirect3DBaseTexture9 *)0xdeadbeef;
4996     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4997     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4998     hr = IDirect3DDevice9_GetTexture(device, 0, &texture);
4999     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5000     ok(!texture, "Got unexpected texture %p.\n", texture);
5001
5002     refcount = IDirect3DDevice9_Release(device);
5003     ok(!refcount, "Device has %u references left.\n", refcount);
5004     IDirect3D9_Release(d3d);
5005     DestroyWindow(window);
5006 }
5007
5008 static void test_lod(void)
5009 {
5010     IDirect3DTexture9 *texture;
5011     IDirect3DDevice9 *device;
5012     IDirect3D9 *d3d;
5013     ULONG refcount;
5014     HWND window;
5015     HRESULT hr;
5016     DWORD ret;
5017
5018     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5019     {
5020         skip("Failed to create D3D object, skipping tests.\n");
5021         return;
5022     }
5023
5024     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5025             0, 0, 640, 480, 0, 0, 0, 0);
5026     if (!(device = create_device(d3d, window, window, TRUE)))
5027     {
5028         skip("Failed to create a D3D device, skipping tests.\n");
5029         IDirect3D9_Release(d3d);
5030         DestroyWindow(window);
5031         return;
5032     }
5033
5034     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
5035             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5036     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5037
5038     /* SetLOD() is only supported on D3DPOOL_MANAGED textures, but doesn't
5039      * return a HRESULT, so it can't return a normal error. Instead, the call
5040      * is simply ignored. */
5041     ret = IDirect3DTexture9_SetLOD(texture, 0);
5042     ok(!ret, "Got unexpected ret %u.\n", ret);
5043     ret = IDirect3DTexture9_SetLOD(texture, 1);
5044     ok(!ret, "Got unexpected ret %u.\n", ret);
5045     ret = IDirect3DTexture9_SetLOD(texture, 2);
5046     ok(!ret, "Got unexpected ret %u.\n", ret);
5047     ret = IDirect3DTexture9_GetLOD(texture);
5048     ok(!ret, "Got unexpected ret %u.\n", ret);
5049
5050     IDirect3DTexture9_Release(texture);
5051     refcount = IDirect3DDevice9_Release(device);
5052     ok(!refcount, "Device has %u references left.\n", refcount);
5053     IDirect3D9_Release(d3d);
5054     DestroyWindow(window);
5055 }
5056
5057 static void test_surface_get_container(void)
5058 {
5059     IDirect3DTexture9 *texture = NULL;
5060     IDirect3DSurface9 *surface = NULL;
5061     IDirect3DDevice9 *device;
5062     IUnknown *container;
5063     IDirect3D9 *d3d;
5064     ULONG refcount;
5065     HWND window;
5066     HRESULT hr;
5067
5068     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5069     {
5070         skip("Failed to create D3D object, skipping tests.\n");
5071         return;
5072     }
5073
5074     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5075             0, 0, 640, 480, 0, 0, 0, 0);
5076     if (!(device = create_device(d3d, window, window, TRUE)))
5077     {
5078         skip("Failed to create a D3D device, skipping tests.\n");
5079         IDirect3D9_Release(d3d);
5080         DestroyWindow(window);
5081         return;
5082     }
5083
5084     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0,
5085             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
5086     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5087     ok(!!texture, "Got unexpected texture %p.\n", texture);
5088
5089     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5090     ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5091     ok(!!surface, "Got unexpected surface %p.\n", surface);
5092
5093     /* These should work... */
5094     container = NULL;
5095     hr = IDirect3DSurface9_GetContainer(surface, &IID_IUnknown, (void **)&container);
5096     ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5097     ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5098     IUnknown_Release(container);
5099
5100     container = NULL;
5101     hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DResource9, (void **)&container);
5102     ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5103     ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5104     IUnknown_Release(container);
5105
5106     container = NULL;
5107     hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DBaseTexture9, (void **)&container);
5108     ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5109     ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5110     IUnknown_Release(container);
5111
5112     container = NULL;
5113     hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **)&container);
5114     ok(SUCCEEDED(hr), "Failed to get surface container, hr %#x.\n", hr);
5115     ok(container == (IUnknown *)texture, "Got unexpected container %p, expected %p.\n", container, texture);
5116     IUnknown_Release(container);
5117
5118     /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5119     hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DSurface9, (void **)&container);
5120     ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
5121     ok(!container, "Got unexpected container %p.\n", container);
5122
5123     IDirect3DSurface9_Release(surface);
5124     IDirect3DTexture9_Release(texture);
5125     refcount = IDirect3DDevice9_Release(device);
5126     ok(!refcount, "Device has %u references left.\n", refcount);
5127     IDirect3D9_Release(d3d);
5128     DestroyWindow(window);
5129 }
5130
5131 static void test_surface_alignment(void)
5132 {
5133     IDirect3DSurface9 *surface;
5134     IDirect3DDevice9 *device;
5135     D3DLOCKED_RECT lr;
5136     unsigned int i, j;
5137     IDirect3D9 *d3d;
5138     ULONG refcount;
5139     HWND window;
5140     HRESULT hr;
5141
5142     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5143     {
5144         skip("Failed to create D3D object, skipping tests.\n");
5145         return;
5146     }
5147
5148     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5149             0, 0, 640, 480, 0, 0, 0, 0);
5150     if (!(device = create_device(d3d, window, window, TRUE)))
5151     {
5152         skip("Failed to create a D3D device, skipping tests.\n");
5153         IDirect3D9_Release(d3d);
5154         DestroyWindow(window);
5155         return;
5156     }
5157
5158     /* Test a sysmem surface because those aren't affected by the hardware's np2 restrictions. */
5159     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 5, 5,
5160             D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
5161     ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5162
5163     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5164     ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5165     ok(!(lr.Pitch & 3), "Got misaligned pitch %d.\n", lr.Pitch);
5166     /* Some applications also depend on the exact pitch, rather than just the
5167      * alignment. */
5168     ok(lr.Pitch == 12, "Got unexpected pitch %d.\n", lr.Pitch);
5169     hr = IDirect3DSurface9_UnlockRect(surface);
5170     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5171     IDirect3DSurface9_Release(surface);
5172
5173     for (i = 0; i < 5; ++i)
5174     {
5175         IDirect3DTexture9 *texture;
5176         unsigned int level_count;
5177         D3DSURFACE_DESC desc;
5178         int expected_pitch;
5179
5180         hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0,
5181                 MAKEFOURCC('D', 'X', 'T', '1' + i), D3DPOOL_MANAGED, &texture, NULL);
5182         ok(SUCCEEDED(hr) || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5183         if (FAILED(hr))
5184         {
5185             skip("DXT%u surfaces are not supported, skipping tests.\n", i + 1);
5186             continue;
5187         }
5188
5189         level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
5190         for (j = 0; j < level_count; ++j)
5191         {
5192             IDirect3DTexture9_GetLevelDesc(texture, j, &desc);
5193             hr = IDirect3DTexture9_LockRect(texture, j, &lr, NULL, 0);
5194             ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5195             hr = IDirect3DTexture9_UnlockRect(texture, j);
5196             ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5197
5198             expected_pitch = ((desc.Width + 3) >> 2) << 3;
5199             if (i > 0)
5200                 expected_pitch <<= 1;
5201             ok(lr.Pitch == expected_pitch, "Got unexpected pitch %d for DXT%u level %u (%ux%u), expected %d.\n",
5202                     lr.Pitch, i + 1, j, desc.Width, desc.Height, expected_pitch);
5203         }
5204         IDirect3DTexture9_Release(texture);
5205     }
5206
5207     refcount = IDirect3DDevice9_Release(device);
5208     ok(!refcount, "Device has %u references left.\n", refcount);
5209     IDirect3D9_Release(d3d);
5210     DestroyWindow(window);
5211 }
5212
5213 /* Since the DXT formats are based on 4x4 blocks, locking works slightly
5214  * different from regular formats. This test verifies we return the correct
5215  * memory offsets. */
5216 static void test_lockrect_offset(void)
5217 {
5218     static const struct
5219     {
5220         D3DFORMAT format;
5221         const char *name;
5222         unsigned int block_width;
5223         unsigned int block_height;
5224         unsigned int block_size;
5225     }
5226     dxt_formats[] =
5227     {
5228         {D3DFMT_DXT1,                 "D3DFMT_DXT1", 4, 4, 8},
5229         {D3DFMT_DXT2,                 "D3DFMT_DXT2", 4, 4, 16},
5230         {D3DFMT_DXT3,                 "D3DFMT_DXT3", 4, 4, 16},
5231         {D3DFMT_DXT4,                 "D3DFMT_DXT4", 4, 4, 16},
5232         {D3DFMT_DXT5,                 "D3DFMT_DXT5", 4, 4, 16},
5233         {MAKEFOURCC('A','T','I','2'), "ATI2N",       1, 1,  1},
5234     };
5235     unsigned int expected_offset, offset, i;
5236     const RECT rect = {60, 60, 68, 68};
5237     IDirect3DSurface9 *surface;
5238     D3DLOCKED_RECT locked_rect;
5239     IDirect3DDevice9 *device;
5240     int expected_pitch;
5241     IDirect3D9 *d3d;
5242     ULONG refcount;
5243     HWND window;
5244     BYTE *base;
5245     HRESULT hr;
5246
5247     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5248     {
5249         skip("Failed to create D3D object, skipping tests.\n");
5250         return;
5251     }
5252
5253     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5254             0, 0, 640, 480, 0, 0, 0, 0);
5255     if (!(device = create_device(d3d, window, window, TRUE)))
5256     {
5257         skip("Failed to create a D3D device, skipping tests.\n");
5258         IDirect3D9_Release(d3d);
5259         DestroyWindow(window);
5260         return;
5261     }
5262
5263     for (i = 0; i < (sizeof(dxt_formats) / sizeof(*dxt_formats)); ++i)
5264     {
5265         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5266                 0, D3DRTYPE_TEXTURE, dxt_formats[i].format)))
5267         {
5268             skip("Format %s not supported, skipping lockrect offset tests.\n", dxt_formats[i].name);
5269             continue;
5270         }
5271
5272         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5273                 dxt_formats[i].format, D3DPOOL_SCRATCH, &surface, NULL);
5274         ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5275
5276         hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5277         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5278
5279         base = locked_rect.pBits;
5280         expected_pitch = (128 + dxt_formats[i].block_height - 1) / dxt_formats[i].block_width
5281                 * dxt_formats[i].block_size;
5282         ok(locked_rect.Pitch == expected_pitch, "Got unexpected pitch %d for format %s, expected %d.\n",
5283                 locked_rect.Pitch, dxt_formats[i].name, expected_pitch);
5284
5285         hr = IDirect3DSurface9_UnlockRect(surface);
5286         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5287
5288         hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5289         ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5290
5291         offset = (BYTE *)locked_rect.pBits - base;
5292         expected_offset = (rect.top / dxt_formats[i].block_height) * expected_pitch
5293                 + (rect.left / dxt_formats[i].block_width) * dxt_formats[i].block_size;
5294         ok(offset == expected_offset, "Got unexpected offset %u for format %s, expected %u.\n",
5295                 offset, dxt_formats[i].name, expected_offset);
5296
5297         hr = IDirect3DSurface9_UnlockRect(surface);
5298         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5299
5300         IDirect3DSurface9_Release(surface);
5301     }
5302
5303     refcount = IDirect3DDevice9_Release(device);
5304     ok(!refcount, "Device has %u references left.\n", refcount);
5305     IDirect3D9_Release(d3d);
5306     DestroyWindow(window);
5307 }
5308
5309 static void test_lockrect_invalid(void)
5310 {
5311     static const struct
5312     {
5313         RECT rect;
5314         HRESULT win7_result;
5315     }
5316     test_data[] =
5317     {
5318         {{60, 60, 68, 68},      D3D_OK},                /* Valid */
5319         {{60, 60, 60, 68},      D3DERR_INVALIDCALL},    /* 0 height */
5320         {{60, 60, 68, 60},      D3DERR_INVALIDCALL},    /* 0 width */
5321         {{68, 60, 60, 68},      D3DERR_INVALIDCALL},    /* left > right */
5322         {{60, 68, 68, 60},      D3DERR_INVALIDCALL},    /* top > bottom */
5323         {{-8, 60,  0, 68},      D3DERR_INVALIDCALL},    /* left < surface */
5324         {{60, -8, 68,  0},      D3DERR_INVALIDCALL},    /* top < surface */
5325         {{-16, 60, -8, 68},     D3DERR_INVALIDCALL},    /* right < surface */
5326         {{60, -16, 68, -8},     D3DERR_INVALIDCALL},    /* bottom < surface */
5327         {{60, 60, 136, 68},     D3DERR_INVALIDCALL},    /* right > surface */
5328         {{60, 60, 68, 136},     D3DERR_INVALIDCALL},    /* bottom > surface */
5329         {{136, 60, 144, 68},    D3DERR_INVALIDCALL},    /* left > surface */
5330         {{60, 136, 68, 144},    D3DERR_INVALIDCALL},    /* top > surface */
5331     };
5332     static const RECT test_rect_2 = {0, 0, 8, 8};
5333     IDirect3DSurface9 *surface = NULL;
5334     D3DLOCKED_RECT locked_rect;
5335     IDirect3DDevice9 *device;
5336     IDirect3D9 *d3d;
5337     unsigned int i;
5338     ULONG refcount;
5339     HWND window;
5340     BYTE *base;
5341     HRESULT hr;
5342
5343     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5344     {
5345         skip("Failed to create D3D object, skipping tests.\n");
5346         return;
5347     }
5348
5349     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5350             0, 0, 640, 480, 0, 0, 0, 0);
5351     if (!(device = create_device(d3d, window, window, TRUE)))
5352     {
5353         skip("Failed to create a D3D device, skipping tests.\n");
5354         IDirect3D9_Release(d3d);
5355         DestroyWindow(window);
5356         return;
5357     }
5358
5359     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5360             D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5361     ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5362     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5363     ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5364     base = locked_rect.pBits;
5365     hr = IDirect3DSurface9_UnlockRect(surface);
5366     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5367
5368     for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i)
5369     {
5370         unsigned int offset, expected_offset;
5371         const RECT *rect = &test_data[i].rect;
5372
5373         locked_rect.pBits = (BYTE *)0xdeadbeef;
5374         locked_rect.Pitch = 0xdeadbeef;
5375
5376         hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0);
5377         /* Windows XP accepts invalid locking rectangles, windows 7 rejects
5378          * them. Some games (C&C3) depend on the XP behavior, mark the Win 7
5379          * one broken. */
5380         ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result),
5381                 "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n",
5382                 rect->left, rect->top, rect->right, rect->bottom, hr);
5383         if (FAILED(hr))
5384             continue;
5385
5386         offset = (BYTE *)locked_rect.pBits - base;
5387         expected_offset = rect->top * locked_rect.Pitch + rect->left * 4;
5388         ok(offset == expected_offset,
5389                 "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n",
5390                 offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom);
5391
5392         hr = IDirect3DSurface9_UnlockRect(surface);
5393         ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5394     }
5395
5396     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5397     ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr);
5398     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5399     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5400     hr = IDirect3DSurface9_UnlockRect(surface);
5401     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5402
5403     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5404     ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5405             hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5406     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0);
5407     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5408             hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom);
5409     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0);
5410     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n",
5411             hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom);
5412     hr = IDirect3DSurface9_UnlockRect(surface);
5413     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5414
5415     IDirect3DSurface9_Release(surface);
5416     refcount = IDirect3DDevice9_Release(device);
5417     ok(!refcount, "Device has %u references left.\n", refcount);
5418     IDirect3D9_Release(d3d);
5419     DestroyWindow(window);
5420 }
5421
5422 static void test_private_data(void)
5423 {
5424     ULONG refcount, expected_refcount;
5425     IDirect3DSurface9 *surface;
5426     IDirect3DDevice9 *device;
5427     IDirect3D9 *d3d;
5428     IUnknown *ptr;
5429     HWND window;
5430     HRESULT hr;
5431     DWORD size;
5432
5433     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5434     {
5435         skip("Failed to create D3D object, skipping tests.\n");
5436         return;
5437     }
5438
5439     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5440             0, 0, 640, 480, 0, 0, 0, 0);
5441     if (!(device = create_device(d3d, window, window, TRUE)))
5442     {
5443         skip("Failed to create a D3D device, skipping tests.\n");
5444         IDirect3D9_Release(d3d);
5445         DestroyWindow(window);
5446         return;
5447     }
5448
5449     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4,
5450             D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5451     ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5452
5453     hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5454             device, 0, D3DSPD_IUNKNOWN);
5455     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5456     hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5457             device, 5, D3DSPD_IUNKNOWN);
5458     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5459     hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5460             device, sizeof(IUnknown *) * 2, D3DSPD_IUNKNOWN);
5461     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5462
5463     refcount = get_refcount((IUnknown *)device);
5464     hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9 /* Abuse this tag */,
5465             device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5466     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5467     expected_refcount = refcount + 1;
5468     refcount = get_refcount((IUnknown *)device);
5469     ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5470     hr = IDirect3DSurface9_FreePrivateData(surface, &IID_IDirect3DSurface9);
5471     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5472     expected_refcount = refcount - 1;
5473     refcount = get_refcount((IUnknown *)device);
5474     ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5475
5476     hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5477             device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5478     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5479     hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5480             surface, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5481     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5482     refcount = get_refcount((IUnknown *)device);
5483     ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5484
5485     hr = IDirect3DSurface9_SetPrivateData(surface, &IID_IDirect3DSurface9,
5486             device, sizeof(IUnknown *), D3DSPD_IUNKNOWN);
5487     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5488     size = sizeof(ptr);
5489     hr = IDirect3DSurface9_GetPrivateData(surface, &IID_IDirect3DSurface9, &ptr, &size);
5490     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
5491     expected_refcount = refcount + 2;
5492     refcount = get_refcount((IUnknown *)device);
5493     ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5494     ok(ptr == (IUnknown *)device, "Got unexpected ptr %p, expected %p.\n", ptr, device);
5495     IUnknown_Release(ptr);
5496
5497     /* Destroying the surface frees the held reference. */
5498     IDirect3DSurface9_Release(surface);
5499     expected_refcount = refcount - 3;
5500     refcount = get_refcount((IUnknown *)device);
5501     ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
5502
5503     refcount = IDirect3DDevice9_Release(device);
5504     ok(!refcount, "Device has %u references left.\n", refcount);
5505     IDirect3D9_Release(d3d);
5506     DestroyWindow(window);
5507 }
5508
5509 static void test_getdc(void)
5510 {
5511     static const struct
5512     {
5513         const char *name;
5514         D3DFORMAT format;
5515         BOOL getdc_supported;
5516     }
5517     testdata[] =
5518     {
5519         {"D3DFMT_A8R8G8B8",    D3DFMT_A8R8G8B8,    TRUE },
5520         {"D3DFMT_X8R8G8B8",    D3DFMT_X8R8G8B8,    TRUE },
5521         {"D3DFMT_R5G6B5",      D3DFMT_R5G6B5,      TRUE },
5522         {"D3DFMT_X1R5G5B5",    D3DFMT_X1R5G5B5,    TRUE },
5523         {"D3DFMT_A1R5G5B5",    D3DFMT_A1R5G5B5,    TRUE },
5524         {"D3DFMT_R8G8B8",      D3DFMT_R8G8B8,      TRUE },
5525         {"D3DFMT_A2R10G10B10", D3DFMT_A2R10G10B10, FALSE}, /* Untested, card on windows didn't support it. */
5526         {"D3DFMT_V8U8",        D3DFMT_V8U8,        FALSE},
5527         {"D3DFMT_Q8W8V8U8",    D3DFMT_Q8W8V8U8,    FALSE},
5528         {"D3DFMT_A8B8G8R8",    D3DFMT_A8B8G8R8,    FALSE},
5529         {"D3DFMT_X8B8G8R8",    D3DFMT_A8B8G8R8,    FALSE},
5530         {"D3DFMT_R3G3B2",      D3DFMT_R3G3B2,      FALSE},
5531         {"D3DFMT_P8",          D3DFMT_P8,          FALSE},
5532         {"D3DFMT_L8",          D3DFMT_L8,          FALSE},
5533         {"D3DFMT_A8L8",        D3DFMT_A8L8,        FALSE},
5534         {"D3DFMT_DXT1",        D3DFMT_DXT1,        FALSE},
5535         {"D3DFMT_DXT2",        D3DFMT_DXT2,        FALSE},
5536         {"D3DFMT_DXT3",        D3DFMT_DXT3,        FALSE},
5537         {"D3DFMT_DXT4",        D3DFMT_DXT4,        FALSE},
5538         {"D3DFMT_DXT5",        D3DFMT_DXT5,        FALSE},
5539     };
5540     IDirect3DTexture9 *texture;
5541     IDirect3DSurface9 *surface;
5542     IDirect3DDevice9 *device;
5543     IDirect3D9 *d3d;
5544     unsigned int i;
5545     ULONG refcount;
5546     HWND window;
5547     HRESULT hr;
5548     HDC dc;
5549
5550     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5551     {
5552         skip("Failed to create D3D object, skipping tests.\n");
5553         return;
5554     }
5555
5556     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5557             0, 0, 640, 480, 0, 0, 0, 0);
5558     if (!(device = create_device(d3d, window, window, TRUE)))
5559     {
5560         skip("Failed to create a D3D device, skipping tests.\n");
5561         IDirect3D9_Release(d3d);
5562         DestroyWindow(window);
5563         return;
5564     }
5565
5566     for (i = 0; i < (sizeof(testdata) / sizeof(*testdata)); ++i)
5567     {
5568         texture = NULL;
5569         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5570                 testdata[i].format, D3DPOOL_SYSTEMMEM, &surface, NULL);
5571         if (FAILED(hr))
5572         {
5573             hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0,
5574                     testdata[i].format, D3DPOOL_MANAGED, &texture, NULL);
5575             if (FAILED(hr))
5576             {
5577                 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", testdata[i].name, hr);
5578                 continue;
5579             }
5580             hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5581             ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5582         }
5583
5584         dc = (void *)0x1234;
5585         hr = IDirect3DSurface9_GetDC(surface, &dc);
5586         if (testdata[i].getdc_supported)
5587             ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5588         else
5589             ok(FAILED(hr), "Got unexpected hr %#x for format %s.\n", hr, testdata[i].name);
5590
5591         if (SUCCEEDED(hr))
5592         {
5593             hr = IDirect3DSurface9_ReleaseDC(surface, dc);
5594             ok(hr == D3D_OK, "Failed to release DC, hr %#x.\n", hr);
5595         }
5596         else
5597         {
5598             ok(dc == (void *)0x1234, "Got unexpected dc %p.\n", dc);
5599         }
5600
5601         IDirect3DSurface9_Release(surface);
5602         if (texture)
5603             IDirect3DTexture9_Release(texture);
5604     }
5605
5606     refcount = IDirect3DDevice9_Release(device);
5607     ok(!refcount, "Device has %u references left.\n", refcount);
5608     IDirect3D9_Release(d3d);
5609     DestroyWindow(window);
5610 }
5611
5612 static void test_surface_dimensions(void)
5613 {
5614     IDirect3DSurface9 *surface;
5615     IDirect3DDevice9 *device;
5616     IDirect3D9 *d3d;
5617     ULONG refcount;
5618     HWND window;
5619     HRESULT hr;
5620
5621     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5622     {
5623         skip("Failed to create D3D object, skipping tests.\n");
5624         return;
5625     }
5626
5627     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5628             0, 0, 640, 480, 0, 0, 0, 0);
5629     if (!(device = create_device(d3d, window, window, TRUE)))
5630     {
5631         skip("Failed to create a D3D device, skipping tests.\n");
5632         IDirect3D9_Release(d3d);
5633         DestroyWindow(window);
5634         return;
5635     }
5636
5637     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 0, 1,
5638             D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5639     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5640     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 1, 0,
5641             D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
5642     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
5643
5644     refcount = IDirect3DDevice9_Release(device);
5645     ok(!refcount, "Device has %u references left.\n", refcount);
5646     IDirect3D9_Release(d3d);
5647     DestroyWindow(window);
5648 }
5649
5650 static void test_surface_format_null(void)
5651 {
5652     static const D3DFORMAT D3DFMT_NULL = MAKEFOURCC('N','U','L','L');
5653     IDirect3DTexture9 *texture;
5654     IDirect3DSurface9 *surface;
5655     IDirect3DSurface9 *rt, *ds;
5656     D3DLOCKED_RECT locked_rect;
5657     IDirect3DDevice9 *device;
5658     D3DSURFACE_DESC desc;
5659     IDirect3D9 *d3d;
5660     ULONG refcount;
5661     HWND window;
5662     HRESULT hr;
5663
5664     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5665     {
5666         skip("Failed to create D3D object, skipping tests.\n");
5667         return;
5668     }
5669
5670     hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5671             D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL);
5672     if (hr != D3D_OK)
5673     {
5674         skip("No D3DFMT_NULL support, skipping test.\n");
5675         IDirect3D9_Release(d3d);
5676         return;
5677     }
5678
5679     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5680             0, 0, 640, 480, 0, 0, 0, 0);
5681     if (!(device = create_device(d3d, window, window, TRUE)))
5682     {
5683         skip("Failed to create a D3D device, skipping tests.\n");
5684         IDirect3D9_Release(d3d);
5685         DestroyWindow(window);
5686         return;
5687     }
5688
5689     hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5690             D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_NULL);
5691     ok(hr == D3D_OK, "D3DFMT_NULL should be supported for render target textures, hr %#x.\n", hr);
5692
5693     hr = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5694             D3DFMT_NULL, D3DFMT_D24S8);
5695     ok(SUCCEEDED(hr), "Depth stencil match failed for D3DFMT_NULL, hr %#x.\n", hr);
5696
5697     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_NULL,
5698             D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
5699     ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5700
5701     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
5702     ok(SUCCEEDED(hr), "Failed to get original render target, hr %#x.\n", hr);
5703
5704     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
5705     ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
5706
5707     hr = IDirect3DDevice9_SetRenderTarget(device, 0, NULL);
5708     ok(FAILED(hr), "Succeeded in setting render target 0 to NULL, should fail.\n");
5709
5710     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
5711     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5712
5713     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
5714     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5715
5716     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
5717     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
5718
5719     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
5720     ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
5721
5722     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
5723     ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
5724
5725     IDirect3DSurface9_Release(rt);
5726     IDirect3DSurface9_Release(ds);
5727
5728     hr = IDirect3DSurface9_GetDesc(surface, &desc);
5729     ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5730     ok(desc.Width == 128, "Expected width 128, got %u.\n", desc.Width);
5731     ok(desc.Height == 128, "Expected height 128, got %u.\n", desc.Height);
5732
5733     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
5734     ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5735     ok(locked_rect.Pitch, "Expected non-zero pitch, got %u.\n", locked_rect.Pitch);
5736     ok(!!locked_rect.pBits, "Expected non-NULL pBits, got %p.\n", locked_rect.pBits);
5737
5738     hr = IDirect3DSurface9_UnlockRect(surface);
5739     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5740
5741     IDirect3DSurface9_Release(surface);
5742
5743     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 0, D3DUSAGE_RENDERTARGET,
5744             D3DFMT_NULL, D3DPOOL_DEFAULT, &texture, NULL);
5745     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5746     IDirect3DTexture9_Release(texture);
5747
5748     refcount = IDirect3DDevice9_Release(device);
5749     ok(!refcount, "Device has %u references left.\n", refcount);
5750     IDirect3D9_Release(d3d);
5751     DestroyWindow(window);
5752 }
5753
5754 static void test_surface_double_unlock(void)
5755 {
5756     static const D3DPOOL pools[] =
5757     {
5758         D3DPOOL_DEFAULT,
5759         D3DPOOL_SCRATCH,
5760         D3DPOOL_SYSTEMMEM,
5761     };
5762     IDirect3DSurface9 *surface;
5763     IDirect3DDevice9 *device;
5764     D3DLOCKED_RECT lr;
5765     IDirect3D9 *d3d;
5766     unsigned int i;
5767     ULONG refcount;
5768     HWND window;
5769     HRESULT hr;
5770
5771     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5772     {
5773         skip("Failed to create D3D object, skipping tests.\n");
5774         return;
5775     }
5776
5777     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5778             0, 0, 640, 480, 0, 0, 0, 0);
5779     if (!(device = create_device(d3d, window, window, TRUE)))
5780     {
5781         skip("Failed to create a D3D device, skipping tests.\n");
5782         IDirect3D9_Release(d3d);
5783         DestroyWindow(window);
5784         return;
5785     }
5786
5787     for (i = 0; i < (sizeof(pools) / sizeof(*pools)); ++i)
5788     {
5789         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
5790                 D3DFMT_X8R8G8B8, pools[i], &surface, NULL);
5791         ok(SUCCEEDED(hr), "Failed to create surface in pool %#x, hr %#x.\n", pools[i], hr);
5792
5793         hr = IDirect3DSurface9_UnlockRect(surface);
5794         ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5795         hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5796         ok(SUCCEEDED(hr), "Failed to lock surface in pool %#x, hr %#x.\n", pools[i], hr);
5797         hr = IDirect3DSurface9_UnlockRect(surface);
5798         ok(SUCCEEDED(hr), "Failed to unlock surface in pool %#x, hr %#x.\n", pools[i], hr);
5799         hr = IDirect3DSurface9_UnlockRect(surface);
5800         ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, for surface in pool %#x.\n", hr, pools[i]);
5801
5802         IDirect3DSurface9_Release(surface);
5803     }
5804
5805     refcount = IDirect3DDevice9_Release(device);
5806     ok(!refcount, "Device has %u references left.\n", refcount);
5807     IDirect3D9_Release(d3d);
5808     DestroyWindow(window);
5809 }
5810
5811 static void test_surface_lockrect_blocks(void)
5812 {
5813     static const struct
5814     {
5815         D3DFORMAT fmt;
5816         const char *name;
5817         unsigned int block_width;
5818         unsigned int block_height;
5819         BOOL broken;
5820     }
5821     formats[] =
5822     {
5823         {D3DFMT_DXT1,                 "D3DFMT_DXT1", 4, 4, FALSE},
5824         {D3DFMT_DXT2,                 "D3DFMT_DXT2", 4, 4, FALSE},
5825         {D3DFMT_DXT3,                 "D3DFMT_DXT3", 4, 4, FALSE},
5826         {D3DFMT_DXT4,                 "D3DFMT_DXT4", 4, 4, FALSE},
5827         {D3DFMT_DXT5,                 "D3DFMT_DXT5", 4, 4, FALSE},
5828         /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
5829          * which doesn't match the format spec. On newer Nvidia cards
5830          * it has the correct 4x4 block size */
5831         {MAKEFOURCC('A','T','I','2'), "ATI2N",       4, 4, TRUE},
5832         {D3DFMT_YUY2,                 "D3DFMT_YUY2", 2, 1, FALSE},
5833         {D3DFMT_UYVY,                 "D3DFMT_UYVY", 2, 1, FALSE},
5834     };
5835     static const struct
5836     {
5837         D3DPOOL pool;
5838         const char *name;
5839         /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
5840          * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
5841         BOOL success;
5842     }
5843     pools[] =
5844     {
5845         {D3DPOOL_DEFAULT,       "D3DPOOL_DEFAULT",  FALSE},
5846         {D3DPOOL_SCRATCH,       "D3DPOOL_SCRATCH",  TRUE},
5847         {D3DPOOL_SYSTEMMEM,     "D3DPOOL_SYSTEMMEM",TRUE},
5848         {D3DPOOL_MANAGED,       "D3DPOOL_MANAGED",  TRUE},
5849     };
5850     IDirect3DTexture9 *texture;
5851     IDirect3DSurface9 *surface;
5852     D3DLOCKED_RECT locked_rect;
5853     IDirect3DDevice9 *device;
5854     unsigned int i, j;
5855     BOOL surface_only;
5856     IDirect3D9 *d3d;
5857     ULONG refcount;
5858     HWND window;
5859     HRESULT hr;
5860     RECT rect;
5861
5862     if (!(d3d = pDirect3DCreate9(D3D_SDK_VERSION)))
5863     {
5864         skip("Failed to create D3D object, skipping tests.\n");
5865         return;
5866     }
5867
5868     window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW,
5869             0, 0, 640, 480, 0, 0, 0, 0);
5870     if (!(device = create_device(d3d, window, window, TRUE)))
5871     {
5872         skip("Failed to create a D3D device, skipping tests.\n");
5873         IDirect3D9_Release(d3d);
5874         DestroyWindow(window);
5875         return;
5876     }
5877
5878     for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
5879     {
5880         surface_only = FALSE;
5881         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5882                 D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, formats[i].fmt)))
5883         {
5884             if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5885                     0, D3DRTYPE_SURFACE, formats[i].fmt)))
5886             {
5887                 skip("Format %s not supported, skipping lockrect offset tests.\n", formats[i].name);
5888                 continue;
5889             }
5890             surface_only = TRUE;
5891         }
5892
5893         for (j = 0; j < (sizeof(pools) / sizeof(*pools)); ++j)
5894         {
5895             switch (pools[j].pool)
5896             {
5897                 case D3DPOOL_SYSTEMMEM:
5898                 case D3DPOOL_MANAGED:
5899                     if (surface_only)
5900                         continue;
5901                     /* Fall through */
5902                 case D3DPOOL_DEFAULT:
5903                     if (surface_only)
5904                     {
5905                         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5906                                 formats[i].fmt, pools[j].pool, &surface, NULL);
5907                         ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5908                     }
5909                     else
5910                     {
5911                         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1,
5912                                 pools[j].pool == D3DPOOL_DEFAULT ? D3DUSAGE_DYNAMIC : 0,
5913                                 formats[i].fmt, pools[j].pool, &texture, NULL);
5914                         ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5915                         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5916                         ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5917                         IDirect3DTexture9_Release(texture);
5918                     }
5919                     break;
5920
5921                 case D3DPOOL_SCRATCH:
5922                     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
5923                             formats[i].fmt, pools[j].pool, &surface, NULL);
5924                     ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5925                     break;
5926
5927                 default:
5928                     break;
5929             }
5930
5931             if (formats[i].block_width > 1)
5932             {
5933                 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
5934                 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5935                 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5936                         "Partial block lock %s, expected %s, format %s, pool %s.\n",
5937                         SUCCEEDED(hr) ? "succeeded" : "failed",
5938                         pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5939                 if (SUCCEEDED(hr))
5940                 {
5941                     hr = IDirect3DSurface9_UnlockRect(surface);
5942                     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5943                 }
5944
5945                 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
5946                 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5947                 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5948                         "Partial block lock %s, expected %s, format %s, pool %s.\n",
5949                         SUCCEEDED(hr) ? "succeeded" : "failed",
5950                         pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5951                 if (SUCCEEDED(hr))
5952                 {
5953                     hr = IDirect3DSurface9_UnlockRect(surface);
5954                     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5955                 }
5956             }
5957
5958             if (formats[i].block_height > 1)
5959             {
5960                 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
5961                 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5962                 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5963                         "Partial block lock %s, expected %s, format %s, pool %s.\n",
5964                         SUCCEEDED(hr) ? "succeeded" : "failed",
5965                         pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5966                 if (SUCCEEDED(hr))
5967                 {
5968                     hr = IDirect3DSurface9_UnlockRect(surface);
5969                     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5970                 }
5971
5972                 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
5973                 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5974                 ok(FAILED(hr) == !pools[j].success || broken(formats[i].broken),
5975                         "Partial block lock %s, expected %s, format %s, pool %s.\n",
5976                         SUCCEEDED(hr) ? "succeeded" : "failed",
5977                         pools[j].success ? "success" : "failure", formats[i].name, pools[j].name);
5978                 if (SUCCEEDED(hr))
5979                 {
5980                     hr = IDirect3DSurface9_UnlockRect(surface);
5981                     ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5982                 }
5983             }
5984
5985             SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
5986             hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0);
5987             ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name);
5988             hr = IDirect3DSurface9_UnlockRect(surface);
5989             ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5990
5991             IDirect3DSurface9_Release(surface);
5992         }
5993     }
5994
5995     refcount = IDirect3DDevice9_Release(device);
5996     ok(!refcount, "Device has %u references left.\n", refcount);
5997     IDirect3D9_Release(d3d);
5998     DestroyWindow(window);
5999 }
6000
6001 static void test_set_palette(void)
6002 {
6003     IDirect3DDevice9 *device;
6004     IDirect3D9 *d3d9;
6005     UINT refcount;
6006     HWND window;
6007     HRESULT hr;
6008     PALETTEENTRY pal[256];
6009     unsigned int i;
6010     D3DCAPS9 caps;
6011
6012     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6013     {
6014         skip("Failed to create IDirect3D9 object, skipping tests.\n");
6015         return;
6016     }
6017
6018     window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6019             0, 0, 640, 480, 0, 0, 0, 0);
6020     if (!(device = create_device(d3d9, window, window, TRUE)))
6021     {
6022         skip("Failed to create a D3D device, skipping tests.\n");
6023         DestroyWindow(window);
6024         return;
6025     }
6026
6027     for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6028     {
6029         pal[i].peRed = i;
6030         pal[i].peGreen = i;
6031         pal[i].peBlue = i;
6032         pal[i].peFlags = 0xff;
6033     }
6034     hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6035     ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6036
6037     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6038     ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6039     for (i = 0; i < sizeof(pal) / sizeof(*pal); i++)
6040     {
6041         pal[i].peRed = i;
6042         pal[i].peGreen = i;
6043         pal[i].peBlue = i;
6044         pal[i].peFlags = i;
6045     }
6046     if (caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)
6047     {
6048         hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6049         ok(SUCCEEDED(hr), "Failed to set palette entries, hr %#x.\n", hr);
6050     }
6051     else
6052     {
6053         hr = IDirect3DDevice9_SetPaletteEntries(device, 0, pal);
6054         ok(hr == D3DERR_INVALIDCALL, "SetPaletteEntries returned %#x, expected D3DERR_INVALIDCALL.\n", hr);
6055     }
6056
6057     refcount = IDirect3DDevice9_Release(device);
6058     ok(!refcount, "Device has %u references left.\n", refcount);
6059     IDirect3D9_Release(d3d9);
6060     DestroyWindow(window);
6061 }
6062
6063 static void test_swvp_buffer(void)
6064 {
6065     IDirect3DDevice9 *device;
6066     IDirect3D9 *d3d9;
6067     UINT refcount;
6068     HWND window;
6069     HRESULT hr;
6070     unsigned int i;
6071     IDirect3DVertexBuffer9 *buffer;
6072     static const unsigned int bufsize = 1024;
6073     D3DVERTEXBUFFER_DESC desc;
6074     D3DPRESENT_PARAMETERS present_parameters = {0};
6075     struct
6076     {
6077         float x, y, z;
6078     } *ptr, *ptr2;
6079
6080     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6081     {
6082         skip("Failed to create IDirect3D9 object, skipping tests.\n");
6083         return;
6084     }
6085
6086     window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6087             0, 0, 640, 480, 0, 0, 0, 0);
6088
6089     present_parameters.Windowed = TRUE;
6090     present_parameters.hDeviceWindow = window;
6091     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
6092     present_parameters.BackBufferWidth = screen_width;
6093     present_parameters.BackBufferHeight = screen_height;
6094     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
6095     present_parameters.EnableAutoDepthStencil = FALSE;
6096     if (FAILED(IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
6097             D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
6098     {
6099         skip("Failed to create a D3D device, skipping tests.\n");
6100         DestroyWindow(window);
6101         IDirect3D9_Release(d3d9);
6102         return;
6103     }
6104
6105     hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*ptr), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0,
6106             D3DPOOL_DEFAULT, &buffer, NULL);
6107     ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6108     hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc);
6109     ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr);
6110     ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u, expected D3DPOOL_DEFAULT\n", desc.Pool);
6111     ok(desc.Usage == (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY),
6112             "Got usage %u, expected D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY\n", desc.Usage);
6113
6114     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD);
6115     ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6116     for (i = 0; i < bufsize; i++)
6117     {
6118         ptr[i].x = i * 1.0f;
6119         ptr[i].y = i * 2.0f;
6120         ptr[i].z = i * 3.0f;
6121     }
6122     hr = IDirect3DVertexBuffer9_Unlock(buffer);
6123     ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6124
6125     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6126     ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6127     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr));
6128     ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6129     hr = IDirect3DDevice9_BeginScene(device);
6130     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6131     hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
6132     ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6133     hr = IDirect3DDevice9_EndScene(device);
6134     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6135
6136     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, bufsize * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD);
6137     ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6138     ok(ptr == ptr2, "Lock returned two different pointers: %p, %p\n", ptr, ptr2);
6139     for (i = 0; i < bufsize; i++)
6140     {
6141         if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f)
6142         {
6143             ok(FALSE, "Vertex %u is %f,%f,%f, expected %f,%f,%f\n", i,
6144                     ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f);
6145             break;
6146         }
6147     }
6148     hr = IDirect3DVertexBuffer9_Unlock(buffer);
6149     ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6150
6151     IDirect3DVertexBuffer9_Release(buffer);
6152     refcount = IDirect3DDevice9_Release(device);
6153     ok(!refcount, "Device has %u references left.\n", refcount);
6154     IDirect3D9_Release(d3d9);
6155     DestroyWindow(window);
6156 }
6157
6158 static void test_rtpatch(void)
6159 {
6160     IDirect3DDevice9 *device;
6161     IDirect3D9 *d3d9;
6162     UINT refcount;
6163     HWND window;
6164     HRESULT hr;
6165     IDirect3DVertexBuffer9 *buffer;
6166     IDirect3DVertexDeclaration9 *decl;
6167     static const unsigned int bufsize = 16;
6168     struct
6169     {
6170         float x, y, z;
6171     } *data;
6172     D3DRECTPATCH_INFO patch;
6173     static const float num_segs[] = {1.0f, 1.0f, 1.0f, 1.0f};
6174     UINT handle = 0x1234;
6175     D3DCAPS9 caps;
6176
6177     /* Position input, this generates tesselated positions, but do not generate normals
6178      *  or texture coordinates. The d3d documentation isn't clear on how to do this */
6179     static const D3DVERTEXELEMENT9 decl_elements[] = {
6180         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6181         D3DDECL_END()
6182     };
6183
6184     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6185     {
6186         skip("Failed to create IDirect3D9 object, skipping tests.\n");
6187         return;
6188     }
6189
6190     window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6191             0, 0, 640, 480, 0, 0, 0, 0);
6192     if (!(device = create_device(d3d9, window, window, TRUE)))
6193     {
6194         skip("Failed to create a D3D device, skipping tests.\n");
6195         IDirect3D9_Release(d3d9);
6196         DestroyWindow(window);
6197         return;
6198     }
6199
6200     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6201     ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6202     if (caps.DevCaps & D3DDEVCAPS_RTPATCHES)
6203     {
6204         /* The draw methods return the same values, but the patch handle support
6205          * is different on the refrast, which is the only d3d implementation
6206          * known to support tri/rect patches */
6207         skip("Device supports patches, skipping unsupported patch test\n");
6208         IDirect3DDevice9_Release(device);
6209         IDirect3D9_Release(d3d9);
6210         DestroyWindow(window);
6211         return;
6212     }
6213
6214     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6215     ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
6216     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6217     ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
6218
6219     hr = IDirect3DDevice9_CreateVertexBuffer(device, bufsize * sizeof(*data), D3DUSAGE_RTPATCHES, 0,
6220             D3DPOOL_MANAGED, &buffer, NULL);
6221     ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
6222     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, (void **)&data, 0);
6223     ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr);
6224     memset(data, 0, bufsize * sizeof(*data));
6225     hr = IDirect3DVertexBuffer9_Unlock(buffer);
6226     ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr);
6227
6228     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*data));
6229     ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
6230     hr = IDirect3DDevice9_BeginScene(device);
6231     ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6232
6233     patch.StartVertexOffsetWidth = 0;
6234     patch.StartVertexOffsetHeight = 0;
6235     patch.Width = 4;
6236     patch.Height = 4;
6237     patch.Stride = 4;
6238     patch.Basis = D3DBASIS_BEZIER;
6239     patch.Degree = D3DDEGREE_CUBIC;
6240     hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6241     ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6242     hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, &patch);
6243     ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6244     hr = IDirect3DDevice9_DrawRectPatch(device, handle, num_segs, NULL);
6245     ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6246     hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, NULL);
6247     ok(SUCCEEDED(hr), "Failed to draw rect patch, hr %#x.\n", hr);
6248
6249     hr = IDirect3DDevice9_EndScene(device);
6250     ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6251
6252     hr = IDirect3DDevice9_DrawRectPatch(device, 0, num_segs, &patch);
6253     ok(SUCCEEDED(hr), "Failed to draw rect patch outside scene, hr %#x.\n", hr);
6254
6255     hr = IDirect3DDevice9_DeletePatch(device, handle);
6256     ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6257     hr = IDirect3DDevice9_DeletePatch(device, 0);
6258     ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6259     hr = IDirect3DDevice9_DeletePatch(device, 0x1235);
6260     ok(hr == D3DERR_INVALIDCALL, "DeletePatch returned hr %#x.\n", hr);
6261
6262     IDirect3DVertexDeclaration9_Release(decl);
6263     IDirect3DVertexBuffer9_Release(buffer);
6264     refcount = IDirect3DDevice9_Release(device);
6265     ok(!refcount, "Device has %u references left.\n", refcount);
6266     IDirect3D9_Release(d3d9);
6267     DestroyWindow(window);
6268 }
6269
6270 static void test_npot_textures(void)
6271 {
6272     IDirect3DDevice9 *device = NULL;
6273     IDirect3D9 *d3d9;
6274     ULONG refcount;
6275     HWND window = NULL;
6276     HRESULT hr;
6277     D3DCAPS9 caps;
6278     IDirect3DTexture9 *texture;
6279     IDirect3DCubeTexture9 *cube_texture;
6280     IDirect3DVolumeTexture9 *volume_texture;
6281     struct
6282     {
6283         D3DPOOL pool;
6284         const char *pool_name;
6285         HRESULT hr;
6286     }
6287     pools[] =
6288     {
6289         { D3DPOOL_DEFAULT,    "D3DPOOL_DEFAULT",    D3DERR_INVALIDCALL },
6290         { D3DPOOL_MANAGED,    "D3DPOOL_MANAGED",    D3DERR_INVALIDCALL },
6291         { D3DPOOL_SYSTEMMEM,  "D3DPOOL_SYSTEMMEM",  D3DERR_INVALIDCALL },
6292         { D3DPOOL_SCRATCH,    "D3DPOOL_SCRATCH",    D3D_OK             },
6293     };
6294     unsigned int i, levels;
6295     BOOL tex_pow2, cube_pow2, vol_pow2;
6296
6297     if (!(d3d9 = pDirect3DCreate9(D3D_SDK_VERSION)))
6298     {
6299         skip("Failed to create IDirect3D9 object, skipping tests.\n");
6300         return;
6301     }
6302
6303     window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
6304             0, 0, 640, 480, 0, 0, 0, 0);
6305     if (!(device = create_device(d3d9, window, window, TRUE)))
6306     {
6307         skip("Failed to create a D3D device, skipping tests.\n");
6308         goto done;
6309     }
6310
6311     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6312     ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6313     tex_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_POW2);
6314     cube_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2);
6315     vol_pow2 = !!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2);
6316     ok(cube_pow2 == tex_pow2, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
6317     ok(vol_pow2 == tex_pow2, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
6318
6319     for (i = 0; i < sizeof(pools) / sizeof(*pools); i++)
6320     {
6321         for (levels = 0; levels <= 2; levels++)
6322         {
6323             HRESULT expected;
6324
6325             hr = IDirect3DDevice9_CreateTexture(device, 10, 10, levels, 0, D3DFMT_X8R8G8B8,
6326                     pools[i].pool, &texture, NULL);
6327             if (!tex_pow2)
6328             {
6329                 expected = D3D_OK;
6330             }
6331             else if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
6332             {
6333                 if (levels == 1)
6334                     expected = D3D_OK;
6335                 else
6336                     expected = pools[i].hr;
6337             }
6338             else
6339             {
6340                 expected = pools[i].hr;
6341             }
6342             ok(hr == expected, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#x, expected %#x.\n",
6343                     pools[i].pool_name, levels, hr, expected);
6344
6345             if (SUCCEEDED(hr))
6346                 IDirect3DTexture9_Release(texture);
6347         }
6348
6349         hr = IDirect3DDevice9_CreateCubeTexture(device, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
6350                 &cube_texture, NULL);
6351         if (tex_pow2)
6352         {
6353             ok(hr == pools[i].hr, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
6354                     pools[i].pool_name, hr, pools[i].hr);
6355         }
6356         else
6357         {
6358             ok(SUCCEEDED(hr), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#x, expected %#x.\n",
6359                     pools[i].pool_name, hr, D3D_OK);
6360         }
6361
6362         if (SUCCEEDED(hr))
6363             IDirect3DCubeTexture9_Release(cube_texture);
6364
6365         hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8, pools[i].pool,
6366                 &volume_texture, NULL);
6367         if (tex_pow2)
6368         {
6369             ok(hr == pools[i].hr, "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
6370                     pools[i].pool_name, hr, pools[i].hr);
6371         }
6372         else
6373         {
6374             ok(SUCCEEDED(hr), "CreateVolumeTextur(Depth=3, %s) returned hr %#x, expected %#x.\n",
6375                     pools[i].pool_name, hr, D3D_OK);
6376         }
6377
6378         if (SUCCEEDED(hr))
6379             IDirect3DVolumeTexture9_Release(volume_texture);
6380     }
6381
6382 done:
6383     if (device)
6384     {
6385         refcount = IDirect3DDevice9_Release(device);
6386         ok(!refcount, "Device has %u references left.\n", refcount);
6387     }
6388     IDirect3D9_Release(d3d9);
6389     DestroyWindow(window);
6390
6391 }
6392
6393 START_TEST(device)
6394 {
6395     HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
6396     WNDCLASS wc = {0};
6397
6398     wc.lpfnWndProc = DefWindowProc;
6399     wc.lpszClassName = "d3d9_test_wc";
6400     RegisterClass(&wc);
6401
6402     if (!d3d9_handle)
6403     {
6404         skip("Could not load d3d9.dll\n");
6405         goto out;
6406     }
6407
6408     pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
6409     ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
6410     if (pDirect3DCreate9)
6411     {
6412         IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
6413         if(!d3d9)
6414         {
6415             skip("could not create D3D9 object\n");
6416             goto out;
6417         }
6418         IDirect3D9_Release(d3d9);
6419
6420         screen_width = GetSystemMetrics(SM_CXSCREEN);
6421         screen_height = GetSystemMetrics(SM_CYSCREEN);
6422
6423         test_fpu_setup();
6424         test_multi_device();
6425         test_display_formats();
6426         test_display_modes();
6427         test_swapchain();
6428         test_refcount();
6429         test_mipmap_levels();
6430         test_checkdevicemultisampletype();
6431         test_cursor();
6432         test_cursor_pos();
6433         test_reset_fullscreen();
6434         test_reset();
6435         test_scene();
6436         test_limits();
6437         test_depthstenciltest();
6438         test_get_rt();
6439         test_draw_indexed();
6440         test_null_stream();
6441         test_lights();
6442         test_set_stream_source();
6443         test_scissor_size();
6444         test_wndproc();
6445         test_wndproc_windowed();
6446         test_window_style();
6447         test_mode_change();
6448         test_device_window_reset();
6449         test_reset_resources();
6450         test_set_rt_vp_scissor();
6451         test_volume_get_container();
6452         test_volume_resource();
6453         test_vb_lock_flags();
6454         test_vertex_buffer_alignment();
6455         test_query_support();
6456         test_occlusion_query_states();
6457         test_get_set_vertex_shader();
6458         test_vertex_shader_constant();
6459         test_get_set_pixel_shader();
6460         test_pixel_shader_constant();
6461         test_wrong_shader();
6462         test_texture_stage_states();
6463         test_cube_textures();
6464         test_mipmap_gen();
6465         test_filter();
6466         test_get_texture();
6467         test_lod();
6468         test_surface_get_container();
6469         test_surface_alignment();
6470         test_lockrect_offset();
6471         test_lockrect_invalid();
6472         test_private_data();
6473         test_getdc();
6474         test_surface_dimensions();
6475         test_surface_format_null();
6476         test_surface_double_unlock();
6477         test_surface_lockrect_blocks();
6478         test_set_palette();
6479         test_swvp_buffer();
6480         test_rtpatch();
6481         test_npot_textures();
6482     }
6483
6484 out:
6485     UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));
6486 }