From d1be0e70770849c093154fd0892f0495328ed8c2 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Mon, 4 Feb 2019 09:31:09 +0000 Subject: [PATCH] Vulkan: Implement the backend connection and adapter. This also changes VulkanInfo to gather info on backends / adapters instead of the device, because all the info gathering can happen before the device is created. BUG=dawn:29 Change-Id: I9dc4412f494428f1ae589544d3adf76fe8b9a3a3 Reviewed-on: https://dawn-review.googlesource.com/c/3941 Commit-Queue: Corentin Wallez Reviewed-by: Kai Ninomiya --- BUILD.gn | 4 + src/dawn_native/vulkan/AdapterVk.cpp | 56 +++++ src/dawn_native/vulkan/AdapterVk.h | 48 ++++ src/dawn_native/vulkan/BackendVk.cpp | 224 ++++++++++++++++++ src/dawn_native/vulkan/BackendVk.h | 64 +++++ src/dawn_native/vulkan/DeviceVk.cpp | 211 +---------------- src/dawn_native/vulkan/DeviceVk.h | 35 +-- src/dawn_native/vulkan/FencedDeleter.cpp | 2 +- .../vulkan/NativeSwapChainImplVk.cpp | 3 +- src/dawn_native/vulkan/VulkanBackend.cpp | 8 +- src/dawn_native/vulkan/VulkanInfo.cpp | 81 ++++--- src/dawn_native/vulkan/VulkanInfo.h | 12 +- src/include/dawn_native/VulkanBackend.h | 5 +- src/utils/VulkanBinding.cpp | 19 +- 14 files changed, 486 insertions(+), 286 deletions(-) create mode 100644 src/dawn_native/vulkan/AdapterVk.cpp create mode 100644 src/dawn_native/vulkan/AdapterVk.h create mode 100644 src/dawn_native/vulkan/BackendVk.cpp create mode 100644 src/dawn_native/vulkan/BackendVk.h diff --git a/BUILD.gn b/BUILD.gn index 92370bec12..0cac20f881 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -649,6 +649,10 @@ source_set("libdawn_native_sources") { if (dawn_enable_vulkan) { deps += [ "third_party:vulkan_headers" ] sources += [ + "src/dawn_native/vulkan/AdapterVk.cpp", + "src/dawn_native/vulkan/AdapterVk.h", + "src/dawn_native/vulkan/BackendVk.cpp", + "src/dawn_native/vulkan/BackendVk.h", "src/dawn_native/vulkan/BindGroupLayoutVk.cpp", "src/dawn_native/vulkan/BindGroupLayoutVk.h", "src/dawn_native/vulkan/BindGroupVk.cpp", diff --git a/src/dawn_native/vulkan/AdapterVk.cpp b/src/dawn_native/vulkan/AdapterVk.cpp new file mode 100644 index 0000000000..60c350a4a2 --- /dev/null +++ b/src/dawn_native/vulkan/AdapterVk.cpp @@ -0,0 +1,56 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn_native/vulkan/AdapterVk.h" + +#include "dawn_native/vulkan/BackendVk.h" +#include "dawn_native/vulkan/DeviceVk.h" + +namespace dawn_native { namespace vulkan { + + Adapter::Adapter(Backend* backend, VkPhysicalDevice physicalDevice) + : AdapterBase(backend->GetInstance(), BackendType::Vulkan), + mPhysicalDevice(physicalDevice), + mBackend(backend) { + } + + const VulkanDeviceInfo& Adapter::GetDeviceInfo() const { + return mDeviceInfo; + } + + VkPhysicalDevice Adapter::GetPhysicalDevice() const { + return mPhysicalDevice; + } + + Backend* Adapter::GetBackend() const { + return mBackend; + } + + MaybeError Adapter::Initialize() { + DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this)); + + mPCIInfo.deviceId = mDeviceInfo.properties.deviceID; + mPCIInfo.vendorId = mDeviceInfo.properties.vendorID; + mPCIInfo.name = mDeviceInfo.properties.deviceName; + + return {}; + } + + ResultOrError Adapter::CreateDeviceImpl() { + std::unique_ptr device = std::make_unique(this); + DAWN_TRY(device->Initialize()); + return device.release(); + } + +}} // namespace dawn_native::vulkan diff --git a/src/dawn_native/vulkan/AdapterVk.h b/src/dawn_native/vulkan/AdapterVk.h new file mode 100644 index 0000000000..acc4f51878 --- /dev/null +++ b/src/dawn_native/vulkan/AdapterVk.h @@ -0,0 +1,48 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef DAWNNATIVE_VULKAN_ADAPTERVK_H_ +#define DAWNNATIVE_VULKAN_ADAPTERVK_H_ + +#include "dawn_native/Adapter.h" + +#include "common/vulkan_platform.h" +#include "dawn_native/vulkan/VulkanInfo.h" + +namespace dawn_native { namespace vulkan { + + class Backend; + + class Adapter : public AdapterBase { + public: + Adapter(Backend* backend, VkPhysicalDevice physicalDevice); + virtual ~Adapter() = default; + + const VulkanDeviceInfo& GetDeviceInfo() const; + VkPhysicalDevice GetPhysicalDevice() const; + Backend* GetBackend() const; + + MaybeError Initialize(); + + private: + ResultOrError CreateDeviceImpl() override; + + VkPhysicalDevice mPhysicalDevice; + Backend* mBackend; + VulkanDeviceInfo mDeviceInfo = {}; + }; + +}} // namespace dawn_native::vulkan + +#endif // DAWNNATIVE_VULKAN_ADAPTERVK_H_ diff --git a/src/dawn_native/vulkan/BackendVk.cpp b/src/dawn_native/vulkan/BackendVk.cpp new file mode 100644 index 0000000000..ecd263f92e --- /dev/null +++ b/src/dawn_native/vulkan/BackendVk.cpp @@ -0,0 +1,224 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn_native/vulkan/BackendVk.h" + +#include "dawn_native/Instance.h" +#include "dawn_native/VulkanBackend.h" +#include "dawn_native/vulkan/AdapterVk.h" +#include "dawn_native/vulkan/VulkanError.h" + +#include + +#if DAWN_PLATFORM_LINUX +const char kVulkanLibName[] = "libvulkan.so.1"; +#elif DAWN_PLATFORM_WINDOWS +const char kVulkanLibName[] = "vulkan-1.dll"; +#else +# error "Unimplemented Vulkan backend platform" +#endif + +namespace dawn_native { namespace vulkan { + + Backend::Backend(InstanceBase* instance) : BackendConnection(instance, BackendType::Vulkan) { + } + + Backend::~Backend() { + if (mDebugReportCallback != VK_NULL_HANDLE) { + mFunctions.DestroyDebugReportCallbackEXT(mInstance, mDebugReportCallback, nullptr); + mDebugReportCallback = VK_NULL_HANDLE; + } + + // VkPhysicalDevices are destroyed when the VkInstance is destroyed + if (mInstance != VK_NULL_HANDLE) { + mFunctions.DestroyInstance(mInstance, nullptr); + mInstance = VK_NULL_HANDLE; + } + } + + const VulkanFunctions& Backend::GetFunctions() const { + return mFunctions; + } + + VkInstance Backend::GetVkInstance() const { + return mInstance; + } + + MaybeError Backend::Initialize() { + if (!mVulkanLib.Open(kVulkanLibName)) { + return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't open ") + kVulkanLibName); + } + + DAWN_TRY(mFunctions.LoadGlobalProcs(mVulkanLib)); + + DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(*this)); + + VulkanGlobalKnobs usedGlobalKnobs = {}; + DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance()); + *static_cast(&mGlobalInfo) = usedGlobalKnobs; + + DAWN_TRY(mFunctions.LoadInstanceProcs(mInstance, mGlobalInfo)); + + if (usedGlobalKnobs.debugReport) { + DAWN_TRY(RegisterDebugReport()); + } + + DAWN_TRY_ASSIGN(mPhysicalDevices, GetPhysicalDevices(*this)); + + return {}; + } + + std::vector> Backend::DiscoverDefaultAdapters() { + std::vector> adapters; + + for (VkPhysicalDevice physicalDevice : mPhysicalDevices) { + std::unique_ptr adapter = std::make_unique(this, physicalDevice); + + if (GetInstance()->ConsumedError(adapter->Initialize())) { + continue; + } + + adapters.push_back(std::move(adapter)); + } + + return adapters; + } + + ResultOrError Backend::CreateInstance() { + VulkanGlobalKnobs usedKnobs = {}; + + std::vector layersToRequest; + std::vector extensionsToRequest; + + // vktrace works by instering a layer, but we hide it behind a macro due to the vktrace + // layer crashes when used without vktrace server started. See this vktrace issue: + // https://github.com/LunarG/VulkanTools/issues/254 + // Also it is good to put it in first position so that it doesn't see Vulkan calls inserted + // by other layers. +#if defined(DAWN_USE_VKTRACE) + if (mGlobalInfo.vktrace) { + layersToRequest.push_back(kLayerNameLunargVKTrace); + usedKnobs.vktrace = true; + } +#endif + // RenderDoc installs a layer at the system level for its capture but we don't want to use + // it unless we are debugging in RenderDoc so we hide it behind a macro. +#if defined(DAWN_USE_RENDERDOC) + if (mGlobalInfo.renderDocCapture) { + layersToRequest.push_back(kLayerNameRenderDocCapture); + usedKnobs.renderDocCapture = true; + } +#endif +#if defined(DAWN_ENABLE_ASSERTS) + if (mGlobalInfo.standardValidation) { + layersToRequest.push_back(kLayerNameLunargStandardValidation); + usedKnobs.standardValidation = true; + } + if (mGlobalInfo.debugReport) { + extensionsToRequest.push_back(kExtensionNameExtDebugReport); + usedKnobs.debugReport = true; + } +#endif + // Always request all extensions used to create VkSurfaceKHR objects so that they are + // always available for embedders looking to create VkSurfaceKHR on our VkInstance. + if (mGlobalInfo.macosSurface) { + extensionsToRequest.push_back(kExtensionNameMvkMacosSurface); + usedKnobs.macosSurface = true; + } + if (mGlobalInfo.surface) { + extensionsToRequest.push_back(kExtensionNameKhrSurface); + usedKnobs.surface = true; + } + if (mGlobalInfo.waylandSurface) { + extensionsToRequest.push_back(kExtensionNameKhrWaylandSurface); + usedKnobs.waylandSurface = true; + } + if (mGlobalInfo.win32Surface) { + extensionsToRequest.push_back(kExtensionNameKhrWin32Surface); + usedKnobs.win32Surface = true; + } + if (mGlobalInfo.xcbSurface) { + extensionsToRequest.push_back(kExtensionNameKhrXcbSurface); + usedKnobs.xcbSurface = true; + } + if (mGlobalInfo.xlibSurface) { + extensionsToRequest.push_back(kExtensionNameKhrXlibSurface); + usedKnobs.xlibSurface = true; + } + + VkApplicationInfo appInfo; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pNext = nullptr; + appInfo.pApplicationName = nullptr; + appInfo.applicationVersion = 0; + appInfo.pEngineName = nullptr; + appInfo.engineVersion = 0; + appInfo.apiVersion = VK_API_VERSION_1_0; + + VkInstanceCreateInfo createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + createInfo.pNext = nullptr; + createInfo.flags = 0; + createInfo.pApplicationInfo = &appInfo; + createInfo.enabledLayerCount = static_cast(layersToRequest.size()); + createInfo.ppEnabledLayerNames = layersToRequest.data(); + createInfo.enabledExtensionCount = static_cast(extensionsToRequest.size()); + createInfo.ppEnabledExtensionNames = extensionsToRequest.data(); + + DAWN_TRY(CheckVkSuccess(mFunctions.CreateInstance(&createInfo, nullptr, &mInstance), + "vkCreateInstance")); + + return usedKnobs; + } + + MaybeError Backend::RegisterDebugReport() { + VkDebugReportCallbackCreateInfoEXT createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; + createInfo.pNext = nullptr; + createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; + createInfo.pfnCallback = Backend::OnDebugReportCallback; + createInfo.pUserData = this; + + return CheckVkSuccess(mFunctions.CreateDebugReportCallbackEXT( + mInstance, &createInfo, nullptr, &mDebugReportCallback), + "vkCreateDebugReportcallback"); + } + + VKAPI_ATTR VkBool32 VKAPI_CALL + Backend::OnDebugReportCallback(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT /*objectType*/, + uint64_t /*object*/, + size_t /*location*/, + int32_t /*messageCode*/, + const char* /*pLayerPrefix*/, + const char* pMessage, + void* /*pUserdata*/) { + std::cout << pMessage << std::endl; + ASSERT((flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) == 0); + + return VK_FALSE; + } + + BackendConnection* Connect(InstanceBase* instance) { + Backend* backend = new Backend(instance); + + if (instance->ConsumedError(backend->Initialize())) { + delete backend; + return nullptr; + } + + return backend; + } + +}} // namespace dawn_native::vulkan diff --git a/src/dawn_native/vulkan/BackendVk.h b/src/dawn_native/vulkan/BackendVk.h new file mode 100644 index 0000000000..b3ab47ec9b --- /dev/null +++ b/src/dawn_native/vulkan/BackendVk.h @@ -0,0 +1,64 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef DAWNNATIVE_VULKAN_BACKENDVK_H_ +#define DAWNNATIVE_VULKAN_BACKENDVK_H_ + +#include "dawn_native/BackendConnection.h" + +#include "common/DynamicLib.h" +#include "dawn_native/vulkan/VulkanFunctions.h" +#include "dawn_native/vulkan/VulkanInfo.h" + +namespace dawn_native { namespace vulkan { + + class Backend : public BackendConnection { + public: + Backend(InstanceBase* instance); + ~Backend() override; + + const VulkanFunctions& GetFunctions() const; + VkInstance GetVkInstance() const; + + MaybeError Initialize(); + + std::vector> DiscoverDefaultAdapters() override; + + private: + ResultOrError CreateInstance(); + + MaybeError RegisterDebugReport(); + static VKAPI_ATTR VkBool32 VKAPI_CALL + OnDebugReportCallback(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage, + void* pUserdata); + + DynamicLib mVulkanLib; + VulkanGlobalInfo mGlobalInfo = {}; + VkInstance mInstance = VK_NULL_HANDLE; + VulkanFunctions mFunctions; + + VkDebugReportCallbackEXT mDebugReportCallback = VK_NULL_HANDLE; + + std::vector mPhysicalDevices; + }; + +}} // namespace dawn_native::vulkan + +#endif // DAWNNATIVE_VULKAN_BACKENDVK_H_ diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index d42df54166..32873c3816 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -19,6 +19,8 @@ #include "dawn_native/Commands.h" #include "dawn_native/DynamicUploader.h" #include "dawn_native/ErrorData.h" +#include "dawn_native/vulkan/AdapterVk.h" +#include "dawn_native/vulkan/BackendVk.h" #include "dawn_native/vulkan/BindGroupLayoutVk.h" #include "dawn_native/vulkan/BindGroupVk.h" #include "dawn_native/vulkan/BufferUploader.h" @@ -38,72 +40,22 @@ #include "dawn_native/vulkan/TextureVk.h" #include "dawn_native/vulkan/VulkanError.h" -#include - -#include - -#if DAWN_PLATFORM_LINUX -const char kVulkanLibName[] = "libvulkan.so.1"; -#elif DAWN_PLATFORM_WINDOWS -const char kVulkanLibName[] = "vulkan-1.dll"; -#else -# error "Unimplemented Vulkan backend platform" -#endif - namespace dawn_native { namespace vulkan { - BackendConnection* Connect(InstanceBase* instance) { - return nullptr; - } - - // Device - - Device::Device() : DeviceBase(nullptr) { - MaybeError maybeError = Initialize(); - - // In device initialization, the error callback can't have been set yet. - // So it's too early to use ConsumedError - consume the error manually. - if (DAWN_UNLIKELY(maybeError.IsError())) { - ErrorData* error = maybeError.AcquireError(); - printf("Device initialization error: %s\n", error->GetMessage().c_str()); - delete error; - ASSERT(false); - return; - } + Device::Device(Adapter* adapter) : DeviceBase(adapter) { } MaybeError Device::Initialize() { - if (!mVulkanLib.Open(kVulkanLibName)) { - return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't open ") + kVulkanLibName); - } + // Copy the adapter's device info to the device so that we can change the "knobs" + mDeviceInfo = ToBackend(GetAdapter())->GetDeviceInfo(); VulkanFunctions* functions = GetMutableFunctions(); - DAWN_TRY(functions->LoadGlobalProcs(mVulkanLib)); + *functions = ToBackend(GetAdapter())->GetBackend()->GetFunctions(); - DAWN_TRY_ASSIGN(mGlobalInfo, GatherGlobalInfo(*this)); - - VulkanGlobalKnobs usedGlobalKnobs = {}; - DAWN_TRY_ASSIGN(usedGlobalKnobs, CreateInstance()); - *static_cast(&mGlobalInfo) = usedGlobalKnobs; - - DAWN_TRY(functions->LoadInstanceProcs(mInstance, mGlobalInfo)); - - if (usedGlobalKnobs.debugReport) { - DAWN_TRY(RegisterDebugReport()); - } - - std::vector physicalDevices; - DAWN_TRY_ASSIGN(physicalDevices, GetPhysicalDevices(*this)); - if (physicalDevices.empty()) { - return DAWN_CONTEXT_LOST_ERROR("No physical devices"); - } - // TODO(cwallez@chromium.org): Choose the physical device based on ??? - mPhysicalDevice = physicalDevices[0]; - - DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this, mPhysicalDevice)); + VkPhysicalDevice physicalDevice = ToBackend(GetAdapter())->GetPhysicalDevice(); VulkanDeviceKnobs usedDeviceKnobs = {}; - DAWN_TRY_ASSIGN(usedDeviceKnobs, CreateDevice()); + DAWN_TRY_ASSIGN(usedDeviceKnobs, CreateDevice(physicalDevice)); *static_cast(&mDeviceInfo) = usedDeviceKnobs; DAWN_TRY(functions->LoadDeviceProcs(mVkDevice, mDeviceInfo)); @@ -116,10 +68,6 @@ namespace dawn_native { namespace vulkan { mMemoryAllocator = std::make_unique(this); mRenderPassCache = std::make_unique(this); - mPCIInfo.deviceId = mDeviceInfo.properties.deviceID; - mPCIInfo.vendorId = mDeviceInfo.properties.vendorID; - mPCIInfo.name = mDeviceInfo.properties.deviceName; - return {}; } @@ -182,17 +130,6 @@ namespace dawn_native { namespace vulkan { fn.DestroyDevice(mVkDevice, nullptr); mVkDevice = VK_NULL_HANDLE; } - - if (mDebugReportCallback != VK_NULL_HANDLE) { - fn.DestroyDebugReportCallbackEXT(mInstance, mDebugReportCallback, nullptr); - mDebugReportCallback = VK_NULL_HANDLE; - } - - // VkPhysicalDevices are destroyed when the VkInstance is destroyed - if (mInstance != VK_NULL_HANDLE) { - fn.DestroyInstance(mInstance, nullptr); - mInstance = VK_NULL_HANDLE; - } } ResultOrError Device::CreateBindGroupImpl( @@ -283,22 +220,13 @@ namespace dawn_native { namespace vulkan { } } - const dawn_native::PCIInfo& Device::GetPCIInfo() const { - return mPCIInfo; + VkInstance Device::GetVkInstance() const { + return ToBackend(GetAdapter())->GetBackend()->GetVkInstance(); } - const VulkanDeviceInfo& Device::GetDeviceInfo() const { return mDeviceInfo; } - VkInstance Device::GetInstance() const { - return mInstance; - } - - VkPhysicalDevice Device::GetPhysicalDevice() const { - return mPhysicalDevice; - } - VkDevice Device::GetVkDevice() const { return mVkDevice; } @@ -392,94 +320,7 @@ namespace dawn_native { namespace vulkan { mWaitSemaphores.push_back(semaphore); } - ResultOrError Device::CreateInstance() { - VulkanGlobalKnobs usedKnobs = {}; - - std::vector layersToRequest; - std::vector extensionsToRequest; - - // vktrace works by instering a layer, but we hide it behind a macro due to the vktrace - // layer crashes when used without vktrace server started, see this vktrace issue: - // https://github.com/LunarG/VulkanTools/issues/254 - // Also it is good to put it in first position so that it doesn't see Vulkan calls inserted - // by other layers. -#if defined(DAWN_USE_VKTRACE) - if (mGlobalInfo.vktrace) { - layersToRequest.push_back(kLayerNameLunargVKTrace); - usedKnobs.vktrace = true; - } -#endif - // RenderDoc installs a layer at the system level for its capture but we don't want to use - // it unless we are debugging in RenderDoc so we hide it behind a macro. -#if defined(DAWN_USE_RENDERDOC) - if (mGlobalInfo.renderDocCapture) { - layersToRequest.push_back(kLayerNameRenderDocCapture); - usedKnobs.renderDocCapture = true; - } -#endif -#if defined(DAWN_ENABLE_ASSERTS) - if (mGlobalInfo.standardValidation) { - layersToRequest.push_back(kLayerNameLunargStandardValidation); - usedKnobs.standardValidation = true; - } - if (mGlobalInfo.debugReport) { - extensionsToRequest.push_back(kExtensionNameExtDebugReport); - usedKnobs.debugReport = true; - } -#endif - // Always request all extensions used to create VkSurfaceKHR objects so that they are - // always available for embedders looking to create VkSurfaceKHR on our VkInstance. - if (mGlobalInfo.macosSurface) { - extensionsToRequest.push_back(kExtensionNameMvkMacosSurface); - usedKnobs.macosSurface = true; - } - if (mGlobalInfo.surface) { - extensionsToRequest.push_back(kExtensionNameKhrSurface); - usedKnobs.surface = true; - } - if (mGlobalInfo.waylandSurface) { - extensionsToRequest.push_back(kExtensionNameKhrWaylandSurface); - usedKnobs.waylandSurface = true; - } - if (mGlobalInfo.win32Surface) { - extensionsToRequest.push_back(kExtensionNameKhrWin32Surface); - usedKnobs.win32Surface = true; - } - if (mGlobalInfo.xcbSurface) { - extensionsToRequest.push_back(kExtensionNameKhrXcbSurface); - usedKnobs.xcbSurface = true; - } - if (mGlobalInfo.xlibSurface) { - extensionsToRequest.push_back(kExtensionNameKhrXlibSurface); - usedKnobs.xlibSurface = true; - } - - VkApplicationInfo appInfo; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pNext = nullptr; - appInfo.pApplicationName = nullptr; - appInfo.applicationVersion = 0; - appInfo.pEngineName = nullptr; - appInfo.engineVersion = 0; - appInfo.apiVersion = VK_API_VERSION_1_0; - - VkInstanceCreateInfo createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - createInfo.pNext = nullptr; - createInfo.flags = 0; - createInfo.pApplicationInfo = &appInfo; - createInfo.enabledLayerCount = static_cast(layersToRequest.size()); - createInfo.ppEnabledLayerNames = layersToRequest.data(); - createInfo.enabledExtensionCount = static_cast(extensionsToRequest.size()); - createInfo.ppEnabledExtensionNames = extensionsToRequest.data(); - - DAWN_TRY(CheckVkSuccess(fn.CreateInstance(&createInfo, nullptr, &mInstance), - "vkCreateInstance")); - - return usedKnobs; - } - - ResultOrError Device::CreateDevice() { + ResultOrError Device::CreateDevice(VkPhysicalDevice physicalDevice) { VulkanDeviceKnobs usedKnobs = {}; float zero = 0.0f; @@ -541,7 +382,7 @@ namespace dawn_native { namespace vulkan { createInfo.ppEnabledExtensionNames = extensionsToRequest.data(); createInfo.pEnabledFeatures = &usedKnobs.features; - DAWN_TRY(CheckVkSuccess(fn.CreateDevice(mPhysicalDevice, &createInfo, nullptr, &mVkDevice), + DAWN_TRY(CheckVkSuccess(fn.CreateDevice(physicalDevice, &createInfo, nullptr, &mVkDevice), "vkCreateDevice")); return usedKnobs; @@ -551,34 +392,6 @@ namespace dawn_native { namespace vulkan { fn.GetDeviceQueue(mVkDevice, mQueueFamily, 0, &mQueue); } - MaybeError Device::RegisterDebugReport() { - VkDebugReportCallbackCreateInfoEXT createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; - createInfo.pNext = nullptr; - createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; - createInfo.pfnCallback = Device::OnDebugReportCallback; - createInfo.pUserData = this; - - return CheckVkSuccess( - fn.CreateDebugReportCallbackEXT(mInstance, &createInfo, nullptr, &mDebugReportCallback), - "vkCreateDebugReportcallback"); - } - - VKAPI_ATTR VkBool32 VKAPI_CALL - Device::OnDebugReportCallback(VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT /*objectType*/, - uint64_t /*object*/, - size_t /*location*/, - int32_t /*messageCode*/, - const char* /*pLayerPrefix*/, - const char* pMessage, - void* /*pUserdata*/) { - std::cout << pMessage << std::endl; - ASSERT((flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) == 0); - - return VK_FALSE; - } - VulkanFunctions* Device::GetMutableFunctions() { return const_cast(&fn); } diff --git a/src/dawn_native/vulkan/DeviceVk.h b/src/dawn_native/vulkan/DeviceVk.h index 27139cb35c..aefd00dcfc 100644 --- a/src/dawn_native/vulkan/DeviceVk.h +++ b/src/dawn_native/vulkan/DeviceVk.h @@ -17,7 +17,6 @@ #include "dawn_native/dawn_platform.h" -#include "common/DynamicLib.h" #include "common/Serial.h" #include "common/SerialQueue.h" #include "dawn_native/Device.h" @@ -30,6 +29,7 @@ namespace dawn_native { namespace vulkan { + class Adapter; class BufferUploader; class FencedDeleter; class MapRequestTracker; @@ -38,15 +38,16 @@ namespace dawn_native { namespace vulkan { class Device : public DeviceBase { public: - Device(); + Device(Adapter* adapter); ~Device(); + MaybeError Initialize(); + // Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo. const VulkanFunctions fn; + VkInstance GetVkInstance() const; const VulkanDeviceInfo& GetDeviceInfo() const; - VkInstance GetInstance() const; - VkPhysicalDevice GetPhysicalDevice() const; VkDevice GetVkDevice() const; uint32_t GetGraphicsQueueFamily() const; VkQueue GetQueue() const; @@ -73,8 +74,6 @@ namespace dawn_native { namespace vulkan { Serial GetLastSubmittedCommandSerial() const final override; void TickImpl() override; - const dawn_native::PCIInfo& GetPCIInfo() const override; - ResultOrError> CreateStagingBuffer(size_t size) override; MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, uint32_t sourceOffset, @@ -103,37 +102,17 @@ namespace dawn_native { namespace vulkan { TextureBase* texture, const TextureViewDescriptor* descriptor) override; - MaybeError Initialize(); - ResultOrError CreateInstance(); - ResultOrError CreateDevice(); + ResultOrError CreateDevice(VkPhysicalDevice physicalDevice); void GatherQueueFromDevice(); - MaybeError RegisterDebugReport(); - static VKAPI_ATTR VkBool32 VKAPI_CALL - OnDebugReportCallback(VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage, - void* pUserdata); - // To make it easier to use fn it is a public const member. However // the Device is allowed to mutate them through these private methods. VulkanFunctions* GetMutableFunctions(); - VulkanGlobalInfo mGlobalInfo = {}; VulkanDeviceInfo mDeviceInfo = {}; - - DynamicLib mVulkanLib; - - VkInstance mInstance = VK_NULL_HANDLE; - VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE; VkDevice mVkDevice = VK_NULL_HANDLE; uint32_t mQueueFamily = 0; VkQueue mQueue = VK_NULL_HANDLE; - VkDebugReportCallbackEXT mDebugReportCallback = VK_NULL_HANDLE; std::unique_ptr mBufferUploader; std::unique_ptr mDeleter; @@ -166,8 +145,6 @@ namespace dawn_native { namespace vulkan { std::vector mUnusedCommands; CommandPoolAndBuffer mPendingCommands; std::vector mWaitSemaphores; - - dawn_native::PCIInfo mPCIInfo; }; }} // namespace dawn_native::vulkan diff --git a/src/dawn_native/vulkan/FencedDeleter.cpp b/src/dawn_native/vulkan/FencedDeleter.cpp index 729ea29ae8..388eb93b2e 100644 --- a/src/dawn_native/vulkan/FencedDeleter.cpp +++ b/src/dawn_native/vulkan/FencedDeleter.cpp @@ -96,7 +96,7 @@ namespace dawn_native { namespace vulkan { void FencedDeleter::Tick(Serial completedSerial) { VkDevice vkDevice = mDevice->GetVkDevice(); - VkInstance instance = mDevice->GetInstance(); + VkInstance instance = mDevice->GetVkInstance(); // Buffers and images must be deleted before memories because it is invalid to free memory // that still have resources bound to it. diff --git a/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp b/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp index a1da700a51..e0121e527c 100644 --- a/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp +++ b/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp @@ -58,7 +58,8 @@ namespace dawn_native { namespace vulkan { } void NativeSwapChainImpl::Init(dawnWSIContextVulkan* /*context*/) { - if (mDevice->ConsumedError(GatherSurfaceInfo(*mDevice, mSurface, &mInfo))) { + if (mDevice->ConsumedError( + GatherSurfaceInfo(*ToBackend(mDevice->GetAdapter()), mSurface, &mInfo))) { ASSERT(false); } diff --git a/src/dawn_native/vulkan/VulkanBackend.cpp b/src/dawn_native/vulkan/VulkanBackend.cpp index ec169294ef..4880e75f9b 100644 --- a/src/dawn_native/vulkan/VulkanBackend.cpp +++ b/src/dawn_native/vulkan/VulkanBackend.cpp @@ -27,15 +27,13 @@ namespace dawn_native { namespace vulkan { - dawnDevice CreateDevice() { - return reinterpret_cast(new Device()); - } - VkInstance GetInstance(dawnDevice device) { Device* backendDevice = reinterpret_cast(device); - return backendDevice->GetInstance(); + return backendDevice->GetVkInstance(); } + // Explicitly export this function because it uses the "native" type for surfaces while the + // header as seen in this file uses the wrapped type. DAWN_NATIVE_EXPORT dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, VkSurfaceKHRNative surfaceNative) { Device* backendDevice = reinterpret_cast(device); diff --git a/src/dawn_native/vulkan/VulkanInfo.cpp b/src/dawn_native/vulkan/VulkanInfo.cpp index c8c11a84b9..4d7a30eb69 100644 --- a/src/dawn_native/vulkan/VulkanInfo.cpp +++ b/src/dawn_native/vulkan/VulkanInfo.cpp @@ -14,7 +14,8 @@ #include "dawn_native/vulkan/VulkanInfo.h" -#include "dawn_native/vulkan/DeviceVk.h" +#include "dawn_native/vulkan/AdapterVk.h" +#include "dawn_native/vulkan/BackendVk.h" #include @@ -43,13 +44,14 @@ namespace dawn_native { namespace vulkan { const char kExtensionNameKhrXcbSurface[] = "VK_KHR_xcb_surface"; const char kExtensionNameKhrXlibSurface[] = "VK_KHR_xlib_surface"; - ResultOrError GatherGlobalInfo(const Device& device) { + ResultOrError GatherGlobalInfo(const Backend& backend) { VulkanGlobalInfo info = {}; + const VulkanFunctions& vkFunctions = backend.GetFunctions(); // Gather the info about the instance layers { uint32_t count = 0; - VkResult result = device.fn.EnumerateInstanceLayerProperties(&count, nullptr); + VkResult result = vkFunctions.EnumerateInstanceLayerProperties(&count, nullptr); // From the Vulkan spec result should be success if there are 0 layers, // incomplete otherwise. This means that both values represent a success. // This is the same for all Enumarte functions @@ -58,7 +60,7 @@ namespace dawn_native { namespace vulkan { } info.layers.resize(count); - result = device.fn.EnumerateInstanceLayerProperties(&count, info.layers.data()); + result = vkFunctions.EnumerateInstanceLayerProperties(&count, info.layers.data()); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceLayerProperties"); } @@ -80,14 +82,14 @@ namespace dawn_native { namespace vulkan { { uint32_t count = 0; VkResult result = - device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, nullptr); + vkFunctions.EnumerateInstanceExtensionProperties(nullptr, &count, nullptr); if (result != VK_SUCCESS && result != VK_INCOMPLETE) { return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceExtensionProperties"); } info.extensions.resize(count); - result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, - info.extensions.data()); + result = vkFunctions.EnumerateInstanceExtensionProperties(nullptr, &count, + info.extensions.data()); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkEnumerateInstanceExtensionProperties"); } @@ -122,17 +124,18 @@ namespace dawn_native { namespace vulkan { return info; } - ResultOrError> GetPhysicalDevices(const Device& device) { - VkInstance instance = device.GetInstance(); + ResultOrError> GetPhysicalDevices(const Backend& backend) { + VkInstance instance = backend.GetVkInstance(); + const VulkanFunctions& vkFunctions = backend.GetFunctions(); uint32_t count = 0; - VkResult result = device.fn.EnumeratePhysicalDevices(instance, &count, nullptr); + VkResult result = vkFunctions.EnumeratePhysicalDevices(instance, &count, nullptr); if (result != VK_SUCCESS && result != VK_INCOMPLETE) { return DAWN_CONTEXT_LOST_ERROR("vkEnumeratePhysicalDevices"); } std::vector physicalDevices(count); - result = device.fn.EnumeratePhysicalDevices(instance, &count, physicalDevices.data()); + result = vkFunctions.EnumeratePhysicalDevices(instance, &count, physicalDevices.data()); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkEnumeratePhysicalDevices"); } @@ -140,18 +143,19 @@ namespace dawn_native { namespace vulkan { return physicalDevices; } - ResultOrError GatherDeviceInfo(const Device& device, - VkPhysicalDevice physicalDevice) { + ResultOrError GatherDeviceInfo(const Adapter& adapter) { VulkanDeviceInfo info = {}; + VkPhysicalDevice physicalDevice = adapter.GetPhysicalDevice(); + const VulkanFunctions& vkFunctions = adapter.GetBackend()->GetFunctions(); // Gather general info about the device - device.fn.GetPhysicalDeviceProperties(physicalDevice, &info.properties); - device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info.features); + vkFunctions.GetPhysicalDeviceProperties(physicalDevice, &info.properties); + vkFunctions.GetPhysicalDeviceFeatures(physicalDevice, &info.features); // Gather info about device memory. { VkPhysicalDeviceMemoryProperties memory; - device.fn.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory); + vkFunctions.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory); info.memoryTypes.assign(memory.memoryTypes, memory.memoryTypes + memory.memoryTypeCount); @@ -162,25 +166,25 @@ namespace dawn_native { namespace vulkan { // Gather info about device queue families { uint32_t count = 0; - device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr); + vkFunctions.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr); info.queueFamilies.resize(count); - device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, - info.queueFamilies.data()); + vkFunctions.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, + info.queueFamilies.data()); } // Gather the info about the device layers { uint32_t count = 0; VkResult result = - device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr); + vkFunctions.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr); if (result != VK_SUCCESS && result != VK_INCOMPLETE) { return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceLayerProperties"); } info.layers.resize(count); - result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, - info.layers.data()); + result = vkFunctions.EnumerateDeviceLayerProperties(physicalDevice, &count, + info.layers.data()); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceLayerProperties"); } @@ -189,15 +193,15 @@ namespace dawn_native { namespace vulkan { // Gather the info about the device extensions { uint32_t count = 0; - VkResult result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, - &count, nullptr); + VkResult result = vkFunctions.EnumerateDeviceExtensionProperties( + physicalDevice, nullptr, &count, nullptr); if (result != VK_SUCCESS && result != VK_INCOMPLETE) { return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceExtensionProperties"); } info.extensions.resize(count); - result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count, - info.extensions.data()); + result = vkFunctions.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count, + info.extensions.data()); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkEnumerateDeviceExtensionProperties"); } @@ -214,14 +218,15 @@ namespace dawn_native { namespace vulkan { return info; } - MaybeError GatherSurfaceInfo(const Device& device, + MaybeError GatherSurfaceInfo(const Adapter& adapter, VkSurfaceKHR surface, VulkanSurfaceInfo* info) { - VkPhysicalDevice physicalDevice = device.GetPhysicalDevice(); + VkPhysicalDevice physicalDevice = adapter.GetPhysicalDevice(); + const VulkanFunctions& vkFunctions = adapter.GetBackend()->GetFunctions(); // Get the surface capabilities { - VkResult result = device.fn.GetPhysicalDeviceSurfaceCapabilitiesKHR( + VkResult result = vkFunctions.GetPhysicalDeviceSurfaceCapabilitiesKHR( physicalDevice, surface, &info->capabilities); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); @@ -230,13 +235,13 @@ namespace dawn_native { namespace vulkan { // Query which queue families support presenting this surface { - size_t nQueueFamilies = device.GetDeviceInfo().queueFamilies.size(); + size_t nQueueFamilies = adapter.GetDeviceInfo().queueFamilies.size(); info->supportedQueueFamilies.resize(nQueueFamilies, false); for (uint32_t i = 0; i < nQueueFamilies; ++i) { VkBool32 supported = VK_FALSE; - VkResult result = device.fn.GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, - surface, &supported); + VkResult result = vkFunctions.GetPhysicalDeviceSurfaceSupportKHR( + physicalDevice, i, surface, &supported); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceSupportKHR"); @@ -249,15 +254,15 @@ namespace dawn_native { namespace vulkan { // Gather supported formats { uint32_t count = 0; - VkResult result = device.fn.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, - &count, nullptr); + VkResult result = vkFunctions.GetPhysicalDeviceSurfaceFormatsKHR( + physicalDevice, surface, &count, nullptr); if (result != VK_SUCCESS && result != VK_INCOMPLETE) { return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR"); } info->formats.resize(count); - result = device.fn.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count, - info->formats.data()); + result = vkFunctions.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count, + info->formats.data()); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR"); } @@ -266,14 +271,14 @@ namespace dawn_native { namespace vulkan { // Gather supported presents modes { uint32_t count = 0; - VkResult result = device.fn.GetPhysicalDeviceSurfacePresentModesKHR( + VkResult result = vkFunctions.GetPhysicalDeviceSurfacePresentModesKHR( physicalDevice, surface, &count, nullptr); if (result != VK_SUCCESS && result != VK_INCOMPLETE) { return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR"); } info->presentModes.resize(count); - result = device.fn.GetPhysicalDeviceSurfacePresentModesKHR( + result = vkFunctions.GetPhysicalDeviceSurfacePresentModesKHR( physicalDevice, surface, &count, info->presentModes.data()); if (result != VK_SUCCESS) { return DAWN_CONTEXT_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR"); diff --git a/src/dawn_native/vulkan/VulkanInfo.h b/src/dawn_native/vulkan/VulkanInfo.h index fee253b84a..77971dc427 100644 --- a/src/dawn_native/vulkan/VulkanInfo.h +++ b/src/dawn_native/vulkan/VulkanInfo.h @@ -22,7 +22,8 @@ namespace dawn_native { namespace vulkan { - class Device; + class Adapter; + class Backend; extern const char kLayerNameLunargStandardValidation[]; extern const char kLayerNameLunargVKTrace[]; @@ -87,11 +88,10 @@ namespace dawn_native { namespace vulkan { std::vector supportedQueueFamilies; }; - ResultOrError GatherGlobalInfo(const Device& device); - ResultOrError> GetPhysicalDevices(const Device& device); - ResultOrError GatherDeviceInfo(const Device& device, - VkPhysicalDevice physicalDevice); - MaybeError GatherSurfaceInfo(const Device& device, + ResultOrError GatherGlobalInfo(const Backend& backend); + ResultOrError> GetPhysicalDevices(const Backend& backend); + ResultOrError GatherDeviceInfo(const Adapter& adapter); + MaybeError GatherSurfaceInfo(const Adapter& adapter, VkSurfaceKHR surface, VulkanSurfaceInfo* info); }} // namespace dawn_native::vulkan diff --git a/src/include/dawn_native/VulkanBackend.h b/src/include/dawn_native/VulkanBackend.h index 9bf7a2a035..73f1a95913 100644 --- a/src/include/dawn_native/VulkanBackend.h +++ b/src/include/dawn_native/VulkanBackend.h @@ -15,17 +15,14 @@ #ifndef DAWNNATIVE_VULKANBACKEND_H_ #define DAWNNATIVE_VULKANBACKEND_H_ -#include #include -#include +#include #include #include namespace dawn_native { namespace vulkan { - DAWN_NATIVE_EXPORT dawnDevice CreateDevice(); - DAWN_NATIVE_EXPORT VkInstance GetInstance(dawnDevice device); DAWN_NATIVE_EXPORT dawnSwapChainImplementation CreateNativeSwapChainImpl(dawnDevice device, diff --git a/src/utils/VulkanBinding.cpp b/src/utils/VulkanBinding.cpp index 7cae7b4776..72baa71414 100644 --- a/src/utils/VulkanBinding.cpp +++ b/src/utils/VulkanBinding.cpp @@ -28,8 +28,20 @@ namespace utils { glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); } dawnDevice CreateDevice() override { - mDevice = dawn_native::vulkan::CreateDevice(); - return mDevice; + // Make an instance and find a Vulkan adapter + mInstance = std::make_unique(); + mInstance->DiscoverDefaultAdapters(); + + std::vector adapters = mInstance->GetAdapters(); + for (dawn_native::Adapter adapter : adapters) { + if (adapter.GetBackendType() == dawn_native::BackendType::Vulkan) { + mDevice = adapter.CreateDevice(); + return mDevice; + } + } + + UNREACHABLE(); + return {}; } uint64_t GetSwapChainImplementation() override { if (mSwapchainImpl.userData == nullptr) { @@ -49,7 +61,8 @@ namespace utils { } private: - dawnDevice mDevice; + std::unique_ptr mInstance; + dawnDevice mDevice = nullptr; dawnSwapChainImplementation mSwapchainImpl = {}; };