From 4a1af434e6bfc80fceab2a472e7a79de59aca823 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 20 Jan 2013 18:09:58 +0100 Subject: r300g: add a workaround for the AA colorbuffer addressing bug on R500 --- src/gallium/drivers/r300/r300_state.c | 18 +++++++++------- src/gallium/drivers/r300/r300_texture_desc.c | 31 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index e5d9bebb2c9..fd02f82bc9e 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -839,14 +839,18 @@ static unsigned r300_get_num_samples(struct r300_context *r300) { struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)r300->fb_state.state; - unsigned num_samples; + unsigned i, num_samples; - if (fb->nr_cbufs) - num_samples = fb->cbufs[0]->texture->nr_samples; - else if (fb->zsbuf) - num_samples = fb->zsbuf->texture->nr_samples; - else - num_samples = 1; + if (!fb->nr_cbufs && !fb->zsbuf) + return 1; + + num_samples = 6; + + for (i = 0; i < fb->nr_cbufs; i++) + num_samples = MIN2(num_samples, fb->cbufs[i]->texture->nr_samples); + + if (fb->zsbuf) + num_samples = MIN2(num_samples, fb->zsbuf->texture->nr_samples); if (!num_samples) num_samples = 1; diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c index c5636ca3bcc..6d645288f98 100644 --- a/src/gallium/drivers/r300/r300_texture_desc.c +++ b/src/gallium/drivers/r300/r300_texture_desc.c @@ -542,6 +542,37 @@ void r300_texture_desc_init(struct r300_screen *rscreen, tex->tex.height0 = base->height0; tex->tex.depth0 = base->depth0; + /* There is a CB memory addressing hardware bug that limits the width + * of the MSAA buffer in some cases in R520. In order to get around it, + * the following code lowers the sample count depending on the format and + * the width. + * + * The only catch is that all MSAA colorbuffers and a zbuffer which are + * supposed to be used together should always be bound together. Only + * then the correct minimum sample count of all bound buffers is used + * for rendering. */ + if (rscreen->caps.is_r500) { + /* FP16 6x MSAA buffers are limited to a width of 1360 pixels. */ + if (tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT && + tex->b.b.nr_samples == 6 && tex->b.b.width0 > 1360) { + tex->b.b.nr_samples = 4; + } + + /* FP16 4x MSAA buffers are limited to a width of 2048 pixels. */ + if (tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT && + tex->b.b.nr_samples == 4 && tex->b.b.width0 > 2048) { + tex->b.b.nr_samples = 2; + } + } + + /* 32-bit 6x MSAA buffers are limited to a width of 2720 pixels. + * This applies to all R300-R500 cards. */ + if (util_format_get_blocksizebits(tex->b.b.format) == 32 && + !util_format_is_depth_or_stencil(tex->b.b.format) && + tex->b.b.nr_samples == 6 && tex->b.b.width0 > 2720) { + tex->b.b.nr_samples = 4; + } + r300_setup_flags(tex); /* Align a 3D NPOT texture to POT. */ -- cgit v1.2.3