[Mesa-dev] [PATCH 3/6] mesa: Make core Mesa allocate the texture renderbuffer wrapper.

Eric Anholt eric at anholt.net
Tue Apr 30 12:56:34 PDT 2013


Every driver did the same thing.
---
 src/mesa/drivers/dri/intel/intel_fbo.c     | 17 +----------
 src/mesa/drivers/dri/nouveau/nouveau_fbo.c | 10 -------
 src/mesa/drivers/dri/radeon/radeon_fbo.c   | 14 ---------
 src/mesa/main/fbobject.c                   | 48 ++++++++++++++++++++++++++----
 src/mesa/main/fbobject.h                   |  5 ++++
 src/mesa/main/teximage.c                   |  3 +-
 src/mesa/state_tracker/st_cb_fbo.c         | 22 ++------------
 src/mesa/swrast/s_texrender.c              | 38 +++--------------------
 8 files changed, 56 insertions(+), 101 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 1d247c7..f44cb4d 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -606,28 +606,13 @@ intel_render_texture(struct gl_context * ctx,
       /* Fallback on drawing to a texture that doesn't have a miptree
        * (has a border, width/height 0, etc.)
        */
-      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
       _swrast_render_texture(ctx, fb, att);
       return;
    }
-   else if (!irb) {
-      intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
 
-      irb = (struct intel_renderbuffer *)intel_new_renderbuffer(ctx, ~0);
-
-      if (irb) {
-         /* bind the wrapper to the attachment point */
-         _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base.Base);
-      }
-      else {
-         /* fallback to software rendering */
-         _swrast_render_texture(ctx, fb, att);
-         return;
-      }
-   }
+   intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
 
    if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) {
-       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
        _swrast_render_texture(ctx, fb, att);
        return;
    }
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
index b487009..adead3d 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
@@ -270,16 +270,6 @@ nouveau_render_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
 	struct gl_texture_image *ti =
 		att->Texture->Image[att->CubeMapFace][att->TextureLevel];
 
-	/* Allocate a renderbuffer object for the texture if we
-	 * haven't already done so. */
-	if (!rb) {
-		rb = nouveau_renderbuffer_new(ctx, ~0);
-		assert(rb);
-
-		rb->AllocStorage = NULL;
-		_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
-	}
-
 	/* Update the renderbuffer fields from the texture. */
 	set_renderbuffer_format(rb, get_tex_format(ti));
 	rb->Width = ti->Width;
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index eb592db..5f996c5 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -835,25 +835,11 @@ radeon_render_texture(struct gl_context * ctx,
    if (!radeon_image->mt) {
       /* Fallback on drawing to a texture without a miptree.
        */
-      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
       _swrast_render_texture(ctx, fb, att);
       return;
    }
-   else if (!rrb) {
-      rrb = radeon_wrap_texture(ctx, newImage);
-      if (rrb) {
-         /* bind the wrapper to the attachment point */
-         _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base.Base);
-      }
-      else {
-         /* fallback to software rendering */
-         _swrast_render_texture(ctx, fb, att);
-         return;
-      }
-   }
 
    if (!radeon_update_wrapper(ctx, rrb, newImage)) {
-       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
        _swrast_render_texture(ctx, fb, att);
        return;
    }
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 645a8a3..26d1cce 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -341,6 +341,47 @@ _mesa_remove_attachment(struct gl_context *ctx,
    att->Complete = GL_TRUE;
 }
 
+/**
+ * Create a renderbuffer which will be set up by the driver to wrap the
+ * texture image slice.
+ *
+ * By using a gl_renderbuffer (like user-allocated renderbuffers), drivers get
+ * to share most of their framebuffer rendering code between winsys,
+ * renderbuffer, and texture attachments.
+ *
+ * The allocated renderbuffer uses a non-zero Name so that drivers can check
+ * it for determining vertical orientation, but we use ~0 to make it fairly
+ * unambiguous with actual user (non-texture) renderbuffers.
+ */
+void
+_mesa_update_texture_renderbuffer(struct gl_context *ctx,
+                                  struct gl_framebuffer *fb,
+                                  struct gl_renderbuffer_attachment *att)
+{
+   struct gl_texture_image *texImage;
+   struct gl_renderbuffer *rb;
+
+   texImage = _mesa_get_attachment_teximage(att);
+   if (!texImage)
+      return;
+
+   rb = att->Renderbuffer;
+   if (!rb) {
+      rb = ctx->Driver.NewRenderbuffer(ctx, ~0);
+      if (!rb) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()");
+         return;
+      }
+      _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
+
+      /* This can't get called on a texture renderbuffer, so set it to NULL
+       * for clarity compared to user renderbuffers.
+       */
+      rb->AllocStorage = NULL;
+   }
+
+   ctx->Driver.RenderTexture(ctx, fb, att);
+}
 
 /**
  * Bind a texture object to an attachment point.
@@ -368,6 +409,7 @@ _mesa_set_texture_attachment(struct gl_context *ctx,
       assert(!att->Texture);
       _mesa_reference_texobj(&att->Texture, texObj);
    }
+   invalidate_framebuffer(fb);
 
    /* always update these fields */
    att->TextureLevel = level;
@@ -375,11 +417,7 @@ _mesa_set_texture_attachment(struct gl_context *ctx,
    att->Zoffset = zoffset;
    att->Complete = GL_FALSE;
 
-   if (_mesa_get_attachment_teximage(att)) {
-      ctx->Driver.RenderTexture(ctx, fb, att);
-   }
-
-   invalidate_framebuffer(fb);
+   _mesa_update_texture_renderbuffer(ctx, fb, att);
 }
 
 
diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
index 9e934ad..721969e 100644
--- a/src/mesa/main/fbobject.h
+++ b/src/mesa/main/fbobject.h
@@ -106,6 +106,11 @@ _mesa_set_renderbuffer_attachment(struct gl_context *ctx,
                                   struct gl_renderbuffer_attachment *att,
                                   struct gl_renderbuffer *rb);
 
+void
+_mesa_update_texture_renderbuffer(struct gl_context *ctx,
+                                  struct gl_framebuffer *fb,
+                                  struct gl_renderbuffer_attachment *att);
+
 extern void
 _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
                                struct gl_framebuffer *fb,
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index c48b86d..26fa4c3 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2760,8 +2760,7 @@ check_rtt_cb(GLuint key, void *data, void *userData)
              att->TextureLevel == level &&
              att->CubeMapFace == face) {
             ASSERT(_mesa_get_attachment_teximage(att));
-            /* Tell driver about the new renderbuffer texture */
-            ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
+            _mesa_update_texture_renderbuffer(ctx, ctx->DrawBuffer, att);
             /* Mark fb status as indeterminate to force re-validation */
             fb->_Status = 0;
          }
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 7335bb4..affe656 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -390,8 +390,8 @@ st_render_texture(struct gl_context *ctx,
 {
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
-   struct st_renderbuffer *strb;
-   struct gl_renderbuffer *rb;
+   struct gl_renderbuffer *rb = att->Renderbuffer;
+   struct st_renderbuffer *strb = st_renderbuffer(rb);
    struct pipe_resource *pt;
    struct st_texture_object *stObj;
    const struct gl_texture_image *texImage;
@@ -406,24 +406,6 @@ st_render_texture(struct gl_context *ctx,
    /* get pointer to texture image we're rendeing to */
    texImage = _mesa_get_attachment_teximage(att);
 
-   /* create new renderbuffer which wraps the texture image.
-    * Use the texture's name as the renderbuffer's name so that we have
-    * something that's non-zero (to determine vertical orientation) and
-    * possibly helpful for debugging.
-    */
-   rb = st_new_renderbuffer(ctx, att->Texture->Name);
-   if (!rb) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()");
-      return;
-   }
-
-   _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
-   assert(rb->RefCount == 1);
-   rb->AllocStorage = NULL; /* should not get called */
-   strb = st_renderbuffer(rb);
-
-   assert(strb->Base.RefCount > 0);
-
    /* get the texture for the texture object */
    stObj = st_texture_object(att->Texture);
 
diff --git a/src/mesa/swrast/s_texrender.c b/src/mesa/swrast/s_texrender.c
index 92d4edc..f56a0d5 100644
--- a/src/mesa/swrast/s_texrender.c
+++ b/src/mesa/swrast/s_texrender.c
@@ -22,37 +22,6 @@ delete_texture_wrapper(struct gl_context *ctx, struct gl_renderbuffer *rb)
    free(rb);
 }
 
-
-/**
- * This function creates a renderbuffer object which wraps a texture image.
- * The new renderbuffer is plugged into the given attachment point.
- * This allows rendering into the texture as if it were a renderbuffer.
- */
-static void
-wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
-{
-   struct gl_renderbuffer *rb;
-   const GLuint name = 0;
-
-   ASSERT(att->Type == GL_TEXTURE);
-   ASSERT(att->Renderbuffer == NULL);
-
-   rb = ctx->Driver.NewRenderbuffer(ctx, name);
-   if (!rb) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");
-      return;
-   }
-
-   /* init base gl_renderbuffer fields */
-   _mesa_init_renderbuffer(rb, name);
-   /* plug in our texture_renderbuffer-specific functions */
-   rb->Delete = delete_texture_wrapper;
-   rb->AllocStorage = NULL; /* illegal! */
-
-   /* update attachment point */
-   _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
-}
-
 /**
  * Update the renderbuffer wrapper for rendering to a texture.
  * For example, update the width, height of the RB based on the texture size,
@@ -116,11 +85,12 @@ _swrast_render_texture(struct gl_context *ctx,
                        struct gl_framebuffer *fb,
                        struct gl_renderbuffer_attachment *att)
 {
+   struct gl_renderbuffer *rb = att->Renderbuffer;
    (void) fb;
 
-   if (!att->Renderbuffer) {
-      wrap_texture(ctx, att);
-   }
+   /* plug in our texture_renderbuffer-specific functions */
+   rb->Delete = delete_texture_wrapper;
+
    update_wrapper(ctx, att);
 }
 
-- 
1.8.3.rc0



More information about the mesa-dev mailing list