venus: reject multi-plane modifiers for tiled wsi images
Force the use of single-plane modifiers for tiled wsi images as long as Venus is integrated with Virgl, which does not support non-format compression metadata planes (e.g. Intel's CCS or AMD's DCC modifiers). Signed-off-by: Ryan Neph <ryanneph@google.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26240>
This commit is contained in:
@@ -2010,6 +2010,48 @@ vn_physical_device_fix_image_format_info(
|
|||||||
return &local_info->format;
|
return &local_info->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
vn_modifier_plane_count(struct vn_physical_device *physical_dev,
|
||||||
|
VkFormat format,
|
||||||
|
uint64_t modifier)
|
||||||
|
{
|
||||||
|
VkPhysicalDevice physical_dev_handle =
|
||||||
|
vn_physical_device_to_handle(physical_dev);
|
||||||
|
|
||||||
|
VkDrmFormatModifierPropertiesListEXT modifier_list = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
|
||||||
|
.pDrmFormatModifierProperties = NULL,
|
||||||
|
};
|
||||||
|
VkFormatProperties2 format_props = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
|
||||||
|
.pNext = &modifier_list,
|
||||||
|
};
|
||||||
|
vn_GetPhysicalDeviceFormatProperties2(physical_dev_handle, format,
|
||||||
|
&format_props);
|
||||||
|
|
||||||
|
STACK_ARRAY(VkDrmFormatModifierPropertiesEXT, modifier_props,
|
||||||
|
modifier_list.drmFormatModifierCount);
|
||||||
|
if (!modifier_props)
|
||||||
|
return 0;
|
||||||
|
modifier_list.pDrmFormatModifierProperties = modifier_props;
|
||||||
|
|
||||||
|
vn_GetPhysicalDeviceFormatProperties2(physical_dev_handle, format,
|
||||||
|
&format_props);
|
||||||
|
|
||||||
|
uint32_t plane_count = 0;
|
||||||
|
for (uint32_t i = 0; i < modifier_list.drmFormatModifierCount; i++) {
|
||||||
|
const struct VkDrmFormatModifierPropertiesEXT *props =
|
||||||
|
&modifier_list.pDrmFormatModifierProperties[i];
|
||||||
|
if (modifier == props->drmFormatModifier) {
|
||||||
|
plane_count = props->drmFormatModifierPlaneCount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STACK_ARRAY_FINISH(modifier_props);
|
||||||
|
return plane_count;
|
||||||
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
vn_GetPhysicalDeviceImageFormatProperties2(
|
vn_GetPhysicalDeviceImageFormatProperties2(
|
||||||
VkPhysicalDevice physicalDevice,
|
VkPhysicalDevice physicalDevice,
|
||||||
@@ -2025,16 +2067,15 @@ vn_GetPhysicalDeviceImageFormatProperties2(
|
|||||||
|
|
||||||
const struct wsi_image_create_info *wsi_info = vk_find_struct_const(
|
const struct wsi_image_create_info *wsi_info = vk_find_struct_const(
|
||||||
pImageFormatInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
|
pImageFormatInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
|
||||||
|
|
||||||
/* force common wsi into choosing DRM_FORMAT_MOD_LINEAR or else fall back
|
|
||||||
* to the legacy path, for which Venus also forces LINEAR for wsi images.
|
|
||||||
*/
|
|
||||||
if (VN_PERF(NO_TILED_WSI_IMAGE)) {
|
|
||||||
const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *modifier_info =
|
const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *modifier_info =
|
||||||
vk_find_struct_const(
|
vk_find_struct_const(
|
||||||
pImageFormatInfo->pNext,
|
pImageFormatInfo->pNext,
|
||||||
PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
|
PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
|
||||||
|
|
||||||
|
/* force common wsi into choosing DRM_FORMAT_MOD_LINEAR or else fall back
|
||||||
|
* to the legacy path, for which Venus also forces LINEAR for wsi images.
|
||||||
|
*/
|
||||||
|
if (VN_PERF(NO_TILED_WSI_IMAGE)) {
|
||||||
if (wsi_info && modifier_info &&
|
if (wsi_info && modifier_info &&
|
||||||
modifier_info->drmFormatModifier != DRM_FORMAT_MOD_LINEAR) {
|
modifier_info->drmFormatModifier != DRM_FORMAT_MOD_LINEAR) {
|
||||||
if (VN_DEBUG(WSI)) {
|
if (VN_DEBUG(WSI)) {
|
||||||
@@ -2047,6 +2088,39 @@ vn_GetPhysicalDeviceImageFormatProperties2(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Integration with Xwayland (using virgl-backed gbm) may only use
|
||||||
|
* modifiers for which `memory_plane_count == format_plane_count` with the
|
||||||
|
* distinction defined in the spec for VkDrmFormatModifierPropertiesEXT.
|
||||||
|
*
|
||||||
|
* The spec also states that:
|
||||||
|
* If an image is non-linear, then the partition of the image’s memory
|
||||||
|
* into memory planes is implementation-specific and may be unrelated to
|
||||||
|
* the partition of the image’s content into format planes.
|
||||||
|
*
|
||||||
|
* A modifier like I915_FORMAT_MOD_Y_TILED_CCS with an extra CCS
|
||||||
|
* metadata-only _memory_ plane is not supported by virgl. In general,
|
||||||
|
* since the partition of format planes into memory planes (even when their
|
||||||
|
* counts match) cannot be guarantably known, the safest option is to limit
|
||||||
|
* both plane counts to 1 while virgl may be involved.
|
||||||
|
*/
|
||||||
|
if (wsi_info && modifier_info &&
|
||||||
|
modifier_info->drmFormatModifier != DRM_FORMAT_MOD_LINEAR) {
|
||||||
|
const uint32_t plane_count =
|
||||||
|
vn_modifier_plane_count(physical_dev, pImageFormatInfo->format,
|
||||||
|
modifier_info->drmFormatModifier);
|
||||||
|
if (plane_count != 1) {
|
||||||
|
if (VN_DEBUG(WSI)) {
|
||||||
|
vn_log(physical_dev->instance,
|
||||||
|
"rejecting multi-plane (%u) modifier %" PRIu64
|
||||||
|
" for wsi image with format %u",
|
||||||
|
plane_count, modifier_info->drmFormatModifier,
|
||||||
|
pImageFormatInfo->format);
|
||||||
|
}
|
||||||
|
return vn_error(physical_dev->instance,
|
||||||
|
VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const VkPhysicalDeviceExternalImageFormatInfo *external_info =
|
const VkPhysicalDeviceExternalImageFormatInfo *external_info =
|
||||||
vk_find_struct_const(pImageFormatInfo->pNext,
|
vk_find_struct_const(pImageFormatInfo->pNext,
|
||||||
PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);
|
PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);
|
||||||
|
Reference in New Issue
Block a user