// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "gpu/vulkan/vulkan_image.h" #include "gpu/vulkan/vulkan_device_queue.h" namespace gpu { bool VulkanImage::InitializeFromGpuMemoryBufferHandle( VulkanDeviceQueue* device_queue, gfx::GpuMemoryBufferHandle gmb_handle, const gfx::Size& size, VkFormat format, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageTiling image_tiling) { if (gmb_handle.type != gfx::GpuMemoryBufferType::NATIVE_PIXMAP) { DLOG(ERROR) << "GpuMemoryBuffer is not supported. type:" << gmb_handle.type; return false; } auto& native_pixmap_handle = gmb_handle.native_pixmap_handle; DCHECK_EQ(native_pixmap_handle.planes.size(), 1u); auto& scoped_fd = native_pixmap_handle.planes[0].fd; if (!scoped_fd.is_valid()) { DLOG(ERROR) << "GpuMemoryBufferHandle doesn't have a valid fd."; return false; } bool using_modifier = native_pixmap_handle.modifier != gfx::NativePixmapHandle::kNoModifier && gfx::HasExtension(device_queue->enabled_extensions(), VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME); // If the driver doesn't support modifier or the native_pixmap_handle doesn't // have modifier, VK_IMAGE_TILING_OPTIMAL will be used. DCHECK_EQ(image_tiling, VK_IMAGE_TILING_OPTIMAL); if (using_modifier) image_tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; VkExternalMemoryImageCreateInfoKHR external_image_create_info = { .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR, .pNext = nullptr, .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, }; VkImageDrmFormatModifierListCreateInfoEXT modifier_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT, .pNext = nullptr, .drmFormatModifierCount = 1, .pDrmFormatModifiers = &native_pixmap_handle.modifier, }; if (using_modifier) external_image_create_info.pNext = &modifier_info; VkImportMemoryFdInfoKHR import_memory_fd_info = { .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, .pNext = nullptr, .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, .fd = scoped_fd.get(), }; VkMemoryRequirements* requirements = nullptr; bool result = Initialize(device_queue, size, format, usage, flags, image_tiling, &external_image_create_info, &import_memory_fd_info, requirements); // If Initialize successfully, the fd in scoped_fd should be owned by vulkan. if (result) ignore_result(scoped_fd.release()); return result; } } // namespace gpu