On Sat, Jun 14, 2014 at 01:59:31AM +0100, Neil Roberts wrote: > 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 {
This should go to the previous line with the closing '{'. (The rest of the patch uses this style correctly). > + 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; The scope for these two could be reduced by placing them into the if-block. > + > + _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); I wouldn't mind having a little explanation why the clear value for depth/stencil is always "float_32_uint_24_8" - I guess this is forced somewhere else. This is not obvious to me after having looked at the spec and the implementation of _mesa_store_teximage() that seems to allow all the different variants: table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8; table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24; table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16; table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24; table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8; table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32; table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32; table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8; Quote from the spec: "5. Should depth/stencil textures be supported? If so, are the depth and stencil values provided separately? RESOLVED. Depth/stencil textures are supported in the same manner they are for TexSubImage. The format and type describe how the data is interpreted." > + else > + memset(depthStencilValue, 0, sizeof depthStencilValue); Would it be a little clearer to assign the clear value directly instead of the temporary copy: ctx->Depth.Clear = (GLfloat)depthStencilValue[0]; } else { ctx->Depth.Clear = 0; depthStencilValue[1] = 0; } > + > + 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; Don't we need to save the depth and stencil clear colors as well? > + > + 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev