[Mesa-dev] [PATCH 7/9] meta: Add an accelerated glCopyTexSubImage using glBlitFramebuffer.
Kenneth Graunke
kenneth at whitecape.org
Sat Apr 12 23:19:15 PDT 2014
On 04/08/2014 02:03 PM, Eric Anholt wrote:
> You'll note from the previous commits that there's something of a loop
> here: You call CTSI, which calls BlitFB, then if things go wrong that
> falls back to CTSI. As a result, meta CTSI reaches over into blitfb to
> tell it "no, don't try that fallback".
>
> v2: Drop the _mesa_update_state(), which was only necessary due to use of
> _mesa_clip_blit() in _mesa_meta_BlitFramebuffer() in another patch
> series.
> ---
> src/mesa/drivers/common/meta.c | 95 +++++++++++++++++++++++---
> src/mesa/drivers/common/meta.h | 4 +-
> src/mesa/drivers/common/meta_blit.c | 3 +
> src/mesa/drivers/common/meta_generate_mipmap.c | 4 +-
> 4 files changed, 94 insertions(+), 12 deletions(-)
>
> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
> index 9e832f2..ab79e74 100644
> --- a/src/mesa/drivers/common/meta.c
> +++ b/src/mesa/drivers/common/meta.c
> @@ -37,6 +37,7 @@
> #include "main/arbprogram.h"
> #include "main/arrayobj.h"
> #include "main/blend.h"
> +#include "main/blit.h"
> #include "main/bufferobj.h"
> #include "main/buffers.h"
> #include "main/colortab.h"
> @@ -97,7 +98,8 @@ static void meta_drawpix_cleanup(struct drawpix_state *drawpix);
> * Bind a particular texture level/layer to mipmap->FBO's GL_COLOR_ATTACHMENT0.
> */
Comment is really bogus now :) Maybe:
/**
* Bind a particular texture level/layer to an FBO attachment.
*/
Or some such? Feel free to change it however you see fit.
> void
> -_mesa_meta_bind_fbo_image(struct gl_texture_image *texImage, GLuint layer)
> +_mesa_meta_bind_fbo_image(GLenum attachment,
> + struct gl_texture_image *texImage, GLuint layer)
> {
> struct gl_texture_object *texObj = texImage->TexObject;
> int level = texImage->Level;
> @@ -106,17 +108,18 @@ _mesa_meta_bind_fbo_image(struct gl_texture_image *texImage, GLuint layer)
> switch (target) {
> case GL_TEXTURE_1D:
> _mesa_FramebufferTexture1D(GL_FRAMEBUFFER,
> - GL_COLOR_ATTACHMENT0,
> + attachment,
> target,
> texObj->Name,
> level);
> break;
> case GL_TEXTURE_1D_ARRAY:
> case GL_TEXTURE_2D_ARRAY:
> + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
> case GL_TEXTURE_CUBE_MAP_ARRAY:
> case GL_TEXTURE_3D:
> _mesa_FramebufferTextureLayer(GL_FRAMEBUFFER,
> - GL_COLOR_ATTACHMENT0,
> + attachment,
> texObj->Name,
> level,
> layer);
> @@ -126,7 +129,7 @@ _mesa_meta_bind_fbo_image(struct gl_texture_image *texImage, GLuint layer)
> target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face;
>
> _mesa_FramebufferTexture2D(GL_FRAMEBUFFER,
> - GL_COLOR_ATTACHMENT0,
> + attachment,
> target,
> texObj->Name,
> level);
> @@ -2732,6 +2735,77 @@ get_temp_image_type(struct gl_context *ctx, mesa_format format)
> }
>
> /**
> + * Attempts to wrap the destination texture in an FBO and use
> + * glBlitFramebuffer() to implement glCopyTexSubImage().
> + */
> +static bool
> +copytexsubimage_using_blit_framebuffer(struct gl_context *ctx, GLuint dims,
> + struct gl_texture_image *texImage,
> + GLint xoffset,
> + GLint yoffset,
> + GLint zoffset,
> + struct gl_renderbuffer *rb,
> + GLint x, GLint y,
> + GLsizei width, GLsizei height)
> +{
> + struct gl_texture_object *texObj = texImage->TexObject;
> + GLuint fbo;
> + bool success = false;
> + GLbitfield mask;
> + GLenum status;
> +
> + if (!ctx->Extensions.ARB_framebuffer_object)
> + return false;
> +
> + _mesa_unlock_texture(ctx, texObj);
> +
> + _mesa_meta_begin(ctx, MESA_META_ALL);
> +
> + _mesa_GenFramebuffers(1, &fbo);
> + _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
> +
> + if (rb->_BaseFormat == GL_DEPTH_STENCIL ||
> + rb->_BaseFormat == GL_DEPTH_COMPONENT) {
> + _mesa_meta_bind_fbo_image(GL_DEPTH_ATTACHMENT, texImage, zoffset);
> + mask = GL_DEPTH_BUFFER_BIT;
> +
> + if (rb->_BaseFormat == GL_DEPTH_STENCIL &&
> + texImage->_BaseFormat == GL_DEPTH_STENCIL) {
> + _mesa_meta_bind_fbo_image(GL_STENCIL_ATTACHMENT, texImage, zoffset);
> + mask |= GL_STENCIL_BUFFER_BIT;
> + }
> + _mesa_DrawBuffer(GL_NONE);
> + } else {
> + _mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, texImage, zoffset);
> + mask = GL_COLOR_BUFFER_BIT;
> + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
Don't need the _EXT here.
> + }
> +
> + status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
> + if (status != GL_FRAMEBUFFER_COMPLETE)
> + goto out;
> +
> + ctx->Meta->Blit.no_ctsi_fallback = true;
> + /* We skip the core BlitFramebuffer checks for format consistency, which
> + * are too strict for CopyTexImage. We know meta will be fine with format
> + * changes.
> + */
> + _mesa_meta_BlitFramebuffer(ctx, x, y,
> + x + width, y + height,
> + xoffset, yoffset,
> + xoffset + width, yoffset + height,
> + mask, GL_NEAREST);
> + ctx->Meta->Blit.no_ctsi_fallback = false;
> + success = true;
> +
> + out:
> + _mesa_lock_texture(ctx, texObj);
> + _mesa_DeleteFramebuffers(1, &fbo);
> + _mesa_meta_end(ctx);
> + return success;
> +}
> +
> +/**
> * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions.
> * Have to be careful with locking and meta state for pixel transfer.
> */
> @@ -2748,11 +2822,14 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
> GLint bpp;
> void *buf;
>
> - /* The gl_renderbuffer is part of the interface for
> - * dd_function_table::CopyTexSubImage, but this implementation does not use
> - * it.
> - */
> - (void) rb;
> + if (copytexsubimage_using_blit_framebuffer(ctx, dims,
> + texImage,
> + xoffset, yoffset, zoffset,
> + rb,
> + x, y,
> + width, height)) {
> + return;
> + }
>
> /* Choose format/type for temporary image buffer */
> format = _mesa_get_format_base_format(texImage->TexFormat);
> diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h
> index ad3da9c..fd8a385 100644
> --- a/src/mesa/drivers/common/meta.h
> +++ b/src/mesa/drivers/common/meta.h
> @@ -253,6 +253,7 @@ struct blit_state
> struct blit_shader_table shaders;
> GLuint msaa_shaders[BLIT_MSAA_SHADER_COUNT];
> struct temp_texture depthTex;
> + bool no_ctsi_fallback;
> };
>
>
> @@ -505,6 +506,7 @@ void
> _mesa_meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap);
>
> void
> -_mesa_meta_bind_fbo_image(struct gl_texture_image *texImage, GLuint layer);
> +_mesa_meta_bind_fbo_image(GLenum attachment,
> + struct gl_texture_image *texImage, GLuint layer);
>
> #endif /* META_H */
> diff --git a/src/mesa/drivers/common/meta_blit.c b/src/mesa/drivers/common/meta_blit.c
> index d7bb7c8..0bd76a1 100644
> --- a/src/mesa/drivers/common/meta_blit.c
> +++ b/src/mesa/drivers/common/meta_blit.c
> @@ -425,6 +425,9 @@ blitframebuffer_texture(struct gl_context *ctx,
> /* Fall back to doing a CopyTexSubImage to get the destination
> * renderbuffer into a texture.
> */
> + if (ctx->Meta->Blit.no_ctsi_fallback)
> + return false;
> +
> if (rb->NumSamples > 1)
> return false;
>
> diff --git a/src/mesa/drivers/common/meta_generate_mipmap.c b/src/mesa/drivers/common/meta_generate_mipmap.c
> index db46974..3c9ac89 100644
> --- a/src/mesa/drivers/common/meta_generate_mipmap.c
> +++ b/src/mesa/drivers/common/meta_generate_mipmap.c
> @@ -103,7 +103,7 @@ fallback_required(struct gl_context *ctx, GLenum target,
> _mesa_GenFramebuffers(1, &mipmap->FBO);
> _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO);
>
> - _mesa_meta_bind_fbo_image(baseImage, 0);
> + _mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, baseImage, 0);
>
> status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
>
> @@ -317,7 +317,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
> _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
> verts, GL_DYNAMIC_DRAW_ARB);
>
> - _mesa_meta_bind_fbo_image(dstImage, layer);
> + _mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, dstImage, layer);
>
> /* sanity check */
> if (_mesa_CheckFramebufferStatus(GL_FRAMEBUFFER) !=
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140412/ad657ebc/attachment.sig>
More information about the mesa-dev
mailing list