From b2c719308c5d691b84d3ac7dfca9f9704b5f74bd Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 30 Sep 2020 11:33:46 -0400 Subject: [PATCH] turnip: enable VK_EXT_image_drm_format_modifier Add missing GetPhysicalDeviceImageFormatProperties2 logic for the extension and enable it. Also stop exposing optimal tiling for formats which are linear only, to simplify dealing with those. Passes dEQP-VK.drm_format_modifiers.* Signed-off-by: Jonathan Marek Part-of: --- src/freedreno/vulkan/tu_extensions.py | 2 +- src/freedreno/vulkan/tu_formats.c | 70 ++++++++++++----- src/freedreno/vulkan/tu_image.c | 105 +++++++++++++------------- src/freedreno/vulkan/tu_private.h | 3 + 4 files changed, 105 insertions(+), 75 deletions(-) diff --git a/src/freedreno/vulkan/tu_extensions.py b/src/freedreno/vulkan/tu_extensions.py index 1bbb107c430..4c34bdc8c4f 100644 --- a/src/freedreno/vulkan/tu_extensions.py +++ b/src/freedreno/vulkan/tu_extensions.py @@ -70,7 +70,7 @@ EXTENSIONS = [ Extension('VK_KHR_external_memory', 1, True), Extension('VK_KHR_external_memory_fd', 1, True), Extension('VK_EXT_external_memory_dma_buf', 1, True), - Extension('VK_EXT_image_drm_format_modifier', 1, False), + Extension('VK_EXT_image_drm_format_modifier', 1, True), Extension('VK_EXT_sample_locations', 1, 'device->gpu_id == 650'), Extension('VK_EXT_sampler_filter_minmax', 1, True), Extension('VK_EXT_transform_feedback', 1, True), diff --git a/src/freedreno/vulkan/tu_formats.c b/src/freedreno/vulkan/tu_formats.c index 1b3597f6802..f3208780fe2 100644 --- a/src/freedreno/vulkan/tu_formats.c +++ b/src/freedreno/vulkan/tu_formats.c @@ -451,6 +451,17 @@ tu_physical_device_get_format_properties( if (tu6_pipe2depth(format) != (enum a6xx_depth_format)~0) optimal |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + /* no tiling for special UBWC formats + * TODO: NV12 can be UBWC but has a special UBWC format for accessing the Y plane aspect + * for 3plane, tiling/UBWC might be supported, but the blob doesn't use tiling + */ + if (format == VK_FORMAT_G8B8G8R8_422_UNORM || + format == VK_FORMAT_B8G8R8G8_422_UNORM || + format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM || + format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) { + optimal = 0; + } + /* D32_SFLOAT_S8_UINT is tiled as two images, so no linear format * blob enables some linear features, but its not useful, so don't bother. */ @@ -480,15 +491,20 @@ tu_GetPhysicalDeviceFormatProperties2( VK_OUTARRAY_MAKE(out, list->pDrmFormatModifierProperties, &list->drmFormatModifierCount); - vk_outarray_append(&out, mod_props) { - mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; - mod_props->drmFormatModifierPlaneCount = 1; + if (pFormatProperties->formatProperties.linearTilingFeatures) { + vk_outarray_append(&out, mod_props) { + mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; + mod_props->drmFormatModifierPlaneCount = 1; + } } - /* TODO: any cases where this should be disabled? */ - vk_outarray_append(&out, mod_props) { - mod_props->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; - mod_props->drmFormatModifierPlaneCount = 1; + /* note: ubwc_possible() argument values to be ignored except for format */ + if (pFormatProperties->formatProperties.optimalTilingFeatures && + ubwc_possible(format, VK_IMAGE_TYPE_2D, 0, false)) { + vk_outarray_append(&out, mod_props) { + mod_props->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + mod_props->drmFormatModifierPlaneCount = 1; + } } } } @@ -515,20 +531,34 @@ tu_get_image_format_properties( format_feature_flags = format_props.linearTilingFeatures; break; - case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: - /* The only difference between optimal and linear is currently whether - * depth/stencil attachments are allowed on depth/stencil formats. - * There's no reason to allow importing depth/stencil textures, so just - * disallow it and then this annoying edge case goes away. - * - * TODO: If anyone cares, we could enable this by looking at the - * modifier and checking if it's LINEAR or not. - */ - if (vk_format_is_depth_or_stencil(info->format)) - goto unsupported; + case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: { + const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_info = + vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT); - assert(format_props.optimalTilingFeatures == format_props.linearTilingFeatures); - /* fallthrough */ + switch (drm_info->drmFormatModifier) { + case DRM_FORMAT_MOD_QCOM_COMPRESSED: + /* falling back to linear/non-UBWC isn't possible with explicit modifier */ + + /* formats which don't support tiling */ + if (!format_props.optimalTilingFeatures) + return VK_ERROR_FORMAT_NOT_SUPPORTED; + + /* for mutable formats, its very unlikely to be possible to use UBWC */ + if (info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) + return VK_ERROR_FORMAT_NOT_SUPPORTED; + + if (!ubwc_possible(info->format, info->type, info->usage, physical_device->limited_z24s8)) + return VK_ERROR_FORMAT_NOT_SUPPORTED; + + format_feature_flags = format_props.optimalTilingFeatures; + break; + case DRM_FORMAT_MOD_LINEAR: + format_feature_flags = format_props.linearTilingFeatures; + break; + default: + return VK_ERROR_FORMAT_NOT_SUPPORTED; + } + } break; case VK_IMAGE_TILING_OPTIMAL: format_feature_flags = format_props.optimalTilingFeatures; break; diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c index 0db7fec18e4..4679c8be929 100644 --- a/src/freedreno/vulkan/tu_image.c +++ b/src/freedreno/vulkan/tu_image.c @@ -446,6 +446,53 @@ tu_image_view_init(struct tu_image_view *iview, } } +bool +ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage, bool limited_z24s8) +{ + /* no UBWC with compressed formats, E5B9G9R9, S8_UINT + * (S8_UINT because separate stencil doesn't have UBWC-enable bit) + */ + if (vk_format_is_compressed(format) || + format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || + format == VK_FORMAT_S8_UINT) + return false; + + if (type == VK_IMAGE_TYPE_3D) { + tu_finishme("UBWC with 3D textures"); + return false; + } + + /* Disable UBWC for storage images. + * + * The closed GL driver skips UBWC for storage images (and additionally + * uses linear for writeonly images). We seem to have image tiling working + * in freedreno in general, so turnip matches that. freedreno also enables + * UBWC on images, but it's not really tested due to the lack of + * UBWC-enabled mipmaps in freedreno currently. Just match the closed GL + * behavior of no UBWC. + */ + if (usage & VK_IMAGE_USAGE_STORAGE_BIT) + return false; + + /* Disable UBWC for D24S8 on A630 in some cases + * + * VK_IMAGE_ASPECT_STENCIL_BIT image view requires to be able to sample + * from the stencil component as UINT, however no format allows this + * on a630 (the special FMT6_Z24_UINT_S8_UINT format is missing) + * + * It must be sampled as FMT6_8_8_8_8_UINT, which is not UBWC-compatible + * + * Additionally, the special AS_R8G8B8A8 format is broken without UBWC, + * so we have to fallback to 8_8_8_8_UNORM when UBWC is disabled + */ + if (limited_z24s8 && + format == VK_FORMAT_D24_UNORM_S8_UINT && + (usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) + return false; + + return true; +} + VkResult tu_CreateImage(VkDevice _device, const VkImageCreateInfo *pCreateInfo, @@ -510,16 +557,8 @@ tu_CreateImage(VkDevice _device, bool ubwc_enabled = !(device->physical_device->instance->debug_flags & TU_DEBUG_NOUBWC); - /* use linear tiling if requested and for special ycbcr formats - * TODO: NV12 can be UBWC but has a special UBWC format for accessing the Y plane aspect - * for 3plane, tiling/UBWC might be supported, but the blob doesn't use tiling - */ - if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR || - modifier == DRM_FORMAT_MOD_LINEAR || - image->vk_format == VK_FORMAT_G8B8G8R8_422_UNORM || - image->vk_format == VK_FORMAT_B8G8R8G8_422_UNORM || - image->vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM || - image->vk_format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) { + /* use linear tiling if requested */ + if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR || modifier == DRM_FORMAT_MOD_LINEAR) { tile_mode = TILE6_LINEAR; ubwc_enabled = false; } @@ -555,52 +594,10 @@ tu_CreateImage(VkDevice _device, ubwc_enabled = false; } - /* don't use UBWC with compressed formats */ - if (vk_format_is_compressed(image->vk_format)) + if (!ubwc_possible(image->vk_format, pCreateInfo->imageType, pCreateInfo->usage, + device->physical_device->limited_z24s8)) ubwc_enabled = false; - /* UBWC can't be used with E5B9G9R9 */ - if (image->vk_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) - ubwc_enabled = false; - - /* separate stencil doesn't have a UBWC enable bit */ - if (image->vk_format == VK_FORMAT_S8_UINT) - ubwc_enabled = false; - - if (pCreateInfo->extent.depth > 1) { - tu_finishme("UBWC with 3D textures"); - ubwc_enabled = false; - } - - /* Disable UBWC for storage images. - * - * The closed GL driver skips UBWC for storage images (and additionally - * uses linear for writeonly images). We seem to have image tiling working - * in freedreno in general, so turnip matches that. freedreno also enables - * UBWC on images, but it's not really tested due to the lack of - * UBWC-enabled mipmaps in freedreno currently. Just match the closed GL - * behavior of no UBWC. - */ - if (pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) - ubwc_enabled = false; - - /* Disable UBWC for D24S8 on A630 in some cases - * - * VK_IMAGE_ASPECT_STENCIL_BIT image view requires to be able to sample - * from the stencil component as UINT, however no format allows this - * on a630 (the special FMT6_Z24_UINT_S8_UINT format is missing) - * - * It must be sampled as FMT6_8_8_8_8_UINT, which is not UBWC-compatible - * - * Additionally, the special AS_R8G8B8A8 format is broken without UBWC, - * so we have to fallback to 8_8_8_8_UNORM when UBWC is disabled - */ - if (device->physical_device->limited_z24s8 && - image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT && - (pCreateInfo->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) { - ubwc_enabled = false; - } - /* expect UBWC enabled if we asked for it */ assert(modifier != DRM_FORMAT_MOD_QCOM_COMPRESSED || ubwc_enabled); diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 12e317337dd..6fbd4857216 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -1380,6 +1380,9 @@ tu_image_view_init(struct tu_image_view *iview, const VkImageViewCreateInfo *pCreateInfo, bool limited_z24s8); +bool +ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage, bool limited_z24s8); + struct tu_buffer_view { struct vk_object_base base;