util: reference surfaces and sampler views in blitter when saving them
authorMarek Olšák <maraeo@gmail.com>
Mon, 28 Jun 2010 23:52:09 +0000 (01:52 +0200)
committerMarek Olšák <maraeo@gmail.com>
Mon, 28 Jun 2010 23:54:26 +0000 (01:54 +0200)
Ooops. This should possibly fix some bugs...

src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_blitter.h
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_state.c

index 98d5a25a3f889b70f14e190e4e9746edbeb3f94b..85c5f36391c3674bd035fdebc3979487a6b39415 100644 (file)
@@ -302,6 +302,7 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
     */
    if (ctx->blitter.saved_fb_state.nr_cbufs != ~0) {
       pipe->set_framebuffer_state(pipe, &ctx->blitter.saved_fb_state);
+      util_assign_framebuffer_state(&ctx->blitter.saved_fb_state, NULL);
       ctx->blitter.saved_fb_state.nr_cbufs = ~0;
    }
 
@@ -316,6 +317,11 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
       pipe->set_fragment_sampler_views(pipe,
                                        ctx->blitter.saved_num_sampler_views,
                                        ctx->blitter.saved_sampler_views);
+
+      for (i = 0; i < ctx->blitter.saved_num_sampler_views; i++)
+         pipe_sampler_view_reference(&ctx->blitter.saved_sampler_views[i],
+                                     NULL);
+
       ctx->blitter.saved_num_sampler_views = ~0;
    }
 
index 22849280ab9be272b6ddf135932fa57317182df4..f421ad5b9380f450e89a8a4565050972dbf399b2 100644 (file)
@@ -208,11 +208,45 @@ void util_blitter_save_vertex_shader(struct blitter_context *blitter,
    blitter->saved_vs = vs;
 }
 
+/* XXX This should probably be moved elsewhere. */
+static INLINE
+void util_assign_framebuffer_state(struct pipe_framebuffer_state *dst,
+                                   const struct pipe_framebuffer_state *src)
+{
+   unsigned i;
+
+   if (src) {
+      /* Reference all surfaces. */
+      for (i = 0; i < src->nr_cbufs; i++) {
+         pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
+      }
+      for (; i < dst->nr_cbufs; i++) {
+         pipe_surface_reference(&dst->cbufs[i], NULL);
+      }
+
+      pipe_surface_reference(&dst->zsbuf, src->zsbuf);
+
+      dst->nr_cbufs = src->nr_cbufs;
+      dst->width = src->width;
+      dst->height = src->height;
+   } else {
+      /* Set all surfaces to NULL. */
+      for (i = 0; i < dst->nr_cbufs; i++) {
+         pipe_surface_reference(&dst->cbufs[i], NULL);
+      }
+
+      pipe_surface_reference(&dst->zsbuf, NULL);
+
+      dst->nr_cbufs = 0;
+   }
+}
+
 static INLINE
 void util_blitter_save_framebuffer(struct blitter_context *blitter,
-                                   struct pipe_framebuffer_state *state)
+                                   const struct pipe_framebuffer_state *state)
 {
-   blitter->saved_fb_state = *state;
+   blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */
+   util_assign_framebuffer_state(&blitter->saved_fb_state, state);
 }
 
 static INLINE
@@ -247,12 +281,13 @@ util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,
                                          int num_views,
                                          struct pipe_sampler_view **views)
 {
+   unsigned i;
    assert(num_views <= Elements(blitter->saved_sampler_views));
 
    blitter->saved_num_sampler_views = num_views;
-   memcpy(blitter->saved_sampler_views,
-          views,
-          num_views * sizeof(struct pipe_sampler_view *));
+   for (i = 0; i < num_views; i++)
+      pipe_sampler_view_reference(&blitter->saved_sampler_views[i],
+                                  views[i]);
 }
 
 static INLINE void
index df2874d5bf2fd399256b0c6bca254c107fac0117..59129bc24d9f268b6a5567f6c4e226a8ed45ecde 100644 (file)
@@ -46,10 +46,7 @@ static void r300_release_referenced_objects(struct r300_context *r300)
     unsigned i;
 
     /* Framebuffer state. */
-    for (i = 0; i < fb->nr_cbufs; i++) {
-        pipe_surface_reference(&fb->cbufs[i], NULL);
-    }
-    pipe_surface_reference(&fb->zsbuf, NULL);
+    util_assign_framebuffer_state(fb, NULL);
 
     /* Textures. */
     for (i = 0; i < textures->sampler_view_count; i++)
index 15de533778f380bb4458ed7f6eb7b47ed9d87781..93cc0dbe985269931e4492abbb88173d3f907877 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "draw/draw_context.h"
 
+#include "util/u_blitter.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "util/u_pack_color.h"
@@ -659,24 +660,6 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
             tex->last_level, util_format_short_name(tex->format));
 }
 
-static void copy_framebuffer_state(struct pipe_framebuffer_state *dst,
-                                   const struct pipe_framebuffer_state *src)
-{
-    unsigned i;
-
-    for (i = 0; i < src->nr_cbufs; i++) {
-        pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
-    }
-    for (; i < dst->nr_cbufs; i++) {
-        pipe_surface_reference(&dst->cbufs[i], NULL);
-    }
-    pipe_surface_reference(&dst->zsbuf, src->zsbuf);
-
-    dst->nr_cbufs = src->nr_cbufs;
-    dst->width = src->width;
-    dst->height = src->height;
-}
-
 static void
     r300_set_framebuffer_state(struct pipe_context* pipe,
                                const struct pipe_framebuffer_state* state)
@@ -723,7 +706,7 @@ static void
     /* The tiling flags are dependent on the surface miplevel, unfortunately. */
     r300_fb_set_tiling_flags(r300, r300->fb_state.state, state);
 
-    copy_framebuffer_state(r300->fb_state.state, state);
+    util_assign_framebuffer_state(r300->fb_state.state, state);
 
     r300->fb_state.size =
             2 +