summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2012-07-04 05:48:25 -0700
committerPaul Berry <[email protected]>2012-07-11 15:14:49 -0700
commit1bd4d456cdecf7bea55f4e3dac574af54efad994 (patch)
tree240f42776eb6e453443539c153e3e84c318fc9b8
parent67b0f7c7dddeb92ee4d24ed3977e20b70f5674f6 (diff)
i965/msaa: Add an enum to describe MSAA layout.
From the Ivy Bridge PRM, Vol 1 Part 1, p112: There are three types of multisampled surface layouts designated as follows: - IMS Interleaved Multisampled Surface - CMS Compressed Mulitsampled Surface - UMS Uncompressed Multisampled Surface Previously, the i965 driver only used IMS and UMS formats, and distinguished beetween them using the boolean intel_mipmap_tree::msaa_is_interleaved. To facilitate adding support for the CMS format, this patch replaces that boolean (and other booleans derived from it) with an enum INTEL_MSAA_LAYOUT_{IMS,CMS,UMS}. It also updates the terminology used in comments throughout the driver to match the IMS/CMS/UMS terminology used in the PRM. CMS layout is not yet used. The enum has a fourth possible value, INTEL_MSAA_LAYOUT_NONE, which is used for non-multisampled surfaces. Reviewed-by: Chad Versace <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_blorp.cpp1
-rw-r--r--src/mesa/drivers/dri/i965/brw_blorp.h32
-rw-r--r--src/mesa/drivers/dri/i965/brw_blorp_blit.cpp190
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen7_wm_surface_state.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c68
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h48
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_validate.c2
10 files changed, 229 insertions, 130 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.cpp b/src/mesa/drivers/dri/i965/brw_blorp.cpp
index afb453001d4..9017e4d8cf6 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp.cpp
@@ -61,6 +61,7 @@ brw_blorp_surface_info::set(struct brw_context *brw,
this->num_samples = mt->num_samples;
this->array_spacing_lod0 = mt->array_spacing_lod0;
this->map_stencil_as_y_tiled = false;
+ this->msaa_layout = mt->msaa_layout;
switch (mt->format) {
case MESA_FORMAT_S8:
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h
index cc7e12e1ae7..053eef74071 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.h
+++ b/src/mesa/drivers/dri/i965/brw_blorp.h
@@ -97,6 +97,12 @@ void set(struct brw_context *brw,
* surface. Should correspond to one of the BRW_SURFACEFORMAT_* enums.
*/
uint32_t brw_surfaceformat;
+
+ /**
+ * For MSAA surfaces, MSAA layout that should be used when setting up the
+ * surface state for this surface.
+ */
+ intel_msaa_layout msaa_layout;
};
@@ -192,38 +198,30 @@ struct brw_blorp_blit_prog_key
*/
unsigned tex_samples;
- /* If tex_samples > 0, this boolean indicates whether or not the GPU
- * pipeline will be configured to read from it as though it were an
- * interleaved MSAA layout. False if tex_samples == 0.
+ /* MSAA layout that has been configured in the surface state for texturing
+ * from.
*/
- bool tex_interleaved;
+ intel_msaa_layout tex_layout;
/* Actual number of samples per pixel in the source image. */
unsigned src_samples;
- /* If src_samples > 0, this boolean indicates whether or not the source
- * image uses an interleaved MSAA layout. False if src_samples == 0.
- */
- bool src_interleaved;
+ /* Actual MSAA layout used by the source image. */
+ intel_msaa_layout src_layout;
/* Number of samples per pixel that have been configured in the render
* target.
*/
unsigned rt_samples;
- /* If rt_samples > 0, whether or not the GPU pipeline will be configured
- * to write to it as though it were an interleaved MSAA layout. False if
- * rt_samples == 0.
- */
- bool rt_interleaved;
+ /* MSAA layout that has been configured in the render target. */
+ intel_msaa_layout rt_layout;
/* Actual number of samples per pixel in the destination image. */
unsigned dst_samples;
- /* If dst_samples > 0, whether or not the destination image uses an
- * interleaved MSAA layout. False if dst_samples == 0.
- */
- bool dst_interleaved;
+ /* Actual MSAA layout used by the destination image. */
+ intel_msaa_layout dst_layout;
/* True if the source image is W tiled. If true, the surface state for the
* source image must be configured as Y tiled, and tex_samples must be 0.
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
index 0467607f289..ea98a66d81a 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
@@ -288,22 +288,22 @@ enum sampler_message_arg
* offset = tile(tiling_format, encode_msaa(num_samples, layout, X, Y, S))
* (X, Y, S) = decode_msaa(num_samples, layout, detile(tiling_format, offset))
*
- * For a single-sampled surface, or for a multisampled surface that stores
- * each sample in a different array slice, encode_msaa() and decode_msaa are
- * the identity function:
+ * For a single-sampled surface, or for a multisampled surface using
+ * INTEL_MSAA_LAYOUT_UMS, encode_msaa() and decode_msaa are the identity
+ * function:
*
- * encode_msaa(1, N/A, X, Y, 0) = (X, Y, 0)
- * decode_msaa(1, N/A, X, Y, 0) = (X, Y, 0)
- * encode_msaa(n, sliced, X, Y, S) = (X, Y, S)
- * decode_msaa(n, sliced, X, Y, S) = (X, Y, S)
+ * encode_msaa(1, NONE, X, Y, 0) = (X, Y, 0)
+ * decode_msaa(1, NONE, X, Y, 0) = (X, Y, 0)
+ * encode_msaa(n, UMS, X, Y, S) = (X, Y, S)
+ * decode_msaa(n, UMS, X, Y, S) = (X, Y, S)
*
- * For a 4x interleaved multisampled surface, encode_msaa() embeds the sample
- * number into bit 1 of the X and Y coordinates:
+ * For a 4x multisampled surface using INTEL_MSAA_LAYOUT_IMS, encode_msaa()
+ * embeds the sample number into bit 1 of the X and Y coordinates:
*
- * encode_msaa(4, interleaved, X, Y, S) = (X', Y', 0)
+ * encode_msaa(4, IMS, X, Y, S) = (X', Y', 0)
* where X' = (X & ~0b1) << 1 | (S & 0b1) << 1 | (X & 0b1)
* Y' = (Y & ~0b1 ) << 1 | (S & 0b10) | (Y & 0b1)
- * decode_msaa(4, interleaved, X, Y, 0) = (X', Y', S)
+ * decode_msaa(4, IMS, X, Y, 0) = (X', Y', S)
* where X' = (X & ~0b11) >> 1 | (X & 0b1)
* Y' = (Y & ~0b11) >> 1 | (Y & 0b1)
* S = (Y & 0b10) | (X & 0b10) >> 1
@@ -419,8 +419,8 @@ private:
void alloc_push_const_regs(int base_reg);
void compute_frag_coords();
void translate_tiling(bool old_tiled_w, bool new_tiled_w);
- void encode_msaa(unsigned num_samples, bool interleaved);
- void decode_msaa(unsigned num_samples, bool interleaved);
+ void encode_msaa(unsigned num_samples, intel_msaa_layout layout);
+ void decode_msaa(unsigned num_samples, intel_msaa_layout layout);
void kill_if_outside_dst_rect();
void translate_dst_to_src();
void single_to_blend();
@@ -529,7 +529,7 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
*/
assert(!key->src_tiled_w);
assert(key->tex_samples == key->src_samples);
- assert(key->tex_interleaved == key->src_interleaved);
+ assert(key->tex_layout == key->src_layout);
assert(key->tex_samples > 0);
}
@@ -540,10 +540,15 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
assert(key->rt_samples > 0);
}
- /* Interleaved only makes sense on MSAA surfaces */
- if (key->tex_interleaved) assert(key->tex_samples > 0);
- if (key->src_interleaved) assert(key->src_samples > 0);
- if (key->dst_interleaved) assert(key->dst_samples > 0);
+ /* Make sure layout is consistent with sample count */
+ assert((key->tex_layout == INTEL_MSAA_LAYOUT_NONE) ==
+ (key->tex_samples == 0));
+ assert((key->rt_layout == INTEL_MSAA_LAYOUT_NONE) ==
+ (key->rt_samples == 0));
+ assert((key->src_layout == INTEL_MSAA_LAYOUT_NONE) ==
+ (key->src_samples == 0));
+ assert((key->dst_layout == INTEL_MSAA_LAYOUT_NONE) ==
+ (key->dst_samples == 0));
/* Set up prog_data */
memset(&prog_data, 0, sizeof(prog_data));
@@ -571,12 +576,12 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
*/
if (rt_tiled_w != key->dst_tiled_w ||
key->rt_samples != key->dst_samples ||
- key->rt_interleaved != key->dst_interleaved) {
- encode_msaa(key->rt_samples, key->rt_interleaved);
+ 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);
/* Now (X, Y, S) = detile(dst_tiling, offset) */
- decode_msaa(key->dst_samples, key->dst_interleaved);
+ decode_msaa(key->dst_samples, key->dst_layout);
}
/* Now (X, Y, S) = decode_msaa(dst_samples, detile(dst_tiling, offset)).
@@ -626,12 +631,12 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
*/
if (tex_tiled_w != key->src_tiled_w ||
key->tex_samples != key->src_samples ||
- key->tex_interleaved != key->src_interleaved) {
- encode_msaa(key->src_samples, key->src_interleaved);
+ key->tex_layout != key->src_layout) {
+ 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);
/* Now (X, Y, S) = detile(tex_tiling, offset) */
- decode_msaa(key->tex_samples, key->tex_interleaved);
+ decode_msaa(key->tex_samples, key->tex_layout);
}
/* Now (X, Y, S) = decode_msaa(tex_samples, detile(tex_tiling, offset)).
@@ -801,7 +806,7 @@ brw_blorp_blit_program::translate_tiling(bool old_tiled_w, bool new_tiled_w)
return;
/* In the code that follows, we can safely assume that S = 0, because W
- * tiling formats always use interleaved encoding.
+ * tiling formats always use IMS layout.
*/
assert(s_is_zero);
@@ -887,15 +892,25 @@ brw_blorp_blit_program::translate_tiling(bool old_tiled_w, bool new_tiled_w)
* (See brw_blorp_blit_program).
*/
void
-brw_blorp_blit_program::encode_msaa(unsigned num_samples, bool interleaved)
+brw_blorp_blit_program::encode_msaa(unsigned num_samples,
+ intel_msaa_layout layout)
{
- if (num_samples == 0) {
+ switch (layout) {
+ case INTEL_MSAA_LAYOUT_NONE:
/* No translation necessary, and S should already be zero. */
assert(s_is_zero);
- } else if (!interleaved) {
+ break;
+ case INTEL_MSAA_LAYOUT_CMS:
+ /* We can't compensate for compressed layout since at this point in the
+ * program we haven't read from the MCS buffer.
+ */
+ assert(!"Bad layout in encode_msaa");
+ break;
+ case INTEL_MSAA_LAYOUT_UMS:
/* No translation necessary. */
- } else {
- /* encode_msaa(4, interleaved, X, Y, S) = (X', Y', 0)
+ break;
+ case INTEL_MSAA_LAYOUT_IMS:
+ /* encode_msaa(4, IMS, X, Y, S) = (X', Y', 0)
* where X' = (X & ~0b1) << 1 | (S & 0b1) << 1 | (X & 0b1)
* Y' = (Y & ~0b1 ) << 1 | (S & 0b10) | (Y & 0b1)
*/
@@ -918,6 +933,7 @@ brw_blorp_blit_program::encode_msaa(unsigned num_samples, bool interleaved)
brw_OR(&func, Yp, t1, t2);
SWAP_XY_AND_XPYP();
s_is_zero = true;
+ break;
}
}
@@ -932,15 +948,25 @@ brw_blorp_blit_program::encode_msaa(unsigned num_samples, bool interleaved)
* (See brw_blorp_blit_program).
*/
void
-brw_blorp_blit_program::decode_msaa(unsigned num_samples, bool interleaved)
+brw_blorp_blit_program::decode_msaa(unsigned num_samples,
+ intel_msaa_layout layout)
{
- if (num_samples == 0) {
+ switch (layout) {
+ case INTEL_MSAA_LAYOUT_NONE:
/* No translation necessary, and S should already be zero. */
assert(s_is_zero);
- } else if (!interleaved) {
+ break;
+ case INTEL_MSAA_LAYOUT_CMS:
+ /* We can't compensate for compressed layout since at this point in the
+ * program we don't have access to the MCS buffer.
+ */
+ assert(!"Bad layout in encode_msaa");
+ break;
+ case INTEL_MSAA_LAYOUT_UMS:
/* No translation necessary. */
- } else {
- /* decode_msaa(4, interleaved, X, Y, 0) = (X', Y', S)
+ break;
+ case INTEL_MSAA_LAYOUT_IMS:
+ /* decode_msaa(4, IMS, X, Y, 0) = (X', Y', S)
* where X' = (X & ~0b11) >> 1 | (X & 0b1)
* Y' = (Y & ~0b11) >> 1 | (Y & 0b1)
* S = (Y & 0b10) | (X & 0b10) >> 1
@@ -960,6 +986,7 @@ brw_blorp_blit_program::decode_msaa(unsigned num_samples, bool interleaved)
brw_OR(&func, S, t1, t2);
s_is_zero = false;
SWAP_XY_AND_XPYP();
+ break;
}
}
@@ -1248,6 +1275,40 @@ brw_blorp_coord_transform_params::setup(GLuint src0, GLuint dst0, GLuint dst1,
}
+/**
+ * Determine which MSAA layout the GPU pipeline should be configured for,
+ * based on the chip generation, the number of samples, and the true layout of
+ * the image in memory.
+ */
+inline intel_msaa_layout
+compute_msaa_layout_for_pipeline(struct brw_context *brw, unsigned num_samples,
+ intel_msaa_layout true_layout)
+{
+ if (num_samples == 0) {
+ /* When configuring the GPU for non-MSAA, we can still accommodate IMS
+ * format buffers, by transforming coordinates appropriately.
+ */
+ assert(true_layout == INTEL_MSAA_LAYOUT_NONE ||
+ true_layout == INTEL_MSAA_LAYOUT_IMS);
+ return INTEL_MSAA_LAYOUT_NONE;
+ }
+
+ /* Prior to Gen7, all MSAA surfaces use IMS layout. */
+ if (brw->intel.gen == 6) {
+ assert(true_layout == INTEL_MSAA_LAYOUT_IMS);
+ return INTEL_MSAA_LAYOUT_IMS;
+ }
+
+ /* Since blorp uses color textures and render targets to do all its work
+ * (even when blitting stencil and depth data), we always have to configure
+ * the Gen7 GPU to use UMS or CMS layout on Gen7.
+ */
+ assert(true_layout == INTEL_MSAA_LAYOUT_UMS ||
+ true_layout == INTEL_MSAA_LAYOUT_CMS);
+ return true_layout;
+}
+
+
brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
struct intel_mipmap_tree *src_mt,
struct intel_mipmap_tree *dst_mt,
@@ -1263,22 +1324,21 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
memset(&wm_prog_key, 0, sizeof(wm_prog_key));
if (brw->intel.gen > 6) {
- /* Gen7 only supports interleaved MSAA surfaces for texturing with the
+ /* Gen7's texturing hardware only supports the IMS layout with the
* ld2dms instruction (which blorp doesn't use). So if the source is
- * interleaved MSAA, we'll have to map it as a single-sampled texture
- * and de-interleave the samples ourselves.
+ * IMS, we'll have to map it as a single-sampled texture and
+ * de-interleave the samples ourselves.
*/
- if (src.num_samples > 0 && src_mt->msaa_is_interleaved)
+ if (src_mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS)
src.num_samples = 0;
- /* Similarly, Gen7 only supports interleaved MSAA surfaces for depth and
- * stencil render targets. Blorp always maps its destination surface as
- * a color render target (even if it's actually a depth or stencil
- * buffer). So if the destination is interleaved MSAA, we'll have to
- * map it as a single-sampled texture and interleave the samples
- * ourselves.
+ /* Similarly, Gen7's rendering hardware only supports the IMS layout for
+ * depth and stencil render targets. Blorp always maps its destination
+ * surface as a color render target (even if it's actually a depth or
+ * stencil buffer). So if the destination is IMS, we'll have to map it
+ * as a single-sampled texture and interleave the samples ourselves.
*/
- if (dst.num_samples > 0 && dst_mt->msaa_is_interleaved)
+ if (dst_mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS)
dst.num_samples = 0;
}
@@ -1324,21 +1384,19 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
wm_prog_key.tex_samples = src.num_samples;
wm_prog_key.rt_samples = dst.num_samples;
- /* tex_interleaved and rt_interleaved indicate whether or not the GPU
- * pipeline will access the source and destination surfaces as though they
- * use an interleaved layout. Since blorp uses color textures and render
- * targets to do all its work (even when blitting stencil and depth data),
- * it will always use sliced layout on Gen7. On Gen6, the MSAA layout is
- * always interleaved.
+ /* tex_layout and rt_layout indicate the MSAA layout the GPU pipeline will
+ * use to access the source and destination surfaces.
*/
- wm_prog_key.tex_interleaved = src.num_samples > 0 && brw->intel.gen == 6;
- wm_prog_key.rt_interleaved = dst.num_samples > 0 && brw->intel.gen == 6;
+ wm_prog_key.tex_layout =
+ compute_msaa_layout_for_pipeline(brw, src.num_samples, src.msaa_layout);
+ wm_prog_key.rt_layout =
+ compute_msaa_layout_for_pipeline(brw, dst.num_samples, dst.msaa_layout);
- /* src_interleaved and dst_interleaved indicate whether src and dst are
- * truly interleaved.
+ /* src_layout and dst_layout indicate the true MSAA layout used by src and
+ * dst.
*/
- wm_prog_key.src_interleaved = src_mt->msaa_is_interleaved;
- wm_prog_key.dst_interleaved = dst_mt->msaa_is_interleaved;
+ wm_prog_key.src_layout = src_mt->msaa_layout;
+ wm_prog_key.dst_layout = dst_mt->msaa_layout;
wm_prog_key.src_tiled_w = src.map_stencil_as_y_tiled;
wm_prog_key.dst_tiled_w = dst.map_stencil_as_y_tiled;
@@ -1358,11 +1416,11 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
* will mean that pixels are scrambled within the multisampling pattern.
* TODO: what if this makes the coordinates too large?
*
- * Note: this only works if the destination surface's MSAA layout is
- * interleaved. If it's sliced, then we have no choice but to set up
- * the rendering pipeline as multisampled.
+ * Note: this only works if the destination surface uses the IMS layout.
+ * If it's UMS, then we have no choice but to set up the rendering
+ * pipeline as multisampled.
*/
- assert(dst_mt->msaa_is_interleaved);
+ assert(dst_mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS);
x0 = (x0 * 2) & ~3;
y0 = (y0 * 2) & ~3;
x1 = ALIGN(x1 * 2, 4);
@@ -1378,14 +1436,14 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
* size, because the differences between W and Y tiling formats will
* mean that pixels are scrambled within the tile.
*
- * Note: if the destination surface configured as an interleaved MSAA
- * surface, then the effective tile size we need to align it to is
- * smaller, because each pixel covers a 2x2 or a 4x2 block of samples.
+ * Note: if the destination surface configured to use IMS layout, then
+ * the effective tile size we need to align it to is smaller, because
+ * each pixel covers a 2x2 or a 4x2 block of samples.
*
* TODO: what if this makes the coordinates too large?
*/
unsigned x_align = 64, y_align = 64;
- if (dst_mt->num_samples > 0 && dst_mt->msaa_is_interleaved) {
+ if (dst_mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
x_align /= (dst_mt->num_samples == 4 ? 2 : 4);
y_align /= 2;
}
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index f7421318c21..1a2bedb2268 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -168,10 +168,16 @@ brw_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree *mt)
break;
default:
- if (mt->num_samples > 0 && !mt->msaa_is_interleaved)
+ switch (mt->msaa_layout) {
+ case INTEL_MSAA_LAYOUT_UMS:
+ case INTEL_MSAA_LAYOUT_CMS:
brw_miptree_layout_texture_array(intel, mt);
- else
+ break;
+ case INTEL_MSAA_LAYOUT_NONE:
+ case INTEL_MSAA_LAYOUT_IMS:
i945_miptree_layout_2d(mt);
+ break;
+ }
break;
}
DBG("%s: %dx%dx%d\n", __FUNCTION__,
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 04ae6b23289..ddf38e3dd35 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -1022,7 +1022,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
width, height, depth,
true,
0 /* num_samples */,
- false /* msaa_is_interleaved */);
+ INTEL_MSAA_LAYOUT_NONE);
intel_miptree_copy_teximage(intel, intel_image, new_mt);
intel_miptree_reference(&irb->mt, intel_image->mt);
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
index 557f36f1be0..52312c9787c 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
@@ -398,8 +398,8 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
sizeof(*surf), 32, &brw->wm.surf_offset[unit]);
memset(surf, 0, sizeof(*surf));
- /* Render targets can't use MSAA interleaved layout */
- assert(!irb->mt->msaa_is_interleaved);
+ /* Render targets can't use IMS layout */
+ assert(irb->mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);
if (irb->mt->align_h == 4)
surf->ss0.vertical_alignment = 1;
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 41d337fba16..7c95b7924ca 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -74,7 +74,7 @@ intel_miptree_create_internal(struct intel_context *intel,
GLuint depth0,
bool for_region,
GLuint num_samples,
- bool msaa_is_interleaved)
+ enum intel_msaa_layout msaa_layout)
{
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
int compress_byte = 0;
@@ -96,13 +96,22 @@ intel_miptree_create_internal(struct intel_context *intel,
mt->cpp = compress_byte ? compress_byte : _mesa_get_format_bytes(mt->format);
mt->num_samples = num_samples;
mt->compressed = compress_byte ? 1 : 0;
- mt->msaa_is_interleaved = msaa_is_interleaved;
+ mt->msaa_layout = msaa_layout;
mt->refcount = 1;
- /* array_spacing_lod0 is only used for non-interleaved MSAA surfaces.
- * TODO: can we use it elsewhere?
+ /* array_spacing_lod0 is only used for non-IMS MSAA surfaces. TODO: can we
+ * use it elsewhere?
*/
- mt->array_spacing_lod0 = num_samples > 0 && !msaa_is_interleaved;
+ switch (msaa_layout) {
+ case INTEL_MSAA_LAYOUT_NONE:
+ case INTEL_MSAA_LAYOUT_IMS:
+ mt->array_spacing_lod0 = false;
+ break;
+ case INTEL_MSAA_LAYOUT_UMS:
+ case INTEL_MSAA_LAYOUT_CMS:
+ mt->array_spacing_lod0 = true;
+ break;
+ }
if (target == GL_TEXTURE_CUBE_MAP) {
assert(depth0 == 1);
@@ -116,8 +125,9 @@ intel_miptree_create_internal(struct intel_context *intel,
(intel->must_use_separate_stencil ||
(intel->has_separate_stencil &&
intel->vtbl.is_hiz_depth_format(intel, format)))) {
- /* MSAA stencil surfaces are always interleaved. */
- bool msaa_is_interleaved = num_samples > 0;
+ /* MSAA stencil surfaces always use IMS layout. */
+ enum intel_msaa_layout msaa_layout =
+ num_samples > 0 ? INTEL_MSAA_LAYOUT_IMS : INTEL_MSAA_LAYOUT_NONE;
mt->stencil_mt = intel_miptree_create(intel,
mt->target,
MESA_FORMAT_S8,
@@ -128,7 +138,7 @@ intel_miptree_create_internal(struct intel_context *intel,
mt->depth0,
true,
num_samples,
- msaa_is_interleaved);
+ msaa_layout);
if (!mt->stencil_mt) {
intel_miptree_release(&mt);
return NULL;
@@ -176,7 +186,7 @@ intel_miptree_create(struct intel_context *intel,
GLuint depth0,
bool expect_accelerated_upload,
GLuint num_samples,
- bool msaa_is_interleaved)
+ enum intel_msaa_layout msaa_layout)
{
struct intel_mipmap_tree *mt;
uint32_t tiling = I915_TILING_NONE;
@@ -187,7 +197,7 @@ intel_miptree_create(struct intel_context *intel,
(base_format == GL_DEPTH_COMPONENT ||
base_format == GL_DEPTH_STENCIL_EXT))
tiling = I915_TILING_Y;
- else if (num_samples > 0) {
+ else if (msaa_layout != INTEL_MSAA_LAYOUT_NONE) {
/* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
* Surface"):
*
@@ -218,7 +228,7 @@ intel_miptree_create(struct intel_context *intel,
mt = intel_miptree_create_internal(intel, target, format,
first_level, last_level, width0,
height0, depth0,
- false, num_samples, msaa_is_interleaved);
+ false, num_samples, msaa_layout);
/*
* pitch == 0 || height == 0 indicates the null texture
*/
@@ -256,7 +266,7 @@ intel_miptree_create_for_region(struct intel_context *intel,
0, 0,
region->width, region->height, 1,
true, 0 /* num_samples */,
- false /* msaa_is_interleaved */);
+ INTEL_MSAA_LAYOUT_NONE);
if (!mt)
return mt;
@@ -266,27 +276,24 @@ intel_miptree_create_for_region(struct intel_context *intel,
}
/**
- * Determine whether the MSAA surface being created should use an interleaved
- * layout or a sliced layout, based on the chip generation and the surface
- * type.
+ * Determine which MSAA layout should be used by the MSAA surface being
+ * created, based on the chip generation and the surface type.
*/
-static bool
-msaa_format_is_interleaved(struct intel_context *intel, gl_format format)
+static enum intel_msaa_layout
+compute_msaa_layout(struct intel_context *intel, gl_format format)
{
- /* Prior to Gen7, all surfaces used interleaved layout. */
+ /* Prior to Gen7, all MSAA surfaces used IMS layout. */
if (intel->gen < 7)
- return true;
+ return INTEL_MSAA_LAYOUT_IMS;
- /* In Gen7, interleaved layout is only used for depth and stencil
- * buffers.
- */
+ /* In Gen7, IMS layout is only used for depth and stencil buffers. */
switch (_mesa_get_format_base_format(format)) {
case GL_DEPTH_COMPONENT:
case GL_STENCIL_INDEX:
case GL_DEPTH_STENCIL:
- return true;
+ return INTEL_MSAA_LAYOUT_IMS;
default:
- return false;
+ return INTEL_MSAA_LAYOUT_UMS;
}
}
@@ -299,12 +306,12 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,
{
struct intel_mipmap_tree *mt;
uint32_t depth = 1;
- bool msaa_is_interleaved = false;
+ enum intel_msaa_layout msaa_layout = INTEL_MSAA_LAYOUT_NONE;
if (num_samples > 0) {
/* Adjust width/height/depth for MSAA */
- msaa_is_interleaved = msaa_format_is_interleaved(intel, format);
- if (msaa_is_interleaved) {
+ msaa_layout = compute_msaa_layout(intel, format);
+ if (msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
/* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says:
*
* "Any of the other messages (sample*, LOD, load4) used with a
@@ -362,7 +369,7 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel,
mt = intel_miptree_create(intel, GL_TEXTURE_2D, format, 0, 0,
width, height, depth, true, num_samples,
- msaa_is_interleaved);
+ msaa_layout);
return mt;
}
@@ -636,8 +643,7 @@ intel_miptree_alloc_hiz(struct intel_context *intel,
GLuint num_samples)
{
assert(mt->hiz_mt == NULL);
- /* MSAA HiZ surfaces are always interleaved. */
- bool msaa_is_interleaved = num_samples > 0;
+ /* MSAA HiZ surfaces always use IMS layout. */
mt->hiz_mt = intel_miptree_create(intel,
mt->target,
MESA_FORMAT_X8_Z24,
@@ -648,7 +654,7 @@ intel_miptree_alloc_hiz(struct intel_context *intel,
mt->depth0,
true,
num_samples,
- msaa_is_interleaved);
+ INTEL_MSAA_LAYOUT_IMS);
if (!mt->hiz_mt)
return false;
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 564c6a49f14..38412cd1b7f 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -138,6 +138,42 @@ struct intel_mipmap_level
} *slice;
};
+/**
+ * Enum for keeping track of the different MSAA layouts supported by Gen7.
+ */
+enum intel_msaa_layout
+{
+ /**
+ * Ordinary surface with no MSAA.
+ */
+ INTEL_MSAA_LAYOUT_NONE,
+
+ /**
+ * Interleaved Multisample Surface. The additional samples are
+ * accommodated by scaling up the width and the height of the surface so
+ * that all the samples corresponding to a pixel are located at nearby
+ * memory locations.
+ */
+ INTEL_MSAA_LAYOUT_IMS,
+
+ /**
+ * Uncompressed Multisample Surface. The surface is stored as a 2D array,
+ * with array slice n containing all pixel data for sample n.
+ */
+ INTEL_MSAA_LAYOUT_UMS,
+
+ /**
+ * Compressed Multisample Surface. The surface is stored as in
+ * INTEL_MSAA_LAYOUT_UMS, but there is an additional buffer called the MCS
+ * (Multisample Control Surface) buffer. Each pixel in the MCS buffer
+ * indicates the mapping from sample number to array slice. This allows
+ * the common case (where all samples constituting a pixel have the same
+ * color value) to be stored efficiently by just using a single array
+ * slice.
+ */
+ INTEL_MSAA_LAYOUT_CMS,
+};
+
struct intel_mipmap_tree
{
/* Effectively the key:
@@ -182,15 +218,9 @@ struct intel_mipmap_tree
bool array_spacing_lod0;
/**
- * For MSAA buffers, there are two possible layouts:
- * - Interleaved, in which the additional samples are accommodated
- * by scaling up the width and height of the surface.
- * - Sliced, in which the surface is stored as a 2D array, with
- * array slice n containing all pixel data for sample n.
- *
- * This value is true if num_samples > 0 and the format is interleaved.
+ * MSAA layout used by this buffer.
*/
- bool msaa_is_interleaved;
+ enum intel_msaa_layout msaa_layout;
/* Derived from the above:
*/
@@ -263,7 +293,7 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
GLuint depth0,
bool expect_accelerated_upload,
GLuint num_samples,
- bool msaa_is_interleaved);
+ enum intel_msaa_layout msaa_layout);
struct intel_mipmap_tree *
intel_miptree_create_for_region(struct intel_context *intel,
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index 70fe762a101..a023fef5634 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -101,7 +101,7 @@ intel_miptree_create_for_teximage(struct intel_context *intel,
depth,
expect_accelerated_upload,
0 /* num_samples */,
- false /* msaa_is_interleaved */);
+ INTEL_MSAA_LAYOUT_NONE);
}
/* There are actually quite a few combinations this will work for,
diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c
index c2d7d67df54..34bbbb83930 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c
@@ -88,7 +88,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
depth,
true,
0 /* num_samples */,
- false /* msaa_is_interleaved */);
+ INTEL_MSAA_LAYOUT_NONE);
if (!intelObj->mt)
return false;
}