mshtml: Added beginning OnDataAvailable implementation.
[wine] / dlls / d3d8 / tests / device.c
1 /*
2  * Copyright (C) 2006 Vitaliy Margolen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20 #include <d3d8.h>
21 #include <dxerr8.h>
22 #include "wine/test.h"
23
24 static IDirect3D8 *(WINAPI *pDirect3DCreate8)(UINT);
25
26 static int get_refcount(IUnknown *object)
27 {
28     IUnknown_AddRef( object );
29     return IUnknown_Release( object );
30 }
31
32 #define CHECK_CALL(r,c,d,rc) \
33     if (SUCCEEDED(r)) {\
34         int tmp1 = get_refcount( (IUnknown *)d ); \
35         ok(rc == tmp1, "Invalid refcount. Expected %d got %d\n", rc, tmp1); \
36     } else {\
37         trace("%s failed: %s\n", c, DXGetErrorString8(r)); \
38     }
39
40 void test_swapchain(void)
41 {
42     HRESULT                      hr;
43     HWND                         hwnd               = NULL;
44     IDirect3D8                  *pD3d               = NULL;
45     IDirect3DDevice8            *pDevice            = NULL;
46     IDirect3DSwapChain8         *swapchain1         = NULL;
47     IDirect3DSwapChain8         *swapchain2         = NULL;
48     IDirect3DSwapChain8         *swapchain3         = NULL;
49     IDirect3DSurface8           *backbuffer         = NULL;
50     D3DPRESENT_PARAMETERS        d3dpp;
51     D3DDISPLAYMODE               d3ddm;
52
53     pD3d = pDirect3DCreate8( D3D_SDK_VERSION );
54     ok(pD3d != NULL, "Failed to create IDirect3D8 object\n");
55     hwnd = CreateWindow( "static", "d3d8_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
56     ok(hwnd != NULL, "Failed to create window\n");
57     if (!pD3d || !hwnd) goto cleanup;
58
59     IDirect3D8_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
60     ZeroMemory( &d3dpp, sizeof(d3dpp) );
61     d3dpp.Windowed         = TRUE;
62     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
63     d3dpp.BackBufferFormat = d3ddm.Format;
64     d3dpp.BackBufferCount  = 0;
65
66     hr = IDirect3D8_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
67                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
68     ok(SUCCEEDED(hr), "Failed to create IDirect3D8Device (%s)\n", DXGetErrorString8(hr));
69     if (FAILED(hr)) goto cleanup;
70
71     /* Check if the back buffer count was modified */
72     ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
73
74     /* Create a bunch of swapchains */
75     d3dpp.BackBufferCount = 0;
76     hr = IDirect3DDevice8_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain1);
77     ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString8(hr));
78     ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount);
79
80     d3dpp.BackBufferCount  = 1;
81     hr = IDirect3DDevice8_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain2);
82     ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString8(hr));
83
84     /* Unsupported by wine for now */
85     d3dpp.BackBufferCount  = 2;
86     hr = IDirect3DDevice8_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3);
87     todo_wine ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString8(hr));
88     if(SUCCEEDED(hr)) {
89         /* Swapchain 3, created with backbuffercount 2 */
90         backbuffer = (void *) 0xdeadbeef;
91         hr = IDirect3DSwapChain8_GetBackBuffer(swapchain3, 0, 0, &backbuffer);
92         ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%s)\n", DXGetErrorString8(hr));
93         ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
94         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer);
95
96         backbuffer = (void *) 0xdeadbeef;
97         hr = IDirect3DSwapChain8_GetBackBuffer(swapchain3, 1, 0, &backbuffer);
98         ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%s)\n", DXGetErrorString8(hr));
99         ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
100         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer);
101
102         backbuffer = (void *) 0xdeadbeef;
103         hr = IDirect3DSwapChain8_GetBackBuffer(swapchain3, 2, 0, &backbuffer);
104         ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %s\n", DXGetErrorString8(hr));
105         ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
106         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer);
107
108         backbuffer = (void *) 0xdeadbeef;
109         hr = IDirect3DSwapChain8_GetBackBuffer(swapchain3, 3, 0, &backbuffer);
110         ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString8(hr));
111         ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
112         if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer);
113     }
114
115     /* Check the back buffers of the swapchains */
116     /* Swapchain 1, created with backbuffercount 0 */
117     hr = IDirect3DSwapChain8_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
118     ok(SUCCEEDED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString8(hr));
119     ok(backbuffer != NULL, "The back buffer is NULL (%s)\n", DXGetErrorString8(hr));
120     if(backbuffer) IDirect3DSurface8_Release(backbuffer);
121
122     backbuffer = (void *) 0xdeadbeef;
123     hr = IDirect3DSwapChain8_GetBackBuffer(swapchain1, 1, 0, &backbuffer);
124     ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString8(hr));
125     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
126     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer);
127
128     /* Swapchain 2 - created with backbuffercount 1 */
129     backbuffer = (void *) 0xdeadbeef;
130     hr = IDirect3DSwapChain8_GetBackBuffer(swapchain2, 0, 0, &backbuffer);
131     ok(SUCCEEDED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString8(hr));
132     ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer);
133     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer);
134
135     backbuffer = (void *) 0xdeadbeef;
136     hr = IDirect3DSwapChain8_GetBackBuffer(swapchain2, 1, 0, &backbuffer);
137     ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %s\n", DXGetErrorString8(hr));
138     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
139     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer);
140
141     backbuffer = (void *) 0xdeadbeef;
142     hr = IDirect3DSwapChain8_GetBackBuffer(swapchain2, 2, 0, &backbuffer);
143     ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString8(hr));
144     ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer);
145     if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer);
146
147     cleanup:
148     if(swapchain1) IDirect3DSwapChain8_Release(swapchain1);
149     if(swapchain2) IDirect3DSwapChain8_Release(swapchain2);
150     if(swapchain3) IDirect3DSwapChain8_Release(swapchain3);
151     if(pDevice) IDirect3DDevice8_Release(pDevice);
152     if(pD3d) IDirect3DDevice8_Release(pD3d);
153     DestroyWindow( hwnd );
154 }
155
156 void test_refcount(void)
157 {
158     HRESULT                      hr;
159     HWND                         hwnd               = NULL;
160     IDirect3D8                  *pD3d               = NULL;
161     IDirect3DDevice8            *pDevice            = NULL;
162     IDirect3DVertexBuffer8      *pVertexBuffer      = NULL;
163     IDirect3DIndexBuffer8       *pIndexBuffer       = NULL;
164     DWORD dVertexShader         = -1;
165     DWORD dPixelShader          = -1;
166     IDirect3DCubeTexture8       *pCubeTexture       = NULL;
167     IDirect3DTexture8           *pTexture           = NULL;
168     IDirect3DVolumeTexture8     *pVolumeTexture     = NULL;
169     IDirect3DSurface8           *pStencilSurface    = NULL;
170     IDirect3DSurface8           *pImageSurface = NULL;
171     IDirect3DSurface8           *pRenderTarget      = NULL;
172     IDirect3DSurface8           *pTextureLevel      = NULL;
173     DWORD dStateBlock           = -1;
174     IDirect3DSwapChain8         *pSwapChain         = NULL;
175
176     D3DPRESENT_PARAMETERS        d3dpp;
177     D3DDISPLAYMODE               d3ddm;
178     int                          refcount, tmp;
179
180     DWORD decl[] =
181     {
182         D3DVSD_STREAM(0),
183         D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),  /* D3DVSDE_POSITION, Register v0 */
184         D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR), /* D3DVSDE_DIFFUSE, Register v5 */
185         D3DVSD_END()
186     };
187     static DWORD simple_vs[] = {0xFFFE0101,             /* vs_1_1               */
188         0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0   */
189         0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1   */
190         0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2   */
191         0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3   */
192         0x0000FFFF};                                    /* END                  */
193     static DWORD simple_ps[] = {0xFFFF0101,                                     /* ps_1_1                       */
194         0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0  */
195         0x00000042, 0xB00F0000,                                                 /* tex t0                       */
196         0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000,                         /* dp3 r0, c1, c0               */
197         0x00000005, 0x800F0000, 0x90E40000, 0x80E40000,                         /* mul r0, v0, r0               */
198         0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000,                         /* mul r0, t0, r0               */
199         0x0000FFFF};                                                            /* END                          */
200
201
202     pD3d = pDirect3DCreate8( D3D_SDK_VERSION );
203     ok(pD3d != NULL, "Failed to create IDirect3D8 object\n");
204     hwnd = CreateWindow( "static", "d3d8_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
205     ok(hwnd != NULL, "Failed to create window\n");
206     if (!pD3d || !hwnd) goto cleanup;
207
208     IDirect3D8_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
209     ZeroMemory( &d3dpp, sizeof(d3dpp) );
210     d3dpp.Windowed         = TRUE;
211     d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
212     d3dpp.BackBufferFormat = d3ddm.Format;
213
214     hr = IDirect3D8_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
215                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
216     ok(SUCCEEDED(hr), "Failed to create IDirect3D8Device (%s)\n", DXGetErrorString8(hr));
217     if (FAILED(hr)) goto cleanup;
218
219
220     /* Buffers */
221     refcount = get_refcount( (IUnknown *)pDevice );
222     hr = IDirect3DDevice8_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer );
223     CHECK_CALL( hr, "CreateIndexBuffer", pDevice, refcount+1 );
224     refcount = get_refcount( (IUnknown *)pDevice );
225     hr = IDirect3DDevice8_CreateVertexBuffer( pDevice, 16, 0, D3DFVF_XYZ, D3DPOOL_DEFAULT, &pVertexBuffer );
226     CHECK_CALL( hr, "CreateVertexBuffer", pDevice, refcount+1 );
227     /* Shaders */
228     refcount = get_refcount( (IUnknown *)pDevice );
229     hr = IDirect3DDevice8_CreateVertexShader( pDevice, decl, simple_vs, &dVertexShader, 0 );
230     CHECK_CALL( hr, "CreateVertexShader", pDevice, refcount );
231     refcount = get_refcount( (IUnknown *)pDevice );
232     hr = IDirect3DDevice8_CreatePixelShader( pDevice, simple_ps, &dPixelShader );
233     CHECK_CALL( hr, "CreatePixelShader", pDevice, refcount );
234     /* Textures */
235     refcount = get_refcount( (IUnknown *)pDevice );
236     hr = IDirect3DDevice8_CreateTexture( pDevice, 32, 32, 3, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture );
237     CHECK_CALL( hr, "CreateTexture", pDevice, refcount+1 );
238     if (pTexture)
239     {
240         tmp = get_refcount( (IUnknown *)pTexture );
241         /* This should not increment device refcount */
242         hr = IDirect3DTexture8_GetSurfaceLevel( pTexture, 1, &pTextureLevel );
243         CHECK_CALL( hr, "GetSurfaceLevel", pDevice, refcount+1 );
244         /* But should increment texture's refcount */
245         CHECK_CALL( hr, "GetSurfaceLevel", pTexture, tmp+1 );
246     }
247     refcount = get_refcount( (IUnknown *)pDevice );
248     hr = IDirect3DDevice8_CreateCubeTexture( pDevice, 32, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeTexture );
249     CHECK_CALL( hr, "CreateCubeTexture", pDevice, refcount+1 );
250     refcount = get_refcount( (IUnknown *)pDevice );
251     hr = IDirect3DDevice8_CreateVolumeTexture( pDevice, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pVolumeTexture );
252     CHECK_CALL( hr, "CreateVolumeTexture", pDevice, refcount+1 );
253     /* Surfaces */
254     refcount = get_refcount( (IUnknown *)pDevice );
255     hr = IDirect3DDevice8_CreateDepthStencilSurface( pDevice, 32, 32, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, &pStencilSurface );
256     todo_wine {CHECK_CALL( hr, "CreateDepthStencilSurface", pDevice, refcount+1 );}
257     refcount = get_refcount( (IUnknown *)pDevice );
258     hr = IDirect3DDevice8_CreateImageSurface( pDevice, 32, 32, D3DFMT_X8R8G8B8, &pImageSurface );
259     todo_wine {CHECK_CALL( hr, "CreateImageSurface", pDevice, refcount+1 );}
260     refcount = get_refcount( (IUnknown *)pDevice );
261     hr = IDirect3DDevice8_CreateRenderTarget( pDevice, 32, 32, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, TRUE, &pRenderTarget );
262     todo_wine {CHECK_CALL( hr, "CreateRenderTarget", pDevice, refcount+1 );}
263     /* Misc */
264     refcount = get_refcount( (IUnknown *)pDevice );
265     hr = IDirect3DDevice8_CreateStateBlock( pDevice, D3DSBT_ALL, &dStateBlock );
266     CHECK_CALL( hr, "CreateStateBlock", pDevice, refcount );
267     refcount = get_refcount( (IUnknown *)pDevice );
268     hr = IDirect3DDevice8_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
269     CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, refcount+1 );
270
271 cleanup:
272     if (pDevice)              IUnknown_Release( pDevice );
273
274     /* Buffers */
275     if (pVertexBuffer)        IUnknown_Release( pVertexBuffer );
276     if (pIndexBuffer)         IUnknown_Release( pIndexBuffer );
277     /* Shaders */
278     if (dVertexShader != -1)  IDirect3DDevice8_DeleteVertexShader( pDevice, dVertexShader );
279     if (dPixelShader != -1)   IDirect3DDevice8_DeletePixelShader( pDevice, dPixelShader );
280     /* Textures */
281     if (pTexture)             IUnknown_Release( pTexture );
282     if (pTextureLevel)        IUnknown_Release( pTextureLevel );
283     if (pCubeTexture)         IUnknown_Release( pCubeTexture );
284     if (pVolumeTexture)       IUnknown_Release( pVolumeTexture );
285     /* Surfaces */
286     if (pStencilSurface)      IUnknown_Release( pStencilSurface );
287     if (pImageSurface)        IUnknown_Release( pImageSurface );
288     if (pRenderTarget)        IUnknown_Release( pRenderTarget );
289     /* Misc */
290     if (dStateBlock != -1)    IDirect3DDevice8_DeleteStateBlock( pDevice, dStateBlock );
291     /* Avoid crash for now.
292     if (pSwapChain)           IUnknown_Release( pSwapChain );
293     */
294
295     if (pD3d)                 IUnknown_Release( pD3d );
296
297     DestroyWindow( hwnd );
298 }
299
300 START_TEST(device)
301 {
302     HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" );
303
304     pDirect3DCreate8 = (void *)GetProcAddress( d3d8_handle, "Direct3DCreate8" );
305     if (pDirect3DCreate8)
306     {
307         test_refcount();
308         test_swapchain();
309     }
310 }