mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 02:10:11 +01:00
isl: Don't align phys_level0_sa by block dimension
Aligning phys_level0_sa by the compression block dimension prior to
mipmap layout causes the layout of compressed surfaces to differ from
the sampler's expectations in certain cases. The hardware docs agree:
From the BDW PRM, Vol. 5, Compressed Mipmap Layout,
The compressed mipmaps are stored in a similar fashion to
uncompressed mipmaps [...]
The following exceptions apply to the layout of compressed (vs.
uncompressed) mipmaps:
* [...]
* The dimensions of the mip maps are first determined by applying
the sizing algorithm presented in Non-Power-of-Two Mipmaps
above. Then, if necessary, they are padded out to compression
block boundaries.
The last bullet indicates that alignment should not be done for
calculating a miplevel's dimensions, but rather for determining miplevel
placement/padding. Comply with this text by removing the extra
alignment.
Fixes some fbo-generatemipmap-formats piglit failures on all tested
platforms (SNB-KBL).
v2:
- Note fixed platforms.
- Update some consumers via a helper function.
Cc: <mesa-stable@lists.freedesktop.org>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
fb1350c76f
commit
02f6995d76
2 changed files with 19 additions and 31 deletions
|
|
@ -717,7 +717,7 @@ isl_surf_choose_dim_layout(const struct isl_device *dev,
|
|||
|
||||
/**
|
||||
* Calculate the physical extent of the surface's first level, in units of
|
||||
* surface samples. The result is aligned to the format's compression block.
|
||||
* surface samples.
|
||||
*/
|
||||
static void
|
||||
isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
|
||||
|
|
@ -746,8 +746,8 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
|
|||
case ISL_DIM_LAYOUT_GEN4_2D:
|
||||
case ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ:
|
||||
*phys_level0_sa = (struct isl_extent4d) {
|
||||
.w = isl_align_npot(info->width, fmtl->bw),
|
||||
.h = fmtl->bh,
|
||||
.w = info->width,
|
||||
.h = 1,
|
||||
.d = 1,
|
||||
.a = info->array_len,
|
||||
};
|
||||
|
|
@ -771,8 +771,8 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
|
|||
assert(info->samples == 1);
|
||||
|
||||
*phys_level0_sa = (struct isl_extent4d) {
|
||||
.w = isl_align_npot(info->width, fmtl->bw),
|
||||
.h = isl_align_npot(info->height, fmtl->bh),
|
||||
.w = info->width,
|
||||
.h = info->height,
|
||||
.d = 1,
|
||||
.a = info->array_len,
|
||||
};
|
||||
|
|
@ -807,9 +807,6 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
|
|||
isl_msaa_interleaved_scale_px_to_sa(info->samples,
|
||||
&phys_level0_sa->w,
|
||||
&phys_level0_sa->h);
|
||||
|
||||
phys_level0_sa->w = isl_align(phys_level0_sa->w, fmtl->bw);
|
||||
phys_level0_sa->h = isl_align(phys_level0_sa->h, fmtl->bh);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
@ -832,8 +829,8 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
|
|||
assert(ISL_DEV_GEN(dev) >= 9);
|
||||
|
||||
*phys_level0_sa = (struct isl_extent4d) {
|
||||
.w = isl_align_npot(info->width, fmtl->bw),
|
||||
.h = isl_align_npot(info->height, fmtl->bh),
|
||||
.w = info->width,
|
||||
.h = info->height,
|
||||
.d = 1,
|
||||
.a = info->depth,
|
||||
};
|
||||
|
|
@ -842,8 +839,8 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
|
|||
case ISL_DIM_LAYOUT_GEN4_3D:
|
||||
assert(ISL_DEV_GEN(dev) < 9);
|
||||
*phys_level0_sa = (struct isl_extent4d) {
|
||||
.w = isl_align(info->width, fmtl->bw),
|
||||
.h = isl_align(info->height, fmtl->bh),
|
||||
.w = info->width,
|
||||
.h = info->height,
|
||||
.d = info->depth,
|
||||
.a = 1,
|
||||
};
|
||||
|
|
@ -968,13 +965,10 @@ isl_calc_phys_slice0_extent_sa_gen4_2d(
|
|||
const struct isl_extent4d *phys_level0_sa,
|
||||
struct isl_extent2d *phys_slice0_sa)
|
||||
{
|
||||
const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
|
||||
|
||||
assert(phys_level0_sa->depth == 1);
|
||||
|
||||
if (info->levels == 1) {
|
||||
/* Do not pad the surface to the image alignment. Instead, pad it only
|
||||
* to the pixel format's block alignment.
|
||||
/* Do not pad the surface to the image alignment.
|
||||
*
|
||||
* For tiled surfaces, using a reduced alignment here avoids wasting CPU
|
||||
* cycles on the below mipmap layout caluclations. Reducing the
|
||||
|
|
@ -989,8 +983,8 @@ isl_calc_phys_slice0_extent_sa_gen4_2d(
|
|||
* VkBufferImageCopy::bufferRowLength.
|
||||
*/
|
||||
*phys_slice0_sa = (struct isl_extent2d) {
|
||||
.w = isl_align_npot(phys_level0_sa->w, fmtl->bw),
|
||||
.h = isl_align_npot(phys_level0_sa->h, fmtl->bh),
|
||||
.w = phys_level0_sa->w,
|
||||
.h = phys_level0_sa->h,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
|
@ -1055,9 +1049,9 @@ isl_calc_phys_total_extent_el_gen4_2d(
|
|||
array_pitch_span,
|
||||
&phys_slice0_sa);
|
||||
*total_extent_el = (struct isl_extent2d) {
|
||||
.w = isl_assert_div(phys_slice0_sa.w, fmtl->bw),
|
||||
.w = isl_align_div_npot(phys_slice0_sa.w, fmtl->bw),
|
||||
.h = *array_pitch_el_rows * (phys_level0_sa->array_len - 1) +
|
||||
isl_assert_div(phys_slice0_sa.h, fmtl->bh),
|
||||
isl_align_div_npot(phys_slice0_sa.h, fmtl->bh),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1201,7 +1195,7 @@ isl_calc_phys_total_extent_el_gen9_1d(
|
|||
{
|
||||
MAYBE_UNUSED const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
|
||||
|
||||
assert(phys_level0_sa->height / fmtl->bh == 1);
|
||||
assert(phys_level0_sa->height == 1);
|
||||
assert(phys_level0_sa->depth == 1);
|
||||
assert(info->samples == 1);
|
||||
assert(image_align_sa->w >= fmtl->bw);
|
||||
|
|
@ -1480,8 +1474,6 @@ isl_surf_init_s(const struct isl_device *dev,
|
|||
struct isl_extent4d phys_level0_sa;
|
||||
isl_calc_phys_level0_extent_sa(dev, info, dim_layout, tiling, msaa_layout,
|
||||
&phys_level0_sa);
|
||||
assert(phys_level0_sa.w % fmtl->bw == 0);
|
||||
assert(phys_level0_sa.h % fmtl->bh == 0);
|
||||
|
||||
enum isl_array_pitch_span array_pitch_span =
|
||||
isl_choose_array_pitch_span(dev, info, dim_layout, &phys_level0_sa);
|
||||
|
|
|
|||
|
|
@ -1176,7 +1176,7 @@ struct isl_surf {
|
|||
|
||||
/**
|
||||
* Physical extent of the surface's base level, in units of physical
|
||||
* surface samples and aligned to the format's compression block.
|
||||
* surface samples.
|
||||
*
|
||||
* Consider isl_dim_layout as an operator that transforms a logical surface
|
||||
* layout to a physical surface layout. Then
|
||||
|
|
@ -1907,13 +1907,9 @@ isl_surf_get_phys_level0_el(const struct isl_surf *surf)
|
|||
{
|
||||
const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format);
|
||||
|
||||
assert(surf->phys_level0_sa.w % fmtl->bw == 0);
|
||||
assert(surf->phys_level0_sa.h % fmtl->bh == 0);
|
||||
assert(surf->phys_level0_sa.d % fmtl->bd == 0);
|
||||
|
||||
return isl_extent4d(surf->phys_level0_sa.w / fmtl->bw,
|
||||
surf->phys_level0_sa.h / fmtl->bh,
|
||||
surf->phys_level0_sa.d / fmtl->bd,
|
||||
return isl_extent4d(DIV_ROUND_UP(surf->phys_level0_sa.w, fmtl->bw),
|
||||
DIV_ROUND_UP(surf->phys_level0_sa.h, fmtl->bh),
|
||||
DIV_ROUND_UP(surf->phys_level0_sa.d, fmtl->bd),
|
||||
surf->phys_level0_sa.a);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue