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>
diff --git a/src/freedreno/vulkan/tu_extensions.py b/src/freedreno/vulkan/tu_extensions.py
index 1bbb107..4c34bdc 100644
--- a/src/freedreno/vulkan/tu_extensions.py
+++ b/src/freedreno/vulkan/tu_extensions.py
@@ -70,7 +70,7 @@
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 1b3597f..f320878 100644
--- a/src/freedreno/vulkan/tu_formats.c
+++ b/src/freedreno/vulkan/tu_formats.c
@@ -451,6 +451,17 @@
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 @@
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 @@
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 0db7fec..4679c8b 100644
--- a/src/freedreno/vulkan/tu_image.c
+++ b/src/freedreno/vulkan/tu_image.c
@@ -446,6 +446,53 @@
}
}
+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 @@
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 @@
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 12e3173..6fbd485 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1380,6 +1380,9 @@
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;