I think it's a bit nicer to do this during validation, but if anyone disagrees 
I won't object to dropping this patch.
Fabian
From cac5460d04e7028ed621e0fe822a7820915dfd3d Mon Sep 17 00:00:00 2001
From: Fabian Bieler <der.f...@gmx.net>
Date: Sat, 2 Apr 2011 13:12:32 +0200
Subject: [PATCH 3/3] st/mesa: Move fbo texture attachment finalization to validation.

Delay surface creation if necessary.
---
 src/mesa/state_tracker/st_cb_fbo.c     |   68 +++++++++++++++++++-------------
 src/mesa/state_tracker/st_cb_texture.c |    4 +-
 2 files changed, 43 insertions(+), 29 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 31348a6..4deb45c 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -344,23 +344,15 @@ st_render_texture(struct gl_context *ctx,
    struct pipe_context *pipe = st->pipe;
    struct st_renderbuffer *strb;
    struct gl_renderbuffer *rb;
-   struct pipe_resource *pt;
+   struct pipe_resource *pt = st_get_texobj_resource(att->Texture);
    struct st_texture_object *stObj;
    const struct gl_texture_image *texImage;
+   const struct st_texture_image *stImage;
    struct pipe_surface surf_tmpl;
 
-   /* Make sure the gallium texture exists and that the texture image is in it.
-    */
-   if (!st_finalize_fbo_tex(ctx, att->Texture,
-                            att->CubeMapFace, att->TextureLevel)) {
-      st_invalidate_state(ctx, _NEW_BUFFERS);
-      return;
-   }
-
-   pt = st_get_texobj_resource(att->Texture);
-
    /* get pointer to texture image we're rendeing to */
    texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+   stImage = st_texture_image(texImage);
 
    /* create new renderbuffer which wraps the texture image */
    rb = st_new_renderbuffer(ctx, 0);
@@ -402,20 +394,24 @@ st_render_texture(struct gl_context *ctx,
    assert(strb->rtt_level <= strb->texture->last_level);
 
    /* new surface for rendering into the texture */
-   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
-   surf_tmpl.format = ctx->Color.sRGBEnabled ? strb->texture->format : util_format_linear(strb->texture->format);
-   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
-   surf_tmpl.u.tex.level = strb->rtt_level;
-   surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
-   surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
-   strb->surface = pipe->create_surface(pipe,
-                                        strb->texture,
-                                        &surf_tmpl);
+   /* Delay creation until renderbuffer validation if texture image is not in
+    * texture object.
+    */
+   if (pt && pt == stImage->pt) {
+      memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+      surf_tmpl.format = ctx->Color.sRGBEnabled ? strb->texture->format :
+                         util_format_linear(strb->texture->format);
+      surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+      surf_tmpl.u.tex.level = strb->rtt_level;
+      surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
+      surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
+      strb->surface = pipe->create_surface(pipe, strb->texture, &surf_tmpl);
+   }
 
-   strb->format = pt->format;
+   strb->format = st_mesa_format_to_pipe_format(texImage->TexFormat);
 
-   strb->Base.Format = st_pipe_format_to_mesa_format(pt->format);
-   strb->Base.DataType = st_format_datatype(pt->format);
+   strb->Base.Format = texImage->TexFormat;
+   strb->Base.DataType = st_format_datatype(strb->format);
 
    /*
    printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p  %d x %d\n",
@@ -463,8 +459,11 @@ st_validate_attachment(struct gl_context *ctx,
 		       const struct gl_renderbuffer_attachment *att,
 		       unsigned bindings)
 {
+   struct st_context *st = st_context(ctx);
+   struct pipe_context *pipe = st->pipe;
    const struct st_texture_object *stObj = st_texture_object(att->Texture);
-   const struct st_texture_image *stImage;
+   struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
+   struct pipe_surface surf_tmpl;
    enum pipe_format format;
    gl_format texFormat;
 
@@ -478,11 +477,26 @@ st_validate_attachment(struct gl_context *ctx,
    if (!stObj)
       return GL_FALSE;
 
-   stImage =
-      st_texture_image(stObj->base.Image[att->CubeMapFace][att->TextureLevel]);
-   if (!stObj->pt || stObj->pt != stImage->pt)
+   if (!st_finalize_fbo_tex(ctx, att->Texture,
+                            att->CubeMapFace, att->TextureLevel))
       return GL_FALSE;
 
+   if (strb->texture != stObj->pt) {
+      pipe_resource_reference(&strb->texture, stObj->pt);
+
+      assert(!strb->surface);
+
+      memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+      surf_tmpl.format = ctx->Color.sRGBEnabled ? strb->texture->format :
+                         util_format_linear(strb->texture->format);
+      surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+      surf_tmpl.u.tex.level = strb->rtt_level;
+      surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
+      surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
+      strb->surface = pipe->create_surface(pipe, strb->texture, &surf_tmpl);
+   }
+   assert(strb->surface);
+
    format = stObj->pt->format;
    texFormat =
       stObj->base.Image[att->CubeMapFace][att->TextureLevel]->TexFormat;
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 4a0c087..a2bcfd8 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -1845,7 +1845,7 @@ st_finalize_texture(struct gl_context *ctx,
 
 
 /**
- * Called when attaching a texture to a fbo.  When this function is finished,
+ * Called during renderbuffer validation.  When this function is finished,
  * the via face and level specified image of the texture object should be ready
  * to be rendered to.
  * \return GL_TRUE for success, GL_FALSE for failure.
@@ -1882,7 +1882,7 @@ st_finalize_fbo_tex(struct gl_context *ctx,
    }
 
    if (!guess_and_alloc_texture(st, stObj, stImage)) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "validating renderbuffer");
       return GL_FALSE;
    }
 
-- 
1.7.4.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to