From e4f8a2da2b601964aa4261cb1617ba41f58b5a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sat, 10 Nov 2007 00:19:19 +0100 Subject: [PATCH] wined3d: Depth stencil fixes. --- dlls/d3d9/device.c | 1 + dlls/d3d9/tests/device.c | 76 +++++++++++++++++++++++++++++++++- dlls/wined3d/device.c | 26 ++++++------ dlls/wined3d/drawprim.c | 2 +- dlls/wined3d/state.c | 1 + dlls/wined3d/stateblock.c | 2 +- dlls/wined3d/wined3d_private.h | 2 +- 7 files changed, 93 insertions(+), 17 deletions(-) diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index d48587fba00..261a3ffc8b2 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -603,6 +603,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDE } } else { WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed\n"); + *ppZStencilSurface = NULL; } LeaveCriticalSection(&d3d9_cs); return hr; diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 37b43621245..21b60436e17 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -1175,7 +1175,8 @@ static void test_depthstenciltest(void) D3DPRESENT_PARAMETERS d3dpp; D3DDISPLAYMODE d3ddm; IDirect3DSurface9 *pDepthStencil = NULL; - DWORD state; + IDirect3DSurface9 *pDepthStencil2 = NULL; + D3DZBUFFERTYPE state; pD3d = pDirect3DCreate9( D3D_SDK_VERSION ); ok(pD3d != NULL, "Failed to create IDirect3D9 object\n"); @@ -1212,6 +1213,11 @@ static void test_depthstenciltest(void) hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL); ok(hr == D3D_OK, "IDirect3DDevice9_SetDepthStencilSurface failed with %s\n", DXGetErrorString9(hr)); + /* Check if the set buffer is returned on a get. WineD3D had a bug with that once, prevent it from coming back */ + hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil2); + ok(hr == D3DERR_NOTFOUND && pDepthStencil2 == NULL, "IDirect3DDevice9_GetDepthStencilSurface failed with %s\n", DXGetErrorString9(hr)); + if(pDepthStencil2) IDirect3DSurface9_Release(pDepthStencil2); + /* This left the render states untouched! */ hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state); ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr)); @@ -1244,6 +1250,74 @@ static void test_depthstenciltest(void) hr = IDirect3DDevice9_Clear(pDevice, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0, 0); ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr)); + if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil); + if(pDevice) IDirect3D9_Release(pDevice); + + /* Now see if autodepthstencil disable is honored. First, without a format set */ + ZeroMemory( &d3dpp, sizeof(d3dpp) ); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferWidth = 800; + d3dpp.BackBufferHeight = 600; + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.EnableAutoDepthStencil = FALSE; + d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + + hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice ); + ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr)); + if(!pDevice) + { + skip("Failed to create a d3d device\n"); + goto cleanup; + } + + pDepthStencil = NULL; + hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil); + ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %s, surface = %p\n", DXGetErrorString9(hr), pDepthStencil); + if(pDepthStencil) { + IDirect3DSurface9_Release(pDepthStencil); + pDepthStencil = NULL; + } + + /* Check the depth test state */ + hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state); + ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr)); + ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW")); + + if(pDevice) IDirect3D9_Release(pDevice); + + /* Next, try EnableAutoDepthStencil FALSE with a depth stencil format set */ + ZeroMemory( &d3dpp, sizeof(d3dpp) ); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferWidth = 800; + d3dpp.BackBufferHeight = 600; + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.EnableAutoDepthStencil = FALSE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + + hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice ); + ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr)); + if(!pDevice) + { + skip("Failed to create a d3d device\n"); + goto cleanup; + } + + pDepthStencil = NULL; + hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &pDepthStencil); + ok(hr == D3DERR_NOTFOUND && pDepthStencil == NULL, "IDirect3DDevice9_GetDepthStencilSurface returned %s, surface = %p\n", DXGetErrorString9(hr), pDepthStencil); + if(pDepthStencil) { + IDirect3DSurface9_Release(pDepthStencil); + pDepthStencil = NULL; + } + + hr = IDirect3DDevice9_GetRenderState(pDevice, D3DRS_ZENABLE, &state); + ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr)); + ok(state == D3DZB_FALSE, "D3DRS_ZENABLE is %s\n", state == D3DZB_FALSE ? "D3DZB_FALSE" : (state == D3DZB_TRUE ? "D3DZB_TRUE" : "D3DZB_USEW")); + cleanup: if(pDepthStencil) IDirect3DSurface9_Release(pDepthStencil); if(pD3d) IDirect3D9_Release(pD3d); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index ef6a0eaa411..7cd60c13e4f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1578,7 +1578,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic /* Under directX swapchains share the depth stencil, so only create one depth-stencil */ if (pPresentationParameters->EnableAutoDepthStencil && hr == WINED3D_OK) { TRACE("Creating depth stencil buffer\n"); - if (This->depthStencilBuffer == NULL ) { + if (This->auto_depth_stencil_buffer == NULL ) { hr = D3DCB_CreateDepthStencil((IUnknown *) This->parent, parent, object->presentParms.BackBufferWidth, @@ -1587,10 +1587,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic object->presentParms.MultiSampleType, object->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */, - &This->depthStencilBuffer, + &This->auto_depth_stencil_buffer, NULL /* pShared (always null)*/ ); - if (This->depthStencilBuffer != NULL) - IWineD3DSurface_SetContainer(This->depthStencilBuffer, 0); + if (This->auto_depth_stencil_buffer != NULL) + IWineD3DSurface_SetContainer(This->auto_depth_stencil_buffer, 0); } /** TODO: A check on width, height and multisample types @@ -2054,7 +2054,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR This->lastThread = GetCurrentThreadId(); /* Depth Stencil support */ - This->stencilBufferTarget = This->depthStencilBuffer; + This->stencilBufferTarget = This->auto_depth_stencil_buffer; if (NULL != This->stencilBufferTarget) { IWineD3DSurface_AddRef(This->stencilBufferTarget); } @@ -2206,8 +2206,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D /* Release the buffers (with sanity checks)*/ TRACE("Releasing the depth stencil buffer at %p\n", This->stencilBufferTarget); if(This->stencilBufferTarget != NULL && (IWineD3DSurface_Release(This->stencilBufferTarget) >0)){ - if(This->depthStencilBuffer != This->stencilBufferTarget) - FIXME("(%p) Something's still holding the depthStencilBuffer\n",This); + if(This->auto_depth_stencil_buffer != This->stencilBufferTarget) + FIXME("(%p) Something's still holding the stencilBufferTarget\n",This); } This->stencilBufferTarget = NULL; @@ -2218,11 +2218,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D TRACE("Setting rendertarget to NULL\n"); This->render_targets[0] = NULL; - if (This->depthStencilBuffer) { - if(D3DCB_DestroyDepthStencilSurface(This->depthStencilBuffer) > 0) { - FIXME("(%p) Something's still holding the depthStencilBuffer\n", This); + if (This->auto_depth_stencil_buffer) { + if(D3DCB_DestroyDepthStencilSurface(This->auto_depth_stencil_buffer) > 0) { + FIXME("(%p) Something's still holding the auto depth stencil buffer\n", This); } - This->depthStencilBuffer = NULL; + This->auto_depth_stencil_buffer = NULL; } for(i=0; i < This->NumberOfSwapChains; i++) { @@ -6045,7 +6045,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice* iface, IWineD3DSurface **ppZStencilSurface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - *ppZStencilSurface = This->depthStencilBuffer; + *ppZStencilSurface = This->stencilBufferTarget; TRACE("(%p) : zStencilSurface returning %p\n", This, *ppZStencilSurface); if(*ppZStencilSurface != NULL) { @@ -6387,7 +6387,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice * HRESULT hr = WINED3D_OK; IWineD3DSurface *tmp; - TRACE("(%p) Swapping z-buffer\n",This); + TRACE("(%p) Swapping z-buffer. Old = %p, new = %p\n",This, This->stencilBufferTarget, pNewZStencil); if (pNewZStencil == This->stencilBufferTarget) { TRACE("Trying to do a NOP SetRenderTarget operation\n"); diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index c6cb9da96d4..64ed0386bd2 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -630,7 +630,7 @@ static void depth_blt(IWineD3DDevice *iface, GLuint texture) { static void depth_copy(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *)This->depthStencilBuffer; + IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer; /* Only copy the depth buffer if there is one. */ if (!depth_stencil) return; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 251e77f93bb..559a9fd9dc9 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -107,6 +107,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { /* No z test without depth stencil buffers */ if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) { + TRACE("No Z buffer - disabling depth test\n"); glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */ checkGLcall("glDisable GL_DEPTH_TEST"); return; diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 758606afaff..e0a40aff094 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1055,7 +1055,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat TRACE("Render states\n"); /* Render states: */ - if (ThisDevice->depthStencilBuffer != NULL) { + if (ThisDevice->auto_depth_stencil_buffer != NULL) { IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_TRUE); } else { IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_FALSE); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8fbf866bb8d..b09fc1bd13b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -685,7 +685,7 @@ struct IWineD3DDeviceImpl /* Render Target Support */ IWineD3DSurface **render_targets; - IWineD3DSurface *depthStencilBuffer; + IWineD3DSurface *auto_depth_stencil_buffer; IWineD3DSurface **fbo_color_attachments; IWineD3DSurface *fbo_depth_attachment;