blob: 61618a1026068fa9db2b1cba61a2d74beff106a6 [file] [log] [blame]
// Copyright 2018 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 <sys/eventfd.h>
#include "base/files/scoped_file.h"
#include "components/viz/common/gpu/vulkan_in_process_context_provider.h"
#include "gpu/vulkan/android/vulkan_implementation_android.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace gpu {
class VulkanImplementationAndroidTest : public testing::Test {
public:
void SetUp() override {
// Create a vulkan implementation.
vk_implementation_ = std::make_unique<VulkanImplementationAndroid>();
ASSERT_TRUE(vk_implementation_);
ASSERT_TRUE(vk_implementation_->InitializeVulkanInstance());
// Create vulkan context provider.
vk_context_provider_ =
viz::VulkanInProcessContextProvider::Create(vk_implementation_.get());
ASSERT_TRUE(vk_context_provider_);
// Get the VkDevice.
vk_device_ = vk_context_provider_->GetDeviceQueue()->GetVulkanDevice();
ASSERT_TRUE(vk_device_);
}
void TearDown() override {
vk_context_provider_->Destroy();
vk_device_ = VK_NULL_HANDLE;
}
protected:
std::unique_ptr<VulkanImplementationAndroid> vk_implementation_;
scoped_refptr<viz::VulkanInProcessContextProvider> vk_context_provider_;
VkDevice vk_device_;
};
TEST_F(VulkanImplementationAndroidTest, ExportImportSyncFd) {
// Create a vk semaphore which can be exported.
// To create a semaphore whose payload can be exported to external handles,
// add the VkExportSemaphoreCreateInfo structure to the pNext chain of the
// VkSemaphoreCreateInfo structure.
VkExportSemaphoreCreateInfo export_info;
export_info.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
export_info.pNext = nullptr;
export_info.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
VkSemaphore semaphore1;
VkSemaphoreCreateInfo sem_info;
sem_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
sem_info.pNext = &export_info;
sem_info.flags = 0;
bool result = vkCreateSemaphore(vk_device_, &sem_info, nullptr, &semaphore1);
EXPECT_EQ(result, VK_SUCCESS);
// SYNC_FD semaphores must be signalled or have an associated semaphore
// signal operation pending execution before the export.
// Semaphores can be signaled by including them in a batch as part of a queue
// submission command, defining a queue operation to signal that semaphore.
unsigned int submit_count = 1;
VkFence fence = VK_NULL_HANDLE;
VkSubmitInfo submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO};
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &semaphore1;
result =
vkQueueSubmit(vk_context_provider_->GetDeviceQueue()->GetVulkanQueue(),
submit_count, &submit_info, fence);
EXPECT_EQ(result, VK_SUCCESS);
// Export a sync fd from the semaphore.
base::ScopedFD sync_fd;
EXPECT_TRUE(
vk_implementation_->GetSemaphoreFdKHR(vk_device_, semaphore1, &sync_fd));
EXPECT_GT(sync_fd.get(), -1);
// Import the above sync fd into a new semaphore.
VkSemaphore semaphore2;
EXPECT_TRUE(vk_implementation_->ImportSemaphoreFdKHR(
vk_device_, std::move(sync_fd), &semaphore2));
// Wait for the device to be idle.
result = vkDeviceWaitIdle(vk_device_);
EXPECT_EQ(result, VK_SUCCESS);
// Destroy the semaphores.
vkDestroySemaphore(vk_device_, semaphore1, nullptr);
vkDestroySemaphore(vk_device_, semaphore2, nullptr);
}
} // namespace gpu