diff options
author | Paul Berry <[email protected]> | 2012-08-30 08:01:54 -0700 |
---|---|---|
committer | Paul Berry <[email protected]> | 2012-09-12 14:44:13 -0700 |
commit | 1a5d4f7cb2367c7863b28efbd78e9169114baf42 (patch) | |
tree | 32896a7e2ff5479c60e31b712c1a9ba747b6d341 /src | |
parent | 5fd67fac14d7f35c311eb5c671be8d4ae9b2ea37 (diff) |
i965/blorp: Fix offsets and width/height for stencil blits.
Fixes piglit test "framebuffer-blit-levels draw stencil".
NOTE: This is a candidate for stable release branches.
Acked-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_blorp_blit.cpp | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp index 6bf37b8d4aa..656a497a678 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp @@ -1778,8 +1778,9 @@ 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 of the destination surface), to account for the fact - * that we are mapping it as Y-tiled when it is in fact W-tiled. + * (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 @@ -1794,7 +1795,25 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw, * 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. + * sub-tiles. We need to modify the layer width and height similarly. + * + * 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? @@ -1804,19 +1823,28 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw, y0 = ROUND_DOWN_TO(y0, y_align) / 2; x1 = ALIGN(x1, x_align) * 2; y1 = ALIGN(y1, y_align) / 2; - dst.width *= 2; - dst.height /= 2; + dst.width = ALIGN(dst.width, x_align) * 2; + dst.height = ALIGN(dst.height, y_align) / 2; + dst.x_offset *= 2; + dst.y_offset /= 2; wm_prog_key.use_kill = true; } if (src.map_stencil_as_y_tiled) { - /* We must modify the size of the source surface to account for the fact - * that we are mapping it as Y-tiled when it is in fact W 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? */ - src.width *= 2; - src.height /= 2; + const unsigned x_align = 8, y_align = 4; + src.width = ALIGN(src.width, x_align) * 2; + src.height = ALIGN(src.height, y_align) / 2; + src.x_offset *= 2; + src.y_offset /= 2; } } |