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