From f57bddc7e431e553e946563d1030e5f239911c8b Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 20 Feb 2014 14:37:23 +0800 Subject: [PATCH] ilo: add slice clear value It is needed for 3DSTATE_CLEAR_PARAMS, and can also be used to track what value the slice has been cleared to. --- .../drivers/ilo/ilo_3d_pipeline_gen6.c | 11 +++++-- .../drivers/ilo/ilo_3d_pipeline_gen7.c | 10 ++++-- src/gallium/drivers/ilo/ilo_blit.c | 31 +++++++++++++++++++ .../drivers/ilo/ilo_blitter_rectlist.c | 3 ++ src/gallium/drivers/ilo/ilo_resource.h | 30 +++++++++++++++++- 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c index 59623bc0ce4..e5ae4f1688f 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c @@ -725,10 +725,14 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p, if (DIRTY(FB) || session->batch_bo_changed) { const struct ilo_zs_surface *zs; struct ilo_zs_surface layer; + uint32_t clear_params; if (ilo->fb.state.zsbuf) { const struct ilo_surface_cso *surface = (const struct ilo_surface_cso *) ilo->fb.state.zsbuf; + const struct ilo_texture_slice *slice = + ilo_texture_get_slice(ilo_texture(surface->base.texture), + surface->base.u.tex.level, surface->base.u.tex.first_layer); if (ilo->fb.offset_to_layers) { assert(surface->base.u.tex.first_layer == @@ -745,9 +749,12 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p, assert(!surface->is_rt); zs = &surface->u.zs; } + + clear_params = slice->clear_value; } else { zs = &ilo->fb.null_zs; + clear_params = 0; } if (p->dev->gen == ILO_GEN(6)) { @@ -758,9 +765,7 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p, gen6_emit_3DSTATE_DEPTH_BUFFER(p->dev, zs, p->cp); gen6_emit_3DSTATE_HIER_DEPTH_BUFFER(p->dev, zs, p->cp); gen6_emit_3DSTATE_STENCIL_BUFFER(p->dev, zs, p->cp); - - /* TODO */ - gen6_emit_3DSTATE_CLEAR_PARAMS(p->dev, 0, p->cp); + gen6_emit_3DSTATE_CLEAR_PARAMS(p->dev, clear_params, p->cp); } } diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c index a1c85197cba..4263882c4bd 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c @@ -545,24 +545,28 @@ gen7_pipeline_wm(struct ilo_3d_pipeline *p, /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */ if (DIRTY(FB) || session->batch_bo_changed) { const struct ilo_zs_surface *zs; + uint32_t clear_params; if (ilo->fb.state.zsbuf) { const struct ilo_surface_cso *surface = (const struct ilo_surface_cso *) ilo->fb.state.zsbuf; + const struct ilo_texture_slice *slice = + ilo_texture_get_slice(ilo_texture(surface->base.texture), + surface->base.u.tex.level, surface->base.u.tex.first_layer); assert(!surface->is_rt); zs = &surface->u.zs; + clear_params = slice->clear_value; } else { zs = &ilo->fb.null_zs; + clear_params = 0; } gen6_emit_3DSTATE_DEPTH_BUFFER(p->dev, zs, p->cp); gen6_emit_3DSTATE_HIER_DEPTH_BUFFER(p->dev, zs, p->cp); gen6_emit_3DSTATE_STENCIL_BUFFER(p->dev, zs, p->cp); - - /* TODO */ - gen7_emit_3DSTATE_CLEAR_PARAMS(p->dev, 0, p->cp); + gen7_emit_3DSTATE_CLEAR_PARAMS(p->dev, clear_params, p->cp); } } diff --git a/src/gallium/drivers/ilo/ilo_blit.c b/src/gallium/drivers/ilo/ilo_blit.c index 74bb3554235..ad304c7109a 100644 --- a/src/gallium/drivers/ilo/ilo_blit.c +++ b/src/gallium/drivers/ilo/ilo_blit.c @@ -163,10 +163,26 @@ ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo, * When ILO_TEXTURE_RENDER_WRITE is set, there can be no reader. We * need to perform a HiZ Buffer Resolve in case the resource was * previously written by another writer, unless this is a clear. + * + * When slices have different clear values, we perform a Depth Buffer + * Resolve on all slices not sharing the clear value of the first slice. + * After resolving, those slices do not use 3DSTATE_CLEAR_PARAMS and can + * be made to have the same clear value as the first slice does. This + * way, + * + * - 3DSTATE_CLEAR_PARAMS can be set to the clear value of any slice + * - we will not resolve unnecessarily next time this function is + * called + * + * Since slice clear value is the value the slice is cleared to when + * ILO_TEXTURE_CLEAR is set, the bit needs to be unset. */ assert(!(resolve_flags & (other_writers | any_reader))); if (!(resolve_flags & ILO_TEXTURE_CLEAR)) { + bool set_clear_value = false; + uint32_t first_clear_value; + for (i = 0; i < num_slices; i++) { const struct ilo_texture_slice *slice = ilo_texture_get_slice(tex, level, first_slice + i); @@ -175,6 +191,21 @@ ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo, ilo_blitter_rectlist_resolve_hiz(ilo->blitter, res, level, first_slice + i); } + else if (i == 0) { + first_clear_value = slice->clear_value; + } + else if (slice->clear_value != first_clear_value && + (slice->flags & ILO_TEXTURE_RENDER_WRITE)) { + ilo_blitter_rectlist_resolve_z(ilo->blitter, + res, level, first_slice + i); + set_clear_value = true; + } + } + + if (set_clear_value) { + /* ILO_TEXTURE_CLEAR will be cleared later */ + ilo_texture_set_slice_clear_value(tex, level, + first_slice, num_slices, first_clear_value); } } } diff --git a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c index 472ab6a1755..534764f5db1 100644 --- a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c +++ b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c @@ -472,6 +472,8 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter, { struct ilo_texture *tex = ilo_texture(res); struct pipe_depth_stencil_alpha_state dsa_state; + const struct ilo_texture_slice *s = + ilo_texture_get_slice(tex, level, slice); if (!ilo_texture_can_enable_hiz(tex, level, slice, 1)) return; @@ -492,6 +494,7 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter, ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_RESOLVE_Z); ilo_blitter_set_dsa(blitter, &dsa_state); + ilo_blitter_set_clear_values(blitter, s->clear_value, 0); ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice); ilo_blitter_set_uses(blitter, ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH); diff --git a/src/gallium/drivers/ilo/ilo_resource.h b/src/gallium/drivers/ilo/ilo_resource.h index d7bc5f9be71..cba425c11dc 100644 --- a/src/gallium/drivers/ilo/ilo_resource.h +++ b/src/gallium/drivers/ilo/ilo_resource.h @@ -61,7 +61,7 @@ enum ilo_texture_flags { * Set when the texture is cleared. * * When set in resolve flags, the new writer will clear. When set in slice - * flags, the slice has been cleared. + * flags, the slice has been cleared to ilo_texture_slice::clear_value. */ ILO_TEXTURE_CLEAR = 1 << 6, @@ -91,6 +91,18 @@ struct ilo_texture_slice { /* 2D offset to the slice */ unsigned x, y; unsigned flags; + + /* + * Slice clear value. It is served for two purposes + * + * - the clear value used in commands such as 3DSTATE_CLEAR_PARAMS + * - the clear value when ILO_TEXTURE_CLEAR is set + * + * Since commands such as 3DSTATE_CLEAR_PARAMS expect a single clear value + * for all slices, ilo_blit_resolve_slices() will silently make all slices + * to have the same clear value. + */ + uint32_t clear_value; }; struct ilo_texture { @@ -189,6 +201,22 @@ ilo_texture_set_slice_flags(struct ilo_texture *tex, unsigned level, } } +static inline void +ilo_texture_set_slice_clear_value(struct ilo_texture *tex, unsigned level, + unsigned first_slice, unsigned num_slices, + uint32_t clear_value) +{ + const struct ilo_texture_slice *last = + ilo_texture_get_slice(tex, level, first_slice + num_slices - 1); + struct ilo_texture_slice *slice = + ilo_texture_get_slice(tex, level, first_slice); + + while (slice <= last) { + slice->clear_value = clear_value; + slice++; + } +} + static inline bool ilo_texture_can_enable_hiz(const struct ilo_texture *tex, unsigned level, unsigned first_slice, unsigned num_slices) -- 2.30.2