Commit cbb0df9b authored by Michael Spang's avatar Michael Spang Committed by Commit Bot

ozone: demo: Add vulkan support

This adds a vulkan renderer to ozone demo. To use it, build ozone_demo
with enable_vulkan=true set in GN args and run:

  ozone_demo --enable-vulkan

Bug: 581471
Test: ozone_demo --enable-vulkan on X11

Change-Id: Ic773186b1c1634611a28d803273d6dfcdb3aa378
Reviewed-on: https://chromium-review.googlesource.com/1058137
Commit-Queue: Michael Spang <spang@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560756}
parent 83d7536f
......@@ -73,7 +73,7 @@ bool VulkanRenderPass::AttachmentData::ValidateData(
return false;
}
if (start_layout < ImageLayoutType::IMAGE_LAYOUT_TYPE_IMAGE_VIEW ||
if (start_layout < ImageLayoutType::IMAGE_LAYOUT_UNDEFINED ||
start_layout > ImageLayoutType::IMAGE_LAYOUT_TYPE_PRESENT) {
DLOG(ERROR) << "Invalid Start Layout: " << static_cast<int>(start_layout);
return false;
......
......@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//gpu/vulkan/features.gni")
group("demo") {
deps = [
":ozone_demo",
......@@ -51,11 +53,20 @@ executable("ozone_demo") {
":ozone_demo_lib",
"//build/config:exe_and_shlib_deps",
"//components/tracing:startup_tracing",
"//gpu/vulkan:buildflags",
"//ui/events/ozone:events_ozone_layout",
"//ui/gl",
"//ui/gl/init",
"//ui/ozone",
]
if (enable_vulkan) {
sources += [
"vulkan_renderer.cc",
"vulkan_renderer.h",
]
deps += [ "//gpu/vulkan/init" ]
}
}
executable("skia_demo") {
......
......@@ -14,11 +14,19 @@
#include "ui/ozone/demo/surfaceless_gl_renderer.h"
#include "ui/ozone/public/ozone_platform.h"
#if BUILDFLAG(ENABLE_VULKAN)
#include "gpu/vulkan/init/vulkan_factory.h"
#include "ui/ozone/demo/vulkan_renderer.h"
#endif
namespace ui {
namespace {
const char kDisableSurfaceless[] = "disable-surfaceless";
const char kDisableGpu[] = "disable-gpu";
#if BUILDFLAG(ENABLE_VULKAN)
const char kEnableVulkan[] = "enable-vulkan";
#endif
scoped_refptr<gl::GLSurface> CreateGLSurface(gfx::AcceleratedWidget widget) {
scoped_refptr<gl::GLSurface> surface;
......@@ -42,6 +50,19 @@ bool SimpleRendererFactory::Initialize() {
OzonePlatform::GetInstance()->AfterSandboxEntry();
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
#if BUILDFLAG(ENABLE_VULKAN)
if (command_line->HasSwitch(kEnableVulkan)) {
vulkan_implementation_ = gpu::CreateVulkanImplementation();
if (vulkan_implementation_ &&
vulkan_implementation_->InitializeVulkanInstance()) {
type_ = VULKAN;
return true;
} else {
vulkan_implementation_.reset();
}
}
#endif
if (!command_line->HasSwitch(kDisableGpu) && gl::init::InitializeGLOneOff() &&
gpu_helper_.Initialize(base::ThreadTaskRunnerHandle::Get())) {
type_ = GL;
......@@ -65,6 +86,11 @@ std::unique_ptr<Renderer> SimpleRendererFactory::CreateRenderer(
}
return std::make_unique<GlRenderer>(widget, surface, size);
}
#if BUILDFLAG(ENABLE_VULKAN)
case VULKAN:
return std::make_unique<VulkanRenderer>(vulkan_implementation_.get(),
widget, size);
#endif
case SOFTWARE:
return std::make_unique<SoftwareRenderer>(widget, size);
}
......
......@@ -5,9 +5,14 @@
#ifndef UI_OZONE_DEMO_SIMPLE_RENDERER_FACTORY_H_
#define UI_OZONE_DEMO_SIMPLE_RENDERER_FACTORY_H_
#include "gpu/vulkan/buildflags.h"
#include "ui/ozone/demo/renderer_factory.h"
#include "ui/ozone/public/ozone_gpu_test_helper.h"
#if BUILDFLAG(ENABLE_VULKAN)
#include "gpu/vulkan/vulkan_implementation.h"
#endif
namespace ui {
class SimpleRendererFactory : public RendererFactory {
......@@ -15,6 +20,9 @@ class SimpleRendererFactory : public RendererFactory {
enum RendererType {
GL,
SOFTWARE,
#if BUILDFLAG(ENABLE_VULKAN)
VULKAN,
#endif
};
SimpleRendererFactory();
......@@ -25,6 +33,10 @@ class SimpleRendererFactory : public RendererFactory {
const gfx::Size& size) override;
private:
#if BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<gpu::VulkanImplementation> vulkan_implementation_;
#endif
RendererType type_ = SOFTWARE;
// Helper for applications that do GL on main thread.
......
// 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 "ui/ozone/demo/vulkan_renderer.h"
#include <vulkan/vulkan.h>
#include "base/location.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "gpu/vulkan/init/vulkan_factory.h"
#include "gpu/vulkan/vulkan_command_buffer.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_implementation.h"
#include "gpu/vulkan/vulkan_render_pass.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "gpu/vulkan/vulkan_swap_chain.h"
namespace ui {
VulkanRenderer::VulkanRenderer(gpu::VulkanImplementation* vulkan_implementation,
gfx::AcceleratedWidget widget,
const gfx::Size& size)
: RendererBase(widget, size),
vulkan_implementation_(vulkan_implementation),
weak_ptr_factory_(this) {}
VulkanRenderer::~VulkanRenderer() {
surface_->Finish();
surface_->Destroy();
surface_.reset();
device_queue_->Destroy();
device_queue_.reset();
}
bool VulkanRenderer::Initialize() {
device_queue_ = gpu::CreateVulkanDeviceQueue(
vulkan_implementation_,
gpu::VulkanDeviceQueue::GRAPHICS_QUEUE_FLAG |
gpu::VulkanDeviceQueue::PRESENTATION_SUPPORT_QUEUE_FLAG);
CHECK(device_queue_);
surface_ = vulkan_implementation_->CreateViewSurface(widget_);
CHECK(surface_->Initialize(device_queue_.get(),
gpu::VulkanSurface::DEFAULT_SURFACE_FORMAT));
gpu::VulkanRenderPass::RenderPassData render_pass_data;
render_pass_data.attachments.resize(1);
gpu::VulkanRenderPass::AttachmentData* attachment =
&render_pass_data.attachments[0];
attachment->attachment_type =
gpu::VulkanRenderPass::AttachmentType::ATTACHMENT_TYPE_SWAP_IMAGE;
attachment->sample_count = VK_SAMPLE_COUNT_1_BIT;
attachment->load_op = VK_ATTACHMENT_LOAD_OP_CLEAR;
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 =
gpu::VulkanRenderPass::ImageLayoutType::IMAGE_LAYOUT_UNDEFINED;
attachment->end_layout =
gpu::VulkanRenderPass::ImageLayoutType::IMAGE_LAYOUT_TYPE_PRESENT;
render_pass_data.subpass_datas.resize(1);
gpu::VulkanRenderPass::SubpassData* subpass_data =
&render_pass_data.subpass_datas[0];
subpass_data->subpass_attachments.resize(1);
gpu::VulkanRenderPass::SubpassAttachment* subpass_attachment =
&subpass_data->subpass_attachments[0];
subpass_attachment->attachment_index = 0;
subpass_attachment->subpass_layout =
gpu::VulkanRenderPass::ImageLayoutType::IMAGE_LAYOUT_TYPE_IMAGE_VIEW;
gpu::VulkanSwapChain* swap_chain = surface_->GetSwapChain();
CHECK(render_pass_data.ValidateData(swap_chain));
render_pass_ = std::make_unique<gpu::VulkanRenderPass>(device_queue_.get());
CHECK(render_pass_->Initialize(swap_chain, render_pass_data));
// Schedule the initial render.
PostRenderFrameTask();
return true;
}
void VulkanRenderer::RenderFrame() {
TRACE_EVENT0("ozone", "VulkanRenderer::RenderFrame");
VkClearValue clear_value = {.color = {{.5f, 1.f - NextFraction(), .5f, 1.f}}};
render_pass_->SetClearValue(0, clear_value);
gpu::VulkanCommandBuffer* command_buffer =
surface_->GetSwapChain()->GetCurrentCommandBuffer();
{
gpu::ScopedSingleUseCommandBufferRecorder recorder(*command_buffer);
render_pass_->BeginRenderPass(recorder, true);
render_pass_->EndRenderPass(recorder);
}
CHECK_EQ(surface_->SwapBuffers(), gfx::SwapResult::SWAP_ACK);
// TODO(spang): Use a better synchronization strategy.
command_buffer->Wait(UINT64_MAX);
PostRenderFrameTask();
}
void VulkanRenderer::PostRenderFrameTask() {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&VulkanRenderer::RenderFrame,
weak_ptr_factory_.GetWeakPtr()));
}
} // namespace ui
// 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.
#ifndef UI_OZONE_DEMO_VULKAN_RENDERER_H_
#define UI_OZONE_DEMO_VULKAN_RENDERER_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "ui/gfx/swap_result.h"
#include "ui/ozone/demo/renderer_base.h"
namespace gpu {
class VulkanDeviceQueue;
class VulkanImplementation;
class VulkanRenderPass;
class VulkanSurface;
} // namespace gpu
namespace ui {
class VulkanRenderer : public RendererBase {
public:
VulkanRenderer(gpu::VulkanImplementation* vulkan_instance,
gfx::AcceleratedWidget widget,
const gfx::Size& size);
~VulkanRenderer() override;
// Renderer:
bool Initialize() override;
private:
void RenderFrame();
void PostRenderFrameTask();
gpu::VulkanImplementation* const vulkan_implementation_;
std::unique_ptr<gpu::VulkanDeviceQueue> device_queue_;
std::unique_ptr<gpu::VulkanSurface> surface_;
std::unique_ptr<gpu::VulkanRenderPass> render_pass_;
base::WeakPtrFactory<VulkanRenderer> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(VulkanRenderer);
};
} // namespace ui
#endif // UI_OZONE_DEMO_VULKAN_RENDERER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment