X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_framebuffer.c;h=c2948a5cfb30b9dd57f1c830fae0308dc6d16cfe;hb=28c95cdb299f56c8224446368fb464b7b1d44a6c;hp=768ae9ceb5d4b520934d7aff797333b80e2884c1;hpb=258f433fffa67710d6424d3703528294133ada65;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_framebuffer.c b/src/gallium/auxiliary/util/u_framebuffer.c index 768ae9ceb5d..c2948a5cfb3 100644 --- a/src/gallium/auxiliary/util/u_framebuffer.c +++ b/src/gallium/auxiliary/util/u_framebuffer.c @@ -55,16 +55,20 @@ util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst, 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; } @@ -82,16 +86,37 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst, { unsigned i; - dst->width = src->width; - dst->height = src->height; + if (src) { + dst->width = src->width; + dst->height = src->height; - for (i = 0; i < Elements(src->cbufs); i++) { - pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]); - } + 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; + + pipe_surface_reference(&dst->zsbuf, src->zsbuf); + } else { + dst->width = 0; + dst->height = 0; - dst->nr_cbufs = src->nr_cbufs; + dst->samples = 0; + dst->layers = 0; - pipe_surface_reference(&dst->zsbuf, src->zsbuf); + for (i = 0 ; i < ARRAY_SIZE(dst->cbufs); i++) + pipe_surface_reference(&dst->cbufs[i], NULL); + + dst->nr_cbufs = 0; + + pipe_surface_reference(&dst->zsbuf, NULL); + } } @@ -106,6 +131,7 @@ util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb) pipe_surface_reference(&fb->zsbuf, NULL); + fb->samples = fb->layers = 0; fb->width = fb->height = 0; fb->nr_cbufs = 0; } @@ -124,6 +150,9 @@ util_framebuffer_min_size(const struct pipe_framebuffer_state *fb, 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); } @@ -133,7 +162,7 @@ util_framebuffer_min_size(const struct pipe_framebuffer_state *fb, h = MIN2(h, fb->zsbuf->height); } - if (w == ~0) { + if (w == ~0u) { *width = 0; *height = 0; return FALSE; @@ -144,3 +173,70 @@ util_framebuffer_min_size(const struct pipe_framebuffer_state *fb, 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; +}