diff options
author | Marek Olšák <[email protected]> | 2014-01-08 13:31:59 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2014-01-13 15:48:08 +0100 |
commit | 07032d40684c3ad8e12fd6979b0b4b6582871db4 (patch) | |
tree | a1737ad29b63d9a05a580ada122e21d4d13f1d84 /src | |
parent | a86de9a72f229e1833af93f5d51023a1dec3af1e (diff) |
r600g: handle NULL colorbuffers correctly on Evergreen
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 59 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_blit.c | 23 |
2 files changed, 54 insertions, 28 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index d5c1792cfb6..77e3c95636d 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1721,11 +1721,8 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, if (rctx->framebuffer.state.nr_cbufs) { rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV; - rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB; - - if (rctx->framebuffer.state.cbufs[0]->texture->nr_samples > 1) { - rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB_META; - } + rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB | + R600_CONTEXT_FLUSH_AND_INV_CB_META; } if (rctx->framebuffer.state.zsbuf) { rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV; @@ -1741,19 +1738,16 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, /* Colorbuffers. */ rctx->framebuffer.export_16bpc = state->nr_cbufs != 0; - rctx->framebuffer.cb0_is_integer = state->nr_cbufs && + rctx->framebuffer.cb0_is_integer = state->nr_cbufs && state->cbufs[0] && util_format_is_pure_integer(state->cbufs[0]->format); rctx->framebuffer.compressed_cb_mask = 0; - - if (state->nr_cbufs) - rctx->framebuffer.nr_samples = state->cbufs[0]->texture->nr_samples; - else if (state->zsbuf) - rctx->framebuffer.nr_samples = state->zsbuf->texture->nr_samples; - else - rctx->framebuffer.nr_samples = 0; + rctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state); for (i = 0; i < state->nr_cbufs; i++) { surf = (struct r600_surface*)state->cbufs[i]; + if (!surf) + continue; + rtex = (struct r600_texture*)surf->base.texture; r600_context_add_resource_size(ctx, state->cbufs[i]->texture); @@ -1774,13 +1768,21 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, /* Update alpha-test state dependencies. * Alpha-test is done on the first colorbuffer only. */ if (state->nr_cbufs) { + bool alphatest_bypass = false; + bool export_16bpc = true; + surf = (struct r600_surface*)state->cbufs[0]; - if (rctx->alphatest_state.bypass != surf->alphatest_bypass) { - rctx->alphatest_state.bypass = surf->alphatest_bypass; + if (surf) { + alphatest_bypass = surf->alphatest_bypass; + export_16bpc = surf->export_16bpc; + } + + if (rctx->alphatest_state.bypass != alphatest_bypass) { + rctx->alphatest_state.bypass = alphatest_bypass; rctx->alphatest_state.atom.dirty = true; } - if (rctx->alphatest_state.cb0_export_16bpc != surf->export_16bpc) { - rctx->alphatest_state.cb0_export_16bpc = surf->export_16bpc; + if (rctx->alphatest_state.cb0_export_16bpc != export_16bpc) { + rctx->alphatest_state.cb0_export_16bpc = export_16bpc; rctx->alphatest_state.atom.dirty = true; } } @@ -2181,12 +2183,21 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r /* Colorbuffers. */ for (i = 0; i < nr_cbufs; i++) { struct r600_surface *cb = (struct r600_surface*)state->cbufs[i]; - struct r600_texture *tex = (struct r600_texture *)cb->base.texture; - unsigned reloc = r600_context_bo_reloc(&rctx->b, - &rctx->b.rings.gfx, - (struct r600_resource*)cb->base.texture, - RADEON_USAGE_READWRITE); - unsigned cmask_reloc = 0; + struct r600_texture *tex; + unsigned reloc, cmask_reloc; + + if (!cb) { + r600_write_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C, + S_028C70_FORMAT(V_028C70_COLOR_INVALID)); + continue; + } + + tex = (struct r600_texture *)cb->base.texture; + reloc = r600_context_bo_reloc(&rctx->b, + &rctx->b.rings.gfx, + (struct r600_resource*)cb->base.texture, + RADEON_USAGE_READWRITE); + if (tex->cmask_buffer && tex->cmask_buffer != &tex->resource) { cmask_reloc = r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, tex->cmask_buffer, RADEON_USAGE_READWRITE); @@ -2227,7 +2238,7 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r radeon_emit(cs, reloc); } /* set CB_COLOR1_INFO for possible dual-src blending */ - if (i == 1) { + if (i == 1 && state->cbufs[0]) { r600_write_context_reg(cs, R_028C70_CB_COLOR0_INFO + 1 * 0x3C, ((struct r600_surface*)state->cbufs[0])->cb_color_info); diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 7e29cc51f7b..2b861389110 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -439,9 +439,14 @@ static bool can_fast_clear_color(struct pipe_context *ctx) } for (i = 0; i < fb->nr_cbufs; i++) { - struct r600_texture *tex = (struct r600_texture *)fb->cbufs[i]->texture; + struct r600_texture *tex; + + if (!fb->cbufs[i]) + continue; + + tex = (struct r600_texture *)fb->cbufs[i]->texture; - /* 128-bit formats are unuspported */ + /* 128-bit formats are unusupported */ if (util_format_get_blocksizebits(fb->cbufs[i]->format) > 64) { return false; } @@ -484,7 +489,12 @@ static void r600_clear(struct pipe_context *ctx, unsigned buffers, int i; for (i = 0; i < fb->nr_cbufs; i++) { - struct r600_texture *tex = (struct r600_texture *)fb->cbufs[i]->texture; + struct r600_texture *tex; + + if (!fb->cbufs[i]) + continue; + + tex = (struct r600_texture *)fb->cbufs[i]->texture; evergreen_set_clear_color(fb->cbufs[i], color); r600_clear_buffer(ctx, &tex->cmask_buffer->b.b, @@ -502,7 +512,12 @@ static void r600_clear(struct pipe_context *ctx, unsigned buffers, /* cannot use fast clear, make sure to disable expansion */ for (i = 0; i < fb->nr_cbufs; i++) { - struct r600_texture *tex = (struct r600_texture *)fb->cbufs[i]->texture; + struct r600_texture *tex; + + if (!fb->cbufs[i]) + continue; + + tex = (struct r600_texture *)fb->cbufs[i]->texture; if (tex->fmask.size == 0) tex->dirty_level_mask &= ~(1 << fb->cbufs[i]->u.tex.level); } |