mesa: Make gl_renderbuffers backed by EGL images use FinishRenderTexture. 37/6637/1
authorEric Anholt <eric@anholt.net>
Fri, 10 May 2013 19:36:43 +0000 (12:36 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 17 May 2013 20:04:04 +0000 (13:04 -0700)
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 <kenneth@whitecape.org>
src/mesa/drivers/dri/intel/intel_fbo.c
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/radeon/radeon_fbo.c
src/mesa/main/fbobject.c
src/mesa/main/mtypes.h

index 2e36b0b..6b30262 100644 (file)
@@ -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;
index ad1b351..9c292d6 100644 (file)
@@ -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;
 }
 
index 5f996c5..e546a6b 100644 (file)
@@ -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;
 
index 80485f7..f00d11a 100644 (file)
@@ -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);
          }
       }
index b68853b..5dfe911 100644 (file)
@@ -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