[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