[Mesa-dev] [PATCH 08/11] meta: Use BindRenderbufferTexture() for meta glBlitFramebuffer().

Eric Anholt eric at anholt.net
Wed Feb 5 17:20:11 PST 2014


This avoids a CopyTexImage() on Intel i965 hardware without blorp.
---
 src/mesa/drivers/common/meta_blit.c | 59 ++++++++++++++++++++++++++++++-------
 1 file changed, 49 insertions(+), 10 deletions(-)

diff --git a/src/mesa/drivers/common/meta_blit.c b/src/mesa/drivers/common/meta_blit.c
index 3c6998f..973ee1b 100644
--- a/src/mesa/drivers/common/meta_blit.c
+++ b/src/mesa/drivers/common/meta_blit.c
@@ -264,9 +264,11 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
 }
 
 /**
- * Try to do a glBlitFramebuffer using no-copy texturing.
- * We can do this when the src renderbuffer is actually a texture.
- * But if the src buffer == dst buffer we cannot do this.
+ * Try to do a color-only glBlitFramebuffer using texturing.
+ *
+ * We can do this when the src renderbuffer is actually a texture, or when the
+ * driver expposes BindRenderbufferTexImage().  But if the src buffer == dst
+ * buffer we cannot do this.
  */
 static bool
 blitframebuffer_texture(struct gl_context *ctx,
@@ -285,7 +287,7 @@ blitframebuffer_texture(struct gl_context *ctx,
    const GLint dstY = MIN2(dstY0, dstY1);
    const GLint dstW = abs(dstX1 - dstX0);
    const GLint dstH = abs(dstY1 - dstY0);
-   const struct gl_texture_object *texObj;
+   struct gl_texture_object *texObj;
    GLuint srcLevel;
    GLint baseLevelSave;
    GLint maxLevelSave;
@@ -294,17 +296,55 @@ blitframebuffer_texture(struct gl_context *ctx,
       ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ?
       ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0;
    int i;
+   GLuint tempTex = 0;
 
    if (readAtt && readAtt->Texture) {
+      /* If there's a texture attached of a type we can handle, then just use
+       * it directly.
+       */
       srcLevel = readAtt->TextureLevel;
       texObj = readAtt->Texture;
+      target = texObj->Target;
+
+      if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB)
+         return false;
+   } else if (ctx->Driver.BindRenderbufferTexImage) {
+      /* Otherwise, we need the driver to be able to bind a renderbuffer as
+       * a texture image.
+       */
+      struct gl_texture_image *texImage;
+      struct gl_renderbuffer *rb = readAtt->Renderbuffer;
+
+      target = GL_TEXTURE_2D;
+      _mesa_GenTextures(1, &tempTex);
+      _mesa_BindTexture(target, tempTex);
+      srcLevel = 0;
+      texObj = _mesa_lookup_texture(ctx, tempTex);
+      texImage = _mesa_get_tex_image(ctx, texObj, target, srcLevel);
+
+      if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, texImage)) {
+         _mesa_DeleteTextures(1, &tempTex);
+         return false;
+      } else {
+         if (ctx->Driver.FinishRenderTexture &&
+             !rb->NeedsFinishRenderTexture) {
+            rb->NeedsFinishRenderTexture = true;
+            ctx->Driver.FinishRenderTexture(ctx, rb);
+         }
+
+         if (_mesa_is_winsys_fbo(readFb)) {
+            GLint temp = srcY0;
+            srcY0 = rb->Height - srcY1;
+            srcY1 = rb->Height - temp;
+            flipY = -flipY;
+         }
+      }
    } else {
       return false;
    }
 
    baseLevelSave = texObj->BaseLevel;
    maxLevelSave = texObj->MaxLevel;
-   target = texObj->Target;
 
    /* Iterate through all draw buffers */
    for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
@@ -318,15 +358,12 @@ blitframebuffer_texture(struct gl_context *ctx,
           * to handle overlapping blits and besides, some hw may not
           * support this.
           */
+         if (tempTex)
+            _mesa_DeleteTextures(1, &tempTex);
          return false;
       }
    }
 
-   if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) {
-      /* Can't handle other texture types at this time */
-      return false;
-   }
-
    /* Choose between glsl version and fixed function version of
     * BlitFramebuffer function.
     */
@@ -440,6 +477,8 @@ blitframebuffer_texture(struct gl_context *ctx,
 
    _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave);
    _mesa_DeleteSamplers(1, &sampler);
+   if (tempTex)
+      _mesa_DeleteTextures(1, &tempTex);
 
    return true;
 }
-- 
1.9.rc1



More information about the mesa-dev mailing list