H. Verbeet : wined3d: Use dst_fbo to do the depth blit.

Alexandre Julliard julliard at winehq.org
Thu Jul 3 06:35:15 CDT 2008


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

Author: H. Verbeet <hverbeet at gmail.com>
Date:   Wed Jul  2 23:00:11 2008 +0200

wined3d: Use dst_fbo to do the depth blit.

This makes the depth copy independent of the currently attached render
targets. This is important for the next patch because it might do a
depth copy when the render targets aren't in a valid configuration
(SetDepthStencilSurface()).

---

 dlls/wined3d/device.c          |   16 ++++++++++++++--
 dlls/wined3d/drawprim.c        |   25 +++++++++++++++++++++++--
 dlls/wined3d/wined3d_private.h |    6 ++++++
 3 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 03c6145..1f5a206 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2279,6 +2279,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D
         glDeleteTextures(1, &This->depth_blt_texture);
         This->depth_blt_texture = 0;
     }
+    if (This->depth_blt_rb) {
+        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
+        This->depth_blt_rb = 0;
+        This->depth_blt_rb_w = 0;
+        This->depth_blt_rb_h = 0;
+    }
     This->shader_backend->shader_destroy_depth_blt(iface);
     This->shader_backend->shader_free_private(iface);
 
@@ -6038,7 +6044,7 @@ static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
     return NULL;
 }
 
-static void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
+void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
     if (!*fbo) {
@@ -6050,7 +6056,7 @@ static void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
 }
 
 /* TODO: Handle stencil attachments */
-static void attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) {
+void attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) {
     IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil;
 
     if (use_render_buffer && depth_stencil_impl->current_renderbuffer) {
@@ -7199,6 +7205,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
         glDeleteTextures(1, &This->depth_blt_texture);
         This->depth_blt_texture = 0;
     }
+    if (This->depth_blt_rb) {
+        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
+        This->depth_blt_rb = 0;
+        This->depth_blt_rb_w = 0;
+        This->depth_blt_rb_h = 0;
+    }
     This->shader_backend->shader_destroy_depth_blt(iface);
     This->shader_backend->shader_free_private(iface);
 
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 7214bf8..d3767a1 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -802,10 +802,31 @@ void depth_copy(IWineD3DDevice *iface) {
         glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
         glBindTexture(GL_TEXTURE_2D, old_binding);
 
-        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, This->fbo));
-        checkGLcall("glBindFramebuffer()");
+        /* Setup the destination */
+        if (!This->depth_blt_rb) {
+            GL_EXTCALL(glGenRenderbuffersEXT(1, &This->depth_blt_rb));
+            checkGLcall("glGenRenderbuffersEXT");
+        }
+        if (This->depth_blt_rb_w != depth_stencil->currentDesc.Width
+                || This->depth_blt_rb_h != depth_stencil->currentDesc.Height) {
+            GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, This->depth_blt_rb));
+            checkGLcall("glBindRenderbufferEXT");
+            GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, depth_stencil->currentDesc.Width, depth_stencil->currentDesc.Height));
+            checkGLcall("glRenderbufferStorageEXT");
+            This->depth_blt_rb_w = depth_stencil->currentDesc.Width;
+            This->depth_blt_rb_h = depth_stencil->currentDesc.Height;
+        }
+
+        bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->dst_fbo);
+        GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, This->depth_blt_rb));
+        checkGLcall("glFramebufferRenderbufferEXT");
+        attach_depth_stencil_fbo(This, GL_FRAMEBUFFER_EXT, (IWineD3DSurface *)depth_stencil, FALSE);
+
+        /* Do the actual blit */
         depth_blt(iface, This->depth_blt_texture);
         checkGLcall("depth_blt");
+
+        bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->fbo);
     } else {
         TRACE("Copying offscreen surface to onscreen depth buffer\n");
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 83955b9..24cf73b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -863,6 +863,9 @@ struct IWineD3DDeviceImpl
     GLuint                  dst_fbo;
     GLenum                  *draw_buffers;
     GLuint                  depth_blt_texture;
+    GLuint                  depth_blt_rb;
+    UINT                    depth_blt_rb_w;
+    UINT                    depth_blt_rb_h;
 
     /* Cursor management */
     BOOL                    bCursorVisible;
@@ -2437,4 +2440,7 @@ static inline BOOL use_ps(IWineD3DDeviceImpl *device) {
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
         IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip);
+void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo);
+void attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer);
+
 #endif




More information about the wine-cvs mailing list