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 IDirect3D8
*(WINAPI
*pDirect3DCreate8
)(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, DXGetErrorString8(r)); \
40 void test_refcount(void)
44 IDirect3D8
*pD3d
= NULL
;
45 IDirect3DDevice8
*pDevice
= NULL
;
46 IDirect3DVertexBuffer8
*pVertexBuffer
= NULL
;
47 IDirect3DIndexBuffer8
*pIndexBuffer
= NULL
;
48 DWORD dVertexShader
= -1;
49 DWORD dPixelShader
= -1;
50 IDirect3DCubeTexture8
*pCubeTexture
= NULL
;
51 IDirect3DTexture8
*pTexture
= NULL
;
52 IDirect3DVolumeTexture8
*pVolumeTexture
= NULL
;
53 IDirect3DSurface8
*pStencilSurface
= NULL
;
54 IDirect3DSurface8
*pImageSurface
= NULL
;
55 IDirect3DSurface8
*pRenderTarget
= NULL
;
56 IDirect3DSurface8
*pTextureLevel
= NULL
;
57 DWORD dStateBlock
= -1;
58 IDirect3DSwapChain8
*pSwapChain
= NULL
;
60 D3DPRESENT_PARAMETERS d3dpp
;
67 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
68 D3DVSD_REG(D3DVSDE_DIFFUSE
, D3DVSDT_D3DCOLOR
), /* D3DVSDE_DIFFUSE, Register v5 */
71 static DWORD simple_vs
[] = {0xFFFE0101, /* vs_1_1 */
72 0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0 */
73 0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1 */
74 0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2 */
75 0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3 */
76 0x0000FFFF}; /* END */
77 static DWORD simple_ps
[] = {0xFFFF0101, /* ps_1_1 */
78 0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
79 0x00000042, 0xB00F0000, /* tex t0 */
80 0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000, /* dp3 r0, c1, c0 */
81 0x00000005, 0x800F0000, 0x90E40000, 0x80E40000, /* mul r0, v0, r0 */
82 0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000, /* mul r0, t0, r0 */
83 0x0000FFFF}; /* END */
86 pD3d
= pDirect3DCreate8( D3D_SDK_VERSION
);
87 ok(pD3d
!= NULL
, "Failed to create IDirect3D8 object\n");
88 hwnd
= CreateWindow( "static", "d3d8_test", WS_OVERLAPPEDWINDOW
, 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
89 ok(hwnd
!= NULL
, "Failed to create window\n");
90 if (!pD3d
|| !hwnd
) goto cleanup
;
92 IDirect3D8_GetAdapterDisplayMode( pD3d
, D3DADAPTER_DEFAULT
, &d3ddm
);
93 ZeroMemory( &d3dpp
, sizeof(d3dpp
) );
94 d3dpp
.Windowed
= TRUE
;
95 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
96 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
98 hr
= IDirect3D8_CreateDevice( pD3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
99 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &pDevice
);
100 ok(SUCCEEDED(hr
), "Failed to create IDirect3D8Device (%s)\n", DXGetErrorString8(hr
));
101 if (FAILED(hr
)) goto cleanup
;
105 refcount
= get_refcount( (IUnknown
*)pDevice
);
106 hr
= IDirect3DDevice8_CreateIndexBuffer( pDevice
, 16, 0, D3DFMT_INDEX32
, D3DPOOL_DEFAULT
, &pIndexBuffer
);
107 CHECK_CALL( hr
, "CreateIndexBuffer", pDevice
, refcount
+1 );
108 refcount
= get_refcount( (IUnknown
*)pDevice
);
109 hr
= IDirect3DDevice8_CreateVertexBuffer( pDevice
, 16, 0, D3DFVF_XYZ
, D3DPOOL_DEFAULT
, &pVertexBuffer
);
110 CHECK_CALL( hr
, "CreateVertexBuffer", pDevice
, refcount
+1 );
112 refcount
= get_refcount( (IUnknown
*)pDevice
);
113 hr
= IDirect3DDevice8_CreateVertexShader( pDevice
, decl
, simple_vs
, &dVertexShader
, 0 );
114 CHECK_CALL( hr
, "CreateVertexShader", pDevice
, refcount
);
115 refcount
= get_refcount( (IUnknown
*)pDevice
);
116 hr
= IDirect3DDevice8_CreatePixelShader( pDevice
, simple_ps
, &dPixelShader
);
117 CHECK_CALL( hr
, "CreatePixelShader", pDevice
, refcount
);
119 refcount
= get_refcount( (IUnknown
*)pDevice
);
120 hr
= IDirect3DDevice8_CreateTexture( pDevice
, 32, 32, 3, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pTexture
);
121 CHECK_CALL( hr
, "CreateTexture", pDevice
, refcount
+1 );
124 tmp
= get_refcount( (IUnknown
*)pTexture
);
125 /* This should not increment device refcount */
126 hr
= IDirect3DTexture8_GetSurfaceLevel( pTexture
, 1, &pTextureLevel
);
127 CHECK_CALL( hr
, "GetSurfaceLevel", pDevice
, refcount
+1 );
128 /* But should increment texture's refcount */
129 CHECK_CALL( hr
, "GetSurfaceLevel", pTexture
, tmp
+1 );
131 refcount
= get_refcount( (IUnknown
*)pDevice
);
132 hr
= IDirect3DDevice8_CreateCubeTexture( pDevice
, 32, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pCubeTexture
);
133 CHECK_CALL( hr
, "CreateCubeTexture", pDevice
, refcount
+1 );
134 refcount
= get_refcount( (IUnknown
*)pDevice
);
135 hr
= IDirect3DDevice8_CreateVolumeTexture( pDevice
, 32, 32, 2, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pVolumeTexture
);
136 CHECK_CALL( hr
, "CreateVolumeTexture", pDevice
, refcount
+1 );
138 refcount
= get_refcount( (IUnknown
*)pDevice
);
139 hr
= IDirect3DDevice8_CreateDepthStencilSurface( pDevice
, 32, 32, D3DFMT_D24S8
, D3DMULTISAMPLE_NONE
, &pStencilSurface
);
140 todo_wine
{CHECK_CALL( hr
, "CreateDepthStencilSurface", pDevice
, refcount
+1 );}
141 refcount
= get_refcount( (IUnknown
*)pDevice
);
142 hr
= IDirect3DDevice8_CreateImageSurface( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, &pImageSurface
);
143 todo_wine
{CHECK_CALL( hr
, "CreateImageSurface", pDevice
, refcount
+1 );}
144 refcount
= get_refcount( (IUnknown
*)pDevice
);
145 hr
= IDirect3DDevice8_CreateRenderTarget( pDevice
, 32, 32, D3DFMT_X8R8G8B8
, D3DMULTISAMPLE_NONE
, TRUE
, &pRenderTarget
);
146 todo_wine
{CHECK_CALL( hr
, "CreateRenderTarget", pDevice
, refcount
+1 );}
148 refcount
= get_refcount( (IUnknown
*)pDevice
);
149 hr
= IDirect3DDevice8_CreateStateBlock( pDevice
, D3DSBT_ALL
, &dStateBlock
);
150 CHECK_CALL( hr
, "CreateStateBlock", pDevice
, refcount
);
151 refcount
= get_refcount( (IUnknown
*)pDevice
);
152 hr
= IDirect3DDevice8_CreateAdditionalSwapChain( pDevice
, &d3dpp
, &pSwapChain
);
153 CHECK_CALL( hr
, "CreateAdditionalSwapChain", pDevice
, refcount
+1 );
156 if (pDevice
) IUnknown_Release( pDevice
);
159 if (pVertexBuffer
) IUnknown_Release( pVertexBuffer
);
160 if (pIndexBuffer
) IUnknown_Release( pIndexBuffer
);
162 if (dVertexShader
!= -1) IDirect3DDevice8_DeleteVertexShader( pDevice
, dVertexShader
);
163 if (dPixelShader
!= -1) IDirect3DDevice8_DeletePixelShader( pDevice
, dPixelShader
);
165 if (pTexture
) IUnknown_Release( pTexture
);
166 if (pTextureLevel
) IUnknown_Release( pTextureLevel
);
167 if (pCubeTexture
) IUnknown_Release( pCubeTexture
);
168 if (pVolumeTexture
) IUnknown_Release( pVolumeTexture
);
170 if (pStencilSurface
) IUnknown_Release( pStencilSurface
);
171 if (pImageSurface
) IUnknown_Release( pImageSurface
);
172 if (pRenderTarget
) IUnknown_Release( pRenderTarget
);
174 if (dStateBlock
!= -1) IDirect3DDevice8_DeleteStateBlock( pDevice
, dStateBlock
);
175 /* Avoid crash for now.
176 if (pSwapChain) IUnknown_Release( pSwapChain );
179 if (pD3d
) IUnknown_Release( pD3d
);
181 DestroyWindow( hwnd
);
186 HMODULE d3d8_handle
= LoadLibraryA( "d3d8.dll" );
188 pDirect3DCreate8
= (void *)GetProcAddress( d3d8_handle
, "Direct3DCreate8" );
189 if (pDirect3DCreate8
)