radv: implement setting a custom pitch to any multiple of 256B on gfx10.3+
authorMarek Olšák <marek.olsak@amd.com>
Mon, 15 May 2023 06:53:18 +0000 (02:53 -0400)
committerMarge Bot <emma+marge@anholt.net>
Thu, 1 Jun 2023 18:46:20 +0000 (18:46 +0000)
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23015>

src/amd/vulkan/radv_device.c
src/amd/vulkan/radv_image.c

index a2b26ce..5420a55 100644 (file)
@@ -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);
    }
index cc6ae6e..aadbd72 100644 (file)
@@ -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;