From 4f31e27297ff43e40bd05b7a676bfa4d8a378619 Mon Sep 17 00:00:00 2001 From: heitbaum Date: Fri, 16 Apr 2021 07:12:14 +0000 Subject: [PATCH] mesa: fix for AMD Kabini vaapi H264 hw decode stopped working reference: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4605 After mesa upgrade 20.3.5 -> 21.0.2, AMD Kabini vaapi H264 hw. decode stopped working System information Describe the issue After mesa sources upgrade from 20.3.5 -> 21.0.2 & recompile, vaapi H264 decode stopped working. Recompiling back to 20.3.5 brings vaapi decode back. Mesa sources change is single change causing vaapi decode to stop working. fix from warpme - Piotr Oniszczuk --- .../mesa/patches/fix_for_ticket4605.patch | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 packages/graphics/mesa/patches/fix_for_ticket4605.patch diff --git a/packages/graphics/mesa/patches/fix_for_ticket4605.patch b/packages/graphics/mesa/patches/fix_for_ticket4605.patch new file mode 100644 index 0000000000..c87682d881 --- /dev/null +++ b/packages/graphics/mesa/patches/fix_for_ticket4605.patch @@ -0,0 +1,149 @@ +diff -Naur mesa-mesa-21.0.2-old/src/amd/common/ac_surface.c mesa-mesa-21.0.2-new/src/amd/common/ac_surface.c +--- mesa-mesa-21.0.2-old/src/amd/common/ac_surface.c 2021-04-07 18:35:30.000000000 +0200 ++++ mesa-mesa-21.0.2-new/src/amd/common/ac_surface.c 2021-04-11 11:35:23.939998177 +0200 +@@ -2502,10 +2502,6 @@ + { + surf->dcc_offset = 0; + surf->display_dcc_offset = 0; +- if (!surf->htile_offset && !surf->fmask_offset && !surf->cmask_offset) { +- surf->total_size = surf->surf_size; +- surf->alignment = surf->surf_alignment; +- } + } + + static unsigned eg_tile_split(unsigned tile_split) +@@ -2804,69 +2800,21 @@ + } + } + +-static uint32_t ac_surface_get_gfx9_pitch_align(struct radeon_surf *surf) +-{ +- if (surf->u.gfx9.surf.swizzle_mode == ADDR_SW_LINEAR) +- return 256 / surf->bpe; +- +- if (surf->u.gfx9.resource_type == RADEON_RESOURCE_3D) +- return 1; /* TODO */ +- +- unsigned bpe_shift = util_logbase2(surf->bpe) / 2; +- switch(surf->u.gfx9.surf.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_VAR_Z_X: +- default: +- return 1; /* TODO */ +- } +-} +- +-bool ac_surface_override_offset_stride(const struct radeon_info *info, struct radeon_surf *surf, ++void ac_surface_override_offset_stride(const struct radeon_info *info, struct radeon_surf *surf, + unsigned num_mipmap_levels, uint64_t offset, unsigned pitch) + { +- /* +- * GFX10 and newer don't support custom strides. Furthermore, for +- * multiple miplevels or compression data we'd really need to rerun +- * addrlib to update all the fields in the surface. That, however, is a +- * software limitation and could be relaxed later. +- */ +- bool require_equal_pitch = surf->surf_size != surf->total_size || +- num_mipmap_levels != 1 || +- info->chip_class >= GFX10; +- + if (info->chip_class >= GFX9) { + if (pitch) { +- 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; +- +- surf->u.gfx9.surf_pitch = pitch; ++ surf->u.gfx9.surf_pitch = pitch; ++ if (num_mipmap_levels == 1) + surf->u.gfx9.surf.epitch = pitch - 1; +- surf->u.gfx9.surf_slice_size = (uint64_t)pitch * surf->u.gfx9.surf_height * surf->bpe; +- surf->total_size = surf->surf_size = surf->u.gfx9.surf_slice_size * slices; +- } ++ surf->u.gfx9.surf_slice_size = (uint64_t)pitch * surf->u.gfx9.surf_height * surf->bpe; + } + surf->u.gfx9.surf_offset = offset; + if (surf->u.gfx9.stencil_offset) + surf->u.gfx9.stencil_offset += offset; + } else { + if (pitch) { +- if (surf->u.legacy.level[0].nblk_x != pitch && require_equal_pitch) +- return false; +- + surf->u.legacy.level[0].nblk_x = pitch; + surf->u.legacy.level[0].slice_size_dw = + ((uint64_t)pitch * surf->u.legacy.level[0].nblk_y * surf->bpe) / 4; +@@ -2878,10 +2826,6 @@ + } + } + +- if (offset & (surf->alignment - 1) || +- offset >= UINT64_MAX - surf->total_size) +- return false; +- + if (surf->htile_offset) + surf->htile_offset += offset; + if (surf->fmask_offset) +@@ -2892,7 +2836,6 @@ + surf->dcc_offset += offset; + if (surf->display_dcc_offset) + surf->display_dcc_offset += offset; +- return true; + } + + unsigned ac_surface_get_nplanes(const struct radeon_surf *surf) +diff -Naur mesa-mesa-21.0.2-old/src/amd/common/ac_surface.h mesa-mesa-21.0.2-new/src/amd/common/ac_surface.h +--- mesa-mesa-21.0.2-old/src/amd/common/ac_surface.h 2021-04-07 18:35:30.000000000 +0200 ++++ mesa-mesa-21.0.2-new/src/amd/common/ac_surface.h 2021-04-11 11:35:23.939998177 +0200 +@@ -336,7 +336,7 @@ + unsigned num_mipmap_levels, uint32_t desc[8], + unsigned *size_metadata, uint32_t metadata[64]); + +-bool ac_surface_override_offset_stride(const struct radeon_info *info, struct radeon_surf *surf, ++void ac_surface_override_offset_stride(const struct radeon_info *info, struct radeon_surf *surf, + unsigned num_mipmap_levels, uint64_t offset, unsigned pitch); + + struct ac_modifier_options { +diff -Naur mesa-mesa-21.0.2-old/src/gallium/drivers/radeonsi/si_texture.c mesa-mesa-21.0.2-new/src/gallium/drivers/radeonsi/si_texture.c +--- mesa-mesa-21.0.2-old/src/gallium/drivers/radeonsi/si_texture.c 2021-04-07 18:35:30.000000000 +0200 ++++ mesa-mesa-21.0.2-new/src/gallium/drivers/radeonsi/si_texture.c 2021-04-11 11:35:23.939998177 +0200 +@@ -941,10 +941,9 @@ + */ + tex->ps_draw_ratio = 0; + +- if (!ac_surface_override_offset_stride(&sscreen->info, &tex->surface, ++ ac_surface_override_offset_stride(&sscreen->info, &tex->surface, + tex->buffer.b.b.last_level + 1, +- offset, pitch_in_bytes / tex->surface.bpe)) +- goto error; ++ offset, pitch_in_bytes / tex->surface.bpe); + + if (tex->is_depth) { + if (sscreen->info.chip_class >= GFX9) { +@@ -1577,13 +1576,6 @@ + si_texture_reference(&tex, NULL); + return NULL; + } +- +- if (ac_surface_get_plane_offset(sscreen->info.chip_class, &tex->surface, 0, 0) + +- tex->surface.total_size > buf->size || +- buf->alignment < tex->surface.alignment) { +- si_texture_reference(&tex, NULL); +- return NULL; +- } + + /* Displayable DCC requires an explicit flush. */ + if (dedicated && offset == 0 && !(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&