d3d9: Initialize pVertexBuffer.
[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 <dxerr9.h>
25 #include "wine/test.h"
26
27 static IDirect3D9 *(WINAPI *pDirect3DCreate9)(UINT);
28
29 static int get_refcount(IUnknown *object)
30 {
31     IUnknown_AddRef( object );
32     return IUnknown_Release( object );
33 }
34
35 #define CHECK_CALL(r,c,d,rc) \
36     if (SUCCEEDED(r)) {\
37         int tmp1 = get_refcount( (IUnknown *)d ); \
38         int rc_new = rc; \
39         ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
40     } else {\
41         trace("%s failed: %s\n", c, DXGetErrorString9(r)); \
42     }
43
44 #define CHECK_RELEASE(obj,d,rc) \
45     if (obj) { \
46         int tmp1, rc_new = rc; \
47         IUnknown_Release( obj ); \
48         tmp1 = get_refcount( (IUnknown *)d ); \
49         ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
50     }
51
52 #define CHECK_REFCOUNT(obj,rc) \
53     { \
54         int rc_new = rc; \
55         int count = get_refcount( (IUnknown *)obj ); \
56         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
57     }
58
59 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
60     { \
61         int rc_new = rc; \
62         int count = IUnknown_Release( (IUnknown *)obj ); \
63         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
64     }
65
66 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
67     { \
68         int rc_new = rc; \
69         int count = IUnknown_AddRef( (IUnknown *)obj ); \
70         ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
71     }
72
73 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
74     { \
75         void *container_ptr = (void *)0x1337c0d3; \
76         hr = IDirect3DSurface9_GetContainer(obj, &iid, &container_ptr); \
77         ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#x, container_ptr %p. " \
78             "Expected hr %#x, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
79         if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
80     }
81
82 static void check_mipmap_levels(
83     IDirect3DDevice9* device, 
84     int width, int height, int count) 
85 {
86
87     IDirect3DBaseTexture9* texture = NULL;
88     HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0, 
89         D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL );
90        
91     if (SUCCEEDED(hr)) {
92         DWORD levels = IDirect3DBaseTexture9_GetLevelCount(texture);
93         ok(levels == count, "Invalid level count. Expected %d got %u\n", count, levels);
94     } else 
95         trace("CreateTexture failed: %s\n", DXGetErrorString9(hr));
96
97     if (texture) IUnknown_Release( texture );
98 }
99
100 static void test_mipmap_levels(void)
101 {
102
103     HRESULT               hr;
104     HWND                  hwnd = NULL;
105
106     IDirect3D9            *pD3d = NULL;
107     IDirect3DDevice9      *pDevice = NULL;
108     D3DPRESENT_PARAMETERS d3dpp;
109     D3DDISPLAYMODE        d3ddm;
110  
111     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
112     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
113     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
114     ok(hwnd != NULL, "Failed to create window\n");
115     if (!pD3d || !hwnd) goto cleanup;
116
117     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
118     ZeroMemory( &d3dpp, sizeof(d3dpp) );
119     d3dpp.Windowed         = TRUE;
120     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
121     d3dpp.BackBufferFormat = d3ddm.Format;
122
123     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
124                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
125     ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
126     if (FAILED(hr)) goto cleanup;
127
128     check_mipmap_levels(pDevice, 32, 32, 6);
129     check_mipmap_levels(pDevice, 256, 1, 9);
130     check_mipmap_levels(pDevice, 1, 256, 9);
131     check_mipmap_levels(pDevice, 1, 1, 1);
132
133     cleanup:
134     if (pD3d)     IUnknown_Release( pD3d );
135     if (pDevice)  IUnknown_Release( pDevice );
136     DestroyWindow( hwnd );
137 }
138
139 static void test_swapchain(void)
140 {
141     HRESULT                      hr;
142     HWND                         hwnd               = NULL;
143     IDirect3D9                  *pD3d               = NULL;
144     IDirect3DDevice9            *pDevice            = NULL;
145     IDirect3DSwapChain9         *swapchain0         = NULL;
146     IDirect3DSwapChain9         *swapchain1         = NULL;
147     IDirect3DSwapChain9         *swapchain2         = NULL;
148     IDirect3DSwapChain9         *swapchain3         = NULL;
149     IDirect3DSwapChain9         *swapchainX         = NULL;
150     IDirect3DSurface9           *backbuffer         = NULL;
151     D3DPRESENT_PARAMETERS        d3dpp;
152     D3DDISPLAYMODE               d3ddm;
153
154     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
155     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
156     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
157     ok(hwnd != NULL, "Failed to create window\n");
158     if (!pD3d || !hwnd) goto cleanup;
159
160     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
161     ZeroMemory( &d3dpp, sizeof(d3dpp) );
162     d3dpp.Windowed         = TRUE;
163     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
164     d3dpp.BackBufferFormat = d3ddm.Format;
165     d3dpp.BackBufferCount  = 0;
166
167     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
168                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
169     ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(hr));
201
202     d3dpp.BackBufferCount  = 2;
203     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3);
204     ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(hr));
236     ok(backbuffer != NULL, "The back buffer is NULL (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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 static void test_refcount(void)
283 {
284     HRESULT                      hr;
285     HWND                         hwnd               = NULL;
286     IDirect3D9                  *pD3d               = NULL;
287     IDirect3DDevice9            *pDevice            = NULL;
288     IDirect3DVertexBuffer9      *pVertexBuffer      = NULL;
289     IDirect3DIndexBuffer9       *pIndexBuffer       = NULL;
290     IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
291     IDirect3DVertexShader9      *pVertexShader      = NULL;
292     IDirect3DPixelShader9       *pPixelShader       = NULL;
293     IDirect3DCubeTexture9       *pCubeTexture       = NULL;
294     IDirect3DTexture9           *pTexture           = NULL;
295     IDirect3DVolumeTexture9     *pVolumeTexture     = NULL;
296     IDirect3DVolume9            *pVolumeLevel       = NULL;
297     IDirect3DSurface9           *pStencilSurface    = NULL;
298     IDirect3DSurface9           *pOffscreenSurface  = NULL;
299     IDirect3DSurface9           *pRenderTarget      = NULL;
300     IDirect3DSurface9           *pRenderTarget2     = NULL;
301     IDirect3DSurface9           *pRenderTarget3     = NULL;
302     IDirect3DSurface9           *pTextureLevel      = NULL;
303     IDirect3DSurface9           *pBackBuffer        = NULL;
304     IDirect3DStateBlock9        *pStateBlock        = NULL;
305     IDirect3DStateBlock9        *pStateBlock1       = NULL;
306     IDirect3DSwapChain9         *pSwapChain         = NULL;
307     IDirect3DQuery9             *pQuery             = NULL;
308     D3DPRESENT_PARAMETERS        d3dpp;
309     D3DDISPLAYMODE               d3ddm;
310     int                          refcount = 0, tmp;
311
312     D3DVERTEXELEMENT9 decl[] =
313     {
314         D3DDECL_END()
315     };
316     static DWORD simple_vs[] = {0xFFFE0101,             /* vs_1_1               */
317         0x0000001F, 0x80000000, 0x900F0000,             /* dcl_position0 v0     */
318         0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0   */
319         0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1   */
320         0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2   */
321         0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3   */
322         0x0000FFFF};                                    /* END                  */
323     static DWORD simple_ps[] = {0xFFFF0101,                                     /* ps_1_1                       */
324         0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0  */
325         0x00000042, 0xB00F0000,                                                 /* tex t0                       */
326         0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000,                         /* dp3 r0, c1, c0               */
327         0x00000005, 0x800F0000, 0x90E40000, 0x80E40000,                         /* mul r0, v0, r0               */
328         0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000,                         /* mul r0, t0, r0               */
329         0x0000FFFF};                                                            /* END                          */
330
331
332     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
333     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
334     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
335     ok(hwnd != NULL, "Failed to create window\n");
336     if (!pD3d || !hwnd) goto cleanup;
337
338     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
339     ZeroMemory( &d3dpp, sizeof(d3dpp) );
340     d3dpp.Windowed         = TRUE;
341     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
342     d3dpp.BackBufferFormat = d3ddm.Format;
343     d3dpp.EnableAutoDepthStencil = TRUE;
344     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
345
346     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
347                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
348     ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
349     if (FAILED(hr)) goto cleanup;
350
351     refcount = get_refcount( (IUnknown *)pDevice );
352     ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
353
354     /**
355      * Check refcount of implicit surfaces and implicit swapchain. Findings:
356      *   - the container is the device OR swapchain
357      *   - they hold a refernce to the device
358      *   - they are created with a refcount of 0 (Get/Release returns orignial refcount)
359      *   - they are not freed if refcount reaches 0.
360      *   - the refcount is not forwarded to the container.
361      */
362     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapChain);
363     CHECK_CALL( hr, "GetSwapChain", pDevice, ++refcount);
364     if (pSwapChain)
365     {
366         CHECK_REFCOUNT( pSwapChain, 1);
367
368         hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
369         CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
370         CHECK_REFCOUNT( pSwapChain, 1);
371         if(pRenderTarget)
372         {
373             CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
374             CHECK_REFCOUNT( pRenderTarget, 1);
375
376             CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
377             CHECK_REFCOUNT(pDevice, refcount);
378             CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
379             CHECK_REFCOUNT(pDevice, refcount);
380
381             hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
382             CHECK_CALL( hr, "GetRenderTarget", pDevice, refcount);
383             CHECK_REFCOUNT( pRenderTarget, 2);
384             CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
385             CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
386             CHECK_REFCOUNT( pDevice, --refcount);
387
388             /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
389             CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
390             CHECK_REFCOUNT(pDevice, ++refcount);
391             CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
392             CHECK_REFCOUNT(pDevice, --refcount);
393         }
394
395         /* Render target and back buffer are identical. */
396         hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, 0, &pBackBuffer);
397         CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
398         if(pBackBuffer)
399         {
400             CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
401             ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
402             pRenderTarget, pBackBuffer);
403             pBackBuffer = NULL;
404         }
405         CHECK_REFCOUNT( pDevice, --refcount);
406
407         hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pStencilSurface);
408         CHECK_CALL( hr, "GetDepthStencilSurface", pDevice, ++refcount);
409         CHECK_REFCOUNT( pSwapChain, 1);
410         if(pStencilSurface)
411         {
412             CHECK_SURFACE_CONTAINER( pStencilSurface, IID_IDirect3DDevice9, pDevice);
413             CHECK_REFCOUNT( pStencilSurface, 1);
414
415             CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
416             CHECK_REFCOUNT(pDevice, refcount);
417             CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
418             CHECK_REFCOUNT(pDevice, refcount);
419
420             CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
421             CHECK_REFCOUNT( pDevice, --refcount);
422
423             /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
424             CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
425             CHECK_REFCOUNT(pDevice, ++refcount);
426             CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
427             CHECK_REFCOUNT(pDevice, --refcount);
428             pStencilSurface = NULL;
429         }
430
431         CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
432         CHECK_REFCOUNT( pDevice, --refcount);
433
434         /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
435         CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
436         CHECK_REFCOUNT(pDevice, ++refcount);
437         CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
438         CHECK_REFCOUNT(pDevice, --refcount);
439         pSwapChain = NULL;
440     }
441
442     /* Buffers */
443     hr = IDirect3DDevice9_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL );
444     CHECK_CALL( hr, "CreateIndexBuffer", pDevice, ++refcount );
445     if(pIndexBuffer)
446     {
447         tmp = get_refcount( (IUnknown *)pIndexBuffer );
448
449         hr = IDirect3DDevice9_SetIndices(pDevice, pIndexBuffer);
450         CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
451         hr = IDirect3DDevice9_SetIndices(pDevice, NULL);
452         CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
453     }
454
455     hr = IDirect3DDevice9_CreateVertexBuffer( pDevice, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
456     CHECK_CALL( hr, "CreateVertexBuffer", pDevice, ++refcount );
457     if(pVertexBuffer)
458     {
459         IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
460         UINT offset = ~0;
461         UINT stride = ~0;
462
463         tmp = get_refcount( (IUnknown *)pVertexBuffer );
464
465         hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, pVertexBuffer, 0, 3 * sizeof(float));
466         CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
467         hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, NULL, 0, 0);
468         CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
469
470         hr = IDirect3DDevice9_GetStreamSource(pDevice, 0, &pVBuf, &offset, &stride);
471         ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
472         ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
473         ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
474         ok(offset==0, "offset not 0 (got %u)!\n", offset);
475     }
476     /* Shaders */
477     hr = IDirect3DDevice9_CreateVertexDeclaration( pDevice, decl, &pVertexDeclaration );
478     CHECK_CALL( hr, "CreateVertexDeclaration", pDevice, ++refcount );
479     hr = IDirect3DDevice9_CreateVertexShader( pDevice, simple_vs, &pVertexShader );
480     CHECK_CALL( hr, "CreateVertexShader", pDevice, ++refcount );
481     hr = IDirect3DDevice9_CreatePixelShader( pDevice, simple_ps, &pPixelShader );
482     CHECK_CALL( hr, "CreatePixelShader", pDevice, ++refcount );
483     /* Textures */
484     hr = IDirect3DDevice9_CreateTexture( pDevice, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL );
485     CHECK_CALL( hr, "CreateTexture", pDevice, ++refcount );
486     if (pTexture)
487     {
488         tmp = get_refcount( (IUnknown *)pTexture );
489
490         /* SetTexture should not increase refcounts */
491         hr = IDirect3DDevice9_SetTexture(pDevice, 0, (IDirect3DBaseTexture9 *) pTexture);
492         CHECK_CALL( hr, "SetTexture", pTexture, tmp);
493         hr = IDirect3DDevice9_SetTexture(pDevice, 0, NULL);
494         CHECK_CALL( hr, "SetTexture", pTexture, tmp);
495
496         /* This should not increment device refcount */
497         hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
498         CHECK_CALL( hr, "GetSurfaceLevel", pDevice, refcount );
499         /* But should increment texture's refcount */
500         CHECK_REFCOUNT( pTexture, tmp+1 );
501         /* Because the texture and surface refcount are identical */
502         if (pTextureLevel)
503         {
504             CHECK_REFCOUNT        ( pTextureLevel, tmp+1 );
505             CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
506             CHECK_REFCOUNT        ( pTexture     , tmp+2 );
507             CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
508             CHECK_REFCOUNT        ( pTexture     , tmp+1 );
509             CHECK_RELEASE_REFCOUNT( pTexture     , tmp   );
510             CHECK_REFCOUNT        ( pTextureLevel, tmp   );
511         }
512     }
513     hr = IDirect3DDevice9_CreateCubeTexture( pDevice, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL );
514     CHECK_CALL( hr, "CreateCubeTexture", pDevice, ++refcount );
515     hr = IDirect3DDevice9_CreateVolumeTexture( pDevice, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL );
516     CHECK_CALL( hr, "CreateVolumeTexture", pDevice, ++refcount );
517     if (pVolumeTexture)
518     {
519         tmp = get_refcount( (IUnknown *)pVolumeTexture );
520
521         /* This should not increment device refcount */
522         hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
523         CHECK_CALL( hr, "GetVolumeLevel", pDevice, refcount );
524         /* But should increment volume texture's refcount */
525         CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
526         /* Because the volume texture and volume refcount are identical */
527         if (pVolumeLevel)
528         {
529             CHECK_REFCOUNT        ( pVolumeLevel  , tmp+1 );
530             CHECK_ADDREF_REFCOUNT ( pVolumeLevel  , tmp+2 );
531             CHECK_REFCOUNT        ( pVolumeTexture, tmp+2 );
532             CHECK_RELEASE_REFCOUNT( pVolumeLevel  , tmp+1 );
533             CHECK_REFCOUNT        ( pVolumeTexture, tmp+1 );
534             CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp   );
535             CHECK_REFCOUNT        ( pVolumeLevel  , tmp   );
536         }
537     }
538     /* Surfaces */
539     hr = IDirect3DDevice9_CreateDepthStencilSurface( pDevice, 32, 32, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL );
540     CHECK_CALL( hr, "CreateDepthStencilSurface", pDevice, ++refcount );
541     CHECK_REFCOUNT( pStencilSurface, 1 );
542     hr = IDirect3DDevice9_CreateOffscreenPlainSurface( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL );
543     CHECK_CALL( hr, "CreateOffscreenPlainSurface", pDevice, ++refcount );
544     CHECK_REFCOUNT( pOffscreenSurface, 1 );
545     hr = IDirect3DDevice9_CreateRenderTarget( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL );
546     CHECK_CALL( hr, "CreateRenderTarget", pDevice, ++refcount );
547     CHECK_REFCOUNT( pRenderTarget3, 1 );
548     /* Misc */
549     hr = IDirect3DDevice9_CreateStateBlock( pDevice, D3DSBT_ALL, &pStateBlock );
550     CHECK_CALL( hr, "CreateStateBlock", pDevice, ++refcount );
551     hr = IDirect3DDevice9_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
552     CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, ++refcount );
553     if(pSwapChain)
554     {
555         /* check implicit back buffer */
556         hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
557         CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
558         CHECK_REFCOUNT( pSwapChain, 1);
559         if(pBackBuffer)
560         {
561             CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
562             CHECK_REFCOUNT( pBackBuffer, 1);
563             CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
564             CHECK_REFCOUNT( pDevice, --refcount);
565
566             /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
567             CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
568             CHECK_REFCOUNT(pDevice, ++refcount);
569             CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
570             CHECK_REFCOUNT(pDevice, --refcount);
571             pBackBuffer = NULL;
572         }
573         CHECK_REFCOUNT( pSwapChain, 1);
574     }
575     hr = IDirect3DDevice9_CreateQuery( pDevice, D3DQUERYTYPE_EVENT, &pQuery );
576     CHECK_CALL( hr, "CreateQuery", pDevice, ++refcount );
577
578     hr = IDirect3DDevice9_BeginStateBlock( pDevice );
579     CHECK_CALL( hr, "BeginStateBlock", pDevice, refcount );
580     hr = IDirect3DDevice9_EndStateBlock( pDevice, &pStateBlock1 );
581     CHECK_CALL( hr, "EndStateBlock", pDevice, ++refcount );
582
583     /* The implicit render target is not freed if refcount reaches 0.
584      * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
585     hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget2);
586     CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
587     if(pRenderTarget2)
588     {
589         CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
590         ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
591            pRenderTarget, pRenderTarget2);
592         CHECK_REFCOUNT( pDevice, --refcount);
593         pRenderTarget2 = NULL;
594     }
595     pRenderTarget = NULL;
596
597 cleanup:
598     CHECK_RELEASE(pDevice,              pDevice, --refcount);
599
600     /* Buffers */
601     CHECK_RELEASE(pVertexBuffer,        pDevice, --refcount);
602     CHECK_RELEASE(pIndexBuffer,         pDevice, --refcount);
603     /* Shaders */
604     CHECK_RELEASE(pVertexDeclaration,   pDevice, --refcount);
605     CHECK_RELEASE(pVertexShader,        pDevice, --refcount);
606     CHECK_RELEASE(pPixelShader,         pDevice, --refcount);
607     /* Textures */
608     CHECK_RELEASE(pTextureLevel,        pDevice, --refcount);
609     CHECK_RELEASE(pCubeTexture,         pDevice, --refcount);
610     CHECK_RELEASE(pVolumeTexture,       pDevice, --refcount);
611     /* Surfaces */
612     CHECK_RELEASE(pStencilSurface,      pDevice, --refcount);
613     CHECK_RELEASE(pOffscreenSurface,    pDevice, --refcount);
614     CHECK_RELEASE(pRenderTarget3,       pDevice, --refcount);
615     /* Misc */
616     CHECK_RELEASE(pStateBlock,          pDevice, --refcount);
617     CHECK_RELEASE(pSwapChain,           pDevice, --refcount);
618     CHECK_RELEASE(pQuery,               pDevice, --refcount);
619     /* This will destroy device - cannot check the refcount here */
620     if (pStateBlock1)         CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
621
622     if (pD3d)                 CHECK_RELEASE_REFCOUNT( pD3d, 0);
623
624     DestroyWindow( hwnd );
625 }
626
627 static void test_cursor(void)
628 {
629     HRESULT                      hr;
630     HWND                         hwnd               = NULL;
631     IDirect3D9                  *pD3d               = NULL;
632     IDirect3DDevice9            *pDevice            = NULL;
633     D3DPRESENT_PARAMETERS        d3dpp;
634     D3DDISPLAYMODE               d3ddm;
635     CURSORINFO                   info;
636     IDirect3DSurface9 *cursor = NULL;
637     HCURSOR cur;
638
639     memset(&info, 0, sizeof(info));
640     info.cbSize = sizeof(info);
641     hr = GetCursorInfo(&info);
642     cur = info.hCursor;
643
644     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
645     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
646     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
647     ok(hwnd != NULL, "Failed to create window\n");
648     if (!pD3d || !hwnd) goto cleanup;
649
650     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
651     ZeroMemory( &d3dpp, sizeof(d3dpp) );
652     d3dpp.Windowed         = TRUE;
653     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
654     d3dpp.BackBufferFormat = d3ddm.Format;
655
656     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
657                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
658     ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
659     if (FAILED(hr)) goto cleanup;
660
661     IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, 0);
662     ok(cursor != NULL, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
663
664     /* Initially hidden */
665     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
666     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
667
668     /* Not enabled without a surface*/
669     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
670     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
671
672     /* Fails */
673     hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, NULL);
674     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
675
676     hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, cursor);
677     ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
678
679     IDirect3DSurface9_Release(cursor);
680
681     memset(&info, 0, sizeof(info));
682     info.cbSize = sizeof(info);
683     hr = GetCursorInfo(&info);
684     ok(hr != 0, "GetCursorInfo returned %08x\n", hr);
685     ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
686     ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
687
688     /* Still hidden */
689     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
690     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
691
692     /* Enabled now*/
693     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
694     ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
695
696     /* GDI cursor unchanged */
697     memset(&info, 0, sizeof(info));
698     info.cbSize = sizeof(info);
699     hr = GetCursorInfo(&info);
700     ok(hr != 0, "GetCursorInfo returned %08x\n", hr);
701     ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
702     ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
703
704 cleanup:
705     if(pDevice) IDirect3D9_Release(pDevice);
706     if(pD3d) IDirect3D9_Release(pD3d);
707     DestroyWindow( hwnd );
708 }
709
710 static void test_reset(void)
711 {
712     HRESULT                      hr;
713     HWND                         hwnd               = NULL;
714     IDirect3D9                  *pD3d               = NULL;
715     IDirect3DDevice9            *pDevice            = NULL;
716     D3DPRESENT_PARAMETERS        d3dpp;
717     D3DDISPLAYMODE               d3ddm;
718     D3DVIEWPORT9                 vp;
719     DWORD                        width, orig_width = GetSystemMetrics(SM_CXSCREEN);
720     DWORD                        height, orig_height = GetSystemMetrics(SM_CYSCREEN);
721     IDirect3DSwapChain9          *pSwapchain;
722
723     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
724     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
725     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
726     ok(hwnd != NULL, "Failed to create window\n");
727     if (!pD3d || !hwnd) goto cleanup;
728
729     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
730     ZeroMemory( &d3dpp, sizeof(d3dpp) );
731     d3dpp.Windowed         = FALSE;
732     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
733     d3dpp.BackBufferWidth  = 800;
734     d3dpp.BackBufferHeight  = 600;
735     d3dpp.BackBufferFormat = d3ddm.Format;
736
737     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
738                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
739
740     if(FAILED(hr))
741     {
742         skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
743         goto cleanup;
744     }
745
746     width = GetSystemMetrics(SM_CXSCREEN);
747     height = GetSystemMetrics(SM_CYSCREEN);
748     ok(width == 800, "Screen width is %d\n", width);
749     ok(height == 600, "Screen height is %d\n", height);
750
751     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
752     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
753     if(SUCCEEDED(hr))
754     {
755         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
756         ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
757         ok(vp.Width == 800, "D3DVIEWPORT->X = %d\n", vp.Width);
758         ok(vp.Height == 600, "D3DVIEWPORT->X = %d\n", vp.Height);
759         ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
760         ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
761     }
762     vp.X = 10;
763     vp.X = 20;
764     vp.MinZ = 2;
765     vp.MaxZ = 3;
766     hr = IDirect3DDevice9_SetViewport(pDevice, &vp);
767     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
768
769     ZeroMemory( &d3dpp, sizeof(d3dpp) );
770     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
771     d3dpp.Windowed         = FALSE;
772     d3dpp.BackBufferWidth  = 640;
773     d3dpp.BackBufferHeight  = 480;
774     d3dpp.BackBufferFormat = d3ddm.Format;
775     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
776     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %s\n", DXGetErrorString9(hr));
777
778     ZeroMemory(&vp, sizeof(vp));
779     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
780     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
781     if(SUCCEEDED(hr))
782     {
783         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
784         ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
785         ok(vp.Width == 640, "D3DVIEWPORT->X = %d\n", vp.Width);
786         ok(vp.Height == 480, "D3DVIEWPORT->X = %d\n", vp.Height);
787         ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
788         ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
789     }
790
791     width = GetSystemMetrics(SM_CXSCREEN);
792     height = GetSystemMetrics(SM_CYSCREEN);
793     ok(width == 640, "Screen width is %d\n", width);
794     ok(height == 480, "Screen height is %d\n", height);
795
796     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapchain);
797     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %s\n", DXGetErrorString9(hr));
798     if(SUCCEEDED(hr))
799     {
800         ZeroMemory(&d3dpp, sizeof(d3dpp));
801         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
802         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %s\n", DXGetErrorString9(hr));
803         if(SUCCEEDED(hr))
804         {
805             ok(d3dpp.BackBufferWidth == 640, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
806             ok(d3dpp.BackBufferHeight == 480, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
807         }
808         IDirect3DSwapChain9_Release(pSwapchain);
809     }
810
811     ZeroMemory( &d3dpp, sizeof(d3dpp) );
812     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
813     d3dpp.Windowed         = TRUE;
814     d3dpp.BackBufferWidth  = 400;
815     d3dpp.BackBufferHeight  = 300;
816     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
817     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %s\n", DXGetErrorString9(hr));
818
819     width = GetSystemMetrics(SM_CXSCREEN);
820     height = GetSystemMetrics(SM_CYSCREEN);
821     ok(width == orig_width, "Screen width is %d\n", width);
822     ok(height == orig_height, "Screen height is %d\n", height);
823
824     ZeroMemory(&vp, sizeof(vp));
825     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
826     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
827     if(SUCCEEDED(hr))
828     {
829         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
830         ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
831         ok(vp.Width == 400, "D3DVIEWPORT->X = %d\n", vp.Width);
832         ok(vp.Height == 300, "D3DVIEWPORT->X = %d\n", vp.Height);
833         ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
834         ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
835     }
836
837     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapchain);
838     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %s\n", DXGetErrorString9(hr));
839     if(SUCCEEDED(hr))
840     {
841         ZeroMemory(&d3dpp, sizeof(d3dpp));
842         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
843         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %s\n", DXGetErrorString9(hr));
844         if(SUCCEEDED(hr))
845         {
846             ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
847             ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
848         }
849         IDirect3DSwapChain9_Release(pSwapchain);
850     }
851
852 cleanup:
853     if(pD3d) IDirect3D9_Release(pD3d);
854     if(pDevice) IDirect3D9_Release(pDevice);
855 }
856
857 /* Test adapter display modes */
858 static void test_display_modes(void)
859 {
860     D3DDISPLAYMODE dmode;
861     IDirect3D9 *pD3d;
862
863     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
864     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
865     if(!pD3d) return;
866
867 #define TEST_FMT(x,r) do { \
868     HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
869     ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %s)!\n", DXGetErrorString9(res)); \
870 } while(0)
871
872     TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
873     TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
874     TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
875     /* D3DFMT_R5G6B5 */
876     TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
877     TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
878     TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
879     TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
880     TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
881     TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
882     TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
883     TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
884     TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
885     TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
886     TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
887     TEST_FMT(D3DFMT_A2R10G10B10, D3DERR_INVALIDCALL);
888     TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
889
890     TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
891     TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
892
893     TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
894     TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
895     TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
896
897     TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
898     TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
899     TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
900     TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
901     TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
902     TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
903
904     TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
905     TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
906     TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
907     TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
908     TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
909     TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
910     TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
911     TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
912     TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
913     TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
914
915     TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
916     TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
917     TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
918     TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
919     TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
920     TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
921     TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
922     TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
923     TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
924     TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
925
926     TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
927     TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
928     TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
929     TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
930     /* Floating point formats */
931     TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
932     TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
933     TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
934
935     /* IEEE formats */
936     TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
937     TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
938     TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
939
940     TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
941
942     TEST_FMT(0, D3DERR_INVALIDCALL);
943
944     IDirect3D9_Release(pD3d);
945 }
946
947 static void test_scene(void)
948 {
949     HRESULT                      hr;
950     HWND                         hwnd               = NULL;
951     IDirect3D9                  *pD3d               = NULL;
952     IDirect3DDevice9            *pDevice            = NULL;
953     D3DPRESENT_PARAMETERS        d3dpp;
954     D3DDISPLAYMODE               d3ddm;
955     IDirect3DSurface9            *pSurface1 = NULL, *pSurface2 = NULL, *pSurface3 = NULL, *pRenderTarget = NULL;
956     IDirect3DSurface9            *pBackBuffer = NULL, *pDepthStencil = NULL;
957     RECT rect = {0, 0, 128, 128};
958     D3DCAPS9                     caps;
959
960     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
961     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
962     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
963     ok(hwnd != NULL, "Failed to create window\n");
964     if (!pD3d || !hwnd) goto cleanup;
965
966     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
967     ZeroMemory( &d3dpp, sizeof(d3dpp) );
968     d3dpp.Windowed         = TRUE;
969     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
970     d3dpp.BackBufferWidth  = 800;
971     d3dpp.BackBufferHeight  = 600;
972     d3dpp.BackBufferFormat = d3ddm.Format;
973     d3dpp.EnableAutoDepthStencil = TRUE;
974     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
975
976     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
977                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
978     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
979     if(!pDevice)
980     {
981         skip("Failed to create a d3d device\n");
982         goto cleanup;
983     }
984
985     /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
986     memset(&caps, 0, sizeof(caps));
987     hr = IDirect3DDevice9_GetDeviceCaps(pDevice, &caps);
988     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %s\n", DXGetErrorString9(hr));
989     if(FAILED(hr)) goto cleanup;
990
991     /* Test an EndScene without beginscene. Should return an error */
992     hr = IDirect3DDevice9_EndScene(pDevice);
993     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
994
995     /* Test a normal BeginScene / EndScene pair, this should work */
996     hr = IDirect3DDevice9_BeginScene(pDevice);
997     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
998     if(SUCCEEDED(hr))
999     {
1000         hr = IDirect3DDevice9_EndScene(pDevice);
1001         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1002     }
1003
1004     /* Test another EndScene without having begun a new scene. Should return an error */
1005     hr = IDirect3DDevice9_EndScene(pDevice);
1006     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
1007
1008     /* Two nested BeginScene and EndScene calls */
1009     hr = IDirect3DDevice9_BeginScene(pDevice);
1010     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1011     hr = IDirect3DDevice9_BeginScene(pDevice);
1012     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
1013     hr = IDirect3DDevice9_EndScene(pDevice);
1014     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1015     hr = IDirect3DDevice9_EndScene(pDevice);
1016     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
1017
1018     /* Create some surfaces to test stretchrect between the scenes */
1019     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface1, NULL);
1020     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
1021     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface2, NULL);
1022     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
1023     hr = IDirect3DDevice9_CreateDepthStencilSurface(pDevice, 800, 600, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface3, NULL);
1024     ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %s\n", DXGetErrorString9(hr));
1025     hr = IDirect3DDevice9_CreateRenderTarget(pDevice, 128, 128, d3ddm.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pRenderTarget, NULL);
1026     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
1027
1028     hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
1029     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
1030     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1031     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
1032
1033     /* First make sure a simple StretchRect call works */
1034     if(pSurface1 && pSurface2) {
1035         hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1036         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
1037     }
1038     if(pBackBuffer && pRenderTarget) {
1039         hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1040         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
1041     }
1042     if(pDepthStencil && pSurface3) {
1043         HRESULT expected;
1044         if(0) /* Disabled for now because it crashes in wine */ {
1045             expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
1046             hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1047             ok( hr == expected, "IDirect3DDevice9_StretchRect returned %s, expected %s\n", DXGetErrorString9(hr), DXGetErrorString9(expected));
1048         }
1049     }
1050
1051     /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1052      * width normal surfaces, render targets and depth stencil surfaces.
1053      */
1054     hr = IDirect3DDevice9_BeginScene(pDevice);
1055     ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1056
1057     if(pSurface1 && pSurface2)
1058     {
1059         hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1060         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
1061     }
1062     if(pBackBuffer && pRenderTarget)
1063     {
1064         hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1065         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
1066     }
1067     if(pDepthStencil && pSurface3)
1068     {
1069         /* This is supposed to fail inside a BeginScene - EndScene pair. */
1070         hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1071         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %s, expected D3DERR_INVALIDCALL\n", DXGetErrorString9(hr));
1072     }
1073
1074     hr = IDirect3DDevice9_EndScene(pDevice);
1075     ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1076
1077     /* Does a SetRenderTarget influence BeginScene / EndScene ?
1078      * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1079      * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1080      */
1081     hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pRenderTarget);
1082     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
1083     hr = IDirect3DDevice9_BeginScene(pDevice);
1084     ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1085     hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pBackBuffer);
1086     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
1087     hr = IDirect3DDevice9_EndScene(pDevice);
1088     ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1089
1090 cleanup:
1091     if(pRenderTarget) IDirect3DSurface9_Release(pRenderTarget);
1092     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1093     if(pBackBuffer) IDirect3DSurface9_Release(pBackBuffer);
1094     if(pSurface1) IDirect3DSurface9_Release(pSurface1);
1095     if(pSurface2) IDirect3DSurface9_Release(pSurface2);
1096     if(pSurface3) IDirect3DSurface9_Release(pSurface3);
1097     if(pD3d) IDirect3D9_Release(pD3d);
1098     if(pDevice) IDirect3D9_Release(pDevice);
1099     if(hwnd) DestroyWindow(hwnd);
1100 }
1101
1102 static void test_limits(void)
1103 {
1104     HRESULT                      hr;
1105     HWND                         hwnd               = NULL;
1106     IDirect3D9                  *pD3d               = NULL;
1107     IDirect3DDevice9            *pDevice            = NULL;
1108     D3DPRESENT_PARAMETERS        d3dpp;
1109     D3DDISPLAYMODE               d3ddm;
1110     IDirect3DTexture9           *pTexture           = NULL;
1111     int i;
1112
1113     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1114     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1115     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1116     ok(hwnd != NULL, "Failed to create window\n");
1117     if (!pD3d || !hwnd) goto cleanup;
1118
1119     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1120     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1121     d3dpp.Windowed         = TRUE;
1122     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1123     d3dpp.BackBufferWidth  = 800;
1124     d3dpp.BackBufferHeight  = 600;
1125     d3dpp.BackBufferFormat = d3ddm.Format;
1126     d3dpp.EnableAutoDepthStencil = TRUE;
1127     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1128
1129     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1130                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1131     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1132     if(!pDevice)
1133     {
1134         skip("Failed to create a d3d device\n");
1135         goto cleanup;
1136     }
1137
1138     hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
1139     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
1140     if(!pTexture) goto cleanup;
1141
1142     /* There are 16 pixel samplers. We should be able to access all of them */
1143     for(i = 0; i < 16; i++) {
1144         hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
1145         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
1146         hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
1147         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
1148         hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
1149         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
1150     }
1151
1152     /* Now test all 8 textures stage states */
1153     for(i = 0; i < 8; i++) {
1154         hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
1155         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %s\n", i, DXGetErrorString9(hr));
1156     }
1157
1158     /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1159      * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1160      * but how do I test that?
1161      */
1162 cleanup:
1163     if(pTexture) IDirect3DTexture9_Release(pTexture);
1164     if(pD3d) IDirect3D9_Release(pD3d);
1165     if(pDevice) IDirect3D9_Release(pDevice);
1166     if(hwnd) DestroyWindow(hwnd);
1167 }
1168
1169 static void test_depthstenciltest(void)
1170 {
1171     HRESULT                      hr;
1172     HWND                         hwnd               = NULL;
1173     IDirect3D9                  *pD3d               = NULL;
1174     IDirect3DDevice9            *pDevice            = NULL;
1175     D3DPRESENT_PARAMETERS        d3dpp;
1176     D3DDISPLAYMODE               d3ddm;
1177     IDirect3DSurface9           *pDepthStencil           = NULL;
1178     IDirect3DSurface9           *pDepthStencil2          = NULL;
1179     D3DZBUFFERTYPE               state;
1180
1181     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1182     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1183     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1184     ok(hwnd != NULL, "Failed to create window\n");
1185     if (!pD3d || !hwnd) goto cleanup;
1186
1187     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1188     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1189     d3dpp.Windowed         = TRUE;
1190     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1191     d3dpp.BackBufferWidth  = 800;
1192     d3dpp.BackBufferHeight  = 600;
1193     d3dpp.BackBufferFormat = d3ddm.Format;
1194     d3dpp.EnableAutoDepthStencil = TRUE;
1195     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1196
1197     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1198                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1199     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1200     if(!pDevice)
1201     {
1202         skip("Failed to create a d3d device\n");
1203         goto cleanup;
1204     }
1205
1206     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1207     ok(hr == D3D_OK && pDepthStencil != NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %s\n", DXGetErrorString9(hr));
1208
1209     /* Try to clear */
1210     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1211     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
1212
1213     hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL);
1214     ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %s\n", DXGetErrorString9(hr));
1215
1216     /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */
1217     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2);
1218     ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %s\n", DXGetErrorString9(hr));
1219     if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2);
1220
1221     /* This left the render states untouched! */
1222     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1223     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
1224     ok(state == D3DZB_TRUE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1225     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZWRITEENABLE, &state);
1226     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
1227     ok(state == TRUE, "D3DRS_ZWRITEENABLE is %s\n", state ? "TRUE" : "FALSE");
1228     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILENABLE, &state);
1229     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
1230     ok(state == FALSE, "D3DRS_STENCILENABLE is %s\n", state ? "TRUE" : "FALSE");
1231     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_STENCILWRITEMASK, &state);
1232     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
1233     ok(state == 0xffffffff, "D3DRS_STENCILWRITEMASK is 0x%08x\n", state);
1234
1235     /* This is supposed to fail now */
1236     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1237     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
1238
1239     hr = IDirect3DDevice9_SetRenderState(pDevice, D3DRS_ZENABLE, D3DZB_FALSE);
1240     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
1241
1242     hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, pDepthStencil);
1243     ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %s\n", DXGetErrorString9(hr));
1244
1245     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1246     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
1247     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1248
1249     /* Now it works again */
1250     hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0);
1251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
1252
1253     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1254     if(pDevice) IDirect3D9_Release(pDevice);
1255
1256     /* Now see if autodepthstencil disable is honored. First, without a format set */
1257     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1258     d3dpp.Windowed         = TRUE;
1259     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1260     d3dpp.BackBufferWidth  = 800;
1261     d3dpp.BackBufferHeight  = 600;
1262     d3dpp.BackBufferFormat = d3ddm.Format;
1263     d3dpp.EnableAutoDepthStencil = FALSE;
1264     d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1265
1266     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1267                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1268     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1269     if(!pDevice)
1270     {
1271         skip("Failed to create a d3d device\n");
1272         goto cleanup;
1273     }
1274
1275     pDepthStencil = NULL;
1276     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1277     ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %s, surface = %p\n", DXGetErrorString9(hr), pDepthStencil);
1278     if(pDepthStencil) {
1279         IDirect3DSurface9_Release(pDepthStencil);
1280         pDepthStencil = NULL;
1281     }
1282
1283     /* Check the depth test state */
1284     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1285     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
1286     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1287
1288     if(pDevice) IDirect3D9_Release(pDevice);
1289
1290     /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */
1291     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1292     d3dpp.Windowed         = TRUE;
1293     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1294     d3dpp.BackBufferWidth  = 800;
1295     d3dpp.BackBufferHeight  = 600;
1296     d3dpp.BackBufferFormat = d3ddm.Format;
1297     d3dpp.EnableAutoDepthStencil = FALSE;
1298     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1299
1300     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1301                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1302     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1303     if(!pDevice)
1304     {
1305         skip("Failed to create a d3d device\n");
1306         goto cleanup;
1307     }
1308
1309     pDepthStencil = NULL;
1310     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1311     ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %s, surface = %p\n", DXGetErrorString9(hr), pDepthStencil);
1312     if(pDepthStencil) {
1313         IDirect3DSurface9_Release(pDepthStencil);
1314         pDepthStencil = NULL;
1315     }
1316
1317     hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state);
1318     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
1319     ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW"));
1320
1321 cleanup:
1322     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1323     if(pD3d) IDirect3D9_Release(pD3d);
1324     if(pDevice) IDirect3D9_Release(pDevice);
1325     if(hwnd) DestroyWindow(hwnd);
1326 }
1327
1328 /* Test what happens when IDirect3DDevice9_DrawIndexedPrimitive is called without a valid index buffer set. */
1329 static void test_draw_indexed(void)
1330 {
1331     static const struct {
1332         float position[3];
1333         DWORD color;
1334     } quad[] = {
1335         {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1336         {{-1.0f,  1.0f, 0.0f}, 0xffff0000},
1337         {{ 1.0f,  1.0f, 0.0f}, 0xffff0000},
1338         {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1339     };
1340     WORD indices[] = {0, 1, 2, 3, 0, 2};
1341
1342     static const D3DVERTEXELEMENT9 decl_elements[] = {
1343         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1344         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1345         D3DDECL_END()
1346     };
1347
1348     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1349     IDirect3DVertexBuffer9 *vertex_buffer = NULL;
1350     IDirect3DIndexBuffer9 *index_buffer = NULL;
1351     D3DPRESENT_PARAMETERS present_parameters;
1352     IDirect3DDevice9 *device = NULL;
1353     IDirect3D9 *d3d9;
1354     HRESULT hr;
1355     HWND hwnd;
1356     void *ptr;
1357
1358     hwnd = CreateWindow("static", "d3d9_test",
1359             0, 0, 0, 10, 10, 0, 0, 0, 0);
1360     if (!hwnd)
1361     {
1362         skip("Failed to create window\n");
1363         return;
1364     }
1365
1366     d3d9 = pDirect3DCreate9(D3D_SDK_VERSION);
1367     if (!d3d9)
1368     {
1369         skip("Failed to create IDirect3D9 object\n");
1370         goto cleanup;
1371     }
1372
1373     ZeroMemory(&present_parameters, sizeof(present_parameters));
1374     present_parameters.Windowed = TRUE;
1375     present_parameters.hDeviceWindow = hwnd;
1376     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1377
1378     hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1379             NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
1380     if (FAILED(hr) || !device)
1381     {
1382         skip("Failed to create device\n");
1383         goto cleanup;
1384     }
1385
1386     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1387     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1388     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1389     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1390
1391     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_DEFAULT, &vertex_buffer, NULL);
1392     ok(SUCCEEDED(hr), "CreateVertexBuffer failed (0x%08x)\n", hr);
1393     hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1394     ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1395     memcpy(ptr, quad, sizeof(quad));
1396     hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);
1397     ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1398     hr = IDirect3DDevice9_SetStreamSource(device, 0, vertex_buffer, 0, sizeof(*quad));
1399     ok(SUCCEEDED(hr), "SetStreamSource failed (0x%08x)\n", hr);
1400
1401     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &index_buffer, NULL);
1402     ok(SUCCEEDED(hr), "CreateIndexBuffer failed (0x%08x)\n", hr);
1403     hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, 0, &ptr, D3DLOCK_DISCARD);
1404     ok(SUCCEEDED(hr), "Lock failed (0x%08x)\n", hr);
1405     memcpy(ptr, indices, sizeof(indices));
1406     hr = IDirect3DIndexBuffer9_Unlock(index_buffer);
1407     ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1408     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1409     ok(SUCCEEDED(hr), "SetRenderState D3DRS_LIGHTING failed (0x%08x)\n", hr);
1410     hr = IDirect3DDevice9_BeginScene(device);
1411     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1412
1413     /* NULL index buffer. Should fail */
1414     hr = IDirect3DDevice9_SetIndices(device, NULL);
1415     ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1416     hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1417             4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1418     ok(hr == D3DERR_INVALIDCALL, "DrawIndexedPrimitive returned 0x%08x, expected D3DERR_INVALIDCALL (0x%08x)\n",
1419             hr, D3DERR_INVALIDCALL);
1420
1421     /* Valid index buffer. Should succeed */
1422     hr = IDirect3DDevice9_SetIndices(device, index_buffer);
1423     ok(SUCCEEDED(hr), "SetIndices failed (0x%08x)\n", hr);
1424     hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0 /* BaseVertexIndex */, 0 /* MinIndex */,
1425             4 /* NumVerts */, 0 /* StartIndex */, 2 /*PrimCount */);
1426     ok(SUCCEEDED(hr), "DrawIndexedPrimitive failed (0x%08x)\n", hr);
1427
1428     hr = IDirect3DDevice9_EndScene(device);
1429     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1430
1431     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1432     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1433
1434     IDirect3DVertexBuffer9_Release(vertex_buffer);
1435     IDirect3DIndexBuffer9_Release(index_buffer);
1436     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1437
1438 cleanup:
1439     if (d3d9) IDirect3D9_Release(d3d9);
1440     if (device) IDirect3DDevice9_Release(device);
1441     if (hwnd) DestroyWindow(hwnd);
1442 }
1443
1444 static void test_null_stream(void)
1445 {
1446     IDirect3DVertexBuffer9 *buffer = NULL;
1447     D3DPRESENT_PARAMETERS present_parameters;
1448     IDirect3DDevice9 *device = NULL;
1449     IDirect3D9 *d3d9;
1450     HWND hwnd;
1451     HRESULT hr;
1452     IDirect3DVertexShader9 *shader = NULL;
1453     IDirect3DVertexDeclaration9 *decl;
1454     DWORD shader_code[] = {
1455         0xfffe0101,                             /* vs_1_1           */
1456         0x0000001f, 0x80000000, 0x900f0000,     /* dcl_position v0  */
1457         0x00000001, 0xc00f0000, 0x90e40000,     /* mov oPos, v0     */
1458         0x0000ffff                              /* end              */
1459     };
1460     static const D3DVERTEXELEMENT9 decl_elements[] = {
1461         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1462         {1, 0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1463         D3DDECL_END()
1464     };
1465
1466     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1467     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1468     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1469     ok(hwnd != NULL, "Failed to create window\n");
1470     if (!d3d9 || !hwnd) goto cleanup;
1471
1472     ZeroMemory(&present_parameters, sizeof(present_parameters));
1473     present_parameters.Windowed = TRUE;
1474     present_parameters.hDeviceWindow = hwnd;
1475     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1476
1477     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1478                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
1479     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1480     if(!device)
1481     {
1482         skip("Failed to create a d3d device\n");
1483         goto cleanup;
1484     }
1485
1486     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1487     if(FAILED(hr)) {
1488         skip("No vertex shader support\n");
1489         goto cleanup;
1490     }
1491     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1492     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed (0x%08x)\n", hr);
1493     hr = IDirect3DDevice9_CreateVertexBuffer(device, 12 * sizeof(float), 0, 0, D3DPOOL_MANAGED, &buffer, NULL);
1494     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x)\n", hr);
1495
1496     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(float) * 3);
1497     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
1498     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
1499     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetStreamSource failed (0x%08x)\n", hr);
1500     hr = IDirect3DDevice9_SetVertexShader(device, shader);
1501     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed (0x%08x)\n", hr);
1502     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
1503     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexDeclaration failed (0x%08x)\n", hr);
1504
1505     hr = IDirect3DDevice9_BeginScene(device);
1506     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (0x%08x)\n", hr);
1507     if(SUCCEEDED(hr)) {
1508         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_POINTLIST, 0, 1);
1509         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawPrimitive failed (0x%08x)\n", hr);
1510
1511         hr = IDirect3DDevice9_EndScene(device);
1512         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed (0x%08x)\n", hr);
1513     }
1514
1515     IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1516     IDirect3DDevice9_SetVertexShader(device, NULL);
1517     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1518
1519     cleanup:
1520     if(decl) IDirect3DVertexDeclaration9_Release(decl);
1521     if(shader) IDirect3DVertexShader9_Release(shader);
1522     if(device) IDirect3DDevice9_Release(device);
1523     if(d3d9) IDirect3D9_Release(d3d9);
1524 }
1525
1526 static inline const char *debug_d3dpool(D3DPOOL pool) {
1527     switch(pool) {
1528         case D3DPOOL_DEFAULT: return "D3DPOOL_DEFAULT";
1529         case D3DPOOL_SYSTEMMEM: return "D3DPOOL_SYSTEMMEM";
1530         case D3DPOOL_SCRATCH: return "D3DPOOL_SCRATCH";
1531         case D3DPOOL_MANAGED: return "D3DPOOL_MANAGED";
1532         default:
1533         return "unknown pool";
1534     }
1535 }
1536
1537 static void test_vertex_buffer_alignment(void)
1538 {
1539     IDirect3DVertexBuffer9 *buffer = NULL;
1540     D3DPRESENT_PARAMETERS present_parameters;
1541     IDirect3DDevice9 *device = NULL;
1542     IDirect3D9 *d3d9;
1543     HWND hwnd;
1544     HRESULT hr;
1545     D3DPOOL pools[] = {D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH, D3DPOOL_MANAGED};
1546     DWORD sizes[] = {1, 4, 16, 17, 32, 33, 64, 65, 1024, 1025, 1048576, 1048577};
1547     unsigned int i, j;
1548     void *data;
1549
1550     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1551     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1552     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1553     ok(hwnd != NULL, "Failed to create window\n");
1554     if (!d3d9 || !hwnd) goto cleanup;
1555
1556     ZeroMemory(&present_parameters, sizeof(present_parameters));
1557     present_parameters.Windowed = TRUE;
1558     present_parameters.hDeviceWindow = hwnd;
1559     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1560
1561     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1562                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device );
1563     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1564     if(!device)
1565     {
1566         skip("Failed to create a d3d device\n");
1567         goto cleanup;
1568     }
1569
1570     for(i = 0; i < (sizeof(sizes) / sizeof(sizes[0])); i++) {
1571         for(j = 0; j < (sizeof(pools) / sizeof(pools[0])); j++) {
1572             hr = IDirect3DDevice9_CreateVertexBuffer(device, sizes[i], 0, 0, pools[j], &buffer, NULL);
1573             if(pools[j] == D3DPOOL_SCRATCH) {
1574                 ok(hr == D3DERR_INVALIDCALL, "Creating a D3DPOOL_SCRATCH buffer returned (0x%08x)\n", hr);
1575             } else {
1576                 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexBuffer failed (0x%08x). Pool = %s, size %d\n", hr,
1577                    debug_d3dpool(pools[j]), sizes[i]);
1578             }
1579             if(FAILED(hr)) continue;
1580
1581             hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, (void **) &data, 0);
1582             ok(SUCCEEDED(hr), "IDirect3DVertexBuffer9_Lock failed (0x%08x)\n", hr);
1583             ok(((DWORD_PTR) data & 31) == 0, "Vertex buffer start address is not 32 byte aligned(size: %d, pool: %s, data: %p)\n",
1584                sizes[i], debug_d3dpool(pools[j]), data);
1585             hr = IDirect3DVertexBuffer9_Unlock(buffer);
1586             ok(SUCCEEDED(hr), "IDirect3DVertexBuffer9_Unlock failed (0x%08x)\n", hr);
1587
1588             if(buffer) IDirect3DVertexBuffer9_Release(buffer);
1589         }
1590     }
1591
1592     cleanup:
1593     if(d3d9) IDirect3D9_Release(d3d9);
1594 }
1595
1596 static void test_lights(void)
1597 {
1598     D3DPRESENT_PARAMETERS present_parameters;
1599     IDirect3DDevice9 *device = NULL;
1600     IDirect3D9 *d3d9;
1601     HWND hwnd;
1602     HRESULT hr;
1603     unsigned int i;
1604     BOOL enabled;
1605     D3DCAPS9 caps;
1606
1607     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1608     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1609     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1610     ok(hwnd != NULL, "Failed to create window\n");
1611     if (!d3d9 || !hwnd) goto cleanup;
1612
1613     ZeroMemory(&present_parameters, sizeof(present_parameters));
1614     present_parameters.Windowed = TRUE;
1615     present_parameters.hDeviceWindow = hwnd;
1616     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1617
1618     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
1619                                   D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &present_parameters, &device );
1620     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1621     if(!device)
1622     {
1623         skip("Failed to create a d3d device\n");
1624         goto cleanup;
1625     }
1626
1627     memset(&caps, 0, sizeof(caps));
1628     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1629     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
1630
1631     for(i = 1; i <= caps.MaxActiveLights; i++) {
1632         hr = IDirect3DDevice9_LightEnable(device, i, TRUE);
1633         ok(hr == D3D_OK, "Enabling light %u failed with %s\n", i, DXGetErrorString9(hr));
1634         hr = IDirect3DDevice9_GetLightEnable(device, i, &enabled);
1635         ok(hr == D3D_OK, "GetLightEnable on light %u failed with %s\n", i, DXGetErrorString9(hr));
1636         ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
1637     }
1638
1639     /* TODO: Test the rendering results in this situation */
1640     hr = IDirect3DDevice9_LightEnable(device, i + 1, TRUE);
1641     ok(hr == D3D_OK, "Enabling one light more than supported returned %s\n", DXGetErrorString9(hr));
1642     hr = IDirect3DDevice9_GetLightEnable(device, i + 1, &enabled);
1643     ok(hr == D3D_OK, "GetLightEnable on light %u failed with %s\n", i + 1, DXGetErrorString9(hr));
1644     ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
1645     hr = IDirect3DDevice9_LightEnable(device, i + 1, FALSE);
1646     ok(hr == D3D_OK, "Disabling the additional returned %s\n", DXGetErrorString9(hr));
1647
1648     for(i = 1; i <= caps.MaxActiveLights; i++) {
1649         hr = IDirect3DDevice9_LightEnable(device, i, FALSE);
1650         ok(hr == D3D_OK, "Disabling light %u failed with %s\n", i, DXGetErrorString9(hr));
1651     }
1652
1653     cleanup:
1654     if(device) IDirect3DDevice9_Release(device);
1655     if(d3d9) IDirect3D9_Release(d3d9);
1656 }
1657
1658 static void test_set_stream_source(void)
1659 {
1660     D3DPRESENT_PARAMETERS present_parameters;
1661     IDirect3DDevice9 *device = NULL;
1662     IDirect3D9 *d3d9;
1663     HWND hwnd;
1664     HRESULT hr;
1665     IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
1666
1667     d3d9 = pDirect3DCreate9( D3D_SDK_VERSION );
1668     ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n");
1669     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1670     ok(hwnd != NULL, "Failed to create window\n");
1671     if (!d3d9 || !hwnd) goto cleanup;
1672
1673     ZeroMemory(&present_parameters, sizeof(present_parameters));
1674     present_parameters.Windowed = TRUE;
1675     present_parameters.hDeviceWindow = hwnd;
1676     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
1677
1678     hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
1679                                   D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
1680     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1681     if(!device)
1682     {
1683         hr = IDirect3D9_CreateDevice( d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd,
1684                                       D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device );
1685         ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1686         if(!device)
1687         {
1688             skip("Failed to create a d3d device\n");
1689             goto cleanup;
1690         }
1691     }
1692
1693     hr = IDirect3DDevice9_CreateVertexBuffer( device, 512, 0, 0, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
1694     ok(hr == D3D_OK, "Failed to create a vertex buffer, hr = %s\n", DXGetErrorString9(hr));
1695     if (SUCCEEDED(hr)) {
1696         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 0, 32);
1697         ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %s\n",
1698            DXGetErrorString9(hr));
1699         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 1, 32);
1700         ok(hr == D3DERR_INVALIDCALL, "Unexpected result when setting the stream source, offset 1, hr = %s\n",
1701            DXGetErrorString9(hr));
1702         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 2, 32);
1703         ok(hr == D3DERR_INVALIDCALL, "Unexpected result when setting the stream source, offset 2, hr = %s\n",
1704            DXGetErrorString9(hr));
1705         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 3, 32);
1706         ok(hr == D3DERR_INVALIDCALL, "Unexpected result when setting the stream source, offset 3, hr = %s\n",
1707            DXGetErrorString9(hr));
1708         hr = IDirect3DDevice9_SetStreamSource(device, 0, pVertexBuffer, 4, 32);
1709         ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %s\n",
1710           DXGetErrorString9(hr));
1711     }
1712     /* Try to set the NULL buffer with an offset and stride 0 */
1713     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1714     ok(hr == D3D_OK, "Failed to set the stream source, offset 0, hr = %s\n",
1715        DXGetErrorString9(hr));
1716     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 1, 0);
1717     ok(hr == D3DERR_INVALIDCALL, "Unexpected result when setting the stream source, offset 1, hr = %s\n",
1718        DXGetErrorString9(hr));
1719     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 2, 0);
1720     ok(hr == D3DERR_INVALIDCALL, "Unexpected result when setting the stream source, offset 2, hr = %s\n",
1721        DXGetErrorString9(hr));
1722     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 3, 0);
1723     ok(hr == D3DERR_INVALIDCALL, "Unexpected result when setting the stream source, offset 3, hr = %s\n",
1724        DXGetErrorString9(hr));
1725     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 4, 0);
1726     ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %s\n",
1727        DXGetErrorString9(hr));
1728
1729     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1730     ok(hr == D3D_OK, "Failed to set the stream source, offset 4, hr = %s\n", DXGetErrorString9(hr));
1731
1732     if(pVertexBuffer) IDirect3DDevice9_Release(pVertexBuffer);
1733 cleanup:
1734     if(device) IDirect3DDevice9_Release(device);
1735     if(d3d9) IDirect3D9_Release(d3d9);
1736 }
1737
1738 START_TEST(device)
1739 {
1740     HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
1741     if (!d3d9_handle)
1742     {
1743         skip("Could not load d3d9.dll\n");
1744         return;
1745     }
1746
1747     pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
1748     ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
1749     if (pDirect3DCreate9)
1750     {
1751         test_display_modes();
1752         test_swapchain();
1753         test_refcount();
1754         test_mipmap_levels();
1755         test_cursor();
1756         test_reset();
1757         test_scene();
1758         test_limits();
1759         test_depthstenciltest();
1760         test_draw_indexed();
1761         test_null_stream();
1762         test_vertex_buffer_alignment();
1763         test_lights();
1764         test_set_stream_source();
1765     }
1766 }