blob: e607b058eba07aeac884e4e394272014ecbc180d [file] [log] [blame]
Chia-I Wu0c203242016-03-15 13:44:51 +08001/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// The API layer of the loader defines Vulkan API and manages layers. The
18// entrypoints are generated and defined in api_dispatch.cpp. Most of them
19// simply find the dispatch table and jump.
20//
21// There are a few of them requiring manual code for things such as layer
22// discovery or chaining. They call into functions defined in this file.
23
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -080024#define ATRACE_TAG ATRACE_TAG_GRAPHICS
25
Chia-I Wu0c203242016-03-15 13:44:51 +080026#include <stdlib.h>
27#include <string.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070028
Chia-I Wu0c203242016-03-15 13:44:51 +080029#include <algorithm>
30#include <mutex>
31#include <new>
Peiyong Lin8f4435a2020-03-11 17:43:28 -070032#include <string>
33#include <unordered_set>
Chia-I Wu0c203242016-03-15 13:44:51 +080034#include <utility>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070035
Cody Northropd2aa3ab2017-10-20 09:01:53 -060036#include <android-base/strings.h>
Chia-I Wu0c203242016-03-15 13:44:51 +080037#include <cutils/properties.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070038#include <log/log.h>
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -080039#include <utils/Trace.h>
Chia-I Wu0c203242016-03-15 13:44:51 +080040
41#include <vulkan/vk_layer_interface.h>
Cody Northropd2aa3ab2017-10-20 09:01:53 -060042#include <graphicsenv/GraphicsEnv.h>
Chia-I Wu0c203242016-03-15 13:44:51 +080043#include "api.h"
44#include "driver.h"
Chia-I Wuc96880f2016-03-26 06:56:45 +080045#include "layers_extensions.h"
Chia-I Wu0c203242016-03-15 13:44:51 +080046
Cody Northropd2aa3ab2017-10-20 09:01:53 -060047
Chia-I Wu0c203242016-03-15 13:44:51 +080048namespace vulkan {
49namespace api {
50
51namespace {
52
53// Provide overridden layer names when there are implicit layers. No effect
54// otherwise.
55class OverrideLayerNames {
56 public:
57 OverrideLayerNames(bool is_instance, const VkAllocationCallbacks& allocator)
58 : is_instance_(is_instance),
59 allocator_(allocator),
60 scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
61 names_(nullptr),
62 name_count_(0),
63 implicit_layers_() {
64 implicit_layers_.result = VK_SUCCESS;
65 }
66
67 ~OverrideLayerNames() {
68 allocator_.pfnFree(allocator_.pUserData, names_);
69 allocator_.pfnFree(allocator_.pUserData, implicit_layers_.elements);
70 allocator_.pfnFree(allocator_.pUserData, implicit_layers_.name_pool);
71 }
72
Chia-I Wu026b8fa2016-04-11 13:44:13 +080073 VkResult Parse(const char* const* names, uint32_t count) {
74 AddImplicitLayers();
Chia-I Wu0c203242016-03-15 13:44:51 +080075
76 const auto& arr = implicit_layers_;
77 if (arr.result != VK_SUCCESS)
78 return arr.result;
79
80 // no need to override when there is no implicit layer
81 if (!arr.count)
82 return VK_SUCCESS;
83
Chia-I Wu026b8fa2016-04-11 13:44:13 +080084 names_ = AllocateNameArray(arr.count + count);
Chia-I Wu0c203242016-03-15 13:44:51 +080085 if (!names_)
86 return VK_ERROR_OUT_OF_HOST_MEMORY;
87
88 // add implicit layer names
89 for (uint32_t i = 0; i < arr.count; i++)
Chia-I Wu026b8fa2016-04-11 13:44:13 +080090 names_[i] = GetImplicitLayerName(i);
Chia-I Wu0c203242016-03-15 13:44:51 +080091
92 name_count_ = arr.count;
93
94 // add explicit layer names
95 for (uint32_t i = 0; i < count; i++) {
96 // ignore explicit layers that are also implicit
Chia-I Wu026b8fa2016-04-11 13:44:13 +080097 if (IsImplicitLayer(names[i]))
Chia-I Wu0c203242016-03-15 13:44:51 +080098 continue;
99
100 names_[name_count_++] = names[i];
101 }
102
103 return VK_SUCCESS;
104 }
105
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800106 const char* const* Names() const { return names_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800107
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800108 uint32_t Count() const { return name_count_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800109
110 private:
111 struct ImplicitLayer {
112 int priority;
113 size_t name_offset;
114 };
115
116 struct ImplicitLayerArray {
117 ImplicitLayer* elements;
118 uint32_t max_count;
119 uint32_t count;
120
121 char* name_pool;
122 size_t max_pool_size;
123 size_t pool_size;
124
125 VkResult result;
126 };
127
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800128 void AddImplicitLayers() {
Yiwei Zhang279df622020-02-18 10:45:15 -0800129 if (!is_instance_)
Chia-I Wu0c203242016-03-15 13:44:51 +0800130 return;
131
Cody Northropd2aa3ab2017-10-20 09:01:53 -0600132 GetLayersFromSettings();
Chia-I Wu0c203242016-03-15 13:44:51 +0800133
Cody Northropd2aa3ab2017-10-20 09:01:53 -0600134 // If no layers specified via Settings, check legacy properties
135 if (implicit_layers_.count <= 0) {
136 ParseDebugVulkanLayers();
137 property_list(ParseDebugVulkanLayer, this);
138
139 // sort by priorities
140 auto& arr = implicit_layers_;
141 std::sort(arr.elements, arr.elements + arr.count,
142 [](const ImplicitLayer& a, const ImplicitLayer& b) {
143 return (a.priority < b.priority);
144 });
145 }
146 }
147
148 void GetLayersFromSettings() {
Yiwei Zhang94b18d52019-11-07 17:12:11 -0800149 // These will only be available if conditions are met in GraphicsEnvironment
Cody Northropd2aa3ab2017-10-20 09:01:53 -0600150 // gpu_debug_layers = layer1:layer2:layerN
151 const std::string layers = android::GraphicsEnv::getInstance().getDebugLayers();
152 if (!layers.empty()) {
153 ALOGV("Debug layer list: %s", layers.c_str());
154 std::vector<std::string> paths = android::base::Split(layers, ":");
155 for (uint32_t i = 0; i < paths.size(); i++) {
156 AddImplicitLayer(int(i), paths[i].c_str(), paths[i].length());
157 }
158 }
Chia-I Wu0c203242016-03-15 13:44:51 +0800159 }
160
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800161 void ParseDebugVulkanLayers() {
Chia-I Wu0c203242016-03-15 13:44:51 +0800162 // debug.vulkan.layers specifies colon-separated layer names
163 char prop[PROPERTY_VALUE_MAX];
164 if (!property_get("debug.vulkan.layers", prop, ""))
165 return;
166
167 // assign negative/high priorities to them
168 int prio = -PROPERTY_VALUE_MAX;
169
170 const char* p = prop;
171 const char* delim;
172 while ((delim = strchr(p, ':'))) {
173 if (delim > p)
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800174 AddImplicitLayer(prio, p, static_cast<size_t>(delim - p));
Chia-I Wu0c203242016-03-15 13:44:51 +0800175
176 prio++;
177 p = delim + 1;
178 }
179
180 if (p[0] != '\0')
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800181 AddImplicitLayer(prio, p, strlen(p));
Chia-I Wu0c203242016-03-15 13:44:51 +0800182 }
183
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800184 static void ParseDebugVulkanLayer(const char* key,
185 const char* val,
186 void* user_data) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800187 static const char prefix[] = "debug.vulkan.layer.";
188 const size_t prefix_len = sizeof(prefix) - 1;
189
190 if (strncmp(key, prefix, prefix_len) || val[0] == '\0')
191 return;
192 key += prefix_len;
193
194 // debug.vulkan.layer.<priority>
195 int priority = -1;
196 if (key[0] >= '0' && key[0] <= '9')
197 priority = atoi(key);
198
199 if (priority < 0) {
200 ALOGW("Ignored implicit layer %s with invalid priority %s", val,
201 key);
202 return;
203 }
204
205 OverrideLayerNames& override_layers =
206 *reinterpret_cast<OverrideLayerNames*>(user_data);
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800207 override_layers.AddImplicitLayer(priority, val, strlen(val));
Chia-I Wu0c203242016-03-15 13:44:51 +0800208 }
209
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800210 void AddImplicitLayer(int priority, const char* name, size_t len) {
211 if (!GrowImplicitLayerArray(1, 0))
Chia-I Wu0c203242016-03-15 13:44:51 +0800212 return;
213
214 auto& arr = implicit_layers_;
215 auto& layer = arr.elements[arr.count++];
216
217 layer.priority = priority;
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800218 layer.name_offset = AddImplicitLayerName(name, len);
Chia-I Wu0c203242016-03-15 13:44:51 +0800219
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800220 ALOGV("Added implicit layer %s", GetImplicitLayerName(arr.count - 1));
Chia-I Wu0c203242016-03-15 13:44:51 +0800221 }
222
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800223 size_t AddImplicitLayerName(const char* name, size_t len) {
224 if (!GrowImplicitLayerArray(0, len + 1))
Chia-I Wu0c203242016-03-15 13:44:51 +0800225 return 0;
226
227 // add the name to the pool
228 auto& arr = implicit_layers_;
229 size_t offset = arr.pool_size;
230 char* dst = arr.name_pool + offset;
231
232 std::copy(name, name + len, dst);
233 dst[len] = '\0';
234
235 arr.pool_size += len + 1;
236
237 return offset;
238 }
239
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800240 bool GrowImplicitLayerArray(uint32_t layer_count, size_t name_size) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800241 const uint32_t initial_max_count = 16;
242 const size_t initial_max_pool_size = 512;
243
244 auto& arr = implicit_layers_;
245
246 // grow the element array if needed
247 while (arr.count + layer_count > arr.max_count) {
248 uint32_t new_max_count =
249 (arr.max_count) ? (arr.max_count << 1) : initial_max_count;
250 void* new_mem = nullptr;
251
252 if (new_max_count > arr.max_count) {
253 new_mem = allocator_.pfnReallocation(
254 allocator_.pUserData, arr.elements,
255 sizeof(ImplicitLayer) * new_max_count,
256 alignof(ImplicitLayer), scope_);
257 }
258
259 if (!new_mem) {
260 arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
261 arr.count = 0;
262 return false;
263 }
264
265 arr.elements = reinterpret_cast<ImplicitLayer*>(new_mem);
266 arr.max_count = new_max_count;
267 }
268
269 // grow the name pool if needed
270 while (arr.pool_size + name_size > arr.max_pool_size) {
271 size_t new_max_pool_size = (arr.max_pool_size)
272 ? (arr.max_pool_size << 1)
273 : initial_max_pool_size;
274 void* new_mem = nullptr;
275
276 if (new_max_pool_size > arr.max_pool_size) {
277 new_mem = allocator_.pfnReallocation(
278 allocator_.pUserData, arr.name_pool, new_max_pool_size,
279 alignof(char), scope_);
280 }
281
282 if (!new_mem) {
283 arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
284 arr.pool_size = 0;
285 return false;
286 }
287
288 arr.name_pool = reinterpret_cast<char*>(new_mem);
289 arr.max_pool_size = new_max_pool_size;
290 }
291
292 return true;
293 }
294
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800295 const char* GetImplicitLayerName(uint32_t index) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800296 const auto& arr = implicit_layers_;
297
298 // this may return nullptr when arr.result is not VK_SUCCESS
299 return implicit_layers_.name_pool + arr.elements[index].name_offset;
300 }
301
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800302 bool IsImplicitLayer(const char* name) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800303 const auto& arr = implicit_layers_;
304
305 for (uint32_t i = 0; i < arr.count; i++) {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800306 if (strcmp(name, GetImplicitLayerName(i)) == 0)
Chia-I Wu0c203242016-03-15 13:44:51 +0800307 return true;
308 }
309
310 return false;
311 }
312
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800313 const char** AllocateNameArray(uint32_t count) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800314 return reinterpret_cast<const char**>(allocator_.pfnAllocation(
315 allocator_.pUserData, sizeof(const char*) * count,
316 alignof(const char*), scope_));
317 }
318
319 const bool is_instance_;
320 const VkAllocationCallbacks& allocator_;
321 const VkSystemAllocationScope scope_;
322
323 const char** names_;
324 uint32_t name_count_;
325
326 ImplicitLayerArray implicit_layers_;
327};
328
329// Provide overridden extension names when there are implicit extensions.
330// No effect otherwise.
331//
332// This is used only to enable VK_EXT_debug_report.
333class OverrideExtensionNames {
334 public:
335 OverrideExtensionNames(bool is_instance,
336 const VkAllocationCallbacks& allocator)
337 : is_instance_(is_instance),
338 allocator_(allocator),
339 scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
340 names_(nullptr),
341 name_count_(0),
342 install_debug_callback_(false) {}
343
344 ~OverrideExtensionNames() {
345 allocator_.pfnFree(allocator_.pUserData, names_);
346 }
347
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800348 VkResult Parse(const char* const* names, uint32_t count) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800349 // this is only for debug.vulkan.enable_callback
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800350 if (!EnableDebugCallback())
Chia-I Wu0c203242016-03-15 13:44:51 +0800351 return VK_SUCCESS;
352
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800353 names_ = AllocateNameArray(count + 1);
Chia-I Wu0c203242016-03-15 13:44:51 +0800354 if (!names_)
355 return VK_ERROR_OUT_OF_HOST_MEMORY;
356
357 std::copy(names, names + count, names_);
358
359 name_count_ = count;
360 names_[name_count_++] = "VK_EXT_debug_report";
361
362 install_debug_callback_ = true;
363
364 return VK_SUCCESS;
365 }
366
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800367 const char* const* Names() const { return names_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800368
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800369 uint32_t Count() const { return name_count_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800370
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800371 bool InstallDebugCallback() const { return install_debug_callback_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800372
373 private:
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800374 bool EnableDebugCallback() const {
Yiwei Zhang6a674c92019-11-08 11:55:36 -0800375 return (is_instance_ &&
376 android::GraphicsEnv::getInstance().isDebuggable() &&
Chia-I Wu0c203242016-03-15 13:44:51 +0800377 property_get_bool("debug.vulkan.enable_callback", false));
378 }
379
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800380 const char** AllocateNameArray(uint32_t count) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800381 return reinterpret_cast<const char**>(allocator_.pfnAllocation(
382 allocator_.pUserData, sizeof(const char*) * count,
383 alignof(const char*), scope_));
384 }
385
386 const bool is_instance_;
387 const VkAllocationCallbacks& allocator_;
388 const VkSystemAllocationScope scope_;
389
390 const char** names_;
391 uint32_t name_count_;
392 bool install_debug_callback_;
393};
394
395// vkCreateInstance and vkCreateDevice helpers with support for layer
396// chaining.
397class LayerChain {
398 public:
Chia-I Wuc3a28912016-04-14 11:55:51 +0800399 struct ActiveLayer {
400 LayerRef ref;
401 union {
402 VkLayerInstanceLink instance_link;
403 VkLayerDeviceLink device_link;
404 };
405 };
406
Chia-I Wueef27fa2016-04-11 13:52:39 +0800407 static VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
408 const VkAllocationCallbacks* allocator,
409 VkInstance* instance_out);
Chia-I Wu0c203242016-03-15 13:44:51 +0800410
Chia-I Wueef27fa2016-04-11 13:52:39 +0800411 static VkResult CreateDevice(VkPhysicalDevice physical_dev,
412 const VkDeviceCreateInfo* create_info,
413 const VkAllocationCallbacks* allocator,
414 VkDevice* dev_out);
Chia-I Wu0c203242016-03-15 13:44:51 +0800415
Chia-I Wueef27fa2016-04-11 13:52:39 +0800416 static void DestroyInstance(VkInstance instance,
417 const VkAllocationCallbacks* allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +0800418
Chia-I Wueef27fa2016-04-11 13:52:39 +0800419 static void DestroyDevice(VkDevice dev,
420 const VkAllocationCallbacks* allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +0800421
Chia-I Wuc3a28912016-04-14 11:55:51 +0800422 static const ActiveLayer* GetActiveLayers(VkPhysicalDevice physical_dev,
423 uint32_t& count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800424
Chia-I Wuc3a28912016-04-14 11:55:51 +0800425 private:
Chia-I Wua4a05552016-05-05 11:57:23 +0800426 LayerChain(bool is_instance,
427 const driver::DebugReportLogger& logger,
428 const VkAllocationCallbacks& allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +0800429 ~LayerChain();
430
Chia-I Wueef27fa2016-04-11 13:52:39 +0800431 VkResult ActivateLayers(const char* const* layer_names,
432 uint32_t layer_count,
433 const char* const* extension_names,
434 uint32_t extension_count);
Chia-I Wuc3a28912016-04-14 11:55:51 +0800435 VkResult ActivateLayers(VkPhysicalDevice physical_dev,
436 const char* const* layer_names,
437 uint32_t layer_count,
438 const char* const* extension_names,
439 uint32_t extension_count);
Chia-I Wueef27fa2016-04-11 13:52:39 +0800440 ActiveLayer* AllocateLayerArray(uint32_t count) const;
441 VkResult LoadLayer(ActiveLayer& layer, const char* name);
442 void SetupLayerLinks();
Chia-I Wu0c203242016-03-15 13:44:51 +0800443
Chia-I Wueef27fa2016-04-11 13:52:39 +0800444 bool Empty() const;
445 void ModifyCreateInfo(VkInstanceCreateInfo& info);
446 void ModifyCreateInfo(VkDeviceCreateInfo& info);
Chia-I Wu0c203242016-03-15 13:44:51 +0800447
Chia-I Wueef27fa2016-04-11 13:52:39 +0800448 VkResult Create(const VkInstanceCreateInfo* create_info,
Chia-I Wu0c203242016-03-15 13:44:51 +0800449 const VkAllocationCallbacks* allocator,
450 VkInstance* instance_out);
451
Chia-I Wueef27fa2016-04-11 13:52:39 +0800452 VkResult Create(VkPhysicalDevice physical_dev,
Chia-I Wu0c203242016-03-15 13:44:51 +0800453 const VkDeviceCreateInfo* create_info,
454 const VkAllocationCallbacks* allocator,
455 VkDevice* dev_out);
456
Chia-I Wueef27fa2016-04-11 13:52:39 +0800457 VkResult ValidateExtensions(const char* const* extension_names,
458 uint32_t extension_count);
459 VkResult ValidateExtensions(VkPhysicalDevice physical_dev,
460 const char* const* extension_names,
461 uint32_t extension_count);
462 VkExtensionProperties* AllocateDriverExtensionArray(uint32_t count) const;
463 bool IsLayerExtension(const char* name) const;
464 bool IsDriverExtension(const char* name) const;
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800465
Chia-I Wu0c203242016-03-15 13:44:51 +0800466 template <typename DataType>
Chia-I Wueef27fa2016-04-11 13:52:39 +0800467 void StealLayers(DataType& data);
Chia-I Wu0c203242016-03-15 13:44:51 +0800468
Chia-I Wueef27fa2016-04-11 13:52:39 +0800469 static void DestroyLayers(ActiveLayer* layers,
470 uint32_t count,
471 const VkAllocationCallbacks& allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +0800472
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800473 static VKAPI_ATTR VkResult SetInstanceLoaderData(VkInstance instance,
474 void* object);
475 static VKAPI_ATTR VkResult SetDeviceLoaderData(VkDevice device,
476 void* object);
477
Chia-I Wu0c203242016-03-15 13:44:51 +0800478 static VKAPI_ATTR VkBool32
Chia-I Wueef27fa2016-04-11 13:52:39 +0800479 DebugReportCallback(VkDebugReportFlagsEXT flags,
480 VkDebugReportObjectTypeEXT obj_type,
481 uint64_t obj,
482 size_t location,
483 int32_t msg_code,
484 const char* layer_prefix,
485 const char* msg,
486 void* user_data);
Chia-I Wu0c203242016-03-15 13:44:51 +0800487
488 const bool is_instance_;
Chia-I Wua4a05552016-05-05 11:57:23 +0800489 const driver::DebugReportLogger& logger_;
Chia-I Wu0c203242016-03-15 13:44:51 +0800490 const VkAllocationCallbacks& allocator_;
491
492 OverrideLayerNames override_layers_;
493 OverrideExtensionNames override_extensions_;
494
495 ActiveLayer* layers_;
496 uint32_t layer_count_;
497
498 PFN_vkGetInstanceProcAddr get_instance_proc_addr_;
499 PFN_vkGetDeviceProcAddr get_device_proc_addr_;
500
501 union {
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800502 VkLayerInstanceCreateInfo instance_chain_info_[2];
503 VkLayerDeviceCreateInfo device_chain_info_[2];
Chia-I Wu0c203242016-03-15 13:44:51 +0800504 };
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800505
506 VkExtensionProperties* driver_extensions_;
507 uint32_t driver_extension_count_;
Chia-I Wu8925efd2016-04-13 15:13:21 +0800508 std::bitset<driver::ProcHook::EXTENSION_COUNT> enabled_extensions_;
Chia-I Wu0c203242016-03-15 13:44:51 +0800509};
510
Chia-I Wua4a05552016-05-05 11:57:23 +0800511LayerChain::LayerChain(bool is_instance,
512 const driver::DebugReportLogger& logger,
513 const VkAllocationCallbacks& allocator)
Chia-I Wu0c203242016-03-15 13:44:51 +0800514 : is_instance_(is_instance),
Chia-I Wua4a05552016-05-05 11:57:23 +0800515 logger_(logger),
Chia-I Wu0c203242016-03-15 13:44:51 +0800516 allocator_(allocator),
517 override_layers_(is_instance, allocator),
518 override_extensions_(is_instance, allocator),
519 layers_(nullptr),
520 layer_count_(0),
521 get_instance_proc_addr_(nullptr),
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800522 get_device_proc_addr_(nullptr),
523 driver_extensions_(nullptr),
Chia-I Wu8925efd2016-04-13 15:13:21 +0800524 driver_extension_count_(0) {
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700525 // advertise the loader supported core Vulkan API version at vulkan::api
526 for (uint32_t i = driver::ProcHook::EXTENSION_CORE_1_0;
527 i != driver::ProcHook::EXTENSION_COUNT; ++i) {
528 enabled_extensions_.set(i);
529 }
Chia-I Wu8925efd2016-04-13 15:13:21 +0800530}
Chia-I Wu0c203242016-03-15 13:44:51 +0800531
532LayerChain::~LayerChain() {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800533 allocator_.pfnFree(allocator_.pUserData, driver_extensions_);
Chia-I Wueef27fa2016-04-11 13:52:39 +0800534 DestroyLayers(layers_, layer_count_, allocator_);
Chia-I Wu0c203242016-03-15 13:44:51 +0800535}
536
Chia-I Wueef27fa2016-04-11 13:52:39 +0800537VkResult LayerChain::ActivateLayers(const char* const* layer_names,
538 uint32_t layer_count,
539 const char* const* extension_names,
540 uint32_t extension_count) {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800541 VkResult result = override_layers_.Parse(layer_names, layer_count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800542 if (result != VK_SUCCESS)
543 return result;
544
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800545 result = override_extensions_.Parse(extension_names, extension_count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800546 if (result != VK_SUCCESS)
547 return result;
548
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800549 if (override_layers_.Count()) {
550 layer_names = override_layers_.Names();
551 layer_count = override_layers_.Count();
Chia-I Wu0c203242016-03-15 13:44:51 +0800552 }
553
554 if (!layer_count) {
555 // point head of chain to the driver
556 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
Chia-I Wu0c203242016-03-15 13:44:51 +0800557
558 return VK_SUCCESS;
559 }
560
Chia-I Wueef27fa2016-04-11 13:52:39 +0800561 layers_ = AllocateLayerArray(layer_count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800562 if (!layers_)
563 return VK_ERROR_OUT_OF_HOST_MEMORY;
564
565 // load layers
566 for (uint32_t i = 0; i < layer_count; i++) {
Chia-I Wueef27fa2016-04-11 13:52:39 +0800567 result = LoadLayer(layers_[i], layer_names[i]);
Chia-I Wu0c203242016-03-15 13:44:51 +0800568 if (result != VK_SUCCESS)
569 return result;
570
571 // count loaded layers for proper destructions on errors
572 layer_count_++;
573 }
574
Chia-I Wueef27fa2016-04-11 13:52:39 +0800575 SetupLayerLinks();
Chia-I Wu0c203242016-03-15 13:44:51 +0800576
577 return VK_SUCCESS;
578}
579
Chia-I Wuc3a28912016-04-14 11:55:51 +0800580VkResult LayerChain::ActivateLayers(VkPhysicalDevice physical_dev,
581 const char* const* layer_names,
582 uint32_t layer_count,
583 const char* const* extension_names,
584 uint32_t extension_count) {
585 uint32_t instance_layer_count;
586 const ActiveLayer* instance_layers =
587 GetActiveLayers(physical_dev, instance_layer_count);
588
589 // log a message if the application device layer array is not empty nor an
590 // exact match of the instance layer array.
591 if (layer_count) {
592 bool exact_match = (instance_layer_count == layer_count);
593 if (exact_match) {
594 for (uint32_t i = 0; i < instance_layer_count; i++) {
595 const Layer& l = *instance_layers[i].ref;
596 if (strcmp(GetLayerProperties(l).layerName, layer_names[i])) {
597 exact_match = false;
598 break;
599 }
600 }
601 }
602
603 if (!exact_match) {
Chia-I Wua4a05552016-05-05 11:57:23 +0800604 logger_.Warn(physical_dev,
605 "Device layers disagree with instance layers and are "
606 "overridden by instance layers");
Chia-I Wuc3a28912016-04-14 11:55:51 +0800607 }
608 }
609
610 VkResult result =
611 override_extensions_.Parse(extension_names, extension_count);
612 if (result != VK_SUCCESS)
613 return result;
614
615 if (!instance_layer_count) {
616 // point head of chain to the driver
617 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
618 get_device_proc_addr_ = driver::GetDeviceProcAddr;
619
620 return VK_SUCCESS;
621 }
622
623 layers_ = AllocateLayerArray(instance_layer_count);
624 if (!layers_)
625 return VK_ERROR_OUT_OF_HOST_MEMORY;
626
627 for (uint32_t i = 0; i < instance_layer_count; i++) {
628 const Layer& l = *instance_layers[i].ref;
629
630 // no need to and cannot chain non-global layers
631 if (!IsLayerGlobal(l))
632 continue;
633
634 // this never fails
635 new (&layers_[layer_count_++]) ActiveLayer{GetLayerRef(l), {}};
636 }
637
Chia-I Wu61b25fd2016-05-27 10:18:25 +0800638 // this may happen when all layers are non-global ones
639 if (!layer_count_) {
640 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
641 get_device_proc_addr_ = driver::GetDeviceProcAddr;
642 return VK_SUCCESS;
643 }
644
Chia-I Wuc3a28912016-04-14 11:55:51 +0800645 SetupLayerLinks();
646
647 return VK_SUCCESS;
648}
649
Chia-I Wueef27fa2016-04-11 13:52:39 +0800650LayerChain::ActiveLayer* LayerChain::AllocateLayerArray(uint32_t count) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800651 VkSystemAllocationScope scope = (is_instance_)
652 ? VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
Chia-I Wuc3a28912016-04-14 11:55:51 +0800653 : VK_SYSTEM_ALLOCATION_SCOPE_COMMAND;
Chia-I Wu0c203242016-03-15 13:44:51 +0800654
655 return reinterpret_cast<ActiveLayer*>(allocator_.pfnAllocation(
656 allocator_.pUserData, sizeof(ActiveLayer) * count, alignof(ActiveLayer),
657 scope));
658}
659
Chia-I Wueef27fa2016-04-11 13:52:39 +0800660VkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) {
Chia-I Wud6e6f512016-04-28 07:39:32 +0800661 const Layer* l = FindLayer(name);
Chia-I Wuc3a28912016-04-14 11:55:51 +0800662 if (!l) {
Chia-I Wua4a05552016-05-05 11:57:23 +0800663 logger_.Err(VK_NULL_HANDLE, "Failed to find layer %s", name);
Chia-I Wud6e6f512016-04-28 07:39:32 +0800664 return VK_ERROR_LAYER_NOT_PRESENT;
665 }
666
Chia-I Wudab25652016-04-28 07:15:51 +0800667 new (&layer) ActiveLayer{GetLayerRef(*l), {}};
Chia-I Wu0c203242016-03-15 13:44:51 +0800668 if (!layer.ref) {
Chia-I Wud6e6f512016-04-28 07:39:32 +0800669 ALOGW("Failed to open layer %s", name);
Chia-I Wu0c203242016-03-15 13:44:51 +0800670 layer.ref.~LayerRef();
671 return VK_ERROR_LAYER_NOT_PRESENT;
672 }
673
Adam Bodnar87edb952019-07-17 12:35:53 -0700674 if (!layer.ref.GetGetInstanceProcAddr()) {
675 ALOGW("Failed to locate vkGetInstanceProcAddr in layer %s", name);
676 layer.ref.~LayerRef();
677 return VK_ERROR_LAYER_NOT_PRESENT;
678 }
679
Chia-I Wuc3a28912016-04-14 11:55:51 +0800680 ALOGI("Loaded layer %s", name);
Chia-I Wu0c203242016-03-15 13:44:51 +0800681
682 return VK_SUCCESS;
683}
684
Chia-I Wueef27fa2016-04-11 13:52:39 +0800685void LayerChain::SetupLayerLinks() {
Chia-I Wu0c203242016-03-15 13:44:51 +0800686 if (is_instance_) {
687 for (uint32_t i = 0; i < layer_count_; i++) {
688 ActiveLayer& layer = layers_[i];
689
690 // point head of chain to the first layer
691 if (i == 0)
692 get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
693
694 // point tail of chain to the driver
695 if (i == layer_count_ - 1) {
696 layer.instance_link.pNext = nullptr;
697 layer.instance_link.pfnNextGetInstanceProcAddr =
698 driver::GetInstanceProcAddr;
699 break;
700 }
701
702 const ActiveLayer& next = layers_[i + 1];
703
704 // const_cast as some naughty layers want to modify our links!
705 layer.instance_link.pNext =
706 const_cast<VkLayerInstanceLink*>(&next.instance_link);
707 layer.instance_link.pfnNextGetInstanceProcAddr =
708 next.ref.GetGetInstanceProcAddr();
709 }
710 } else {
711 for (uint32_t i = 0; i < layer_count_; i++) {
712 ActiveLayer& layer = layers_[i];
713
714 // point head of chain to the first layer
715 if (i == 0) {
716 get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
717 get_device_proc_addr_ = layer.ref.GetGetDeviceProcAddr();
718 }
719
720 // point tail of chain to the driver
721 if (i == layer_count_ - 1) {
722 layer.device_link.pNext = nullptr;
723 layer.device_link.pfnNextGetInstanceProcAddr =
724 driver::GetInstanceProcAddr;
725 layer.device_link.pfnNextGetDeviceProcAddr =
726 driver::GetDeviceProcAddr;
727 break;
728 }
729
730 const ActiveLayer& next = layers_[i + 1];
731
732 // const_cast as some naughty layers want to modify our links!
733 layer.device_link.pNext =
734 const_cast<VkLayerDeviceLink*>(&next.device_link);
735 layer.device_link.pfnNextGetInstanceProcAddr =
736 next.ref.GetGetInstanceProcAddr();
737 layer.device_link.pfnNextGetDeviceProcAddr =
738 next.ref.GetGetDeviceProcAddr();
739 }
740 }
741}
742
Chia-I Wueef27fa2016-04-11 13:52:39 +0800743bool LayerChain::Empty() const {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800744 return (!layer_count_ && !override_layers_.Count() &&
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800745 !override_extensions_.Count());
Chia-I Wu0c203242016-03-15 13:44:51 +0800746}
747
Chia-I Wueef27fa2016-04-11 13:52:39 +0800748void LayerChain::ModifyCreateInfo(VkInstanceCreateInfo& info) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800749 if (layer_count_) {
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800750 auto& link_info = instance_chain_info_[1];
751 link_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
752 link_info.pNext = info.pNext;
753 link_info.function = VK_LAYER_FUNCTION_LINK;
754 link_info.u.pLayerInfo = &layers_[0].instance_link;
Chia-I Wu0c203242016-03-15 13:44:51 +0800755
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800756 auto& cb_info = instance_chain_info_[0];
757 cb_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
758 cb_info.pNext = &link_info;
759 cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK;
760 cb_info.u.pfnSetInstanceLoaderData = SetInstanceLoaderData;
Chia-I Wu0c203242016-03-15 13:44:51 +0800761
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800762 info.pNext = &cb_info;
Chia-I Wu0c203242016-03-15 13:44:51 +0800763 }
764
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800765 if (override_layers_.Count()) {
766 info.enabledLayerCount = override_layers_.Count();
767 info.ppEnabledLayerNames = override_layers_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800768 }
769
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800770 if (override_extensions_.Count()) {
771 info.enabledExtensionCount = override_extensions_.Count();
772 info.ppEnabledExtensionNames = override_extensions_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800773 }
774}
775
Chia-I Wueef27fa2016-04-11 13:52:39 +0800776void LayerChain::ModifyCreateInfo(VkDeviceCreateInfo& info) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800777 if (layer_count_) {
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800778 auto& link_info = device_chain_info_[1];
779 link_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
780 link_info.pNext = info.pNext;
781 link_info.function = VK_LAYER_FUNCTION_LINK;
782 link_info.u.pLayerInfo = &layers_[0].device_link;
Chia-I Wu0c203242016-03-15 13:44:51 +0800783
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800784 auto& cb_info = device_chain_info_[0];
785 cb_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
786 cb_info.pNext = &link_info;
787 cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK;
788 cb_info.u.pfnSetDeviceLoaderData = SetDeviceLoaderData;
Chia-I Wu0c203242016-03-15 13:44:51 +0800789
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800790 info.pNext = &cb_info;
Chia-I Wu0c203242016-03-15 13:44:51 +0800791 }
792
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800793 if (override_layers_.Count()) {
794 info.enabledLayerCount = override_layers_.Count();
795 info.ppEnabledLayerNames = override_layers_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800796 }
797
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800798 if (override_extensions_.Count()) {
799 info.enabledExtensionCount = override_extensions_.Count();
800 info.ppEnabledExtensionNames = override_extensions_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800801 }
802}
803
Chia-I Wueef27fa2016-04-11 13:52:39 +0800804VkResult LayerChain::Create(const VkInstanceCreateInfo* create_info,
Chia-I Wu0c203242016-03-15 13:44:51 +0800805 const VkAllocationCallbacks* allocator,
806 VkInstance* instance_out) {
Chia-I Wueef27fa2016-04-11 13:52:39 +0800807 VkResult result = ValidateExtensions(create_info->ppEnabledExtensionNames,
808 create_info->enabledExtensionCount);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800809 if (result != VK_SUCCESS)
810 return result;
811
Chia-I Wu0c203242016-03-15 13:44:51 +0800812 // call down the chain
813 PFN_vkCreateInstance create_instance =
814 reinterpret_cast<PFN_vkCreateInstance>(
815 get_instance_proc_addr_(VK_NULL_HANDLE, "vkCreateInstance"));
816 VkInstance instance;
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800817 result = create_instance(create_info, allocator, &instance);
Chia-I Wu0c203242016-03-15 13:44:51 +0800818 if (result != VK_SUCCESS)
819 return result;
820
821 // initialize InstanceData
822 InstanceData& data = GetData(instance);
Chia-I Wu0c203242016-03-15 13:44:51 +0800823
Chia-I Wu8925efd2016-04-13 15:13:21 +0800824 if (!InitDispatchTable(instance, get_instance_proc_addr_,
825 enabled_extensions_)) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800826 if (data.dispatch.DestroyInstance)
827 data.dispatch.DestroyInstance(instance, allocator);
828
829 return VK_ERROR_INITIALIZATION_FAILED;
830 }
831
832 // install debug report callback
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800833 if (override_extensions_.InstallDebugCallback()) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800834 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
835 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
836 get_instance_proc_addr_(instance,
837 "vkCreateDebugReportCallbackEXT"));
838 data.destroy_debug_callback =
839 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
840 get_instance_proc_addr_(instance,
841 "vkDestroyDebugReportCallbackEXT"));
842 if (!create_debug_report_callback || !data.destroy_debug_callback) {
843 ALOGE("Broken VK_EXT_debug_report support");
844 data.dispatch.DestroyInstance(instance, allocator);
845 return VK_ERROR_INITIALIZATION_FAILED;
846 }
847
848 VkDebugReportCallbackCreateInfoEXT debug_callback_info = {};
849 debug_callback_info.sType =
850 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
851 debug_callback_info.flags =
852 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
Chia-I Wueef27fa2016-04-11 13:52:39 +0800853 debug_callback_info.pfnCallback = DebugReportCallback;
Chia-I Wu0c203242016-03-15 13:44:51 +0800854
855 VkDebugReportCallbackEXT debug_callback;
856 result = create_debug_report_callback(instance, &debug_callback_info,
857 nullptr, &debug_callback);
858 if (result != VK_SUCCESS) {
859 ALOGE("Failed to install debug report callback");
860 data.dispatch.DestroyInstance(instance, allocator);
861 return VK_ERROR_INITIALIZATION_FAILED;
862 }
863
864 data.debug_callback = debug_callback;
865
866 ALOGI("Installed debug report callback");
867 }
868
Chia-I Wueef27fa2016-04-11 13:52:39 +0800869 StealLayers(data);
Chia-I Wu0c203242016-03-15 13:44:51 +0800870
871 *instance_out = instance;
872
873 return VK_SUCCESS;
874}
875
Chia-I Wueef27fa2016-04-11 13:52:39 +0800876VkResult LayerChain::Create(VkPhysicalDevice physical_dev,
Chia-I Wu0c203242016-03-15 13:44:51 +0800877 const VkDeviceCreateInfo* create_info,
878 const VkAllocationCallbacks* allocator,
879 VkDevice* dev_out) {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800880 VkResult result =
Chia-I Wueef27fa2016-04-11 13:52:39 +0800881 ValidateExtensions(physical_dev, create_info->ppEnabledExtensionNames,
882 create_info->enabledExtensionCount);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800883 if (result != VK_SUCCESS)
884 return result;
885
Chia-I Wu0c203242016-03-15 13:44:51 +0800886 // call down the chain
Chia-I Wuc3a28912016-04-14 11:55:51 +0800887 PFN_vkCreateDevice create_device =
888 GetData(physical_dev).dispatch.CreateDevice;
Chia-I Wu0c203242016-03-15 13:44:51 +0800889 VkDevice dev;
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800890 result = create_device(physical_dev, create_info, allocator, &dev);
Chia-I Wu0c203242016-03-15 13:44:51 +0800891 if (result != VK_SUCCESS)
892 return result;
893
894 // initialize DeviceData
895 DeviceData& data = GetData(dev);
Chia-I Wu0c203242016-03-15 13:44:51 +0800896
Chia-I Wu8925efd2016-04-13 15:13:21 +0800897 if (!InitDispatchTable(dev, get_device_proc_addr_, enabled_extensions_)) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800898 if (data.dispatch.DestroyDevice)
899 data.dispatch.DestroyDevice(dev, allocator);
900
901 return VK_ERROR_INITIALIZATION_FAILED;
902 }
903
Chia-I Wuc3a28912016-04-14 11:55:51 +0800904 // no StealLayers so that active layers are destroyed with this
905 // LayerChain
Chia-I Wu0c203242016-03-15 13:44:51 +0800906 *dev_out = dev;
907
908 return VK_SUCCESS;
909}
910
Chia-I Wueef27fa2016-04-11 13:52:39 +0800911VkResult LayerChain::ValidateExtensions(const char* const* extension_names,
912 uint32_t extension_count) {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800913 if (!extension_count)
914 return VK_SUCCESS;
915
916 // query driver instance extensions
917 uint32_t count;
918 VkResult result =
919 EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
920 if (result == VK_SUCCESS && count) {
Chia-I Wueef27fa2016-04-11 13:52:39 +0800921 driver_extensions_ = AllocateDriverExtensionArray(count);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800922 result = (driver_extensions_) ? EnumerateInstanceExtensionProperties(
923 nullptr, &count, driver_extensions_)
924 : VK_ERROR_OUT_OF_HOST_MEMORY;
925 }
926 if (result != VK_SUCCESS)
927 return result;
928
929 driver_extension_count_ = count;
930
931 for (uint32_t i = 0; i < extension_count; i++) {
932 const char* name = extension_names[i];
Chia-I Wueef27fa2016-04-11 13:52:39 +0800933 if (!IsLayerExtension(name) && !IsDriverExtension(name)) {
Chia-I Wua4a05552016-05-05 11:57:23 +0800934 logger_.Err(VK_NULL_HANDLE,
935 "Failed to enable missing instance extension %s", name);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800936 return VK_ERROR_EXTENSION_NOT_PRESENT;
937 }
Chia-I Wu8925efd2016-04-13 15:13:21 +0800938
939 auto ext_bit = driver::GetProcHookExtension(name);
940 if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN)
941 enabled_extensions_.set(ext_bit);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800942 }
943
944 return VK_SUCCESS;
945}
946
Chia-I Wueef27fa2016-04-11 13:52:39 +0800947VkResult LayerChain::ValidateExtensions(VkPhysicalDevice physical_dev,
948 const char* const* extension_names,
949 uint32_t extension_count) {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800950 if (!extension_count)
951 return VK_SUCCESS;
952
953 // query driver device extensions
954 uint32_t count;
955 VkResult result = EnumerateDeviceExtensionProperties(physical_dev, nullptr,
956 &count, nullptr);
957 if (result == VK_SUCCESS && count) {
Chia-I Wueef27fa2016-04-11 13:52:39 +0800958 driver_extensions_ = AllocateDriverExtensionArray(count);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800959 result = (driver_extensions_)
960 ? EnumerateDeviceExtensionProperties(
961 physical_dev, nullptr, &count, driver_extensions_)
962 : VK_ERROR_OUT_OF_HOST_MEMORY;
963 }
964 if (result != VK_SUCCESS)
965 return result;
966
967 driver_extension_count_ = count;
968
969 for (uint32_t i = 0; i < extension_count; i++) {
970 const char* name = extension_names[i];
Chia-I Wueef27fa2016-04-11 13:52:39 +0800971 if (!IsLayerExtension(name) && !IsDriverExtension(name)) {
Chia-I Wua4a05552016-05-05 11:57:23 +0800972 logger_.Err(physical_dev,
973 "Failed to enable missing device extension %s", name);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800974 return VK_ERROR_EXTENSION_NOT_PRESENT;
975 }
Chia-I Wu8925efd2016-04-13 15:13:21 +0800976
977 auto ext_bit = driver::GetProcHookExtension(name);
978 if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN)
979 enabled_extensions_.set(ext_bit);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800980 }
981
982 return VK_SUCCESS;
983}
984
Chia-I Wueef27fa2016-04-11 13:52:39 +0800985VkExtensionProperties* LayerChain::AllocateDriverExtensionArray(
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800986 uint32_t count) const {
987 return reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
988 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
989 alignof(VkExtensionProperties), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
990}
991
Chia-I Wueef27fa2016-04-11 13:52:39 +0800992bool LayerChain::IsLayerExtension(const char* name) const {
Chia-I Wudab25652016-04-28 07:15:51 +0800993 if (is_instance_) {
994 for (uint32_t i = 0; i < layer_count_; i++) {
995 const ActiveLayer& layer = layers_[i];
996 if (FindLayerInstanceExtension(*layer.ref, name))
997 return true;
998 }
999 } else {
1000 for (uint32_t i = 0; i < layer_count_; i++) {
1001 const ActiveLayer& layer = layers_[i];
1002 if (FindLayerDeviceExtension(*layer.ref, name))
1003 return true;
1004 }
Chia-I Wu1f8f46b2016-04-06 14:17:48 +08001005 }
1006
1007 return false;
1008}
1009
Chia-I Wueef27fa2016-04-11 13:52:39 +08001010bool LayerChain::IsDriverExtension(const char* name) const {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +08001011 for (uint32_t i = 0; i < driver_extension_count_; i++) {
1012 if (strcmp(driver_extensions_[i].extensionName, name) == 0)
1013 return true;
1014 }
1015
1016 return false;
1017}
1018
Chia-I Wu0c203242016-03-15 13:44:51 +08001019template <typename DataType>
Chia-I Wueef27fa2016-04-11 13:52:39 +08001020void LayerChain::StealLayers(DataType& data) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001021 data.layers = layers_;
1022 data.layer_count = layer_count_;
1023
1024 layers_ = nullptr;
1025 layer_count_ = 0;
1026}
1027
Chia-I Wueef27fa2016-04-11 13:52:39 +08001028void LayerChain::DestroyLayers(ActiveLayer* layers,
1029 uint32_t count,
1030 const VkAllocationCallbacks& allocator) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001031 for (uint32_t i = 0; i < count; i++)
1032 layers[i].ref.~LayerRef();
1033
1034 allocator.pfnFree(allocator.pUserData, layers);
1035}
1036
Chia-I Wu94a2c0e2016-04-13 10:20:59 +08001037VkResult LayerChain::SetInstanceLoaderData(VkInstance instance, void* object) {
1038 driver::InstanceDispatchable dispatchable =
1039 reinterpret_cast<driver::InstanceDispatchable>(object);
1040
1041 return (driver::SetDataInternal(dispatchable, &driver::GetData(instance)))
1042 ? VK_SUCCESS
1043 : VK_ERROR_INITIALIZATION_FAILED;
1044}
1045
1046VkResult LayerChain::SetDeviceLoaderData(VkDevice device, void* object) {
1047 driver::DeviceDispatchable dispatchable =
1048 reinterpret_cast<driver::DeviceDispatchable>(object);
1049
1050 return (driver::SetDataInternal(dispatchable, &driver::GetData(device)))
1051 ? VK_SUCCESS
1052 : VK_ERROR_INITIALIZATION_FAILED;
1053}
1054
Chia-I Wueef27fa2016-04-11 13:52:39 +08001055VkBool32 LayerChain::DebugReportCallback(VkDebugReportFlagsEXT flags,
1056 VkDebugReportObjectTypeEXT obj_type,
1057 uint64_t obj,
1058 size_t location,
1059 int32_t msg_code,
1060 const char* layer_prefix,
1061 const char* msg,
1062 void* user_data) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001063 int prio;
1064
1065 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
1066 prio = ANDROID_LOG_ERROR;
1067 else if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT |
1068 VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT))
1069 prio = ANDROID_LOG_WARN;
1070 else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
1071 prio = ANDROID_LOG_INFO;
1072 else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
1073 prio = ANDROID_LOG_DEBUG;
1074 else
1075 prio = ANDROID_LOG_UNKNOWN;
1076
1077 LOG_PRI(prio, LOG_TAG, "[%s] Code %d : %s", layer_prefix, msg_code, msg);
1078
1079 (void)obj_type;
1080 (void)obj;
1081 (void)location;
1082 (void)user_data;
1083
1084 return false;
1085}
1086
Chia-I Wueef27fa2016-04-11 13:52:39 +08001087VkResult LayerChain::CreateInstance(const VkInstanceCreateInfo* create_info,
1088 const VkAllocationCallbacks* allocator,
1089 VkInstance* instance_out) {
Courtney Goeltzenleuchter1531bf12016-12-29 08:46:18 -07001090 const driver::DebugReportLogger logger(*create_info);
1091 LayerChain chain(true, logger,
Chia-I Wu0c203242016-03-15 13:44:51 +08001092 (allocator) ? *allocator : driver::GetDefaultAllocator());
1093
Chia-I Wueef27fa2016-04-11 13:52:39 +08001094 VkResult result = chain.ActivateLayers(create_info->ppEnabledLayerNames,
1095 create_info->enabledLayerCount,
1096 create_info->ppEnabledExtensionNames,
1097 create_info->enabledExtensionCount);
Chia-I Wu0c203242016-03-15 13:44:51 +08001098 if (result != VK_SUCCESS)
1099 return result;
1100
1101 // use a local create info when the chain is not empty
1102 VkInstanceCreateInfo local_create_info;
Chia-I Wueef27fa2016-04-11 13:52:39 +08001103 if (!chain.Empty()) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001104 local_create_info = *create_info;
Chia-I Wueef27fa2016-04-11 13:52:39 +08001105 chain.ModifyCreateInfo(local_create_info);
Chia-I Wu0c203242016-03-15 13:44:51 +08001106 create_info = &local_create_info;
1107 }
1108
Chia-I Wueef27fa2016-04-11 13:52:39 +08001109 return chain.Create(create_info, allocator, instance_out);
Chia-I Wu0c203242016-03-15 13:44:51 +08001110}
1111
Chia-I Wueef27fa2016-04-11 13:52:39 +08001112VkResult LayerChain::CreateDevice(VkPhysicalDevice physical_dev,
1113 const VkDeviceCreateInfo* create_info,
1114 const VkAllocationCallbacks* allocator,
1115 VkDevice* dev_out) {
Courtney Goeltzenleuchter1531bf12016-12-29 08:46:18 -07001116 const driver::DebugReportLogger logger = driver::Logger(physical_dev);
Chia-I Wua4a05552016-05-05 11:57:23 +08001117 LayerChain chain(
Courtney Goeltzenleuchter1531bf12016-12-29 08:46:18 -07001118 false, logger,
Chia-I Wua4a05552016-05-05 11:57:23 +08001119 (allocator) ? *allocator : driver::GetData(physical_dev).allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +08001120
Chia-I Wuc3a28912016-04-14 11:55:51 +08001121 VkResult result = chain.ActivateLayers(
1122 physical_dev, create_info->ppEnabledLayerNames,
1123 create_info->enabledLayerCount, create_info->ppEnabledExtensionNames,
1124 create_info->enabledExtensionCount);
Chia-I Wu0c203242016-03-15 13:44:51 +08001125 if (result != VK_SUCCESS)
1126 return result;
1127
1128 // use a local create info when the chain is not empty
1129 VkDeviceCreateInfo local_create_info;
Chia-I Wueef27fa2016-04-11 13:52:39 +08001130 if (!chain.Empty()) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001131 local_create_info = *create_info;
Chia-I Wueef27fa2016-04-11 13:52:39 +08001132 chain.ModifyCreateInfo(local_create_info);
Chia-I Wu0c203242016-03-15 13:44:51 +08001133 create_info = &local_create_info;
1134 }
1135
Chia-I Wueef27fa2016-04-11 13:52:39 +08001136 return chain.Create(physical_dev, create_info, allocator, dev_out);
Chia-I Wu0c203242016-03-15 13:44:51 +08001137}
1138
Chia-I Wueef27fa2016-04-11 13:52:39 +08001139void LayerChain::DestroyInstance(VkInstance instance,
1140 const VkAllocationCallbacks* allocator) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001141 InstanceData& data = GetData(instance);
1142
1143 if (data.debug_callback != VK_NULL_HANDLE)
1144 data.destroy_debug_callback(instance, data.debug_callback, allocator);
1145
1146 ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers);
1147 uint32_t layer_count = data.layer_count;
1148
1149 VkAllocationCallbacks local_allocator;
1150 if (!allocator)
1151 local_allocator = driver::GetData(instance).allocator;
1152
1153 // this also destroys InstanceData
1154 data.dispatch.DestroyInstance(instance, allocator);
1155
Chia-I Wueef27fa2016-04-11 13:52:39 +08001156 DestroyLayers(layers, layer_count,
1157 (allocator) ? *allocator : local_allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +08001158}
1159
Chia-I Wueef27fa2016-04-11 13:52:39 +08001160void LayerChain::DestroyDevice(VkDevice device,
1161 const VkAllocationCallbacks* allocator) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001162 DeviceData& data = GetData(device);
Chia-I Wu0c203242016-03-15 13:44:51 +08001163 // this also destroys DeviceData
1164 data.dispatch.DestroyDevice(device, allocator);
Chia-I Wuc3a28912016-04-14 11:55:51 +08001165}
Chia-I Wu0c203242016-03-15 13:44:51 +08001166
Chia-I Wuc3a28912016-04-14 11:55:51 +08001167const LayerChain::ActiveLayer* LayerChain::GetActiveLayers(
1168 VkPhysicalDevice physical_dev,
1169 uint32_t& count) {
1170 count = GetData(physical_dev).layer_count;
1171 return reinterpret_cast<const ActiveLayer*>(GetData(physical_dev).layers);
Chia-I Wu0c203242016-03-15 13:44:51 +08001172}
1173
1174// ----------------------------------------------------------------------------
1175
1176bool EnsureInitialized() {
1177 static std::once_flag once_flag;
1178 static bool initialized;
1179
1180 std::call_once(once_flag, []() {
1181 if (driver::OpenHAL()) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001182 initialized = true;
1183 }
1184 });
1185
Yiwei Zhang9dfc93a2019-08-09 17:25:24 -07001186 {
Yiwei Zhang519b44c2019-08-14 23:15:02 -07001187 static pid_t pid = getpid() + 1;
Yiwei Zhang9dfc93a2019-08-09 17:25:24 -07001188 static std::mutex layer_lock;
1189 std::lock_guard<std::mutex> lock(layer_lock);
Yiwei Zhang519b44c2019-08-14 23:15:02 -07001190 if (pid != getpid()) {
1191 pid = getpid();
1192 DiscoverLayers();
1193 }
Yiwei Zhang9dfc93a2019-08-09 17:25:24 -07001194 }
1195
Chia-I Wu0c203242016-03-15 13:44:51 +08001196 return initialized;
1197}
1198
1199} // anonymous namespace
1200
1201VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1202 const VkAllocationCallbacks* pAllocator,
1203 VkInstance* pInstance) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001204 ATRACE_CALL();
1205
Chia-I Wu0c203242016-03-15 13:44:51 +08001206 if (!EnsureInitialized())
1207 return VK_ERROR_INITIALIZATION_FAILED;
1208
Chia-I Wueef27fa2016-04-11 13:52:39 +08001209 return LayerChain::CreateInstance(pCreateInfo, pAllocator, pInstance);
Chia-I Wu0c203242016-03-15 13:44:51 +08001210}
1211
1212void DestroyInstance(VkInstance instance,
1213 const VkAllocationCallbacks* pAllocator) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001214 ATRACE_CALL();
1215
Chia-I Wu0c203242016-03-15 13:44:51 +08001216 if (instance != VK_NULL_HANDLE)
Chia-I Wueef27fa2016-04-11 13:52:39 +08001217 LayerChain::DestroyInstance(instance, pAllocator);
Chia-I Wu0c203242016-03-15 13:44:51 +08001218}
1219
1220VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1221 const VkDeviceCreateInfo* pCreateInfo,
1222 const VkAllocationCallbacks* pAllocator,
1223 VkDevice* pDevice) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001224 ATRACE_CALL();
1225
Chia-I Wueef27fa2016-04-11 13:52:39 +08001226 return LayerChain::CreateDevice(physicalDevice, pCreateInfo, pAllocator,
1227 pDevice);
Chia-I Wu0c203242016-03-15 13:44:51 +08001228}
1229
1230void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001231 ATRACE_CALL();
1232
Chia-I Wu0c203242016-03-15 13:44:51 +08001233 if (device != VK_NULL_HANDLE)
Chia-I Wueef27fa2016-04-11 13:52:39 +08001234 LayerChain::DestroyDevice(device, pAllocator);
Chia-I Wu0c203242016-03-15 13:44:51 +08001235}
1236
1237VkResult EnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
1238 VkLayerProperties* pProperties) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001239 ATRACE_CALL();
1240
Chia-I Wu0c203242016-03-15 13:44:51 +08001241 if (!EnsureInitialized())
1242 return VK_ERROR_INITIALIZATION_FAILED;
1243
Chia-I Wu25700b42016-04-28 06:36:09 +08001244 uint32_t count = GetLayerCount();
Chia-I Wu0c203242016-03-15 13:44:51 +08001245
Chia-I Wu25700b42016-04-28 06:36:09 +08001246 if (!pProperties) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001247 *pPropertyCount = count;
Chia-I Wu25700b42016-04-28 06:36:09 +08001248 return VK_SUCCESS;
1249 }
Chia-I Wu0c203242016-03-15 13:44:51 +08001250
Chia-I Wu25700b42016-04-28 06:36:09 +08001251 uint32_t copied = std::min(*pPropertyCount, count);
1252 for (uint32_t i = 0; i < copied; i++)
1253 pProperties[i] = GetLayerProperties(GetLayer(i));
1254 *pPropertyCount = copied;
1255
1256 return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE;
Chia-I Wu0c203242016-03-15 13:44:51 +08001257}
1258
1259VkResult EnumerateInstanceExtensionProperties(
1260 const char* pLayerName,
1261 uint32_t* pPropertyCount,
1262 VkExtensionProperties* pProperties) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001263 ATRACE_CALL();
1264
Chia-I Wu0c203242016-03-15 13:44:51 +08001265 if (!EnsureInitialized())
1266 return VK_ERROR_INITIALIZATION_FAILED;
1267
1268 if (pLayerName) {
Chia-I Wu04c65512016-04-27 09:54:02 +08001269 const Layer* layer = FindLayer(pLayerName);
Chia-I Wu6184b202016-04-27 11:57:53 +08001270 if (!layer)
1271 return VK_ERROR_LAYER_NOT_PRESENT;
1272
1273 uint32_t count;
1274 const VkExtensionProperties* props =
1275 GetLayerInstanceExtensions(*layer, count);
Chia-I Wu0c203242016-03-15 13:44:51 +08001276
1277 if (!pProperties || *pPropertyCount > count)
1278 *pPropertyCount = count;
1279 if (pProperties)
1280 std::copy(props, props + *pPropertyCount, pProperties);
1281
1282 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1283 }
1284
Peiyong Lin8f4435a2020-03-11 17:43:28 -07001285 // If the pLayerName is nullptr, we must advertise all instance extensions
1286 // from all implicitly enabled layers and the driver implementation. If
1287 // there are duplicates among layers and the driver implementation, always
1288 // only preserve the top layer closest to the application regardless of the
1289 // spec version.
1290 std::vector<VkExtensionProperties> properties;
1291 std::unordered_set<std::string> extensionNames;
1292
1293 // Expose extensions from implicitly enabled layers.
1294 const std::string layersSetting =
1295 android::GraphicsEnv::getInstance().getDebugLayers();
1296 if (!layersSetting.empty()) {
1297 std::vector<std::string> layers =
1298 android::base::Split(layersSetting, ":");
1299 for (uint32_t i = 0; i < layers.size(); i++) {
1300 const Layer* layer = FindLayer(layers[i].c_str());
1301 if (!layer) {
1302 continue;
1303 }
1304 uint32_t count = 0;
1305 const VkExtensionProperties* props =
1306 GetLayerInstanceExtensions(*layer, count);
1307 if (count > 0) {
1308 for (uint32_t i = 0; i < count; ++i) {
1309 if (extensionNames.emplace(props[i].extensionName).second) {
1310 properties.push_back(props[i]);
1311 }
1312 }
1313 }
1314 }
1315 }
1316
1317 // TODO(b/143293104): Parse debug.vulkan.layers properties
1318
1319 // Expose extensions from driver implementation.
1320 {
1321 uint32_t count = 0;
1322 VkResult result = vulkan::driver::EnumerateInstanceExtensionProperties(
1323 nullptr, &count, nullptr);
1324 if (result == VK_SUCCESS && count > 0) {
1325 std::vector<VkExtensionProperties> props(count);
1326 result = vulkan::driver::EnumerateInstanceExtensionProperties(
1327 nullptr, &count, props.data());
1328 for (auto prop : props) {
1329 if (extensionNames.emplace(prop.extensionName).second) {
1330 properties.push_back(prop);
1331 }
1332 }
1333 }
1334 }
1335
1336 uint32_t totalCount = properties.size();
1337 if (!pProperties || *pPropertyCount > totalCount) {
1338 *pPropertyCount = totalCount;
1339 }
1340 if (pProperties) {
1341 std::copy(properties.data(), properties.data() + *pPropertyCount,
1342 pProperties);
1343 }
1344 return *pPropertyCount < totalCount ? VK_INCOMPLETE : VK_SUCCESS;
Chia-I Wu0c203242016-03-15 13:44:51 +08001345}
1346
1347VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1348 uint32_t* pPropertyCount,
1349 VkLayerProperties* pProperties) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001350 ATRACE_CALL();
1351
Chia-I Wuc3a28912016-04-14 11:55:51 +08001352 uint32_t count;
1353 const LayerChain::ActiveLayer* layers =
1354 LayerChain::GetActiveLayers(physicalDevice, count);
Chia-I Wu0c203242016-03-15 13:44:51 +08001355
Chia-I Wu25700b42016-04-28 06:36:09 +08001356 if (!pProperties) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001357 *pPropertyCount = count;
Chia-I Wu25700b42016-04-28 06:36:09 +08001358 return VK_SUCCESS;
1359 }
Chia-I Wu0c203242016-03-15 13:44:51 +08001360
Chia-I Wuc3a28912016-04-14 11:55:51 +08001361 uint32_t copied = std::min(*pPropertyCount, count);
1362 for (uint32_t i = 0; i < copied; i++)
1363 pProperties[i] = GetLayerProperties(*layers[i].ref);
Chia-I Wu25700b42016-04-28 06:36:09 +08001364 *pPropertyCount = copied;
1365
1366 return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE;
Chia-I Wu0c203242016-03-15 13:44:51 +08001367}
1368
1369VkResult EnumerateDeviceExtensionProperties(
1370 VkPhysicalDevice physicalDevice,
1371 const char* pLayerName,
1372 uint32_t* pPropertyCount,
1373 VkExtensionProperties* pProperties) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001374 ATRACE_CALL();
1375
Chia-I Wu0c203242016-03-15 13:44:51 +08001376 if (pLayerName) {
Chia-I Wuc3a28912016-04-14 11:55:51 +08001377 // EnumerateDeviceLayerProperties enumerates active layers for
1378 // backward compatibility. The extension query here should work for
1379 // all layers.
Chia-I Wu04c65512016-04-27 09:54:02 +08001380 const Layer* layer = FindLayer(pLayerName);
Chia-I Wuc3a28912016-04-14 11:55:51 +08001381 if (!layer)
Chia-I Wu6184b202016-04-27 11:57:53 +08001382 return VK_ERROR_LAYER_NOT_PRESENT;
1383
1384 uint32_t count;
1385 const VkExtensionProperties* props =
1386 GetLayerDeviceExtensions(*layer, count);
Chia-I Wu0c203242016-03-15 13:44:51 +08001387
1388 if (!pProperties || *pPropertyCount > count)
1389 *pPropertyCount = count;
1390 if (pProperties)
1391 std::copy(props, props + *pPropertyCount, pProperties);
1392
1393 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1394 }
1395
Yiwei Zhanga885c062019-10-24 12:07:57 -07001396 // TODO(b/143293104): expose extensions from implicitly enabled layers
Chia-I Wu0c203242016-03-15 13:44:51 +08001397 const InstanceData& data = GetData(physicalDevice);
1398 return data.dispatch.EnumerateDeviceExtensionProperties(
1399 physicalDevice, nullptr, pPropertyCount, pProperties);
1400}
1401
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001402VkResult EnumerateInstanceVersion(uint32_t* pApiVersion) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001403 ATRACE_CALL();
1404
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001405 *pApiVersion = VK_API_VERSION_1_1;
1406 return VK_SUCCESS;
1407}
1408
Chia-I Wu0c203242016-03-15 13:44:51 +08001409} // namespace api
1410} // namespace vulkan