1 // Copyright 2019 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWNNATIVE_VULKAN_BACKENDVK_H_ 16 #define DAWNNATIVE_VULKAN_BACKENDVK_H_ 17 18 #include "dawn_native/BackendConnection.h" 19 20 #include "common/DynamicLib.h" 21 #include "common/RefCounted.h" 22 #include "common/ityp_array.h" 23 #include "dawn_native/vulkan/VulkanFunctions.h" 24 #include "dawn_native/vulkan/VulkanInfo.h" 25 26 namespace dawn_native { namespace vulkan { 27 28 enum class ICD { 29 None, 30 SwiftShader, 31 }; 32 33 // VulkanInstance holds the reference to the Vulkan library, the VkInstance, VkPhysicalDevices 34 // on that instance, Vulkan functions loaded from the library, and global information 35 // gathered from the instance. VkPhysicalDevices bound to the VkInstance are bound to the GPU 36 // and GPU driver, keeping them active. It is RefCounted so that (eventually) when all adapters 37 // on an instance are no longer in use, the instance is deleted. This can be particuarly useful 38 // when we create multiple instances to selectively discover ICDs (like only 39 // SwiftShader/iGPU/dGPU/eGPU), and only one physical device on one instance remains in use. We 40 // can delete the VkInstances that are not in use to avoid holding the discrete GPU active. 41 class VulkanInstance : public RefCounted { 42 public: 43 static ResultOrError<Ref<VulkanInstance>> Create(const InstanceBase* instance, ICD icd); 44 ~VulkanInstance(); 45 46 const VulkanFunctions& GetFunctions() const; 47 VkInstance GetVkInstance() const; 48 const VulkanGlobalInfo& GetGlobalInfo() const; 49 const std::vector<VkPhysicalDevice>& GetPhysicalDevices() const; 50 51 private: 52 VulkanInstance(); 53 54 MaybeError Initialize(const InstanceBase* instance, ICD icd); 55 ResultOrError<VulkanGlobalKnobs> CreateVkInstance(const InstanceBase* instance); 56 57 MaybeError RegisterDebugUtils(); 58 59 DynamicLib mVulkanLib; 60 VulkanGlobalInfo mGlobalInfo = {}; 61 VkInstance mInstance = VK_NULL_HANDLE; 62 VulkanFunctions mFunctions; 63 64 VkDebugUtilsMessengerEXT mDebugUtilsMessenger = VK_NULL_HANDLE; 65 66 std::vector<VkPhysicalDevice> mPhysicalDevices; 67 }; 68 69 class Backend : public BackendConnection { 70 public: 71 Backend(InstanceBase* instance); 72 ~Backend() override; 73 74 MaybeError Initialize(); 75 76 std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override; 77 ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters( 78 const AdapterDiscoveryOptionsBase* optionsBase) override; 79 80 private: 81 ityp::array<ICD, Ref<VulkanInstance>, 2> mVulkanInstances = {}; 82 }; 83 84 }} // namespace dawn_native::vulkan 85 86 #endif // DAWNNATIVE_VULKAN_BACKENDVK_H_ 87