util/u_format: add _is_alpha()
[mesa.git] / src / gallium / auxiliary / util / u_framebuffer.c
index bdac12dbca24794555a6a07951844b98c109f408..2e0ef749e820603fc5635707076ddc4b9afe9760 100644 (file)
@@ -85,9 +85,12 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
    dst->width = src->width;
    dst->height = src->height;
 
-   for (i = 0; i < Elements(src->cbufs); i++) {
+   for (i = 0; i < src->nr_cbufs; i++)
       pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
-   }
+
+   /* Set remaining dest cbuf pointers to NULL */
+   for ( ; i < Elements(dst->cbufs); i++)
+      pipe_surface_reference(&dst->cbufs[i], NULL);
 
    dst->nr_cbufs = src->nr_cbufs;
 
@@ -109,3 +112,86 @@ util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb)
    fb->width = fb->height = 0;
    fb->nr_cbufs = 0;
 }
+
+
+/* Where multiple sizes are allowed for framebuffer surfaces, find the
+ * minimum width and height of all bound surfaces.
+ */
+boolean
+util_framebuffer_min_size(const struct pipe_framebuffer_state *fb,
+                          unsigned *width,
+                          unsigned *height)
+{
+   unsigned w = ~0;
+   unsigned h = ~0;
+   unsigned i;
+
+   for (i = 0; i < fb->nr_cbufs; i++) {
+      if (!fb->cbufs[i])
+         continue;
+
+      w = MIN2(w, fb->cbufs[i]->width);
+      h = MIN2(h, fb->cbufs[i]->height);
+   }
+
+   if (fb->zsbuf) {
+      w = MIN2(w, fb->zsbuf->width);
+      h = MIN2(h, fb->zsbuf->height);
+   }
+
+   if (w == ~0) {
+      *width = 0;
+      *height = 0;
+      return FALSE;
+   }
+   else {
+      *width = w;
+      *height = h;
+      return TRUE;
+   }
+}
+
+
+/**
+ * Return the number of layers set in the framebuffer state.
+ */
+unsigned
+util_framebuffer_get_num_layers(const struct pipe_framebuffer_state *fb)
+{
+       unsigned i, num_layers = 0;
+
+       for (i = 0; i < fb->nr_cbufs; i++) {
+               if (fb->cbufs[i]) {
+                       unsigned num = fb->cbufs[i]->u.tex.last_layer -
+                                      fb->cbufs[i]->u.tex.first_layer + 1;
+                       num_layers = MAX2(num_layers, num);
+               }
+       }
+       if (fb->zsbuf) {
+               unsigned num = fb->zsbuf->u.tex.last_layer -
+                              fb->zsbuf->u.tex.first_layer + 1;
+               num_layers = MAX2(num_layers, num);
+       }
+       return num_layers;
+}
+
+
+/**
+ * Return the number of MSAA samples.
+ */
+unsigned
+util_framebuffer_get_num_samples(const struct pipe_framebuffer_state *fb)
+{
+   unsigned i;
+
+   for (i = 0; i < fb->nr_cbufs; i++) {
+      if (fb->cbufs[i]) {
+         return MAX2(1, fb->cbufs[i]->texture->nr_samples);
+      }
+   }
+   if (fb->zsbuf) {
+      return MAX2(1, fb->zsbuf->texture->nr_samples);
+   }
+
+   return 1;
+}