wined3d: Be more careful when deleting FBOs

Henri Verbeet hverbeet at codeweavers.com
Tue Sep 2 08:11:00 CDT 2008


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 e199ad1..1b6fdca 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -6079,6 +6079,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()");
-- 
1.5.6.4


--------------080701020107040707070209--



More information about the wine-patches mailing list