summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2014-02-20 14:37:23 +0800
committerChia-I Wu <[email protected]>2014-02-22 22:45:13 +0800
commitf57bddc7e431e553e946563d1030e5f239911c8b (patch)
treec36cda8e0fd1222366b3d2c545b0d856a62e0916
parent4afb8a7fb5a5f0581ba1bbf608033e69dab6dbb3 (diff)
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.
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c11
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c10
-rw-r--r--src/gallium/drivers/ilo/ilo_blit.c31
-rw-r--r--src/gallium/drivers/ilo/ilo_blitter_rectlist.c3
-rw-r--r--src/gallium/drivers/ilo/ilo_resource.h30
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)