LibGfx: Preserve imported Linux DMABUF handles

Keep the Linux DMABUF handle alongside the bitmap wrapper when imported
shared images reach the UI process. This lets consumers import the same
GPU backing store directly instead of only reading it through the mapped
bitmap.

Also require exported Vulkan shared images to be sampleable, since the
Qt Vulkan presentation path needs to sample compositor backing stores.
This commit is contained in:
Andreas Kling 2026-06-01 11:38:38 +02:00 committed by Andreas Kling
parent b4b0233ba1
commit f619caf621
3 changed files with 22 additions and 4 deletions

View file

@ -55,6 +55,14 @@ SharedImageBuffer::SharedImageBuffer(NonnullRefPtr<Bitmap> bitmap)
: m_bitmap(move(bitmap))
{
}
# ifdef USE_VULKAN_DMABUF_IMAGES
SharedImageBuffer::SharedImageBuffer(NonnullRefPtr<Bitmap> bitmap, LinuxDmaBufHandle&& dmabuf)
: m_linux_dmabuf_handle(move(dmabuf))
, m_bitmap(move(bitmap))
{
}
# endif
#endif
SharedImageBuffer SharedImageBuffer::create(IntSize size)
@ -81,7 +89,8 @@ SharedImageBuffer SharedImageBuffer::import_from_shared_image(SharedImage shared
},
[](LinuxDmaBufHandle& dmabuf) -> SharedImageBuffer {
# ifdef USE_VULKAN_DMABUF_IMAGES
return SharedImageBuffer(create_bitmap_from_linux_dmabuf(dmabuf));
auto bitmap = create_bitmap_from_linux_dmabuf(dmabuf);
return SharedImageBuffer(move(bitmap), move(dmabuf));
# else
(void)dmabuf;
VERIFY_NOT_REACHED();

View file

@ -8,6 +8,7 @@
#include <AK/Noncopyable.h>
#include <AK/NonnullRefPtr.h>
#include <AK/Optional.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/SharedImage.h>
@ -34,6 +35,8 @@ public:
#ifdef AK_OS_MACOS
Core::IOSurfaceHandle const& iosurface_handle() const { return m_iosurface_handle; }
#elif defined(USE_VULKAN_DMABUF_IMAGES)
LinuxDmaBufHandle const* linux_dmabuf_handle() const { return m_linux_dmabuf_handle.has_value() ? &m_linux_dmabuf_handle.value() : nullptr; }
#endif
private:
@ -42,6 +45,10 @@ private:
Core::IOSurfaceHandle m_iosurface_handle;
#else
explicit SharedImageBuffer(NonnullRefPtr<Bitmap>);
# ifdef USE_VULKAN_DMABUF_IMAGES
SharedImageBuffer(NonnullRefPtr<Bitmap>, LinuxDmaBufHandle&&);
Optional<LinuxDmaBufHandle> m_linux_dmabuf_handle;
# endif
#endif
NonnullRefPtr<Bitmap> m_bitmap;
};

View file

@ -110,10 +110,12 @@ ErrorOr<NonnullRefPtr<VulkanImage>> create_shared_vulkan_image(VulkanContext con
format_mod_props_list.pDrmFormatModifierProperties = format_mod_props.data();
vkGetPhysicalDeviceFormatProperties2(context.physical_device, format, &format_props);
// populate a list of all format modifiers that are both renderable and accepted by the caller
// populate a list of all format modifiers that are both renderable, sampleable,
// and accepted by the caller
Vector<uint64_t> format_mods;
for (VkDrmFormatModifierPropertiesEXT const& props : format_mod_props) {
if ((props.drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) && (props.drmFormatModifierPlaneCount == 1)) {
VkFormatFeatureFlags required_features = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
if ((props.drmFormatModifierTilingFeatures & required_features) == required_features && (props.drmFormatModifierPlaneCount == 1)) {
if (modifiers.contains_slow(props.drmFormatModifier))
format_mods.append(props.drmFormatModifier);
}
@ -152,7 +154,7 @@ ErrorOr<NonnullRefPtr<VulkanImage>> create_shared_vulkan_image(VulkanContext con
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = queue_families.size(),
.pQueueFamilyIndices = queue_families.data(),