From e03ec6a9dc4def4598186b7cf02a9c25465cf8d3 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig <alyssa@rosenzweig.io> Date: Tue, 11 Mar 2025 12:18:14 -0400 Subject: [PATCH] hk: fix unaligned copies Fixes regression in Deus Ex: Human Revolution (DX11) via DXVK reported by James Calligeros. Pending CTS coverage: https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/5640 Only the alignment check here is load bearing but I clarified the logic while at it. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> --- src/asahi/vulkan/hk_cmd_meta.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/asahi/vulkan/hk_cmd_meta.c b/src/asahi/vulkan/hk_cmd_meta.c index 96e91f37117ef..c9bb25ea1f86b 100644 --- a/src/asahi/vulkan/hk_cmd_meta.c +++ b/src/asahi/vulkan/hk_cmd_meta.c @@ -1382,13 +1382,23 @@ hk_meta_resolve_rendering(struct hk_cmd_buffer *cmd, static void hk_cmd_copy(struct hk_cmd_buffer *cmd, uint64_t dst, uint64_t src, size_t size) { - if (size / 16) { - libagx_copy_uint4(cmd, agx_1d(size / 16), AGX_BARRIER_ALL, dst, src); + /* Use vectorized copies for as much of the buffer as possible. This requires + * that dst, src, and size are all properly aligned. Failing to check for + * alignment on the buffers causes subtle and hard-to-debug issues! + */ + if (size >= 16 && (dst & 0xf) == 0 && (src & 0xf) == 0) { + unsigned uint4s = size / 16; + unsigned bytes = uint4s * 16; + + libagx_copy_uint4(cmd, agx_1d(uint4s), AGX_BARRIER_ALL, dst, src); + + dst += bytes; + src += bytes; + size -= bytes; } - if (size % 16) { - libagx_copy_uchar(cmd, agx_1d(size % 16), AGX_BARRIER_ALL, - dst + (size & ~15), src + (size & ~15)); + if (size) { + libagx_copy_uchar(cmd, agx_1d(size), AGX_BARRIER_ALL, dst, src); } } -- GitLab