From 749a92786d378ee55cf9ebbbe8596c217fbae0f9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 22 Apr 2013 10:38:41 -0700 Subject: [PATCH] mesa: Make core Mesa allocate the texture renderbuffer wrapper. Every driver did the same thing. Reviewed-by: Kenneth Graunke --- 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 bf440a12c83..caecd3f4b03 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 b4870099a28..adead3d1bd4 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 eb592dbf8c5..5f996c52b67 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 e7da58d43d2..867798cc291 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. @@ -369,6 +410,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; @@ -377,11 +419,7 @@ _mesa_set_texture_attachment(struct gl_context *ctx, att->Layered = layered; 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 e5d096f0937..bfab6e17da7 100644 --- a/src/mesa/main/fbobject.h +++ b/src/mesa/main/fbobject.h @@ -107,6 +107,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 c48b86d1563..26fa4c38190 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 7335bb4bac5..affe6561b15 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 92d4edcd835..f56a0d5bc10 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); } -- 2.30.2