mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 15:38:09 +02:00
Enable VK_EXT_image_drm_format_modifier on Linux guests
Do not force linear tiling for WSI in vkCreateImage. Allow creating WSI images from DMABUFs with DRM format modifiers. If the extension is supported by host, forward VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT to vkGetPhysicalDeviceImageFormatProperties2 and vkCreateImage. If it's not supported, attempt to support DRM_FORMAT_MOD_LINEAR by mapping it to VK_TILING_LINEAR. Reviewed-by: Aaron Ruby <aruby@blackberry.com> Acked-by: Yonggang Luo <luoyonggang@gmail.com> Acked-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27246>
This commit is contained in:
parent
048037727f
commit
8847a50a04
2 changed files with 62 additions and 13 deletions
|
|
@ -46,6 +46,10 @@
|
|||
#include "vk_struct_id.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <drm_fourcc.h>
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__) || defined(__linux__) || defined(__APPLE__)
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
|
@ -1893,6 +1897,9 @@ VkResult ResourceTracker::on_vkEnumerateDeviceExtensionProperties(
|
|||
#if !defined(VK_USE_PLATFORM_ANDROID_KHR) && defined(__linux__)
|
||||
filteredExts.push_back(VkExtensionProperties{"VK_KHR_external_memory_fd", 1});
|
||||
filteredExts.push_back(VkExtensionProperties{"VK_EXT_external_memory_dma_buf", 1});
|
||||
// In case the host doesn't support format modifiers, they are emulated
|
||||
// on guest side.
|
||||
filteredExts.push_back(VkExtensionProperties{"VK_EXT_image_drm_format_modifier", 1});
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -4224,28 +4231,40 @@ VkResult ResourceTracker::on_vkCreateImage(void* context, VkResult, VkDevice dev
|
|||
|
||||
#if defined(LINUX_GUEST_BUILD)
|
||||
bool isDmaBufImage = false;
|
||||
VkImageDrmFormatModifierExplicitCreateInfoEXT localDrmFormatModifierInfo;
|
||||
|
||||
if (extImgCiPtr &&
|
||||
(extImgCiPtr->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)) {
|
||||
const wsi_image_create_info* wsiImageCi =
|
||||
vk_find_struct<wsi_image_create_info>(pCreateInfo);
|
||||
if (wsiImageCi) {
|
||||
if (!wsiImageCi->scanout) {
|
||||
mesa_logd(
|
||||
"gfxstream only supports native DRM image scanout path for Linux WSI "
|
||||
"(wsi_image_create_info::scanout)");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
if (wsiImageCi && wsiImageCi->scanout) {
|
||||
// Linux WSI creates swapchain images with VK_IMAGE_CREATE_ALIAS_BIT. Vulkan spec
|
||||
// states: "If the pNext chain includes a VkExternalMemoryImageCreateInfo or
|
||||
// VkExternalMemoryImageCreateInfoNV structure whose handleTypes member is not 0, it is
|
||||
// as if VK_IMAGE_CREATE_ALIAS_BIT is set." To avoid flag mismatches on host driver,
|
||||
// remove the VK_IMAGE_CREATE_ALIAS_BIT here.
|
||||
localCreateInfo.flags &= ~VK_IMAGE_CREATE_ALIAS_BIT;
|
||||
// TODO (b/326956485): DRM format modifiers to support client/compositor awareness
|
||||
// For now, override WSI images to use linear tiling, as compositor will default to
|
||||
// DRM_FORMAT_MOD_LINEAR.
|
||||
localCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
}
|
||||
|
||||
const VkImageDrmFormatModifierExplicitCreateInfoEXT* drmFmtMod =
|
||||
vk_find_struct<VkImageDrmFormatModifierExplicitCreateInfoEXT>(pCreateInfo);
|
||||
if (drmFmtMod) {
|
||||
if (getHostDeviceExtensionIndex(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME) !=
|
||||
-1) {
|
||||
// host supports DRM format modifiers => forward the struct
|
||||
localDrmFormatModifierInfo = vk_make_orphan_copy(*drmFmtMod);
|
||||
vk_append_struct(&structChainIter, &localDrmFormatModifierInfo);
|
||||
} else {
|
||||
// host doesn't support DRM format modifiers, try emulating
|
||||
if (drmFmtMod->drmFormatModifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
mesa_logd("emulating DRM_FORMAT_MOD_LINEAR with VK_IMAGE_TILING_LINEAR");
|
||||
localCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
} else {
|
||||
return VK_ERROR_VALIDATION_FAILED_EXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isDmaBufImage = true;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -6680,6 +6699,8 @@ VkResult ResourceTracker::on_vkGetPhysicalDeviceImageFormatProperties2_common(
|
|||
VkEncoder* enc = (VkEncoder*)context;
|
||||
(void)input_result;
|
||||
|
||||
VkPhysicalDeviceImageFormatInfo2 localImageFormatInfo = *pImageFormatInfo;
|
||||
|
||||
uint32_t supportedHandleType = 0;
|
||||
VkExternalImageFormatProperties* ext_img_properties =
|
||||
vk_find_struct<VkExternalImageFormatProperties>(pImageFormatProperties);
|
||||
|
|
@ -6723,14 +6744,37 @@ VkResult ResourceTracker::on_vkGetPhysicalDeviceImageFormatProperties2_common(
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef LINUX_GUEST_BUILD
|
||||
VkImageDrmFormatModifierExplicitCreateInfoEXT localDrmFormatModifierInfo;
|
||||
|
||||
const VkPhysicalDeviceImageDrmFormatModifierInfoEXT* drmFmtMod =
|
||||
vk_find_struct<VkPhysicalDeviceImageDrmFormatModifierInfoEXT>(pImageFormatInfo);
|
||||
if (drmFmtMod) {
|
||||
if (getHostDeviceExtensionIndex(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME) != -1) {
|
||||
// Host supports DRM format modifiers => leave the input unchanged.
|
||||
} else {
|
||||
// Host doesn't support DRM format modifiers, try emulating.
|
||||
if (drmFmtMod->drmFormatModifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
mesa_logd("emulating DRM_FORMAT_MOD_LINEAR with VK_IMAGE_TILING_LINEAR");
|
||||
localImageFormatInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
pImageFormatInfo = &localImageFormatInfo;
|
||||
// Leave drmFormatMod in the input; it should be ignored when
|
||||
// tiling is not VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT
|
||||
} else {
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // LINUX_GUEST_BUILD
|
||||
|
||||
VkResult hostRes;
|
||||
|
||||
if (isKhr) {
|
||||
hostRes = enc->vkGetPhysicalDeviceImageFormatProperties2KHR(
|
||||
physicalDevice, pImageFormatInfo, pImageFormatProperties, true /* do lock */);
|
||||
physicalDevice, &localImageFormatInfo, pImageFormatProperties, true /* do lock */);
|
||||
} else {
|
||||
hostRes = enc->vkGetPhysicalDeviceImageFormatProperties2(
|
||||
physicalDevice, pImageFormatInfo, pImageFormatProperties, true /* do lock */);
|
||||
physicalDevice, &localImageFormatInfo, pImageFormatProperties, true /* do lock */);
|
||||
}
|
||||
|
||||
if (hostRes != VK_SUCCESS) return hostRes;
|
||||
|
|
|
|||
|
|
@ -135,6 +135,11 @@ REGISTER_VK_STRUCT_ID(VkTimelineSemaphoreSubmitInfo,
|
|||
#if defined(LINUX_GUEST_BUILD)
|
||||
REGISTER_VK_STRUCT_ID(wsi_image_create_info, VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA);
|
||||
#endif
|
||||
REGISTER_VK_STRUCT_ID(VkImageDrmFormatModifierExplicitCreateInfoEXT,
|
||||
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
|
||||
REGISTER_VK_STRUCT_ID(VkFormatProperties2, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
|
||||
REGISTER_VK_STRUCT_ID(VkPhysicalDeviceImageDrmFormatModifierInfoEXT,
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
|
||||
|
||||
#undef REGISTER_VK_STRUCT_ID
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue