• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // DeviceVk.cpp:
7 //    Implements the class methods for DeviceVk.
8 //
9 
10 #include "libANGLE/renderer/vulkan/DeviceVk.h"
11 
12 #include <stdint.h>
13 
14 #include "common/debug.h"
15 #include "common/vulkan/vulkan_icd.h"
16 #include "libANGLE/Display.h"
17 #include "libANGLE/renderer/vulkan/DisplayVk.h"
18 #include "libANGLE/renderer/vulkan/vk_renderer.h"
19 
20 namespace rx
21 {
22 namespace
23 {
24 
25 DeviceVk *gDevice = nullptr;
26 
27 class [[nodiscard]] ScopedEnv : public angle::vk::ScopedVkLoaderEnvironment
28 {
29   public:
ScopedEnv()30     ScopedEnv()
31         : angle::vk::ScopedVkLoaderEnvironment(
32               gDevice ? gDevice->getRenderer()->getEnableValidationLayers() : false,
33               gDevice ? gDevice->getRenderer()->getEnabledICD() : angle::vk::ICD::Default)
34     {
35         if (!gDevice)
36         {
37             WARN() << "No DeviceVk instance.";
38         }
39     }
40 };
41 
42 }  // namespace
43 
44 DeviceVk::DeviceVk() = default;
45 
~DeviceVk()46 DeviceVk::~DeviceVk()
47 {
48     if (gDevice == this)
49     {
50         gDevice = nullptr;
51     }
52 }
53 
initialize()54 egl::Error DeviceVk::initialize()
55 {
56     return egl::NoError();
57 }
58 
getAttribute(const egl::Display * display,EGLint attribute,void ** outValue)59 egl::Error DeviceVk::getAttribute(const egl::Display *display, EGLint attribute, void **outValue)
60 {
61     vk::Renderer *renderer =
62         static_cast<rx::DisplayVk *>(display->getImplementation())->getRenderer();
63     ASSERT(mRenderer == nullptr || mRenderer == renderer);
64     mRenderer = renderer;
65     switch (attribute)
66     {
67         case EGL_VULKAN_VERSION_ANGLE:
68         {
69             auto version = static_cast<intptr_t>(mRenderer->getDeviceVersion());
70             *outValue    = reinterpret_cast<void *>(version);
71             return egl::NoError();
72         }
73         case EGL_VULKAN_INSTANCE_ANGLE:
74         {
75             *outValue = mRenderer->getInstance();
76             return egl::NoError();
77         }
78         case EGL_VULKAN_DEVICE_ANGLE:
79         {
80             *outValue = mRenderer->getDevice();
81             return egl::NoError();
82         }
83         case EGL_VULKAN_PHYSICAL_DEVICE_ANGLE:
84         {
85             *outValue = mRenderer->getPhysicalDevice();
86             return egl::NoError();
87         }
88         case EGL_VULKAN_QUEUE_ANGLE:
89         {
90             // egl::ContextPriority::Medium is the default context priority.
91             *outValue = mRenderer->getQueue(egl::ContextPriority::Medium);
92             return egl::NoError();
93         }
94         case EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE:
95         {
96             intptr_t index = static_cast<intptr_t>(mRenderer->getQueueFamilyIndex());
97             *outValue      = reinterpret_cast<void *>(index);
98             return egl::NoError();
99         }
100         case EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE:
101         {
102             char **extensions = const_cast<char **>(mRenderer->getEnabledDeviceExtensions().data());
103             *outValue         = reinterpret_cast<void *>(extensions);
104             return egl::NoError();
105         }
106         case EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE:
107         {
108             char **extensions =
109                 const_cast<char **>(mRenderer->getEnabledInstanceExtensions().data());
110             *outValue = reinterpret_cast<void *>(extensions);
111             return egl::NoError();
112         }
113         case EGL_VULKAN_FEATURES_ANGLE:
114         {
115             const auto *features = &mRenderer->getEnabledFeatures();
116             *outValue            = const_cast<void *>(reinterpret_cast<const void *>(features));
117             return egl::NoError();
118         }
119         case EGL_VULKAN_GET_INSTANCE_PROC_ADDR:
120         {
121             *outValue = reinterpret_cast<void *>(DeviceVk::WrappedGetInstanceProcAddr);
122             ASSERT(!gDevice || gDevice == this);
123             gDevice = this;
124             return egl::NoError();
125         }
126         default:
127             return egl::Error(EGL_BAD_ACCESS);
128     }
129 }
130 
generateExtensions(egl::DeviceExtensions * outExtensions) const131 void DeviceVk::generateExtensions(egl::DeviceExtensions *outExtensions) const
132 {
133     outExtensions->deviceVulkan = true;
134 }
135 
136 // static
137 VKAPI_ATTR VkResult VKAPI_CALL
WrappedCreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)138 DeviceVk::WrappedCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
139                                 const VkAllocationCallbacks *pAllocator,
140                                 VkInstance *pInstance)
141 {
142     ScopedEnv scopedEnv;
143     return vkCreateInstance(pCreateInfo, pAllocator, pInstance);
144 }
145 
146 // static
147 VKAPI_ATTR VkResult VKAPI_CALL
WrappedEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)148 DeviceVk::WrappedEnumerateInstanceExtensionProperties(const char *pLayerName,
149                                                       uint32_t *pPropertyCount,
150                                                       VkExtensionProperties *pProperties)
151 {
152     ScopedEnv scopedEnv;
153     return vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
154 }
155 
156 // static
157 VKAPI_ATTR VkResult VKAPI_CALL
WrappedEnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)158 DeviceVk::WrappedEnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
159                                                   VkLayerProperties *pProperties)
160 {
161     ScopedEnv scopedEnv;
162     return vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
163 }
164 
165 // static
WrappedEnumerateInstanceVersion(uint32_t * pApiVersion)166 VKAPI_ATTR VkResult VKAPI_CALL DeviceVk::WrappedEnumerateInstanceVersion(uint32_t *pApiVersion)
167 {
168     ScopedEnv scopedEnv;
169     return vkEnumerateInstanceVersion(pApiVersion);
170 }
171 
172 // static
WrappedGetInstanceProcAddr(VkInstance instance,const char * pName)173 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL DeviceVk::WrappedGetInstanceProcAddr(VkInstance instance,
174                                                                               const char *pName)
175 {
176     if (!pName || pName[0] != 'v' || pName[1] != 'k')
177     {
178         return nullptr;
179     }
180 
181     if (instance != VK_NULL_HANDLE)
182     {
183         return vkGetInstanceProcAddr(instance, pName);
184     }
185 
186     if (!strcmp(pName, "vkCreateInstance"))
187     {
188         return reinterpret_cast<PFN_vkVoidFunction>(DeviceVk::WrappedCreateInstance);
189     }
190     if (!strcmp(pName, "vkEnumerateInstanceExtensionProperties"))
191     {
192         return reinterpret_cast<PFN_vkVoidFunction>(
193             DeviceVk::WrappedEnumerateInstanceExtensionProperties);
194     }
195     if (!strcmp(pName, "vkEnumerateInstanceLayerProperties"))
196     {
197         return reinterpret_cast<PFN_vkVoidFunction>(
198             DeviceVk::WrappedEnumerateInstanceLayerProperties);
199     }
200     if (!strcmp(pName, "vkEnumerateInstanceVersion"))
201     {
202         if (!vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"))
203         {
204             // Vulkan 1.0 doesn't have vkEnumerateInstanceVersion.
205             return nullptr;
206         }
207         return reinterpret_cast<PFN_vkVoidFunction>(DeviceVk::WrappedEnumerateInstanceVersion);
208     }
209     if (!strcmp(pName, "vkGetInstanceProcAddr"))
210     {
211         return reinterpret_cast<PFN_vkVoidFunction>(DeviceVk::WrappedGetInstanceProcAddr);
212     }
213 
214     return vkGetInstanceProcAddr(instance, pName);
215 }
216 
217 }  // namespace rx
218