From 3f5723a23fc492a1dfedb798ae40c5a73da23654 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 15 May 2023 01:12:55 -0400 Subject: [PATCH] ac/surface: validate overridden pitch for all chips Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/amd/common/ac_surface.c | 97 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c index 03e667b..e449b3e 100644 --- a/src/amd/common/ac_surface.c +++ b/src/amd/common/ac_surface.c @@ -2944,35 +2944,89 @@ void ac_surface_compute_umd_metadata(const struct radeon_info *info, struct rade } } -static uint32_t ac_surface_get_gfx9_pitch_align(struct radeon_surf *surf) +static uint32_t ac_surface_get_pitch_align(const struct radeon_info *info, + const struct radeon_surf *surf) { - if (surf->u.gfx9.swizzle_mode == ADDR_SW_LINEAR) - return 256 / surf->bpe; + if (surf->is_linear) { + switch (info->gfx_level) { + case GFX6: + case GFX7: + case GFX8: + return MAX2(8, 64 / surf->bpe); - if (surf->u.gfx9.resource_type == RADEON_RESOURCE_3D) - return 1; /* TODO */ + case GFX9: + case GFX10: + case GFX10_3: + case GFX11: + return 256 / surf->bpe; - unsigned bpe_shift = util_logbase2(surf->bpe) / 2; - switch(surf->u.gfx9.swizzle_mode & ~3) { - case ADDR_SW_LINEAR: /* 256B block. */ - return 16 >> bpe_shift; - case ADDR_SW_4KB_Z: - case ADDR_SW_4KB_Z_X: - return 64 >> bpe_shift; - case ADDR_SW_64KB_Z: - case ADDR_SW_64KB_Z_T: - case ADDR_SW_64KB_Z_X: - return 256 >> bpe_shift; - case ADDR_SW_256KB_Z_X: - return 512 >> bpe_shift; - default: - return 1; /* TODO */ + default: + unreachable("unhandled gfx_level"); + } + } + + if (info->gfx_level >= GFX9) { + if (surf->u.gfx9.resource_type == RADEON_RESOURCE_3D) + return 1u << 31; /* reject 3D textures by returning an impossible alignment */ + + unsigned bpe_log2 = util_logbase2(surf->bpe); + unsigned block_size_log2; + + switch((surf->u.gfx9.swizzle_mode & ~3) + 3) { + case ADDR_SW_256B_R: + block_size_log2 = 8; + break; + case ADDR_SW_4KB_R: + case ADDR_SW_4KB_R_X: + block_size_log2 = 12; + break; + case ADDR_SW_64KB_R: + case ADDR_SW_64KB_R_T: + case ADDR_SW_64KB_R_X: + block_size_log2 = 16; + break; + case ADDR_SW_256KB_R_X: + block_size_log2 = 18; + break; + default: + unreachable("unhandled swizzle mode"); + } + + if (info->gfx_level >= GFX10) { + return 1 << (((block_size_log2 - bpe_log2) + 1) / 2); + } else { + static unsigned block_256B_width[] = {16, 16, 8, 8, 4}; + return block_256B_width[bpe_log2] << ((block_size_log2 - 8) / 2); + } + } else { + unsigned mode; + + if ((surf->flags & RADEON_SURF_Z_OR_SBUFFER) == RADEON_SURF_SBUFFER) + mode = surf->u.legacy.zs.stencil_level[0].mode; + else + mode = surf->u.legacy.level[0].mode; + + /* Note that display usage requires an alignment of 32 pixels (see AdjustPitchAlignment), + * which is not checked here. + */ + switch (mode) { + case RADEON_SURF_MODE_1D: + return 8; + case RADEON_SURF_MODE_2D: + return 8 * surf->u.legacy.bankw * surf->u.legacy.mtilea * + ac_pipe_config_to_num_pipes(surf->u.legacy.pipe_config); + default: + unreachable("unhandled surf mode"); + } } } bool ac_surface_override_offset_stride(const struct radeon_info *info, struct radeon_surf *surf, unsigned num_mipmap_levels, uint64_t offset, unsigned pitch) { + if ((ac_surface_get_pitch_align(info, surf) - 1) & pitch) + return false; + /* * GFX10 and newer don't support custom strides. Furthermore, for * multiple miplevels or compression data we'd really need to rerun @@ -2988,9 +3042,6 @@ bool ac_surface_override_offset_stride(const struct radeon_info *info, struct ra if (surf->u.gfx9.surf_pitch != pitch && require_equal_pitch) return false; - if ((ac_surface_get_gfx9_pitch_align(surf) - 1) & pitch) - return false; - if (pitch != surf->u.gfx9.surf_pitch) { unsigned slices = surf->surf_size / surf->u.gfx9.surf_slice_size; -- 2.7.4