| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/ozone/platform/flatland/vulkan_implementation_flatland.h" |
| |
| #include <lib/zx/channel.h> |
| #include <vulkan/vulkan.h> |
| |
| #include <memory> |
| #include <tuple> |
| |
| #include "base/files/file_path.h" |
| #include "base/fuchsia/fuchsia_logging.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/notimplemented.h" |
| #include "gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h" |
| #include "gpu/vulkan/vulkan_function_pointers.h" |
| #include "gpu/vulkan/vulkan_image.h" |
| #include "gpu/vulkan/vulkan_instance.h" |
| #include "gpu/vulkan/vulkan_surface.h" |
| #include "gpu/vulkan/vulkan_util.h" |
| #include "mojo/public/cpp/system/platform_handle.h" |
| #include "ui/gfx/gpu_fence.h" |
| #include "ui/gfx/gpu_memory_buffer_handle.h" |
| #include "ui/ozone/platform/flatland/flatland_surface.h" |
| #include "ui/ozone/platform/flatland/flatland_surface_factory.h" |
| #include "ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.h" |
| #include "ui/ozone/platform/flatland/flatland_window.h" |
| #include "ui/ozone/platform/flatland/flatland_window_manager.h" |
| |
| namespace ui { |
| |
| VulkanImplementationFlatland::VulkanImplementationFlatland( |
| FlatlandSurfaceFactory* flatland_surface_factory, |
| FlatlandSysmemBufferManager* flatland_sysmem_buffer_manager, |
| bool use_swiftshader, |
| bool allow_protected_memory) |
| : VulkanImplementation(use_swiftshader, allow_protected_memory), |
| flatland_sysmem_buffer_manager_(flatland_sysmem_buffer_manager) {} |
| |
| VulkanImplementationFlatland::~VulkanImplementationFlatland() = default; |
| |
| bool VulkanImplementationFlatland::InitializeVulkanInstance( |
| bool using_surface) { |
| DCHECK(!using_surface); |
| |
| base::FilePath path(use_swiftshader() ? "libvk_swiftshader.so" |
| : "libvulkan.so"); |
| std::vector<const char*> required_extensions; |
| std::vector<const char*> required_layers; |
| return vulkan_instance_.Initialize(path, required_extensions, |
| required_layers); |
| } |
| |
| gpu::VulkanInstance* VulkanImplementationFlatland::GetVulkanInstance() { |
| return &vulkan_instance_; |
| } |
| |
| std::unique_ptr<gpu::VulkanSurface> |
| VulkanImplementationFlatland::CreateViewSurface(gfx::AcceleratedWidget window) { |
| NOTREACHED(); |
| } |
| |
| bool VulkanImplementationFlatland::GetPhysicalDevicePresentationSupport( |
| VkPhysicalDevice physical_device, |
| const std::vector<VkQueueFamilyProperties>& queue_family_properties, |
| uint32_t queue_family_index) { |
| return true; |
| } |
| |
| std::vector<const char*> |
| VulkanImplementationFlatland::GetRequiredDeviceExtensions() { |
| std::vector<const char*> result = { |
| VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, |
| VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, |
| VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, |
| VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, |
| VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, |
| VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, |
| VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, |
| VK_KHR_MAINTENANCE1_EXTENSION_NAME, |
| }; |
| |
| // Following extensions are not supported by Swiftshader. |
| if (!use_swiftshader()) { |
| result.push_back(VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME); |
| result.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| } |
| |
| return result; |
| } |
| |
| std::vector<const char*> |
| VulkanImplementationFlatland::GetOptionalDeviceExtensions() { |
| return {}; |
| } |
| |
| VkFence VulkanImplementationFlatland::CreateVkFenceForGpuFence( |
| VkDevice vk_device) { |
| NOTIMPLEMENTED(); |
| return VK_NULL_HANDLE; |
| } |
| |
| std::unique_ptr<gfx::GpuFence> |
| VulkanImplementationFlatland::ExportVkFenceToGpuFence(VkDevice vk_device, |
| VkFence vk_fence) { |
| NOTIMPLEMENTED(); |
| return nullptr; |
| } |
| |
| VkExternalSemaphoreHandleTypeFlagBits |
| VulkanImplementationFlatland::GetExternalSemaphoreHandleType() { |
| return VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA; |
| } |
| |
| bool VulkanImplementationFlatland::CanImportGpuMemoryBuffer( |
| gpu::VulkanDeviceQueue* device_queue, |
| gfx::GpuMemoryBufferType memory_buffer_type) { |
| return memory_buffer_type == gfx::NATIVE_PIXMAP; |
| } |
| |
| std::unique_ptr<gpu::VulkanImage> |
| VulkanImplementationFlatland::CreateImageFromGpuMemoryHandle( |
| gpu::VulkanDeviceQueue* device_queue, |
| gfx::GpuMemoryBufferHandle gmb_handle, |
| gfx::Size size, |
| VkFormat vk_format, |
| const gfx::ColorSpace& color_space) { |
| if (gmb_handle.type != gfx::NATIVE_PIXMAP) |
| return nullptr; |
| |
| if (!gmb_handle.native_pixmap_handle().buffer_collection_handle) { |
| DLOG(ERROR) << "NativePixmapHandle.buffer_collection_handle is not set."; |
| return nullptr; |
| } |
| |
| auto collection = flatland_sysmem_buffer_manager_->GetCollectionByHandle( |
| gmb_handle.native_pixmap_handle().buffer_collection_handle); |
| if (!collection) { |
| DLOG(ERROR) << "Tried to use an unknown buffer collection ID."; |
| return nullptr; |
| } |
| VkImage vk_image = VK_NULL_HANDLE; |
| VkImageCreateInfo vk_image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO}; |
| VkDeviceMemory vk_device_memory = VK_NULL_HANDLE; |
| VkDeviceSize vk_device_size = 0; |
| if (!collection->CreateVkImage(gmb_handle.native_pixmap_handle().buffer_index, |
| device_queue->GetVulkanDevice(), size, |
| &vk_image, &vk_image_info, &vk_device_memory, |
| &vk_device_size)) { |
| DLOG(ERROR) << "CreateVkImage failed."; |
| return nullptr; |
| } |
| |
| auto image = gpu::VulkanImage::Create( |
| device_queue, vk_image, vk_device_memory, size, vk_image_info.format, |
| vk_image_info.tiling, vk_device_size, 0 /* memory_type_index */, |
| vk_image_info.usage, vk_image_info.flags); |
| |
| if (image->format() != vk_format) { |
| DLOG(ERROR) << "Unexpected format " << vk_format << " vs " |
| << image->format(); |
| image->Destroy(); |
| return nullptr; |
| } |
| |
| image->set_queue_family_index(VK_QUEUE_FAMILY_EXTERNAL); |
| image->set_native_pixmap(collection->CreateNativePixmap( |
| std::move(gmb_handle).native_pixmap_handle(), size)); |
| return image; |
| } |
| |
| void VulkanImplementationFlatland::RegisterSysmemBufferCollection( |
| VkDevice device, |
| zx::eventpair service_handle, |
| zx::channel sysmem_token, |
| viz::SharedImageFormat format, |
| gfx::BufferUsage usage, |
| gfx::Size size, |
| size_t min_buffer_count, |
| bool register_with_flatland_allocator) { |
| flatland_sysmem_buffer_manager_->ImportSysmemBufferCollection( |
| device, std::move(service_handle), std::move(sysmem_token), size, format, |
| usage, min_buffer_count, register_with_flatland_allocator); |
| } |
| |
| } // namespace ui |