1 // Copyright (c) 2018 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 "ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h"
6 
7 #include <memory>
8 
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/native_library.h"
12 #include "gpu/vulkan/vulkan_function_pointers.h"
13 #include "gpu/vulkan/vulkan_image.h"
14 #include "gpu/vulkan/vulkan_instance.h"
15 #include "gpu/vulkan/vulkan_surface.h"
16 #include "gpu/vulkan/vulkan_util.h"
17 #include "ui/gfx/gpu_fence.h"
18 #include "ui/gfx/gpu_memory_buffer.h"
19 
20 namespace ui {
21 
VulkanImplementationGbm()22 VulkanImplementationGbm::VulkanImplementationGbm() {}
23 
~VulkanImplementationGbm()24 VulkanImplementationGbm::~VulkanImplementationGbm() {}
25 
InitializeVulkanInstance(bool using_surface)26 bool VulkanImplementationGbm::InitializeVulkanInstance(bool using_surface) {
27   DLOG_IF(ERROR, using_surface) << "VK_KHR_surface is not supported.";
28   gpu::VulkanFunctionPointers* vulkan_function_pointers =
29       gpu::GetVulkanFunctionPointers();
30 
31   base::NativeLibraryLoadError native_library_load_error;
32   vulkan_function_pointers->vulkan_loader_library = base::LoadNativeLibrary(
33       base::FilePath("libvulkan.so.1"), &native_library_load_error);
34   if (!vulkan_function_pointers->vulkan_loader_library)
35     return false;
36 
37   std::vector<const char*> required_extensions = {
38       "VK_KHR_external_fence_capabilities",
39       "VK_KHR_get_physical_device_properties2",
40   };
41   if (!vulkan_instance_.Initialize(required_extensions, {}))
42     return false;
43 
44   vkGetPhysicalDeviceExternalFencePropertiesKHR_ =
45       reinterpret_cast<PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR>(
46           vkGetInstanceProcAddr(
47               vulkan_instance_.vk_instance(),
48               "vkGetPhysicalDeviceExternalFencePropertiesKHR"));
49   if (!vkGetPhysicalDeviceExternalFencePropertiesKHR_)
50     return false;
51 
52   vkGetFenceFdKHR_ = reinterpret_cast<PFN_vkGetFenceFdKHR>(
53       vkGetInstanceProcAddr(vulkan_instance_.vk_instance(), "vkGetFenceFdKHR"));
54   if (!vkGetFenceFdKHR_)
55     return false;
56 
57   return true;
58 }
59 
GetVulkanInstance()60 gpu::VulkanInstance* VulkanImplementationGbm::GetVulkanInstance() {
61   return &vulkan_instance_;
62 }
63 
CreateViewSurface(gfx::AcceleratedWidget window)64 std::unique_ptr<gpu::VulkanSurface> VulkanImplementationGbm::CreateViewSurface(
65     gfx::AcceleratedWidget window) {
66   return nullptr;
67 }
68 
GetPhysicalDevicePresentationSupport(VkPhysicalDevice physical_device,const std::vector<VkQueueFamilyProperties> & queue_family_properties,uint32_t queue_family_index)69 bool VulkanImplementationGbm::GetPhysicalDevicePresentationSupport(
70     VkPhysicalDevice physical_device,
71     const std::vector<VkQueueFamilyProperties>& queue_family_properties,
72     uint32_t queue_family_index) {
73   VkPhysicalDeviceExternalFenceInfo external_fence_info = {
74       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
75       .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT};
76   VkExternalFenceProperties external_fence_properties;
77   vkGetPhysicalDeviceExternalFencePropertiesKHR_(
78       physical_device, &external_fence_info, &external_fence_properties);
79   if (!(external_fence_properties.externalFenceFeatures &
80         VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT)) {
81     return false;
82   }
83 
84   return true;
85 }
86 
87 std::vector<const char*>
GetRequiredDeviceExtensions()88 VulkanImplementationGbm::GetRequiredDeviceExtensions() {
89   return {VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME,
90           VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME,
91           VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
92           VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
93           VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
94           VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME};
95 }
96 
97 std::vector<const char*>
GetOptionalDeviceExtensions()98 VulkanImplementationGbm::GetOptionalDeviceExtensions() {
99   return {};
100 }
101 
CreateVkFenceForGpuFence(VkDevice vk_device)102 VkFence VulkanImplementationGbm::CreateVkFenceForGpuFence(VkDevice vk_device) {
103   VkFenceCreateInfo fence_create_info = {};
104   fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
105   VkExportFenceCreateInfo fence_export_create_info = {};
106   fence_create_info.pNext = &fence_export_create_info;
107   fence_export_create_info.sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO;
108   fence_export_create_info.handleTypes =
109       VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
110 
111   VkFence fence;
112   VkResult result =
113       vkCreateFence(vk_device, &fence_create_info, nullptr, &fence);
114   if (result != VK_SUCCESS) {
115     DLOG(ERROR) << "vkCreateFence failed: " << result;
116     return VK_NULL_HANDLE;
117   }
118 
119   return fence;
120 }
121 
ExportVkFenceToGpuFence(VkDevice vk_device,VkFence vk_fence)122 std::unique_ptr<gfx::GpuFence> VulkanImplementationGbm::ExportVkFenceToGpuFence(
123     VkDevice vk_device,
124     VkFence vk_fence) {
125   VkFenceGetFdInfoKHR fence_get_fd_info = {};
126   fence_get_fd_info.sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR;
127   fence_get_fd_info.fence = vk_fence;
128   fence_get_fd_info.handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
129   int fence_fd = -1;
130   VkResult result = vkGetFenceFdKHR_(vk_device, &fence_get_fd_info, &fence_fd);
131   if (result != VK_SUCCESS) {
132     DLOG(ERROR) << "vkGetFenceFdKHR failed: " << result;
133     return nullptr;
134   }
135 
136   gfx::GpuFenceHandle gpu_fence_handle;
137   gpu_fence_handle.owned_fd = base::ScopedFD(fence_fd);
138   return std::make_unique<gfx::GpuFence>(std::move(gpu_fence_handle));
139 }
140 
CreateExternalSemaphore(VkDevice vk_device)141 VkSemaphore VulkanImplementationGbm::CreateExternalSemaphore(
142     VkDevice vk_device) {
143   return gpu::CreateExternalVkSemaphore(
144       vk_device, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
145 }
146 
ImportSemaphoreHandle(VkDevice vk_device,gpu::SemaphoreHandle sync_handle)147 VkSemaphore VulkanImplementationGbm::ImportSemaphoreHandle(
148     VkDevice vk_device,
149     gpu::SemaphoreHandle sync_handle) {
150   return gpu::ImportVkSemaphoreHandle(vk_device, std::move(sync_handle));
151 }
152 
GetSemaphoreHandle(VkDevice vk_device,VkSemaphore vk_semaphore)153 gpu::SemaphoreHandle VulkanImplementationGbm::GetSemaphoreHandle(
154     VkDevice vk_device,
155     VkSemaphore vk_semaphore) {
156   return gpu::GetVkSemaphoreHandle(
157       vk_device, vk_semaphore, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
158 }
159 
160 VkExternalMemoryHandleTypeFlagBits
GetExternalImageHandleType()161 VulkanImplementationGbm::GetExternalImageHandleType() {
162   return VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
163 }
164 
CanImportGpuMemoryBuffer(gfx::GpuMemoryBufferType memory_buffer_type)165 bool VulkanImplementationGbm::CanImportGpuMemoryBuffer(
166     gfx::GpuMemoryBufferType memory_buffer_type) {
167   return false;
168 }
169 
170 std::unique_ptr<gpu::VulkanImage>
CreateImageFromGpuMemoryHandle(gpu::VulkanDeviceQueue * device_queue,gfx::GpuMemoryBufferHandle gmb_handle,gfx::Size size,VkFormat vk_formae)171 VulkanImplementationGbm::CreateImageFromGpuMemoryHandle(
172     gpu::VulkanDeviceQueue* device_queue,
173     gfx::GpuMemoryBufferHandle gmb_handle,
174     gfx::Size size,
175     VkFormat vk_formae) {
176   NOTIMPLEMENTED();
177   return nullptr;
178 }
179 
180 }  // namespace ui
181