1 /*
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
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <algorithm>
28 #include <mutex>
29 #include <new>
30 #include <utility>
31
32 #include <cutils/properties.h>
33 #include <log/log.h>
34
35 #include <vulkan/vk_layer_interface.h>
36 #include "api.h"
37 #include "driver.h"
38 #include "layers_extensions.h"
39
40
41 namespace vulkan {
42 namespace api {
43
44 namespace {
45
46 // Provide overridden layer names when there are implicit layers. No effect
47 // otherwise.
48 class OverrideLayerNames {
49 public:
OverrideLayerNames(bool is_instance,const VkAllocationCallbacks & allocator)50 OverrideLayerNames(bool is_instance, const VkAllocationCallbacks& allocator)
51 : is_instance_(is_instance),
52 allocator_(allocator),
53 scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
54 names_(nullptr),
55 name_count_(0),
56 implicit_layers_() {
57 implicit_layers_.result = VK_SUCCESS;
58 }
59
~OverrideLayerNames()60 ~OverrideLayerNames() {
61 allocator_.pfnFree(allocator_.pUserData, names_);
62 allocator_.pfnFree(allocator_.pUserData, implicit_layers_.elements);
63 allocator_.pfnFree(allocator_.pUserData, implicit_layers_.name_pool);
64 }
65
Parse(const char * const * names,uint32_t count)66 VkResult Parse(const char* const* names, uint32_t count) {
67 AddImplicitLayers();
68
69 const auto& arr = implicit_layers_;
70 if (arr.result != VK_SUCCESS)
71 return arr.result;
72
73 // no need to override when there is no implicit layer
74 if (!arr.count)
75 return VK_SUCCESS;
76
77 names_ = AllocateNameArray(arr.count + count);
78 if (!names_)
79 return VK_ERROR_OUT_OF_HOST_MEMORY;
80
81 // add implicit layer names
82 for (uint32_t i = 0; i < arr.count; i++)
83 names_[i] = GetImplicitLayerName(i);
84
85 name_count_ = arr.count;
86
87 // add explicit layer names
88 for (uint32_t i = 0; i < count; i++) {
89 // ignore explicit layers that are also implicit
90 if (IsImplicitLayer(names[i]))
91 continue;
92
93 names_[name_count_++] = names[i];
94 }
95
96 return VK_SUCCESS;
97 }
98
Names() const99 const char* const* Names() const { return names_; }
100
Count() const101 uint32_t Count() const { return name_count_; }
102
103 private:
104 struct ImplicitLayer {
105 int priority;
106 size_t name_offset;
107 };
108
109 struct ImplicitLayerArray {
110 ImplicitLayer* elements;
111 uint32_t max_count;
112 uint32_t count;
113
114 char* name_pool;
115 size_t max_pool_size;
116 size_t pool_size;
117
118 VkResult result;
119 };
120
AddImplicitLayers()121 void AddImplicitLayers() {
122 if (!is_instance_ || !driver::Debuggable())
123 return;
124
125 GetLayersFromSettings();
126
127 // If no layers specified via Settings, check legacy properties
128 if (implicit_layers_.count <= 0) {
129 ParseDebugVulkanLayers();
130 }
131 }
132
GetLayersFromSettings()133 void GetLayersFromSettings() {
134 // TODO: Implement for host
135 // These will only be available if conditions are met in GraphicsEnvironemnt
136 // gpu_debug_layers = layer1:layer2:layerN
137 // const std::string layers;
138 // if (!layers.empty()) {
139 // ALOGV("Debug layer list: %s", layers.c_str());
140 // std::vector<std::string> paths = android::base::Split(layers, ":");
141 // for (uint32_t i = 0; i < paths.size(); i++) {
142 // AddImplicitLayer(int(i), paths[i].c_str(), paths[i].length());
143 // }
144 // }
145 }
146
ParseDebugVulkanLayers()147 void ParseDebugVulkanLayers() {
148 // debug.vulkan.layers specifies colon-separated layer names
149 char prop[PROPERTY_VALUE_MAX];
150 if (!property_get("debug.vulkan.layers", prop, ""))
151 return;
152
153 // assign negative/high priorities to them
154 int prio = -PROPERTY_VALUE_MAX;
155
156 const char* p = prop;
157 const char* delim;
158 while ((delim = strchr(p, ':'))) {
159 if (delim > p)
160 AddImplicitLayer(prio, p, static_cast<size_t>(delim - p));
161
162 prio++;
163 p = delim + 1;
164 }
165
166 if (p[0] != '\0')
167 AddImplicitLayer(prio, p, strlen(p));
168 }
169
ParseDebugVulkanLayer(const char * key,const char * val,void * user_data)170 static void ParseDebugVulkanLayer(const char* key,
171 const char* val,
172 void* user_data) {
173 static const char prefix[] = "debug.vulkan.layer.";
174 const size_t prefix_len = sizeof(prefix) - 1;
175
176 if (strncmp(key, prefix, prefix_len) || val[0] == '\0')
177 return;
178 key += prefix_len;
179
180 // debug.vulkan.layer.<priority>
181 int priority = -1;
182 if (key[0] >= '0' && key[0] <= '9')
183 priority = atoi(key);
184
185 if (priority < 0) {
186 ALOGW("Ignored implicit layer %s with invalid priority %s", val,
187 key);
188 return;
189 }
190
191 OverrideLayerNames& override_layers =
192 *reinterpret_cast<OverrideLayerNames*>(user_data);
193 override_layers.AddImplicitLayer(priority, val, strlen(val));
194 }
195
AddImplicitLayer(int priority,const char * name,size_t len)196 void AddImplicitLayer(int priority, const char* name, size_t len) {
197 if (!GrowImplicitLayerArray(1, 0))
198 return;
199
200 auto& arr = implicit_layers_;
201 auto& layer = arr.elements[arr.count++];
202
203 layer.priority = priority;
204 layer.name_offset = AddImplicitLayerName(name, len);
205
206 ALOGV("Added implicit layer %s", GetImplicitLayerName(arr.count - 1));
207 }
208
AddImplicitLayerName(const char * name,size_t len)209 size_t AddImplicitLayerName(const char* name, size_t len) {
210 if (!GrowImplicitLayerArray(0, len + 1))
211 return 0;
212
213 // add the name to the pool
214 auto& arr = implicit_layers_;
215 size_t offset = arr.pool_size;
216 char* dst = arr.name_pool + offset;
217
218 std::copy(name, name + len, dst);
219 dst[len] = '\0';
220
221 arr.pool_size += len + 1;
222
223 return offset;
224 }
225
GrowImplicitLayerArray(uint32_t layer_count,size_t name_size)226 bool GrowImplicitLayerArray(uint32_t layer_count, size_t name_size) {
227 const uint32_t initial_max_count = 16;
228 const size_t initial_max_pool_size = 512;
229
230 auto& arr = implicit_layers_;
231
232 // grow the element array if needed
233 while (arr.count + layer_count > arr.max_count) {
234 uint32_t new_max_count =
235 (arr.max_count) ? (arr.max_count << 1) : initial_max_count;
236 void* new_mem = nullptr;
237
238 if (new_max_count > arr.max_count) {
239 new_mem = allocator_.pfnReallocation(
240 allocator_.pUserData, arr.elements,
241 sizeof(ImplicitLayer) * new_max_count,
242 alignof(ImplicitLayer), scope_);
243 }
244
245 if (!new_mem) {
246 arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
247 arr.count = 0;
248 return false;
249 }
250
251 arr.elements = reinterpret_cast<ImplicitLayer*>(new_mem);
252 arr.max_count = new_max_count;
253 }
254
255 // grow the name pool if needed
256 while (arr.pool_size + name_size > arr.max_pool_size) {
257 size_t new_max_pool_size = (arr.max_pool_size)
258 ? (arr.max_pool_size << 1)
259 : initial_max_pool_size;
260 void* new_mem = nullptr;
261
262 if (new_max_pool_size > arr.max_pool_size) {
263 new_mem = allocator_.pfnReallocation(
264 allocator_.pUserData, arr.name_pool, new_max_pool_size,
265 alignof(char), scope_);
266 }
267
268 if (!new_mem) {
269 arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
270 arr.pool_size = 0;
271 return false;
272 }
273
274 arr.name_pool = reinterpret_cast<char*>(new_mem);
275 arr.max_pool_size = new_max_pool_size;
276 }
277
278 return true;
279 }
280
GetImplicitLayerName(uint32_t index) const281 const char* GetImplicitLayerName(uint32_t index) const {
282 const auto& arr = implicit_layers_;
283
284 // this may return nullptr when arr.result is not VK_SUCCESS
285 return implicit_layers_.name_pool + arr.elements[index].name_offset;
286 }
287
IsImplicitLayer(const char * name) const288 bool IsImplicitLayer(const char* name) const {
289 const auto& arr = implicit_layers_;
290
291 for (uint32_t i = 0; i < arr.count; i++) {
292 if (strcmp(name, GetImplicitLayerName(i)) == 0)
293 return true;
294 }
295
296 return false;
297 }
298
AllocateNameArray(uint32_t count) const299 const char** AllocateNameArray(uint32_t count) const {
300 return reinterpret_cast<const char**>(allocator_.pfnAllocation(
301 allocator_.pUserData, sizeof(const char*) * count,
302 alignof(const char*), scope_));
303 }
304
305 const bool is_instance_;
306 const VkAllocationCallbacks& allocator_;
307 const VkSystemAllocationScope scope_;
308
309 const char** names_;
310 uint32_t name_count_;
311
312 ImplicitLayerArray implicit_layers_;
313 };
314
315 // Provide overridden extension names when there are implicit extensions.
316 // No effect otherwise.
317 //
318 // This is used only to enable VK_EXT_debug_report.
319 class OverrideExtensionNames {
320 public:
OverrideExtensionNames(bool is_instance,const VkAllocationCallbacks & allocator)321 OverrideExtensionNames(bool is_instance,
322 const VkAllocationCallbacks& allocator)
323 : is_instance_(is_instance),
324 allocator_(allocator),
325 scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
326 names_(nullptr),
327 name_count_(0),
328 install_debug_callback_(false) {}
329
~OverrideExtensionNames()330 ~OverrideExtensionNames() {
331 allocator_.pfnFree(allocator_.pUserData, names_);
332 }
333
Parse(const char * const * names,uint32_t count)334 VkResult Parse(const char* const* names, uint32_t count) {
335 // this is only for debug.vulkan.enable_callback
336 if (!EnableDebugCallback())
337 return VK_SUCCESS;
338
339 names_ = AllocateNameArray(count + 1);
340 if (!names_)
341 return VK_ERROR_OUT_OF_HOST_MEMORY;
342
343 std::copy(names, names + count, names_);
344
345 name_count_ = count;
346 names_[name_count_++] = "VK_EXT_debug_report";
347
348 install_debug_callback_ = true;
349
350 return VK_SUCCESS;
351 }
352
Names() const353 const char* const* Names() const { return names_; }
354
Count() const355 uint32_t Count() const { return name_count_; }
356
InstallDebugCallback() const357 bool InstallDebugCallback() const { return install_debug_callback_; }
358
359 private:
EnableDebugCallback() const360 bool EnableDebugCallback() const {
361 return false;
362 }
363
AllocateNameArray(uint32_t count) const364 const char** AllocateNameArray(uint32_t count) const {
365 return reinterpret_cast<const char**>(allocator_.pfnAllocation(
366 allocator_.pUserData, sizeof(const char*) * count,
367 alignof(const char*), scope_));
368 }
369
370 const bool is_instance_;
371 const VkAllocationCallbacks& allocator_;
372 const VkSystemAllocationScope scope_;
373
374 const char** names_;
375 uint32_t name_count_;
376 bool install_debug_callback_;
377 };
378
379 // vkCreateInstance and vkCreateDevice helpers with support for layer
380 // chaining.
381 class LayerChain {
382 public:
383 struct ActiveLayer {
384 LayerRef ref;
385 union {
386 VkLayerInstanceLink instance_link;
387 VkLayerDeviceLink device_link;
388 };
389 };
390
391 static VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
392 const VkAllocationCallbacks* allocator,
393 VkInstance* instance_out);
394
395 static VkResult CreateDevice(VkPhysicalDevice physical_dev,
396 const VkDeviceCreateInfo* create_info,
397 const VkAllocationCallbacks* allocator,
398 VkDevice* dev_out);
399
400 static void DestroyInstance(VkInstance instance,
401 const VkAllocationCallbacks* allocator);
402
403 static void DestroyDevice(VkDevice dev,
404 const VkAllocationCallbacks* allocator);
405
406 static const ActiveLayer* GetActiveLayers(VkPhysicalDevice physical_dev,
407 uint32_t& count);
408
409 private:
410 LayerChain(bool is_instance,
411 const driver::DebugReportLogger& logger,
412 const VkAllocationCallbacks& allocator);
413 ~LayerChain();
414
415 VkResult ActivateLayers(const char* const* layer_names,
416 uint32_t layer_count,
417 const char* const* extension_names,
418 uint32_t extension_count);
419 VkResult ActivateLayers(VkPhysicalDevice physical_dev,
420 const char* const* layer_names,
421 uint32_t layer_count,
422 const char* const* extension_names,
423 uint32_t extension_count);
424 ActiveLayer* AllocateLayerArray(uint32_t count) const;
425 VkResult LoadLayer(ActiveLayer& layer, const char* name);
426 void SetupLayerLinks();
427
428 bool Empty() const;
429 void ModifyCreateInfo(VkInstanceCreateInfo& info);
430 void ModifyCreateInfo(VkDeviceCreateInfo& info);
431
432 VkResult Create(const VkInstanceCreateInfo* create_info,
433 const VkAllocationCallbacks* allocator,
434 VkInstance* instance_out);
435
436 VkResult Create(VkPhysicalDevice physical_dev,
437 const VkDeviceCreateInfo* create_info,
438 const VkAllocationCallbacks* allocator,
439 VkDevice* dev_out);
440
441 VkResult ValidateExtensions(const char* const* extension_names,
442 uint32_t extension_count);
443 VkResult ValidateExtensions(VkPhysicalDevice physical_dev,
444 const char* const* extension_names,
445 uint32_t extension_count);
446 VkExtensionProperties* AllocateDriverExtensionArray(uint32_t count) const;
447 bool IsLayerExtension(const char* name) const;
448 bool IsDriverExtension(const char* name) const;
449
450 template <typename DataType>
451 void StealLayers(DataType& data);
452
453 static void DestroyLayers(ActiveLayer* layers,
454 uint32_t count,
455 const VkAllocationCallbacks& allocator);
456
457 static VKAPI_ATTR VkResult SetInstanceLoaderData(VkInstance instance,
458 void* object);
459 static VKAPI_ATTR VkResult SetDeviceLoaderData(VkDevice device,
460 void* object);
461
462 static VKAPI_ATTR VkBool32
463 DebugReportCallback(VkDebugReportFlagsEXT flags,
464 VkDebugReportObjectTypeEXT obj_type,
465 uint64_t obj,
466 size_t location,
467 int32_t msg_code,
468 const char* layer_prefix,
469 const char* msg,
470 void* user_data);
471
472 const bool is_instance_;
473 const driver::DebugReportLogger& logger_;
474 const VkAllocationCallbacks& allocator_;
475
476 OverrideLayerNames override_layers_;
477 OverrideExtensionNames override_extensions_;
478
479 ActiveLayer* layers_;
480 uint32_t layer_count_;
481
482 PFN_vkGetInstanceProcAddr get_instance_proc_addr_;
483 PFN_vkGetDeviceProcAddr get_device_proc_addr_;
484
485 union {
486 VkLayerInstanceCreateInfo instance_chain_info_[2];
487 VkLayerDeviceCreateInfo device_chain_info_[2];
488 };
489
490 VkExtensionProperties* driver_extensions_;
491 uint32_t driver_extension_count_;
492 std::bitset<driver::ProcHook::EXTENSION_COUNT> enabled_extensions_;
493 };
494
LayerChain(bool is_instance,const driver::DebugReportLogger & logger,const VkAllocationCallbacks & allocator)495 LayerChain::LayerChain(bool is_instance,
496 const driver::DebugReportLogger& logger,
497 const VkAllocationCallbacks& allocator)
498 : is_instance_(is_instance),
499 logger_(logger),
500 allocator_(allocator),
501 override_layers_(is_instance, allocator),
502 override_extensions_(is_instance, allocator),
503 layers_(nullptr),
504 layer_count_(0),
505 get_instance_proc_addr_(nullptr),
506 get_device_proc_addr_(nullptr),
507 driver_extensions_(nullptr),
508 driver_extension_count_(0) {
509 enabled_extensions_.set(driver::ProcHook::EXTENSION_CORE);
510 }
511
~LayerChain()512 LayerChain::~LayerChain() {
513 allocator_.pfnFree(allocator_.pUserData, driver_extensions_);
514 DestroyLayers(layers_, layer_count_, allocator_);
515 }
516
ActivateLayers(const char * const * layer_names,uint32_t layer_count,const char * const * extension_names,uint32_t extension_count)517 VkResult LayerChain::ActivateLayers(const char* const* layer_names,
518 uint32_t layer_count,
519 const char* const* extension_names,
520 uint32_t extension_count) {
521 VkResult result = override_layers_.Parse(layer_names, layer_count);
522 if (result != VK_SUCCESS)
523 return result;
524
525 result = override_extensions_.Parse(extension_names, extension_count);
526 if (result != VK_SUCCESS)
527 return result;
528
529 if (override_layers_.Count()) {
530 layer_names = override_layers_.Names();
531 layer_count = override_layers_.Count();
532 }
533
534 if (!layer_count) {
535 // point head of chain to the driver
536 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
537
538 return VK_SUCCESS;
539 }
540
541 layers_ = AllocateLayerArray(layer_count);
542 if (!layers_)
543 return VK_ERROR_OUT_OF_HOST_MEMORY;
544
545 // load layers
546 for (uint32_t i = 0; i < layer_count; i++) {
547 result = LoadLayer(layers_[i], layer_names[i]);
548 if (result != VK_SUCCESS)
549 return result;
550
551 // count loaded layers for proper destructions on errors
552 layer_count_++;
553 }
554
555 SetupLayerLinks();
556
557 return VK_SUCCESS;
558 }
559
ActivateLayers(VkPhysicalDevice physical_dev,const char * const * layer_names,uint32_t layer_count,const char * const * extension_names,uint32_t extension_count)560 VkResult LayerChain::ActivateLayers(VkPhysicalDevice physical_dev,
561 const char* const* layer_names,
562 uint32_t layer_count,
563 const char* const* extension_names,
564 uint32_t extension_count) {
565 uint32_t instance_layer_count;
566 const ActiveLayer* instance_layers =
567 GetActiveLayers(physical_dev, instance_layer_count);
568
569 // log a message if the application device layer array is not empty nor an
570 // exact match of the instance layer array.
571 if (layer_count) {
572 bool exact_match = (instance_layer_count == layer_count);
573 if (exact_match) {
574 for (uint32_t i = 0; i < instance_layer_count; i++) {
575 const Layer& l = *instance_layers[i].ref;
576 if (strcmp(GetLayerProperties(l).layerName, layer_names[i])) {
577 exact_match = false;
578 break;
579 }
580 }
581 }
582
583 if (!exact_match) {
584 logger_.Warn(physical_dev,
585 "Device layers disagree with instance layers and are "
586 "overridden by instance layers");
587 }
588 }
589
590 VkResult result =
591 override_extensions_.Parse(extension_names, extension_count);
592 if (result != VK_SUCCESS)
593 return result;
594
595 if (!instance_layer_count) {
596 // point head of chain to the driver
597 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
598 get_device_proc_addr_ = driver::GetDeviceProcAddr;
599
600 return VK_SUCCESS;
601 }
602
603 layers_ = AllocateLayerArray(instance_layer_count);
604 if (!layers_)
605 return VK_ERROR_OUT_OF_HOST_MEMORY;
606
607 for (uint32_t i = 0; i < instance_layer_count; i++) {
608 const Layer& l = *instance_layers[i].ref;
609
610 // no need to and cannot chain non-global layers
611 if (!IsLayerGlobal(l))
612 continue;
613
614 // this never fails
615 new (&layers_[layer_count_++]) ActiveLayer{GetLayerRef(l), {}};
616 }
617
618 // this may happen when all layers are non-global ones
619 if (!layer_count_) {
620 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
621 get_device_proc_addr_ = driver::GetDeviceProcAddr;
622 return VK_SUCCESS;
623 }
624
625 SetupLayerLinks();
626
627 return VK_SUCCESS;
628 }
629
AllocateLayerArray(uint32_t count) const630 LayerChain::ActiveLayer* LayerChain::AllocateLayerArray(uint32_t count) const {
631 VkSystemAllocationScope scope = (is_instance_)
632 ? VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
633 : VK_SYSTEM_ALLOCATION_SCOPE_COMMAND;
634
635 return reinterpret_cast<ActiveLayer*>(allocator_.pfnAllocation(
636 allocator_.pUserData, sizeof(ActiveLayer) * count, alignof(ActiveLayer),
637 scope));
638 }
639
LoadLayer(ActiveLayer & layer,const char * name)640 VkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) {
641 const Layer* l = FindLayer(name);
642 if (!l) {
643 logger_.Err(VK_NULL_HANDLE, "Failed to find layer %s", name);
644 return VK_ERROR_LAYER_NOT_PRESENT;
645 }
646
647 new (&layer) ActiveLayer{GetLayerRef(*l), {}};
648 if (!layer.ref) {
649 ALOGW("Failed to open layer %s", name);
650 layer.ref.~LayerRef();
651 return VK_ERROR_LAYER_NOT_PRESENT;
652 }
653
654 ALOGI("Loaded layer %s", name);
655
656 return VK_SUCCESS;
657 }
658
SetupLayerLinks()659 void LayerChain::SetupLayerLinks() {
660 if (is_instance_) {
661 for (uint32_t i = 0; i < layer_count_; i++) {
662 ActiveLayer& layer = layers_[i];
663
664 // point head of chain to the first layer
665 if (i == 0)
666 get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
667
668 // point tail of chain to the driver
669 if (i == layer_count_ - 1) {
670 layer.instance_link.pNext = nullptr;
671 layer.instance_link.pfnNextGetInstanceProcAddr =
672 driver::GetInstanceProcAddr;
673 break;
674 }
675
676 const ActiveLayer& next = layers_[i + 1];
677
678 // const_cast as some naughty layers want to modify our links!
679 layer.instance_link.pNext =
680 const_cast<VkLayerInstanceLink*>(&next.instance_link);
681 layer.instance_link.pfnNextGetInstanceProcAddr =
682 next.ref.GetGetInstanceProcAddr();
683 }
684 } else {
685 for (uint32_t i = 0; i < layer_count_; i++) {
686 ActiveLayer& layer = layers_[i];
687
688 // point head of chain to the first layer
689 if (i == 0) {
690 get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
691 get_device_proc_addr_ = layer.ref.GetGetDeviceProcAddr();
692 }
693
694 // point tail of chain to the driver
695 if (i == layer_count_ - 1) {
696 layer.device_link.pNext = nullptr;
697 layer.device_link.pfnNextGetInstanceProcAddr =
698 driver::GetInstanceProcAddr;
699 layer.device_link.pfnNextGetDeviceProcAddr =
700 driver::GetDeviceProcAddr;
701 break;
702 }
703
704 const ActiveLayer& next = layers_[i + 1];
705
706 // const_cast as some naughty layers want to modify our links!
707 layer.device_link.pNext =
708 const_cast<VkLayerDeviceLink*>(&next.device_link);
709 layer.device_link.pfnNextGetInstanceProcAddr =
710 next.ref.GetGetInstanceProcAddr();
711 layer.device_link.pfnNextGetDeviceProcAddr =
712 next.ref.GetGetDeviceProcAddr();
713 }
714 }
715 }
716
Empty() const717 bool LayerChain::Empty() const {
718 return (!layer_count_ && !override_layers_.Count() &&
719 !override_extensions_.Count());
720 }
721
ModifyCreateInfo(VkInstanceCreateInfo & info)722 void LayerChain::ModifyCreateInfo(VkInstanceCreateInfo& info) {
723 if (layer_count_) {
724 auto& link_info = instance_chain_info_[1];
725 link_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
726 link_info.pNext = info.pNext;
727 link_info.function = VK_LAYER_FUNCTION_LINK;
728 link_info.u.pLayerInfo = &layers_[0].instance_link;
729
730 auto& cb_info = instance_chain_info_[0];
731 cb_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
732 cb_info.pNext = &link_info;
733 cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK;
734 cb_info.u.pfnSetInstanceLoaderData = SetInstanceLoaderData;
735
736 info.pNext = &cb_info;
737 }
738
739 if (override_layers_.Count()) {
740 info.enabledLayerCount = override_layers_.Count();
741 info.ppEnabledLayerNames = override_layers_.Names();
742 }
743
744 if (override_extensions_.Count()) {
745 info.enabledExtensionCount = override_extensions_.Count();
746 info.ppEnabledExtensionNames = override_extensions_.Names();
747 }
748 }
749
ModifyCreateInfo(VkDeviceCreateInfo & info)750 void LayerChain::ModifyCreateInfo(VkDeviceCreateInfo& info) {
751 if (layer_count_) {
752 auto& link_info = device_chain_info_[1];
753 link_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
754 link_info.pNext = info.pNext;
755 link_info.function = VK_LAYER_FUNCTION_LINK;
756 link_info.u.pLayerInfo = &layers_[0].device_link;
757
758 auto& cb_info = device_chain_info_[0];
759 cb_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
760 cb_info.pNext = &link_info;
761 cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK;
762 cb_info.u.pfnSetDeviceLoaderData = SetDeviceLoaderData;
763
764 info.pNext = &cb_info;
765 }
766
767 if (override_layers_.Count()) {
768 info.enabledLayerCount = override_layers_.Count();
769 info.ppEnabledLayerNames = override_layers_.Names();
770 }
771
772 if (override_extensions_.Count()) {
773 info.enabledExtensionCount = override_extensions_.Count();
774 info.ppEnabledExtensionNames = override_extensions_.Names();
775 }
776 }
777
Create(const VkInstanceCreateInfo * create_info,const VkAllocationCallbacks * allocator,VkInstance * instance_out)778 VkResult LayerChain::Create(const VkInstanceCreateInfo* create_info,
779 const VkAllocationCallbacks* allocator,
780 VkInstance* instance_out) {
781 VkResult result = ValidateExtensions(create_info->ppEnabledExtensionNames,
782 create_info->enabledExtensionCount);
783 if (result != VK_SUCCESS)
784 return result;
785
786 // call down the chain
787 PFN_vkCreateInstance create_instance =
788 reinterpret_cast<PFN_vkCreateInstance>(
789 get_instance_proc_addr_(VK_NULL_HANDLE, "vkCreateInstance"));
790 VkInstance instance;
791 result = create_instance(create_info, allocator, &instance);
792 if (result != VK_SUCCESS)
793 return result;
794
795 // initialize InstanceData
796 InstanceData& data = GetData(instance);
797
798 if (!InitDispatchTable(instance, get_instance_proc_addr_,
799 enabled_extensions_)) {
800 if (data.dispatch.DestroyInstance)
801 data.dispatch.DestroyInstance(instance, allocator);
802
803 return VK_ERROR_INITIALIZATION_FAILED;
804 }
805
806 // install debug report callback
807 if (override_extensions_.InstallDebugCallback()) {
808 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
809 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
810 get_instance_proc_addr_(instance,
811 "vkCreateDebugReportCallbackEXT"));
812 data.destroy_debug_callback =
813 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
814 get_instance_proc_addr_(instance,
815 "vkDestroyDebugReportCallbackEXT"));
816 if (!create_debug_report_callback || !data.destroy_debug_callback) {
817 ALOGE("Broken VK_EXT_debug_report support");
818 data.dispatch.DestroyInstance(instance, allocator);
819 return VK_ERROR_INITIALIZATION_FAILED;
820 }
821
822 VkDebugReportCallbackCreateInfoEXT debug_callback_info = {};
823 debug_callback_info.sType =
824 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
825 debug_callback_info.flags =
826 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
827 debug_callback_info.pfnCallback = DebugReportCallback;
828
829 VkDebugReportCallbackEXT debug_callback;
830 result = create_debug_report_callback(instance, &debug_callback_info,
831 nullptr, &debug_callback);
832 if (result != VK_SUCCESS) {
833 ALOGE("Failed to install debug report callback");
834 data.dispatch.DestroyInstance(instance, allocator);
835 return VK_ERROR_INITIALIZATION_FAILED;
836 }
837
838 data.debug_callback = debug_callback;
839
840 ALOGI("Installed debug report callback");
841 }
842
843 StealLayers(data);
844
845 *instance_out = instance;
846
847 return VK_SUCCESS;
848 }
849
Create(VkPhysicalDevice physical_dev,const VkDeviceCreateInfo * create_info,const VkAllocationCallbacks * allocator,VkDevice * dev_out)850 VkResult LayerChain::Create(VkPhysicalDevice physical_dev,
851 const VkDeviceCreateInfo* create_info,
852 const VkAllocationCallbacks* allocator,
853 VkDevice* dev_out) {
854 VkResult result =
855 ValidateExtensions(physical_dev, create_info->ppEnabledExtensionNames,
856 create_info->enabledExtensionCount);
857 if (result != VK_SUCCESS)
858 return result;
859
860 // call down the chain
861 PFN_vkCreateDevice create_device =
862 GetData(physical_dev).dispatch.CreateDevice;
863 VkDevice dev;
864 result = create_device(physical_dev, create_info, allocator, &dev);
865 if (result != VK_SUCCESS)
866 return result;
867
868 // initialize DeviceData
869 DeviceData& data = GetData(dev);
870
871 if (!InitDispatchTable(dev, get_device_proc_addr_, enabled_extensions_)) {
872 if (data.dispatch.DestroyDevice)
873 data.dispatch.DestroyDevice(dev, allocator);
874
875 return VK_ERROR_INITIALIZATION_FAILED;
876 }
877
878 // no StealLayers so that active layers are destroyed with this
879 // LayerChain
880 *dev_out = dev;
881
882 return VK_SUCCESS;
883 }
884
ValidateExtensions(const char * const * extension_names,uint32_t extension_count)885 VkResult LayerChain::ValidateExtensions(const char* const* extension_names,
886 uint32_t extension_count) {
887 if (!extension_count)
888 return VK_SUCCESS;
889
890 // query driver instance extensions
891 uint32_t count;
892 VkResult result =
893 EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
894 if (result == VK_SUCCESS && count) {
895 driver_extensions_ = AllocateDriverExtensionArray(count);
896 result = (driver_extensions_) ? EnumerateInstanceExtensionProperties(
897 nullptr, &count, driver_extensions_)
898 : VK_ERROR_OUT_OF_HOST_MEMORY;
899 }
900 if (result != VK_SUCCESS)
901 return result;
902
903 driver_extension_count_ = count;
904
905 for (uint32_t i = 0; i < extension_count; i++) {
906 const char* name = extension_names[i];
907 if (!IsLayerExtension(name) && !IsDriverExtension(name)) {
908 logger_.Err(VK_NULL_HANDLE,
909 "Failed to enable missing instance extension %s", name);
910 return VK_ERROR_EXTENSION_NOT_PRESENT;
911 }
912
913 auto ext_bit = driver::GetProcHookExtension(name);
914 if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN)
915 enabled_extensions_.set(ext_bit);
916 }
917
918 return VK_SUCCESS;
919 }
920
ValidateExtensions(VkPhysicalDevice physical_dev,const char * const * extension_names,uint32_t extension_count)921 VkResult LayerChain::ValidateExtensions(VkPhysicalDevice physical_dev,
922 const char* const* extension_names,
923 uint32_t extension_count) {
924 if (!extension_count)
925 return VK_SUCCESS;
926
927 // query driver device extensions
928 uint32_t count;
929 VkResult result = EnumerateDeviceExtensionProperties(physical_dev, nullptr,
930 &count, nullptr);
931 if (result == VK_SUCCESS && count) {
932 driver_extensions_ = AllocateDriverExtensionArray(count);
933 result = (driver_extensions_)
934 ? EnumerateDeviceExtensionProperties(
935 physical_dev, nullptr, &count, driver_extensions_)
936 : VK_ERROR_OUT_OF_HOST_MEMORY;
937 }
938 if (result != VK_SUCCESS)
939 return result;
940
941 driver_extension_count_ = count;
942
943 for (uint32_t i = 0; i < extension_count; i++) {
944 const char* name = extension_names[i];
945 if (!IsLayerExtension(name) && !IsDriverExtension(name)) {
946 logger_.Err(physical_dev,
947 "Failed to enable missing device extension %s", name);
948 return VK_ERROR_EXTENSION_NOT_PRESENT;
949 }
950
951 auto ext_bit = driver::GetProcHookExtension(name);
952 if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN)
953 enabled_extensions_.set(ext_bit);
954 }
955
956 return VK_SUCCESS;
957 }
958
AllocateDriverExtensionArray(uint32_t count) const959 VkExtensionProperties* LayerChain::AllocateDriverExtensionArray(
960 uint32_t count) const {
961 return reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
962 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
963 alignof(VkExtensionProperties), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
964 }
965
IsLayerExtension(const char * name) const966 bool LayerChain::IsLayerExtension(const char* name) const {
967 if (is_instance_) {
968 for (uint32_t i = 0; i < layer_count_; i++) {
969 const ActiveLayer& layer = layers_[i];
970 if (FindLayerInstanceExtension(*layer.ref, name))
971 return true;
972 }
973 } else {
974 for (uint32_t i = 0; i < layer_count_; i++) {
975 const ActiveLayer& layer = layers_[i];
976 if (FindLayerDeviceExtension(*layer.ref, name))
977 return true;
978 }
979 }
980
981 return false;
982 }
983
IsDriverExtension(const char * name) const984 bool LayerChain::IsDriverExtension(const char* name) const {
985 for (uint32_t i = 0; i < driver_extension_count_; i++) {
986 if (strcmp(driver_extensions_[i].extensionName, name) == 0)
987 return true;
988 }
989
990 return false;
991 }
992
993 template <typename DataType>
StealLayers(DataType & data)994 void LayerChain::StealLayers(DataType& data) {
995 data.layers = layers_;
996 data.layer_count = layer_count_;
997
998 layers_ = nullptr;
999 layer_count_ = 0;
1000 }
1001
DestroyLayers(ActiveLayer * layers,uint32_t count,const VkAllocationCallbacks & allocator)1002 void LayerChain::DestroyLayers(ActiveLayer* layers,
1003 uint32_t count,
1004 const VkAllocationCallbacks& allocator) {
1005 for (uint32_t i = 0; i < count; i++)
1006 layers[i].ref.~LayerRef();
1007
1008 allocator.pfnFree(allocator.pUserData, layers);
1009 }
1010
SetInstanceLoaderData(VkInstance instance,void * object)1011 VkResult LayerChain::SetInstanceLoaderData(VkInstance instance, void* object) {
1012 driver::InstanceDispatchable dispatchable =
1013 reinterpret_cast<driver::InstanceDispatchable>(object);
1014
1015 return (driver::SetDataInternal(dispatchable, &driver::GetData(instance)))
1016 ? VK_SUCCESS
1017 : VK_ERROR_INITIALIZATION_FAILED;
1018 }
1019
SetDeviceLoaderData(VkDevice device,void * object)1020 VkResult LayerChain::SetDeviceLoaderData(VkDevice device, void* object) {
1021 driver::DeviceDispatchable dispatchable =
1022 reinterpret_cast<driver::DeviceDispatchable>(object);
1023
1024 return (driver::SetDataInternal(dispatchable, &driver::GetData(device)))
1025 ? VK_SUCCESS
1026 : VK_ERROR_INITIALIZATION_FAILED;
1027 }
1028
DebugReportCallback(VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT obj_type,uint64_t obj,size_t location,int32_t msg_code,const char * layer_prefix,const char * msg,void * user_data)1029 VkBool32 LayerChain::DebugReportCallback(VkDebugReportFlagsEXT flags,
1030 VkDebugReportObjectTypeEXT obj_type,
1031 uint64_t obj,
1032 size_t location,
1033 int32_t msg_code,
1034 const char* layer_prefix,
1035 const char* msg,
1036 void* user_data) {
1037 int prio;
1038
1039 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
1040 prio = ANDROID_LOG_ERROR;
1041 else if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT |
1042 VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT))
1043 prio = ANDROID_LOG_WARN;
1044 else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
1045 prio = ANDROID_LOG_INFO;
1046 else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
1047 prio = ANDROID_LOG_DEBUG;
1048 else
1049 prio = ANDROID_LOG_UNKNOWN;
1050
1051 LOG_PRI(prio, LOG_TAG, "[%s] Code %d : %s", layer_prefix, msg_code, msg);
1052
1053 (void)obj_type;
1054 (void)obj;
1055 (void)location;
1056 (void)user_data;
1057
1058 return false;
1059 }
1060
CreateInstance(const VkInstanceCreateInfo * create_info,const VkAllocationCallbacks * allocator,VkInstance * instance_out)1061 VkResult LayerChain::CreateInstance(const VkInstanceCreateInfo* create_info,
1062 const VkAllocationCallbacks* allocator,
1063 VkInstance* instance_out) {
1064 const driver::DebugReportLogger logger(*create_info);
1065 LayerChain chain(true, logger,
1066 (allocator) ? *allocator : driver::GetDefaultAllocator());
1067
1068 VkResult result = chain.ActivateLayers(create_info->ppEnabledLayerNames,
1069 create_info->enabledLayerCount,
1070 create_info->ppEnabledExtensionNames,
1071 create_info->enabledExtensionCount);
1072 if (result != VK_SUCCESS)
1073 return result;
1074
1075 // use a local create info when the chain is not empty
1076 VkInstanceCreateInfo local_create_info;
1077 if (!chain.Empty()) {
1078 local_create_info = *create_info;
1079 chain.ModifyCreateInfo(local_create_info);
1080 create_info = &local_create_info;
1081 }
1082
1083 return chain.Create(create_info, allocator, instance_out);
1084 }
1085
CreateDevice(VkPhysicalDevice physical_dev,const VkDeviceCreateInfo * create_info,const VkAllocationCallbacks * allocator,VkDevice * dev_out)1086 VkResult LayerChain::CreateDevice(VkPhysicalDevice physical_dev,
1087 const VkDeviceCreateInfo* create_info,
1088 const VkAllocationCallbacks* allocator,
1089 VkDevice* dev_out) {
1090 const driver::DebugReportLogger logger = driver::Logger(physical_dev);
1091 LayerChain chain(
1092 false, logger,
1093 (allocator) ? *allocator : driver::GetData(physical_dev).allocator);
1094
1095 VkResult result = chain.ActivateLayers(
1096 physical_dev, create_info->ppEnabledLayerNames,
1097 create_info->enabledLayerCount, create_info->ppEnabledExtensionNames,
1098 create_info->enabledExtensionCount);
1099 if (result != VK_SUCCESS)
1100 return result;
1101
1102 // use a local create info when the chain is not empty
1103 VkDeviceCreateInfo local_create_info;
1104 if (!chain.Empty()) {
1105 local_create_info = *create_info;
1106 chain.ModifyCreateInfo(local_create_info);
1107 create_info = &local_create_info;
1108 }
1109
1110 return chain.Create(physical_dev, create_info, allocator, dev_out);
1111 }
1112
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * allocator)1113 void LayerChain::DestroyInstance(VkInstance instance,
1114 const VkAllocationCallbacks* allocator) {
1115 InstanceData& data = GetData(instance);
1116
1117 if (data.debug_callback != VK_NULL_HANDLE)
1118 data.destroy_debug_callback(instance, data.debug_callback, allocator);
1119
1120 ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers);
1121 uint32_t layer_count = data.layer_count;
1122
1123 VkAllocationCallbacks local_allocator;
1124 if (!allocator)
1125 local_allocator = driver::GetData(instance).allocator;
1126
1127 // this also destroys InstanceData
1128 data.dispatch.DestroyInstance(instance, allocator);
1129
1130 DestroyLayers(layers, layer_count,
1131 (allocator) ? *allocator : local_allocator);
1132 }
1133
DestroyDevice(VkDevice device,const VkAllocationCallbacks * allocator)1134 void LayerChain::DestroyDevice(VkDevice device,
1135 const VkAllocationCallbacks* allocator) {
1136 DeviceData& data = GetData(device);
1137 // this also destroys DeviceData
1138 data.dispatch.DestroyDevice(device, allocator);
1139 }
1140
GetActiveLayers(VkPhysicalDevice physical_dev,uint32_t & count)1141 const LayerChain::ActiveLayer* LayerChain::GetActiveLayers(
1142 VkPhysicalDevice physical_dev,
1143 uint32_t& count) {
1144 count = GetData(physical_dev).layer_count;
1145 return reinterpret_cast<const ActiveLayer*>(GetData(physical_dev).layers);
1146 }
1147
1148 // ----------------------------------------------------------------------------
1149
EnsureInitialized()1150 bool EnsureInitialized() {
1151 static std::once_flag once_flag;
1152 static bool initialized;
1153
1154 std::call_once(once_flag, []() {
1155 if (driver::OpenHAL()) {
1156 DiscoverLayers();
1157 initialized = true;
1158 }
1159 });
1160
1161 return initialized;
1162 }
1163
1164 } // anonymous namespace
1165
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)1166 VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1167 const VkAllocationCallbacks* pAllocator,
1168 VkInstance* pInstance) {
1169 if (!EnsureInitialized())
1170 return VK_ERROR_INITIALIZATION_FAILED;
1171
1172 return LayerChain::CreateInstance(pCreateInfo, pAllocator, pInstance);
1173 }
1174
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)1175 void DestroyInstance(VkInstance instance,
1176 const VkAllocationCallbacks* pAllocator) {
1177 if (instance != VK_NULL_HANDLE)
1178 LayerChain::DestroyInstance(instance, pAllocator);
1179 }
1180
CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1181 VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1182 const VkDeviceCreateInfo* pCreateInfo,
1183 const VkAllocationCallbacks* pAllocator,
1184 VkDevice* pDevice) {
1185 return LayerChain::CreateDevice(physicalDevice, pCreateInfo, pAllocator,
1186 pDevice);
1187 }
1188
DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)1189 void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1190 if (device != VK_NULL_HANDLE)
1191 LayerChain::DestroyDevice(device, pAllocator);
1192 }
1193
EnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)1194 VkResult EnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
1195 VkLayerProperties* pProperties) {
1196 if (!EnsureInitialized())
1197 return VK_ERROR_INITIALIZATION_FAILED;
1198
1199 uint32_t count = GetLayerCount();
1200
1201 if (!pProperties) {
1202 *pPropertyCount = count;
1203 return VK_SUCCESS;
1204 }
1205
1206 uint32_t copied = std::min(*pPropertyCount, count);
1207 for (uint32_t i = 0; i < copied; i++)
1208 pProperties[i] = GetLayerProperties(GetLayer(i));
1209 *pPropertyCount = copied;
1210
1211 return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE;
1212 }
1213
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1214 VkResult EnumerateInstanceExtensionProperties(
1215 const char* pLayerName,
1216 uint32_t* pPropertyCount,
1217 VkExtensionProperties* pProperties) {
1218 if (!EnsureInitialized())
1219 return VK_ERROR_INITIALIZATION_FAILED;
1220
1221 if (pLayerName) {
1222 const Layer* layer = FindLayer(pLayerName);
1223 if (!layer)
1224 return VK_ERROR_LAYER_NOT_PRESENT;
1225
1226 uint32_t count;
1227 const VkExtensionProperties* props =
1228 GetLayerInstanceExtensions(*layer, count);
1229
1230 if (!pProperties || *pPropertyCount > count)
1231 *pPropertyCount = count;
1232 if (pProperties)
1233 std::copy(props, props + *pPropertyCount, pProperties);
1234
1235 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1236 }
1237
1238 // TODO how about extensions from implicitly enabled layers?
1239 return vulkan::driver::EnumerateInstanceExtensionProperties(
1240 nullptr, pPropertyCount, pProperties);
1241 }
1242
EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkLayerProperties * pProperties)1243 VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1244 uint32_t* pPropertyCount,
1245 VkLayerProperties* pProperties) {
1246 uint32_t count;
1247 const LayerChain::ActiveLayer* layers =
1248 LayerChain::GetActiveLayers(physicalDevice, count);
1249
1250 if (!pProperties) {
1251 *pPropertyCount = count;
1252 return VK_SUCCESS;
1253 }
1254
1255 uint32_t copied = std::min(*pPropertyCount, count);
1256 for (uint32_t i = 0; i < copied; i++)
1257 pProperties[i] = GetLayerProperties(*layers[i].ref);
1258 *pPropertyCount = copied;
1259
1260 return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE;
1261 }
1262
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1263 VkResult EnumerateDeviceExtensionProperties(
1264 VkPhysicalDevice physicalDevice,
1265 const char* pLayerName,
1266 uint32_t* pPropertyCount,
1267 VkExtensionProperties* pProperties) {
1268 if (pLayerName) {
1269 // EnumerateDeviceLayerProperties enumerates active layers for
1270 // backward compatibility. The extension query here should work for
1271 // all layers.
1272 const Layer* layer = FindLayer(pLayerName);
1273 if (!layer)
1274 return VK_ERROR_LAYER_NOT_PRESENT;
1275
1276 uint32_t count;
1277 const VkExtensionProperties* props =
1278 GetLayerDeviceExtensions(*layer, count);
1279
1280 if (!pProperties || *pPropertyCount > count)
1281 *pPropertyCount = count;
1282 if (pProperties)
1283 std::copy(props, props + *pPropertyCount, pProperties);
1284
1285 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1286 }
1287
1288 // TODO how about extensions from implicitly enabled layers?
1289 const InstanceData& data = GetData(physicalDevice);
1290 return data.dispatch.EnumerateDeviceExtensionProperties(
1291 physicalDevice, nullptr, pPropertyCount, pProperties);
1292 }
1293
EnumerateInstanceVersion(uint32_t * pApiVersion)1294 VkResult EnumerateInstanceVersion(uint32_t* pApiVersion) {
1295 *pApiVersion = VK_API_VERSION_1_1;
1296 return VK_SUCCESS;
1297 }
1298
1299 } // namespace api
1300 } // namespace vulkan
1301