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) !=
>
signature.asc
Description: OpenPGP digital signature
_______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
