Merge commit 'origin/gallium-master-merge'
[mesa.git] / src / mesa / main / fbobject.c
index 1a191cd288cf2a7699a168049ab95180818d88f3..c3cdc110379c5a882a03b7d34f1c45fcc31ff454 100644 (file)
@@ -193,7 +193,7 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
    if (att->Type == GL_TEXTURE) {
       ASSERT(att->Texture);
       if (ctx->Driver.FinishRenderTexture) {
-         /* tell driver we're done rendering to this texobj */
+         /* tell driver that we're done rendering to this texture. */
          ctx->Driver.FinishRenderTexture(ctx, att);
       }
       _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
@@ -1268,7 +1268,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
                /* But the object will not be freed until it's no longer
                 * bound in any context.
                 */
-               _mesa_unreference_framebuffer(&fb);
+               _mesa_reference_framebuffer(&fb, NULL);
            }
         }
       }
@@ -1367,16 +1367,31 @@ framebuffer_texture(GLcontext *ctx, const char *caller, GLenum target,
    struct gl_renderbuffer_attachment *att;
    struct gl_texture_object *texObj = NULL;
    struct gl_framebuffer *fb;
+   GLboolean error = GL_FALSE;
 
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (target != GL_FRAMEBUFFER_EXT) {
+   switch (target) {
+   case GL_READ_FRAMEBUFFER_EXT:
+      error = !ctx->Extensions.EXT_framebuffer_blit;
+      fb = ctx->ReadBuffer;
+      break;
+   case GL_DRAW_FRAMEBUFFER_EXT:
+      error = !ctx->Extensions.EXT_framebuffer_blit;
+      /* fall-through */
+   case GL_FRAMEBUFFER_EXT:
+      fb = ctx->DrawBuffer;
+      break;
+   default:
+      error = GL_TRUE;
+   }
+
+   if (error) {
       _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glFramebufferTexture%sEXT(target)", caller);
+                  "glFramebufferTexture%sEXT(target=0x%x)", caller, target);
       return;
    }
 
-   fb = ctx->DrawBuffer;
    ASSERT(fb);
 
    /* check framebuffer binding */
@@ -1469,6 +1484,15 @@ framebuffer_texture(GLcontext *ctx, const char *caller, GLenum target,
    if (texObj) {
       _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
                                    level, zoffset);
+      /* Set the render-to-texture flag.  We'll check this flag in
+       * glTexImage() and friends to determine if we need to revalidate
+       * any FBOs that might be rendering into this texture.
+       * This flag never gets cleared since it's non-trivial to determine
+       * when all FBOs might be done rendering to this texture.  That's OK
+       * though since it's uncommon to render to a texture then repeatedly
+       * call glTexImage() to change images in the texture.
+       */
+      texObj->_RenderToTexture = GL_TRUE;
    }
    else {
       _mesa_remove_attachment(ctx, att);
@@ -1509,7 +1533,7 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
        (textarget != GL_TEXTURE_RECTANGLE_ARB) &&
        (!IS_CUBE_FACE(textarget))) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glFramebufferTexture2DEXT(textarget)");
+                  "glFramebufferTexture2DEXT(textarget=0x%x)", textarget);
       return;
    }