mesa: avoid calling _mesa_test_framebuffer_completeness() more than needed
authorBrian Paul <brianp@vmware.com>
Wed, 21 Jan 2009 23:28:38 +0000 (16:28 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 22 Jan 2009 22:21:17 +0000 (15:21 -0700)
When we change a FBO's attachments, set _Status=0.
Before using an FBO, check if status != GL_FRAMEBUFFER_COMPLETE.
Also, fix missing GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE status.

src/mesa/main/fbobject.c
src/mesa/main/framebuffer.c

index 85e15a6e94b9fae751dfedceafefbe002a1799c8..c16ac0f0093d31998de895a7ad88fcdc4d855be5 100644 (file)
@@ -125,6 +125,18 @@ _mesa_lookup_framebuffer(GLcontext *ctx, GLuint id)
 }
 
 
+/**
+ * Mark the given framebuffer as invalid.  This will force the
+ * test for framebuffer completeness to be done before the framebuffer
+ * is used.
+ */
+static void
+invalidate_framebuffer(struct gl_framebuffer *fb)
+{
+   fb->_Status = 0; /* "indeterminate" */
+}
+
+
 /**
  * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
  * gl_renderbuffer_attachment object.
@@ -234,6 +246,8 @@ _mesa_set_texture_attachment(GLcontext *ctx,
    if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
       ctx->Driver.RenderTexture(ctx, fb, att);
    }
+
+   invalidate_framebuffer(fb);
 }
 
 
@@ -282,6 +296,8 @@ _mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
       _mesa_remove_attachment(ctx, att);
    }
 
+   invalidate_framebuffer(fb);
+
    _glthread_UNLOCK_MUTEX(fb->Mutex);
 }
 
@@ -520,13 +536,17 @@ _mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb)
          continue;
       }
 
+      if (numSamples < 0) {
+         /* first buffer */
+         numSamples = att->Renderbuffer->NumSamples;
+      }
+
       /* Error-check width, height, format, samples
        */
       if (numImages == 1) {
          /* save format, num samples */
          if (i >= 0) {
             intFormat = f;
-            numSamples = att->Renderbuffer->NumSamples;
          }
       }
       else {
@@ -546,6 +566,7 @@ _mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb)
          }
          if (att->Renderbuffer &&
              att->Renderbuffer->NumSamples != numSamples) {
+            fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
             fbo_incomplete("inconsistant number of samples", i);
             return;
          }            
@@ -700,6 +721,7 @@ detach_renderbuffer(GLcontext *ctx,
          _mesa_remove_attachment(ctx, &fb->Attachment[i]);
       }
    }
+   invalidate_framebuffer(fb);
 }
 
 
@@ -1322,7 +1344,10 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
 
    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
 
-   _mesa_test_framebuffer_completeness(ctx, buffer);
+   if (buffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
+      _mesa_test_framebuffer_completeness(ctx, buffer);
+   }
+
    return buffer->_Status;
 }
 
@@ -1445,6 +1470,9 @@ framebuffer_texture(GLcontext *ctx, const char *caller, GLenum target,
    else {
       _mesa_remove_attachment(ctx, att);
    }
+
+   invalidate_framebuffer(fb);
+
    _glthread_UNLOCK_MUTEX(fb->Mutex);
 }
 
index 079f457503f46f8197f376bf6dd746a5ee2f3b85..2d7e3b050385c1c2dbf8388ebcc6e032581ed28b 100644 (file)
@@ -793,8 +793,10 @@ update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
       /* This is a user-created framebuffer.
        * Completeness only matters for user-created framebuffers.
        */
-      _mesa_test_framebuffer_completeness(ctx, fb);
-      _mesa_update_framebuffer_visual(fb);
+      if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) {
+         _mesa_test_framebuffer_completeness(ctx, fb);
+         _mesa_update_framebuffer_visual(fb);
+      }
    }
 
    /* Strictly speaking, we don't need to update the draw-state