[Mesa-dev] [PATCH 1/4] mesa: Make gl_renderbuffers backed by EGL images use FinishRenderTexture.

Eric Anholt eric at anholt.net
Fri May 10 23:37:27 PDT 2013


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.
---
 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 2e36b0b..6b30262 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 ad1b351..9c292d6 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 5f996c5..e546a6b 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 80485f7..f00d11a 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 3fb8618..cd29614 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2569,6 +2569,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
-- 
1.8.3.rc0



More information about the mesa-dev mailing list