summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2012-05-10 17:52:09 -0700
committerPaul Berry <stereotype441@gmail.com>2012-05-25 08:45:10 -0700
commit52fcc36f11b12236eb4f960b65b17b047cf32efa (patch)
treec477c1f0586447877cc34d0a7e2361cb9112ae67
parent93594f38be75227879b835a2037b7466adbd70ef (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 <kenneth@whitecape.org> Reviewed-by: Chad Versace <chad.versace@linux.intel.com> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c45
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,