From 663ac447476268998fa7f86b03b32115978dfda4 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Tue, 20 Feb 2024 11:36:37 +0100 Subject: 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 --- src/core/compositor/native_skia_output_device.cpp | 91 +++++++--- src/core/compositor/native_skia_output_device.h | 14 +- .../native_skia_output_device_vulkan.cpp | 184 +++++++++++++++------ src/core/compositor/vulkan_implementation_qt.cpp | 1 + src/core/web_engine_context.cpp | 3 +- 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 &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 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 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 NativeSkiaOutputDevice::Buffer::skImage() +{ + return m_cachedSkImage; +} #if defined(USE_OZONE) scoped_refptr 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(); #if defined(USE_OZONE) scoped_refptr 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 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 m_skiaRepresentation; std::unique_ptr m_scopedSkiaWriteAccess; + std::unique_ptr m_scopedSkiaReadAccess; std::unique_ptr m_overlayRepresentation; std::unique_ptr m_scopedOverlayReadAccess; std::vector m_endSemaphores; int m_presentCount = 0; + + mutable QMutex m_skImageMutex; + sk_sp m_cachedSkImage; }; protected: + scoped_refptr m_contextState; std::unique_ptr 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 m_taskRunner; + scoped_refptr m_gpuTaskRunner; const raw_ptr m_factory; const raw_ptr 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 #include +#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 nativePixmap = m_frontBuffer->nativePixmap(); if (!nativePixmap) { - qWarning("No native pixmap."); - return nullptr; + if (m_isNativeBufferSupported) { + qWarning("VULKAN: No NativePixmap."); + return nullptr; + } + + sk_sp 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 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 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(';'); -- cgit v1.2.3