diff options
author | Paul Berry <[email protected]> | 2012-05-10 17:52:09 -0700 |
---|---|---|
committer | Paul Berry <[email protected]> | 2012-05-25 08:45:10 -0700 |
commit | 52fcc36f11b12236eb4f960b65b17b047cf32efa (patch) | |
tree | c477c1f0586447877cc34d0a7e2361cb9112ae67 | |
parent | 93594f38be75227879b835a2037b7466adbd70ef (diff) |
i965/msaa: Expand odd-sized MSAA surfaces to account for interleaving pattern.
Gen6 MSAA buffers (and Gen7 MSAA depth/stencil buffers) interleave
MSAA samples in a complex pattern that repeats every 2x2 pixel block.
Therefore, when allocating an MSAA buffer, we need to make sure to
allocate an integer number of 2x2 blocks; if we don't, then some of
the samples in the last row and column will be cut off.
Fixes piglit tests "EXT_framebuffer_multisample/unaligned-blit {2,4}
color msaa" on i965/Gen6.
Acked-by: Kenneth Graunke <[email protected]>
Reviewed-by: Chad Versace <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 40cd3d03019..13e73969e6a 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -261,15 +261,50 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel, { struct intel_mipmap_tree *mt; - /* Adjust width/height for MSAA */ + /* Adjust width/height for MSAA. + * + * In the Sandy Bridge PRM, volume 4, part 1, page 31, it says: + * + * "Any of the other messages (sample*, LOD, load4) used with a + * (4x) multisampled surface will in-effect sample a surface with + * double the height and width as that indicated in the surface + * state. Each pixel position on the original-sized surface is + * replaced with a 2x2 of samples with the following arrangement: + * + * sample 0 sample 2 + * sample 1 sample 3" + * + * Thus, when sampling from a multisampled texture, it behaves as though + * the layout in memory for (x,y,sample) is: + * + * (0,0,0) (0,0,2) (1,0,0) (1,0,2) + * (0,0,1) (0,0,3) (1,0,1) (1,0,3) + * + * (0,1,0) (0,1,2) (1,1,0) (1,1,2) + * (0,1,1) (0,1,3) (1,1,1) (1,1,3) + * + * However, the actual layout of multisampled data in memory is: + * + * (0,0,0) (1,0,0) (0,0,1) (1,0,1) + * (0,1,0) (1,1,0) (0,1,1) (1,1,1) + * + * (0,0,2) (1,0,2) (0,0,3) (1,0,3) + * (0,1,2) (1,1,2) (0,1,3) (1,1,3) + * + * This pattern repeats for each 2x2 pixel block. + * + * As a result, when calculating the size of our 4-sample buffer for + * an odd width or height, we have to align before scaling up because + * sample 3 is in that bottom right 2x2 block. + */ if (num_samples > 4) { num_samples = 8; - width *= 4; - height *= 2; + width = ALIGN(width, 2) * 4; + height = ALIGN(height, 2) * 2; } else if (num_samples > 0) { num_samples = 4; - width *= 2; - height *= 2; + width = ALIGN(width, 2) * 2; + height = ALIGN(height, 2) * 2; } mt = intel_miptree_create(intel, GL_TEXTURE_2D, format, 0, 0, |