dst->height != src->height)
return FALSE;
- for (i = 0; i < Elements(src->cbufs); i++) {
- if (dst->cbufs[i] != src->cbufs[i]) {
- return FALSE;
- }
- }
+ if (dst->samples != src->samples ||
+ dst->layers != src->layers)
+ return FALSE;
if (dst->nr_cbufs != src->nr_cbufs) {
return FALSE;
}
+ for (i = 0; i < src->nr_cbufs; i++) {
+ if (dst->cbufs[i] != src->cbufs[i]) {
+ return FALSE;
+ }
+ }
+
if (dst->zsbuf != src->zsbuf) {
return FALSE;
}
{
unsigned i;
- dst->width = src->width;
- dst->height = src->height;
+ if (src) {
+ dst->width = src->width;
+ dst->height = src->height;
+
+ dst->samples = src->samples;
+ dst->layers = src->layers;
+
+ 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 < ARRAY_SIZE(dst->cbufs); i++)
+ pipe_surface_reference(&dst->cbufs[i], NULL);
+
+ dst->nr_cbufs = src->nr_cbufs;
- for (i = 0; i < src->nr_cbufs; i++)
- pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
+ pipe_surface_reference(&dst->zsbuf, src->zsbuf);
+ } else {
+ dst->width = 0;
+ dst->height = 0;
- for (i = src->nr_cbufs; i < dst->nr_cbufs; i++)
- pipe_surface_reference(&dst->cbufs[i], NULL);
+ dst->samples = 0;
+ dst->layers = 0;
- dst->nr_cbufs = src->nr_cbufs;
+ for (i = 0 ; i < ARRAY_SIZE(dst->cbufs); i++)
+ pipe_surface_reference(&dst->cbufs[i], NULL);
- pipe_surface_reference(&dst->zsbuf, src->zsbuf);
+ dst->nr_cbufs = 0;
+
+ pipe_surface_reference(&dst->zsbuf, NULL);
+ }
}
pipe_surface_reference(&fb->zsbuf, NULL);
+ fb->samples = fb->layers = 0;
fb->width = fb->height = 0;
fb->nr_cbufs = 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);
}
h = MIN2(h, fb->zsbuf->height);
}
- if (w == ~0) {
+ if (w == ~0u) {
*width = 0;
*height = 0;
return FALSE;
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;
+
+ /**
+ * In the case of ARB_framebuffer_no_attachment
+ * we obtain the number of layers directly from
+ * the framebuffer state.
+ */
+ if (!(fb->nr_cbufs || fb->zsbuf))
+ return fb->layers;
+
+ 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;
+
+ /**
+ * In the case of ARB_framebuffer_no_attachment
+ * we obtain the number of samples directly from
+ * the framebuffer state.
+ *
+ * NOTE: fb->samples may wind up as zero due to memset()'s on internal
+ * driver structures on their initialization and so we take the
+ * MAX here to ensure we have a valid number of samples. However,
+ * if samples is legitimately not getting set somewhere
+ * multi-sampling will evidently break.
+ */
+ if (!(fb->nr_cbufs || fb->zsbuf))
+ return MAX2(fb->samples, 1);
+
+ 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;
+}
+
+
+/**
+ * Flip the sample location state along the Y axis.
+ */
+void
+util_sample_locations_flip_y(struct pipe_screen *screen, unsigned fb_height,
+ unsigned samples, uint8_t *locations)
+{
+ unsigned row, i, shift, grid_width, grid_height;
+ uint8_t new_locations[
+ PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE *
+ PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * 32];
+
+ screen->get_sample_pixel_grid(screen, samples, &grid_width, &grid_height);
+
+ shift = fb_height % grid_height;
+
+ for (row = 0; row < grid_height; row++) {
+ unsigned row_size = grid_width * samples;
+ for (i = 0; i < row_size; i++) {
+ unsigned dest_row = grid_height - row - 1;
+ /* this relies on unsigned integer wraparound behaviour */
+ dest_row = (dest_row - shift) % grid_height;
+ new_locations[dest_row * row_size + i] = locations[row * row_size + i];
+ }
+ }
+
+ memcpy(locations, new_locations, grid_width * grid_height * samples);
+}