wined3d: No bounds checking is done on sampler / texture numbers.
[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  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #include <d3d9.h>
23 #include <dxerr9.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: %s\n", c, DXGetErrorString9(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: %s\n", DXGetErrorString9(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 (%s)\n", DXGetErrorString9(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_NULLREF, hwnd,
167                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
168     ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
169     if (FAILED(hr)) goto cleanup;
170
171     /* Check if the back buffer count was modified */
172     ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
173
174     /* Get the implicit swapchain */
175     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &swapchain0);
176     ok(SUCCEEDED(hr), "Failed to get the impicit swapchain (%s)\n", DXGetErrorString9(hr));
177     if(swapchain0) IDirect3DSwapChain9_Release(swapchain0);
178
179     /* Check if there is a back buffer */
180     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
181     ok(SUCCEEDED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr));
182     ok(backbuffer != NULL, "The back buffer is NULL\n");
183     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
184
185     /* Try to get a nonexistant swapchain */
186     hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
187     ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an nonexistent swapchain returned (%s)\n", DXGetErrorString9(hr));
188     ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX);
189     if(swapchainX) IDirect3DSwapChain9_Release(swapchainX);
190
191     /* Create a bunch of swapchains */
192     d3dpp.BackBufferCount = 0;
193     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain1);
194     ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString9(hr));
195     ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
196
197     d3dpp.BackBufferCount  = 1;
198     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain2);
199     ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString9(hr));
200
201     d3dpp.BackBufferCount  = 2;
202     hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3);
203     ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString9(hr));
204     if(SUCCEEDED(hr)) {
205         /* Swapchain 3, created with backbuffercount 2 */
206         backbuffer = (void *) 0xdeadbeef;
207         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
208         ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%s)\n", DXGetErrorString9(hr));
209         ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
210         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
211
212         backbuffer = (void *) 0xdeadbeef;
213         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
214         ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%s)\n", DXGetErrorString9(hr));
215         ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
216         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
217
218         backbuffer = (void *) 0xdeadbeef;
219         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
220         ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %s\n", DXGetErrorString9(hr));
221         ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
222         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
223
224         backbuffer = (void *) 0xdeadbeef;
225         hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
226         ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr));
227         ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
228         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
229     }
230
231     /* Check the back buffers of the swapchains */
232     /* Swapchain 1, created with backbuffercount 0 */
233     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
234     ok(SUCCEEDED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr));
235     ok(backbuffer != NULL, "The back buffer is NULL (%s)\n", DXGetErrorString9(hr));
236     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
237
238     backbuffer = (void *) 0xdeadbeef;
239     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
240     ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr));
241     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
242     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
243
244     /* Swapchain 2 - created with backbuffercount 1 */
245     backbuffer = (void *) 0xdeadbeef;
246     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
247     ok(SUCCEEDED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr));
248     ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
249     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
250
251     backbuffer = (void *) 0xdeadbeef;
252     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
253     ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %s\n", DXGetErrorString9(hr));
254     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
255     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
256
257     backbuffer = (void *) 0xdeadbeef;
258     hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
259     ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr));
260     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
261     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer);
262
263     /* Try getSwapChain on a manually created swapchain
264      * it should fail, apparently GetSwapChain only returns implicit swapchains
265      */
266     swapchainX = (void *) 0xdeadbeef;
267     hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX);
268     ok(hr == D3DERR_INVALIDCALL, "Failed to get the second swapchain (%s)\n", DXGetErrorString9(hr));
269     ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX);
270     if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX);
271
272     cleanup:
273     if(swapchain1) IDirect3DSwapChain9_Release(swapchain1);
274     if(swapchain2) IDirect3DSwapChain9_Release(swapchain2);
275     if(swapchain3) IDirect3DSwapChain9_Release(swapchain3);
276     if(pDevice) IDirect3DDevice9_Release(pDevice);
277     if(pD3d) IDirect3DDevice9_Release(pD3d);
278     DestroyWindow( hwnd );
279 }
280
281 static void test_refcount(void)
282 {
283     HRESULT                      hr;
284     HWND                         hwnd               = NULL;
285     IDirect3D9                  *pD3d               = NULL;
286     IDirect3DDevice9            *pDevice            = NULL;
287     IDirect3DVertexBuffer9      *pVertexBuffer      = NULL;
288     IDirect3DIndexBuffer9       *pIndexBuffer       = NULL;
289     IDirect3DVertexDeclaration9 *pVertexDeclaration = NULL;
290     IDirect3DVertexShader9      *pVertexShader      = NULL;
291     IDirect3DPixelShader9       *pPixelShader       = NULL;
292     IDirect3DCubeTexture9       *pCubeTexture       = NULL;
293     IDirect3DTexture9           *pTexture           = NULL;
294     IDirect3DVolumeTexture9     *pVolumeTexture     = NULL;
295     IDirect3DVolume9            *pVolumeLevel       = NULL;
296     IDirect3DSurface9           *pStencilSurface    = NULL;
297     IDirect3DSurface9           *pOffscreenSurface  = NULL;
298     IDirect3DSurface9           *pRenderTarget      = NULL;
299     IDirect3DSurface9           *pRenderTarget2     = NULL;
300     IDirect3DSurface9           *pRenderTarget3     = NULL;
301     IDirect3DSurface9           *pTextureLevel      = NULL;
302     IDirect3DSurface9           *pBackBuffer        = NULL;
303     IDirect3DStateBlock9        *pStateBlock        = NULL;
304     IDirect3DStateBlock9        *pStateBlock1       = NULL;
305     IDirect3DSwapChain9         *pSwapChain         = NULL;
306     IDirect3DQuery9             *pQuery             = NULL;
307     D3DPRESENT_PARAMETERS        d3dpp;
308     D3DDISPLAYMODE               d3ddm;
309     int                          refcount = 0, tmp;
310
311     D3DVERTEXELEMENT9 decl[] =
312     {
313         D3DDECL_END()
314     };
315     static DWORD simple_vs[] = {0xFFFE0101,             /* vs_1_1               */
316         0x0000001F, 0x80000000, 0x900F0000,             /* dcl_position0 v0     */
317         0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0   */
318         0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1   */
319         0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2   */
320         0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3   */
321         0x0000FFFF};                                    /* END                  */
322     static DWORD simple_ps[] = {0xFFFF0101,                                     /* ps_1_1                       */
323         0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0  */
324         0x00000042, 0xB00F0000,                                                 /* tex t0                       */
325         0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000,                         /* dp3 r0, c1, c0               */
326         0x00000005, 0x800F0000, 0x90E40000, 0x80E40000,                         /* mul r0, v0, r0               */
327         0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000,                         /* mul r0, t0, r0               */
328         0x0000FFFF};                                                            /* END                          */
329
330
331     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
332     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
333     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
334     ok(hwnd != NULL, "Failed to create window\n");
335     if (!pD3d || !hwnd) goto cleanup;
336
337     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
338     ZeroMemory( &d3dpp, sizeof(d3dpp) );
339     d3dpp.Windowed         = TRUE;
340     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
341     d3dpp.BackBufferFormat = d3ddm.Format;
342     d3dpp.EnableAutoDepthStencil = TRUE;
343     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
344
345     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
346                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
347     ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
348     if (FAILED(hr)) goto cleanup;
349
350     refcount = get_refcount( (IUnknown *)pDevice );
351     ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
352
353     /**
354      * Check refcount of implicit surfaces and implicit swapchain. Findings:
355      *   - the container is the device OR swapchain
356      *   - they hold a refernce to the device
357      *   - they are created with a refcount of 0 (Get/Release returns orignial refcount)
358      *   - they are not freed if refcount reaches 0.
359      *   - the refcount is not forwarded to the container.
360      */
361     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapChain);
362     CHECK_CALL( hr, "GetSwapChain", pDevice, ++refcount);
363     if (pSwapChain)
364     {
365         CHECK_REFCOUNT( pSwapChain, 1);
366
367         hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
368         CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
369         CHECK_REFCOUNT( pSwapChain, 1);
370         if(pRenderTarget)
371         {
372             CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain);
373             CHECK_REFCOUNT( pRenderTarget, 1);
374
375             CHECK_ADDREF_REFCOUNT(pRenderTarget, 2);
376             CHECK_REFCOUNT(pDevice, refcount);
377             CHECK_RELEASE_REFCOUNT(pRenderTarget, 1);
378             CHECK_REFCOUNT(pDevice, refcount);
379
380             hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget);
381             CHECK_CALL( hr, "GetRenderTarget", pDevice, refcount);
382             CHECK_REFCOUNT( pRenderTarget, 2);
383             CHECK_RELEASE_REFCOUNT( pRenderTarget, 1);
384             CHECK_RELEASE_REFCOUNT( pRenderTarget, 0);
385             CHECK_REFCOUNT( pDevice, --refcount);
386
387             /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
388             CHECK_ADDREF_REFCOUNT(pRenderTarget, 1);
389             CHECK_REFCOUNT(pDevice, ++refcount);
390             CHECK_RELEASE_REFCOUNT(pRenderTarget, 0);
391             CHECK_REFCOUNT(pDevice, --refcount);
392         }
393
394         /* Render target and back buffer are identical. */
395         hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, 0, &pBackBuffer);
396         CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
397         if(pBackBuffer)
398         {
399             CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
400             ok(pRenderTarget == pBackBuffer, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
401             pRenderTarget, pBackBuffer);
402             pBackBuffer = NULL;
403         }
404         CHECK_REFCOUNT( pDevice, --refcount);
405
406         hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pStencilSurface);
407         CHECK_CALL( hr, "GetDepthStencilSurface", pDevice, ++refcount);
408         CHECK_REFCOUNT( pSwapChain, 1);
409         if(pStencilSurface)
410         {
411             CHECK_SURFACE_CONTAINER( pStencilSurface, IID_IDirect3DDevice9, pDevice);
412             CHECK_REFCOUNT( pStencilSurface, 1);
413
414             CHECK_ADDREF_REFCOUNT(pStencilSurface, 2);
415             CHECK_REFCOUNT(pDevice, refcount);
416             CHECK_RELEASE_REFCOUNT(pStencilSurface, 1);
417             CHECK_REFCOUNT(pDevice, refcount);
418
419             CHECK_RELEASE_REFCOUNT( pStencilSurface, 0);
420             CHECK_REFCOUNT( pDevice, --refcount);
421
422             /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
423             CHECK_ADDREF_REFCOUNT(pStencilSurface, 1);
424             CHECK_REFCOUNT(pDevice, ++refcount);
425             CHECK_RELEASE_REFCOUNT(pStencilSurface, 0);
426             CHECK_REFCOUNT(pDevice, --refcount);
427             pStencilSurface = NULL;
428         }
429
430         CHECK_RELEASE_REFCOUNT( pSwapChain, 0);
431         CHECK_REFCOUNT( pDevice, --refcount);
432
433         /* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */
434         CHECK_ADDREF_REFCOUNT(pSwapChain, 1);
435         CHECK_REFCOUNT(pDevice, ++refcount);
436         CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
437         CHECK_REFCOUNT(pDevice, --refcount);
438         pSwapChain = NULL;
439     }
440
441     /* Buffers */
442     hr = IDirect3DDevice9_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer, NULL );
443     CHECK_CALL( hr, "CreateIndexBuffer", pDevice, ++refcount );
444     if(pIndexBuffer)
445     {
446         tmp = get_refcount( (IUnknown *)pIndexBuffer );
447
448         hr = IDirect3DDevice9_SetIndices(pDevice, pIndexBuffer);
449         CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
450         hr = IDirect3DDevice9_SetIndices(pDevice, NULL);
451         CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp);
452     }
453
454     hr = IDirect3DDevice9_CreateVertexBuffer( pDevice, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer, NULL );
455     CHECK_CALL( hr, "CreateVertexBuffer", pDevice, ++refcount );
456     if(pVertexBuffer)
457     {
458         IDirect3DVertexBuffer9 *pVBuf = (void*)~0;
459         UINT offset = ~0;
460         UINT stride = ~0;
461
462         tmp = get_refcount( (IUnknown *)pVertexBuffer );
463
464         hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, pVertexBuffer, 0, 3 * sizeof(float));
465         CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
466         hr = IDirect3DDevice9_SetStreamSource(pDevice, 0, NULL, 0, 0);
467         CHECK_CALL( hr, "SetStreamSource", pVertexBuffer, tmp);
468
469         hr = IDirect3DDevice9_GetStreamSource(pDevice, 0, &pVBuf, &offset, &stride);
470         ok(SUCCEEDED(hr), "GetStreamSource did not succeed with NULL stream!\n");
471         ok(pVBuf==NULL, "pVBuf not NULL (%p)!\n", pVBuf);
472         ok(stride==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride);
473         ok(offset==0, "offset not 0 (got %u)!\n", offset);
474     }
475     /* Shaders */
476     hr = IDirect3DDevice9_CreateVertexDeclaration( pDevice, decl, &pVertexDeclaration );
477     CHECK_CALL( hr, "CreateVertexDeclaration", pDevice, ++refcount );
478     hr = IDirect3DDevice9_CreateVertexShader( pDevice, simple_vs, &pVertexShader );
479     CHECK_CALL( hr, "CreateVertexShader", pDevice, ++refcount );
480     hr = IDirect3DDevice9_CreatePixelShader( pDevice, simple_ps, &pPixelShader );
481     CHECK_CALL( hr, "CreatePixelShader", pDevice, ++refcount );
482     /* Textures */
483     hr = IDirect3DDevice9_CreateTexture( pDevice, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL );
484     CHECK_CALL( hr, "CreateTexture", pDevice, ++refcount );
485     if (pTexture)
486     {
487         tmp = get_refcount( (IUnknown *)pTexture );
488
489         /* SetTexture should not increase refcounts */
490         hr = IDirect3DDevice9_SetTexture(pDevice, 0, (IDirect3DBaseTexture9 *) pTexture);
491         CHECK_CALL( hr, "SetTexture", pTexture, tmp);
492         hr = IDirect3DDevice9_SetTexture(pDevice, 0, NULL);
493         CHECK_CALL( hr, "SetTexture", pTexture, tmp);
494
495         /* This should not increment device refcount */
496         hr = IDirect3DTexture9_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
497         CHECK_CALL( hr, "GetSurfaceLevel", pDevice, refcount );
498         /* But should increment texture's refcount */
499         CHECK_REFCOUNT( pTexture, tmp+1 );
500         /* Because the texture and surface refcount are identical */
501         if (pTextureLevel)
502         {
503             CHECK_REFCOUNT        ( pTextureLevel, tmp+1 );
504             CHECK_ADDREF_REFCOUNT ( pTextureLevel, tmp+2 );
505             CHECK_REFCOUNT        ( pTexture     , tmp+2 );
506             CHECK_RELEASE_REFCOUNT( pTextureLevel, tmp+1 );
507             CHECK_REFCOUNT        ( pTexture     , tmp+1 );
508             CHECK_RELEASE_REFCOUNT( pTexture     , tmp   );
509             CHECK_REFCOUNT        ( pTextureLevel, tmp   );
510         }
511     }
512     hr = IDirect3DDevice9_CreateCubeTexture( pDevice, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture, NULL );
513     CHECK_CALL( hr, "CreateCubeTexture", pDevice, ++refcount );
514     hr = IDirect3DDevice9_CreateVolumeTexture( pDevice, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture, NULL );
515     CHECK_CALL( hr, "CreateVolumeTexture", pDevice, ++refcount );
516     if (pVolumeTexture)
517     {
518         tmp = get_refcount( (IUnknown *)pVolumeTexture );
519
520         /* This should not increment device refcount */
521         hr = IDirect3DVolumeTexture9_GetVolumeLevel(pVolumeTexture, 0, &pVolumeLevel);
522         CHECK_CALL( hr, "GetVolumeLevel", pDevice, refcount );
523         /* But should increment volume texture's refcount */
524         CHECK_REFCOUNT( pVolumeTexture, tmp+1 );
525         /* Because the volume texture and volume refcount are identical */
526         if (pVolumeLevel)
527         {
528             CHECK_REFCOUNT        ( pVolumeLevel  , tmp+1 );
529             CHECK_ADDREF_REFCOUNT ( pVolumeLevel  , tmp+2 );
530             CHECK_REFCOUNT        ( pVolumeTexture, tmp+2 );
531             CHECK_RELEASE_REFCOUNT( pVolumeLevel  , tmp+1 );
532             CHECK_REFCOUNT        ( pVolumeTexture, tmp+1 );
533             CHECK_RELEASE_REFCOUNT( pVolumeTexture, tmp   );
534             CHECK_REFCOUNT        ( pVolumeLevel  , tmp   );
535         }
536     }
537     /* Surfaces */
538     hr = IDirect3DDevice9_CreateDepthStencilSurface( pDevice, 32, 32, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &pStencilSurface, NULL );
539     CHECK_CALL( hr, "CreateDepthStencilSurface", pDevice, ++refcount );
540     CHECK_REFCOUNT( pStencilSurface, 1 );
541     hr = IDirect3DDevice9_CreateOffscreenPlainSurface( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pOffscreenSurface, NULL );
542     CHECK_CALL( hr, "CreateOffscreenPlainSurface", pDevice, ++refcount );
543     CHECK_REFCOUNT( pOffscreenSurface, 1 );
544     hr = IDirect3DDevice9_CreateRenderTarget( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRenderTarget3, NULL );
545     CHECK_CALL( hr, "CreateRenderTarget", pDevice, ++refcount );
546     CHECK_REFCOUNT( pRenderTarget3, 1 );
547     /* Misc */
548     hr = IDirect3DDevice9_CreateStateBlock( pDevice, D3DSBT_ALL, &pStateBlock );
549     CHECK_CALL( hr, "CreateStateBlock", pDevice, ++refcount );
550     hr = IDirect3DDevice9_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
551     CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, ++refcount );
552     if(pSwapChain)
553     {
554         /* check implicit back buffer */
555         hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
556         CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
557         CHECK_REFCOUNT( pSwapChain, 1);
558         if(pBackBuffer)
559         {
560             CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
561             CHECK_REFCOUNT( pBackBuffer, 1);
562             CHECK_RELEASE_REFCOUNT( pBackBuffer, 0);
563             CHECK_REFCOUNT( pDevice, --refcount);
564
565             /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
566             CHECK_ADDREF_REFCOUNT(pBackBuffer, 1);
567             CHECK_REFCOUNT(pDevice, ++refcount);
568             CHECK_RELEASE_REFCOUNT(pBackBuffer, 0);
569             CHECK_REFCOUNT(pDevice, --refcount);
570             pBackBuffer = NULL;
571         }
572         CHECK_REFCOUNT( pSwapChain, 1);
573     }
574     hr = IDirect3DDevice9_CreateQuery( pDevice, D3DQUERYTYPE_EVENT, &pQuery );
575     CHECK_CALL( hr, "CreateQuery", pDevice, ++refcount );
576
577     hr = IDirect3DDevice9_BeginStateBlock( pDevice );
578     CHECK_CALL( hr, "BeginStateBlock", pDevice, refcount );
579     hr = IDirect3DDevice9_EndStateBlock( pDevice, &pStateBlock1 );
580     CHECK_CALL( hr, "EndStateBlock", pDevice, ++refcount );
581
582     /* The implicit render target is not freed if refcount reaches 0.
583      * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
584     hr = IDirect3DDevice9_GetRenderTarget(pDevice, 0, &pRenderTarget2);
585     CHECK_CALL( hr, "GetRenderTarget", pDevice, ++refcount);
586     if(pRenderTarget2)
587     {
588         CHECK_RELEASE_REFCOUNT(pRenderTarget2, 0);
589         ok(pRenderTarget == pRenderTarget2, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
590            pRenderTarget, pRenderTarget2);
591         CHECK_REFCOUNT( pDevice, --refcount);
592         pRenderTarget2 = NULL;
593     }
594     pRenderTarget = NULL;
595
596 cleanup:
597     CHECK_RELEASE(pDevice,              pDevice, --refcount);
598
599     /* Buffers */
600     CHECK_RELEASE(pVertexBuffer,        pDevice, --refcount);
601     CHECK_RELEASE(pIndexBuffer,         pDevice, --refcount);
602     /* Shaders */
603     CHECK_RELEASE(pVertexDeclaration,   pDevice, --refcount);
604     CHECK_RELEASE(pVertexShader,        pDevice, --refcount);
605     CHECK_RELEASE(pPixelShader,         pDevice, --refcount);
606     /* Textures */
607     CHECK_RELEASE(pTextureLevel,        pDevice, --refcount);
608     CHECK_RELEASE(pCubeTexture,         pDevice, --refcount);
609     CHECK_RELEASE(pVolumeTexture,       pDevice, --refcount);
610     /* Surfaces */
611     CHECK_RELEASE(pStencilSurface,      pDevice, --refcount);
612     CHECK_RELEASE(pOffscreenSurface,    pDevice, --refcount);
613     CHECK_RELEASE(pRenderTarget3,       pDevice, --refcount);
614     /* Misc */
615     CHECK_RELEASE(pStateBlock,          pDevice, --refcount);
616     CHECK_RELEASE(pSwapChain,           pDevice, --refcount);
617     CHECK_RELEASE(pQuery,               pDevice, --refcount);
618     /* This will destroy device - cannot check the refcount here */
619     if (pStateBlock1)         CHECK_RELEASE_REFCOUNT( pStateBlock1, 0);
620
621     if (pD3d)                 CHECK_RELEASE_REFCOUNT( pD3d, 0);
622
623     DestroyWindow( hwnd );
624 }
625
626 static void test_cursor(void)
627 {
628     HRESULT                      hr;
629     HWND                         hwnd               = NULL;
630     IDirect3D9                  *pD3d               = NULL;
631     IDirect3DDevice9            *pDevice            = NULL;
632     D3DPRESENT_PARAMETERS        d3dpp;
633     D3DDISPLAYMODE               d3ddm;
634     CURSORINFO                   info;
635     IDirect3DSurface9 *cursor = NULL;
636     HCURSOR cur;
637
638     memset(&info, 0, sizeof(info));
639     info.cbSize = sizeof(info);
640     hr = GetCursorInfo(&info);
641     cur = info.hCursor;
642
643     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
644     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
645     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
646     ok(hwnd != NULL, "Failed to create window\n");
647     if (!pD3d || !hwnd) goto cleanup;
648
649     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
650     ZeroMemory( &d3dpp, sizeof(d3dpp) );
651     d3dpp.Windowed         = TRUE;
652     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
653     d3dpp.BackBufferFormat = d3ddm.Format;
654
655     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
656                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
657     ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
658     if (FAILED(hr)) goto cleanup;
659
660     IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, 0);
661     ok(cursor != NULL, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
662
663     /* Initially hidden */
664     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
665     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
666
667     /* Not enabled without a surface*/
668     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
669     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
670
671     /* Fails */
672     hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, NULL);
673     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
674
675     hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, cursor);
676     ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08x\n", hr);
677
678     IDirect3DSurface9_Release(cursor);
679
680     memset(&info, 0, sizeof(info));
681     info.cbSize = sizeof(info);
682     hr = GetCursorInfo(&info);
683     ok(hr != 0, "GetCursorInfo returned %08x\n", hr);
684     ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
685     ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
686
687     /* Still hidden */
688     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
689     ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
690
691     /* Enabled now*/
692     hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
693     ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08x\n", hr);
694
695     /* GDI cursor unchanged */
696     memset(&info, 0, sizeof(info));
697     info.cbSize = sizeof(info);
698     hr = GetCursorInfo(&info);
699     ok(hr != 0, "GetCursorInfo returned %08x\n", hr);
700     ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08x)\n", info.flags);
701     ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
702
703 cleanup:
704     if(pDevice) IDirect3D9_Release(pDevice);
705     if(pD3d) IDirect3D9_Release(pD3d);
706     DestroyWindow( hwnd );
707 }
708
709 static void test_reset(void)
710 {
711     HRESULT                      hr;
712     HWND                         hwnd               = NULL;
713     IDirect3D9                  *pD3d               = NULL;
714     IDirect3DDevice9            *pDevice            = NULL;
715     D3DPRESENT_PARAMETERS        d3dpp;
716     D3DDISPLAYMODE               d3ddm;
717     D3DVIEWPORT9                 vp;
718     DWORD                        width, orig_width = GetSystemMetrics(SM_CXSCREEN);
719     DWORD                        height, orig_height = GetSystemMetrics(SM_CYSCREEN);
720     IDirect3DSwapChain9          *pSwapchain;
721
722     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
723     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
724     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
725     ok(hwnd != NULL, "Failed to create window\n");
726     if (!pD3d || !hwnd) goto cleanup;
727
728     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
729     ZeroMemory( &d3dpp, sizeof(d3dpp) );
730     d3dpp.Windowed         = FALSE;
731     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
732     d3dpp.BackBufferWidth  = 800;
733     d3dpp.BackBufferHeight  = 600;
734     d3dpp.BackBufferFormat = d3ddm.Format;
735
736     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
737                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
738
739     if(FAILED(hr))
740     {
741         trace("could not create device, IDirect3D9_CreateDevice returned %#x\n", hr);
742         goto cleanup;
743     }
744
745     width = GetSystemMetrics(SM_CXSCREEN);
746     height = GetSystemMetrics(SM_CYSCREEN);
747     ok(width == 800, "Screen width is %d\n", width);
748     ok(height == 600, "Screen height is %d\n", height);
749
750     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
751     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
752     if(SUCCEEDED(hr))
753     {
754         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
755         ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
756         ok(vp.Width == 800, "D3DVIEWPORT->X = %d\n", vp.Width);
757         ok(vp.Height == 600, "D3DVIEWPORT->X = %d\n", vp.Height);
758         ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
759         ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
760     }
761     vp.X = 10;
762     vp.X = 20;
763     vp.MinZ = 2;
764     vp.MaxZ = 3;
765     hr = IDirect3DDevice9_SetViewport(pDevice, &vp);
766     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
767
768     ZeroMemory( &d3dpp, sizeof(d3dpp) );
769     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
770     d3dpp.Windowed         = FALSE;
771     d3dpp.BackBufferWidth  = 640;
772     d3dpp.BackBufferHeight  = 480;
773     d3dpp.BackBufferFormat = d3ddm.Format;
774     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
775     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %s\n", DXGetErrorString9(hr));
776
777     ZeroMemory(&vp, sizeof(vp));
778     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
779     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
780     if(SUCCEEDED(hr))
781     {
782         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
783         ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
784         ok(vp.Width == 640, "D3DVIEWPORT->X = %d\n", vp.Width);
785         ok(vp.Height == 480, "D3DVIEWPORT->X = %d\n", vp.Height);
786         ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
787         ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
788     }
789
790     width = GetSystemMetrics(SM_CXSCREEN);
791     height = GetSystemMetrics(SM_CYSCREEN);
792     ok(width == 640, "Screen width is %d\n", width);
793     ok(height == 480, "Screen height is %d\n", height);
794
795     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapchain);
796     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %s\n", DXGetErrorString9(hr));
797     if(SUCCEEDED(hr))
798     {
799         ZeroMemory(&d3dpp, sizeof(d3dpp));
800         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
801         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %s\n", DXGetErrorString9(hr));
802         if(SUCCEEDED(hr))
803         {
804             ok(d3dpp.BackBufferWidth == 640, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
805             ok(d3dpp.BackBufferHeight == 480, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
806         }
807         IDirect3DSwapChain9_Release(pSwapchain);
808     }
809
810     ZeroMemory( &d3dpp, sizeof(d3dpp) );
811     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
812     d3dpp.Windowed         = TRUE;
813     d3dpp.BackBufferWidth  = 400;
814     d3dpp.BackBufferHeight  = 300;
815     hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
816     ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %s\n", DXGetErrorString9(hr));
817
818     width = GetSystemMetrics(SM_CXSCREEN);
819     height = GetSystemMetrics(SM_CYSCREEN);
820     ok(width == orig_width, "Screen width is %d\n", width);
821     ok(height == orig_height, "Screen height is %d\n", height);
822
823     ZeroMemory(&vp, sizeof(vp));
824     hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
825     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
826     if(SUCCEEDED(hr))
827     {
828         ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
829         ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
830         ok(vp.Width == 400, "D3DVIEWPORT->X = %d\n", vp.Width);
831         ok(vp.Height == 300, "D3DVIEWPORT->X = %d\n", vp.Height);
832         ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
833         ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
834     }
835
836     hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapchain);
837     ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %s\n", DXGetErrorString9(hr));
838     if(SUCCEEDED(hr))
839     {
840         ZeroMemory(&d3dpp, sizeof(d3dpp));
841         hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
842         ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %s\n", DXGetErrorString9(hr));
843         if(SUCCEEDED(hr))
844         {
845             ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
846             ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
847         }
848         IDirect3DSwapChain9_Release(pSwapchain);
849     }
850
851 cleanup:
852     if(pD3d) IDirect3D9_Release(pD3d);
853     if(pDevice) IDirect3D9_Release(pDevice);
854 }
855
856 /* Test adapter display modes */
857 static void test_display_modes(void)
858 {
859     D3DDISPLAYMODE dmode;
860     IDirect3D9 *pD3d;
861
862     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
863     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
864     if(!pD3d) return;
865
866 #define TEST_FMT(x,r) do { \
867     HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
868     ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %s)!\n", DXGetErrorString9(res)); \
869 } while(0)
870
871     TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
872     TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
873     TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
874     /* D3DFMT_R5G6B5 */
875     TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
876     TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
877     TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
878     TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
879     TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
880     TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
881     TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
882     TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
883     TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
884     TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
885     TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
886     TEST_FMT(D3DFMT_A2R10G10B10, D3DERR_INVALIDCALL);
887     TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
888
889     TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
890     TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
891
892     TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
893     TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
894     TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
895
896     TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
897     TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
898     TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
899     TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
900     TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
901     TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
902
903     TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
904     TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
905     TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
906     TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
907     TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
908     TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
909     TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
910     TEST_FMT(D3DFMT_MULTI2_ARGB8, D3DERR_INVALIDCALL);
911     TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
912     TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
913
914     TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
915     TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
916     TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
917     TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
918     TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
919     TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
920     TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
921     TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
922     TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
923     TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
924
925     TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
926     TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
927     TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
928     TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
929     /* Floating point formats */
930     TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
931     TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
932     TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
933
934     /* IEEE formats */
935     TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
936     TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
937     TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
938
939     TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
940
941     TEST_FMT(0, D3DERR_INVALIDCALL);
942
943     IDirect3D9_Release(pD3d);
944 }
945
946 static void test_scene(void)
947 {
948     HRESULT                      hr;
949     HWND                         hwnd               = NULL;
950     IDirect3D9                  *pD3d               = NULL;
951     IDirect3DDevice9            *pDevice            = NULL;
952     D3DPRESENT_PARAMETERS        d3dpp;
953     D3DDISPLAYMODE               d3ddm;
954     IDirect3DSurface9            *pSurface1 = NULL, *pSurface2 = NULL, *pSurface3 = NULL, *pRenderTarget = NULL;
955     IDirect3DSurface9            *pBackBuffer = NULL, *pDepthStencil = NULL;
956     RECT rect = {0, 0, 128, 128};
957     D3DCAPS9                     caps;
958
959     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
960     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
961     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
962     ok(hwnd != NULL, "Failed to create window\n");
963     if (!pD3d || !hwnd) goto cleanup;
964
965     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
966     ZeroMemory( &d3dpp, sizeof(d3dpp) );
967     d3dpp.Windowed         = TRUE;
968     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
969     d3dpp.BackBufferWidth  = 800;
970     d3dpp.BackBufferHeight  = 600;
971     d3dpp.BackBufferFormat = d3ddm.Format;
972     d3dpp.EnableAutoDepthStencil = TRUE;
973     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
974
975     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
976                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
977     ok(hr == D3D_OK, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
978     if(!pDevice) goto cleanup;
979
980     /* Get the caps, they will be needed to tell if an operation is supposed to be valid */
981     memset(&caps, 0, sizeof(caps));
982     hr = IDirect3DDevice9_GetDeviceCaps(pDevice, &caps);
983     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed with %s\n", DXGetErrorString9(hr));
984     if(FAILED(hr)) goto cleanup;
985
986     /* Test an EndScene without beginscene. Should return an error */
987     hr = IDirect3DDevice9_EndScene(pDevice);
988     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
989
990     /* Test a normal BeginScene / EndScene pair, this should work */
991     hr = IDirect3DDevice9_BeginScene(pDevice);
992     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
993     if(SUCCEEDED(hr))
994     {
995         hr = IDirect3DDevice9_EndScene(pDevice);
996         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
997     }
998
999     /* Test another EndScene without having begun a new scene. Should return an error */
1000     hr = IDirect3DDevice9_EndScene(pDevice);
1001     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
1002
1003     /* Two nested BeginScene and EndScene calls */
1004     hr = IDirect3DDevice9_BeginScene(pDevice);
1005     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1006     hr = IDirect3DDevice9_BeginScene(pDevice);
1007     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
1008     hr = IDirect3DDevice9_EndScene(pDevice);
1009     ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1010     hr = IDirect3DDevice9_EndScene(pDevice);
1011     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
1012
1013     /* Create some surfaces to test stretchrect between the scenes */
1014     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface1, NULL);
1015     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
1016     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 128, 128, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface2, NULL);
1017     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
1018     hr = IDirect3DDevice9_CreateDepthStencilSurface(pDevice, 800, 600, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface3, NULL);
1019     ok(hr == D3D_OK, "IDirect3DDevice9_CreateDepthStencilSurface failed with %s\n", DXGetErrorString9(hr));
1020     hr = IDirect3DDevice9_CreateRenderTarget(pDevice, 128, 128, d3ddm.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pRenderTarget, NULL);
1021     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
1022
1023     hr = IDirect3DDevice9_GetBackBuffer(pDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
1024     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
1025     hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil);
1026     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
1027
1028     /* First make sure a simple StretchRect call works */
1029     if(pSurface1 && pSurface2) {
1030         hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1031         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
1032     }
1033     if(pBackBuffer && pRenderTarget) {
1034         hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1035         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
1036     }
1037     if(pDepthStencil && pSurface3) {
1038         HRESULT expected;
1039         if(0) /* Disabled for now because it crashes in wine */ {
1040             expected = caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES ? D3D_OK : D3DERR_INVALIDCALL;
1041             hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1042             ok( hr == expected, "IDirect3DDevice9_StretchRect returned %s, expected %s\n", DXGetErrorString9(hr), DXGetErrorString9(expected));
1043         }
1044     }
1045
1046     /* Now try it in a BeginScene - EndScene pair. Seems to be allowed in a beginScene - Endscene pair
1047      * width normal surfaces, render targets and depth stencil surfaces.
1048      */
1049     hr = IDirect3DDevice9_BeginScene(pDevice);
1050     ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1051
1052     if(pSurface1 && pSurface2)
1053     {
1054         hr = IDirect3DDevice9_StretchRect(pDevice, pSurface1, NULL, pSurface2, NULL, 0);
1055         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
1056     }
1057     if(pBackBuffer && pRenderTarget)
1058     {
1059         hr = IDirect3DDevice9_StretchRect(pDevice, pBackBuffer, &rect, pRenderTarget, NULL, 0);
1060         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
1061     }
1062     if(pDepthStencil && pSurface3)
1063     {
1064         /* This is supposed to fail inside a BeginScene - EndScene pair. */
1065         hr = IDirect3DDevice9_StretchRect(pDevice, pDepthStencil, NULL, pSurface3, NULL, 0);
1066         ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect returned %s, expected D3DERR_INVALIDCALL\n", DXGetErrorString9(hr));
1067     }
1068
1069     hr = IDirect3DDevice9_EndScene(pDevice);
1070     ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1071
1072     /* Does a SetRenderTarget influence BeginScene / EndScene ?
1073      * Set a new render target, then see if it started a new scene. Flip the rt back and see if that maybe
1074      * ended the scene. Expected result is that the scene is not affected by SetRenderTarget
1075      */
1076     hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pRenderTarget);
1077     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
1078     hr = IDirect3DDevice9_BeginScene(pDevice);
1079     ok( hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1080     hr = IDirect3DDevice9_SetRenderTarget(pDevice, 0, pBackBuffer);
1081     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
1082     hr = IDirect3DDevice9_EndScene(pDevice);
1083     ok( hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1084
1085 cleanup:
1086     if(pRenderTarget) IDirect3DSurface9_Release(pRenderTarget);
1087     if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil);
1088     if(pBackBuffer) IDirect3DSurface9_Release(pBackBuffer);
1089     if(pSurface1) IDirect3DSurface9_Release(pSurface1);
1090     if(pSurface2) IDirect3DSurface9_Release(pSurface2);
1091     if(pSurface3) IDirect3DSurface9_Release(pSurface3);
1092     if(pD3d) IDirect3D9_Release(pD3d);
1093     if(pDevice) IDirect3D9_Release(pDevice);
1094     if(hwnd) DestroyWindow(hwnd);
1095 }
1096
1097 static void test_limits(void)
1098 {
1099     HRESULT                      hr;
1100     HWND                         hwnd               = NULL;
1101     IDirect3D9                  *pD3d               = NULL;
1102     IDirect3DDevice9            *pDevice            = NULL;
1103     D3DPRESENT_PARAMETERS        d3dpp;
1104     D3DDISPLAYMODE               d3ddm;
1105     IDirect3DTexture9           *pTexture           = NULL;
1106     int i;
1107
1108     pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
1109     ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
1110     hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1111     ok(hwnd != NULL, "Failed to create window\n");
1112     if (!pD3d || !hwnd) goto cleanup;
1113
1114     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
1115     ZeroMemory( &d3dpp, sizeof(d3dpp) );
1116     d3dpp.Windowed         = TRUE;
1117     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
1118     d3dpp.BackBufferWidth  = 800;
1119     d3dpp.BackBufferHeight  = 600;
1120     d3dpp.BackBufferFormat = d3ddm.Format;
1121     d3dpp.EnableAutoDepthStencil = TRUE;
1122     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
1123
1124     hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
1125                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
1126     ok(hr == D3D_OK, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
1127     if(!pDevice) goto cleanup;
1128
1129     hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
1130     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
1131     if(!pTexture) goto cleanup;
1132
1133     /* There are 16 pixel samplers. We should be able to access all of them */
1134     for(i = 0; i < 16; i++) {
1135         hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
1136         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
1137         hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
1138         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
1139         hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
1140         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
1141     }
1142
1143     /* Now test all 8 textures stage states */
1144     for(i = 0; i < 8; i++) {
1145         hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
1146         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %s\n", i, DXGetErrorString9(hr));
1147     }
1148
1149     /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
1150      * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
1151      * but how do I test that?
1152      */
1153 cleanup:
1154     if(pTexture) IDirect3DTexture9_Release(pTexture);
1155     if(pD3d) IDirect3D9_Release(pD3d);
1156     if(pDevice) IDirect3D9_Release(pDevice);
1157     if(hwnd) DestroyWindow(hwnd);
1158 }
1159
1160 START_TEST(device)
1161 {
1162     HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
1163     if (!d3d9_handle)
1164     {
1165         skip("Could not load d3d9.dll\n");
1166         return;
1167     }
1168
1169     pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
1170     ok(pDirect3DCreate9 != NULL, "Failed to get address of Direct3DCreate9\n");
1171     if (pDirect3DCreate9)
1172     {
1173         test_display_modes();
1174         test_swapchain();
1175         test_refcount();
1176         test_mipmap_levels();
1177         test_cursor();
1178         test_reset();
1179         test_scene();
1180         test_limits();
1181     }
1182 }