diff options
author | Marek Olšák <[email protected]> | 2010-08-08 18:43:42 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2010-08-08 22:53:31 +0200 |
commit | 4f5e51068bce4e32a9561b4b4d6f3feca33642bf (patch) | |
tree | c4cebb02d8437bfe405e458dfbd83c78a323dbad /src/gallium | |
parent | 363b74f132a5a329fac25322f3c5c227c55b94a8 (diff) |
r300g: flush zmasks of zbuffers we are going to use as samplers
It sometimes works, sometimes not. I guess we have the zmask offsets wrong.
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/r300/r300_blit.c | 19 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 36 |
4 files changed, 58 insertions, 7 deletions
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 6f8d9abfc81..18d00d61f48 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -259,27 +259,32 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe, r300_blitter_end(r300); } -/* Clear a region of a depth stencil surface. */ -static void r300_flush_depth_stencil(struct pipe_context *pipe, - struct pipe_resource *dst, - struct pipe_subresource subdst) +/* Flush a depth stencil buffer. */ +void r300_flush_depth_stencil(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned zslice) { struct r300_context *r300 = r300_context(pipe); struct pipe_surface *dstsurf; struct r300_texture *tex = r300_texture(dst); - /* only flush the zmask if we have one attached to this texture */ if (!tex->zmask_mem[subdst.level]) return; + if (!tex->dirty_zmask[subdst.level]) + return; dstsurf = pipe->screen->get_tex_surface(pipe->screen, dst, - subdst.face, subdst.level, 0, + subdst.face, subdst.level, zslice, PIPE_BIND_DEPTH_STENCIL); r300->z_decomp_rd = TRUE; r300_blitter_begin(r300, R300_CLEAR_SURFACE); util_blitter_flush_depth_stencil(r300->blitter, dstsurf); r300_blitter_end(r300); r300->z_decomp_rd = FALSE; + + tex->dirty_zmask[subdst.level] = FALSE; + pipe->flush(pipe, 0, NULL); } /* Copy a block of pixels from one surface to another using HW. */ @@ -342,7 +347,7 @@ static void r300_resource_copy_region(struct pipe_context *pipe, is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; if (is_depth) { - r300_flush_depth_stencil(pipe, src, subsrc); + r300_flush_depth_stencil(pipe, src, subsrc, srcz); } if (old_format != new_format) { dst->format = new_format; diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index d86a5c8fc98..8b772f38874 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -397,6 +397,7 @@ struct r300_texture { /* hyper-z memory allocs */ struct mem_block *hiz_mem[R300_MAX_TEXTURE_LEVELS]; struct mem_block *zmask_mem[R300_MAX_TEXTURE_LEVELS]; + boolean dirty_zmask[R300_MAX_TEXTURE_LEVELS]; /* This is the level tiling flags were last time set for. * It's used to prevent redundant tiling-flags changes from happening.*/ @@ -628,6 +629,12 @@ void r300_init_render_functions(struct r300_context *r300); void r300_init_state_functions(struct r300_context* r300); void r300_init_resource_functions(struct r300_context* r300); +/* r300_blit.c */ +void r300_flush_depth_stencil(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned zslice); + /* r300_query.c */ void r300_resume_query(struct r300_context *r300, struct r300_query *query); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 0c40e2db93e..c35774c1490 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1069,6 +1069,9 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state offset <<= offset_shift; r300_emit_zmask_line_clear(r300, offset, stride, 0x0);//0xffffffff); } + + /* Mark the current zbuffer's zmask as dirty. */ + tex->dirty_zmask[fb->zsbuf->level] = TRUE; } void r300_emit_ztop_state(struct r300_context* r300, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index a85b46f5c7d..693b1e29f22 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -677,8 +677,44 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) } } +/* We can't use compressed zbuffers as samplers. */ +static void r300_flush_depth_textures(struct r300_context *r300) +{ + struct r300_textures_state *state = + (struct r300_textures_state*)r300->textures_state.state; + unsigned i, level; + unsigned count = MIN2(state->sampler_view_count, + state->sampler_state_count); + + if (r300->z_decomp_rd) + return; + + for (i = 0; i < count; i++) + if (state->sampler_views[i] && state->sampler_states[i]) { + struct pipe_resource *tex = state->sampler_views[i]->base.texture; + + if (tex->target == PIPE_TEXTURE_3D || + tex->target == PIPE_TEXTURE_CUBE) + continue; + + /* Ignore non-depth textures. + * Also ignore reinterpreted depth textures, e.g. resource_copy. */ + if (!util_format_is_depth_or_stencil(tex->format)) + continue; + + for (level = 0; level <= tex->last_level; level++) + if (r300_texture(tex)->dirty_zmask[level]) { + /* We don't handle 3D textures and cubemaps yet. */ + r300_flush_depth_stencil(&r300->context, tex, + u_subresource(0, level), 0); + } + } +} + void r300_update_derived_state(struct r300_context* r300) { + r300_flush_depth_textures(r300); + if (r300->textures_state.dirty) { r300_merge_textures_and_samplers(r300); } |