From 34e0d5c698bde814d0a12cb3c15e363b915670f2 Mon Sep 17 00:00:00 2001 From: Zan Dobersek Date: Fri, 20 Mar 2026 14:44:42 +0100 Subject: [PATCH] tu/a8xx: fix tu_desc_set_ubwc() to avoid unwanted bitfield override Current implementation of tu_desc_set_ubwc() for A8XX will override bitfields in the upper half of A8XX_TEX_MEMOBJ[5], leading to incorrect behavior. Fix this by using pkt_field_set() to correctly set the relevant descriptor fields. Similarly, tu_desc_get_ubwc() is changed to use pkt_field_get() to retrieve relevant field data from which it forms the returned address. Fixes CTS tests on a8xx: dEQP-VK.api.copy_and_blit.*.resolve_image.copy_with_regions_before_resolving.* Signed-off-by: Zan Dobersek Part-of: --- src/freedreno/vulkan/tu_descriptor_set.h | 25 ++++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/freedreno/vulkan/tu_descriptor_set.h b/src/freedreno/vulkan/tu_descriptor_set.h index d553ffa621d..aa70658fe5d 100644 --- a/src/freedreno/vulkan/tu_descriptor_set.h +++ b/src/freedreno/vulkan/tu_descriptor_set.h @@ -468,17 +468,17 @@ template static inline uint64_t tu_desc_get_ubwc(uint32_t *desc) { + uint64_t addr = 0; + if ((CHIP >= A8XX) && (desc[4] & A8XX_TEX_MEMOBJ_4_FLAG)) { - uint64_t addr = desc[4] & ~0x1f; - addr |= (uint64_t)(desc[5] & 0xffff) << 32; - return addr; + addr = pkt_field_get(A8XX_TEX_MEMOBJ_4_FLAG_LO, desc[4]) << 6; + addr |= (uint64_t)pkt_field_get(A8XX_TEX_MEMOBJ_5_FLAG_HI, desc[5]) << 32; } else if ((CHIP <= A7XX) && (desc[3] & A6XX_TEX_MEMOBJ_3_FLAG)) { - uint64_t addr = desc[7]; - addr |= (uint64_t)(desc[8] & 0xffff) << 32; - return addr; - } else { - return 0; + addr = pkt_field_get(A6XX_TEX_MEMOBJ_7_FLAG_LO, desc[7]) << 5; + addr |= (uint64_t)pkt_field_get(A6XX_TEX_MEMOBJ_8_FLAG_HI, desc[8]) << 32; } + + return addr; } template @@ -486,18 +486,17 @@ static inline void tu_desc_set_ubwc(uint32_t *desc, uint64_t addr) { if (CHIP >= A8XX) { - assert(!(addr & 0x1f)); if (addr) { - desc[4] = (desc[4] & 0x1f) | addr; - desc[5] = (desc[5] & 0xffff) | addr >> 32; + desc[4] = pkt_field_set(A8XX_TEX_MEMOBJ_4_FLAG_LO, desc[4], addr); + desc[5] = pkt_field_set(A8XX_TEX_MEMOBJ_5_FLAG_HI, desc[5], addr >> 32); desc[4] |= A8XX_TEX_MEMOBJ_4_FLAG; } else { desc[4] &= ~A8XX_TEX_MEMOBJ_4_FLAG; } } else { if (addr) { - desc[7] = addr; - desc[8] = (desc[8] & 0xffff) | addr >> 32; + desc[7] = pkt_field_set(A6XX_TEX_MEMOBJ_7_FLAG_LO, desc[7], addr); + desc[8] = pkt_field_set(A6XX_TEX_MEMOBJ_8_FLAG_HI, desc[8], addr >> 32); desc[3] |= A6XX_TEX_MEMOBJ_3_FLAG; } else { desc[3] &= ~A6XX_TEX_MEMOBJ_3_FLAG;