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 <chad.versace@linux.intel.com>
This commit is contained in:
Paul Berry 2012-07-04 05:48:25 -07:00
parent 67b0f7c7dd
commit 1bd4d456cd
10 changed files with 229 additions and 130 deletions

View file

@ -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:

View file

@ -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.

View file

@ -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;
}

View file

@ -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__,

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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,

View file

@ -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,

View file

@ -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;
}