2 * Copyright (C) 2006 Vitaliy Margolen
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.
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.
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
22 #include "wine/test.h"
24 static IDirect3D9
*(WINAPI
*pDirect3DCreate9
)(UINT
);
26 static int get_refcount(IUnknown
*object
)
28 IUnknown_AddRef( object
);
29 return IUnknown_Release( object
);
32 #define CHECK_CALL(r,c,d,rc) \
34 int tmp1 = get_refcount( (IUnknown *)d ); \
35 ok(rc == tmp1, "Invalid refcount. Expected %d got %d\n", rc, tmp1); \
37 trace("%s failed: %s\n", c, DXGetErrorString9(r)); \
40 void test_refcount(void)
44 IDirect3D9
*pD3d
= NULL
;
45 IDirect3DDevice9
*pDevice
= NULL
;
46 IDirect3DVertexBuffer9
*pVertexBuffer
= NULL
;
47 IDirect3DIndexBuffer9
*pIndexBuffer
= NULL
;
48 IDirect3DVertexDeclaration9
*pVertexDeclaration
= NULL
;
49 IDirect3DVertexShader9
*pVertexShader
= NULL
;
50 IDirect3DPixelShader9
*pPixelShader
= NULL
;
51 IDirect3DCubeTexture9
*pCubeTexture
= NULL
;
52 IDirect3DTexture9
*pTexture
= NULL
;
53 IDirect3DVolumeTexture9
*pVolumeTexture
= NULL
;
54 IDirect3DSurface9
*pStencilSurface
= NULL
;
55 IDirect3DSurface9
*pOffscreenSurface
= NULL
;
56 IDirect3DSurface9
*pRenderTarget
= NULL
;
57 IDirect3DSurface9
*pTextureLevel
= NULL
;
58 IDirect3DStateBlock9
*pStateBlock
= NULL
;
59 IDirect3DSwapChain9
*pSwapChain
= NULL
;
60 IDirect3DQuery9
*pQuery
= NULL
;
61 D3DPRESENT_PARAMETERS d3dpp
;
65 D3DVERTEXELEMENT9 decl
[] =
69 static DWORD simple_vs
[] = {0xFFFE0101, /* vs_1_1 */
70 0x0000001F, 0x80000000, 0x900F0000, /* dcl_position0 v0 */
71 0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0 */
72 0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1 */
73 0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2 */
74 0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3 */
75 0x0000FFFF}; /* END */
76 static DWORD simple_ps
[] = {0xFFFF0101, /* ps_1_1 */
77 0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
78 0x00000042, 0xB00F0000, /* tex t0 */
79 0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000, /* dp3 r0, c1, c0 */
80 0x00000005, 0x800F0000, 0x90E40000, 0x80E40000, /* mul r0, v0, r0 */
81 0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000, /* mul r0, t0, r0 */
82 0x0000FFFF}; /* END */
85 pD3d
= pDirect3DCreate9( D3D_SDK_VERSION
);
86 ok(pD3d
!= NULL
, "Failed to create IDirect3D9 object\n");
87 hwnd
= CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
88 ok(hwnd
!= NULL
, "Failed to create window\n");
89 if (!pD3d
|| !hwnd
) goto cleanup
;
91 IDirect3D9_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
92 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
93 d3dpp
.Windowed
= TRUE
;
94 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
95 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
97 hr
= IDirect3D9_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_NULLREF
, hwnd
,
98 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
99 ok(SUCCEEDED(hr
), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr
));
100 if (FAILED(hr
)) goto cleanup
;
104 refcount
= get_refcount( (IUnknown
*)pDevice
);
105 hr
= IDirect3DDevice9_CreateIndexBuffer( pDevice
, 16, 0, D3DFMT_INDEX32
, D3DPOOL_DEFAULT
, &pIndexBuffer
, NULL
);
106 CHECK_CALL( hr
, "CreateIndexBuffer", pDevice
, refcount
+1 );
107 refcount
= get_refcount( (IUnknown
*)pDevice
);
108 hr
= IDirect3DDevice9_CreateVertexBuffer( pDevice
, 16, 0, D3DFVF_XYZ
, D3DPOOL_DEFAULT
, &pVertexBuffer
, NULL
);
109 CHECK_CALL( hr
, "CreateVertexBuffer", pDevice
, refcount
+1 );
111 refcount
= get_refcount( (IUnknown
*)pDevice
);
112 hr
= IDirect3DDevice9_CreateVertexDeclaration( pDevice
, decl
, &pVertexDeclaration
);
113 CHECK_CALL( hr
, "CreateVertexDeclaration", pDevice
, refcount
+1 );
114 refcount
= get_refcount( (IUnknown
*)pDevice
);
115 hr
= IDirect3DDevice9_CreateVertexShader( pDevice
, simple_vs
, &pVertexShader
);
116 CHECK_CALL( hr
, "CreateVertexShader", pDevice
, refcount
+1 );
117 refcount
= get_refcount( (IUnknown
*)pDevice
);
118 hr
= IDirect3DDevice9_CreatePixelShader( pDevice
, simple_ps
, &pPixelShader
);
119 CHECK_CALL( hr
, "CreatePixelShader", pDevice
, refcount
+1 );
121 refcount
= get_refcount( (IUnknown
*)pDevice
);
122 hr
= IDirect3DDevice9_CreateTexture( pDevice
, 32, 32, 3, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pTexture
, NULL
);
123 CHECK_CALL( hr
, "CreateTexture", pDevice
, refcount
+1 );
126 tmp
= get_refcount( (IUnknown
*)pTexture
);
127 /* This should not increment device refcount */
128 hr
= IDirect3DTexture9_GetSurfaceLevel( pTexture
, 1, &pTextureLevel
);
129 CHECK_CALL( hr
, "GetSurfaceLevel", pDevice
, refcount
+1 );
130 /* But should increment texture's refcount */
131 CHECK_CALL( hr
, "GetSurfaceLevel", pTexture
, tmp
+1 );
133 refcount
= get_refcount( (IUnknown
*)pDevice
);
134 hr
= IDirect3DDevice9_CreateCubeTexture( pDevice
, 32, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pCubeTexture
, NULL
);
135 CHECK_CALL( hr
, "CreateCubeTexture", pDevice
, refcount
+1 );
136 refcount
= get_refcount( (IUnknown
*)pDevice
);
137 hr
= IDirect3DDevice9_CreateVolumeTexture( pDevice
, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pVolumeTexture
, NULL
);
138 CHECK_CALL( hr
, "CreateVolumeTexture", pDevice
, refcount
+1 );
140 refcount
= get_refcount( (IUnknown
*)pDevice
);
141 hr
= IDirect3DDevice9_CreateDepthStencilSurface( pDevice
, 32, 32, D3DFMT_D24S8
, D3DMULTISAMPLE_NONE
, 0, TRUE
, &pStencilSurface
, NULL
);
142 todo_wine
{CHECK_CALL( hr
, "CreateDepthStencilSurface", pDevice
, refcount
+1 );}
143 refcount
= get_refcount( (IUnknown
*)pDevice
);
144 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pOffscreenSurface
, NULL
);
145 todo_wine
{CHECK_CALL( hr
, "CreateOffscreenPlainSurface", pDevice
, refcount
+1 );}
146 refcount
= get_refcount( (IUnknown
*)pDevice
);
147 hr
= IDirect3DDevice9_CreateRenderTarget( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, D3DMULTISAMPLE_NONE
, 0, TRUE
, &pRenderTarget
, NULL
);
148 todo_wine
{CHECK_CALL( hr
, "CreateRenderTarget", pDevice
, refcount
+1 );}
150 refcount
= get_refcount( (IUnknown
*)pDevice
);
151 hr
= IDirect3DDevice9_CreateStateBlock( pDevice
, D3DSBT_ALL
, &pStateBlock
);
152 CHECK_CALL( hr
, "CreateStateBlock", pDevice
, refcount
+1 );
153 refcount
= get_refcount( (IUnknown
*)pDevice
);
154 hr
= IDirect3DDevice9_CreateAdditionalSwapChain( pDevice
, &d3dpp
, &pSwapChain
);
155 CHECK_CALL( hr
, "CreateAdditionalSwapChain", pDevice
, refcount
+1 );
156 refcount
= get_refcount( (IUnknown
*)pDevice
);
157 hr
= IDirect3DDevice9_CreateQuery( pDevice
, D3DQUERYTYPE_EVENT
, &pQuery
);
158 CHECK_CALL( hr
, "CreateQuery", pDevice
, refcount
+1 );
161 if (pDevice
) IUnknown_Release( pDevice
);
164 if (pVertexBuffer
) IUnknown_Release( pVertexBuffer
);
165 if (pIndexBuffer
) IUnknown_Release( pIndexBuffer
);
167 if (pVertexDeclaration
) IUnknown_Release( pVertexDeclaration
);
168 if (pVertexShader
) IUnknown_Release( pVertexShader
);
169 if (pPixelShader
) IUnknown_Release( pPixelShader
);
171 if (pTexture
) IUnknown_Release( pTexture
);
172 if (pTextureLevel
) IUnknown_Release( pTextureLevel
);
173 if (pCubeTexture
) IUnknown_Release( pCubeTexture
);
174 if (pVolumeTexture
) IUnknown_Release( pVolumeTexture
);
176 if (pStencilSurface
) IUnknown_Release( pStencilSurface
);
177 if (pOffscreenSurface
) IUnknown_Release( pOffscreenSurface
);
178 if (pRenderTarget
) IUnknown_Release( pRenderTarget
);
180 if (pStateBlock
) IUnknown_Release( pStateBlock
);
181 /* Avoid crash for now.
182 if (pSwapChain) IUnknown_Release( pSwapChain );
184 if (pQuery
) IUnknown_Release( pQuery
);
186 if (pD3d
) IUnknown_Release( pD3d
);
188 DestroyWindow( hwnd
);
193 HMODULE d3d9_handle
= LoadLibraryA( "d3d9.dll" );
195 pDirect3DCreate9
= (void *)GetProcAddress( d3d9_handle
, "Direct3DCreate9" );
196 if (pDirect3DCreate9
)