[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