blob: 96c445ae5e9823e4417239ae3467cbd7ebd82801 [file] [log] [blame]
// Copyright 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 <memory>
#include "gpu/vulkan/tests/native_window.h"
#include "gpu/vulkan/vulkan_command_buffer.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_render_pass.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "gpu/vulkan/vulkan_swap_chain.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"
// This file tests basic vulkan initialization steps.
namespace gpu {
class BasicVulkanTest : public testing::Test {
public:
void SetUp() override {
const gfx::Rect kDefaultBounds(10, 10, 100, 100);
window_ = CreateNativeWindow(kDefaultBounds);
device_queue_.Initialize(
VulkanDeviceQueue::GRAPHICS_QUEUE_FLAG |
VulkanDeviceQueue::PRESENTATION_SUPPORT_QUEUE_FLAG);
}
void TearDown() override {
DestroyNativeWindow(window_);
window_ = gfx::kNullAcceleratedWidget;
device_queue_.Destroy();
}
gfx::AcceleratedWidget window() const { return window_; }
VulkanDeviceQueue* GetDeviceQueue() { return &device_queue_; }
private:
VulkanDeviceQueue device_queue_;
gfx::AcceleratedWidget window_ = gfx::kNullAcceleratedWidget;
};
TEST_F(BasicVulkanTest, BasicVulkanSurface) {
std::unique_ptr<VulkanSurface> surface =
VulkanSurface::CreateViewSurface(window());
EXPECT_TRUE(surface);
EXPECT_TRUE(surface->Initialize(GetDeviceQueue(),
VulkanSurface::DEFAULT_SURFACE_FORMAT));
surface->Destroy();
}
TEST_F(BasicVulkanTest, EmptyVulkanSwaps) {
std::unique_ptr<VulkanSurface> surface =
VulkanSurface::CreateViewSurface(window());
ASSERT_TRUE(surface);
ASSERT_TRUE(surface->Initialize(GetDeviceQueue(),
VulkanSurface::DEFAULT_SURFACE_FORMAT));
// First swap is a special case, call it first to get better errors.
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers());
// Also make sure we can swap multiple times.
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers());
}
surface->Finish();
surface->Destroy();
}
TEST_F(BasicVulkanTest, BasicRenderPass) {
std::unique_ptr<VulkanSurface> surface =
VulkanSurface::CreateViewSurface(window());
ASSERT_TRUE(surface);
ASSERT_TRUE(surface->Initialize(GetDeviceQueue(),
VulkanSurface::DEFAULT_SURFACE_FORMAT));
VulkanSwapChain* swap_chain = surface->GetSwapChain();
VulkanRenderPass::RenderPassData render_pass_data;
// There is a single attachment which transitions present -> color -> present.
render_pass_data.attachments.resize(1);
VulkanRenderPass::AttachmentData* attachment =
&render_pass_data.attachments[0];
attachment->attachment_type =
VulkanRenderPass::AttachmentType::ATTACHMENT_TYPE_SWAP_IMAGE;
attachment->sample_count = VK_SAMPLE_COUNT_1_BIT;
attachment->load_op = VK_ATTACHMENT_LOAD_OP_LOAD;
attachment->store_op = VK_ATTACHMENT_STORE_OP_STORE;
attachment->stencil_load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment->stencil_store_op = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment->start_layout =
VulkanRenderPass::ImageLayoutType::IMAGE_LAYOUT_TYPE_PRESENT;
attachment->end_layout =
VulkanRenderPass::ImageLayoutType::IMAGE_LAYOUT_TYPE_PRESENT;
// Single subpass.
render_pass_data.subpass_datas.resize(1);
VulkanRenderPass::SubpassData* subpass_data =
&render_pass_data.subpass_datas[0];
// Our subpass will handle the transition to Color.
subpass_data->subpass_attachments.resize(1);
VulkanRenderPass::SubpassAttachment* subpass_attachment =
&subpass_data->subpass_attachments[0];
subpass_attachment->attachment_index = 0;
subpass_attachment->subpass_layout =
VulkanRenderPass::ImageLayoutType::IMAGE_LAYOUT_TYPE_IMAGE_VIEW;
ASSERT_TRUE(render_pass_data.ValidateData(swap_chain));
VulkanRenderPass render_pass(GetDeviceQueue());
EXPECT_TRUE(render_pass.Initialize(swap_chain, render_pass_data));
for (int i = 0; i < 10; ++i) {
VulkanCommandBuffer* command_buffer = swap_chain->GetCurrentCommandBuffer();
{
ScopedSingleUseCommandBufferRecorder recorder(*command_buffer);
render_pass.BeginRenderPass(recorder, true);
render_pass.EndRenderPass(recorder);
}
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers());
}
surface->Finish();
render_pass.Destroy();
surface->Destroy();
}
} // namespace gpu