[Mesa-dev] [PATCH 20/20] i965/blorp: Translate w-tiling into linear instead of into Y-tiling
Topi Pohjolainen
topi.pohjolainen at intel.com
Fri Apr 11 00:29:00 PDT 2014
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
src/mesa/drivers/dri/i965/brw_blorp.cpp | 10 ++--
src/mesa/drivers/dri/i965/brw_blorp_blit.cpp | 90 +++++++---------------------
src/mesa/drivers/dri/i965/gen6_blorp.cpp | 10 +---
src/mesa/drivers/dri/i965/gen7_blorp.cpp | 10 +---
4 files changed, 31 insertions(+), 89 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.cpp b/src/mesa/drivers/dri/i965/brw_blorp.cpp
index 82e30d4..99b1069 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp.cpp
@@ -88,14 +88,14 @@ brw_blorp_surface_info::set(struct brw_context *brw,
switch (mt->format) {
case MESA_FORMAT_S_UINT8:
- /* The miptree is a W-tiled stencil buffer. Surface states can't be set
- * up for W tiling, so we'll need to use Y tiling and have the WM
- * program swizzle the coordinates, and offset to correct level/layer.
+ /* The miptree is a W-tiled stencil buffer. Surface states can't be set
+ * up for W tiling, and hence the surface is configured as linear and
+ * the program swizzles and offsets the coordinates.
*/
this->map_stencil_as_y_tiled = true;
this->brw_surfaceformat = BRW_SURFACEFORMAT_R8_UNORM;
- this->width = mt->physical_width0;
- this->height = mt->total_height;
+ this->width = mt->region->pitch;
+ this->height = ALIGN(mt->total_height, 64);
break;
case MESA_FORMAT_Z24_UNORM_X8_UINT:
/* It would make sense to use BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
index c69fac4..d5ab1e1 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
@@ -835,7 +835,10 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
key->rt_layout != key->dst_layout) {
encode_msaa(key->rt_samples, key->rt_layout);
/* Now (X, Y, S) = detile(rt_tiling, offset) */
- translate_tiling(rt_tiled_w, key->dst_tiled_w);
+ if (rt_tiled_w != key->dst_tiled_w) {
+ emit_linear_to_w_tiling(t1, t2, dst_stride, X, Y, Xp, Yp);
+ SWAP_XY_AND_XPYP();
+ }
/* Now (X, Y, S) = detile(dst_tiling, offset) */
decode_msaa(key->dst_samples, key->dst_layout);
}
@@ -895,7 +898,10 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
!key->bilinear_filter) {
encode_msaa(key->src_samples, key->src_layout);
/* Now (X, Y, S) = detile(src_tiling, offset) */
- translate_tiling(key->src_tiled_w, tex_tiled_w);
+ if (tex_tiled_w != key->src_tiled_w) {
+ emit_w_tiling_to_linear(t1, t2, src_stride, X, Y, Xp, Yp);
+ SWAP_XY_AND_XPYP();
+ }
/* Now (X, Y, S) = detile(tex_tiling, offset) */
if (!key->src_tiled_w)
decode_msaa(key->tex_samples, key->tex_layout);
@@ -2224,75 +2230,23 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
if (dst.map_stencil_as_y_tiled) {
/* We must modify the rectangle we send through the rendering pipeline
- * (and the size and x/y offset of the destination surface), to account
- * for the fact that we are mapping it as Y-tiled when it is in fact
- * W-tiled.
- *
- * Both Y tiling and W tiling can be understood as organizations of
- * 32-byte sub-tiles; within each 32-byte sub-tile, the layout of pixels
- * is different, but the layout of the 32-byte sub-tiles within the 4k
- * tile is the same (8 sub-tiles across by 16 sub-tiles down, in
- * column-major order). In Y tiling, the sub-tiles are 16 bytes wide
- * and 2 rows high; in W tiling, they are 8 bytes wide and 4 rows high.
- *
- * Therefore, to account for the layout differences within the 32-byte
- * sub-tiles, we must expand the rectangle so the X coordinates of its
- * edges are multiples of 8 (the W sub-tile width), and its Y
- * coordinates of its edges are multiples of 4 (the W sub-tile height).
- * Then we need to scale the X and Y coordinates of the rectangle to
- * account for the differences in aspect ratio between the Y and W
- * sub-tiles. We need to modify the layer width and height similarly.
- *
- * A correction needs to be applied when MSAA is in use: since
- * INTEL_MSAA_LAYOUT_IMS uses an interleaving pattern whose height is 4,
- * we need to align the Y coordinates to multiples of 8, so that when
- * they are divided by two they are still multiples of 4.
- *
- * Note: Since the x/y offset of the surface will be applied using the
- * SURFACE_STATE command packet, it will be invisible to the swizzling
- * code in the shader; therefore it needs to be in a multiple of the
- * 32-byte sub-tile size. Fortunately it is, since the sub-tile is 8
- * pixels wide and 4 pixels high (when viewed as a W-tiled stencil
- * buffer), and the miplevel alignment used for stencil buffers is 8
- * pixels horizontally and either 4 or 8 pixels vertically (see
- * intel_horizontal_texture_alignment_unit() and
- * intel_vertical_texture_alignment_unit()).
- *
- * Note: Also, since the SURFACE_STATE command packet can only apply
- * offsets that are multiples of 4 pixels horizontally and 2 pixels
- * vertically, it is important that the offsets will be multiples of
- * these sizes after they are converted into Y-tiled coordinates.
- * Fortunately they will be, since we know from above that the offsets
- * are a multiple of the 32-byte sub-tile size, and in Y-tiled
- * coordinates the sub-tile is 16 pixels wide and 2 pixels high.
- *
- * TODO: what if this makes the coordinates (or the texture size) too
- * large?
+ * to account for the fact that we are mapping it as linear when it is
+ * in fact W-tiled. In W-tiling 8x8 blocks are in column major order and
+ * hence full width is needed but the height can be restricted by
+ * examining the offset in the furthest included corner x1 - 1, y1 - 1.
*/
- const unsigned x_align = 8, y_align = dst.num_samples != 0 ? 8 : 4;
- x0 = ROUND_DOWN_TO(x0, x_align) * 2;
- y0 = ROUND_DOWN_TO(y0, y_align) / 2;
- x1 = ALIGN(x1, x_align) * 2;
- y1 = ALIGN(y1, y_align) / 2;
- dst.width = ALIGN(dst.width, x_align) * 2;
- dst.height = ALIGN(dst.height, y_align) / 2;
+ static const unsigned make_exclusive = 1;
+ const unsigned stride = dst_mt->region->pitch;
+ const intptr_t min_off = intel_offset_S8(stride, x0, y0,
+ brw->has_swizzling);
+ const intptr_t max_off = intel_offset_S8(stride, x1 - 1, y1 - 1,
+ brw->has_swizzling);
+ y0 = ROUND_DOWN_TO(min_off, stride) / stride;
+ y1 = ALIGN(max_off, stride) / stride + make_exclusive;
+ x1 = dst_mt->region->pitch;
+ x0 = 0;
wm_prog_key.use_kill = true;
}
-
- if (src.map_stencil_as_y_tiled) {
- /* We must modify the size and x/y offset of the source surface to
- * account for the fact that we are mapping it as Y-tiled when it is in
- * fact W tiled.
- *
- * See the comments above concerning x/y offset alignment for the
- * destination surface.
- *
- * TODO: what if this makes the texture size too large?
- */
- const unsigned x_align = 8, y_align = src.num_samples != 0 ? 8 : 4;
- src.width = ALIGN(src.width, x_align) * 2;
- src.height = ALIGN(src.height, y_align) / 2;
- }
}
uint32_t
diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
index 4b6430b..3551a20 100644
--- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
@@ -391,15 +391,9 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
(width - 1) << BRW_SURFACE_WIDTH_SHIFT |
(height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
- uint32_t tiling = surface->map_stencil_as_y_tiled
- ? BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y
- : brw_get_surface_tiling_bits(region->tiling);
- uint32_t pitch_bytes = region->pitch;
- if (surface->map_stencil_as_y_tiled)
- pitch_bytes *= 2;
- surf[3] = (tiling |
+ surf[3] = (brw_get_surface_tiling_bits(region->tiling) |
0 << BRW_SURFACE_DEPTH_SHIFT |
- (pitch_bytes - 1) << BRW_SURFACE_PITCH_SHIFT);
+ SET_FIELD(region->pitch - 1, BRW_SURFACE_PITCH));
surf[4] = surface->map_stencil_as_y_tiled ?
0 : brw_get_surface_num_multisamples(surface->num_samples);
diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
index ab76bee..93fd970 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
@@ -153,16 +153,13 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
uint32_t tile_x = 0, tile_y = 0;
const uint8_t mocs = GEN7_MOCS_L3;
- uint32_t tiling = surface->map_stencil_as_y_tiled
- ? I915_TILING_Y : region->tiling;
-
uint32_t *surf = (uint32_t *)
brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4, 32, &wm_surf_offset);
memset(surf, 0, 8 * 4);
surf[0] = BRW_SURFACE_2D << BRW_SURFACE_TYPE_SHIFT |
surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT |
- gen7_surface_tiling_mode(tiling);
+ gen7_surface_tiling_mode(region->tiling);
if (surface->mt->align_h == 4)
surf[0] |= GEN7_SURFACE_VALIGN_4;
@@ -193,10 +190,7 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);
- uint32_t pitch_bytes = region->pitch;
- if (surface->map_stencil_as_y_tiled)
- pitch_bytes *= 2;
- surf[3] = pitch_bytes - 1;
+ surf[3] = region->pitch - 1;
if (surface->map_stencil_as_y_tiled)
surf[4] = 0;
--
1.8.3.1
More information about the mesa-dev
mailing list