[Mesa-dev] [PATCH 5/5] meta: Add a meta implementation of GL_ARB_clear_texture
Ian Romanick
idr at freedesktop.org
Mon Jun 30 16:00:04 PDT 2014
On 06/13/2014 05:59 PM, 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 {
> + 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;
Every driver in Mesa supports GL_EXT_framebuffer_object and
GL_EXT_framebuffer_blit. The only functionality added by ARB_fbo over
EXT_fbo+EXT_fb_blit that this extension uses (if I'm not mistaken) is
rendering to additional color formats (e.g., luminance). However,
drivers can still generate GL_FRAMEBUFFER_UNSUPPORTED for those cases
with ARB_fbo.
So, I don't think this check adds any value.
> +
> + /* This probably won't work with images that have a border */
> + if (texImage->Border != 0)
> + return false;
The border is stripped. Even if Border != 0, it's stored as if Border
== 0. This check can get dropped too.
> +
> + _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;
I think I'd structure the previous code as:
success = true;
for (i = 0; i < depth; i++) {
if (!...) {
success = false;
break;
}
}
I think Ilia already suggested using for-statements in another patch,
and using break in this manner is more like other Mesa code. I'm not an
anti-goto person, but I don't think it adds anything here.
> +
> + 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);
>
More information about the mesa-dev
mailing list