wined3d: The final luminance factor is clamped.
[wine] / dlls / d3d9 / tests / device.c
1 /*
2  * Copyright (C) 2006 Vitaliy Margolen
3  * Copyright (C) 2006 Chris Robinson
4  * Copyright (C) 2006-2007 Stefan Dösinger(For CodeWeavers)
5  * Copyright 2007 Henri Verbeet
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #define COBJMACROS
23 #include <d3d9.h>
24 #include "wine/test.h"
25
26 static IDirect3D9 *(WINAPI *pDirect3DCreate9)(UINT);
27
28 static int get_refcount(IUnknown *object)
29 {
30     IUnknown_AddRef( object );
31     return IUnknown_Release( object );
32 }
33
34 #define CHECK_CALL(r,c,d,rc) \
35     if (SUCCEEDED(r)) {\
36         int tmp1 = get_refcount( (IUnknown *)d ); \
37         int rc_new = rc; \
38         ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
39     } else {\
40         trace("%s failed: %08x\n", c, r); \
41     }
42
43 #define CHECK_RELEASE(obj,d,rc) \
44     if (obj) { \
45         int tmp1, rc_new = rc; \
46         IUnknown_Release( obj ); \
47         tmp1 = get_refcount( (IUnknown *)d ); \
48         ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
49     }
50
51 #define CHECK_REFCOUNT(obj,rc) \
52     { \
53         int rc_new = rc; \
54         int count = get_refcount( (IUnknown *)obj ); \
55         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
56     }
57
58 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
59     { \
60         int rc_new = rc; \
61         int count = IUnknown_Release( (IUnknown *)obj ); \
62         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
63     }
64
65 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
66     { \
67         int rc_new = rc; \
68         int count = IUnknown_AddRef( (IUnknown *)obj ); \
69         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
70     }
71
72 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
73     { \
74         void *container_ptr = (void *)0x1337c0d3; \
75         hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
76         ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
77             "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
78         if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
79     }
80
81 static void check_mipmap_levels(
82     IDirect3DDevice9* device, 
83     int width, int height, int count) 
84 {
85
86     IDirect3DBaseTexture9* texture = NULL;
87     HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0, 
88         D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
89        
90     if (SUCCEEDED(hr)) {
91         DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
92         ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
93     } else 
94         trace("CreateTexture failed: %08x\n", hr);
95
96     if (texture) IUnknown_Release( texture );
97 }
98
99 static void test_mipmap_levels(void)
100 {
101
102     HRESULT               hr;
103     HWND                  hwnd = NULL;
104
105     IDirect3D9            *pD3d = NULL;
106     IDirect3DDevice9      *pDevice = NULL;
107     D3DPRESENT_PARAMETERS d3dpp;
108     D3DDISPLAYMODE        d3ddm;
109  
110     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
111     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
112     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
113     ok(hwnd != NULL, "Failed to create window\n");
114     if (!pD3d || !hwnd) goto cleanup;
115
116     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
117     ZeroMemory( &d3dpp, sizeof(d3dpp) );
118     d3dpp.Windowed         = TRUE;
119     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
120     d3dpp.BackBufferFormat = d3ddm.Format;
121
122     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
123                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
124     ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%08x)\n", hr);
125     if (FAILED(hr)) goto cleanup;
126
127     check_mipmap_levels(pDevice, 32, 32, 6);
128     check_mipmap_levels(pDevice, 256, 1, 9);
129     check_mipmap_levels(pDevice, 1, 256, 9);
130     check_mipmap_levels(pDevice, 1, 1, 1);
131
132     cleanup:
133     if (pD3d)     IUnknown_Release( pD3d );
134     if (pDevice)  IUnknown_Release( pDevice );
135     DestroyWindow( hwnd );
136 }
137
138 static void test_swapchain(void)
139 {
140     HRESULT                      hr;
141     HWND                         hwnd               = NULL;
142     IDirect3D9                  *pD3d               = NULL;
143     IDirect3DDevice9            *pDevice            = NULL;
144     IDirect3DSwapChain9         *swapchain0         = NULL;
145     IDirect3DSwapChain9         *swapchain1         = NULL;
146     IDirect3DSwapChain9         *swapchain2         = NULL;
147     IDirect3DSwapChain9         *swapchain3         = NULL;
148     IDirect3DSwapChain9         *swapchainX         = NULL;
149     IDirect3DSurface9           *backbuffer         = NULL;
150     D3DPRESENT_PARAMETERS        d3dpp;
151     D3DDISPLAYMODE               d3ddm;
152
153     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
154     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
155     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
156     ok(hwnd != NULL, "Failed to create window\n");
157     if (!pD3d || !hwnd) goto cleanup;
158
159     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
160     ZeroMemory( &d3dpp, sizeof(d3dpp) );
161     d3dpp.Windowed         = TRUE;
162     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
163     d3dpp.BackBufferFormat = d3ddm.Format;
164     d3dpp.BackBufferCount  = 0;
165
166     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
167                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
168     ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
169        "Failed to create IDirect3D9Device (%08x)\n", hr);
170     if (FAILED(hr)) goto cleanup;
171
172     /* Check if the back buffer count was modified */
173     ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
174
175     /* Get the implicit swapchain */
176     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &swapchain0);
177     ok(SUCCEEDED(hr), "Failed to get the impicit swapchain (%08x)\n", hr);
178     if(swapchain0) IDirect3DSwapChain9_Release(swapchain0);
179
180     /* Check if there is a back buffer */
181     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
182     ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
183     ok(backbuffer != NULL, "The back buffer is NULL\n");
184     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
185
186     /* Try to get a nonexistent swapchain */
187     hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
188     ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%08x)\n", hr);
189     ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
190     if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
191
192     /* Create a bunch of swapchains */
193     d3dpp.BackBufferCount = 0;
194     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain1);
195     ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
196     ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
197
198     d3dpp.BackBufferCount  = 1;
199     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain2);
200     ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
201
202     d3dpp.BackBufferCount  = 2;
203     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3);
204     ok(SUCCEEDED(hr), "Failed to create a swapchain (%08x)\n", hr);
205     if(SUCCEEDED(hr)) {
206         /* Swapchain 3, created with backbuffercount 2 */
207         backbuffer = (void *) 0xdeadbeef;
208         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
209         ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%08x)\n", hr);
210         ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
211         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
212
213         backbuffer = (void *) 0xdeadbeef;
214         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
215         ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%08x)\n", hr);
216         ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
217         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
218
219         backbuffer = (void *) 0xdeadbeef;
220         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
221         ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
222         ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
223         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
224
225         backbuffer = (void *) 0xdeadbeef;
226         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
227         ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
228         ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
229         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
230     }
231
232     /* Check the back buffers of the swapchains */
233     /* Swapchain 1, created with backbuffercount 0 */
234     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
235     ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
236     ok(backbuffer != NULL, "The back buffer is NULL (%08x)\n", hr);
237     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
238
239     backbuffer = (void *) 0xdeadbeef;
240     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
241     ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
242     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
243     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
244
245     /* Swapchain 2 - created with backbuffercount 1 */
246     backbuffer = (void *) 0xdeadbeef;
247     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
248     ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
249     ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
250     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
251
252     backbuffer = (void *) 0xdeadbeef;
253     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
254     ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %08x\n", hr);
255     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
256     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
257
258     backbuffer = (void *) 0xdeadbeef;
259     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
260     ok(FAILED(hr), "Failed to get the back buffer (%08x)\n", hr);
261     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
262     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
263
264     /* Try getSwapChain on a manually created swapchain
265      * it should fail, apparently GetSwapChain only returns implicit swapchains
266      */
267     swapchainX = (void *) 0xdeadbeef;
268     hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
269     ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%08x)\n", hr);
270     ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
271     if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
272
273     cleanup:
274     if(swapchain1) IDirect3DSwapChain9_Release(swapchain1);
275     if(swapchain2) IDirect3DSwapChain9_Release(swapchain2);
276     if(swapchain3) IDirect3DSwapChain9_Release(swapchain3);
277     if(pDevice) IDirect3DDevice9_Release(pDevice);
278     if(pD3d) IDirect3DDevice9_Release(pD3d);
279     DestroyWindow( hwnd );
280 }
281
282 /* Shared between two functions */
283 static const DWORD simple_vs[] = {0xFFFE0101,       /* vs_1_1               */
284     0x0000001F, 0x80000000, 0x900F0000,             /* dcl_position0 v0     */
285     0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0   */
286     0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1   */
287     0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2   */
288     0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3   */
289     0x0000FFFF};                                    /* END                  */
290
291 static void test_refcount(void)
292 {
293     HRESULT                      hr;
294     HWND                         hwnd               = NULL;
295     IDirect3D9                  *pD3d               = NULL;
296     IDirect3DDevice9            *pDevice            = NULL;
297     IDirect3DVertexBuffer9      *pVertexBuffer      = NULL;
298     IDirect3DIndexBuffer9       *pIndexBuffer       = NULL;
299     IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
300     IDirect3DVertexShader9      *pVertexShader      = NULL;
301     IDirect3DPixelShader9       *pPixelShader       = NULL;
302     IDirect3DCubeTexture9       *pCubeTexture       = NULL;
303     IDirect3DTexture9           *pTexture           = NULL;
304     IDirect3DVolumeTexture9     *pVolumeTexture     = NULL;
305     IDirect3DVolume9            *pVolumeLevel       = NULL;
306     IDirect3DSurface9           *pStencilSurface    = NULL;
307     IDirect3DSurface9           *pOffscreenSurface  = NULL;
308     IDirect3DSurface9           *pRenderTarget      = NULL;
309     IDirect3DSurface9           *pRenderTarget2     = NULL;
310     IDirect3DSurface9           *pRenderTarget3     = NULL;
311     IDirect3DSurface9           *pTextureLevel      = NULL;
312     IDirect3DSurface9           *pBackBuffer        = NULL;
313     IDirect3DStateBlock9        *pStateBlock        = NULL;
314     IDirect3DStateBlock9        *pStateBlock1       = NULL;
315     IDirect3DSwapChain9         *pSwapChain         = NULL;
316     IDirect3DQuery9             *pQuery             = NULL;
317     D3DPRESENT_PARAMETERS        d3dpp;
318     D3DDISPLAYMODE               d3ddm;
319     int                          refcount = 0, tmp;
320
321     D3DVERTEXELEMENT9 decl[] =
322     {
323         D3DDECL_END()
324     };
325     static DWORD simple_ps[] = {0xFFFF0101,                                     /* ps_1_1                       */
326         0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0  */
327         0x00000042, 0xB00F0000,                                                 /* tex t0                       */
328         0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000,                         /* dp3 r0, c1, c0               */
329         0x00000005, 0x800F0000, 0x90E40000, 0x80E40000,                         /* mul r0, v0, r0               */
330         0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000,                         /* mul r0, t0, r0               */
331         0x0000FFFF};                                                            /* END                          */
332
333
334     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
335     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
336     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
337     ok(hwnd != NULL, "Failed to create window\n");
338     if (!pD3d || !hwnd) goto cleanup;
339
340     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
341     ZeroMemory( &d3dpp, sizeof(d3dpp) );
342     d3dpp.Windowed         = TRUE;
343     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
344     d3dpp.BackBufferFormat = d3ddm.Format;
345     d3dpp.EnableAutoDepthStencil = TRUE;
346     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
347
348     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
349                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
350     ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
351        "Failed to create IDirect3D9Device (%08x)\n", hr);
352     if (FAILED(hr)) goto cleanup;
353
354     refcount = get_refcount( (IUnknown *)pDevice );
355     ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
356
357     /**
358      * Check refcount of implicit surfaces and implicit swapchain. Findings:
359      *   - the container is the device OR swapchain
360      *   - they hold a reference to the device
361      *   - they are created with a refcount of 0 (Get/Release returns original refcount)
362      *   - they are not freed if refcount reaches 0.
363      *   - the refcount is not forwarded to the container.
364      */
365     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapChain);
366     CHECK_CALL( hr, "GetSwapChain", pDevice, ++refcount);
367     if (pSwapChain)
368     {
369         CHECK_REFCOUNT( pSwapChain, 1);
370
371         hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
372         CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
373         CHECK_REFCOUNT( pSwapChain, 1);
374         if(pRenderTarget)
375         {
376             CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
377             CHECK_REFCOUNT( pRenderTarget, 1);
378
379             CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
380             CHECK_REFCOUNT(pDevice, refcount);
381             CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
382             CHECK_REFCOUNT(pDevice, refcount);
383
384             hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
385             CHECK_CALL( hr, "GetRenderTarget", pDevice, refcount);
386             CHECK_REFCOUNT( pRenderTarget, 2);
387             CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
388             CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
389             CHECK_REFCOUNT( pDevice, --refcount);
390
391             /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
392             CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
393             CHECK_REFCOUNT(pDevice, ++refcount);
394             CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
395             CHECK_REFCOUNT(pDevice, --refcount);
396         }
397
398         /* Render target and back buffer are identical. */
399         hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, 0, &pBackBuffer);
400         CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
401         if(pBackBuffer)
402         {
403             CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
404             ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
405             pRenderTarget, pBackBuffer);
406             pBackBuffer = NULL;
407         }
408         CHECK_REFCOUNT( pDevice, --refcount);
409
410         hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pStencilSurface);
411         CHECK_CALL( hr, "GetDepthStencilSurface", pDevice, ++refcount);
412         CHECK_REFCOUNT( pSwapChain, 1);
413         if(pStencilSurface)
414         {
415             CHECK_SURFACE_CONTAINER( pStencilSurface, IID_IDirect3DDevice9, pDevice);
416             CHECK_REFCOUNT( pStencilSurface, 1);
417
418             CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
419             CHECK_REFCOUNT(pDevice, refcount);
420             CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
421             CHECK_REFCOUNT(pDevice, refcount);
422
423             CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
424             CHECK_REFCOUNT( pDevice, --refcount);
425
426             /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
427             CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
428             CHECK_REFCOUNT(pDevice, ++refcount);
429             CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
430             CHECK_REFCOUNT(pDevice, --refcount);
431             pStencilSurface = NULL;
432         }
433
434         CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
435         CHECK_REFCOUNT( pDevice, --refcount);
436
437         /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
438         CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
439         CHECK_REFCOUNT(pDevice, ++refcount);
440         CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
441         CHECK_REFCOUNT(pDevice, --refcount);
442         pSwapChain = NULL;
443     }
444
445     /* Buffers */
446     hr = IDirect3DDevice9_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL );
447     CHECK_CALL( hr, "CreateIndexBuffer", pDevice, ++refcount );
448     if(pIndexBuffer)
449     {
450         tmp = get_refcount( (IUnknown *)pIndexBuffer );
451
452         hr = IDirect3DDevice9_SetIndices(pDevice, pIndexBuffer);
453         CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
454         hr = IDirect3DDevice9_SetIndices(pDevice, NULL);
455         CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
456     }
457
458     hr = IDirect3DDevice9_CreateVertexBuffer( pDevice, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
459     CHECK_CALL( hr, "CreateVertexBuffer", pDevice, ++refcount );
460     if(pVertexBuffer)
461     {
462         IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
463         UINT offset = ~0;
464         UINT stride = ~0;
465
466         tmp = get_refcount( (IUnknown *)pVertexBuffer );
467
468         hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, pVertexBuffer, 0, 3 * sizeof(float));
469         CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
470         hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, NULL, 0, 0);
471         CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
472
473         hr = IDirect3DDevice9_GetStreamSource(pDevice, 0, &pVBuf, &offset, &stride);
474         ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
475         ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
476         ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
477         ok(offset==0, "offset not 0 (got %u)!\n", offset);
478     }
479     /* Shaders */
480     hr = IDirect3DDevice9_CreateVertexDeclaration( pDevice, decl, &pVertexDeclaration );
481     CHECK_CALL( hr, "CreateVertexDeclaration", pDevice, ++refcount );
482     hr = IDirect3DDevice9_CreateVertexShader( pDevice, simple_vs, &pVertexShader );
483     CHECK_CALL( hr, "CreateVertexShader", pDevice, ++refcount );
484     hr = IDirect3DDevice9_CreatePixelShader( pDevice, simple_ps, &pPixelShader );
485     CHECK_CALL( hr, "CreatePixelShader", pDevice, ++refcount );
486     /* Textures */
487     hr = IDirect3DDevice9_CreateTexture( pDevice, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL );
488     CHECK_CALL( hr, "CreateTexture", pDevice, ++refcount );
489     if (pTexture)
490     {
491         tmp = get_refcount( (IUnknown *)pTexture );
492
493         /* SetTexture should not increase refcounts */
494         hr = IDirect3DDevice9_SetTexture(pDevice, 0, (IDirect3DBaseTexture9 *) pTexture);
495         CHECK_CALL( hr, "SetTexture", pTexture, tmp);
496         hr = IDirect3DDevice9_SetTexture(pDevice, 0, NULL);
497         CHECK_CALL( hr, "SetTexture", pTexture, tmp);
498
499         /* This should not increment device refcount */
500         hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
501         CHECK_CALL( hr, "GetSurfaceLevel", pDevice, refcount );
502         /* But should increment texture's refcount */
503         CHECK_REFCOUNT( pTexture, tmp+1 );
504         /* Because the texture and surface refcount are identical */
505         if (pTextureLevel)
506         {
507             CHECK_REFCOUNT        ( pTextureLevel, tmp+1 );
508             CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
509             CHECK_REFCOUNT        ( pTexture     , tmp+2 );
510             CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
511             CHECK_REFCOUNT        ( pTexture     , tmp+1 );
512             CHECK_RELEASE_REFCOUNT( pTexture     , tmp   );
513             CHECK_REFCOUNT        ( pTextureLevel, tmp   );
514         }
515     }
516     hr = IDirect3DDevice9_CreateCubeTexture( pDevice, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL );
517     CHECK_CALL( hr, "CreateCubeTexture", pDevice, ++refcount );
518     hr = IDirect3DDevice9_CreateVolumeTexture( pDevice, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL );
519     CHECK_CALL( hr, "CreateVolumeTexture", pDevice, ++refcount );
520     if (pVolumeTexture)
521     {
522         tmp = get_refcount( (IUnknown *)pVolumeTexture );
523
524         /* This should not increment device refcount */
525         hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
526         CHECK_CALL( hr, "GetVolumeLevel", pDevice, refcount );
527         /* But should increment volume texture's refcount */
528         CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
529         /* Because the volume texture and volume refcount are identical */
530         if (pVolumeLevel)
531         {
532             CHECK_REFCOUNT        ( pVolumeLevel  , tmp+1 );
533             CHECK_ADDREF_REFCOUNT ( pVolumeLevel  , tmp+2 );
534             CHECK_REFCOUNT        ( pVolumeTexture, tmp+2 );
535             CHECK_RELEASE_REFCOUNT( pVolumeLevel  , tmp+1 );
536             CHECK_REFCOUNT        ( pVolumeTexture, tmp+1 );
537             CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp   );
538             CHECK_REFCOUNT        ( pVolumeLevel  , tmp   );
539         }
540     }
541     /* Surfaces */
542     hr = IDirect3DDevice9_CreateDepthStencilSurface( pDevice, 32, 32, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL );
543     CHECK_CALL( hr, "CreateDepthStencilSurface", pDevice, ++refcount );
544     CHECK_REFCOUNT( pStencilSurface, 1 );
545     hr = IDirect3DDevice9_CreateOffscreenPlainSurface( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL );
546     CHECK_CALL( hr, "CreateOffscreenPlainSurface", pDevice, ++refcount );
547     CHECK_REFCOUNT( pOffscreenSurface, 1 );
548     hr = IDirect3DDevice9_CreateRenderTarget( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL );
549     CHECK_CALL( hr, "CreateRenderTarget", pDevice, ++refcount );
550     CHECK_REFCOUNT( pRenderTarget3, 1 );
551     /* Misc */
552     hr = IDirect3DDevice9_CreateStateBlock( pDevice, D3DSBT_ALL, &pStateBlock );
553     CHECK_CALL( hr, "CreateStateBlock", pDevice, ++refcount );
554     hr = IDirect3DDevice9_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
555     CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, ++refcount );
556     if(pSwapChain)
557     {
558         /* check implicit back buffer */
559         hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
560         CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
561         CHECK_REFCOUNT( pSwapChain, 1);
562         if(pBackBuffer)
563         {
564             CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
565             CHECK_REFCOUNT( pBackBuffer, 1);
566             CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
567             CHECK_REFCOUNT( pDevice, --refcount);
568
569             /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
570             CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
571             CHECK_REFCOUNT(pDevice, ++refcount);
572             CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
573             CHECK_REFCOUNT(pDevice, --refcount);
574             pBackBuffer = NULL;
575         }
576         CHECK_REFCOUNT( pSwapChain, 1);
577     }
578     hr = IDirect3DDevice9_CreateQuery( pDevice, D3DQUERYTYPE_EVENT, &pQuery );
579     CHECK_CALL( hr, "CreateQuery", pDevice, ++refcount );
580
581     hr = IDirect3DDevice9_BeginStateBlock( pDevice );
582     CHECK_CALL( hr, "BeginStateBlock", pDevice, refcount );
583     hr = IDirect3DDevice9_EndStateBlock( pDevice, &pStateBlock1 );
584     CHECK_CALL( hr, "EndStateBlock", pDevice, ++refcount );
585
586     /* The implicit render target is not freed if refcount reaches 0.
587      * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
588     hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget2);
589     CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
590     if(pRenderTarget2)
591     {
592         CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
593         ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
594            pRenderTarget, pRenderTarget2);
595         CHECK_REFCOUNT( pDevice, --refcount);
596         pRenderTarget2 = NULL;
597     }
598     pRenderTarget = NULL;
599
600 cleanup:
601     CHECK_RELEASE(pDevice,              pDevice, --refcount);
602
603     /* Buffers */
604     CHECK_RELEASE(pVertexBuffer,        pDevice, --refcount);
605     CHECK_RELEASE(pIndexBuffer,         pDevice, --refcount);
606     /* Shaders */
607     CHECK_RELEASE(pVertexDeclaration,   pDevice, --refcount);
608     CHECK_RELEASE(pVertexShader,        pDevice, --refcount);
609     CHECK_RELEASE(pPixelShader,         pDevice, --refcount);
610     /* Textures */
611     CHECK_RELEASE(pTextureLevel,        pDevice, --refcount);
612     CHECK_RELEASE(pCubeTexture,         pDevice, --refcount);
613     CHECK_RELEASE(pVolumeTexture,       pDevice, --refcount);
614     /* Surfaces */
615     CHECK_RELEASE(pStencilSurface,      pDevice, --refcount);
616     CHECK_RELEASE(pOffscreenSurface,    pDevice, --refcount);
617     CHECK_RELEASE(pRenderTarget3,       pDevice, --refcount);
618     /* Misc */
619     CHECK_RELEASE(pStateBlock,          pDevice, --refcount);
620     CHECK_RELEASE(pSwapChain,           pDevice, --refcount);
621     CHECK_RELEASE(pQuery,               pDevice, --refcount);
622     /* This will destroy device - cannot check the refcount here */
623     if (pStateBlock1)         CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
624
625     if (pD3d)                 CHECK_RELEASE_REFCOUNT( pD3d, 0);
626
627     DestroyWindow( hwnd );
628 }
629
630 static void test_cursor(void)
631 {
632     HRESULT                      hr;
633     HWND                         hwnd               = NULL;
634     IDirect3D9                  *pD3d               = NULL;
635     IDirect3DDevice9            *pDevice            = NULL;
636     D3DPRESENT_PARAMETERS        d3dpp;
637     D3DDISPLAYMODE               d3ddm;
638     CURSORINFO                   info;
639     IDirect3DSurface9 *cursor = NULL;
640     HCURSOR cur;
641
642     memset(&info, 0, sizeof(info));
643     info.cbSize = sizeof(info);
644     hr = GetCursorInfo(&info);
645     cur = info.hCursor;
646
647     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
648     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
649     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
650     ok(hwnd != NULL, "Failed to create window\n");
651     if (!pD3d || !hwnd) goto cleanup;
652
653     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
654     ZeroMemory( &d3dpp, sizeof(d3dpp) );
655     d3dpp.Windowed         = TRUE;
656     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
657     d3dpp.BackBufferFormat = d3ddm.Format;
658
659     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
660                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
661     ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE,
662        "Failed to create IDirect3D9Device (%08x)\n", hr);
663     if (FAILED(hr)) goto cleanup;
664
665     IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, 0);
666     ok(cursor != NULL, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
667
668     /* Initially hidden */
669     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
670     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
671
672     /* Not enabled without a surface*/
673     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
674     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
675
676     /* Fails */
677     hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, NULL);
678     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
679
680     hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, cursor);
681     ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
682
683     IDirect3DSurface9_Release(cursor);
684
685     memset(&info, 0, sizeof(info));
686     info.cbSize = sizeof(info);
687     hr = GetCursorInfo(&info);
688     ok(hr != 0, "GetCursorInfo returned %08x\n", hr);
689     ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
690     ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
691
692     /* Still hidden */
693     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
694     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
695
696     /* Enabled now*/
697     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
698     ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
699
700     /* GDI cursor unchanged */
701     memset(&info, 0, sizeof(info));
702     info.cbSize = sizeof(info);
703     hr = GetCursorInfo(&info);
704     ok(hr != 0, "GetCursorInfo returned %08x\n", hr);
705     ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
706     ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
707
708 cleanup:
709     if(pDevice) IDirect3D9_Release(pDevice);
710     if(pD3d) IDirect3D9_Release(pD3d);
711     DestroyWindow( hwnd );
712 }
713
714 static void test_reset(void)
715 {
716     HRESULT                      hr;
717     HWND                         hwnd               = NULL;
718     IDirect3D9                  *pD3d               = NULL;
719     IDirect3DDevice9            *pDevice            = NULL;
720     D3DPRESENT_PARAMETERS        d3dpp;
721     D3DDISPLAYMODE               d3ddm, d3ddm2;
722     D3DVIEWPORT9                 vp;
723     DWORD                        width, orig_width = GetSystemMetrics(SM_CXSCREEN);
724     DWORD                        height, orig_height = GetSystemMetrics(SM_CYSCREEN);
725     IDirect3DSwapChain9          *pSwapchain;
726     IDirect3DSurface9            *surface;
727     IDirect3DTexture9            *texture;
728     IDirect3DVertexShader9       *shader;
729     BOOL                         support_800x600 = FALSE;
730     UINT                         i;
731     D3DLOCKED_RECT               lockrect;
732
733     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
734     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
735     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
736     ok(hwnd != NULL, "Failed to create window\n");
737     if (!pD3d || !hwnd) goto cleanup;
738
739     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
740     ZeroMemory( &d3dpp, sizeof(d3dpp) );
741     d3dpp.Windowed         = FALSE;
742     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
743     d3dpp.BackBufferWidth  = 800;
744     d3dpp.BackBufferHeight  = 600;
745     d3dpp.BackBufferFormat = d3ddm.Format;
746
747     for(i = 0; i < IDirect3D9_GetAdapterModeCount(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format); i++) {
748         ZeroMemory( &d3ddm2, sizeof(d3ddm2) );
749         hr = IDirect3D9_EnumAdapterModes(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2);
750         ok(hr == D3D_OK, "IDirect3D9_EnumAdapterModes returned %#x\n", hr);
751
752         if(d3ddm2.Width == 800 && d3ddm2.Height == 600) {
753             support_800x600 = TRUE;
754         }
755         /* We use them as invalid modes */
756         if((d3ddm2.Width == 801 && d3ddm2.Height == 600) ||
757            (d3ddm2.Width == 32 && d3ddm2.Height == 32)) {
758             skip("This system supports a screen resolution of %dx%d, not running mode tests\n",
759                  d3ddm2.Width, d3ddm2.Height);
760             goto cleanup;
761         }
762     }
763     if(!support_800x600) {
764         skip("Mode 800x600 not supported, skipping mode tests\n");
765         goto cleanup;
766     }
767
768     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
769                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
770
771     if(FAILED(hr))
772     {
773         skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
774         goto cleanup;
775     }
776     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
777     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after creation returned %#x\n", hr);
778
779     width = GetSystemMetrics(SM_CXSCREEN);
780     height = GetSystemMetrics(SM_CYSCREEN);
781     ok(width == 800, "Screen width is %d\n", width);
782     ok(height == 600, "Screen height is %d\n", height);
783
784     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
785     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
786     if(SUCCEEDED(hr))
787     {
788         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
789         ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
790         ok(vp.Width == 800, "D3DVIEWPORT->Width = %d\n", vp.Width);
791         ok(vp.Height == 600, "D3DVIEWPORT->Height = %d\n", vp.Height);
792         ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
793         ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
794     }
795     vp.X = 10;
796     vp.X = 20;
797     vp.MinZ = 2;
798     vp.MaxZ = 3;
799     hr = IDirect3DDevice9_SetViewport(pDevice, &vp);
800     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
801
802     ZeroMemory( &d3dpp, sizeof(d3dpp) );
803     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
804     d3dpp.Windowed         = FALSE;
805     d3dpp.BackBufferWidth  = 640;
806     d3dpp.BackBufferHeight  = 480;
807     d3dpp.BackBufferFormat = d3ddm.Format;
808     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
809     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
810     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
811     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
812
813     ZeroMemory(&vp, sizeof(vp));
814     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
815     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
816     if(SUCCEEDED(hr))
817     {
818         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
819         ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
820         ok(vp.Width == 640, "D3DVIEWPORT->Width = %d\n", vp.Width);
821         ok(vp.Height == 480, "D3DVIEWPORT->Height = %d\n", vp.Height);
822         ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
823         ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
824     }
825
826     width = GetSystemMetrics(SM_CXSCREEN);
827     height = GetSystemMetrics(SM_CYSCREEN);
828     ok(width == 640, "Screen width is %d\n", width);
829     ok(height == 480, "Screen height is %d\n", height);
830
831     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapchain);
832     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
833     if(SUCCEEDED(hr))
834     {
835         ZeroMemory(&d3dpp, sizeof(d3dpp));
836         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
837         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
838         if(SUCCEEDED(hr))
839         {
840             ok(d3dpp.BackBufferWidth == 640, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
841             ok(d3dpp.BackBufferHeight == 480, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
842         }
843         IDirect3DSwapChain9_Release(pSwapchain);
844     }
845
846     ZeroMemory( &d3dpp, sizeof(d3dpp) );
847     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
848     d3dpp.Windowed         = TRUE;
849     d3dpp.BackBufferWidth  = 400;
850     d3dpp.BackBufferHeight  = 300;
851     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
852     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
853     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
854     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
855
856     width = GetSystemMetrics(SM_CXSCREEN);
857     height = GetSystemMetrics(SM_CYSCREEN);
858     ok(width == orig_width, "Screen width is %d\n", width);
859     ok(height == orig_height, "Screen height is %d\n", height);
860
861     ZeroMemory(&vp, sizeof(vp));
862     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
863     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
864     if(SUCCEEDED(hr))
865     {
866         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
867         ok(vp.Y == 0, "D3DVIEWPORT->Y = %d\n", vp.Y);
868         ok(vp.Width == 400, "D3DVIEWPORT->Width = %d\n", vp.Width);
869         ok(vp.Height == 300, "D3DVIEWPORT->Height = %d\n", vp.Height);
870         ok(vp.MinZ == 0, "D3DVIEWPORT->MinZ = %f\n", vp.MinZ);
871         ok(vp.MaxZ == 1, "D3DVIEWPORT->MaxZ = %f\n", vp.MaxZ);
872     }
873
874     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapchain);
875     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %08x\n", hr);
876     if(SUCCEEDED(hr))
877     {
878         ZeroMemory(&d3dpp, sizeof(d3dpp));
879         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
880         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %08x\n", hr);
881         if(SUCCEEDED(hr))
882         {
883             ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
884             ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
885         }
886         IDirect3DSwapChain9_Release(pSwapchain);
887     }
888
889     ZeroMemory( &d3dpp, sizeof(d3dpp) );
890     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
891     d3dpp.Windowed         = TRUE;
892     d3dpp.BackBufferWidth  = 400;
893     d3dpp.BackBufferHeight  = 300;
894
895     /* _Reset fails if there is a resource in the default pool */
896     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 16, 16, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL);
897     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
898     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
899     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
900     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
901     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
902     IDirect3DSurface9_Release(surface);
903     /* Reset again to get the device out of the lost state */
904     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
905     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
906     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
907     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
908
909     /* Scratch, sysmem and managed pools are fine */
910     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
911     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
912     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
913     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
914     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
915     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
916     IDirect3DSurface9_Release(surface);
917
918     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
919     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
920     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
921     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
922     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
923     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
924     IDirect3DSurface9_Release(surface);
925
926     /* Will a sysmem or scratch survive while locked */
927     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL);
928     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
929     hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
930     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
931     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
932     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
933     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
934     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
935     IDirect3DSurface9_UnlockRect(surface);
936     IDirect3DSurface9_Release(surface);
937
938     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SCRATCH, &surface, NULL);
939     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
940     hr = IDirect3DSurface9_LockRect(surface, &lockrect, NULL, D3DLOCK_DISCARD);
941     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
942     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
943     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
944     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
945     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
946     IDirect3DSurface9_UnlockRect(surface);
947     IDirect3DSurface9_Release(surface);
948
949     hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 0, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, &texture, NULL);
950     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
951     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
952     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
953     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
954     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
955     IDirect3DTexture9_Release(texture);
956
957     /* A reference held to an implicit surface causes failures as well */
958     hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
959     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer returned %08x\n", hr);
960     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
961     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset failed with %08x\n", hr);
962     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
963     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
964     IDirect3DSurface9_Release(surface);
965     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
966     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
967     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
968     ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr);
969
970     /* Shaders are fine as well */
971     hr = IDirect3DDevice9_CreateVertexShader(pDevice, simple_vs, &shader);
972     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
973     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
974     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %08x\n", hr);
975     IDirect3DVertexShader9_Release(shader);
976
977     /* Try setting invalid modes */
978     ZeroMemory( &d3dpp, sizeof(d3dpp) );
979     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
980     d3dpp.Windowed         = FALSE;
981     d3dpp.BackBufferWidth  = 32;
982     d3dpp.BackBufferHeight  = 32;
983     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
984     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %08x\n", hr);
985     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
986     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
987
988     ZeroMemory( &d3dpp, sizeof(d3dpp) );
989     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
990     d3dpp.Windowed         = FALSE;
991     d3dpp.BackBufferWidth  = 801;
992     d3dpp.BackBufferHeight  = 600;
993     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
994     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %08x\n", hr);
995     hr = IDirect3DDevice9_TestCooperativeLevel(pDevice);
996     ok(hr == D3DERR_DEVICENOTRESET, "IDirect3DDevice9_TestCooperativeLevel after a failed reset returned %#x\n", hr);
997
998 cleanup:
999     if(pD3d) IDirect3D9_Release(pD3d);
1000     if(pDevice) IDirect3D9_Release(pDevice);
1001 }
1002
1003 /* Test adapter display modes */
1004 static void test_display_modes(void)
1005 {
1006     D3DDISPLAYMODE dmode;
1007     IDirect3D9 *pD3d;
1008
1009     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1010     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1011     if(!pD3d) return;
1012
1013 #define TEST_FMT(x,r) do { \
1014     HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
1015     ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %08x)!\n", res); \
1016 } while(0)
1017
1018     TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
1019     TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
1020     TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1021     /* D3DFMT_R5G6B5 */
1022     TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
1023     TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
1024     TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
1025     TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
1026     TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
1027     TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
1028     TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
1029     TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
1030     TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
1031     TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
1032     TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
1033     TEST_FMT(D3DFMT_A2R10G10B10, D3DERR_INVALIDCALL);
1034     TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
1035
1036     TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
1037     TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
1038
1039     TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
1040     TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
1041     TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
1042
1043     TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
1044     TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
1045     TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
1046     TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
1047     TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
1048     TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
1049
1050     TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
1051     TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
1052     TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
1053     TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
1054     TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
1055     TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
1056     TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
1057     TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
1058     TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
1059     TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
1060
1061     TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
1062     TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
1063     TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
1064     TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
1065     TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
1066     TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
1067     TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
1068     TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
1069     TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
1070     TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
1071
1072     TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
1073     TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
1074     TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
1075     TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
1076     /* Floating point formats */
1077     TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
1078     TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
1079     TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
1080
1081     /* IEEE formats */
1082     TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
1083     TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
1084     TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
1085
1086     TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
1087
1088     TEST_FMT(0, D3DERR_INVALIDCALL);
1089
1090     IDirect3D9_Release(pD3d);
1091 }
1092
1093 static void test_scene(void)
1094 {
1095     HRESULT                      hr;
1096     HWND                         hwnd               = NULL;
1097     IDirect3D9                  *pD3d               = NULL;
1098     IDirect3DDevice9            *pDevice            = NULL;
1099     D3DPRESENT_PARAMETERS        d3dpp;
1100     D3DDISPLAYMODE               d3ddm;
1101     IDirect3DSurface9            *pSurface1 = NULL, *pSurface2 = NULL, *pSurface3 = NULL, *pRenderTarget = NULL;
1102     IDirect3DSurface9            *pBackBuffer = NULL, *pDepthStencil = NULL;
1103     RECT rect = {0, 0, 128, 128};
1104     D3DCAPS9                     caps;
1105
1106     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1107     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1108     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1109     ok(hwnd != NULL, "Failed to create window\n");
1110     if (!pD3d || !hwnd) goto cleanup;
1111
1112     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1113     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1114     d3dpp.Windowed         = TRUE;
1115     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1116     d3dpp.BackBufferWidth  = 800;
1117     d3dpp.BackBufferHeight  = 600;
1118     d3dpp.BackBufferFormat = d3ddm.Format;
1119     d3dpp.EnableAutoDepthStencil = TRUE;
1120     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1121
1122     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1123                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1124     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1125     if(!pDevice)
1126     {
1127         skip("Failed to create a d3d device\n");
1128         goto cleanup;
1129     }
1130
1131     /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
1132     memset(&caps, 0, sizeof(caps));
1133     hr = IDirect3DDevice9_GetDeviceCaps(pDevice, &caps);
1134     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %08x\n", hr);
1135     if(FAILED(hr)) goto cleanup;
1136
1137     /* Test an EndScene without beginscene. Should return an error */
1138     hr = IDirect3DDevice9_EndScene(pDevice);
1139     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1140
1141     /* Test a normal BeginScene / EndScene pair, this should work */
1142     hr = IDirect3DDevice9_BeginScene(pDevice);
1143     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1144     if(SUCCEEDED(hr))
1145     {
1146         hr = IDirect3DDevice9_EndScene(pDevice);
1147         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1148     }
1149
1150     /* Test another EndScene without having begun a new scene. Should return an error */
1151     hr = IDirect3DDevice9_EndScene(pDevice);
1152     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1153
1154     /* Two nested BeginScene and EndScene calls */
1155     hr = IDirect3DDevice9_BeginScene(pDevice);
1156     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1157     hr = IDirect3DDevice9_BeginScene(pDevice);
1158     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
1159     hr = IDirect3DDevice9_EndScene(pDevice);
1160     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1161     hr = IDirect3DDevice9_EndScene(pDevice);
1162     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %08x\n", hr);
1163
1164     /* Create some surfaces to test stretchrect between the scenes */
1165     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface1, NULL);
1166     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1167     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface2, NULL);
1168     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
1169     hr = IDirect3DDevice9_CreateDepthStencilSurface(pDevice, 800, 600, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface3, NULL);
1170     ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %08x\n", hr);
1171     hr = IDirect3DDevice9_CreateRenderTarget(pDevice, 128, 128, d3ddm.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pRenderTarget, NULL);
1172     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
1173
1174     hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
1175     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1176     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1177     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
1178
1179     /* First make sure a simple StretchRect call works */
1180     if(pSurface1 && pSurface2) {
1181         hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1182         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1183     }
1184     if(pBackBuffer && pRenderTarget) {
1185         hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1186         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1187     }
1188     if(pDepthStencil && pSurface3) {
1189         HRESULT expected;
1190         if(0) /* Disabled for now because it crashes in wine */ {
1191             expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
1192             hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1193             ok( hr == expected, "IDirect3DDevice9_StretchRect returned %08x, expected %08x\n", hr, expected);
1194         }
1195     }
1196
1197     /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1198      * width normal surfaces, render targets and depth stencil surfaces.
1199      */
1200     hr = IDirect3DDevice9_BeginScene(pDevice);
1201     ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1202
1203     if(pSurface1 && pSurface2)
1204     {
1205         hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1206         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1207     }
1208     if(pBackBuffer && pRenderTarget)
1209     {
1210         hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1211         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
1212     }
1213     if(pDepthStencil && pSurface3)
1214     {
1215         /* This is supposed to fail inside a BeginScene - EndScene pair. */
1216         hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1217         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %08x, expected D3DERR_INVALIDCALL\n", hr);
1218     }
1219
1220     hr = IDirect3DDevice9_EndScene(pDevice);
1221     ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1222
1223     /* Does a SetRenderTarget influence BeginScene / EndScene ?
1224      * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1225      * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1226      */
1227     hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pRenderTarget);
1228     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1229     hr = IDirect3DDevice9_BeginScene(pDevice);
1230     ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1231     hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pBackBuffer);
1232     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
1233     hr = IDirect3DDevice9_EndScene(pDevice);
1234     ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1235
1236 cleanup:
1237     if(pRenderTarget) IDirect3DSurface9_Release(pRenderTarget);
1238     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1239     if(pBackBuffer) IDirect3DSurface9_Release(pBackBuffer);
1240     if(pSurface1) IDirect3DSurface9_Release(pSurface1);
1241     if(pSurface2) IDirect3DSurface9_Release(pSurface2);
1242     if(pSurface3) IDirect3DSurface9_Release(pSurface3);
1243     if(pD3d) IDirect3D9_Release(pD3d);
1244     if(pDevice) IDirect3D9_Release(pDevice);
1245     if(hwnd) DestroyWindow(hwnd);
1246 }
1247
1248 static void test_limits(void)
1249 {
1250     HRESULT                      hr;
1251     HWND                         hwnd               = NULL;
1252     IDirect3D9                  *pD3d               = NULL;
1253     IDirect3DDevice9            *pDevice            = NULL;
1254     D3DPRESENT_PARAMETERS        d3dpp;
1255     D3DDISPLAYMODE               d3ddm;
1256     IDirect3DTexture9           *pTexture           = NULL;
1257     int i;
1258
1259     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1260     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1261     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1262     ok(hwnd != NULL, "Failed to create window\n");
1263     if (!pD3d || !hwnd) goto cleanup;
1264
1265     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1266     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1267     d3dpp.Windowed         = TRUE;
1268     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1269     d3dpp.BackBufferWidth  = 800;
1270     d3dpp.BackBufferHeight  = 600;
1271     d3dpp.BackBufferFormat = d3ddm.Format;
1272     d3dpp.EnableAutoDepthStencil = TRUE;
1273     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1274
1275     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1276                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1277     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1278     if(!pDevice)
1279     {
1280         skip("Failed to create a d3d device\n");
1281         goto cleanup;
1282     }
1283
1284     hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
1285     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
1286     if(!pTexture) goto cleanup;
1287
1288     /* There are 16 pixel samplers. We should be able to access all of them */
1289     for(i = 0; i < 16; i++) {
1290         hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
1291         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1292         hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
1293         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %08x\n", i, hr);
1294         hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
1295         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %08x\n", i, hr);
1296     }
1297
1298     /* Now test all 8 textures stage states */
1299     for(i = 0; i < 8; i++) {
1300         hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
1301         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %08x\n", i, hr);
1302     }
1303
1304     /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1305      * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1306      * but how do I test that?
1307      */
1308 cleanup:
1309     if(pTexture) IDirect3DTexture9_Release(pTexture);
1310     if(pD3d) IDirect3D9_Release(pD3d);
1311     if(pDevice) IDirect3D9_Release(pDevice);
1312     if(hwnd) DestroyWindow(hwnd);
1313 }
1314
1315 static void test_depthstenciltest(void)
1316 {
1317     HRESULT                      hr;
1318     HWND                         hwnd               = NULL;
1319     IDirect3D9                  *pD3d               = NULL;
1320     IDirect3DDevice9            *pDevice            = NULL;
1321     D3DPRESENT_PARAMETERS        d3dpp;
1322     D3DDISPLAYMODE               d3ddm;
1323     IDirect3DSurface9           *pDepthStencil           = NULL;
1324     IDirect3DSurface9           *pDepthStencil2          = NULL;
1325     D3DZBUFFERTYPE               state;
1326
1327     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1328     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1329     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1330     ok(hwnd != NULL, "Failed to create window\n");
1331     if (!pD3d || !hwnd) goto cleanup;
1332
1333     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1334     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1335     d3dpp.Windowed         = TRUE;
1336     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1337     d3dpp.BackBufferWidth  = 800;
1338     d3dpp.BackBufferHeight  = 600;
1339     d3dpp.BackBufferFormat = d3ddm.Format;
1340     d3dpp.EnableAutoDepthStencil = TRUE;
1341     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1342
1343     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1344                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1345     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1346     if(!pDevice)
1347     {
1348         skip("Failed to create a d3d device\n");
1349         goto cleanup;
1350     }
1351
1352     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1353     ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1354
1355     /* Try to clear */
1356     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1357     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1358
1359     hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
1360     ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1361
1362     /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
1363     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
1364     ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %08x\n", hr);
1365     if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
1366
1367     /* This left the render states untouched! */
1368     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1369     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1370     ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1371     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
1372     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1373     ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
1374     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
1375     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1376     ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
1377     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
1378     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1379     ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
1380
1381     /* This is supposed to fail now */
1382     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1383     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1384
1385     hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
1386     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1387
1388     hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
1389     ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %08x\n", hr);
1390
1391     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1392     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1393     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1394
1395     /* Now it works again */
1396     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1397     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1398
1399     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1400     if(pDevice) IDirect3D9_Release(pDevice);
1401
1402     /* Now see if autodepthstencil disable is honored. First, without a format set */
1403     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1404     d3dpp.Windowed         = TRUE;
1405     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1406     d3dpp.BackBufferWidth  = 800;
1407     d3dpp.BackBufferHeight  = 600;
1408     d3dpp.BackBufferFormat = d3ddm.Format;
1409     d3dpp.EnableAutoDepthStencil = FALSE;
1410     d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1411
1412     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1413                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1414     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1415     if(!pDevice)
1416     {
1417         skip("Failed to create a d3d device\n");
1418         goto cleanup;
1419     }
1420
1421     pDepthStencil = NULL;
1422     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1423     ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1424     if(pDepthStencil) {
1425         IDirect3DSurface9_Release(pDepthStencil);
1426         pDepthStencil = NULL;
1427     }
1428
1429     /* Check the depth test state */
1430     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1431     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1432     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1433
1434     if(pDevice) IDirect3D9_Release(pDevice);
1435
1436     /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
1437     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1438     d3dpp.Windowed         = TRUE;
1439     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1440     d3dpp.BackBufferWidth  = 800;
1441     d3dpp.BackBufferHeight  = 600;
1442     d3dpp.BackBufferFormat = d3ddm.Format;
1443     d3dpp.EnableAutoDepthStencil = FALSE;
1444     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1445
1446     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1447                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1448     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1449     if(!pDevice)
1450     {
1451         skip("Failed to create a d3d device\n");
1452         goto cleanup;
1453     }
1454
1455     pDepthStencil = NULL;
1456     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1457     ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %08x, surface = %p\n", hr, pDepthStencil);
1458     if(pDepthStencil) {
1459         IDirect3DSurface9_Release(pDepthStencil);
1460         pDepthStencil = NULL;
1461     }
1462
1463     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1464     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1465     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1466
1467 cleanup:
1468     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1469     if(pD3d) IDirect3D9_Release(pD3d);
1470     if(pDevice) IDirect3D9_Release(pDevice);
1471     if(hwnd) DestroyWindow(hwnd);
1472 }
1473
1474 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
1475 static void test_draw_indexed(void)
1476 {
1477     static const struct {
1478         float position[3];
1479         DWORD color;
1480     } quad[] = {
1481         {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1482         {{-1.0f,  1.0f, 0.0f}, 0xffff0000},
1483         {{ 1.0f,  1.0f, 0.0f}, 0xffff0000},
1484         {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1485     };
1486     WORD indices[] = {0, 1, 2, 3, 0, 2};
1487
1488     static const D3DVERTEXELEMENT9 decl_elements[] = {
1489         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1490         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1491         D3DDECL_END()
1492     };
1493
1494     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1495     IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1496     IDirect3DIndexBuffer9 *index_buffer = NULL;
1497     D3DPRESENT_PARAMETERS present_parameters;
1498     IDirect3DDevice9 *device = NULL;
1499     IDirect3D9 *d3d9;
1500     HRESULT hr;
1501     HWND hwnd;
1502     void *ptr;
1503
1504     hwnd = CreateWindow("static", "d3d9_test",
1505             0, 0, 0, 10, 10, 0, 0, 0, 0);
1506     if (!hwnd)
1507     {
1508         skip("Failed to create window\n");
1509         return;
1510     }
1511
1512     d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
1513     if (!d3d9)
1514     {
1515         skip("Failed to create IDirect3D9 object\n");
1516         goto cleanup;
1517     }
1518
1519     ZeroMemory(&present_parameters, sizeof(present_parameters));
1520     present_parameters.Windowed = TRUE;
1521     present_parameters.hDeviceWindow = hwnd;
1522     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1523
1524     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1525             NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
1526     if (FAILED(hr) || !device)
1527     {
1528         skip("Failed to create device\n");
1529         goto cleanup;
1530     }
1531
1532     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1533     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1534     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1535     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1536
1537     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
1538     ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
1539     hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1540     ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1541     memcpy(ptr, quad, sizeof(quad));
1542     hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
1543     ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1544     hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
1545     ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
1546
1547     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
1548     ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
1549     hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1550     ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1551     memcpy(ptr, indices, sizeof(indices));
1552     hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
1553     ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1555     ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
1556     hr = IDirect3DDevice9_BeginScene(device);
1557     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1558
1559     /* NULL index buffer. Should fail */
1560     hr = IDirect3DDevice9_SetIndices(device, NULL);
1561     ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1562     hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1563             4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1564     ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1565             hr, D3DERR_INVALIDCALL);
1566
1567     /* Valid index buffer, NULL vertex declaration. Should fail */
1568     hr = IDirect3DDevice9_SetIndices(device, index_buffer);
1569     ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1570     hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1571             4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1572     ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1573             hr, D3DERR_INVALIDCALL);
1574
1575     /* Valid index buffer and vertex declaration. Should succeed */
1576     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1577     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1578     hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1579             4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1580     ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
1581
1582     hr = IDirect3DDevice9_EndScene(device);
1583     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1584
1585     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1586     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1587
1588     IDirect3DVertexBuffer9_Release(vertex_buffer);
1589     IDirect3DIndexBuffer9_Release(index_buffer);
1590     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1591
1592 cleanup:
1593     if (d3d9) IDirect3D9_Release(d3d9);
1594     if (device) IDirect3DDevice9_Release(device);
1595     if (hwnd) DestroyWindow(hwnd);
1596 }
1597
1598 static void test_null_stream(void)
1599 {
1600     IDirect3DVertexBuffer9 *buffer = NULL;
1601     D3DPRESENT_PARAMETERS present_parameters;
1602     IDirect3DDevice9 *device = NULL;
1603     IDirect3D9 *d3d9;
1604     HWND hwnd;
1605     HRESULT hr;
1606     IDirect3DVertexShader9 *shader = NULL;
1607     IDirect3DVertexDeclaration9 *decl = NULL;
1608     DWORD shader_code[] = {
1609         0xfffe0101,                             /* vs_1_1           */
1610         0x0000001f, 0x80000000, 0x900f0000,     /* dcl_position v0  */
1611         0x00000001, 0xc00f0000, 0x90e40000,     /* mov oPos, v0     */
1612         0x0000ffff                              /* end              */
1613     };
1614     static const D3DVERTEXELEMENT9 decl_elements[] = {
1615         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1616         {1, 0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1617         D3DDECL_END()
1618     };
1619
1620     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1621     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1622     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1623     ok(hwnd != NULL, "Failed to create window\n");
1624     if (!d3d9 || !hwnd) goto cleanup;
1625
1626     ZeroMemory(&present_parameters, sizeof(present_parameters));
1627     present_parameters.Windowed = TRUE;
1628     present_parameters.hDeviceWindow = hwnd;
1629     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1630
1631     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1632                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
1633     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1634     if(!device)
1635     {
1636         skip("Failed to create a d3d device\n");
1637         goto cleanup;
1638     }
1639
1640     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1641     if(FAILED(hr)) {
1642         skip("No vertex shader support\n");
1643         goto cleanup;
1644     }
1645     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1646     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
1647     if (!SUCCEEDED(hr)) {
1648         skip("Vertex declaration handling not possible.\n");
1649         goto cleanup;
1650     }
1651     hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
1652     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
1653     if (!SUCCEEDED(hr)) {
1654         skip("Vertex buffer handling not possible.\n");
1655         goto cleanup;
1656     }
1657
1658     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
1659     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
1660     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
1661     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
1662     hr = IDirect3DDevice9_SetVertexShader(device, shader);
1663     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
1664     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
1665     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
1666
1667     hr = IDirect3DDevice9_BeginScene(device);
1668     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr);
1669     if(SUCCEEDED(hr)) {
1670         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
1671         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr);
1672
1673         hr = IDirect3DDevice9_EndScene(device);
1674         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr);
1675     }
1676
1677     IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1678     IDirect3DDevice9_SetVertexShader(device, NULL);
1679     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1680
1681 cleanup:
1682     if(decl) IDirect3DVertexDeclaration9_Release(decl);
1683     if(shader) IDirect3DVertexShader9_Release(shader);
1684     if(device) IDirect3DDevice9_Release(device);
1685     if(d3d9) IDirect3D9_Release(d3d9);
1686 }
1687
1688 static inline const char *debug_d3dpool(D3DPOOL pool) {
1689     switch(pool) {
1690         case D3DPOOL_DEFAULT: return "D3DPOOL_DEFAULT";
1691         case D3DPOOL_SYSTEMMEM: return "D3DPOOL_SYSTEMMEM";
1692         case D3DPOOL_SCRATCH: return "D3DPOOL_SCRATCH";
1693         case D3DPOOL_MANAGED: return "D3DPOOL_MANAGED";
1694         default:
1695         return "unknown pool";
1696     }
1697 }
1698
1699 static void test_vertex_buffer_alignment(void)
1700 {
1701     IDirect3DVertexBuffer9 *buffer = NULL;
1702     D3DPRESENT_PARAMETERS present_parameters;
1703     IDirect3DDevice9 *device = NULL;
1704     IDirect3D9 *d3d9;
1705     HWND hwnd;
1706     HRESULT hr;
1707     D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
1708     DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
1709     unsigned int i, j;
1710     void *data;
1711
1712     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1713     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1714     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1715     ok(hwnd != NULL, "Failed to create window\n");
1716     if (!d3d9 || !hwnd) goto cleanup;
1717
1718     ZeroMemory(&present_parameters, sizeof(present_parameters));
1719     present_parameters.Windowed = TRUE;
1720     present_parameters.hDeviceWindow = hwnd;
1721     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1722
1723     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1724                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
1725     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1726     if(!device)
1727     {
1728         skip("Failed to create a d3d device\n");
1729         goto cleanup;
1730     }
1731
1732     for(i = 0; i < (sizeof(sizes) / sizeof(sizes[0])); i++) {
1733         for(j = 0; j < (sizeof(pools) / sizeof(pools[0])); j++) {
1734             hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
1735             if(pools[j] == D3DPOOL_SCRATCH) {
1736                 ok(hr == D3DERR_INVALIDCALL, "Creating a D3DPOOL_SCRATCH buffer returned (0x%08x)\n", hr);
1737             } else {
1738                 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x). Pool = %s, size %d\n", hr,
1739                    debug_d3dpool(pools[j]), sizes[i]);
1740             }
1741             if(FAILED(hr)) continue;
1742
1743             hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, (void **) &data, 0);
1744             ok(SUCCEEDED(hr), "IDirect3DVertexBuffer9_Lock failed (0x%08x)\n", hr);
1745             ok(((DWORD_PTR) data & 31) == 0, "Vertex buffer start address is not 32 byte aligned(size: %d, pool: %s, data: %p)\n",
1746                sizes[i], debug_d3dpool(pools[j]), data);
1747             hr = IDirect3DVertexBuffer9_Unlock(buffer);
1748             ok(SUCCEEDED(hr), "IDirect3DVertexBuffer9_Unlock failed (0x%08x)\n", hr);
1749
1750             if(buffer) IDirect3DVertexBuffer9_Release(buffer);
1751         }
1752     }
1753
1754     cleanup:
1755     if(d3d9) IDirect3D9_Release(d3d9);
1756 }
1757
1758 static void test_lights(void)
1759 {
1760     D3DPRESENT_PARAMETERS present_parameters;
1761     IDirect3DDevice9 *device = NULL;
1762     IDirect3D9 *d3d9;
1763     HWND hwnd;
1764     HRESULT hr;
1765     unsigned int i;
1766     BOOL enabled;
1767     D3DCAPS9 caps;
1768
1769     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1770     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1771     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1772     ok(hwnd != NULL, "Failed to create window\n");
1773     if (!d3d9 || !hwnd) goto cleanup;
1774
1775     ZeroMemory(&present_parameters, sizeof(present_parameters));
1776     present_parameters.Windowed = TRUE;
1777     present_parameters.hDeviceWindow = hwnd;
1778     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1779
1780     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
1781                                   D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &present_parameters, &device );
1782     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
1783        "IDirect3D9_CreateDevice failed with %08x\n", hr);
1784     if(!device)
1785     {
1786         skip("Failed to create a d3d device\n");
1787         goto cleanup;
1788     }
1789
1790     memset(&caps, 0, sizeof(caps));
1791     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1792     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
1793
1794     for(i = 1; i <= caps.MaxActiveLights; i++) {
1795         hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
1796         ok(hr == D3D_OK, "Enabling light %u failed with %08x\n", i, hr);
1797         hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
1798         ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i, hr);
1799         ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
1800     }
1801
1802     /* TODO: Test the rendering results in this situation */
1803     hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
1804     ok(hr == D3D_OK, "Enabling one light more than supported returned %08x\n", hr);
1805     hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
1806     ok(hr == D3D_OK, "GetLightEnable on light %u failed with %08x\n", i + 1, hr);
1807     ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
1808     hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
1809     ok(hr == D3D_OK, "Disabling the additional returned %08x\n", hr);
1810
1811     for(i = 1; i <= caps.MaxActiveLights; i++) {
1812         hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
1813         ok(hr == D3D_OK, "Disabling light %u failed with %08x\n", i, hr);
1814     }
1815
1816     cleanup:
1817     if(device) IDirect3DDevice9_Release(device);
1818     if(d3d9) IDirect3D9_Release(d3d9);
1819 }
1820
1821 static void test_set_stream_source(void)
1822 {
1823     D3DPRESENT_PARAMETERS present_parameters;
1824     IDirect3DDevice9 *device = NULL;
1825     IDirect3D9 *d3d9;
1826     HWND hwnd;
1827     HRESULT hr;
1828     IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
1829
1830     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1831     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1832     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1833     ok(hwnd != NULL, "Failed to create window\n");
1834     if (!d3d9 || !hwnd) goto cleanup;
1835
1836     ZeroMemory(&present_parameters, sizeof(present_parameters));
1837     present_parameters.Windowed = TRUE;
1838     present_parameters.hDeviceWindow = hwnd;
1839     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1840
1841     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
1842                                   D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
1843     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE || hr == D3DERR_INVALIDCALL,
1844        "IDirect3D9_CreateDevice failed with %08x\n", hr);
1845     if(!device)
1846     {
1847         hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd,
1848                                       D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
1849         ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %08x\n", hr);
1850         if(!device)
1851         {
1852             skip("Failed to create a d3d device\n");
1853             goto cleanup;
1854         }
1855     }
1856
1857     hr = IDirect3DDevice9_CreateVertexBuffer( device, 512, 0, 0, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
1858     ok(hr == D3D_OK, "Failed to create a vertex buffer, hr = %08x\n", hr);
1859     if (SUCCEEDED(hr)) {
1860         /* Some cards(Geforce 7400 at least) accept non-aligned offsets, others(radeon 9000 verified) reject it,
1861          * so accept both results. Wine currently rejects this to be able to optimize the vbo conversion, but writes
1862          * a WARN
1863          */
1864         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 32);
1865         ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
1866         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 1, 32);
1867         ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
1868         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 2, 32);
1869         ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
1870         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 3, 32);
1871         ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
1872         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 4, 32);
1873         ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
1874     }
1875     /* Try to set the NULL buffer with an offset and stride 0 */
1876     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1877     ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %08x\n", hr);
1878     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
1879     ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 1, hr = %08x\n", hr);
1880     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
1881     ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 2, hr = %08x\n", hr);
1882     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
1883     ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Unexpected result when setting the stream source, offset 3, hr = %08x\n", hr);
1884     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
1885     ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
1886
1887     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1888     ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %08x\n", hr);
1889
1890     if(pVertexBuffer) IDirect3DDevice9_Release(pVertexBuffer);
1891 cleanup:
1892     if(device) IDirect3DDevice9_Release(device);
1893     if(d3d9) IDirect3D9_Release(d3d9);
1894 }
1895
1896 struct formats {
1897     D3DFORMAT DisplayFormat;
1898     D3DFORMAT BackBufferFormat;
1899     BOOL shouldPass;
1900 };
1901
1902 struct formats r5g6b5_format_list[] =
1903 {
1904     { D3DFMT_R5G6B5, D3DFMT_R5G6B5, TRUE },
1905     { D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, FALSE },
1906     { D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, FALSE },
1907     { D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, FALSE },
1908     { D3DFMT_R5G6B5, D3DFMT_A8R8G8B8, FALSE },
1909     { 0, 0, 0}
1910 };
1911
1912 struct formats x1r5g5b5_format_list[] =
1913 {
1914     { D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, FALSE },
1915     { D3DFMT_X1R5G5B5, D3DFMT_X1R5G5B5, TRUE },
1916     { D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE },
1917     { D3DFMT_X1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
1918     { D3DFMT_X1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
1919
1920     /* A1R5G5B5 should not be usable as a display format, it is backbuffer-only */
1921     { D3DFMT_A1R5G5B5, D3DFMT_R5G6B5, FALSE },
1922     { D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5, FALSE },
1923     { D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE },
1924     { D3DFMT_A1R5G5B5, D3DFMT_X8R8G8B8, FALSE },
1925     { D3DFMT_A1R5G5B5, D3DFMT_A8R8G8B8, FALSE },
1926     { 0, 0, 0}
1927 };
1928
1929 struct formats x8r8g8b8_format_list[] =
1930 {
1931     { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, FALSE },
1932     { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
1933     { D3DFMT_X8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
1934     { D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, TRUE },
1935     { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE },
1936
1937     /* A1R8G8B8 should not be usable as a display format, it is backbuffer-only */
1938     { D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, FALSE },
1939     { D3DFMT_A8R8G8B8, D3DFMT_X1R5G5B5, FALSE },
1940     { D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, FALSE },
1941     { D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE },
1942     { D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE },
1943     { 0, 0, 0}
1944 };
1945
1946 static void test_display_formats()
1947 {
1948     /* Direct3D9 offers 4 display formats R5G6B5, X1R5G5B5, X8R8G8B8 and A2R10G10B10.
1949      * Next to these there are 6 different backbuffer formats. Only a fixed number of
1950      * combinations are possible in FULLSCREEN mode. In windowed mode more combinations are
1951      * allowed due to depth conversion and this is likely driver dependent.
1952      * This test checks which combinations are possible in fullscreen mode and this should not be driver dependent.
1953      * TODO: handle A2R10G10B10 but what hardware supports it? Parhelia? It is very rare. */
1954
1955     UINT Adapter = D3DADAPTER_DEFAULT;
1956     D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
1957     int i, nmodes;
1958     HRESULT hr;
1959
1960     IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1961     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1962     if(!d3d9) return;
1963
1964     nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_R5G6B5);
1965     if(!nmodes) {
1966         skip("Display format R5G6B5 not supported, skipping\n");
1967     } else {
1968         trace("Testing display format R5G6B5\n");
1969         for(i=0; r5g6b5_format_list[i].DisplayFormat != 0; i++)
1970         {
1971             hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, FALSE);
1972
1973             if(r5g6b5_format_list[i].shouldPass)
1974                 ok(hr == D3D_OK ||
1975                    broken(hr == D3DERR_NOTAVAILABLE),
1976                    "format %d %d didn't pass with hr=%#08x\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, hr);
1977             else
1978                 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);
1979         }
1980     }
1981
1982     nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X1R5G5B5);
1983     if(!nmodes) {
1984         skip("Display format X1R5G5B5 not supported, skipping\n");
1985     } else {
1986         trace("Testing display format X1R5G5B5\n");
1987         for(i=0; x1r5g5b5_format_list[i].DisplayFormat != 0; i++)
1988         {
1989             hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, FALSE);
1990
1991             if(x1r5g5b5_format_list[i].shouldPass)
1992                 ok(hr == D3D_OK, "format %d %d didn't pass with hr=%#08x\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, hr);
1993             else
1994                 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);
1995         }
1996     }
1997
1998     nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
1999     if(!nmodes) {
2000         skip("Display format X8R8G8B8 not supported, skipping\n");
2001     } else {
2002         trace("Testing display format X8R8G8B8\n");
2003         for(i=0; x8r8g8b8_format_list[i].DisplayFormat != 0; i++)
2004         {
2005             hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, FALSE);
2006
2007             if(x8r8g8b8_format_list[i].shouldPass)
2008                 ok(hr == D3D_OK ||
2009                    broken(hr == D3DERR_NOTAVAILABLE),
2010                    "format %d %d didn't pass with hr=%#08x\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr);
2011             else
2012                 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);
2013         }
2014     }
2015
2016     if(d3d9) IDirect3D9_Release(d3d9);
2017 }
2018
2019 START_TEST(device)
2020 {
2021     HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
2022     if (!d3d9_handle)
2023     {
2024         skip("Could not load d3d9.dll\n");
2025         return;
2026     }
2027
2028     pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
2029     ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
2030     if (pDirect3DCreate9)
2031     {
2032         test_display_formats();
2033         test_display_modes();
2034         test_swapchain();
2035         test_refcount();
2036         test_mipmap_levels();
2037         test_cursor();
2038         test_reset();
2039         test_reset();
2040         test_scene();
2041         test_limits();
2042         test_depthstenciltest();
2043         test_draw_indexed();
2044         test_null_stream();
2045         test_vertex_buffer_alignment();
2046         test_lights();
2047         test_set_stream_source();
2048     }
2049 }