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 mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev