Support multiple Vulkan instances in the Vulkan backend

This will allow the Vulkan backend connection to be initialized, and
then selectively discover adapters on just one of the instances.
This is needed so that discovery of the fallback WebGPU adapter can
avoid initializing any adapters other than SwiftShader.

Bug: chromium:1266550
Change-Id: Ia8b31c0239da89a41aa89f1c09a66e9e56e10d95
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/69980
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng 2021-12-06 19:31:12 +00:00 committed by Dawn LUCI CQ
parent 1a57ee9d4e
commit 652293f14c
10 changed files with 184 additions and 128 deletions

View File

@ -96,6 +96,9 @@ namespace dawn_native {
// gracefully shut down.
#define DAWN_INTERNAL_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::Internal, MESSAGE)
#define DAWN_FORMAT_INTERNAL_ERROR(...) \
DAWN_MAKE_ERROR(InternalErrorType::Internal, absl::StrFormat(__VA_ARGS__))
#define DAWN_UNIMPLEMENTED_ERROR(MESSAGE) \
DAWN_MAKE_ERROR(InternalErrorType::Internal, std::string("Unimplemented: ") + MESSAGE)

View File

@ -51,7 +51,7 @@ namespace dawn_native {
#endif // defined(DAWN_ENABLE_BACKEND_OPENGL)
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
namespace vulkan {
BackendConnection* Connect(InstanceBase* instance, bool useSwiftshader);
BackendConnection* Connect(InstanceBase* instance);
}
#endif // defined(DAWN_ENABLE_BACKEND_VULKAN)
@ -187,16 +187,7 @@ namespace dawn_native {
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
case wgpu::BackendType::Vulkan:
// TODO(https://github.com/KhronosGroup/Vulkan-Loader/issues/287):
// When we can load SwiftShader in parallel with the system driver, we should
// create the backend only once and expose SwiftShader as an additional adapter.
// For now, we create two VkInstances, one from SwiftShader, and one from the
// system. Note: If the Vulkan driver *is* SwiftShader, then this would load
// SwiftShader twice.
Register(vulkan::Connect(this, false), wgpu::BackendType::Vulkan);
# if defined(DAWN_ENABLE_SWIFTSHADER)
Register(vulkan::Connect(this, true), wgpu::BackendType::Vulkan);
# endif // defined(DAWN_ENABLE_SWIFTSHADER)
Register(vulkan::Connect(this), wgpu::BackendType::Vulkan);
break;
#endif // defined(DAWN_ENABLE_BACKEND_VULKAN)

View File

@ -22,10 +22,12 @@
namespace dawn_native { namespace vulkan {
Adapter::Adapter(Backend* backend, VkPhysicalDevice physicalDevice)
: AdapterBase(backend->GetInstance(), wgpu::BackendType::Vulkan),
Adapter::Adapter(InstanceBase* instance,
VulkanInstance* vulkanInstance,
VkPhysicalDevice physicalDevice)
: AdapterBase(instance, wgpu::BackendType::Vulkan),
mPhysicalDevice(physicalDevice),
mBackend(backend) {
mVulkanInstance(vulkanInstance) {
}
const VulkanDeviceInfo& Adapter::GetDeviceInfo() const {
@ -36,8 +38,8 @@ namespace dawn_native { namespace vulkan {
return mPhysicalDevice;
}
Backend* Adapter::GetBackend() const {
return mBackend;
VulkanInstance* Adapter::GetVulkanInstance() const {
return mVulkanInstance.Get();
}
bool Adapter::IsDepthStencilFormatSupported(VkFormat format) {
@ -45,8 +47,8 @@ namespace dawn_native { namespace vulkan {
format == VK_FORMAT_D32_SFLOAT_S8_UINT);
VkFormatProperties properties;
GetBackend()->GetFunctions().GetPhysicalDeviceFormatProperties(mPhysicalDevice, format,
&properties);
mVulkanInstance->GetFunctions().GetPhysicalDeviceFormatProperties(mPhysicalDevice, format,
&properties);
return properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
}
@ -327,7 +329,7 @@ namespace dawn_native { namespace vulkan {
// Via dawn_native::vulkan::WrapVulkanImage
return external_memory::Service::CheckSupport(mDeviceInfo) &&
external_semaphore::Service::CheckSupport(mDeviceInfo, mPhysicalDevice,
mBackend->GetFunctions());
mVulkanInstance->GetFunctions());
}
ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl(const DawnDeviceDescriptor* descriptor) {

View File

@ -17,16 +17,19 @@
#include "dawn_native/Adapter.h"
#include "common/RefCounted.h"
#include "common/vulkan_platform.h"
#include "dawn_native/vulkan/VulkanInfo.h"
namespace dawn_native { namespace vulkan {
class Backend;
class VulkanInstance;
class Adapter : public AdapterBase {
public:
Adapter(Backend* backend, VkPhysicalDevice physicalDevice);
Adapter(InstanceBase* instance,
VulkanInstance* vulkanInstance,
VkPhysicalDevice physicalDevice);
~Adapter() override = default;
// AdapterBase Implementation
@ -34,7 +37,7 @@ namespace dawn_native { namespace vulkan {
const VulkanDeviceInfo& GetDeviceInfo() const;
VkPhysicalDevice GetPhysicalDevice() const;
Backend* GetBackend() const;
VulkanInstance* GetVulkanInstance() const;
bool IsDepthStencilFormatSupported(VkFormat format);
@ -47,7 +50,7 @@ namespace dawn_native { namespace vulkan {
const DawnDeviceDescriptor* descriptor) override;
VkPhysicalDevice mPhysicalDevice;
Backend* mBackend;
Ref<VulkanInstance> mVulkanInstance;
VulkanDeviceInfo mDeviceInfo = {};
};

View File

@ -56,6 +56,13 @@ namespace dawn_native { namespace vulkan {
namespace {
static constexpr ICD kICDs[] = {
ICD::None,
#if defined(DAWN_ENABLE_SWIFTSHADER)
ICD::SwiftShader,
#endif // defined(DAWN_ENABLE_SWIFTSHADER)
};
VKAPI_ATTR VkBool32 VKAPI_CALL
OnDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT /* messageTypes */,
@ -81,11 +88,9 @@ namespace dawn_native { namespace vulkan {
} // anonymous namespace
Backend::Backend(InstanceBase* instance)
: BackendConnection(instance, wgpu::BackendType::Vulkan) {
}
VulkanInstance::VulkanInstance() = default;
Backend::~Backend() {
VulkanInstance::~VulkanInstance() {
if (mDebugUtilsMessenger != VK_NULL_HANDLE) {
mFunctions.DestroyDebugUtilsMessengerEXT(mInstance, mDebugUtilsMessenger, nullptr);
mDebugUtilsMessenger = VK_NULL_HANDLE;
@ -98,21 +103,36 @@ namespace dawn_native { namespace vulkan {
}
}
const VulkanFunctions& Backend::GetFunctions() const {
const VulkanFunctions& VulkanInstance::GetFunctions() const {
return mFunctions;
}
VkInstance Backend::GetVkInstance() const {
VkInstance VulkanInstance::GetVkInstance() const {
return mInstance;
}
const VulkanGlobalInfo& Backend::GetGlobalInfo() const {
const VulkanGlobalInfo& VulkanInstance::GetGlobalInfo() const {
return mGlobalInfo;
}
MaybeError Backend::LoadVulkan(bool useSwiftshader) {
// First try to load the system Vulkan driver, if that fails, try to load with Swiftshader.
// Note: The system driver could potentially be Swiftshader if it was installed.
const std::vector<VkPhysicalDevice>& VulkanInstance::GetPhysicalDevices() const {
return mPhysicalDevices;
}
// static
ResultOrError<Ref<VulkanInstance>> VulkanInstance::Create(const InstanceBase* instance,
ICD icd) {
Ref<VulkanInstance> vulkanInstance = AcquireRef(new VulkanInstance());
DAWN_TRY(vulkanInstance->Initialize(instance, icd));
return std::move(vulkanInstance);
}
MaybeError VulkanInstance::Initialize(const InstanceBase* instance, ICD icd) {
// These environment variables need only be set while loading procs and gathering device
// info.
ScopedEnvironmentVar vkICDFilenames;
ScopedEnvironmentVar vkLayerPath;
#if defined(DAWN_ENABLE_VULKAN_LOADER)
// If enabled, we use our own built Vulkan loader by specifying an absolute path to the
// shared library. Note that when we are currently getting the absolute path for the custom
@ -126,49 +146,48 @@ namespace dawn_native { namespace vulkan {
#else
const std::string resolvedVulkanLibPath = kVulkanLibName;
#endif // defined(DAWN_ENABLE_VULKAN_LOADER)
if (mVulkanLib.Open(resolvedVulkanLibPath)) {
return {};
}
dawn::WarningLog() << std::string("Couldn't open ") + resolvedVulkanLibPath;
// If |useSwiftshader == true|, fallback and try to directly load the Swiftshader
// library.
if (useSwiftshader) {
switch (icd) {
case ICD::None: {
if (!mVulkanLib.Open(resolvedVulkanLibPath)) {
return DAWN_FORMAT_INTERNAL_ERROR("Couldn't load %s.", resolvedVulkanLibPath);
}
break;
}
case ICD::SwiftShader: {
#if defined(DAWN_ENABLE_SWIFTSHADER)
if (mVulkanLib.Open(kSwiftshaderLibName)) {
return {};
}
dawn::WarningLog() << std::string("Couldn't open ") + kSwiftshaderLibName;
#else
UNREACHABLE();
// First try to load the system Vulkan driver, if that fails, try to load with
// Swiftshader. Note: The system driver could potentially be Swiftshader if it was
// installed.
# if defined(DAWN_SWIFTSHADER_VK_ICD_JSON)
if (mVulkanLib.Open(resolvedVulkanLibPath)) {
std::string fullSwiftshaderICDPath =
GetExecutableDirectory() + DAWN_SWIFTSHADER_VK_ICD_JSON;
if (!vkICDFilenames.Set("VK_ICD_FILENAMES", fullSwiftshaderICDPath.c_str())) {
return DAWN_FORMAT_INTERNAL_ERROR("Couldn't set VK_ICD_FILENAMES to %s.",
fullSwiftshaderICDPath);
}
// Succesfully loaded driver and set VK_ICD_FILENAMES.
break;
} else
# endif // defined(DAWN_SWIFTSHADER_VK_ICD_JSON)
// Fallback to loading SwiftShader directly.
if (mVulkanLib.Open(kSwiftshaderLibName)) {
// Succesfully loaded SwiftShader.
break;
}
return DAWN_FORMAT_INTERNAL_ERROR(
"Failed to load SwiftShader. DAWN_SWIFTSHADER_VK_ICD_JSON was not defined and "
"could not load %s.",
kSwiftshaderLibName);
#endif // defined(DAWN_ENABLE_SWIFTSHADER)
}
return DAWN_INTERNAL_ERROR("Couldn't load Vulkan");
}
MaybeError Backend::Initialize(bool useSwiftshader) {
DAWN_TRY(LoadVulkan(useSwiftshader));
// These environment variables need only be set while loading procs and gathering device
// info.
ScopedEnvironmentVar vkICDFilenames;
ScopedEnvironmentVar vkLayerPath;
if (useSwiftshader) {
#if defined(DAWN_SWIFTSHADER_VK_ICD_JSON)
std::string fullSwiftshaderICDPath =
GetExecutableDirectory() + DAWN_SWIFTSHADER_VK_ICD_JSON;
if (!vkICDFilenames.Set("VK_ICD_FILENAMES", fullSwiftshaderICDPath.c_str())) {
return DAWN_INTERNAL_ERROR("Couldn't set VK_ICD_FILENAMES");
// ICD::SwiftShader should not be passed if SwiftShader is not enabled.
UNREACHABLE();
}
#else
dawn::WarningLog() << "Swiftshader enabled but Dawn was not built with "
"DAWN_SWIFTSHADER_VK_ICD_JSON.";
#endif
}
if (GetInstance()->IsBackendValidationEnabled()) {
if (instance->IsBackendValidationEnabled()) {
#if defined(DAWN_ENABLE_VULKAN_VALIDATION_LAYERS)
std::string vkDataDir = GetExecutableDirectory() + DAWN_VK_DATA_DIR;
if (!vkLayerPath.Set("VK_LAYER_PATH", vkDataDir.c_str())) {
@ -182,10 +201,10 @@ namespace dawn_native { namespace vulkan {
DAWN_TRY(mFunctions.LoadGlobalProcs(mVulkanLib));
DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(*this));
DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(mFunctions));
VulkanGlobalKnobs usedGlobalKnobs = {};
DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance());
DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateVkInstance(instance));
*static_cast<VulkanGlobalKnobs*>(&mGlobalInfo) = usedGlobalKnobs;
DAWN_TRY(mFunctions.LoadInstanceProcs(mInstance, mGlobalInfo));
@ -194,28 +213,13 @@ namespace dawn_native { namespace vulkan {
DAWN_TRY(RegisterDebugUtils());
}
DAWN_TRY_ASSIGN(mPhysicalDevices, GetPhysicalDevices(*this));
DAWN_TRY_ASSIGN(mPhysicalDevices, GatherPhysicalDevices(mInstance, mFunctions));
return {};
}
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
std::vector<std::unique_ptr<AdapterBase>> adapters;
for (VkPhysicalDevice physicalDevice : mPhysicalDevices) {
std::unique_ptr<Adapter> adapter = std::make_unique<Adapter>(this, physicalDevice);
if (GetInstance()->ConsumedError(adapter->Initialize())) {
continue;
}
adapters.push_back(std::move(adapter));
}
return adapters;
}
ResultOrError<VulkanGlobalKnobs> Backend::CreateInstance() {
ResultOrError<VulkanGlobalKnobs> VulkanInstance::CreateVkInstance(
const InstanceBase* instance) {
VulkanGlobalKnobs usedKnobs = {};
std::vector<const char*> layerNames;
InstanceExtSet extensionsToRequest = mGlobalInfo.extensions;
@ -242,7 +246,7 @@ namespace dawn_native { namespace vulkan {
UseLayerIfAvailable(VulkanLayer::RenderDocCapture);
#endif
if (GetInstance()->IsBackendValidationEnabled()) {
if (instance->IsBackendValidationEnabled()) {
UseLayerIfAvailable(VulkanLayer::Validation);
}
@ -315,7 +319,7 @@ namespace dawn_native { namespace vulkan {
VkValidationFeaturesEXT validationFeatures;
VkValidationFeatureEnableEXT kEnableSynchronizationValidation =
VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT;
if (GetInstance()->IsBackendValidationEnabled() &&
if (instance->IsBackendValidationEnabled() &&
usedKnobs.HasExt(InstanceExt::ValidationFeatures)) {
validationFeatures.enabledValidationFeatureCount = 1;
validationFeatures.pEnabledValidationFeatures = &kEnableSynchronizationValidation;
@ -331,7 +335,7 @@ namespace dawn_native { namespace vulkan {
return usedKnobs;
}
MaybeError Backend::RegisterDebugUtils() {
MaybeError VulkanInstance::RegisterDebugUtils() {
VkDebugUtilsMessengerCreateInfoEXT createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
createInfo.pNext = nullptr;
@ -348,15 +352,41 @@ namespace dawn_native { namespace vulkan {
"vkCreateDebugUtilsMessengerEXT");
}
BackendConnection* Connect(InstanceBase* instance, bool useSwiftshader) {
Backend* backend = new Backend(instance);
Backend::Backend(InstanceBase* instance)
: BackendConnection(instance, wgpu::BackendType::Vulkan) {
}
if (instance->ConsumedError(backend->Initialize(useSwiftshader))) {
delete backend;
return nullptr;
Backend::~Backend() = default;
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
std::vector<std::unique_ptr<AdapterBase>> adapters;
InstanceBase* instance = GetInstance();
for (ICD icd : kICDs) {
if (mVulkanInstances[icd] == nullptr && instance->ConsumedError([&]() -> MaybeError {
DAWN_TRY_ASSIGN(mVulkanInstances[icd], VulkanInstance::Create(instance, icd));
return {};
}())) {
// Instance failed to initialize.
continue;
}
const std::vector<VkPhysicalDevice>& physicalDevices =
mVulkanInstances[icd]->GetPhysicalDevices();
for (uint32_t i = 0; i < physicalDevices.size(); ++i) {
std::unique_ptr<Adapter> adapter = std::make_unique<Adapter>(
instance, mVulkanInstances[icd].Get(), physicalDevices[i]);
if (instance->ConsumedError(adapter->Initialize())) {
continue;
}
adapters.push_back(std::move(adapter));
}
}
return backend;
return adapters;
}
BackendConnection* Connect(InstanceBase* instance) {
return new Backend(instance);
}
}} // namespace dawn_native::vulkan

View File

@ -18,27 +18,41 @@
#include "dawn_native/BackendConnection.h"
#include "common/DynamicLib.h"
#include "common/RefCounted.h"
#include "common/ityp_array.h"
#include "dawn_native/vulkan/VulkanFunctions.h"
#include "dawn_native/vulkan/VulkanInfo.h"
namespace dawn_native { namespace vulkan {
class Backend : public BackendConnection {
enum class ICD {
None,
SwiftShader,
};
// VulkanInstance holds the reference to the Vulkan library, the VkInstance, VkPhysicalDevices
// on that instance, Vulkan functions loaded from the library, and global information
// gathered from the instance. VkPhysicalDevices bound to the VkInstance are bound to the GPU
// and GPU driver, keeping them active. It is RefCounted so that (eventually) when all adapters
// on an instance are no longer in use, the instance is deleted. This can be particuarly useful
// when we create multiple instances to selectively discover ICDs (like only
// SwiftShader/iGPU/dGPU/eGPU), and only one physical device on one instance remains in use. We
// can delete the VkInstances that are not in use to avoid holding the discrete GPU active.
class VulkanInstance : public RefCounted {
public:
Backend(InstanceBase* instance);
~Backend() override;
static ResultOrError<Ref<VulkanInstance>> Create(const InstanceBase* instance, ICD icd);
~VulkanInstance();
const VulkanFunctions& GetFunctions() const;
VkInstance GetVkInstance() const;
const VulkanGlobalInfo& GetGlobalInfo() const;
MaybeError Initialize(bool useSwiftshader);
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
const std::vector<VkPhysicalDevice>& GetPhysicalDevices() const;
private:
MaybeError LoadVulkan(bool useSwiftshader);
ResultOrError<VulkanGlobalKnobs> CreateInstance();
VulkanInstance();
MaybeError Initialize(const InstanceBase* instance, ICD icd);
ResultOrError<VulkanGlobalKnobs> CreateVkInstance(const InstanceBase* instance);
MaybeError RegisterDebugUtils();
@ -52,6 +66,19 @@ namespace dawn_native { namespace vulkan {
std::vector<VkPhysicalDevice> mPhysicalDevices;
};
class Backend : public BackendConnection {
public:
Backend(InstanceBase* instance);
~Backend() override;
MaybeError Initialize();
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
private:
ityp::array<ICD, Ref<VulkanInstance>, 2> mVulkanInstances = {};
};
}} // namespace dawn_native::vulkan
#endif // DAWNNATIVE_VULKAN_BACKENDVK_H_

View File

@ -63,7 +63,7 @@ namespace dawn_native { namespace vulkan {
// Initialize the "instance" procs of our local function table.
VulkanFunctions* functions = GetMutableFunctions();
*functions = ToBackend(GetAdapter())->GetBackend()->GetFunctions();
*functions = ToBackend(GetAdapter())->GetVulkanInstance()->GetFunctions();
// Two things are crucial if device initialization fails: the function pointers to destroy
// objects, and the fence deleter that calls these functions. Do not do anything before
@ -196,14 +196,14 @@ namespace dawn_native { namespace vulkan {
}
VkInstance Device::GetVkInstance() const {
return ToBackend(GetAdapter())->GetBackend()->GetVkInstance();
return ToBackend(GetAdapter())->GetVulkanInstance()->GetVkInstance();
}
const VulkanDeviceInfo& Device::GetDeviceInfo() const {
return mDeviceInfo;
}
const VulkanGlobalInfo& Device::GetGlobalInfo() const {
return ToBackend(GetAdapter())->GetBackend()->GetGlobalInfo();
return ToBackend(GetAdapter())->GetVulkanInstance()->GetGlobalInfo();
}
VkDevice Device::GetVkDevice() const {

View File

@ -86,10 +86,10 @@ namespace dawn_native { namespace vulkan {
namespace {
ResultOrError<VkSurfaceKHR> CreateVulkanSurface(Backend* backend, Surface* surface) {
const VulkanGlobalInfo& info = backend->GetGlobalInfo();
const VulkanFunctions& fn = backend->GetFunctions();
VkInstance instance = backend->GetVkInstance();
ResultOrError<VkSurfaceKHR> CreateVulkanSurface(Adapter* adapter, Surface* surface) {
const VulkanGlobalInfo& info = adapter->GetVulkanInstance()->GetGlobalInfo();
const VulkanFunctions& fn = adapter->GetVulkanInstance()->GetFunctions();
VkInstance instance = adapter->GetVulkanInstance()->GetVkInstance();
// May not be used in the platform-specific switches below.
DAWN_UNUSED(info);
@ -155,7 +155,7 @@ namespace dawn_native { namespace vulkan {
// See https://xcb.freedesktop.org/MixingCalls/ for more information about
// interoperability between Xlib and XCB
const XlibXcbFunctions* xlibXcb =
backend->GetInstance()->GetOrCreateXlibXcbFunctions();
adapter->GetInstance()->GetOrCreateXlibXcbFunctions();
ASSERT(xlibXcb != nullptr);
if (info.HasExt(InstanceExt::XcbSurface) && xlibXcb->IsLoaded()) {
@ -275,7 +275,7 @@ namespace dawn_native { namespace vulkan {
}
if (mVkSurface == VK_NULL_HANDLE) {
DAWN_TRY_ASSIGN(mVkSurface, CreateVulkanSurface(adapter->GetBackend(), GetSurface()));
DAWN_TRY_ASSIGN(mVkSurface, CreateVulkanSurface(adapter, GetSurface()));
}
VulkanSurfaceInfo surfaceInfo;

View File

@ -61,10 +61,8 @@ namespace dawn_native { namespace vulkan {
return extensions[ext];
}
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Backend& backend) {
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const VulkanFunctions& vkFunctions) {
VulkanGlobalInfo info = {};
const VulkanFunctions& vkFunctions = backend.GetFunctions();
// Gather info on available API version
{
info.apiVersion = VK_MAKE_VERSION(1, 0, 0);
@ -121,10 +119,9 @@ namespace dawn_native { namespace vulkan {
return std::move(info);
}
ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Backend& backend) {
VkInstance instance = backend.GetVkInstance();
const VulkanFunctions& vkFunctions = backend.GetFunctions();
ResultOrError<std::vector<VkPhysicalDevice>> GatherPhysicalDevices(
VkInstance instance,
const VulkanFunctions& vkFunctions) {
uint32_t count = 0;
VkResult result =
VkResult::WrapUnsafe(vkFunctions.EnumeratePhysicalDevices(instance, &count, nullptr));
@ -143,8 +140,8 @@ namespace dawn_native { namespace vulkan {
ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
VulkanDeviceInfo info = {};
VkPhysicalDevice physicalDevice = adapter.GetPhysicalDevice();
const VulkanGlobalInfo& globalInfo = adapter.GetBackend()->GetGlobalInfo();
const VulkanFunctions& vkFunctions = adapter.GetBackend()->GetFunctions();
const VulkanGlobalInfo& globalInfo = adapter.GetVulkanInstance()->GetGlobalInfo();
const VulkanFunctions& vkFunctions = adapter.GetVulkanInstance()->GetFunctions();
// Query the device properties first to get the ICD's `apiVersion`
vkFunctions.GetPhysicalDeviceProperties(physicalDevice, &info.properties);
@ -276,7 +273,7 @@ namespace dawn_native { namespace vulkan {
VulkanSurfaceInfo info = {};
VkPhysicalDevice physicalDevice = adapter.GetPhysicalDevice();
const VulkanFunctions& vkFunctions = adapter.GetBackend()->GetFunctions();
const VulkanFunctions& vkFunctions = adapter.GetVulkanInstance()->GetFunctions();
// Get the surface capabilities
DAWN_TRY(CheckVkSuccess(vkFunctions.GetPhysicalDeviceSurfaceCapabilitiesKHR(

View File

@ -26,6 +26,7 @@ namespace dawn_native { namespace vulkan {
class Adapter;
class Backend;
struct VulkanFunctions;
// Global information - gathered before the instance is created
struct VulkanGlobalKnobs {
@ -76,8 +77,10 @@ namespace dawn_native { namespace vulkan {
std::vector<bool> supportedQueueFamilies;
};
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Backend& backend);
ResultOrError<std::vector<VkPhysicalDevice>> GetPhysicalDevices(const Backend& backend);
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const VulkanFunctions& vkFunctions);
ResultOrError<std::vector<VkPhysicalDevice>> GatherPhysicalDevices(
VkInstance instance,
const VulkanFunctions& vkFunctions);
ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Adapter& adapter);
ResultOrError<VulkanSurfaceInfo> GatherSurfaceInfo(const Adapter& adapter,
VkSurfaceKHR surface);