1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gpu/vulkan/vulkan_image.h"
6
7 #include "gpu/vulkan/vulkan_device_queue.h"
8
9 namespace gpu {
10
InitializeFromGpuMemoryBufferHandle(VulkanDeviceQueue * device_queue,gfx::GpuMemoryBufferHandle gmb_handle,const gfx::Size & size,VkFormat format,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageTiling image_tiling)11 bool VulkanImage::InitializeFromGpuMemoryBufferHandle(
12 VulkanDeviceQueue* device_queue,
13 gfx::GpuMemoryBufferHandle gmb_handle,
14 const gfx::Size& size,
15 VkFormat format,
16 VkImageUsageFlags usage,
17 VkImageCreateFlags flags,
18 VkImageTiling image_tiling) {
19 if (gmb_handle.type != gfx::GpuMemoryBufferType::NATIVE_PIXMAP) {
20 DLOG(ERROR) << "GpuMemoryBuffer is not supported. type:" << gmb_handle.type;
21 return false;
22 }
23
24 auto& native_pixmap_handle = gmb_handle.native_pixmap_handle;
25 DCHECK_EQ(native_pixmap_handle.planes.size(), 1u);
26
27 auto& scoped_fd = native_pixmap_handle.planes[0].fd;
28 if (!scoped_fd.is_valid()) {
29 DLOG(ERROR) << "GpuMemoryBufferHandle doesn't have a valid fd.";
30 return false;
31 }
32
33 bool using_modifier =
34 native_pixmap_handle.modifier != gfx::NativePixmapHandle::kNoModifier &&
35 gfx::HasExtension(device_queue->enabled_extensions(),
36 VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
37
38 // If the driver doesn't support modifier or the native_pixmap_handle doesn't
39 // have modifier, VK_IMAGE_TILING_OPTIMAL will be used.
40 DCHECK_EQ(image_tiling, VK_IMAGE_TILING_OPTIMAL);
41 if (using_modifier)
42 image_tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
43
44 VkExternalMemoryImageCreateInfoKHR external_image_create_info = {
45 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR,
46 .pNext = nullptr,
47 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
48 };
49 VkImageDrmFormatModifierListCreateInfoEXT modifier_info = {
50 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
51 .pNext = nullptr,
52 .drmFormatModifierCount = 1,
53 .pDrmFormatModifiers = &native_pixmap_handle.modifier,
54 };
55 if (using_modifier)
56 external_image_create_info.pNext = &modifier_info;
57
58 VkImportMemoryFdInfoKHR import_memory_fd_info = {
59 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
60 .pNext = nullptr,
61 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
62 .fd = scoped_fd.get(),
63 };
64
65 VkMemoryRequirements* requirements = nullptr;
66 bool result = Initialize(device_queue, size, format, usage, flags,
67 image_tiling, &external_image_create_info,
68 &import_memory_fd_info, requirements);
69 // If Initialize successfully, the fd in scoped_fd should be owned by vulkan.
70 if (result)
71 ignore_result(scoped_fd.release());
72
73 return result;
74 }
75
76 } // namespace gpu
77