Mesa (master): radv: Deal with Android external formats.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Oct 10 17:03:31 UTC 2019


Module: Mesa
Branch: master
Commit: adad61239c43f4a06b8a97bf9c31b7d2a8148d6b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=adad61239c43f4a06b8a97bf9c31b7d2a8148d6b

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Tue Sep 24 16:33:39 2019 +0200

radv: Deal with Android external formats.

To abstract things a bit, this adds a helper function in radv_android.c.
However, this means we have to link in radv_android.c on non-android as
well, which means some scaffolding changes.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>

---

 src/amd/vulkan/meson.build    |  2 +-
 src/amd/vulkan/radv_android.c | 20 +++++++++++++
 src/amd/vulkan/radv_formats.c | 24 ++++++++--------
 src/amd/vulkan/radv_image.c   | 66 +++++++++++++++++++++++++------------------
 src/amd/vulkan/radv_private.h |  3 ++
 5 files changed, 76 insertions(+), 39 deletions(-)

diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build
index 7fa945a346f..4243f66055f 100644
--- a/src/amd/vulkan/meson.build
+++ b/src/amd/vulkan/meson.build
@@ -67,6 +67,7 @@ libradv_files = files(
   'winsys/amdgpu/radv_amdgpu_winsys.c',
   'winsys/amdgpu/radv_amdgpu_winsys.h',
   'winsys/amdgpu/radv_amdgpu_winsys_public.h',
+  'radv_android.c',
   'radv_cmd_buffer.c',
   'radv_cs.h',
   'radv_debug.c',
@@ -143,7 +144,6 @@ if with_platform_android
   radv_flags += [
     '-DVK_USE_PLATFORM_ANDROID_KHR'
   ]
-  libradv_files += files('radv_android.c')
 endif
 
 libvulkan_radeon = shared_library(
diff --git a/src/amd/vulkan/radv_android.c b/src/amd/vulkan/radv_android.c
index f3cbe2d4bd2..7833e6d8922 100644
--- a/src/amd/vulkan/radv_android.c
+++ b/src/amd/vulkan/radv_android.c
@@ -21,6 +21,7 @@
  * IN THE SOFTWARE.
  */
 
+#ifdef ANDROID
 #include <hardware/gralloc.h>
 #include <hardware/hardware.h>
 #include <hardware/hwvulkan.h>
@@ -28,10 +29,13 @@
 #include <vulkan/vk_android_native_buffer.h>
 #include <vulkan/vk_icd.h>
 #include <libsync.h>
+#endif
 
 #include "radv_private.h"
 #include "vk_util.h"
 
+#ifdef ANDROID
+
 static int radv_hal_open(const struct hw_module_t* mod, const char* id, struct hw_device_t** dev);
 static int radv_hal_close(struct hw_device_t *dev);
 
@@ -374,6 +378,7 @@ radv_QueueSignalReleaseImageANDROID(
 	}
 	return VK_SUCCESS;
 }
+#endif
 
 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
 
@@ -579,3 +584,18 @@ radv_GetMemoryAndroidHardwareBufferANDROID(
 }
 
 #endif
+
+VkFormat
+radv_select_android_external_format(const void *next, VkFormat default_format)
+{
+#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
+	const VkExternalFormatANDROID *android_format =
+		vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
+
+	if (android_format && android_format->externalFormat) {
+		return (VkFormat)android_format->externalFormat;
+	}
+#endif
+
+	return default_format;
+}
diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c
index c6e01d66fa6..0a84b064b21 100644
--- a/src/amd/vulkan/radv_formats.c
+++ b/src/amd/vulkan/radv_formats.c
@@ -1104,6 +1104,7 @@ void radv_GetPhysicalDeviceFormatProperties2(
 
 static VkResult radv_get_image_format_properties(struct radv_physical_device *physical_device,
 						 const VkPhysicalDeviceImageFormatInfo2 *info,
+						 VkFormat format,
 						 VkImageFormatProperties *pImageFormatProperties)
 
 {
@@ -1113,10 +1114,10 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
 	uint32_t maxMipLevels;
 	uint32_t maxArraySize;
 	VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
-	const struct vk_format_description *desc = vk_format_description(info->format);
+	const struct vk_format_description *desc = vk_format_description(format);
 	enum chip_class chip_class = physical_device->rad_info.chip_class;
 
-	radv_physical_device_get_format_properties(physical_device, info->format,
+	radv_physical_device_get_format_properties(physical_device, format,
 						   &format_props);
 	if (info->tiling == VK_IMAGE_TILING_LINEAR) {
 		format_feature_flags = format_props.linearTilingFeatures;
@@ -1129,7 +1130,7 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
 	if (format_feature_flags == 0)
 		goto unsupported;
 
-	if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(info->format))
+	if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(format))
 		goto unsupported;
 
 	switch (info->type) {
@@ -1179,9 +1180,9 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
 	}
 
 	if (info->tiling == VK_IMAGE_TILING_LINEAR &&
-	    (info->format == VK_FORMAT_R32G32B32_SFLOAT ||
-	     info->format == VK_FORMAT_R32G32B32_SINT ||
-	     info->format == VK_FORMAT_R32G32B32_UINT)) {
+	    (format == VK_FORMAT_R32G32B32_SFLOAT ||
+	     format == VK_FORMAT_R32G32B32_SINT ||
+	     format == VK_FORMAT_R32G32B32_UINT)) {
 		/* R32G32B32 is a weird format and the driver currently only
 		 * supports the barely minimum.
 		 * TODO: Implement more if we really need to.
@@ -1196,8 +1197,8 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
 	/* We can't create 3d compressed 128bpp images that can be rendered to on GFX9 */
 	if (physical_device->rad_info.chip_class >= GFX9 &&
 	    info->type == VK_IMAGE_TYPE_3D &&
-	    vk_format_get_blocksizebits(info->format) == 128 &&
-	    vk_format_is_compressed(info->format) &&
+	    vk_format_get_blocksizebits(format) == 128 &&
+	    vk_format_is_compressed(format) &&
 	    (info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) &&
 	    ((info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) ||
 	     (info->usage & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))) {
@@ -1293,7 +1294,7 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties(
 		.flags = createFlags,
 	};
 
-	return radv_get_image_format_properties(physical_device, &info,
+	return radv_get_image_format_properties(physical_device, &info, format,
 						pImageFormatProperties);
 }
 
@@ -1348,8 +1349,9 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2(
 	struct VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
 	VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
 	VkResult result;
+	VkFormat format = radv_select_android_external_format(base_info->pNext, base_info->format);
 
-	result = radv_get_image_format_properties(physical_device, base_info,
+	result = radv_get_image_format_properties(physical_device, base_info, format,
 						&base_props->imageFormatProperties);
 	if (result != VK_SUCCESS)
 		return result;
@@ -1416,7 +1418,7 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2(
 	}
 
 	if (ycbcr_props) {
-		ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(base_info->format);
+		ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(format);
 	}
 
 	return VK_SUCCESS;
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 9df7dd4ae81..316f883f676 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -36,15 +36,16 @@
 
 static unsigned
 radv_choose_tiling(struct radv_device *device,
-		   const VkImageCreateInfo *pCreateInfo)
+		   const VkImageCreateInfo *pCreateInfo,
+		   VkFormat format)
 {
 	if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
 		assert(pCreateInfo->samples <= 1);
 		return RADEON_SURF_MODE_LINEAR_ALIGNED;
 	}
 
-	if (!vk_format_is_compressed(pCreateInfo->format) &&
-	    !vk_format_is_depth_or_stencil(pCreateInfo->format)
+	if (!vk_format_is_compressed(format) &&
+	    !vk_format_is_depth_or_stencil(format)
 	    && device->physical_device->rad_info.chip_class <= GFX8) {
 		/* this causes hangs in some VK CTS tests on GFX9. */
 		/* Textures with a very small height are recommended to be linear. */
@@ -64,7 +65,8 @@ radv_choose_tiling(struct radv_device *device,
 
 static bool
 radv_use_tc_compat_htile_for_image(struct radv_device *device,
-				   const VkImageCreateInfo *pCreateInfo)
+				   const VkImageCreateInfo *pCreateInfo,
+				   VkFormat format)
 {
 	/* TC-compat HTILE is only available for GFX8+. */
 	if (device->physical_device->rad_info.chip_class < GFX8)
@@ -84,8 +86,8 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device,
 	 * tests - disable for now. On GFX10 D32_SFLOAT is affected as well.
 	 */
 	if (pCreateInfo->samples >= 2 &&
-	    (pCreateInfo->format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
-	     (pCreateInfo->format == VK_FORMAT_D32_SFLOAT &&
+	    (format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
+	     (format == VK_FORMAT_D32_SFLOAT &&
 	      device->physical_device->rad_info.chip_class == GFX10)))
 		return false;
 
@@ -93,9 +95,9 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device,
 	 * supports 32-bit. Though, it's possible to enable TC-compat for
 	 * 16-bit depth surfaces if no Z planes are compressed.
 	 */
-	if (pCreateInfo->format != VK_FORMAT_D32_SFLOAT_S8_UINT &&
-	    pCreateInfo->format != VK_FORMAT_D32_SFLOAT &&
-	    pCreateInfo->format != VK_FORMAT_D16_UNORM)
+	if (format != VK_FORMAT_D32_SFLOAT_S8_UINT &&
+	    format != VK_FORMAT_D32_SFLOAT &&
+	    format != VK_FORMAT_D16_UNORM)
 		return false;
 
 	if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
@@ -113,7 +115,7 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device,
 				if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
 					continue;
 
-				if (pCreateInfo->format != format_list->pViewFormats[i])
+				if (format != format_list->pViewFormats[i])
 					return false;
 			}
 		} else {
@@ -143,7 +145,8 @@ radv_surface_has_scanout(struct radv_device *device, const struct radv_image_cre
 static bool
 radv_use_dcc_for_image(struct radv_device *device,
 		       const struct radv_image *image,
-		       const VkImageCreateInfo *pCreateInfo)
+		       const VkImageCreateInfo *pCreateInfo,
+		       VkFormat format)
 {
 	bool dcc_compatible_formats;
 	bool blendable;
@@ -166,8 +169,8 @@ radv_use_dcc_for_image(struct radv_device *device,
 	if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
 		return false;
 
-	if (vk_format_is_subsampled(pCreateInfo->format) ||
-	    vk_format_get_plane_count(pCreateInfo->format) > 1)
+	if (vk_format_is_subsampled(format) ||
+	    vk_format_get_plane_count(format) > 1)
 		return false;
 
 	/* TODO: Enable DCC for mipmaps on GFX9+. */
@@ -189,7 +192,7 @@ radv_use_dcc_for_image(struct radv_device *device,
 
 	/* Determine if the formats are DCC compatible. */
 	dcc_compatible_formats =
-		radv_is_colorbuffer_format_supported(pCreateInfo->format,
+		radv_is_colorbuffer_format_supported(format,
 						     &blendable);
 
 	if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
@@ -206,7 +209,7 @@ radv_use_dcc_for_image(struct radv_device *device,
 				if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
 					continue;
 
-				if (!radv_dcc_formats_compatible(pCreateInfo->format,
+				if (!radv_dcc_formats_compatible(format,
 				                                 format_list->pViewFormats[i]))
 					dcc_compatible_formats = false;
 			}
@@ -389,10 +392,11 @@ radv_init_surface(struct radv_device *device,
 		  const struct radv_image *image,
 		  struct radeon_surf *surface,
 		  unsigned plane_id,
-		  const VkImageCreateInfo *pCreateInfo)
+		  const VkImageCreateInfo *pCreateInfo,
+		  VkFormat image_format)
 {
-	unsigned array_mode = radv_choose_tiling(device, pCreateInfo);
-	VkFormat format = vk_format_get_plane_format(pCreateInfo->format, plane_id);
+	unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format);
+	VkFormat format = vk_format_get_plane_format(image_format, plane_id);
 	const struct vk_format_description *desc = vk_format_description(format);
 	bool is_depth, is_stencil;
 
@@ -432,7 +436,7 @@ radv_init_surface(struct radv_device *device,
 
 	if (is_depth) {
 		surface->flags |= RADEON_SURF_ZBUFFER;
-		if (radv_use_tc_compat_htile_for_image(device, pCreateInfo))
+		if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format))
 			surface->flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
 	}
 
@@ -441,13 +445,13 @@ radv_init_surface(struct radv_device *device,
 
 	if (device->physical_device->rad_info.chip_class >= GFX9 &&
 	    pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
-	    vk_format_get_blocksizebits(pCreateInfo->format) == 128 &&
-	    vk_format_is_compressed(pCreateInfo->format))
+	    vk_format_get_blocksizebits(image_format) == 128 &&
+	    vk_format_is_compressed(image_format))
 		surface->flags |= RADEON_SURF_NO_RENDER_TARGET;
 
 	surface->flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE;
 
-	if (!radv_use_dcc_for_image(device, image, pCreateInfo))
+	if (!radv_use_dcc_for_image(device, image, pCreateInfo, image_format))
 		surface->flags |= RADEON_SURF_DISABLE_DCC;
 
 	return 0;
@@ -1439,9 +1443,11 @@ radv_image_create(VkDevice _device,
 	RADV_FROM_HANDLE(radv_device, device, _device);
 	const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
 	struct radv_image *image = NULL;
+	VkFormat format = radv_select_android_external_format(pCreateInfo->pNext,
+	                                                      pCreateInfo->format);
 	assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
 
-	const unsigned plane_count = vk_format_get_plane_count(pCreateInfo->format);
+	const unsigned plane_count = vk_format_get_plane_count(format);
 	const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count;
 
 	radv_assert(pCreateInfo->mipLevels > 0);
@@ -1464,9 +1470,9 @@ radv_image_create(VkDevice _device,
 	image->info.storage_samples = pCreateInfo->samples;
 	image->info.array_size = pCreateInfo->arrayLayers;
 	image->info.levels = pCreateInfo->mipLevels;
-	image->info.num_channels = vk_format_get_nr_components(pCreateInfo->format);
+	image->info.num_channels = vk_format_get_nr_components(format);
 
-	image->vk_format = pCreateInfo->format;
+	image->vk_format = format;
 	image->tiling = pCreateInfo->tiling;
 	image->usage = pCreateInfo->usage;
 	image->flags = pCreateInfo->flags;
@@ -1484,12 +1490,12 @@ 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) && !image->shareable) {
+	if (!vk_format_is_depth_or_stencil(format) && !image->shareable) {
 		image->info.surf_index = &device->image_mrt_offset_counter;
 	}
 
 	for (unsigned plane = 0; plane < image->plane_count; ++plane) {
-		radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo);
+		radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo, format);
 	}
 
 	ASSERTED VkResult result = radv_image_create_layout(device, *create_info, image);
@@ -1632,8 +1638,14 @@ radv_image_view_init(struct radv_image_view *iview,
 	iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask);
 	iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
 	iview->multiple_planes = vk_format_get_plane_count(image->vk_format) > 1 && iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT;
+
 	iview->vk_format = pCreateInfo->format;
 
+	/* If the image has an Android external format, pCreateInfo->format will be
+	 * VK_FORMAT_UNDEFINED. */
+	if (iview->vk_format == VK_FORMAT_UNDEFINED)
+		iview->vk_format = image->vk_format;
+
 	if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
 		iview->vk_format = vk_format_stencil_only(iview->vk_format);
 	} else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 6ad055aacdc..f0a5fc19604 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1928,6 +1928,9 @@ uint64_t
 radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create,
                              const VkImageUsageFlags vk_usage);
 
+VkFormat
+radv_select_android_external_format(const void *next, VkFormat default_format);
+
 
 struct radv_image_view_extra_create_info {
 	bool disable_compression;




More information about the mesa-commit mailing list