Adds an implementation of the ClearTexSubImage driver entry point that tries to set up an FBO to render to the texture and then calls glClear with a scissor to perform the actual clear. If an FBO can't be created for the texture then it will fall back to using _mesa_store_ClearTexSubImage. --- src/mesa/drivers/common/driverfuncs.c | 2 +- src/mesa/drivers/common/meta.c | 162 ++++++++++++++++++++++++++++++++++ src/mesa/drivers/common/meta.h | 7 ++ 3 files changed, 170 insertions(+), 1 deletion(-)
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 34b6fef..1ac2aee 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -95,7 +95,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->TexImage = _mesa_store_teximage; driver->TexSubImage = _mesa_store_texsubimage; driver->GetTexImage = _mesa_meta_GetTexImage; - driver->ClearTexSubImage = _mesa_store_cleartexsubimage; + driver->ClearTexSubImage = _mesa_meta_ClearTexSubImage; driver->CopyTexSubImage = _mesa_meta_CopyTexSubImage; driver->GenerateMipmap = _mesa_meta_GenerateMipmap; driver->TestProxyTexImage = _mesa_test_proxy_teximage; diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index cab0dd8..7308ce6 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -40,6 +40,7 @@ #include "main/blit.h" #include "main/bufferobj.h" #include "main/buffers.h" +#include "main/clear.h" #include "main/colortab.h" #include "main/condrender.h" #include "main/depth.h" @@ -47,6 +48,7 @@ #include "main/fbobject.h" #include "main/feedback.h" #include "main/formats.h" +#include "main/format_unpack.h" #include "main/glformats.h" #include "main/image.h" #include "main/macros.h" @@ -71,6 +73,7 @@ #include "main/teximage.h" #include "main/texparam.h" #include "main/texstate.h" +#include "main/texstore.h" #include "main/transformfeedback.h" #include "main/uniforms.h" #include "main/varray.h" @@ -3360,3 +3363,162 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, _mesa_meta_end(ctx); } + +static void +set_color_clear_value(struct gl_context *ctx, + mesa_format format, + const GLvoid *clearValue) +{ + if (clearValue == 0) { + memset(&ctx->Color.ClearColor, 0, sizeof ctx->Color.ClearColor); + } + else { + switch (_mesa_get_format_datatype(format)) { + case GL_UNSIGNED_INT: + case GL_INT: + _mesa_unpack_uint_rgba_row(format, 1, clearValue, + (GLuint (*)[4]) ctx->Color.ClearColor.ui); + break; + default: + _mesa_unpack_rgba_row(format, 1, clearValue, + (GLfloat (*)[4]) ctx->Color.ClearColor.f); + break; + } + } +} + +static bool +cleartexsubimage_using_fbo_for_zoffset(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, + GLint zoffset, + GLsizei width, GLsizei height, + const GLvoid *clearValue) +{ + GLuint fbo; + bool success = false; + GLbitfield mask; + GLenum status; + GLuint depthStencilValue[2]; + GLfloat depthValue; + + _mesa_GenFramebuffers(1, &fbo); + _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + + if (texImage->_BaseFormat == GL_DEPTH_STENCIL || + texImage->_BaseFormat == GL_DEPTH_COMPONENT) { + _mesa_meta_bind_fbo_image(GL_DEPTH_ATTACHMENT, texImage, zoffset); + mask = GL_DEPTH_BUFFER_BIT; + + if (clearValue) + _mesa_unpack_float_32_uint_24_8_depth_stencil_row(texImage->TexFormat, + 1, /* n */ + clearValue, + depthStencilValue); + else + memset(depthStencilValue, 0, sizeof depthStencilValue); + + memcpy(&depthValue, depthStencilValue, sizeof depthValue); + ctx->Depth.Clear = depthValue; + + if (texImage->_BaseFormat == GL_DEPTH_STENCIL) { + _mesa_meta_bind_fbo_image(GL_STENCIL_ATTACHMENT, texImage, zoffset); + mask |= GL_STENCIL_BUFFER_BIT; + ctx->Stencil.Clear = depthStencilValue[1] & 0xff; + } + _mesa_DrawBuffer(GL_NONE); + } else { + _mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, texImage, zoffset); + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0); + mask = GL_COLOR_BUFFER_BIT; + + set_color_clear_value(ctx, texImage->TexFormat, clearValue); + } + + status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + goto out; + + _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_TRUE); + _mesa_Scissor(xoffset, yoffset, width, height); + _mesa_Clear(mask); + + success = true; + + out: + _mesa_DeleteFramebuffers(1, &fbo); + return success; +} + +static bool +cleartexsubimage_using_fbo(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue) +{ + union gl_color_union saveColorValue; + bool success = false; + + if (!ctx->Extensions.ARB_framebuffer_object) + return false; + + /* This probably won't work with images that have a border */ + if (texImage->Border != 0) + return false; + + _mesa_meta_begin(ctx, + MESA_META_SCISSOR | + MESA_META_COLOR_MASK | + MESA_META_DEPTH_TEST | + MESA_META_STENCIL_TEST); + + /* _mesa_meta_begin doesn't seem to save this */ + saveColorValue = ctx->Color.ClearColor; + + while (depth-- > 0) { + if (!cleartexsubimage_using_fbo_for_zoffset(ctx, texImage, + xoffset, yoffset, zoffset++, + width, height, + clearValue)) + goto out; + } + + success = true; + + out: + ctx->Color.ClearColor = saveColorValue; + _mesa_meta_end(ctx); + return success; +} + +extern void +_mesa_meta_ClearTexSubImage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue) +{ + bool res; + + _mesa_unlock_texture(ctx, texImage->TexObject); + + res = cleartexsubimage_using_fbo(ctx, texImage, + xoffset, yoffset, zoffset, + width, height, depth, + clearValue); + + _mesa_lock_texture(ctx, texImage->TexObject); + + if (res) + return; + + _mesa_warning(ctx, + "Falling back to mapping the texture in " + "glClearTexSubImage\n"); + + _mesa_store_cleartexsubimage(ctx, texImage, + xoffset, yoffset, zoffset, + width, height, depth, + clearValue); +} diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h index 765f8df..863ab3f 100644 --- a/src/mesa/drivers/common/meta.h +++ b/src/mesa/drivers/common/meta.h @@ -473,6 +473,13 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, GLsizei width, GLsizei height); extern void +_mesa_meta_ClearTexSubImage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + const GLvoid *clearValue); + +extern void _mesa_meta_GetTexImage(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels, struct gl_texture_image *texImage); -- 1.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev