blob: b40b4e34f15a3e79c68eb455e90ff7ff9902fbbf [file] [log] [blame]
// Copyright (c) 2016 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_implementation.h"
#include "base/bind.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_instance.h"
namespace gpu {
VulkanImplementation::VulkanImplementation() {}
VulkanImplementation::~VulkanImplementation() {}
std::unique_ptr<VulkanDeviceQueue> CreateVulkanDeviceQueue(
VulkanImplementation* vulkan_implementation,
uint32_t option) {
auto device_queue = std::make_unique<VulkanDeviceQueue>(
vulkan_implementation->GetVulkanInstance()->vk_instance());
auto callback = base::BindRepeating(
&VulkanImplementation::GetPhysicalDevicePresentationSupport,
base::Unretained(vulkan_implementation));
std::vector<const char*> required_extensions =
vulkan_implementation->GetRequiredDeviceExtensions();
if (!device_queue->Initialize(option, std::move(required_extensions),
callback)) {
device_queue->Destroy();
return nullptr;
}
return device_queue;
}
bool VulkanImplementation::SubmitSignalSemaphore(VkQueue vk_queue,
VkSemaphore vk_semaphore,
VkFence vk_fence) {
// Structure specifying a queue submit operation.
VkSubmitInfo submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO};
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &vk_semaphore;
const unsigned int submit_count = 1;
if (vkQueueSubmit(vk_queue, submit_count, &submit_info, vk_fence) !=
VK_SUCCESS) {
return false;
}
return true;
}
bool VulkanImplementation::SubmitWaitSemaphores(
VkQueue vk_queue,
const std::vector<VkSemaphore>& vk_semaphores,
VkFence vk_fence) {
DCHECK(!vk_semaphores.empty());
// Structure specifying a queue submit operation.
VkSubmitInfo submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO};
submit_info.waitSemaphoreCount = vk_semaphores.size();
submit_info.pWaitSemaphores = vk_semaphores.data();
const unsigned int submit_count = 1;
if (vkQueueSubmit(vk_queue, submit_count, &submit_info, vk_fence) !=
VK_SUCCESS) {
return false;
}
return true;
}
#if defined(OS_LINUX) || defined(OS_ANDROID)
bool VulkanImplementation::ImportSemaphoreFdKHR(VkDevice vk_device,
base::ScopedFD sync_fd,
VkSemaphore* vk_semaphore) {
if (!sync_fd.is_valid())
return false;
VkSemaphore semaphore = VK_NULL_HANDLE;
VkSemaphoreCreateInfo info = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
VkResult result = vkCreateSemaphore(vk_device, &info, nullptr, &semaphore);
if (result != VK_SUCCESS)
return false;
VkImportSemaphoreFdInfoKHR import = {
VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR};
import.semaphore = semaphore;
#if defined(OS_ANDROID)
import.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR;
// VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT specifies a POSIX file
// descriptor handle to a Linux Sync File or Android Fence object.
import.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
#else
import.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
#endif
import.fd = sync_fd.get();
result = vkImportSemaphoreFdKHR(vk_device, &import);
if (result != VK_SUCCESS) {
vkDestroySemaphore(vk_device, semaphore, nullptr);
return false;
}
// If import is successful, the VkSemaphore object takes the ownership of fd.
ignore_result(sync_fd.release());
*vk_semaphore = semaphore;
return true;
}
bool VulkanImplementation::GetSemaphoreFdKHR(VkDevice vk_device,
VkSemaphore vk_semaphore,
base::ScopedFD* sync_fd) {
// Create VkSemaphoreGetFdInfoKHR structure.
VkSemaphoreGetFdInfoKHR info = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
info.semaphore = vk_semaphore;
#if defined(OS_ANDROID)
// VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT specifies a POSIX file
// descriptor handle to a Linux Sync File or Android Fence object.
info.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
#else
info.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
#endif
// Create a new sync fd from the semaphore.
int fd = -1;
VkResult result = vkGetSemaphoreFdKHR(vk_device, &info, &fd);
if (result != VK_SUCCESS) {
LOG(ERROR) << "vkGetSemaphoreFdKHR failed : " << result;
sync_fd->reset(-1);
return false;
}
// Transfer the ownership of the fd to the caller.
sync_fd->reset(fd);
return true;
}
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
} // namespace gpu