Commit c2d69ccd authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Vulkan: Add VulkanInfo structure for storing all vulkan related info.

In follow up CLs, this VulkanInfo will be sent from viz process to
browser process and then displayed in about:gpu page.

Bug: 887018
Change-Id: Idde45c731aed65092fc384e529e8b5028c93e545
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1845872Reviewed-by: default avatarSergey Ulanov <sergeyu@chromium.org>
Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#703517}
parent 5a6ecf93
...@@ -45,18 +45,24 @@ VulkanInProcessContextProvider::~VulkanInProcessContextProvider() { ...@@ -45,18 +45,24 @@ VulkanInProcessContextProvider::~VulkanInProcessContextProvider() {
bool VulkanInProcessContextProvider::Initialize() { bool VulkanInProcessContextProvider::Initialize() {
DCHECK(!device_queue_); DCHECK(!device_queue_);
const gfx::ExtensionSet& extensions =
vulkan_implementation_->GetVulkanInstance()->enabled_extensions(); const auto& instance_extensions = vulkan_implementation_->GetVulkanInstance()
bool support_surface = ->vulkan_info()
gfx::HasExtension(extensions, VK_KHR_SURFACE_EXTENSION_NAME); .enabled_instance_extensions;
uint32_t flags = gpu::VulkanDeviceQueue::GRAPHICS_QUEUE_FLAG; uint32_t flags = gpu::VulkanDeviceQueue::GRAPHICS_QUEUE_FLAG;
if (support_surface) constexpr base::StringPiece surface_extension_name(
flags |= gpu::VulkanDeviceQueue::PRESENTATION_SUPPORT_QUEUE_FLAG; VK_KHR_SURFACE_EXTENSION_NAME);
std::unique_ptr<gpu::VulkanDeviceQueue> device_queue = for (const auto* extension : instance_extensions) {
gpu::CreateVulkanDeviceQueue(vulkan_implementation_, flags); if (surface_extension_name == extension) {
if (!device_queue) flags |= gpu::VulkanDeviceQueue::PRESENTATION_SUPPORT_QUEUE_FLAG;
break;
}
}
device_queue_ = gpu::CreateVulkanDeviceQueue(vulkan_implementation_, flags);
if (!device_queue_)
return false; return false;
device_queue_ = std::move(device_queue);
GrVkBackendContext backend_context; GrVkBackendContext backend_context;
backend_context.fInstance = device_queue_->GetVulkanInstance(); backend_context.fInstance = device_queue_->GetVulkanInstance();
...@@ -64,8 +70,9 @@ bool VulkanInProcessContextProvider::Initialize() { ...@@ -64,8 +70,9 @@ bool VulkanInProcessContextProvider::Initialize() {
backend_context.fDevice = device_queue_->GetVulkanDevice(); backend_context.fDevice = device_queue_->GetVulkanDevice();
backend_context.fQueue = device_queue_->GetVulkanQueue(); backend_context.fQueue = device_queue_->GetVulkanQueue();
backend_context.fGraphicsQueueIndex = device_queue_->GetVulkanQueueIndex(); backend_context.fGraphicsQueueIndex = device_queue_->GetVulkanQueueIndex();
backend_context.fMaxAPIVersion = backend_context.fMaxAPIVersion = vulkan_implementation_->GetVulkanInstance()
vulkan_implementation_->GetVulkanInstance()->api_version(); ->vulkan_info()
.used_api_version;
gpu::VulkanFunctionPointers* vulkan_function_pointers = gpu::VulkanFunctionPointers* vulkan_function_pointers =
gpu::GetVulkanFunctionPointers(); gpu::GetVulkanFunctionPointers();
...@@ -73,11 +80,7 @@ bool VulkanInProcessContextProvider::Initialize() { ...@@ -73,11 +80,7 @@ bool VulkanInProcessContextProvider::Initialize() {
make_unified_getter(vulkan_function_pointers->vkGetInstanceProcAddrFn, make_unified_getter(vulkan_function_pointers->vkGetInstanceProcAddrFn,
vulkan_function_pointers->vkGetDeviceProcAddrFn); vulkan_function_pointers->vkGetDeviceProcAddrFn);
std::vector<const char*> instance_extensions;
std::vector<const char*> device_extensions; std::vector<const char*> device_extensions;
instance_extensions.reserve(extensions.size());
for (const auto& extension : extensions)
instance_extensions.push_back(extension.data());
device_extensions.reserve(device_queue_->enabled_extensions().size()); device_extensions.reserve(device_queue_->enabled_extensions().size());
for (const auto& extension : device_queue_->enabled_extensions()) for (const auto& extension : device_queue_->enabled_extensions())
device_extensions.push_back(extension.data()); device_extensions.push_back(extension.data());
......
...@@ -43,7 +43,10 @@ if (enable_vulkan) { ...@@ -43,7 +43,10 @@ if (enable_vulkan) {
"vulkan_function_pointers.h", "vulkan_function_pointers.h",
"vulkan_implementation.cc", "vulkan_implementation.cc",
"vulkan_implementation.h", "vulkan_implementation.h",
"vulkan_info.cc",
"vulkan_info.h",
"vulkan_instance.cc", "vulkan_instance.cc",
"vulkan_instance.h",
"vulkan_surface.cc", "vulkan_surface.cc",
"vulkan_surface.h", "vulkan_surface.h",
"vulkan_swap_chain.cc", "vulkan_swap_chain.cc",
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "gpu/vulkan/vulkan_command_pool.h" #include "gpu/vulkan/vulkan_command_pool.h"
#include "gpu/vulkan/vulkan_fence_helper.h" #include "gpu/vulkan/vulkan_fence_helper.h"
#include "gpu/vulkan/vulkan_function_pointers.h" #include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_info.h"
namespace gpu { namespace gpu {
...@@ -27,7 +28,7 @@ VulkanDeviceQueue::~VulkanDeviceQueue() { ...@@ -27,7 +28,7 @@ VulkanDeviceQueue::~VulkanDeviceQueue() {
bool VulkanDeviceQueue::Initialize( bool VulkanDeviceQueue::Initialize(
uint32_t options, uint32_t options,
uint32_t max_api_version, const VulkanInfo& info,
const std::vector<const char*>& required_extensions, const std::vector<const char*>& required_extensions,
bool allow_protected_memory, bool allow_protected_memory,
const GetPresentationSupportCallback& get_presentation_support) { const GetPresentationSupportCallback& get_presentation_support) {
...@@ -42,60 +43,41 @@ bool VulkanDeviceQueue::Initialize( ...@@ -42,60 +43,41 @@ bool VulkanDeviceQueue::Initialize(
VkResult result = VK_SUCCESS; VkResult result = VK_SUCCESS;
uint32_t device_count = 0;
result = vkEnumeratePhysicalDevices(vk_instance_, &device_count, nullptr);
if (VK_SUCCESS != result || device_count == 0)
return false;
std::vector<VkPhysicalDevice> devices(device_count);
result =
vkEnumeratePhysicalDevices(vk_instance_, &device_count, devices.data());
if (VK_SUCCESS != result) {
DLOG(ERROR) << "vkEnumeratePhysicalDevices() failed: " << result;
return false;
}
VkQueueFlags queue_flags = 0; VkQueueFlags queue_flags = 0;
if (options & DeviceQueueOption::GRAPHICS_QUEUE_FLAG) if (options & DeviceQueueOption::GRAPHICS_QUEUE_FLAG)
queue_flags |= VK_QUEUE_GRAPHICS_BIT; queue_flags |= VK_QUEUE_GRAPHICS_BIT;
int device_index = -1; int device_index = -1;
int queue_index = -1; int queue_index = -1;
for (size_t i = 0; i < devices.size(); ++i) { for (size_t i = 0; i < info.physical_devices.size(); ++i) {
const VkPhysicalDevice& device = devices[i]; const auto& device_info = info.physical_devices[i];
uint32_t queue_count = 0; const VkPhysicalDevice& device = device_info.device;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, nullptr); for (size_t n = 0; n < device_info.queue_families.size(); ++n) {
if (queue_count) { if ((device_info.queue_families[n].queueFlags & queue_flags) !=
std::vector<VkQueueFamilyProperties> queue_properties(queue_count); queue_flags)
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, continue;
queue_properties.data());
for (size_t n = 0; n < queue_properties.size(); ++n) { if (options & DeviceQueueOption::PRESENTATION_SUPPORT_QUEUE_FLAG &&
if ((queue_properties[n].queueFlags & queue_flags) != queue_flags) !get_presentation_support.Run(device, device_info.queue_families,
continue; n)) {
continue;
if (options & DeviceQueueOption::PRESENTATION_SUPPORT_QUEUE_FLAG &&
!get_presentation_support.Run(device, queue_properties, n)) {
continue;
}
queue_index = static_cast<int>(n);
break;
} }
if (-1 != queue_index) { queue_index = static_cast<int>(n);
device_index = static_cast<int>(i); break;
break; }
} if (-1 != queue_index) {
device_index = static_cast<int>(i);
break;
} }
} }
if (queue_index == -1) if (queue_index == -1)
return false; return false;
vk_physical_device_ = devices[device_index]; const auto& physical_device_info = info.physical_devices[device_index];
vkGetPhysicalDeviceProperties(vk_physical_device_, vk_physical_device_ = physical_device_info.device;
&vk_physical_device_properties_); vk_physical_device_properties_ = physical_device_info.properties;
vk_queue_index_ = queue_index; vk_queue_index_ = queue_index;
float queue_priority = 0.0f; float queue_priority = 0.0f;
...@@ -109,29 +91,13 @@ bool VulkanDeviceQueue::Initialize( ...@@ -109,29 +91,13 @@ bool VulkanDeviceQueue::Initialize(
std::vector<const char*> enabled_layer_names; std::vector<const char*> enabled_layer_names;
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
uint32_t num_device_layers = 0;
result = vkEnumerateDeviceLayerProperties(vk_physical_device_,
&num_device_layers, nullptr);
if (VK_SUCCESS != result) {
DLOG(ERROR) << "vkEnumerateDeviceLayerProperties(NULL) failed: " << result;
return false;
}
std::vector<VkLayerProperties> device_layers(num_device_layers);
result = vkEnumerateDeviceLayerProperties(
vk_physical_device_, &num_device_layers, device_layers.data());
if (VK_SUCCESS != result) {
DLOG(ERROR) << "vkEnumerateDeviceLayerProperties() failed: " << result;
return false;
}
std::unordered_set<std::string> desired_layers({ std::unordered_set<std::string> desired_layers({
"VK_LAYER_KHRONOS_validation", "VK_LAYER_KHRONOS_validation",
}); });
for (const VkLayerProperties& layer_property : device_layers) { for (const auto& layer : physical_device_info.layers) {
if (desired_layers.find(layer_property.layerName) != desired_layers.end()) if (desired_layers.find(layer.layerName) != desired_layers.end())
enabled_layer_names.push_back(layer_property.layerName); enabled_layer_names.push_back(layer.layerName);
} }
#endif // DCHECK_IS_ON() #endif // DCHECK_IS_ON()
...@@ -140,30 +106,21 @@ bool VulkanDeviceQueue::Initialize( ...@@ -140,30 +106,21 @@ bool VulkanDeviceQueue::Initialize(
std::begin(required_extensions), std::begin(required_extensions),
std::end(required_extensions)); std::end(required_extensions));
uint32_t device_api_version = uint32_t device_api_version = std::min(
std::min(max_api_version, vk_physical_device_properties_.apiVersion); info.used_api_version, vk_physical_device_properties_.apiVersion);
// Disable all physical device features by default.
enabled_device_features_2_ = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
// Android and Fuchsia need YCbCr sampler support. // Android and Fuchsia need YCbCr sampler support.
#if defined(OS_ANDROID) || defined(OS_FUCHSIA) #if defined(OS_ANDROID) || defined(OS_FUCHSIA)
if (!vkGetPhysicalDeviceFeatures2) { if (!physical_device_info.feature_sampler_ycbcr_conversion) {
DLOG(ERROR) << "Vulkan 1.1 or VK_KHR_get_physical_device_properties2 "
"extension is required.";
return false;
}
// Query if VkPhysicalDeviceSamplerYcbcrConversionFeatures is supported by
// the implementation. This extension must be supported for Android and
// Fuchsia.
sampler_ycbcr_conversion_features_.pNext = nullptr;
VkPhysicalDeviceFeatures2 supported_device_features_2 = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
&sampler_ycbcr_conversion_features_};
vkGetPhysicalDeviceFeatures2(vk_physical_device_,
&supported_device_features_2);
if (!sampler_ycbcr_conversion_features_.samplerYcbcrConversion) {
LOG(ERROR) << "samplerYcbcrConversion is not supported."; LOG(ERROR) << "samplerYcbcrConversion is not supported.";
return false; return false;
} }
sampler_ycbcr_conversion_features_ = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES};
sampler_ycbcr_conversion_features_.samplerYcbcrConversion = VK_TRUE;
// Add VkPhysicalDeviceSamplerYcbcrConversionFeatures struct to pNext chain // Add VkPhysicalDeviceSamplerYcbcrConversionFeatures struct to pNext chain
// of VkPhysicalDeviceFeatures2 to enable YCbCr sampler support. // of VkPhysicalDeviceFeatures2 to enable YCbCr sampler support.
...@@ -172,21 +129,13 @@ bool VulkanDeviceQueue::Initialize( ...@@ -172,21 +129,13 @@ bool VulkanDeviceQueue::Initialize(
#endif // defined(OS_ANDROID) || defined(OS_FUCHSIA) #endif // defined(OS_ANDROID) || defined(OS_FUCHSIA)
if (allow_protected_memory) { if (allow_protected_memory) {
if (device_api_version < VK_MAKE_VERSION(1, 1, 0)) { if (!physical_device_info.feature_protected_memory) {
DLOG(ERROR) << "Vulkan 1.1 is required for protected memory";
return false;
}
protected_memory_features_.pNext = nullptr;
VkPhysicalDeviceFeatures2 supported_device_features_2 = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
&protected_memory_features_};
vkGetPhysicalDeviceFeatures2(vk_physical_device_,
&supported_device_features_2);
if (!protected_memory_features_.protectedMemory) {
DLOG(ERROR) << "Protected memory is not supported"; DLOG(ERROR) << "Protected memory is not supported";
return false; return false;
} }
protected_memory_features_ = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES};
protected_memory_features_.protectedMemory = VK_TRUE;
// Add VkPhysicalDeviceProtectedMemoryFeatures struct to pNext chain // Add VkPhysicalDeviceProtectedMemoryFeatures struct to pNext chain
// of VkPhysicalDeviceFeatures2 to enable YCbCr sampler support. // of VkPhysicalDeviceFeatures2 to enable YCbCr sampler support.
...@@ -194,11 +143,8 @@ bool VulkanDeviceQueue::Initialize( ...@@ -194,11 +143,8 @@ bool VulkanDeviceQueue::Initialize(
enabled_device_features_2_.pNext = &protected_memory_features_; enabled_device_features_2_.pNext = &protected_memory_features_;
} }
// Disable all physical device features by default. VkDeviceCreateInfo device_create_info = {
enabled_device_features_2_.features = {}; VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO};
VkDeviceCreateInfo device_create_info = {};
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_create_info.pNext = enabled_device_features_2_.pNext; device_create_info.pNext = enabled_device_features_2_.pNext;
device_create_info.queueCreateInfoCount = 1; device_create_info.queueCreateInfoCount = 1;
device_create_info.pQueueCreateInfos = &queue_create_info; device_create_info.pQueueCreateInfos = &queue_create_info;
......
...@@ -18,8 +18,9 @@ ...@@ -18,8 +18,9 @@
namespace gpu { namespace gpu {
class VulkanFenceHelper;
class VulkanCommandPool; class VulkanCommandPool;
class VulkanFenceHelper;
class VulkanInfo;
class VULKAN_EXPORT VulkanDeviceQueue { class VULKAN_EXPORT VulkanDeviceQueue {
public: public:
...@@ -38,7 +39,7 @@ class VULKAN_EXPORT VulkanDeviceQueue { ...@@ -38,7 +39,7 @@ class VULKAN_EXPORT VulkanDeviceQueue {
uint32_t queue_family_index)>; uint32_t queue_family_index)>;
bool Initialize( bool Initialize(
uint32_t options, uint32_t options,
uint32_t max_api_version, const VulkanInfo& info,
const std::vector<const char*>& required_extensions, const std::vector<const char*>& required_extensions,
bool allow_protected_memory, bool allow_protected_memory,
const GetPresentationSupportCallback& get_presentation_support); const GetPresentationSupportCallback& get_presentation_support);
...@@ -103,20 +104,17 @@ class VULKAN_EXPORT VulkanDeviceQueue { ...@@ -103,20 +104,17 @@ class VULKAN_EXPORT VulkanDeviceQueue {
uint32_t vk_queue_index_ = 0; uint32_t vk_queue_index_ = 0;
const VkInstance vk_instance_; const VkInstance vk_instance_;
std::unique_ptr<VulkanFenceHelper> cleanup_helper_; std::unique_ptr<VulkanFenceHelper> cleanup_helper_;
VkPhysicalDeviceFeatures2 enabled_device_features_2_ = { VkPhysicalDeviceFeatures2 enabled_device_features_2_;
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
const bool enforce_protected_memory_; const bool enforce_protected_memory_;
bool allow_protected_memory_ = false; bool allow_protected_memory_ = false;
#if defined(OS_ANDROID) || defined(OS_FUCHSIA) #if defined(OS_ANDROID) || defined(OS_FUCHSIA)
VkPhysicalDeviceSamplerYcbcrConversionFeatures VkPhysicalDeviceSamplerYcbcrConversionFeatures
sampler_ycbcr_conversion_features_ = { sampler_ycbcr_conversion_features_;
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES};
#endif // defined(OS_ANDROID) || defined(OS_FUCHSIA) #endif // defined(OS_ANDROID) || defined(OS_FUCHSIA)
VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features_ = { VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features_;
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES};
DISALLOW_COPY_AND_ASSIGN(VulkanDeviceQueue); DISALLOW_COPY_AND_ASSIGN(VulkanDeviceQueue);
}; };
......
...@@ -32,7 +32,7 @@ std::unique_ptr<VulkanDeviceQueue> CreateVulkanDeviceQueue( ...@@ -32,7 +32,7 @@ std::unique_ptr<VulkanDeviceQueue> CreateVulkanDeviceQueue(
std::vector<const char*> required_extensions = std::vector<const char*> required_extensions =
vulkan_implementation->GetRequiredDeviceExtensions(); vulkan_implementation->GetRequiredDeviceExtensions();
if (!device_queue->Initialize( if (!device_queue->Initialize(
option, vulkan_implementation->GetVulkanInstance()->api_version(), option, vulkan_implementation->GetVulkanInstance()->vulkan_info(),
std::move(required_extensions), std::move(required_extensions),
vulkan_implementation->allow_protected_memory(), callback)) { vulkan_implementation->allow_protected_memory(), callback)) {
device_queue->Destroy(); device_queue->Destroy();
......
// Copyright 2019 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 "gpu/vulkan/vulkan_info.h"
namespace gpu {
VulkanInfo::VulkanInfo() = default;
VulkanInfo::~VulkanInfo() = default;
VulkanInfo::PhysicalDeviceInfo::PhysicalDeviceInfo() = default;
VulkanInfo::PhysicalDeviceInfo::PhysicalDeviceInfo(
const PhysicalDeviceInfo& other) = default;
VulkanInfo::PhysicalDeviceInfo::~PhysicalDeviceInfo() = default;
VulkanInfo::PhysicalDeviceInfo& VulkanInfo::PhysicalDeviceInfo::operator=(
const PhysicalDeviceInfo& info) = default;
} // namespace gpu
// Copyright 2019 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 GPU_VULKAN_VULKAN_INFO_H_
#define GPU_VULKAN_VULKAN_INFO_H_
#include <vulkan/vulkan.h>
#include <vector>
#include "base/macros.h"
#include "gpu/vulkan/vulkan_export.h"
#include "ui/gfx/extension_set.h"
namespace gpu {
class VULKAN_EXPORT VulkanInfo {
public:
VulkanInfo();
~VulkanInfo();
class PhysicalDeviceInfo {
public:
PhysicalDeviceInfo();
PhysicalDeviceInfo(const PhysicalDeviceInfo& other);
~PhysicalDeviceInfo();
PhysicalDeviceInfo& operator=(const PhysicalDeviceInfo& other);
VkPhysicalDevice device = VK_NULL_HANDLE;
VkPhysicalDeviceProperties properties = {};
std::vector<VkLayerProperties> layers;
VkPhysicalDeviceFeatures features = {};
// Extended physical device features:
bool feature_sampler_ycbcr_conversion = false;
bool feature_protected_memory = false;
std::vector<VkQueueFamilyProperties> queue_families;
};
uint32_t api_version = VK_MAKE_VERSION(1, 0, 0);
uint32_t used_api_version = VK_MAKE_VERSION(1, 0, 0);
std::vector<VkExtensionProperties> instance_extensions;
std::vector<const char*> enabled_instance_extensions;
std::vector<VkLayerProperties> instance_layers;
std::vector<PhysicalDeviceInfo> physical_devices;
};
} // namespace gpu
#endif // GPU_VULKAN_VULKAN_INFO_H_
...@@ -57,34 +57,33 @@ bool VulkanInstance::Initialize( ...@@ -57,34 +57,33 @@ bool VulkanInstance::Initialize(
if (!vulkan_function_pointers->BindUnassociatedFunctionPointers()) if (!vulkan_function_pointers->BindUnassociatedFunctionPointers())
return false; return false;
uint32_t supported_api_version = VK_MAKE_VERSION(1, 0, 0);
if (vulkan_function_pointers->vkEnumerateInstanceVersionFn) { if (vulkan_function_pointers->vkEnumerateInstanceVersionFn) {
vulkan_function_pointers->vkEnumerateInstanceVersionFn( vulkan_function_pointers->vkEnumerateInstanceVersionFn(
&supported_api_version); &vulkan_info_.api_version);
} }
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Ensure that android works only with vulkan apiVersion >= 1.1. Vulkan will // Ensure that android works only with vulkan apiVersion >= 1.1. Vulkan will
// only be enabled for Android P+ and Android P+ requires vulkan // only be enabled for Android P+ and Android P+ requires vulkan
// apiVersion >= 1.1. // apiVersion >= 1.1.
if (supported_api_version < VK_MAKE_VERSION(1, 1, 0)) if (vulkan_info_.api_version < VK_MAKE_VERSION(1, 1, 0))
return false; return false;
#endif #endif
// Use Vulkan 1.1 if it's available. // Use Vulkan 1.1 if it's available.
api_version_ = (supported_api_version >= VK_MAKE_VERSION(1, 1, 0)) vulkan_info_.used_api_version =
? VK_MAKE_VERSION(1, 1, 0) (vulkan_info_.api_version >= VK_MAKE_VERSION(1, 1, 0))
: VK_MAKE_VERSION(1, 0, 0); ? VK_MAKE_VERSION(1, 1, 0)
: VK_MAKE_VERSION(1, 0, 0);
VkResult result = VK_SUCCESS; VkResult result = VK_SUCCESS;
VkApplicationInfo app_info = {}; VkApplicationInfo app_info = {};
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.pApplicationName = "Chromium"; app_info.pApplicationName = "Chromium";
app_info.apiVersion = api_version_; app_info.apiVersion = vulkan_info_.used_api_version;
std::vector<const char*> enabled_extensions = required_extensions;
vulkan_info_.enabled_instance_extensions = required_extensions;
uint32_t num_instance_exts = 0; uint32_t num_instance_exts = 0;
result = vkEnumerateInstanceExtensionProperties(nullptr, &num_instance_exts, result = vkEnumerateInstanceExtensionProperties(nullptr, &num_instance_exts,
nullptr); nullptr);
...@@ -94,27 +93,31 @@ bool VulkanInstance::Initialize( ...@@ -94,27 +93,31 @@ bool VulkanInstance::Initialize(
return false; return false;
} }
std::vector<VkExtensionProperties> instance_exts(num_instance_exts); vulkan_info_.instance_extensions.resize(num_instance_exts);
result = vkEnumerateInstanceExtensionProperties(nullptr, &num_instance_exts, result = vkEnumerateInstanceExtensionProperties(
instance_exts.data()); nullptr, &num_instance_exts, vulkan_info_.instance_extensions.data());
if (VK_SUCCESS != result) { if (VK_SUCCESS != result) {
DLOG(ERROR) << "vkEnumerateInstanceExtensionProperties() failed: " DLOG(ERROR) << "vkEnumerateInstanceExtensionProperties() failed: "
<< result; << result;
return false; return false;
} }
for (const VkExtensionProperties& ext_property : instance_exts) { for (const VkExtensionProperties& ext_property :
vulkan_info_.instance_extensions) {
if (strcmp(ext_property.extensionName, if (strcmp(ext_property.extensionName,
VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) { VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
debug_report_enabled_ = true; debug_report_enabled_ = true;
enabled_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); vulkan_info_.enabled_instance_extensions.push_back(
VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
} }
} }
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
for (const char* enabled_extension : enabled_extensions) { for (const char* enabled_extension :
vulkan_info_.enabled_instance_extensions) {
bool found = false; bool found = false;
for (const VkExtensionProperties& ext_property : instance_exts) { for (const VkExtensionProperties& ext_property :
vulkan_info_.instance_extensions) {
if (strcmp(ext_property.extensionName, enabled_extension) == 0) { if (strcmp(ext_property.extensionName, enabled_extension) == 0) {
found = true; found = true;
break; break;
...@@ -137,29 +140,29 @@ bool VulkanInstance::Initialize( ...@@ -137,29 +140,29 @@ bool VulkanInstance::Initialize(
return false; return false;
} }
layer_properties_.resize(num_instance_layers); vulkan_info_.instance_layers.resize(num_instance_layers);
result = vkEnumerateInstanceLayerProperties(&num_instance_layers, result = vkEnumerateInstanceLayerProperties(
layer_properties_.data()); &num_instance_layers, vulkan_info_.instance_layers.data());
if (VK_SUCCESS != result) { if (VK_SUCCESS != result) {
DLOG(ERROR) << "vkEnumerateInstanceLayerProperties() failed: " << result; DLOG(ERROR) << "vkEnumerateInstanceLayerProperties() failed: " << result;
return false; return false;
} }
gfx::ExtensionSet enabled_extensions(
std::begin(vulkan_info_.enabled_instance_extensions),
std::end(vulkan_info_.enabled_instance_extensions));
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
// TODO(crbug.com/843346): Make validation work in combination with // TODO(crbug.com/843346): Make validation work in combination with
// VK_KHR_xlib_surface or switch to VK_KHR_xcb_surface. // VK_KHR_xlib_surface or switch to VK_KHR_xcb_surface.
constexpr base::StringPiece xlib_surface_extension_name(
"VK_KHR_xlib_surface");
bool require_xlib_surface_extension = bool require_xlib_surface_extension =
std::find_if(enabled_extensions.begin(), enabled_extensions.end(), gfx::HasExtension(enabled_extensions, "VK_KHR_xlib_surface");
[xlib_surface_extension_name](const char* e) {
return xlib_surface_extension_name == e;
}) != enabled_extensions.end();
// VK_LAYER_KHRONOS_validation 1.1.106 is required to support // VK_LAYER_KHRONOS_validation 1.1.106 is required to support
// VK_KHR_xlib_surface. // VK_KHR_xlib_surface.
constexpr base::StringPiece standard_validation( constexpr base::StringPiece standard_validation(
"VK_LAYER_KHRONOS_validation"); "VK_LAYER_KHRONOS_validation");
for (const VkLayerProperties& layer_property : layer_properties_) { for (const VkLayerProperties& layer_property : vulkan_info_.instance_layers) {
if (standard_validation != layer_property.layerName) if (standard_validation != layer_property.layerName)
continue; continue;
if (!require_xlib_surface_extension || if (!require_xlib_surface_extension ||
...@@ -171,14 +174,15 @@ bool VulkanInstance::Initialize( ...@@ -171,14 +174,15 @@ bool VulkanInstance::Initialize(
#endif // DCHECK_IS_ON() #endif // DCHECK_IS_ON()
VkInstanceCreateInfo instance_create_info = { VkInstanceCreateInfo instance_create_info = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
&app_info, // pApplicationInfo &app_info, // pApplicationInfo
enabled_layer_names.size(), // enableLayerCount enabled_layer_names.size(), // enableLayerCount
enabled_layer_names.data(), // ppEnabledLayerNames enabled_layer_names.data(), // ppEnabledLayerNames
enabled_extensions.size(), // enabledExtensionCount vulkan_info_.enabled_instance_extensions.size(), // enabledExtensionCount
enabled_extensions.data(), // ppEnabledExtensionNames vulkan_info_.enabled_instance_extensions
.data(), // ppEnabledExtensionNames
}; };
result = vkCreateInstance(&instance_create_info, nullptr, &vk_instance_); result = vkCreateInstance(&instance_create_info, nullptr, &vk_instance_);
...@@ -187,9 +191,6 @@ bool VulkanInstance::Initialize( ...@@ -187,9 +191,6 @@ bool VulkanInstance::Initialize(
return false; return false;
} }
enabled_extensions_ = gfx::ExtensionSet(std::begin(enabled_extensions),
std::end(enabled_extensions));
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
// Register our error logging function. // Register our error logging function.
if (debug_report_enabled_) { if (debug_report_enabled_) {
...@@ -225,8 +226,75 @@ bool VulkanInstance::Initialize( ...@@ -225,8 +226,75 @@ bool VulkanInstance::Initialize(
} }
#endif #endif
return vulkan_function_pointers->BindInstanceFunctionPointers( if (!vulkan_function_pointers->BindInstanceFunctionPointers(
vk_instance_, api_version_, enabled_extensions_); vk_instance_, vulkan_info_.used_api_version, enabled_extensions)) {
return false;
}
CollectInfo();
return true;
}
void VulkanInstance::CollectInfo() {
uint32_t count = 0;
VkResult result = vkEnumeratePhysicalDevices(vk_instance_, &count, nullptr);
if (result != VK_SUCCESS) {
DLOG(ERROR) << "vkEnumeratePhysicalDevices failed: " << result;
}
std::vector<VkPhysicalDevice> physical_devices(count);
result =
vkEnumeratePhysicalDevices(vk_instance_, &count, physical_devices.data());
if (VK_SUCCESS != result) {
DLOG(ERROR) << "vkEnumeratePhysicalDevices() failed: " << result;
return;
}
vulkan_info_.physical_devices.reserve(count);
for (VkPhysicalDevice device : physical_devices) {
vulkan_info_.physical_devices.emplace_back();
auto& info = vulkan_info_.physical_devices.back();
info.device = device;
vkGetPhysicalDeviceProperties(device, &info.properties);
count = 0;
result = vkEnumerateDeviceLayerProperties(device, &count, nullptr);
DLOG_IF(ERROR, result != VK_SUCCESS)
<< "vkEnumerateDeviceLayerProperties failed: " << result;
info.layers.resize(count);
result =
vkEnumerateDeviceLayerProperties(device, &count, info.layers.data());
DLOG_IF(ERROR, result != VK_SUCCESS)
<< "vkEnumerateDeviceLayerProperties failed: " << result;
if (vkGetPhysicalDeviceFeatures2) {
VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_converson_features =
{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES};
VkPhysicalDeviceProtectedMemoryFeatures protected_memory_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES};
VkPhysicalDeviceFeatures2 features_2 = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
features_2.pNext = &ycbcr_converson_features;
ycbcr_converson_features.pNext = &protected_memory_feature;
vkGetPhysicalDeviceFeatures2(device, &features_2);
info.feature_sampler_ycbcr_conversion =
ycbcr_converson_features.samplerYcbcrConversion;
info.feature_protected_memory = protected_memory_feature.protectedMemory;
} else {
vkGetPhysicalDeviceFeatures(device, &info.features);
}
count = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &count, nullptr);
if (count) {
info.queue_families.resize(count);
vkGetPhysicalDeviceQueueFamilyProperties(device, &count,
info.queue_families.data());
}
}
} }
void VulkanInstance::Destroy() { void VulkanInstance::Destroy() {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "gpu/vulkan/vulkan_export.h" #include "gpu/vulkan/vulkan_export.h"
#include "gpu/vulkan/vulkan_info.h"
#include "ui/gfx/extension_set.h" #include "ui/gfx/extension_set.h"
namespace gpu { namespace gpu {
...@@ -29,27 +30,17 @@ class VULKAN_EXPORT VulkanInstance { ...@@ -29,27 +30,17 @@ class VULKAN_EXPORT VulkanInstance {
bool Initialize(const std::vector<const char*>& required_extensions, bool Initialize(const std::vector<const char*>& required_extensions,
const std::vector<const char*>& required_layers); const std::vector<const char*>& required_layers);
// VkApplicationInfo.apiVersion value used to initialize the instance. const VulkanInfo& vulkan_info() const { return vulkan_info_; }
uint32_t api_version() const { return api_version_; }
const gfx::ExtensionSet& enabled_extensions() const {
return enabled_extensions_;
}
const std::vector<VkLayerProperties>& layer_properties() const {
return layer_properties_;
}
VkInstance vk_instance() { return vk_instance_; } VkInstance vk_instance() { return vk_instance_; }
private: private:
void CollectInfo();
void Destroy(); void Destroy();
uint32_t api_version_; VulkanInfo vulkan_info_;
VkInstance vk_instance_ = VK_NULL_HANDLE; VkInstance vk_instance_ = VK_NULL_HANDLE;
std::vector<VkLayerProperties> layer_properties_;
gfx::ExtensionSet enabled_extensions_;
bool debug_report_enabled_ = false; bool debug_report_enabled_ = false;
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
VkDebugReportCallbackEXT error_callback_ = VK_NULL_HANDLE; VkDebugReportCallbackEXT error_callback_ = VK_NULL_HANDLE;
......
...@@ -81,7 +81,7 @@ VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) { ...@@ -81,7 +81,7 @@ VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) {
constexpr base::StringPiece image_pipe_swapchain( constexpr base::StringPiece image_pipe_swapchain(
"VK_LAYER_FUCHSIA_imagepipe_swapchain"); "VK_LAYER_FUCHSIA_imagepipe_swapchain");
for (const VkLayerProperties& layer_property : for (const VkLayerProperties& layer_property :
vulkan_instance_.layer_properties()) { vulkan_instance_.vulkan_info().instance_layers) {
if (image_pipe_swapchain != layer_property.layerName) if (image_pipe_swapchain != layer_property.layerName)
continue; continue;
image_pipe_swapchain_implementation_version = image_pipe_swapchain_implementation_version =
......
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