radeon: fix mipmap level 0 and 1 alignment for SI and CIK

Signed-off-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
main
Michel Dänzer 2013-11-14 16:40:30 +01:00 committed by Marek Olšák
parent 0c3fd8708f
commit ce8af45425
1 changed files with 12 additions and 10 deletions

View File

@ -1541,6 +1541,7 @@ static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
uint64_t offset, unsigned start_level) uint64_t offset, unsigned start_level)
{ {
uint32_t xalign, yalign, zalign, slice_align; uint32_t xalign, yalign, zalign, slice_align;
unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
unsigned i; unsigned i;
/* compute alignment */ /* compute alignment */
@ -1552,11 +1553,11 @@ static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
xalign = MAX2((bpe == 1) ? 64 : 32, xalign); xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
} }
if (!start_level) { if (start_level <= 1) {
surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes); surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
if (offset) { if (offset) {
offset = ALIGN(offset, surf->bo_alignment); offset = ALIGN(offset, alignment);
} }
} }
@ -1567,7 +1568,7 @@ static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
/* level0 and first mipmap need to have alignment */ /* level0 and first mipmap need to have alignment */
offset = surf->bo_size; offset = surf->bo_size;
if ((i == 0)) { if ((i == 0)) {
offset = ALIGN(offset, surf->bo_alignment); offset = ALIGN(offset, alignment);
} }
if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) { if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
if (surf->level == level) { if (surf->level == level) {
@ -1609,6 +1610,7 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
uint64_t offset, uint64_t offset,
unsigned start_level) unsigned start_level)
{ {
uint64_t aligned_offset = offset;
unsigned tilew, tileh, tileb; unsigned tilew, tileh, tileb;
unsigned mtilew, mtileh, mtileb; unsigned mtilew, mtileh, mtileb;
unsigned slice_pt; unsigned slice_pt;
@ -1632,19 +1634,19 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
/* macro tile bytes */ /* macro tile bytes */
mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb; mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
if (!start_level) { if (start_level <= 1) {
unsigned alignment = MAX2(256, mtileb); unsigned alignment = MAX2(256, mtileb);
surf->bo_alignment = MAX2(surf->bo_alignment, alignment); surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
if (offset) { if (aligned_offset) {
offset = ALIGN(offset, alignment); aligned_offset = ALIGN(aligned_offset, alignment);
} }
} }
/* build mipmap tree */ /* build mipmap tree */
for (i = start_level; i <= surf->last_level; i++) { for (i = start_level; i <= surf->last_level; i++) {
level[i].mode = RADEON_SURF_MODE_2D; level[i].mode = RADEON_SURF_MODE_2D;
si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, offset); si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
if (level[i].mode == RADEON_SURF_MODE_1D) { if (level[i].mode == RADEON_SURF_MODE_1D) {
switch (tile_mode) { switch (tile_mode) {
case SI_TILE_MODE_COLOR_2D_8BPP: case SI_TILE_MODE_COLOR_2D_8BPP:
@ -1669,9 +1671,9 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i); return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
} }
/* level0 and first mipmap need to have alignment */ /* level0 and first mipmap need to have alignment */
offset = surf->bo_size; aligned_offset = surf->bo_size;
if ((i == 0)) { if ((i == 0)) {
offset = ALIGN(offset, surf->bo_alignment); aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
} }
if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) { if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
if (surf->level == level) { if (surf->level == level) {