Henri Verbeet : wined3d: Allow depth and stencil clears on surfaces other than the current depth / stencil buffer.

Alexandre Julliard julliard at winehq.org
Wed Apr 6 11:36:35 CDT 2011


Module: wine
Branch: master
Commit: 99bfd817141ca32f9c50e539aa4d0dcbfded24b7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=99bfd817141ca32f9c50e539aa4d0dcbfded24b7

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue Apr  5 19:01:30 2011 +0200

wined3d: Allow depth and stencil clears on surfaces other than the current depth / stencil buffer.

---

 dlls/wined3d/context.c         |    8 ++++----
 dlls/wined3d/device.c          |   32 ++++++++++++++++++++++----------
 dlls/wined3d/surface.c         |   18 ++++++------------
 dlls/wined3d/wined3d_private.h |    4 ++--
 4 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 8ffb30c..5b5ae5a 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2,7 +2,7 @@
  * Context and render target management in wined3d
  *
  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
- * Copyright 2009-2010 Henri Verbeet for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1915,7 +1915,7 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur
 /* Context activation is done by the caller. */
 static void context_apply_draw_buffers(struct wined3d_context *context, UINT rt_count, IWineD3DSurfaceImpl **rts)
 {
-    if (!surface_is_offscreen(rts[0]))
+    if (rt_count && !surface_is_offscreen(rts[0]))
     {
         ENTER_GL();
         glDrawBuffer(surface_get_gl_buffer(rts[0]));
@@ -1951,7 +1951,7 @@ static void context_apply_draw_buffers(struct wined3d_context *context, UINT rt_
         }
         else
         {
-            glDrawBuffer(rts[0]->resource.device->offscreenBuffer);
+            glDrawBuffer(rt_count ? rts[0]->resource.device->offscreenBuffer : GL_NONE);
             checkGLcall("glDrawBuffer()");
         }
         LEAVE_GL();
@@ -2086,7 +2086,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceIm
 
         ENTER_GL();
 
-        if (surface_is_offscreen(rts[0]))
+        if (!rt_count || surface_is_offscreen(rts[0]))
         {
             for (i = 0; i < rt_count; ++i)
             {
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 2d50caa..5e9f04e 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -652,15 +652,15 @@ static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *co
 
 /* Do not call while under the GL lock. */
 HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts,
-        UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags,
-        const WINED3DCOLORVALUE *color, float depth, DWORD stencil)
+        IWineD3DSurfaceImpl *depth_stencil, UINT rect_count, const RECT *rects, const RECT *draw_rect,
+        DWORD flags, const WINED3DCOLORVALUE *color, float depth, DWORD stencil)
 {
     const RECT *clear_rect = (rect_count > 0 && rects) ? (const RECT *)rects : NULL;
-    IWineD3DSurfaceImpl *depth_stencil = device->depth_stencil;
-    IWineD3DSurfaceImpl *target = rts[0];
+    IWineD3DSurfaceImpl *target = rt_count ? rts[0] : NULL;
     UINT drawable_width, drawable_height;
     struct wined3d_context *context;
     GLbitfield clear_mask = 0;
+    BOOL render_offscreen;
     unsigned int i;
 
     /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
@@ -694,7 +694,17 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
         return WINED3D_OK;
     }
 
-    target->get_drawable_size(context, &drawable_width, &drawable_height);
+    if (target)
+    {
+        render_offscreen = context->render_offscreen;
+        target->get_drawable_size(context, &drawable_width, &drawable_height);
+    }
+    else
+    {
+        render_offscreen = FALSE;
+        drawable_width = depth_stencil->pow2Width;
+        drawable_height = depth_stencil->pow2Height;
+    }
 
     ENTER_GL();
 
@@ -715,7 +725,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
 
     if (flags & WINED3DCLEAR_ZBUFFER)
     {
-        DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+        DWORD location = render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
 
         if (location == SFLAG_DS_ONSCREEN && depth_stencil != device->onscreen_depth_stencil)
         {
@@ -752,7 +762,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
 
     if (!clear_rect)
     {
-        if (context->render_offscreen)
+        if (render_offscreen)
         {
             glScissor(draw_rect->left, draw_rect->top,
                     draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
@@ -789,7 +799,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
                 continue;
             }
 
-            if (context->render_offscreen)
+            if (render_offscreen)
             {
                 glScissor(current_rect.left, current_rect.top,
                         current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
@@ -808,7 +818,8 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
 
     LEAVE_GL();
 
-    if (wined3d_settings.strict_draw_ordering || (target->container.type == WINED3D_CONTAINER_SWAPCHAIN
+    if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET
+            && target->container.type == WINED3D_CONTAINER_SWAPCHAIN
             && target->container.u.swapchain->front_buffer == target))
         wglFlush(); /* Flush to ensure ordering across contexts. */
 
@@ -4816,7 +4827,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD rect
     device_get_draw_rect(device, &draw_rect);
 
     return device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
-            device->render_targets, rect_count, rects, &draw_rect, flags, &c, depth, stencil);
+            device->render_targets, device->depth_stencil, rect_count, rects,
+            &draw_rect, flags, &c, depth, stencil);
 }
 
 /*****
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index e62f1f3..58cd197 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1112,7 +1112,7 @@ void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, IWineD3DS
     unsigned int src_width, src_height;
     unsigned int width, height;
 
-    if (rt->resource.format->id != WINED3DFMT_NULL)
+    if (rt && rt->resource.format->id != WINED3DFMT_NULL)
     {
         width = rt->pow2Width;
         height = rt->pow2Height;
@@ -3897,16 +3897,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
 /* Do not call while under the GL lock. */
 static HRESULT wined3d_surface_depth_fill(IWineD3DSurfaceImpl *surface, const RECT *rect, float depth)
 {
-    IWineD3DDeviceImpl *device = surface->resource.device;
-
-    if (surface != device->depth_stencil)
-    {
-        FIXME("Depth fill is only implemented for the current depth / stencil buffer.\n");
-        return WINED3DERR_INVALIDCALL;
-    }
+    const RECT draw_rect = {0, 0, surface->resource.width, surface->resource.height};
 
-    return IWineD3DDevice_Clear((IWineD3DDevice *)device, !!rect, rect,
-            WINED3DCLEAR_ZBUFFER, 0x00000000, depth, 0);
+    return device_clear_render_targets(surface->resource.device, 0, NULL, surface,
+            !!rect, rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0);
 }
 
 /* Do not call while under the GL lock. */
@@ -4921,8 +4915,8 @@ static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceIm
 {
     const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height};
 
-    return device_clear_render_targets(device, 1 /* rt_count */, &dst_surface, 1 /* rect_count */,
-            dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f /* depth */, 0 /* stencil */);
+    return device_clear_render_targets(device, 1, &dst_surface, NULL,
+            1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0);
 }
 
 const struct blit_shader ffp_blit =  {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 15a18dd..eb015eb 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1769,8 +1769,8 @@ struct IWineD3DDeviceImpl
 };
 
 HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts,
-        UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags,
-        const WINED3DCOLORVALUE *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
+        IWineD3DSurfaceImpl *depth_stencil, UINT rect_count, const RECT *rects, const RECT *draw_rect,
+        DWORD flags, const WINED3DCOLORVALUE *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
 BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
 void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
 void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list