vulkan_android_unittests.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 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. #include <sys/eventfd.h>
  5. #include "base/android/android_hardware_buffer_compat.h"
  6. #include "base/android/scoped_hardware_buffer_handle.h"
  7. #include "components/viz/common/gpu/vulkan_in_process_context_provider.h"
  8. #include "gpu/vulkan/android/vulkan_implementation_android.h"
  9. #include "gpu/vulkan/vulkan_function_pointers.h"
  10. #include "gpu/vulkan/vulkan_image.h"
  11. #include "gpu/vulkan/vulkan_util.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. namespace gpu {
  14. class VulkanImplementationAndroidTest : public testing::Test {
  15. public:
  16. void SetUp() override {
  17. // Create a vulkan implementation.
  18. vk_implementation_ = std::make_unique<VulkanImplementationAndroid>();
  19. ASSERT_TRUE(vk_implementation_);
  20. // This call checks for all instance extensions. Let the test pass if this
  21. // call fails since many bots would not have this extension present.
  22. if (!vk_implementation_->InitializeVulkanInstance(true /* using_surface */))
  23. return;
  24. // Create vulkan context provider. This call checks for all device
  25. // extensions. Let the test pass if this call fails since many bots would
  26. // not have this extension present.
  27. vk_context_provider_ =
  28. viz::VulkanInProcessContextProvider::Create(vk_implementation_.get());
  29. if (!vk_context_provider_)
  30. return;
  31. // Get the VkDevice.
  32. vk_device_ = vk_context_provider_->GetDeviceQueue()->GetVulkanDevice();
  33. ASSERT_TRUE(vk_device_);
  34. // Get the physical device.
  35. vk_phy_device_ =
  36. vk_context_provider_->GetDeviceQueue()->GetVulkanPhysicalDevice();
  37. ASSERT_TRUE(vk_phy_device_);
  38. }
  39. void TearDown() override {
  40. if (vk_context_provider_)
  41. vk_context_provider_->Destroy();
  42. vk_device_ = VK_NULL_HANDLE;
  43. }
  44. protected:
  45. std::unique_ptr<VulkanImplementation> vk_implementation_;
  46. scoped_refptr<viz::VulkanInProcessContextProvider> vk_context_provider_;
  47. VkDevice vk_device_;
  48. VkPhysicalDevice vk_phy_device_;
  49. };
  50. TEST_F(VulkanImplementationAndroidTest, ExportImportSyncFd) {
  51. if (!vk_implementation_ || !vk_context_provider_)
  52. return;
  53. // Create a vk semaphore which can be exported.
  54. // To create a semaphore whose payload can be exported to external handles,
  55. // add the VkExportSemaphoreCreateInfo structure to the pNext chain of the
  56. // VkSemaphoreCreateInfo structure.
  57. VkExportSemaphoreCreateInfo export_info;
  58. export_info.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
  59. export_info.pNext = nullptr;
  60. export_info.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
  61. VkSemaphore semaphore1;
  62. VkSemaphoreCreateInfo sem_info;
  63. sem_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
  64. sem_info.pNext = &export_info;
  65. sem_info.flags = 0;
  66. bool result = vkCreateSemaphore(vk_device_, &sem_info, nullptr, &semaphore1);
  67. EXPECT_EQ(result, VK_SUCCESS);
  68. // SYNC_FD semaphores must be signalled or have an associated semaphore
  69. // signal operation pending execution before the export.
  70. // Semaphores can be signaled by including them in a batch as part of a queue
  71. // submission command, defining a queue operation to signal that semaphore.
  72. EXPECT_TRUE(SubmitSignalVkSemaphore(
  73. vk_context_provider_->GetDeviceQueue()->GetVulkanQueue(), semaphore1));
  74. // Export a handle from the semaphore.
  75. SemaphoreHandle handle =
  76. vk_implementation_->GetSemaphoreHandle(vk_device_, semaphore1);
  77. EXPECT_TRUE(handle.is_valid());
  78. // Import the above semaphore handle into a new semaphore.
  79. VkSemaphore semaphore2 =
  80. vk_implementation_->ImportSemaphoreHandle(vk_device_, std::move(handle));
  81. EXPECT_NE(semaphore2, static_cast<VkSemaphore>(VK_NULL_HANDLE));
  82. // Wait for the device to be idle.
  83. result = vkDeviceWaitIdle(vk_device_);
  84. EXPECT_EQ(result, VK_SUCCESS);
  85. // Destroy the semaphores.
  86. vkDestroySemaphore(vk_device_, semaphore1, nullptr);
  87. vkDestroySemaphore(vk_device_, semaphore2, nullptr);
  88. }
  89. TEST_F(VulkanImplementationAndroidTest, CreateVkImageFromAHB) {
  90. if (!vk_implementation_ || !vk_context_provider_)
  91. return;
  92. // Setup and Create an AHardwareBuffer.
  93. AHardwareBuffer* buffer = nullptr;
  94. AHardwareBuffer_Desc hwb_desc;
  95. hwb_desc.width = 128;
  96. hwb_desc.height = 128;
  97. hwb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
  98. hwb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
  99. AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
  100. hwb_desc.layers = 1;
  101. hwb_desc.stride = 0;
  102. hwb_desc.rfu0 = 0;
  103. hwb_desc.rfu1 = 0;
  104. // Allocate an AHardwareBuffer.
  105. base::AndroidHardwareBufferCompat::GetInstance().Allocate(&hwb_desc, &buffer);
  106. EXPECT_TRUE(buffer);
  107. // Create a vkimage and import the AHB into it.
  108. const gfx::Size size(hwb_desc.width, hwb_desc.height);
  109. auto* device_queue = vk_context_provider_->GetDeviceQueue();
  110. auto handle = base::android::ScopedHardwareBufferHandle::Adopt(buffer);
  111. gfx::GpuMemoryBufferHandle gmb_handle(std::move(handle));
  112. auto vulkan_image = VulkanImage::CreateFromGpuMemoryBufferHandle(
  113. device_queue, std::move(gmb_handle), size, VK_FORMAT_R8G8B8A8_UNORM,
  114. /*usage=*/0, /*flags=*/0, /*image_tiling=*/VK_IMAGE_TILING_OPTIMAL,
  115. /*queue_family_index=*/VK_QUEUE_FAMILY_EXTERNAL);
  116. EXPECT_TRUE(vulkan_image);
  117. vulkan_image->Destroy();
  118. }
  119. } // namespace gpu