I'm trying to solve bug 5872 http://bugs.winehq.org/show_bug.cgi?id=5872 BF1942 calls GetDepthStencilSurface/IUnknown_Release and checks the refcount to be 0, but wine returns 1. (test hack attached)
I have done some testing: The first call to GetDepthStencilSurface increases the refcount of the device, any subsequent call increases the refcount of the surface. On release calls the refcount of the surface gets decreased. If the refcount is 1 the release call decreases the surface refcount AND the device refcount.
The exact same behaviour shows GetRenderTarget. d3d9 does also the same.
Any ideas how we should implement this behaviour?
Markus
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index e735502..3ad8ca0 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -20,6 +20,7 @@ #define COBJMACROS #include <d3d8.h> #include <dxerr8.h> #include "wine/test.h" +#include <stdio.h>
static IDirect3D8 *(WINAPI *pDirect3DCreate8)(UINT);
@@ -183,6 +184,8 @@ static void test_refcount(void) D3DPRESENT_PARAMETERS d3dpp; D3DDISPLAYMODE d3ddm; int refcount = 0, tmp; + IDirect3DSurface8 *pRenderTarget2 = NULL; + IDirect3DSurface8 *pStencilSurface2 = NULL;
DWORD decl[] = { @@ -217,6 +220,8 @@ static void test_refcount(void) d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = IDirect3D8_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice ); @@ -226,6 +231,41 @@ static void test_refcount(void) refcount = get_refcount( (IUnknown *)pDevice ); ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
+ printf("hr=%x refDevice=%d\n\n", hr, refcount); + + hr = IDirect3DDevice8_GetDepthStencilSurface(pDevice, &pStencilSurface2); + printf("hr=%x refSurface=%d\n", hr, get_refcount( (IUnknown *)pStencilSurface2) ); + printf("hr=%x refDevice=%d\n\n", hr, get_refcount( (IUnknown *)pDevice) ); + + hr = IDirect3DDevice8_GetDepthStencilSurface(pDevice, &pStencilSurface2); + printf("hr=%x refSurface=%d\n", hr, get_refcount( (IUnknown *)pStencilSurface2) ); + printf("hr=%x refDevice=%d\n\n", hr, get_refcount( (IUnknown *)pDevice) ); + + hr = IDirect3DDevice8_GetRenderTarget(pDevice, &pRenderTarget2); + printf("hr=%x refTarget=%d\n", hr, get_refcount( (IUnknown *)pRenderTarget2) ); + printf("hr=%x refDevice=%d\n\n", hr, get_refcount( (IUnknown *)pDevice) ); + + hr = IDirect3DDevice8_GetRenderTarget(pDevice, &pRenderTarget2); + printf("hr=%x refTarget=%d\n", hr, get_refcount( (IUnknown *)pRenderTarget2) ); + printf("hr=%x refDevice=%d\n\n", hr, get_refcount( (IUnknown *)pDevice) ); + + refcount = IUnknown_Release(pRenderTarget2); + printf("hr=%x refTarget=%d\n", hr, refcount ); + printf("hr=%x refDevice=%d\n\n", hr, get_refcount( (IUnknown *)pDevice) ); + + refcount = IUnknown_Release(pRenderTarget2); + printf("hr=%x refTarget=%d\n", hr, refcount ); + printf("hr=%x refDevice=%d\n\n", hr, get_refcount( (IUnknown *)pDevice) ); + + refcount = IUnknown_Release(pStencilSurface2); + printf("hr=%x refSurface=%d\n", hr, refcount ); + printf("hr=%x refDevice=%d\n\n", hr, get_refcount( (IUnknown *)pDevice) ); + + refcount = IUnknown_Release(pStencilSurface2); + printf("hr=%x refSurface=%d\n", hr, refcount ); + printf("hr=%x refDevice=%d\n", hr, get_refcount( (IUnknown *)pDevice) ); + return; + /* Buffers */ hr = IDirect3DDevice8_CreateIndexBuffer( pDevice, 16, 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &pIndexBuffer ); CHECK_CALL( hr, "CreateIndexBuffer", pDevice, ++refcount ); @@ -316,6 +356,6 @@ START_TEST(device) if (pDirect3DCreate8) { test_refcount(); - test_swapchain(); +// test_swapchain(); } }