mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-03 10:30:32 +01:00
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:
parent
67b0f7c7dd
commit
1bd4d456cd
10 changed files with 229 additions and 130 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue