Henri Verbeet : wined3d: Be more careful when deleting FBOs.

Alexandre Julliard julliard at winehq.org
Thu Sep 4 08:26:40 CDT 2008


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Wed Sep  3 16:25:38 2008 +0200

wined3d: Be more careful when deleting FBOs.

Clear all attachments before deleting FBOs. It should be valid to
delete FBOs that still have attachments, but for some reason the
nvidia drivers don't like it. The resulting memory corruption can be
pretty nasty, and this workaround seems clean enough.

---

 dlls/wined3d/context.c |   28 +++++++++++++++++++++++++---
 dlls/wined3d/device.c  |    1 +
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 66206bd..2f30aff 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -632,6 +632,25 @@ static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *con
     HeapFree(GetProcessHeap(), 0, oldArray);
 }
 
+static void destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
+{
+    int i = 0;
+
+    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo));
+    checkGLcall("glBindFramebuffer()");
+    for (i = 0; i < GL_LIMITS(buffers); ++i)
+    {
+        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
+        checkGLcall("glFramebufferTexture2D()");
+    }
+    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+    checkGLcall("glFramebufferTexture2D()");
+    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+    checkGLcall("glBindFramebuffer()");
+    GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
+    checkGLcall("glDeleteFramebuffers()");
+}
+
 /*****************************************************************************
  * DestroyContext
  *
@@ -655,13 +674,16 @@ void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) {
     ENTER_GL();
 
     if (context->fbo) {
-        GL_EXTCALL(glDeleteFramebuffersEXT(1, &context->fbo));
+        TRACE("Destroy FBO %d\n", context->fbo);
+        destroy_fbo(This, &context->fbo);
     }
     if (context->src_fbo) {
-        GL_EXTCALL(glDeleteFramebuffersEXT(1, &context->src_fbo));
+        TRACE("Destroy src FBO %d\n", context->src_fbo);
+        destroy_fbo(This, &context->src_fbo);
     }
     if (context->dst_fbo) {
-        GL_EXTCALL(glDeleteFramebuffersEXT(1, &context->dst_fbo));
+        TRACE("Destroy dst FBO %d\n", context->dst_fbo);
+        destroy_fbo(This, &context->dst_fbo);
     }
 
     LEAVE_GL();
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 2085b07..d12aebd 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -6128,6 +6128,7 @@ void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
     if (!*fbo) {
         GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
         checkGLcall("glGenFramebuffersEXT()");
+        TRACE("Created FBO %d\n", *fbo);
     }
     GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
     checkGLcall("glBindFramebuffer()");




More information about the wine-cvs mailing list