blob: f1d61eb3d12069fe44751af7fd59839140b77d2a [file] [log] [blame]
// Copyright 2018 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 "garnet/lib/ui/gfx/tests/vk_session_test.h"
#include "src/ui/lib/escher/impl/vulkan_utils.h"
using namespace escher;
namespace scenic_impl {
namespace gfx {
namespace test {
VulkanDeviceQueuesPtr VkSessionTest::CreateVulkanDeviceQueues() {
VulkanInstance::Params instance_params(
{{"VK_LAYER_LUNARG_standard_validation"},
{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME},
false});
auto vulkan_instance = VulkanInstance::New(std::move(instance_params));
// This extension is necessary to support exporting Vulkan memory to a VMO.
return VulkanDeviceQueues::New(
vulkan_instance, {{VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME},
vk::SurfaceKHR()});
}
vk::DeviceMemory VkSessionTest::AllocateExportableMemory(
vk::Device device, vk::PhysicalDevice physical_device,
vk::MemoryRequirements requirements, vk::MemoryPropertyFlags flags) {
uint32_t memory_type_index = impl::GetMemoryTypeIndex(
physical_device, requirements.memoryTypeBits, flags);
vk::PhysicalDeviceMemoryProperties memory_types =
physical_device.getMemoryProperties();
if (memory_type_index == memory_types.memoryTypeCount) {
return nullptr;
}
vk::ExportMemoryAllocateInfoKHR export_info;
export_info.handleTypes =
vk::ExternalMemoryHandleTypeFlagBits::eTempZirconVmoFUCHSIA;
vk::MemoryAllocateInfo info;
info.pNext = &export_info;
info.allocationSize = requirements.size;
info.memoryTypeIndex = memory_type_index;
vk::DeviceMemory memory =
ESCHER_CHECKED_VK_RESULT(device.allocateMemory(info));
return memory;
}
zx::vmo VkSessionTest::ExportMemoryAsVmo(
vk::Device device, vk::DispatchLoaderDynamic dispatch_loader,
vk::DeviceMemory memory) {
vk::MemoryGetZirconHandleInfoFUCHSIA export_memory_info(
memory, vk::ExternalMemoryHandleTypeFlagBits::eTempZirconVmoFUCHSIA);
auto result =
device.getMemoryZirconHandleFUCHSIA(export_memory_info, dispatch_loader);
if (result.result != vk::Result::eSuccess) {
FXL_LOG(ERROR) << "Failed to export vk::DeviceMemory as zx::vmo";
return zx::vmo();
}
return zx::vmo(result.value);
}
vk::MemoryRequirements VkSessionTest::GetBufferRequirements(
vk::Device device, vk::DeviceSize size, vk::BufferUsageFlags usage_flags) {
// Create a temp buffer to find out memory requirements.
vk::BufferCreateInfo buffer_create_info;
buffer_create_info.size = size;
buffer_create_info.usage = usage_flags;
buffer_create_info.sharingMode = vk::SharingMode::eExclusive;
auto vk_buffer =
escher::ESCHER_CHECKED_VK_RESULT(device.createBuffer(buffer_create_info));
auto retval = device.getBufferMemoryRequirements(vk_buffer);
device.destroyBuffer(vk_buffer);
return retval;
}
std::unique_ptr<SessionForTest> VkSessionTest::CreateSession() {
SessionContext session_context = CreateBarebonesSessionContext();
auto vulkan_device = CreateVulkanDeviceQueues();
escher_ = std::make_unique<Escher>(vulkan_device);
release_fence_signaller_ = std::make_unique<ReleaseFenceSignaller>(
escher_->command_buffer_sequencer());
image_factory_ = std::make_unique<ImageFactoryAdapter>(
escher_->gpu_allocator(), escher_->resource_recycler());
session_context.vk_device = escher_->vk_device();
session_context.escher = escher_.get();
session_context.escher_resource_recycler = escher_->resource_recycler();
session_context.escher_image_factory = image_factory_.get();
session_context.release_fence_signaller = release_fence_signaller_.get();
OnSessionContextCreated(&session_context);
return std::make_unique<SessionForTest>(1, std::move(session_context), this,
error_reporter());
}
} // namespace test
} // namespace gfx
} // namespace scenic_impl