From 9701cb1034a683e9e14222d5e8a9e464053573ca Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 13 May 2019 14:09:55 +0200 Subject: [PATCH] radv: Use bo metadata for imported image tiling on Android. This way we handle linear images etc. correctly. Acked-by: Samuel Pitoiset --- src/amd/vulkan/radv_android.c | 13 ++------ src/amd/vulkan/radv_image.c | 61 ++++++++++++++++++++++++++++++++--- src/amd/vulkan/radv_private.h | 1 + 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/amd/vulkan/radv_android.c b/src/amd/vulkan/radv_android.c index a0a35e23e76..ba4716801e7 100644 --- a/src/amd/vulkan/radv_android.c +++ b/src/amd/vulkan/radv_android.c @@ -160,14 +160,6 @@ radv_image_from_gralloc(VkDevice device_h, struct radeon_bo_metadata md; device->ws->buffer_get_metadata(radv_device_memory_from_handle(memory_h)->bo, &md); - bool is_scanout; - if (device->physical_device->rad_info.chip_class >= GFX9) { - /* Copied from radeonsi, but is hacky so should be cleaned up. */ - is_scanout = md.u.gfx9.swizzle_mode == 0 || md.u.gfx9.swizzle_mode % 4 == 2; - } else { - is_scanout = md.u.legacy.scanout; - } - VkImageCreateInfo updated_base_info = *base_info; VkExternalMemoryImageCreateInfo external_memory_info = { @@ -181,8 +173,9 @@ radv_image_from_gralloc(VkDevice device_h, result = radv_image_create(device_h, &(struct radv_image_create_info) { .vk_info = &updated_base_info, - .scanout = is_scanout, - .no_metadata_planes = true}, + .no_metadata_planes = true, + .bo_metadata = &md, + }, alloc, &image_h); diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index b9793d1a286..afb426fc3c5 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -127,6 +127,22 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device, return true; } +static bool +radv_surface_has_scanout(struct radv_device *device, const struct radv_image_create_info *info) +{ + if (info->scanout) + return true; + + if (!info->bo_metadata) + return false; + + if (device->physical_device->rad_info.chip_class >= GFX9) { + return info->bo_metadata->u.gfx9.swizzle_mode == 0 || info->bo_metadata->u.gfx9.swizzle_mode % 4 == 2; + } else { + return info->bo_metadata->u.legacy.scanout; + } +} + static bool radv_use_dcc_for_image(struct radv_device *device, const struct radv_image *image, @@ -164,7 +180,7 @@ radv_use_dcc_for_image(struct radv_device *device, if (pCreateInfo->mipLevels > 1 || pCreateInfo->arrayLayers > 1) return false; - if (create_info->scanout) + if (radv_surface_has_scanout(device, create_info)) return false; /* FIXME: DCC for MSAA with 4x and 8x samples doesn't work yet, while @@ -206,6 +222,37 @@ radv_use_dcc_for_image(struct radv_device *device, return true; } +static void +radv_prefill_surface_from_metadata(struct radv_device *device, + struct radeon_surf *surface, + const struct radv_image_create_info *create_info) +{ + const struct radeon_bo_metadata *md = create_info->bo_metadata; + if (device->physical_device->rad_info.chip_class >= GFX9) { + if (md->u.gfx9.swizzle_mode > 0) + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); + else + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); + + surface->u.gfx9.surf.swizzle_mode = md->u.gfx9.swizzle_mode; + } else { + surface->u.legacy.pipe_config = md->u.legacy.pipe_config; + surface->u.legacy.bankw = md->u.legacy.bankw; + surface->u.legacy.bankh = md->u.legacy.bankh; + surface->u.legacy.tile_split = md->u.legacy.tile_split; + surface->u.legacy.mtilea = md->u.legacy.mtilea; + surface->u.legacy.num_banks = md->u.legacy.num_banks; + + if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED) + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); + else if (md->u.legacy.microtile == RADEON_LAYOUT_TILED) + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); + else + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); + + } +} + static int radv_init_surface(struct radv_device *device, const struct radv_image *image, @@ -230,7 +277,11 @@ radv_init_surface(struct radv_device *device, if (surface->bpe == 3) { surface->bpe = 4; } - surface->flags = RADEON_SURF_SET(array_mode, MODE); + if (create_info->bo_metadata) { + radv_prefill_surface_from_metadata(device, surface, create_info); + } else { + surface->flags = RADEON_SURF_SET(array_mode, MODE); + } switch (pCreateInfo->imageType){ case VK_IMAGE_TYPE_1D: @@ -272,8 +323,9 @@ radv_init_surface(struct radv_device *device, if (!radv_use_dcc_for_image(device, image, create_info, pCreateInfo)) surface->flags |= RADEON_SURF_DISABLE_DCC; - if (create_info->scanout) + if (radv_surface_has_scanout(device, create_info)) surface->flags |= RADEON_SURF_SCANOUT; + return 0; } @@ -1057,7 +1109,8 @@ radv_image_create(VkDevice _device, image->shareable = vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO) != NULL; - if (!vk_format_is_depth_or_stencil(pCreateInfo->format) && !create_info->scanout && !image->shareable) { + if (!vk_format_is_depth_or_stencil(pCreateInfo->format) && + !radv_surface_has_scanout(device, create_info) && !image->shareable) { image->info.surf_index = &device->image_mrt_offset_counter; } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 828edb56540..9af8fb3b6db 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1733,6 +1733,7 @@ struct radv_image_create_info { const VkImageCreateInfo *vk_info; bool scanout; bool no_metadata_planes; + const struct radeon_bo_metadata *bo_metadata; }; VkResult radv_image_create(VkDevice _device, -- 2.30.2