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