From 3f7ddaf28163a23de218990908725387f03205c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 15 May 2023 02:53:18 -0400 Subject: [PATCH] radv: implement setting a custom pitch to any multiple of 256B on gfx10.3+ Reviewed-by: Pierre-Eric Pelloux-Prayer Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/amd/vulkan/radv_device.c | 18 ++++++++++++++++++ src/amd/vulkan/radv_image.c | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index a2b26ceaaa7..5420a5526cd 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -1674,6 +1674,24 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff S_028C74_MIP0_DEPTH(mip0_depth) | S_028C74_RESOURCE_TYPE(surf->u.gfx9.resource_type); } + /* GFX10.3+ can set a custom pitch for 1D and 2D non-array, but it must be a multiple + * of 256B. Only set it for 2D linear for multi-GPU interop. + * + * We set the pitch in MIP0_WIDTH. + */ + if (device->physical_device->rad_info.gfx_level && + iview->image->vk.image_type == VK_IMAGE_TYPE_2D && + iview->image->vk.array_layers == 1 && + plane->surface.is_linear) { + assert((plane->surface.u.gfx9.surf_pitch * plane->surface.bpe) % 256 == 0); + + width = plane->surface.u.gfx9.surf_pitch; + + /* Subsampled images have the pitch in the units of blocks. */ + if (plane->surface.blk_w == 2) + width *= 2; + } + cb->cb_color_attrib2 = S_028C68_MIP0_WIDTH(width - 1) | S_028C68_MIP0_HEIGHT(height - 1) | S_028C68_MAX_MIP(max_mip); } diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index cc6ae6ef37d..aadbd72ca29 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -862,6 +862,29 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image *im } } + /* GFX10.3+ can set a custom pitch for 1D and 2D non-array, but it must be a multiple + * of 256B. Only set it for 2D linear for multi-GPU interop. + * + * If an imported image is used with VK_IMAGE_VIEW_TYPE_2D_ARRAY, it may hang due to VM faults + * because DEPTH means pitch with 2D, but it means depth with 2D array. + */ + if (device->physical_device->rad_info.gfx_level >= GFX10_3 && + image->vk.image_type == VK_IMAGE_TYPE_2D && + plane->surface.is_linear && + util_is_power_of_two_nonzero(plane->surface.bpe) && + G_00A00C_TYPE(state[3]) == V_008F1C_SQ_RSRC_IMG_2D) { + assert((plane->surface.u.gfx9.surf_pitch * plane->surface.bpe) % 256 == 0); + unsigned pitch = plane->surface.u.gfx9.surf_pitch; + + /* Subsampled images have the pitch in the units of blocks. */ + if (plane->surface.blk_w == 2) + pitch *= 2; + + state[4] &= C_00A010_DEPTH & C_00A010_PITCH_MSB; + state[4] |= S_00A010_DEPTH(pitch - 1) | /* DEPTH contains low bits of PITCH. */ + S_00A010_PITCH_MSB((pitch - 1) >> 13); + } + if (gfx_level >= GFX10) { state[3] &= C_00A00C_SW_MODE;