summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Varga <pvarga@inf.u-szeged.hu>2024-02-20 11:36:37 +0100
committerPeter Varga <pvarga@inf.u-szeged.hu>2024-03-20 08:15:40 +0100
commit663ac447476268998fa7f86b03b32115978dfda4 (patch)
tree05d6fa61509edf289b0daffea770afdd5ca9f327
parent9bcbf87e047008bf587afc2da1da4651bef8ca6b (diff)
Fix Vulkan rendering with Nvidia on Linux
Nvidia driver does not support GPU memory buffer (GMB) properly. The NativePixmap is only available if the SharedImage is backed by GMB. OverlayImageRepresentation only provides NativePixmap to access the texture memory by default. ExternalVkImageBacking is a fallback for OzoneImageBacking if GMB is not supported and native Vulkan rendering is used on Linux (see //gpu/command_buffer/service/shared_image/shared_image_factory.cc). It uses VkImage backing instead of GMB by default. This VkImage can be accessed via SkiaImageRepresentation what we already use for synchronizing texture rendering into the backing buffer. As a workaround for Nvidia, the backing VkImage is imported into the Qt's Vulkan context instead of NativePixmap. Pick-to: 6.7 Change-Id: I94a29488521473291a5ba547abca34a3dba567a2 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--src/core/compositor/native_skia_output_device.cpp91
-rw-r--r--src/core/compositor/native_skia_output_device.h14
-rw-r--r--src/core/compositor/native_skia_output_device_vulkan.cpp184
-rw-r--r--src/core/compositor/vulkan_implementation_qt.cpp1
-rw-r--r--src/core/web_engine_context.cpp3
5 files changed, 217 insertions, 76 deletions
diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index d37e77af9..8f11e5162 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -19,6 +19,10 @@
#include "ui/gfx/gpu_fence.h"
#include "ui/gl/gl_fence.h"
+#if defined(USE_OZONE)
+#include "ui/ozone/public/ozone_platform.h"
+#endif
+
namespace QtWebEngineCore {
namespace {
@@ -40,7 +44,7 @@ NativeSkiaOutputDevice::NativeSkiaOutputDevice(
: SkiaOutputDevice(contextState->gr_context(), contextState->graphite_context(), memoryTracker,
didSwapBufferCompleteCallback)
, Compositor(Type::Native)
- , m_grContextType(contextState->gr_context_type())
+ , m_contextState(contextState)
, m_requiresAlpha(requiresAlpha)
, m_factory(shared_image_factory)
, m_representationFactory(shared_image_representation_factory)
@@ -51,6 +55,12 @@ NativeSkiaOutputDevice::NativeSkiaOutputDevice(
capabilities_.output_surface_origin = gfx::SurfaceOrigin::kTopLeft;
capabilities_.preserve_buffer_content = true;
capabilities_.only_invalidates_damage_rect = false;
+
+#if defined(USE_OZONE)
+ m_isNativeBufferSupported = ui::OzonePlatform::GetInstance()
+ ->GetPlatformRuntimeProperties()
+ .supports_native_pixmaps;
+#endif
}
NativeSkiaOutputDevice::~NativeSkiaOutputDevice()
@@ -84,7 +94,7 @@ void NativeSkiaOutputDevice::Present(const absl::optional<gfx::Rect> &update_rec
{
QMutexLocker locker(&m_mutex);
m_backBuffer->createFence();
- m_taskRunner = base::SingleThreadTaskRunner::GetCurrentDefault();
+ m_gpuTaskRunner = base::SingleThreadTaskRunner::GetCurrentDefault();
std::swap(m_middleBuffer, m_backBuffer);
m_readyToUpdate = true;
}
@@ -126,10 +136,9 @@ void NativeSkiaOutputDevice::swapFrame()
QMutexLocker locker(&m_mutex);
if (m_readyToUpdate) {
std::swap(m_frontBuffer, m_middleBuffer);
- m_taskRunner->PostTask(FROM_HERE,
- base::BindOnce(&NativeSkiaOutputDevice::SwapBuffersFinished,
- base::Unretained(this)));
- m_taskRunner.reset();
+ m_gpuTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&NativeSkiaOutputDevice::SwapBuffersFinished,
+ base::Unretained(this)));
m_readyToUpdate = false;
if (m_frontBuffer) {
m_readyWithTexture = true;
@@ -137,6 +146,7 @@ void NativeSkiaOutputDevice::swapFrame()
}
if (m_middleBuffer)
m_middleBuffer->freeTexture();
+ m_gpuTaskRunner.reset();
}
}
@@ -228,17 +238,19 @@ bool NativeSkiaOutputDevice::Buffer::initialize()
}
m_mailbox = mailbox;
- m_skiaRepresentation = m_parent->m_representationFactory->ProduceSkia(
- m_mailbox, m_parent->m_deps->GetSharedContextState());
+ m_skiaRepresentation =
+ m_parent->m_representationFactory->ProduceSkia(m_mailbox, m_parent->m_contextState);
if (!m_skiaRepresentation) {
LOG(ERROR) << "ProduceSkia() failed.";
return false;
}
- m_overlayRepresentation = m_parent->m_representationFactory->ProduceOverlay(m_mailbox);
- if (!m_overlayRepresentation) {
- LOG(ERROR) << "ProduceOverlay() failed";
- return false;
+ if (m_parent->m_isNativeBufferSupported) {
+ m_overlayRepresentation = m_parent->m_representationFactory->ProduceOverlay(m_mailbox);
+ if (!m_overlayRepresentation) {
+ LOG(ERROR) << "ProduceOverlay() failed";
+ return false;
+ }
}
return true;
@@ -295,30 +307,62 @@ std::vector<GrBackendSemaphore> NativeSkiaOutputDevice::Buffer::takeEndWriteSkia
return std::exchange(m_endSemaphores, {});
}
+void NativeSkiaOutputDevice::Buffer::createSkImageOnGPUThread()
+{
+ if (!m_scopedSkiaReadAccess)
+ return;
+
+ QMutexLocker locker(&m_skImageMutex);
+ m_cachedSkImage = m_scopedSkiaReadAccess->CreateSkImage(m_parent->m_contextState.get());
+ if (!m_cachedSkImage)
+ qWarning("SKIA: Failed to create SkImage.");
+}
+
void NativeSkiaOutputDevice::Buffer::beginPresent()
{
if (++m_presentCount != 1) {
- DCHECK(m_scopedOverlayReadAccess);
+ DCHECK(m_scopedOverlayReadAccess || m_scopedSkiaReadAccess);
return;
}
DCHECK(!m_scopedSkiaWriteAccess);
- DCHECK(!m_scopedOverlayReadAccess);
+ DCHECK(!m_scopedOverlayReadAccess && !m_scopedSkiaReadAccess);
- m_scopedOverlayReadAccess = m_overlayRepresentation->BeginScopedReadAccess();
- DCHECK(m_scopedOverlayReadAccess);
- m_acquireFence = TakeGpuFence(m_scopedOverlayReadAccess->TakeAcquireFence());
+ if (m_overlayRepresentation) {
+ m_scopedOverlayReadAccess = m_overlayRepresentation->BeginScopedReadAccess();
+ DCHECK(m_scopedOverlayReadAccess);
+ m_acquireFence = TakeGpuFence(m_scopedOverlayReadAccess->TakeAcquireFence());
+ } else {
+ DCHECK(m_skiaRepresentation);
+ std::vector<GrBackendSemaphore> beginSemaphores;
+ m_scopedSkiaReadAccess =
+ m_skiaRepresentation->BeginScopedReadAccess(&beginSemaphores, nullptr);
+ DCHECK(m_scopedSkiaReadAccess);
+ if (!beginSemaphores.empty())
+ qWarning("SKIA: Unexpected semaphores while reading texture, wait is not implemented.");
+
+ m_parent->m_gpuTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&NativeSkiaOutputDevice::Buffer::createSkImageOnGPUThread,
+ base::Unretained(this)));
+ }
}
void NativeSkiaOutputDevice::Buffer::endPresent()
{
if (!m_presentCount)
return;
- DCHECK(m_scopedOverlayReadAccess);
+ DCHECK(m_scopedOverlayReadAccess || m_scopedSkiaReadAccess);
if (--m_presentCount)
return;
- m_scopedOverlayReadAccess.reset();
+ if (m_scopedOverlayReadAccess) {
+ DCHECK(!m_scopedSkiaReadAccess);
+ m_scopedOverlayReadAccess.reset();
+ } else if (m_scopedSkiaReadAccess) {
+ DCHECK(!m_scopedOverlayReadAccess);
+ QMutexLocker locker(&m_skImageMutex);
+ m_scopedSkiaReadAccess.reset();
+ }
}
void NativeSkiaOutputDevice::Buffer::freeTexture()
@@ -332,7 +376,7 @@ void NativeSkiaOutputDevice::Buffer::freeTexture()
void NativeSkiaOutputDevice::Buffer::createFence()
{
// For some reason we still need to create this, but we do not need to wait on it.
- if (m_parent->m_grContextType == gpu::GrContextType::kGL)
+ if (m_parent->m_contextState->gr_context_type() == gpu::GrContextType::kGL)
m_fence = gl::GLFence::Create();
}
@@ -344,10 +388,17 @@ void NativeSkiaOutputDevice::Buffer::consumeFence()
}
}
+sk_sp<SkImage> NativeSkiaOutputDevice::Buffer::skImage()
+{
+ return m_cachedSkImage;
+}
#if defined(USE_OZONE)
scoped_refptr<gfx::NativePixmap> NativeSkiaOutputDevice::Buffer::nativePixmap()
{
DCHECK(m_presentCount);
+ if (!m_scopedOverlayReadAccess)
+ return nullptr;
+
return m_scopedOverlayReadAccess->GetNativePixmap();
}
#elif defined(Q_OS_WIN)
diff --git a/src/core/compositor/native_skia_output_device.h b/src/core/compositor/native_skia_output_device.h
index e66269b51..2c35cef77 100644
--- a/src/core/compositor/native_skia_output_device.h
+++ b/src/core/compositor/native_skia_output_device.h
@@ -117,6 +117,7 @@ protected:
void createFence();
void consumeFence();
+ sk_sp<SkImage> skImage();
#if defined(USE_OZONE)
scoped_refptr<gfx::NativePixmap> nativePixmap();
#elif defined(Q_OS_WIN)
@@ -126,11 +127,13 @@ protected:
#endif
const Shape &shape() const { return m_shape; }
- viz::SharedImageFormat sharedImageFormat() { return m_overlayRepresentation->format(); }
+ viz::SharedImageFormat sharedImageFormat() const { return m_skiaRepresentation->format(); }
std::function<void()> textureCleanupCallback;
private:
+ void createSkImageOnGPUThread();
+
NativeSkiaOutputDevice *m_parent;
Shape m_shape;
uint64_t m_estimatedSize = 0; // FIXME: estimate size
@@ -139,17 +142,22 @@ protected:
gpu::Mailbox m_mailbox;
std::unique_ptr<gpu::SkiaImageRepresentation> m_skiaRepresentation;
std::unique_ptr<gpu::SkiaImageRepresentation::ScopedWriteAccess> m_scopedSkiaWriteAccess;
+ std::unique_ptr<gpu::SkiaImageRepresentation::ScopedReadAccess> m_scopedSkiaReadAccess;
std::unique_ptr<gpu::OverlayImageRepresentation> m_overlayRepresentation;
std::unique_ptr<gpu::OverlayImageRepresentation::ScopedReadAccess>
m_scopedOverlayReadAccess;
std::vector<GrBackendSemaphore> m_endSemaphores;
int m_presentCount = 0;
+
+ mutable QMutex m_skImageMutex;
+ sk_sp<SkImage> m_cachedSkImage;
};
protected:
+ scoped_refptr<gpu::SharedContextState> m_contextState;
std::unique_ptr<Buffer> m_frontBuffer;
bool m_readyWithTexture = false;
- gpu::GrContextType m_grContextType;
+ bool m_isNativeBufferSupported = true;
private:
friend class NativeSkiaOutputDevice::Buffer;
@@ -163,7 +171,7 @@ private:
viz::OutputSurfaceFrame m_frame;
bool m_readyToUpdate = false;
bool m_requiresAlpha;
- scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+ scoped_refptr<base::SingleThreadTaskRunner> m_gpuTaskRunner;
const raw_ptr<gpu::SharedImageFactory> m_factory;
const raw_ptr<gpu::SharedImageRepresentationFactory> m_representationFactory;
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index fae2854e1..c2ad7a382 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -10,6 +10,20 @@
#include <QtQuick/qquickwindow.h>
#include <QtQuick/qsgtexture.h>
+#if defined(USE_OZONE)
+#include "ui/ozone/buildflags.h"
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+// We need to define USE_VULKAN_XCB for proper vulkan function pointers.
+// Avoiding it may lead to call wrong vulkan functions.
+// This is originally defined in chromium/gpu/vulkan/BUILD.gn.
+#define USE_VULKAN_XCB
+#endif // BUILDFLAG(OZONE_PLATFORM_X11)
+#include "gpu/vulkan/vulkan_function_pointers.h"
+
+#include "components/viz/common/gpu/vulkan_context_provider.h"
+#include "gpu/vulkan/vulkan_device_queue.h"
+#endif // defined(USE_OZONE)
+
namespace QtWebEngineCore {
NativeSkiaOutputDeviceVulkan::NativeSkiaOutputDeviceVulkan(
@@ -37,14 +51,48 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
return nullptr;
#if defined(USE_OZONE)
- Q_ASSERT(m_grContextType == gpu::GrContextType::kVulkan);
+ Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kVulkan);
+
+ GrVkImageInfo vkImageInfo;
scoped_refptr<gfx::NativePixmap> nativePixmap = m_frontBuffer->nativePixmap();
if (!nativePixmap) {
- qWarning("No native pixmap.");
- return nullptr;
+ if (m_isNativeBufferSupported) {
+ qWarning("VULKAN: No NativePixmap.");
+ return nullptr;
+ }
+
+ sk_sp<SkImage> skImage = m_frontBuffer->skImage();
+ if (!skImage) {
+ qWarning("VULKAN: No SkImage.");
+ return nullptr;
+ }
+
+ if (!skImage->isTextureBacked()) {
+ qWarning("VULKAN: SkImage is not backed by GPU texture.");
+ return nullptr;
+ }
+
+ GrBackendTexture backendTexture;
+ bool success = SkImages::GetBackendTextureFromImage(skImage, &backendTexture, false);
+ if (!success || !backendTexture.isValid()) {
+ qWarning("VULKAN: Failed to retrieve backend texture from SkImage.");
+ return nullptr;
+ }
+
+ if (backendTexture.backend() != GrBackendApi::kVulkan) {
+ qWarning("VULKAN: Backend texture is not a Vulkan texture.");
+ return nullptr;
+ }
+
+ backendTexture.getVkImageInfo(&vkImageInfo);
+ if (vkImageInfo.fAlloc.fMemory == VK_NULL_HANDLE) {
+ qWarning("VULKAN: Unable to access Vulkan memory.");
+ return nullptr;
+ }
}
#elif defined(Q_OS_WIN)
- Q_ASSERT(m_grContextType == gpu::GrContextType::kGL);
+ Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kGL);
+
absl::optional<gl::DCLayerOverlayImage> overlayImage = m_frontBuffer->overlayImage();
if (!overlayImage) {
qWarning("No overlay image.");
@@ -60,14 +108,73 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
QVulkanFunctions *f = win->vulkanInstance()->functions();
QVulkanDeviceFunctions *df = win->vulkanInstance()->deviceFunctions(qtVulkanDevice);
+ VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ VkPhysicalDeviceProperties deviceProperties;
+ f->vkGetPhysicalDeviceProperties(qtPhysicalDevice, &deviceProperties);
+ if (deviceProperties.vendorID == 0x10DE) {
+ // FIXME: This is a workaround for Nvidia driver.
+ // The imported image is empty if the initialLayout is not
+ // VK_IMAGE_LAYOUT_PREINITIALIZED.
+ imageLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+ }
+
+ VkExternalMemoryImageCreateInfoKHR externalMemoryImageCreateInfo = {
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR
+ };
#if defined(USE_OZONE)
- gfx::NativePixmapHandle nativePixmapHandle = nativePixmap->ExportHandle();
- if (nativePixmapHandle.planes.size() != 1)
- qFatal("VULKAN: Multiple planes are not supported.");
+ VkSubresourceLayout planeLayout = {};
+ VkImageDrmFormatModifierExplicitCreateInfoEXT modifierInfo = {
+ VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT
+ };
+ base::ScopedFD scopedFd;
+
+ if (nativePixmap) {
+ gfx::NativePixmapHandle nativePixmapHandle = nativePixmap->ExportHandle();
+ if (nativePixmapHandle.planes.size() != 1)
+ qFatal("VULKAN: Multiple planes are not supported.");
+
+ planeLayout.offset = nativePixmapHandle.planes[0].offset;
+ planeLayout.size = 0;
+ planeLayout.rowPitch = nativePixmapHandle.planes[0].stride;
+ planeLayout.arrayPitch = 0;
+ planeLayout.depthPitch = 0;
- base::ScopedFD &scopedFd = nativePixmapHandle.planes[0].fd;
- Q_ASSERT(scopedFd.is_valid());
+ modifierInfo.drmFormatModifier = nativePixmapHandle.modifier;
+ modifierInfo.drmFormatModifierPlaneCount = 1;
+ modifierInfo.pPlaneLayouts = &planeLayout;
+
+ externalMemoryImageCreateInfo.pNext = &modifierInfo;
+ externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+
+ scopedFd = std::move(nativePixmapHandle.planes[0].fd);
+ } else {
+ externalMemoryImageCreateInfo.pNext = nullptr;
+ externalMemoryImageCreateInfo.handleTypes =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ VkMemoryGetFdInfoKHR exportInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR };
+ exportInfo.pNext = nullptr;
+ exportInfo.memory = vkImageInfo.fAlloc.fMemory;
+ exportInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ gpu::VulkanFunctionPointers *vfp = gpu::GetVulkanFunctionPointers();
+ gpu::VulkanDeviceQueue *vulkanDeviceQueue =
+ m_contextState->vk_context_provider()->GetDeviceQueue();
+ VkDevice vulkanDevice = vulkanDeviceQueue->GetVulkanDevice();
+
+ int fd = -1;
+ if (vfp->vkGetMemoryFdKHR(vulkanDevice, &exportInfo, &fd) != VK_SUCCESS)
+ qFatal("VULKAN: Unable to extract file descriptor out of external VkImage.");
+
+ scopedFd.reset(fd);
+ }
+
+ if (!scopedFd.is_valid())
+ qFatal("VULKAN: Unable to extract file descriptor.");
#elif defined(Q_OS_WIN)
+ externalMemoryImageCreateInfo.pNext = nullptr;
+ externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
+
HRESULT status = S_OK;
HANDLE sharedHandle = nullptr;
IDXGIResource1 *resource = nullptr;
@@ -80,49 +187,15 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
Q_ASSERT(status == S_OK);
status = resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle);
Q_ASSERT(status == S_OK);
- Q_ASSERT(sharedHandle);
-#endif
-
- VkExternalMemoryImageCreateInfoKHR externalMemoryImageCreateInfo = {
- VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR
- };
-
-#if defined(USE_OZONE)
- VkSubresourceLayout planeLayout = {};
- planeLayout.offset = nativePixmapHandle.planes[0].offset;
- planeLayout.size = nativePixmapHandle.planes[0].size;
- planeLayout.rowPitch = nativePixmapHandle.planes[0].stride;
- planeLayout.arrayPitch = 0;
- planeLayout.depthPitch = 0;
- VkImageDrmFormatModifierExplicitCreateInfoEXT modifierInfo = {
- VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT
- };
- modifierInfo.drmFormatModifier = nativePixmapHandle.modifier;
- modifierInfo.drmFormatModifierPlaneCount = 1;
- modifierInfo.pPlaneLayouts = &planeLayout;
-
- externalMemoryImageCreateInfo.pNext = &modifierInfo;
- externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
-#elif defined(Q_OS_WIN)
- externalMemoryImageCreateInfo.pNext = nullptr;
- externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
+ if (!sharedHandle)
+ qFatal("VULKAN: Unable to extract shared handle.");
#endif
constexpr VkImageUsageFlags kUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
- VkPhysicalDeviceProperties deviceProperties;
- f->vkGetPhysicalDeviceProperties(qtPhysicalDevice, &deviceProperties);
- VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- if (deviceProperties.vendorID == 0x10DE) {
- // FIXME: This is a workaround for Nvidia driver.
- // The imported image is empty if the initialLayout is not
- // VK_IMAGE_LAYOUT_PREINITIALIZED.
- imageLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
- }
-
VkImageCreateInfo importedImageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
importedImageCreateInfo.pNext = &externalMemoryImageCreateInfo;
importedImageCreateInfo.flags = 0;
@@ -134,17 +207,20 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
importedImageCreateInfo.mipLevels = 1;
importedImageCreateInfo.arrayLayers = 1;
importedImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
-#if defined(USE_OZONE)
- importedImageCreateInfo.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
-#elif defined(Q_OS_WIN)
importedImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
-#endif
importedImageCreateInfo.usage = kUsage;
importedImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
importedImageCreateInfo.queueFamilyIndexCount = 0;
importedImageCreateInfo.pQueueFamilyIndices = nullptr;
importedImageCreateInfo.initialLayout = imageLayout;
+#if defined(USE_OZONE)
+ if (nativePixmap)
+ importedImageCreateInfo.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+ else
+ importedImageCreateInfo.tiling = vkImageInfo.fImageTiling;
+#endif
+
VkResult result;
VkImage importedImage = VK_NULL_HANDLE;
result = df->vkCreateImage(qtVulkanDevice, &importedImageCreateInfo, nullptr /* pAllocator */,
@@ -156,8 +232,11 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
VkImportMemoryFdInfoKHR importMemoryHandleInfo = {
VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR
};
- importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+ importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
importMemoryHandleInfo.fd = scopedFd.release();
+
+ if (nativePixmap)
+ importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
#elif defined(Q_OS_WIN)
VkImportMemoryWin32HandleInfoKHR importMemoryHandleInfo = {
VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR
@@ -173,6 +252,9 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
dedicatedMemoryInfo.pNext = &importMemoryHandleInfo;
dedicatedMemoryInfo.image = importedImage;
+ VkMemoryAllocateInfo memoryAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
+ memoryAllocateInfo.pNext = &dedicatedMemoryInfo;
+
VkMemoryRequirements requirements;
df->vkGetImageMemoryRequirements(qtVulkanDevice, importedImage, &requirements);
if (!requirements.memoryTypeBits)
@@ -195,8 +277,6 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
if (memoryTypeIndex > kMaxIndex)
qFatal("VULKAN: Cannot find valid memory type index.");
- VkMemoryAllocateInfo memoryAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
- memoryAllocateInfo.pNext = &dedicatedMemoryInfo;
memoryAllocateInfo.allocationSize = requirements.size;
memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;
diff --git a/src/core/compositor/vulkan_implementation_qt.cpp b/src/core/compositor/vulkan_implementation_qt.cpp
index fbbbc29c4..2f2259666 100644
--- a/src/core/compositor/vulkan_implementation_qt.cpp
+++ b/src/core/compositor/vulkan_implementation_qt.cpp
@@ -85,6 +85,7 @@ std::vector<const char *> VulkanImplementationQt::GetOptionalDeviceExtensions()
VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
#else
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
+ VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME,
VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME,
VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME,
#endif
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index d1d0c7a9f..2402e9570 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -738,7 +738,8 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitchASCII(switches::kUseVulkan,
switches::kVulkanImplementationNameNative);
const char deviceExtensionsVar[] = "QT_VULKAN_DEVICE_EXTENSIONS";
- QByteArrayList requiredDeviceExtensions = { "VK_EXT_external_memory_dma_buf",
+ QByteArrayList requiredDeviceExtensions = { "VK_KHR_external_memory_fd",
+ "VK_EXT_external_memory_dma_buf",
"VK_EXT_image_drm_format_modifier" };
if (qEnvironmentVariableIsSet(deviceExtensionsVar)) {
QByteArrayList envExtList = qgetenv(deviceExtensionsVar).split(';');