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 <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6940>
This commit is contained in:
Jonathan Marek 2020-09-30 11:33:46 -04:00 committed by Marge Bot
parent f624692a57
commit b2c719308c
4 changed files with 105 additions and 75 deletions

View File

@ -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),

View File

@ -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;

View File

@ -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);

View File

@ -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;