[Mesa-dev] [v2 04/39] i965/gen6: Calculate stencil offset on demand
Topi Pohjolainen
topi.pohjolainen at gmail.com
Wed May 3 09:22:17 UTC 2017
This is kept on purpose in i965. It can be moved to ISL if it
is needed in vulkan.
Pointers to miptrees are given solely for verification purposes.
These will be dropped in following patches.
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
src/mesa/drivers/dri/i965/brw_tex_layout.c | 65 +++++++++++++++++++++++++++
src/mesa/drivers/dri/i965/gen6_depth_state.c | 14 +++---
src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 5 +++
3 files changed, 78 insertions(+), 6 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index bfa8afa..3fbb78f 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -163,6 +163,71 @@ gen9_miptree_layout_1d(struct intel_mipmap_tree *mt)
}
}
+static unsigned
+all_slices_at_each_lod_x_offset(unsigned w0, unsigned align, unsigned level)
+{
+ const unsigned w = level >= 2 ? minify(w0, 1) : 0;
+ return ALIGN(w, align);
+}
+
+static unsigned
+all_slices_at_each_lod_y_offset(const struct isl_extent4d *phys_level0_sa,
+ enum isl_surf_dim dim, unsigned align,
+ unsigned level)
+{
+ unsigned y = 0;
+
+ /* Add vertical space taken by lower levels one by one. Levels one and two
+ * are side-by-side just below level zero. Levels three and greater are
+ * stacked one after another below level two.
+ */
+ for (unsigned i = 1; i <= level; ++i) {
+ const unsigned d = dim == ISL_SURF_DIM_3D ?
+ minify(phys_level0_sa->depth, i - 1) :
+ phys_level0_sa->array_len;
+
+ /* Levels two and greater are stacked just below level zero. */
+ if (i != 2) {
+ const unsigned h = minify(phys_level0_sa->height, i - 1);
+ y += d * ALIGN(h, align);
+ }
+ }
+
+ return y;
+}
+
+uint32_t
+brw_stencil_all_slices_at_each_lod_offset(const struct isl_surf *surf,
+ const struct intel_mipmap_tree *mt,
+ unsigned level)
+{
+ assert(mt->array_layout == ALL_SLICES_AT_EACH_LOD);
+
+ const unsigned halign = 64;
+ const unsigned valign = 64;
+ const unsigned level_x = all_slices_at_each_lod_x_offset(
+ surf->phys_level0_sa.width, halign, level);
+ const unsigned level_y = all_slices_at_each_lod_y_offset(
+ &surf->phys_level0_sa, surf->dim, valign, level);
+
+ assert(level_x == mt->level[level].level_x);
+ assert(level_y == mt->level[level].level_y);
+
+ /* From Vol 2a, 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
+ * The pitch must be set to 2x the value computed based on width, as
+ * the stencil buffer is stored with two rows interleaved.
+ *
+ * While ISL surface stores the pitch expected by hardware, the offset
+ * into individual slices needs to be calculated as if rows are
+ * interleaved.
+ */
+ const unsigned two_rows_interleaved_pitch = surf->row_pitch / 2;
+
+ assert(two_rows_interleaved_pitch == mt->pitch);
+
+ return level_y * two_rows_interleaved_pitch + level_x * 64;
+}
+
static void
brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
{
diff --git a/src/mesa/drivers/dri/i965/gen6_depth_state.c b/src/mesa/drivers/dri/i965/gen6_depth_state.c
index cda66e8..a055c10 100644
--- a/src/mesa/drivers/dri/i965/gen6_depth_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_depth_state.c
@@ -192,12 +192,14 @@ gen6_emit_depth_stencil_hiz(struct brw_context *brw,
if (stencil_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
assert(stencil_mt->format == MESA_FORMAT_S_UINT8);
- /* Note: we can't compute the stencil offset using
- * intel_region_get_aligned_offset(), because stencil_region
- * claims that the region is untiled even though it's W tiled.
- */
- offset = stencil_mt->level[lod].level_y * stencil_mt->pitch +
- stencil_mt->level[lod].level_x * 64;
+ struct isl_surf temp_surf;
+ intel_miptree_get_isl_surf(brw, stencil_mt, &temp_surf);
+
+ offset = brw_stencil_all_slices_at_each_lod_offset(
+ &temp_surf, stencil_mt, lod);
+ assert(offset ==
+ stencil_mt->level[lod].level_y * stencil_mt->pitch +
+ stencil_mt->level[lod].level_x * 64);
}
BEGIN_BATCH(3);
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index 4bc30a2..8f938ee 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -973,6 +973,11 @@ brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw,
const struct intel_mipmap_tree *mt,
unsigned level);
+uint32_t
+brw_stencil_all_slices_at_each_lod_offset(const struct isl_surf *surf,
+ const struct intel_mipmap_tree *mt,
+ uint32_t level);
+
bool
brw_miptree_layout(struct brw_context *brw,
struct intel_mipmap_tree *mt,
--
2.9.3
More information about the mesa-dev
mailing list