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

Kenneth Graunke kenneth at whitecape.org
Wed Feb 5 18:22:21 PST 2014


On 02/05/2014 05:20 PM, Eric Anholt wrote:
> 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)

Could drop the _ARB suffix, but no big deal either way.

> +         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 {

You already early return if the driver hook fails, so there's no need to
indent this code (below) in an else block.  Looks kind of weird.

> +         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;
>  }
> 



More information about the mesa-dev mailing list