summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-09-17 09:47:51 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-09-17 09:47:51 -0600
commitf10e7f0d288530a31a7ed3bc976a537fe640ce69 (patch)
treec6591e4c563fa98433d9bfa77bf66e6b6cb81010
parent0d20c88f626dfcfd8ad0b95f9e05feed19151e35 (diff)
gallium: fix lack of surface reference counting in cso_set/save/restore_framebuffer()
Fixes asst problems with FBO / render to texture.
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index f22ba4082..b1ccfc037 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -765,12 +765,30 @@ void cso_restore_vertex_shader(struct cso_context *ctx)
}
+/**
+ * Copy framebuffer state from src to dst with refcounting of surfaces.
+ */
+static void
+copy_framebuffer_state(struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src)
+{
+ uint i;
+
+ dst->width = src->width;
+ dst->height = src->height;
+ dst->num_cbufs = src->num_cbufs;
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
+ }
+ pipe_surface_reference(&dst->zsbuf, src->zsbuf);
+}
+
enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
const struct pipe_framebuffer_state *fb)
{
if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) {
- ctx->fb = *fb;
+ copy_framebuffer_state(&ctx->fb, fb);
ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
}
return PIPE_OK;
@@ -778,13 +796,13 @@ enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
void cso_save_framebuffer(struct cso_context *ctx)
{
- ctx->fb_saved = ctx->fb;
+ copy_framebuffer_state(&ctx->fb_saved, &ctx->fb);
}
void cso_restore_framebuffer(struct cso_context *ctx)
{
if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) {
- ctx->fb = ctx->fb_saved;
+ copy_framebuffer_state(&ctx->fb, &ctx->fb_saved);
ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb);
}
}