From c810e67c55a8a2965b730317873fbdcc186a7514 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 10 May 2013 12:36:43 -0700 Subject: [PATCH] mesa: Make gl_renderbuffers backed by EGL images use FinishRenderTexture. This is the opportunity that radeon and intel drivers rely on for flushing render targets that may get reused as textures. Before EGL, that only happened for GL_TEXTURE attachments. Fixes piglits: KHR_gl_renderbuffer_image/renderbuffer-texture OES_EGL_image/renderbuffer-texture NOTE: This is a candidate for the 9.1 branch. Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/intel/intel_fbo.c | 10 ++++------ src/mesa/drivers/dri/intel/intel_screen.c | 1 + src/mesa/drivers/dri/radeon/radeon_fbo.c | 10 ++++++---- src/mesa/main/fbobject.c | 24 ++++++++++++++--------- src/mesa/main/mtypes.h | 9 +++++++++ 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 2e36b0b8d5a..6b30262892a 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -306,6 +306,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx, rb->Format = image->format; rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx, image->internal_format); + rb->NeedsFinishRenderTexture = true; } /** @@ -621,13 +622,10 @@ intel_finish_render_texture(struct gl_context * ctx, struct gl_renderbuffer_attachment *att) { struct intel_context *intel = intel_context(ctx); - struct gl_texture_object *tex_obj = att->Texture; - struct gl_texture_image *image = - tex_obj->Image[att->CubeMapFace][att->TextureLevel]; - struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); + struct gl_renderbuffer *rb = att->Renderbuffer; + struct intel_renderbuffer *irb = intel_renderbuffer(rb); - DBG("Finish render %s texture tex=%u\n", - _mesa_get_format_name(image->TexFormat), att->Texture->Name); + DBG("Finish render %s texture\n", _mesa_get_format_name(rb->Format)); if (irb) irb->tex_image = NULL; diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index ad1b351b711..9c292d6029d 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -409,6 +409,7 @@ intel_create_image_from_renderbuffer(__DRIcontext *context, image->dri_format = intel_dri_format(image->format); image->has_depthstencil = irb->mt->stencil_mt? true : false; + rb->NeedsFinishRenderTexture = true; return image; } diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index 5f996c52b67..e546a6b365c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -597,6 +597,7 @@ radeon_image_target_renderbuffer_storage(struct gl_context *ctx, rb->Format = image->format; rb->_BaseFormat = _mesa_base_fbo_format(&radeon->glCtx, image->internal_format); + rb->NeedsFinishRenderTexture = GL_TRUE; } /** @@ -883,10 +884,11 @@ radeon_finish_render_texture(struct gl_context * ctx, struct gl_renderbuffer_attachment *att) { struct gl_texture_object *tex_obj = att->Texture; - struct gl_texture_image *image = - tex_obj->Image[att->CubeMapFace][att->TextureLevel]; - radeon_texture_image *radeon_image = (radeon_texture_image *)image; - + radeon_texture_image *radeon_image = NULL; + + if (tex_obj) + radeon_image = (radeon_texture_image *)_mesa_get_attachment_teximage(att); + if (radeon_image) radeon_image->used_as_render_target = GL_FALSE; diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 80485f7da98..f00d11ab9f1 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -323,12 +323,14 @@ void _mesa_remove_attachment(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) { + struct gl_renderbuffer *rb = att->Renderbuffer; + + /* tell driver that we're done rendering to this texture. */ + if (rb && rb->NeedsFinishRenderTexture) + ctx->Driver.FinishRenderTexture(ctx, att); + if (att->Type == GL_TEXTURE) { ASSERT(att->Texture); - if (ctx->Driver.FinishRenderTexture) { - /* tell driver that we're done rendering to this texture. */ - ctx->Driver.FinishRenderTexture(ctx, att); - } _mesa_reference_texobj(&att->Texture, NULL); /* unbind */ ASSERT(!att->Texture); } @@ -378,6 +380,8 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx, * for clarity compared to user renderbuffers. */ rb->AllocStorage = NULL; + + rb->NeedsFinishRenderTexture = ctx->Driver.FinishRenderTexture != NULL; } rb->_BaseFormat = texImage->_BaseFormat; @@ -402,16 +406,17 @@ _mesa_set_texture_attachment(struct gl_context *ctx, GLenum texTarget, GLuint level, GLuint zoffset, GLboolean layered) { + struct gl_renderbuffer *rb = att->Renderbuffer; + + if (rb && rb->NeedsFinishRenderTexture) + ctx->Driver.FinishRenderTexture(ctx, att); + if (att->Texture == texObj) { /* re-attaching same texture */ ASSERT(att->Type == GL_TEXTURE); - if (ctx->Driver.FinishRenderTexture) - ctx->Driver.FinishRenderTexture(ctx, att); } else { /* new attachment */ - if (ctx->Driver.FinishRenderTexture && att->Texture) - ctx->Driver.FinishRenderTexture(ctx, att); _mesa_remove_attachment(ctx, att); att->Type = GL_TEXTURE; assert(!att->Texture); @@ -1879,7 +1884,8 @@ check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) GLuint i; for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = fb->Attachment + i; - if (att->Texture && att->Renderbuffer) { + struct gl_renderbuffer *rb = att->Renderbuffer; + if (rb && rb->NeedsFinishRenderTexture) { ctx->Driver.FinishRenderTexture(ctx, att); } } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b68853bebe1..5dfe911d060 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2572,6 +2572,15 @@ struct gl_renderbuffer GLuint Depth; GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ GLboolean AttachedAnytime; /**< TRUE if it was attached to a framebuffer */ + /** + * True for renderbuffers that wrap textures, giving the driver a chance to + * flush render caches through the FinishRenderTexture hook. + * + * Drivers may also set this on renderbuffers other than those generated by + * glFramebufferTexture(), though it means FinishRenderTexture() would be + * called without a rb->TexImage. + */ + GLboolean NeedsFinishRenderTexture; GLubyte NumSamples; GLenum InternalFormat; /**< The user-specified format */ GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or -- 2.30.2