Skip to content

Commit

Permalink
Added initial implementation of the Vulkan Context Provider.
Browse files Browse the repository at this point in the history
The Vulkan Device/Queue has been included into a custom class which
will be provided by the vulkan context provider. The context provider
will be how we manage sharing of vulkan objects.

R=piman@chromium.org
BUG=582558 582564
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel

Review URL: https://codereview.chromium.org/1829163003

Cr-Commit-Position: refs/heads/master@{#384161}
  • Loading branch information
dyen authored and Commit bot committed Mar 31, 2016
1 parent 11cb963 commit 8a145fb
Show file tree
Hide file tree
Showing 23 changed files with 484 additions and 200 deletions.
23 changes: 23 additions & 0 deletions cc/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/ui.gni")
import("//testing/test.gni")

component("cc") {
Expand Down Expand Up @@ -567,6 +568,28 @@ component("cc") {
configs -= [ "//build/config/compiler:default_optimization" ]
configs += [ "//build/config/compiler:optimize_max" ]
}

if (enable_vulkan) {
deps += [ ":vulkan_cc" ]
}
}

if (enable_vulkan) {
source_set("vulkan_cc") {
include_dirs = [ "/usr/include" ]
sources = [
"output/vulkan_context_provider.h",
"output/vulkan_in_process_context_provider.cc",
"output/vulkan_in_process_context_provider.h",
]

configs += [ "//build/config:precompiled_headers" ]
defines = [ "CC_IMPLEMENTATION=1" ]

deps = [
"//gpu/vulkan",
]
}
}

source_set("test_support") {
Expand Down
1 change: 1 addition & 0 deletions cc/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ include_rules = [
"+gpu/command_buffer/common/mailbox.h",
"+gpu/command_buffer/common/mailbox_holder.h",
"+gpu/command_buffer/common/sync_token.h",
"+gpu/vulkan",
"+media",
"+skia/ext",
"+third_party/khronos/GLES2/gl2.h",
Expand Down
29 changes: 29 additions & 0 deletions cc/output/vulkan_context_provider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 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.

#ifndef CC_OUTPUT_VULKAN_CONTEXT_PROVIDER_H_
#define CC_OUTPUT_VULKAN_CONTEXT_PROVIDER_H_

#include "base/memory/ref_counted.h"

namespace gpu {
class VulkanDeviceQueue;
}

namespace cc {

// The VulkanContextProvider groups sharing of vulkan objects synchronously.
class VulkanContextProvider
: public base::RefCountedThreadSafe<VulkanContextProvider> {
public:
virtual gpu::VulkanDeviceQueue* GetDeviceQueue() = 0;

protected:
friend class base::RefCountedThreadSafe<VulkanContextProvider>;
virtual ~VulkanContextProvider() {}
};

} // namespace cc

#endif // CC_OUTPUT_VULKAN_CONTEXT_PROVIDER_H_
53 changes: 53 additions & 0 deletions cc/output/vulkan_in_process_context_provider.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) 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 "cc/output/vulkan_in_process_context_provider.h"

#include <vector>

#include "gpu/vulkan/vulkan_device_queue.h"

#if defined(VK_USE_PLATFORM_XLIB_KHR)
#include "ui/gfx/x/x11_types.h"
#endif // defined(VK_USE_PLATFORM_XLIB_KHR)

namespace cc {

scoped_refptr<VulkanInProcessContextProvider>
VulkanInProcessContextProvider::Create() {
scoped_refptr<VulkanInProcessContextProvider> context_provider(
new VulkanInProcessContextProvider);
if (!context_provider->Initialize())
return nullptr;
return context_provider;
}

bool VulkanInProcessContextProvider::Initialize() {
scoped_ptr<gpu::VulkanDeviceQueue> device_queue(new gpu::VulkanDeviceQueue);
if (device_queue->Initialize(
gpu::VulkanDeviceQueue::GRAPHICS_QUEUE_FLAG |
gpu::VulkanDeviceQueue::PRESENTATION_SUPPORT_QUEUE_FLAG)) {
device_queue_ = std::move(device_queue);
return true;
}

return false;
}

void VulkanInProcessContextProvider::Destroy() {
if (device_queue_) {
device_queue_->Destroy();
device_queue_.reset();
}
}

gpu::VulkanDeviceQueue* VulkanInProcessContextProvider::GetDeviceQueue() {
return device_queue_.get();
}

VulkanInProcessContextProvider::VulkanInProcessContextProvider() {}

VulkanInProcessContextProvider::~VulkanInProcessContextProvider() {}

} // namespace cc
37 changes: 37 additions & 0 deletions cc/output/vulkan_in_process_context_provider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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.

#ifndef CC_OUTPUT_VULKAN_IN_PROCESS_CONTEXT_PROVIDER_H_
#define CC_OUTPUT_VULKAN_IN_PROCESS_CONTEXT_PROVIDER_H_

#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/output/vulkan_context_provider.h"

namespace gpu {
class VulkanDeviceQueue;
}

namespace cc {

class CC_EXPORT VulkanInProcessContextProvider : public VulkanContextProvider {
public:
static scoped_refptr<VulkanInProcessContextProvider> Create();

bool Initialize();
void Destroy();

gpu::VulkanDeviceQueue* GetDeviceQueue() override;

protected:
VulkanInProcessContextProvider();
~VulkanInProcessContextProvider() override;

private:
scoped_ptr<gpu::VulkanDeviceQueue> device_queue_;
};

} // namespace cc

#endif // CC_OUTPUT_VULKAN_IN_PROCESS_CONTEXT_PROVIDER_H_
2 changes: 2 additions & 0 deletions gpu/vulkan/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ if (enable_vulkan) {
"vulkan_command_buffer.h",
"vulkan_command_pool.cc",
"vulkan_command_pool.h",
"vulkan_device_queue.cc",
"vulkan_device_queue.h",
"vulkan_export.h",
"vulkan_image_view.cc",
"vulkan_image_view.h",
Expand Down
18 changes: 14 additions & 4 deletions gpu/vulkan/tests/vulkan_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#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"
Expand All @@ -19,32 +20,40 @@ class BasicVulkanTest : public testing::Test {
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) {
scoped_ptr<VulkanSurface> surface =
VulkanSurface::CreateViewSurface(window());
EXPECT_TRUE(surface);
EXPECT_TRUE(surface->Initialize(VulkanSurface::DEFAULT_SURFACE_FORMAT));
EXPECT_TRUE(surface->Initialize(GetDeviceQueue(),
VulkanSurface::DEFAULT_SURFACE_FORMAT));
surface->Destroy();
}

TEST_F(BasicVulkanTest, EmptyVulkanSwaps) {
scoped_ptr<VulkanSurface> surface =
VulkanSurface::CreateViewSurface(window());
ASSERT_TRUE(surface);
ASSERT_TRUE(surface->Initialize(VulkanSurface::DEFAULT_SURFACE_FORMAT));
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());
Expand All @@ -61,7 +70,8 @@ TEST_F(BasicVulkanTest, BasicRenderPass) {
scoped_ptr<VulkanSurface> surface =
VulkanSurface::CreateViewSurface(window());
ASSERT_TRUE(surface);
ASSERT_TRUE(surface->Initialize(VulkanSurface::DEFAULT_SURFACE_FORMAT));
ASSERT_TRUE(surface->Initialize(GetDeviceQueue(),
VulkanSurface::DEFAULT_SURFACE_FORMAT));
VulkanSwapChain* swap_chain = surface->GetSwapChain();

VulkanRenderPass::RenderPassData render_pass_data;
Expand Down Expand Up @@ -97,7 +107,7 @@ TEST_F(BasicVulkanTest, BasicRenderPass) {

ASSERT_TRUE(render_pass_data.ValidateData(swap_chain));

VulkanRenderPass render_pass;
VulkanRenderPass render_pass(GetDeviceQueue());
EXPECT_TRUE(render_pass.Initialize(swap_chain, render_pass_data));

for (int i = 0; i < 10; ++i) {
Expand Down
38 changes: 27 additions & 11 deletions gpu/vulkan/vulkan_command_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@

#include "base/logging.h"
#include "gpu/vulkan/vulkan_command_pool.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_implementation.h"

namespace gpu {

VulkanCommandBuffer::VulkanCommandBuffer(VulkanCommandPool* command_pool,
VulkanCommandBuffer::VulkanCommandBuffer(VulkanDeviceQueue* device_queue,
VulkanCommandPool* command_pool,
bool primary)
: primary_(primary), command_pool_(command_pool) {
: primary_(primary),
device_queue_(device_queue),
command_pool_(command_pool) {
command_pool_->IncrementCommandBufferCount();
}

Expand All @@ -25,7 +29,7 @@ VulkanCommandBuffer::~VulkanCommandBuffer() {

bool VulkanCommandBuffer::Initialize() {
VkResult result = VK_SUCCESS;
VkDevice device = GetVulkanDevice();
VkDevice device = device_queue_->GetVulkanDevice();

VkCommandBufferAllocateInfo command_buffer_info = {};
command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
Expand Down Expand Up @@ -57,7 +61,7 @@ bool VulkanCommandBuffer::Initialize() {
}

void VulkanCommandBuffer::Destroy() {
VkDevice device = GetVulkanDevice();
VkDevice device = device_queue_->GetVulkanDevice();
if (VK_NULL_HANDLE != submission_fence_) {
DCHECK(SubmissionFinished());
vkDestroyFence(device, submission_fence_, nullptr);
Expand All @@ -70,8 +74,7 @@ void VulkanCommandBuffer::Destroy() {
}
}

bool VulkanCommandBuffer::Submit(VkQueue queue,
uint32_t num_wait_semaphores,
bool VulkanCommandBuffer::Submit(uint32_t num_wait_semaphores,
VkSemaphore* wait_semaphores,
uint32_t num_signal_semaphores,
VkSemaphore* signal_semaphores) {
Expand All @@ -85,8 +88,18 @@ bool VulkanCommandBuffer::Submit(VkQueue queue,
submit_info.signalSemaphoreCount = num_signal_semaphores;
submit_info.pSignalSemaphores = signal_semaphores;

vkResetFences(GetVulkanDevice(), 1, &submission_fence_);
VkResult result = vkQueueSubmit(queue, 1, &submit_info, submission_fence_);
VkResult result = VK_SUCCESS;

result =
vkResetFences(device_queue_->GetVulkanDevice(), 1, &submission_fence_);
if (VK_SUCCESS != result) {
DLOG(ERROR) << "vkResetFences() failed: " << result;
return false;
}

result = vkQueueSubmit(device_queue_->GetVulkanQueue(), 1, &submit_info,
submission_fence_);

PostExecution();
if (VK_SUCCESS != result) {
DLOG(ERROR) << "vkQueueSubmit() failed: " << result;
Expand All @@ -109,11 +122,13 @@ void VulkanCommandBuffer::Clear() {
}

void VulkanCommandBuffer::Wait(uint64_t timeout) {
vkWaitForFences(GetVulkanDevice(), 1, &submission_fence_, true, timeout);
VkDevice device = device_queue_->GetVulkanDevice();
vkWaitForFences(device, 1, &submission_fence_, true, timeout);
}

bool VulkanCommandBuffer::SubmissionFinished() {
return VK_SUCCESS == vkGetFenceStatus(GetVulkanDevice(), submission_fence_);
VkDevice device = device_queue_->GetVulkanDevice();
return VK_SUCCESS == vkGetFenceStatus(device, submission_fence_);
}

void VulkanCommandBuffer::PostExecution() {
Expand All @@ -131,7 +146,8 @@ void VulkanCommandBuffer::ResetIfDirty() {
if (record_type_ == RECORD_TYPE_DIRTY) {
// Block if command buffer is still in use. This can be externally avoided
// using the asynchronous SubmissionFinished() function.
vkWaitForFences(GetVulkanDevice(), 1, &submission_fence_, true, UINT64_MAX);
VkDevice device = device_queue_->GetVulkanDevice();
vkWaitForFences(device, 1, &submission_fence_, true, UINT64_MAX);

vkResetCommandBuffer(command_buffer_, 0);
record_type_ = RECORD_TYPE_EMPTY;
Expand Down
9 changes: 6 additions & 3 deletions gpu/vulkan/vulkan_command_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@
namespace gpu {

class VulkanCommandPool;
class VulkanDeviceQueue;

class VULKAN_EXPORT VulkanCommandBuffer {
public:
VulkanCommandBuffer(VulkanCommandPool* command_pool, bool primary);
VulkanCommandBuffer(VulkanDeviceQueue* device_queue,
VulkanCommandPool* command_pool,
bool primary);
~VulkanCommandBuffer();

bool Initialize();
void Destroy();

// Submit primary command buffer to the queue.
bool Submit(VkQueue queue,
uint32_t num_wait_semaphores,
bool Submit(uint32_t num_wait_semaphores,
VkSemaphore* wait_semaphores,
uint32_t num_signal_semaphores,
VkSemaphore* signal_semaphores);
Expand Down Expand Up @@ -70,6 +72,7 @@ class VULKAN_EXPORT VulkanCommandBuffer {
const bool primary_;
bool recording_ = false;
RecordType record_type_ = RECORD_TYPE_EMPTY;
VulkanDeviceQueue* device_queue_;
VulkanCommandPool* command_pool_;
VkCommandBuffer command_buffer_ = VK_NULL_HANDLE;
VkFence submission_fence_ = VK_NULL_HANDLE;
Expand Down
Loading

0 comments on commit 8a145fb

Please sign in to comment.