blob: 0ed55d99bff6932b5f5da63130cbf23d98ec2a06 [file] [log] [blame]
// Copyright 2019 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 "src/ui/lib/escher/vk/chained_semaphore_generator.h"
#include "src/ui/lib/escher/renderer/batch_gpu_downloader.h"
#include "src/ui/lib/escher/renderer/batch_gpu_uploader.h"
#include "src/ui/lib/escher/test/common/gtest_escher.h"
#include "src/ui/lib/escher/util/image_utils.h"
namespace escher {
using ChainedSemaphoreGeneratorTest = escher::test::TestWithVkValidationLayer;
// We upload to an image twice using different pixel information, and we use
// ChainedSemaphoreGenerator to ensure that the pixel finally uploaded to
// the image is the latter one we uploaded.
VK_TEST_F(ChainedSemaphoreGeneratorTest, SequentialUpload) {
auto escher = test::GetEscher()->GetWeakPtr();
auto uploader1 = BatchGpuUploader::New(escher);
auto uploader2 = BatchGpuUploader::New(escher);
const size_t image_size = sizeof(uint8_t) * 4;
// Create a 1x1 RGBA (8-bit channels) image to write to.
ImageFactoryAdapter image_factory(escher->gpu_allocator(), escher->resource_recycler());
ImagePtr image = image_utils::NewImage(&image_factory, vk::Format::eR8G8B8A8Unorm, 1, 1);
vk::BufferImageCopy region;
region.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eColor;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageExtent.width = 1;
region.imageExtent.height = 1;
region.imageExtent.depth = 1;
region.bufferOffset = 0;
// Do write.
std::vector<uint8_t> host_data = {100, 90, 80, 255};
// We set image layout to eTransferDstOptimal as we need to write to it
// later.
uploader1->ScheduleWriteImage(image, std::move(host_data), vk::ImageLayout::eTransferDstOptimal,
region);
std::vector<uint8_t> host_data_2 = {200, 190, 180, 255};
uploader2->ScheduleWriteImage(image, std::move(host_data_2));
// Set up semaphore chain.
auto* semaphore_chain = escher->semaphore_chain();
auto semaphore_pair_writer1 = semaphore_chain->TakeLastAndCreateNextSemaphore();
uploader1->AddSignalSemaphore(semaphore_pair_writer1.semaphore_to_signal);
auto semaphore_pair_writer2 = semaphore_chain->TakeLastAndCreateNextSemaphore();
uploader2->AddWaitSemaphore(semaphore_pair_writer2.semaphore_to_wait,
vk::PipelineStageFlagBits::eTransfer);
EXPECT_EQ(semaphore_pair_writer1.semaphore_to_signal->vk_semaphore(),
semaphore_pair_writer2.semaphore_to_wait->vk_semaphore());
// Submit the work.
uploader1->Submit();
uploader2->Submit();
escher->vk_device().waitIdle();
EXPECT_TRUE(escher->Cleanup());
// Check if the image downloaded contains color_2.
auto downloader = BatchGpuDownloader::New(escher);
bool downloaded = false;
bool image_correct = false;
std::vector<uint8_t> color_2 = {200, 190, 180, 255};
downloader->ScheduleReadImage(
image,
[&color_2, &downloaded, &image_correct](const void* host_ptr, size_t size) {
downloaded = true;
image_correct = memcmp(host_ptr, color_2.data(), image_size) == 0;
},
region);
downloader->Submit();
escher->vk_device().waitIdle();
EXPECT_TRUE(escher->Cleanup());
EXPECT_TRUE(downloaded && image_correct);
}
} // namespace escher