meta: Use BindRenderbufferTexImage() for meta glBlitFramebuffer().

This avoids a CopyTexImage() on Intel i965 hardware without blorp.

v2: Move the !readAtt check up higher.
v3: Rebase on idr's changes, plus readAtt check is totally gone, and also
    fix a typo in a comment.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> (v2)
This commit is contained in:
Eric Anholt
2014-02-04 15:00:46 -08:00
parent f29c25fc1d
commit 067c7b67e8
+46 -9
View File
@@ -94,8 +94,10 @@ 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.
* 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 exposes BindRenderbufferTexImage().
*/
static bool
blitframebuffer_texture(struct gl_context *ctx,
@@ -112,7 +114,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 = readAtt->Texture;
struct gl_texture_object *texObj;
GLuint srcLevel;
GLint baseLevelSave;
GLint maxLevelSave;
@@ -120,22 +122,55 @@ blitframebuffer_texture(struct gl_context *ctx,
GLuint sampler, samplerSave =
ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ?
ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0;
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) {
/* Can't handle other texture types at this time */
return mask;
}
GLuint tempTex = 0;
if (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;
if (glsl_version) {
setup_glsl_blit_framebuffer(ctx, blit, target);
@@ -242,6 +277,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;
}