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:
parent
1a57ee9d4e
commit
652293f14c
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 = {};
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue