+static VkResult
+radv_patch_image_dimensions(struct radv_device *device,
+ struct radv_image *image,
+ const struct radv_image_create_info *create_info,
+ struct ac_surf_info *image_info)
+{
+ unsigned width = image->info.width;
+ unsigned height = image->info.height;
+
+ /*
+ * minigbm sometimes allocates bigger images which is going to result in
+ * weird strides and other properties. Lets be lenient where possible and
+ * fail it on GFX10 (as we cannot cope there).
+ *
+ * Example hack: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1457777/
+ */
+ if (create_info->bo_metadata &&
+ radv_is_valid_opaque_metadata(device, create_info->bo_metadata)) {
+ const struct radeon_bo_metadata *md = create_info->bo_metadata;
+
+ if (device->physical_device->rad_info.chip_class >= GFX10) {
+ width = G_00A004_WIDTH_LO(md->metadata[3]) +
+ (G_00A008_WIDTH_HI(md->metadata[4]) << 2) + 1;
+ height = S_00A008_HEIGHT(md->metadata[4]) + 1;
+ } else {
+ width = G_008F18_WIDTH(md->metadata[4]) + 1;
+ height = G_008F18_HEIGHT(md->metadata[4]) + 1;
+ }
+ }
+
+ if (image->info.width == width && image->info.height == height)
+ return VK_SUCCESS;
+
+ if (width < image->info.width || height < image->info.height) {
+ fprintf(stderr,
+ "The imported image has smaller dimensions than the internal\n"
+ "dimensions. Using it is going to fail badly, so we reject\n"
+ "this import.\n"
+ "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
+ image->info.width, image->info.height, width, height);
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ } else if (device->physical_device->rad_info.chip_class >= GFX10) {
+ fprintf(stderr,
+ "Tried to import an image with inconsistent width on GFX10.\n"
+ "As GFX10 has no separate stride fields we cannot cope with\n"
+ "an inconsistency in width and will fail this import.\n"
+ "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
+ image->info.width, image->info.height, width, height);
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ } else {
+ fprintf(stderr,
+ "Tried to import an image with inconsistent width on pre-GFX10.\n"
+ "As GFX10 has no separate stride fields we cannot cope with\n"
+ "an inconsistency and would fail on GFX10.\n"
+ "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
+ image->info.width, image->info.height, width, height);
+ }
+ image_info->width = width;
+ image_info->height = height;
+
+ return VK_SUCCESS;
+}
+
+static VkResult
+radv_patch_image_from_extra_info(struct radv_device *device,
+ struct radv_image *image,
+ const struct radv_image_create_info *create_info,
+ struct ac_surf_info *image_info)
+{
+ VkResult result = radv_patch_image_dimensions(device, image, create_info, image_info);
+ if (result != VK_SUCCESS)
+ return result;
+
+ for (unsigned plane = 0; plane < image->plane_count; ++plane) {
+ if (create_info->bo_metadata) {
+ radv_patch_surface_from_metadata(device, &image->planes[plane].surface,
+ create_info->bo_metadata);
+ }
+
+ if (radv_surface_has_scanout(device, create_info)) {
+ image->planes[plane].surface.flags |= RADEON_SURF_SCANOUT;
+ image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC;
+
+ image->info.surf_index = NULL;
+ }
+ }
+ return VK_SUCCESS;
+}
+