[DDRAW] Set/unset the depth-stencil surface in wined3d, enable the Z test, implement depth-filling through blit.

Elie Morisse lachienne at wanadoo.fr
Sun Aug 27 10:24:17 CDT 2006


The first patch incorporates the Stefan Dösinger earlier patch ( I had my own but his one is more correct ).
I've also attached a lighter second patch without Stefan's changes.
-------------- next part --------------
>From 6141134b175b3956d34874bbf16e810139c6f80f Mon Sep 17 00:00:00 2001
From: Elie Morisse <lachienne at wanadoo.fr>
Date: Sat, 26 Aug 2006 17:54:55 +0400
Subject: [PATCH] ddraw: Set/unset the depth-stencil surface in wined3d, enable z test, implement depth-filling through blit.

---
 dlls/ddraw/ddraw.c     |    4 ++--
 dlls/ddraw/direct3d.c  |   15 +++++++++++++++
 dlls/ddraw/surface.c   |   17 +++++++++++++++++
 dlls/wined3d/surface.c |   38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 44fe5a0..60823c7 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1801,7 +1801,7 @@ IDirectDrawImpl_CreateNewSurface(IDirect
                                  DDSCAPS_VISIBLE     |
                                  DDSCAPS_LOCALVIDMEM;
     }
-    if(This->depthstencil)
+    if(This->depthstencil || (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
     {
         /* The depth stencil creation callback sets this flag.
          * Set the WineD3D usage to let it know that it's a depth
@@ -2696,7 +2696,7 @@ D3D7CB_CreateDepthStencilSurface(IUnknow
     ddsd.dwSize = sizeof(ddsd);
     ddsd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
     ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
-    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+    ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
     ddsd.dwHeight = Height;
     ddsd.dwWidth = Width;
     if(Format != 0)
diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c
index ab59340..3eadefd 100644
--- a/dlls/ddraw/direct3d.c
+++ b/dlls/ddraw/direct3d.c
@@ -737,6 +737,8 @@ IDirect3DImpl_7_CreateDevice(IDirect3D7 
     IParentImpl *IndexBufferParent;
     HRESULT hr;
     IDirectDrawSurfaceImpl *target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Surface);
+    IDirectDrawSurface7 *depthbuffer = NULL;
+    static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
     TRACE("(%p)->(%s,%p,%p)\n", iface, debugstr_guid(refiid), Surface, Device);
 
     *Device = NULL;
@@ -872,6 +874,19 @@ IDirect3DImpl_7_CreateDevice(IDirect3D7 
 
     This->d3ddevice = object;
 
+    /* Look for a depth buffer and enable the Z test if one is found */
+    hr = IDirectDrawSurface7_GetAttachedSurface(Surface,
+                                                &depthcaps,
+                                                &depthbuffer);
+    if(depthbuffer)
+    {
+        TRACE("(%p) Depth buffer found, enabling Z test\n", object);
+        IWineD3DDevice_SetRenderState(This->wineD3DDevice,
+                                      WINED3DRS_ZENABLE,
+                                      TRUE);
+        IDirectDrawSurface7_Release(depthbuffer);
+    }
+
     return D3D_OK;
 }
 
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 74fdd35..2c50241 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -316,6 +316,7 @@ IDirectDrawSurfaceImpl_Release(IDirectDr
 
                 /* Unset any index buffer, just to be sure */
                 IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL, 0);
+                IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, NULL);
 
                 if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice) != D3D_OK)
                 {
@@ -789,6 +790,14 @@ IDirectDrawSurfaceImpl_AddAttachedSurfac
     Surf->first_attached = This->first_attached;
     This->next_attached = Surf;
 
+    /* Check if we attach a back buffer to the primary */
+    if(Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER &&
+       This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+    {
+        IWineD3DDevice_SetDepthStencilSurface(This->ddraw->wineD3DDevice,
+                                              Surf->WineD3DSurface);
+    }
+
     /* MSDN: 
      * "This method increments the reference count of the surface being attached."
      */
@@ -848,6 +857,14 @@ IDirectDrawSurfaceImpl_DeleteAttachedSur
     Surf->next_attached = NULL;
     Surf->first_attached = Surf;
 
+    /* Check if we attach a back buffer to the primary */
+    if(Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER &&
+       This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+    {
+        IWineD3DDevice_SetDepthStencilSurface(This->ddraw->wineD3DDevice,
+                                              NULL);
+    }
+
     IDirectDrawSurface7_Release(Attach);
     return DD_OK;
 }
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 0e0e6dd..f11ee79 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2832,12 +2832,50 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
     return WINED3DERR_INVALIDCALL;
 }
 
+static HRESULT WINAPI IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx)
+{
+    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
+
+    /* We only support the BLT with DEPTH_FILL for now */
+    if (Flags & DDBLT_DEPTHFILL) {
+        D3DRECT rect;
+
+        if (DestRect) {
+            rect.x1 = DestRect->left;
+            rect.y1 = DestRect->top;
+            rect.x2 = DestRect->right;
+            rect.y2 = DestRect->bottom;
+        }
+        IWineD3DDevice_Clear( (IWineD3DDevice *) myDevice,
+                              (DestRect == NULL ? 0 : 1),
+                              &rect,
+                              D3DCLEAR_ZBUFFER,
+                              0x00000000,
+                              ((double) DDBltFx->u5.dwFillDepth) / 4294967295.0,
+                              0x00000000);
+
+        return WINED3D_OK;
+    }
+
+    if (SrcSurface) {
+        FIXME("(%p): Other depthstencil blts not supported yet\n", This);
+        return WINED3D_OK;
+    }
+
+    return WINED3DERR_INVALIDCALL;
+}
+
 static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
     TRACE("(%p)->(%p,%p,%p,%lx,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx);
     TRACE("(%p): Usage is %s\n", This, debug_d3dusage(This->resource.usage));
 
+    /* Even more special but rare cases for Depth/Stencil buffers */
+    if(iface == This->resource.wineD3DDevice->stencilBufferTarget) {
+        return IWineD3DSurfaceImpl_BltZ(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx);
+    }
+
     /* Special cases for RenderTargets */
     if( (This->resource.usage & WINED3DUSAGE_RENDERTARGET) ||
         ( Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET) )) {
-- 
1.4.2

-------------- next part --------------
>From 6bc1c6e606b7e4cc11d112edbacf4f4781ec2812 Mon Sep 17 00:00:00 2001
From: Elie Morisse <lachienne at wanadoo.fr>
Date: Sun, 27 Aug 2006 19:10:43 +0400
Subject: [PATCH] ddraw: Set/unset the depth-stencil surface in wined3d, enable z test, implement depth-filling through blit.

---
 dlls/ddraw/ddraw.c     |    4 ++--
 dlls/wined3d/surface.c |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 44fe5a0..60823c7 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1801,7 +1801,7 @@ IDirectDrawImpl_CreateNewSurface(IDirect
                                  DDSCAPS_VISIBLE     |
                                  DDSCAPS_LOCALVIDMEM;
     }
-    if(This->depthstencil)
+    if(This->depthstencil || (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
     {
         /* The depth stencil creation callback sets this flag.
          * Set the WineD3D usage to let it know that it's a depth
@@ -2696,7 +2696,7 @@ D3D7CB_CreateDepthStencilSurface(IUnknow
     ddsd.dwSize = sizeof(ddsd);
     ddsd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
     ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
-    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+    ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
     ddsd.dwHeight = Height;
     ddsd.dwWidth = Width;
     if(Format != 0)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 0e0e6dd..988f124 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2832,12 +2832,50 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
     return WINED3DERR_INVALIDCALL;
 }
 
+static HRESULT WINAPI IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx)
+{
+    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
+
+    /* We only support the BLT with DEPTH_FILL for now */
+    if (Flags & DDBLT_DEPTHFILL) {
+        D3DRECT rect;
+
+        if (DestRect) {
+            rect.x1 = DestRect->left;
+            rect.y1 = DestRect->top;
+            rect.x2 = DestRect->right;
+            rect.y2 = DestRect->bottom;
+        }
+        IWineD3DDevice_Clear( (IWineD3DDevice *) myDevice,
+                              (DestRect == NULL ? 0 : 1),
+                              &rect,
+                              D3DCLEAR_ZBUFFER,
+                              0x00000000,
+                              ((double) DDBltFx->u5.dwFillDepth) / 4294967295.0,
+                              0x00000000);
+
+        return WINED3D_OK;
+    }
+
+    if (SrcSurface) {
+        FIXME("(%p): Other depthstencil blts not supported yet\n", This);
+        return WINED3D_OK;
+    }
+
+    return WINED3DERR_INVALIDCALL;
+}
+
 static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
     TRACE("(%p)->(%p,%p,%p,%lx,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx);
     TRACE("(%p): Usage is %s\n", This, debug_d3dusage(This->resource.usage));
 
+    /* Special but rare cases for Depth/Stencil buffers */
+    if(iface == This->resource.wineD3DDevice->stencilBufferTarget) {
+        return IWineD3DSurfaceImpl_BltZ(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx);
+    }
+
     /* Special cases for RenderTargets */
     if( (This->resource.usage & WINED3DUSAGE_RENDERTARGET) ||
         ( Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET) )) {
-- 
1.4.2



More information about the wine-patches mailing list