summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c17
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_fbo.c10
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c14
-rw-r--r--src/mesa/main/fbobject.c48
-rw-r--r--src/mesa/main/fbobject.h5
-rw-r--r--src/mesa/main/teximage.c3
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c22
-rw-r--r--src/mesa/swrast/s_texrender.c38
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);
}