radv: Use bo metadata for imported image tiling on Android.
authorBas Nieuwenhuizen <basni@chromium.org>
Mon, 13 May 2019 12:09:55 +0000 (14:09 +0200)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Tue, 4 Jun 2019 18:32:45 +0000 (18:32 +0000)
This way we handle linear images etc. correctly.

Acked-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/amd/vulkan/radv_android.c
src/amd/vulkan/radv_image.c
src/amd/vulkan/radv_private.h

index a0a35e23e7673b2cb6c54addf274a50d86c1d06b..ba4716801e7e6bb7bc503620de858d90f1ef6797 100644 (file)
@@ -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);
 
index b9793d1a28645060e073adca8859d8a55b0d4e3d..afb426fc3c588b4c02be54446decf62590f036e4 100644 (file)
@@ -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;
        }
 
index 828edb565400fec638fbfa527012797608f4c7df..9af8fb3b6db21129e1b965a98a2710bf5d6acc7b 100644 (file)
@@ -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,