blob: 08a00fd91199b8ebd86d77b0ba4017daac424553 [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 <atomic>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
#include <gtest/gtest.h>
#include <vulkan/vulkan.h>
#include "src/lib/fxl/test/test_settings.h"
#include "vkreadback.h"
inline constexpr int64_t ms_to_ns(int64_t ms) { return ms * 1000000ull; }
int main(int argc, char** argv) {
if (!fxl::SetTestSettings(argc, argv)) {
return EXIT_FAILURE;
}
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
TEST(Vulkan, Readback) {
VkReadbackTest test;
ASSERT_TRUE(test.Initialize());
ASSERT_TRUE(test.Exec());
ASSERT_TRUE(test.Readback());
}
TEST(Vulkan, ManyReadback) {
std::vector<std::unique_ptr<VkReadbackTest>> tests;
constexpr uint32_t kReps = 75;
for (uint32_t i = 0; i < kReps; i++) {
tests.emplace_back(std::make_unique<VkReadbackTest>());
ASSERT_TRUE(tests.back()->Initialize());
ASSERT_TRUE(tests.back()->Exec());
}
for (auto& test : tests) {
ASSERT_TRUE(test->Readback());
}
}
TEST(Vulkan, ReadbackLoopWithFenceWait) {
VkReadbackTest test;
ASSERT_TRUE(test.Initialize());
std::mutex mutex;
std::condition_variable cond_var;
std::queue<vk::Fence> fences;
constexpr uint32_t kCounter = 500;
const vk::Device device = test.vulkan_device();
std::thread thread([&] {
for (uint32_t i = 0; i < kCounter; i++) {
vk::Fence fence = {};
while (!fence) {
std::unique_lock<std::mutex> lock(mutex);
if (fences.empty()) {
cond_var.wait(lock);
continue;
}
fence = fences.front();
fences.pop();
}
EXPECT_EQ(vk::Result::eSuccess,
device.waitForFences(1, &fence, true /* waitAll */, ms_to_ns(1000)));
device.destroyFence(fence, nullptr /* allocator */);
}
});
const vk::FenceCreateInfo fence_info{};
for (uint32_t i = 0; i < kCounter; i++) {
vk::Fence fence{};
auto rv_fence = device.createFence(&fence_info, nullptr /* allocator */, &fence);
ASSERT_EQ(rv_fence, vk::Result::eSuccess);
{
std::unique_lock<std::mutex> lock(mutex);
fences.push(fence);
const bool transition_image = (i == 0);
EXPECT_TRUE(test.Submit(fence, transition_image));
cond_var.notify_one();
}
EXPECT_TRUE(test.Wait());
}
thread.join();
EXPECT_TRUE(test.Readback());
}