blob: ce6b533f4067afbf10bd944ed481437ea8c592d0 [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
24#include <stdlib.h>
25#include <string.h>
26#include <algorithm>
27#include <mutex>
28#include <new>
29#include <utility>
30#include <cutils/properties.h>
31#include <log/log.h>
32
33#include <vulkan/vk_layer_interface.h>
34#include "api.h"
35#include "driver.h"
Chia-I Wuc96880f2016-03-26 06:56:45 +080036#include "layers_extensions.h"
Chia-I Wu0c203242016-03-15 13:44:51 +080037
38namespace vulkan {
39namespace api {
40
41namespace {
42
43// Provide overridden layer names when there are implicit layers. No effect
44// otherwise.
45class OverrideLayerNames {
46 public:
47 OverrideLayerNames(bool is_instance, const VkAllocationCallbacks& allocator)
48 : is_instance_(is_instance),
49 allocator_(allocator),
50 scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
51 names_(nullptr),
52 name_count_(0),
53 implicit_layers_() {
54 implicit_layers_.result = VK_SUCCESS;
55 }
56
57 ~OverrideLayerNames() {
58 allocator_.pfnFree(allocator_.pUserData, names_);
59 allocator_.pfnFree(allocator_.pUserData, implicit_layers_.elements);
60 allocator_.pfnFree(allocator_.pUserData, implicit_layers_.name_pool);
61 }
62
Chia-I Wu026b8fa2016-04-11 13:44:13 +080063 VkResult Parse(const char* const* names, uint32_t count) {
64 AddImplicitLayers();
Chia-I Wu0c203242016-03-15 13:44:51 +080065
66 const auto& arr = implicit_layers_;
67 if (arr.result != VK_SUCCESS)
68 return arr.result;
69
70 // no need to override when there is no implicit layer
71 if (!arr.count)
72 return VK_SUCCESS;
73
Chia-I Wu026b8fa2016-04-11 13:44:13 +080074 names_ = AllocateNameArray(arr.count + count);
Chia-I Wu0c203242016-03-15 13:44:51 +080075 if (!names_)
76 return VK_ERROR_OUT_OF_HOST_MEMORY;
77
78 // add implicit layer names
79 for (uint32_t i = 0; i < arr.count; i++)
Chia-I Wu026b8fa2016-04-11 13:44:13 +080080 names_[i] = GetImplicitLayerName(i);
Chia-I Wu0c203242016-03-15 13:44:51 +080081
82 name_count_ = arr.count;
83
84 // add explicit layer names
85 for (uint32_t i = 0; i < count; i++) {
86 // ignore explicit layers that are also implicit
Chia-I Wu026b8fa2016-04-11 13:44:13 +080087 if (IsImplicitLayer(names[i]))
Chia-I Wu0c203242016-03-15 13:44:51 +080088 continue;
89
90 names_[name_count_++] = names[i];
91 }
92
93 return VK_SUCCESS;
94 }
95
Chia-I Wu026b8fa2016-04-11 13:44:13 +080096 const char* const* Names() const { return names_; }
Chia-I Wu0c203242016-03-15 13:44:51 +080097
Chia-I Wu026b8fa2016-04-11 13:44:13 +080098 uint32_t Count() const { return name_count_; }
Chia-I Wu0c203242016-03-15 13:44:51 +080099
100 private:
101 struct ImplicitLayer {
102 int priority;
103 size_t name_offset;
104 };
105
106 struct ImplicitLayerArray {
107 ImplicitLayer* elements;
108 uint32_t max_count;
109 uint32_t count;
110
111 char* name_pool;
112 size_t max_pool_size;
113 size_t pool_size;
114
115 VkResult result;
116 };
117
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800118 void AddImplicitLayers() {
Chia-I Wu0c203242016-03-15 13:44:51 +0800119 if (!driver::Debuggable())
120 return;
121
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800122 ParseDebugVulkanLayers();
123 property_list(ParseDebugVulkanLayer, this);
Chia-I Wu0c203242016-03-15 13:44:51 +0800124
125 // sort by priorities
126 auto& arr = implicit_layers_;
127 std::sort(arr.elements, arr.elements + arr.count,
128 [](const ImplicitLayer& a, const ImplicitLayer& b) {
129 return (a.priority < b.priority);
130 });
131 }
132
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800133 void ParseDebugVulkanLayers() {
Chia-I Wu0c203242016-03-15 13:44:51 +0800134 // debug.vulkan.layers specifies colon-separated layer names
135 char prop[PROPERTY_VALUE_MAX];
136 if (!property_get("debug.vulkan.layers", prop, ""))
137 return;
138
139 // assign negative/high priorities to them
140 int prio = -PROPERTY_VALUE_MAX;
141
142 const char* p = prop;
143 const char* delim;
144 while ((delim = strchr(p, ':'))) {
145 if (delim > p)
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800146 AddImplicitLayer(prio, p, static_cast<size_t>(delim - p));
Chia-I Wu0c203242016-03-15 13:44:51 +0800147
148 prio++;
149 p = delim + 1;
150 }
151
152 if (p[0] != '\0')
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800153 AddImplicitLayer(prio, p, strlen(p));
Chia-I Wu0c203242016-03-15 13:44:51 +0800154 }
155
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800156 static void ParseDebugVulkanLayer(const char* key,
157 const char* val,
158 void* user_data) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800159 static const char prefix[] = "debug.vulkan.layer.";
160 const size_t prefix_len = sizeof(prefix) - 1;
161
162 if (strncmp(key, prefix, prefix_len) || val[0] == '\0')
163 return;
164 key += prefix_len;
165
166 // debug.vulkan.layer.<priority>
167 int priority = -1;
168 if (key[0] >= '0' && key[0] <= '9')
169 priority = atoi(key);
170
171 if (priority < 0) {
172 ALOGW("Ignored implicit layer %s with invalid priority %s", val,
173 key);
174 return;
175 }
176
177 OverrideLayerNames& override_layers =
178 *reinterpret_cast<OverrideLayerNames*>(user_data);
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800179 override_layers.AddImplicitLayer(priority, val, strlen(val));
Chia-I Wu0c203242016-03-15 13:44:51 +0800180 }
181
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800182 void AddImplicitLayer(int priority, const char* name, size_t len) {
183 if (!GrowImplicitLayerArray(1, 0))
Chia-I Wu0c203242016-03-15 13:44:51 +0800184 return;
185
186 auto& arr = implicit_layers_;
187 auto& layer = arr.elements[arr.count++];
188
189 layer.priority = priority;
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800190 layer.name_offset = AddImplicitLayerName(name, len);
Chia-I Wu0c203242016-03-15 13:44:51 +0800191
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800192 ALOGV("Added implicit layer %s", GetImplicitLayerName(arr.count - 1));
Chia-I Wu0c203242016-03-15 13:44:51 +0800193 }
194
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800195 size_t AddImplicitLayerName(const char* name, size_t len) {
196 if (!GrowImplicitLayerArray(0, len + 1))
Chia-I Wu0c203242016-03-15 13:44:51 +0800197 return 0;
198
199 // add the name to the pool
200 auto& arr = implicit_layers_;
201 size_t offset = arr.pool_size;
202 char* dst = arr.name_pool + offset;
203
204 std::copy(name, name + len, dst);
205 dst[len] = '\0';
206
207 arr.pool_size += len + 1;
208
209 return offset;
210 }
211
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800212 bool GrowImplicitLayerArray(uint32_t layer_count, size_t name_size) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800213 const uint32_t initial_max_count = 16;
214 const size_t initial_max_pool_size = 512;
215
216 auto& arr = implicit_layers_;
217
218 // grow the element array if needed
219 while (arr.count + layer_count > arr.max_count) {
220 uint32_t new_max_count =
221 (arr.max_count) ? (arr.max_count << 1) : initial_max_count;
222 void* new_mem = nullptr;
223
224 if (new_max_count > arr.max_count) {
225 new_mem = allocator_.pfnReallocation(
226 allocator_.pUserData, arr.elements,
227 sizeof(ImplicitLayer) * new_max_count,
228 alignof(ImplicitLayer), scope_);
229 }
230
231 if (!new_mem) {
232 arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
233 arr.count = 0;
234 return false;
235 }
236
237 arr.elements = reinterpret_cast<ImplicitLayer*>(new_mem);
238 arr.max_count = new_max_count;
239 }
240
241 // grow the name pool if needed
242 while (arr.pool_size + name_size > arr.max_pool_size) {
243 size_t new_max_pool_size = (arr.max_pool_size)
244 ? (arr.max_pool_size << 1)
245 : initial_max_pool_size;
246 void* new_mem = nullptr;
247
248 if (new_max_pool_size > arr.max_pool_size) {
249 new_mem = allocator_.pfnReallocation(
250 allocator_.pUserData, arr.name_pool, new_max_pool_size,
251 alignof(char), scope_);
252 }
253
254 if (!new_mem) {
255 arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
256 arr.pool_size = 0;
257 return false;
258 }
259
260 arr.name_pool = reinterpret_cast<char*>(new_mem);
261 arr.max_pool_size = new_max_pool_size;
262 }
263
264 return true;
265 }
266
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800267 const char* GetImplicitLayerName(uint32_t index) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800268 const auto& arr = implicit_layers_;
269
270 // this may return nullptr when arr.result is not VK_SUCCESS
271 return implicit_layers_.name_pool + arr.elements[index].name_offset;
272 }
273
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800274 bool IsImplicitLayer(const char* name) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800275 const auto& arr = implicit_layers_;
276
277 for (uint32_t i = 0; i < arr.count; i++) {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800278 if (strcmp(name, GetImplicitLayerName(i)) == 0)
Chia-I Wu0c203242016-03-15 13:44:51 +0800279 return true;
280 }
281
282 return false;
283 }
284
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800285 const char** AllocateNameArray(uint32_t count) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800286 return reinterpret_cast<const char**>(allocator_.pfnAllocation(
287 allocator_.pUserData, sizeof(const char*) * count,
288 alignof(const char*), scope_));
289 }
290
291 const bool is_instance_;
292 const VkAllocationCallbacks& allocator_;
293 const VkSystemAllocationScope scope_;
294
295 const char** names_;
296 uint32_t name_count_;
297
298 ImplicitLayerArray implicit_layers_;
299};
300
301// Provide overridden extension names when there are implicit extensions.
302// No effect otherwise.
303//
304// This is used only to enable VK_EXT_debug_report.
305class OverrideExtensionNames {
306 public:
307 OverrideExtensionNames(bool is_instance,
308 const VkAllocationCallbacks& allocator)
309 : is_instance_(is_instance),
310 allocator_(allocator),
311 scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
312 names_(nullptr),
313 name_count_(0),
314 install_debug_callback_(false) {}
315
316 ~OverrideExtensionNames() {
317 allocator_.pfnFree(allocator_.pUserData, names_);
318 }
319
320 VkResult parse(const char* const* names, uint32_t count) {
321 // this is only for debug.vulkan.enable_callback
322 if (!enable_debug_callback())
323 return VK_SUCCESS;
324
325 names_ = allocate_name_array(count + 1);
326 if (!names_)
327 return VK_ERROR_OUT_OF_HOST_MEMORY;
328
329 std::copy(names, names + count, names_);
330
331 name_count_ = count;
332 names_[name_count_++] = "VK_EXT_debug_report";
333
334 install_debug_callback_ = true;
335
336 return VK_SUCCESS;
337 }
338
339 const char* const* names() const { return names_; }
340
341 uint32_t count() const { return name_count_; }
342
343 bool install_debug_callback() const { return install_debug_callback_; }
344
345 private:
346 bool enable_debug_callback() const {
347 return (is_instance_ && driver::Debuggable() &&
348 property_get_bool("debug.vulkan.enable_callback", false));
349 }
350
351 const char** allocate_name_array(uint32_t count) const {
352 return reinterpret_cast<const char**>(allocator_.pfnAllocation(
353 allocator_.pUserData, sizeof(const char*) * count,
354 alignof(const char*), scope_));
355 }
356
357 const bool is_instance_;
358 const VkAllocationCallbacks& allocator_;
359 const VkSystemAllocationScope scope_;
360
361 const char** names_;
362 uint32_t name_count_;
363 bool install_debug_callback_;
364};
365
366// vkCreateInstance and vkCreateDevice helpers with support for layer
367// chaining.
368class LayerChain {
369 public:
370 static VkResult create_instance(const VkInstanceCreateInfo* create_info,
371 const VkAllocationCallbacks* allocator,
372 VkInstance* instance_out);
373
374 static VkResult create_device(VkPhysicalDevice physical_dev,
375 const VkDeviceCreateInfo* create_info,
376 const VkAllocationCallbacks* allocator,
377 VkDevice* dev_out);
378
379 static void destroy_instance(VkInstance instance,
380 const VkAllocationCallbacks* allocator);
381
382 static void destroy_device(VkDevice dev,
383 const VkAllocationCallbacks* allocator);
384
385 private:
386 struct ActiveLayer {
387 LayerRef ref;
388 union {
389 VkLayerInstanceLink instance_link;
390 VkLayerDeviceLink device_link;
391 };
392 };
393
394 LayerChain(bool is_instance, const VkAllocationCallbacks& allocator);
395 ~LayerChain();
396
397 VkResult activate_layers(const char* const* layer_names,
398 uint32_t layer_count,
399 const char* const* extension_names,
400 uint32_t extension_count);
401 ActiveLayer* allocate_layer_array(uint32_t count) const;
402 VkResult load_layer(ActiveLayer& layer, const char* name);
403 void setup_layer_links();
404
405 bool empty() const;
406 void modify_create_info(VkInstanceCreateInfo& info);
407 void modify_create_info(VkDeviceCreateInfo& info);
408
409 VkResult create(const VkInstanceCreateInfo* create_info,
410 const VkAllocationCallbacks* allocator,
411 VkInstance* instance_out);
412
413 VkResult create(VkPhysicalDevice physical_dev,
414 const VkDeviceCreateInfo* create_info,
415 const VkAllocationCallbacks* allocator,
416 VkDevice* dev_out);
417
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800418 VkResult validate_extensions(const char* const* extension_names,
419 uint32_t extension_count);
420 VkResult validate_extensions(VkPhysicalDevice physical_dev,
421 const char* const* extension_names,
422 uint32_t extension_count);
423 VkExtensionProperties* allocate_driver_extension_array(
424 uint32_t count) const;
425 bool is_layer_extension(const char* name) const;
426 bool is_driver_extension(const char* name) const;
427
Chia-I Wu0c203242016-03-15 13:44:51 +0800428 template <typename DataType>
429 void steal_layers(DataType& data);
430
431 static void destroy_layers(ActiveLayer* layers,
432 uint32_t count,
433 const VkAllocationCallbacks& allocator);
434
435 static VKAPI_ATTR VkBool32
436 debug_report_callback(VkDebugReportFlagsEXT flags,
437 VkDebugReportObjectTypeEXT obj_type,
438 uint64_t obj,
439 size_t location,
440 int32_t msg_code,
441 const char* layer_prefix,
442 const char* msg,
443 void* user_data);
444
445 const bool is_instance_;
446 const VkAllocationCallbacks& allocator_;
447
448 OverrideLayerNames override_layers_;
449 OverrideExtensionNames override_extensions_;
450
451 ActiveLayer* layers_;
452 uint32_t layer_count_;
453
454 PFN_vkGetInstanceProcAddr get_instance_proc_addr_;
455 PFN_vkGetDeviceProcAddr get_device_proc_addr_;
456
457 union {
458 VkLayerInstanceCreateInfo instance_chain_info_;
459 VkLayerDeviceCreateInfo device_chain_info_;
460 };
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800461
462 VkExtensionProperties* driver_extensions_;
463 uint32_t driver_extension_count_;
Chia-I Wu0c203242016-03-15 13:44:51 +0800464};
465
466LayerChain::LayerChain(bool is_instance, const VkAllocationCallbacks& allocator)
467 : is_instance_(is_instance),
468 allocator_(allocator),
469 override_layers_(is_instance, allocator),
470 override_extensions_(is_instance, allocator),
471 layers_(nullptr),
472 layer_count_(0),
473 get_instance_proc_addr_(nullptr),
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800474 get_device_proc_addr_(nullptr),
475 driver_extensions_(nullptr),
476 driver_extension_count_(0) {}
Chia-I Wu0c203242016-03-15 13:44:51 +0800477
478LayerChain::~LayerChain() {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800479 allocator_.pfnFree(allocator_.pUserData, driver_extensions_);
Chia-I Wu0c203242016-03-15 13:44:51 +0800480 destroy_layers(layers_, layer_count_, allocator_);
481}
482
483VkResult LayerChain::activate_layers(const char* const* layer_names,
484 uint32_t layer_count,
485 const char* const* extension_names,
486 uint32_t extension_count) {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800487 VkResult result = override_layers_.Parse(layer_names, layer_count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800488 if (result != VK_SUCCESS)
489 return result;
490
491 result = override_extensions_.parse(extension_names, extension_count);
492 if (result != VK_SUCCESS)
493 return result;
494
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800495 if (override_layers_.Count()) {
496 layer_names = override_layers_.Names();
497 layer_count = override_layers_.Count();
Chia-I Wu0c203242016-03-15 13:44:51 +0800498 }
499
500 if (!layer_count) {
501 // point head of chain to the driver
502 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
503 if (!is_instance_)
504 get_device_proc_addr_ = driver::GetDeviceProcAddr;
505
506 return VK_SUCCESS;
507 }
508
509 layers_ = allocate_layer_array(layer_count);
510 if (!layers_)
511 return VK_ERROR_OUT_OF_HOST_MEMORY;
512
513 // load layers
514 for (uint32_t i = 0; i < layer_count; i++) {
515 result = load_layer(layers_[i], layer_names[i]);
516 if (result != VK_SUCCESS)
517 return result;
518
519 // count loaded layers for proper destructions on errors
520 layer_count_++;
521 }
522
523 setup_layer_links();
524
525 return VK_SUCCESS;
526}
527
528LayerChain::ActiveLayer* LayerChain::allocate_layer_array(
529 uint32_t count) const {
530 VkSystemAllocationScope scope = (is_instance_)
531 ? VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
532 : VK_SYSTEM_ALLOCATION_SCOPE_DEVICE;
533
534 return reinterpret_cast<ActiveLayer*>(allocator_.pfnAllocation(
535 allocator_.pUserData, sizeof(ActiveLayer) * count, alignof(ActiveLayer),
536 scope));
537}
538
539VkResult LayerChain::load_layer(ActiveLayer& layer, const char* name) {
540 if (is_instance_)
541 new (&layer) ActiveLayer{GetInstanceLayerRef(name), {}};
542 else
543 new (&layer) ActiveLayer{GetDeviceLayerRef(name), {}};
544
545 if (!layer.ref) {
546 ALOGE("Failed to load layer %s", name);
547 layer.ref.~LayerRef();
548 return VK_ERROR_LAYER_NOT_PRESENT;
549 }
550
551 ALOGI("Loaded %s layer %s", (is_instance_) ? "instance" : "device", name);
552
553 return VK_SUCCESS;
554}
555
556void LayerChain::setup_layer_links() {
557 if (is_instance_) {
558 for (uint32_t i = 0; i < layer_count_; i++) {
559 ActiveLayer& layer = layers_[i];
560
561 // point head of chain to the first layer
562 if (i == 0)
563 get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
564
565 // point tail of chain to the driver
566 if (i == layer_count_ - 1) {
567 layer.instance_link.pNext = nullptr;
568 layer.instance_link.pfnNextGetInstanceProcAddr =
569 driver::GetInstanceProcAddr;
570 break;
571 }
572
573 const ActiveLayer& next = layers_[i + 1];
574
575 // const_cast as some naughty layers want to modify our links!
576 layer.instance_link.pNext =
577 const_cast<VkLayerInstanceLink*>(&next.instance_link);
578 layer.instance_link.pfnNextGetInstanceProcAddr =
579 next.ref.GetGetInstanceProcAddr();
580 }
581 } else {
582 for (uint32_t i = 0; i < layer_count_; i++) {
583 ActiveLayer& layer = layers_[i];
584
585 // point head of chain to the first layer
586 if (i == 0) {
587 get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
588 get_device_proc_addr_ = layer.ref.GetGetDeviceProcAddr();
589 }
590
591 // point tail of chain to the driver
592 if (i == layer_count_ - 1) {
593 layer.device_link.pNext = nullptr;
594 layer.device_link.pfnNextGetInstanceProcAddr =
595 driver::GetInstanceProcAddr;
596 layer.device_link.pfnNextGetDeviceProcAddr =
597 driver::GetDeviceProcAddr;
598 break;
599 }
600
601 const ActiveLayer& next = layers_[i + 1];
602
603 // const_cast as some naughty layers want to modify our links!
604 layer.device_link.pNext =
605 const_cast<VkLayerDeviceLink*>(&next.device_link);
606 layer.device_link.pfnNextGetInstanceProcAddr =
607 next.ref.GetGetInstanceProcAddr();
608 layer.device_link.pfnNextGetDeviceProcAddr =
609 next.ref.GetGetDeviceProcAddr();
610 }
611 }
612}
613
614bool LayerChain::empty() const {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800615 return (!layer_count_ && !override_layers_.Count() &&
Chia-I Wu0c203242016-03-15 13:44:51 +0800616 !override_extensions_.count());
617}
618
619void LayerChain::modify_create_info(VkInstanceCreateInfo& info) {
620 if (layer_count_) {
621 const ActiveLayer& layer = layers_[0];
622
623 instance_chain_info_.sType =
624 VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
625 instance_chain_info_.function = VK_LAYER_FUNCTION_LINK;
626 // TODO fix vk_layer_interface.h and get rid of const_cast?
627 instance_chain_info_.u.pLayerInfo =
628 const_cast<VkLayerInstanceLink*>(&layer.instance_link);
629
630 // insert layer info
631 instance_chain_info_.pNext = info.pNext;
632 info.pNext = &instance_chain_info_;
633 }
634
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800635 if (override_layers_.Count()) {
636 info.enabledLayerCount = override_layers_.Count();
637 info.ppEnabledLayerNames = override_layers_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800638 }
639
640 if (override_extensions_.count()) {
641 info.enabledExtensionCount = override_extensions_.count();
642 info.ppEnabledExtensionNames = override_extensions_.names();
643 }
644}
645
646void LayerChain::modify_create_info(VkDeviceCreateInfo& info) {
647 if (layer_count_) {
648 const ActiveLayer& layer = layers_[0];
649
650 device_chain_info_.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
651 device_chain_info_.function = VK_LAYER_FUNCTION_LINK;
652 // TODO fix vk_layer_interface.h and get rid of const_cast?
653 device_chain_info_.u.pLayerInfo =
654 const_cast<VkLayerDeviceLink*>(&layer.device_link);
655
656 // insert layer info
657 device_chain_info_.pNext = info.pNext;
658 info.pNext = &device_chain_info_;
659 }
660
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800661 if (override_layers_.Count()) {
662 info.enabledLayerCount = override_layers_.Count();
663 info.ppEnabledLayerNames = override_layers_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800664 }
665
666 if (override_extensions_.count()) {
667 info.enabledExtensionCount = override_extensions_.count();
668 info.ppEnabledExtensionNames = override_extensions_.names();
669 }
670}
671
672VkResult LayerChain::create(const VkInstanceCreateInfo* create_info,
673 const VkAllocationCallbacks* allocator,
674 VkInstance* instance_out) {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800675 VkResult result = validate_extensions(create_info->ppEnabledExtensionNames,
676 create_info->enabledExtensionCount);
677 if (result != VK_SUCCESS)
678 return result;
679
Chia-I Wu0c203242016-03-15 13:44:51 +0800680 // call down the chain
681 PFN_vkCreateInstance create_instance =
682 reinterpret_cast<PFN_vkCreateInstance>(
683 get_instance_proc_addr_(VK_NULL_HANDLE, "vkCreateInstance"));
684 VkInstance instance;
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800685 result = create_instance(create_info, allocator, &instance);
Chia-I Wu0c203242016-03-15 13:44:51 +0800686 if (result != VK_SUCCESS)
687 return result;
688
689 // initialize InstanceData
690 InstanceData& data = GetData(instance);
691 memset(&data, 0, sizeof(data));
692
693 data.instance = instance;
694
695 if (!InitDispatchTable(instance, get_instance_proc_addr_)) {
696 if (data.dispatch.DestroyInstance)
697 data.dispatch.DestroyInstance(instance, allocator);
698
699 return VK_ERROR_INITIALIZATION_FAILED;
700 }
701
702 // install debug report callback
703 if (override_extensions_.install_debug_callback()) {
704 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
705 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
706 get_instance_proc_addr_(instance,
707 "vkCreateDebugReportCallbackEXT"));
708 data.destroy_debug_callback =
709 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
710 get_instance_proc_addr_(instance,
711 "vkDestroyDebugReportCallbackEXT"));
712 if (!create_debug_report_callback || !data.destroy_debug_callback) {
713 ALOGE("Broken VK_EXT_debug_report support");
714 data.dispatch.DestroyInstance(instance, allocator);
715 return VK_ERROR_INITIALIZATION_FAILED;
716 }
717
718 VkDebugReportCallbackCreateInfoEXT debug_callback_info = {};
719 debug_callback_info.sType =
720 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
721 debug_callback_info.flags =
722 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
723 debug_callback_info.pfnCallback = debug_report_callback;
724
725 VkDebugReportCallbackEXT debug_callback;
726 result = create_debug_report_callback(instance, &debug_callback_info,
727 nullptr, &debug_callback);
728 if (result != VK_SUCCESS) {
729 ALOGE("Failed to install debug report callback");
730 data.dispatch.DestroyInstance(instance, allocator);
731 return VK_ERROR_INITIALIZATION_FAILED;
732 }
733
734 data.debug_callback = debug_callback;
735
736 ALOGI("Installed debug report callback");
737 }
738
739 steal_layers(data);
740
741 *instance_out = instance;
742
743 return VK_SUCCESS;
744}
745
746VkResult LayerChain::create(VkPhysicalDevice physical_dev,
747 const VkDeviceCreateInfo* create_info,
748 const VkAllocationCallbacks* allocator,
749 VkDevice* dev_out) {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800750 VkResult result =
751 validate_extensions(physical_dev, create_info->ppEnabledExtensionNames,
752 create_info->enabledExtensionCount);
753 if (result != VK_SUCCESS)
754 return result;
755
Chia-I Wu0c203242016-03-15 13:44:51 +0800756 // call down the chain
757 //
758 // TODO Instance call chain available at
759 // GetData(physical_dev).dispatch.CreateDevice is ignored. Is that
760 // right?
761 VkInstance instance = GetData(physical_dev).instance;
762 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
763 get_instance_proc_addr_(instance, "vkCreateDevice"));
764 VkDevice dev;
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800765 result = create_device(physical_dev, create_info, allocator, &dev);
Chia-I Wu0c203242016-03-15 13:44:51 +0800766 if (result != VK_SUCCESS)
767 return result;
768
769 // initialize DeviceData
770 DeviceData& data = GetData(dev);
771 memset(&data, 0, sizeof(data));
772
773 if (!InitDispatchTable(dev, get_device_proc_addr_)) {
774 if (data.dispatch.DestroyDevice)
775 data.dispatch.DestroyDevice(dev, allocator);
776
777 return VK_ERROR_INITIALIZATION_FAILED;
778 }
779
780 steal_layers(data);
781
782 *dev_out = dev;
783
784 return VK_SUCCESS;
785}
786
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800787VkResult LayerChain::validate_extensions(const char* const* extension_names,
788 uint32_t extension_count) {
789 if (!extension_count)
790 return VK_SUCCESS;
791
792 // query driver instance extensions
793 uint32_t count;
794 VkResult result =
795 EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
796 if (result == VK_SUCCESS && count) {
797 driver_extensions_ = allocate_driver_extension_array(count);
798 result = (driver_extensions_) ? EnumerateInstanceExtensionProperties(
799 nullptr, &count, driver_extensions_)
800 : VK_ERROR_OUT_OF_HOST_MEMORY;
801 }
802 if (result != VK_SUCCESS)
803 return result;
804
805 driver_extension_count_ = count;
806
807 for (uint32_t i = 0; i < extension_count; i++) {
808 const char* name = extension_names[i];
809 if (!is_layer_extension(name) && !is_driver_extension(name)) {
810 ALOGE("Failed to enable missing instance extension %s", name);
811 return VK_ERROR_EXTENSION_NOT_PRESENT;
812 }
813 }
814
815 return VK_SUCCESS;
816}
817
818VkResult LayerChain::validate_extensions(VkPhysicalDevice physical_dev,
819 const char* const* extension_names,
820 uint32_t extension_count) {
821 if (!extension_count)
822 return VK_SUCCESS;
823
824 // query driver device extensions
825 uint32_t count;
826 VkResult result = EnumerateDeviceExtensionProperties(physical_dev, nullptr,
827 &count, nullptr);
828 if (result == VK_SUCCESS && count) {
829 driver_extensions_ = allocate_driver_extension_array(count);
830 result = (driver_extensions_)
831 ? EnumerateDeviceExtensionProperties(
832 physical_dev, nullptr, &count, driver_extensions_)
833 : VK_ERROR_OUT_OF_HOST_MEMORY;
834 }
835 if (result != VK_SUCCESS)
836 return result;
837
838 driver_extension_count_ = count;
839
840 for (uint32_t i = 0; i < extension_count; i++) {
841 const char* name = extension_names[i];
842 if (!is_layer_extension(name) && !is_driver_extension(name)) {
843 ALOGE("Failed to enable missing device extension %s", name);
844 return VK_ERROR_EXTENSION_NOT_PRESENT;
845 }
846 }
847
848 return VK_SUCCESS;
849}
850
851VkExtensionProperties* LayerChain::allocate_driver_extension_array(
852 uint32_t count) const {
853 return reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
854 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
855 alignof(VkExtensionProperties), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
856}
857
858bool LayerChain::is_layer_extension(const char* name) const {
859 for (uint32_t i = 0; i < layer_count_; i++) {
860 const ActiveLayer& layer = layers_[i];
861 if (layer.ref.SupportsExtension(name))
862 return true;
863 }
864
865 return false;
866}
867
868bool LayerChain::is_driver_extension(const char* name) const {
869 for (uint32_t i = 0; i < driver_extension_count_; i++) {
870 if (strcmp(driver_extensions_[i].extensionName, name) == 0)
871 return true;
872 }
873
874 return false;
875}
876
Chia-I Wu0c203242016-03-15 13:44:51 +0800877template <typename DataType>
878void LayerChain::steal_layers(DataType& data) {
879 data.layers = layers_;
880 data.layer_count = layer_count_;
881
882 layers_ = nullptr;
883 layer_count_ = 0;
884}
885
886void LayerChain::destroy_layers(ActiveLayer* layers,
887 uint32_t count,
888 const VkAllocationCallbacks& allocator) {
889 for (uint32_t i = 0; i < count; i++)
890 layers[i].ref.~LayerRef();
891
892 allocator.pfnFree(allocator.pUserData, layers);
893}
894
895VkBool32 LayerChain::debug_report_callback(VkDebugReportFlagsEXT flags,
896 VkDebugReportObjectTypeEXT obj_type,
897 uint64_t obj,
898 size_t location,
899 int32_t msg_code,
900 const char* layer_prefix,
901 const char* msg,
902 void* user_data) {
903 int prio;
904
905 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
906 prio = ANDROID_LOG_ERROR;
907 else if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT |
908 VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT))
909 prio = ANDROID_LOG_WARN;
910 else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
911 prio = ANDROID_LOG_INFO;
912 else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
913 prio = ANDROID_LOG_DEBUG;
914 else
915 prio = ANDROID_LOG_UNKNOWN;
916
917 LOG_PRI(prio, LOG_TAG, "[%s] Code %d : %s", layer_prefix, msg_code, msg);
918
919 (void)obj_type;
920 (void)obj;
921 (void)location;
922 (void)user_data;
923
924 return false;
925}
926
927VkResult LayerChain::create_instance(const VkInstanceCreateInfo* create_info,
928 const VkAllocationCallbacks* allocator,
929 VkInstance* instance_out) {
930 LayerChain chain(true,
931 (allocator) ? *allocator : driver::GetDefaultAllocator());
932
933 VkResult result = chain.activate_layers(
934 create_info->ppEnabledLayerNames, create_info->enabledLayerCount,
935 create_info->ppEnabledExtensionNames,
936 create_info->enabledExtensionCount);
937 if (result != VK_SUCCESS)
938 return result;
939
940 // use a local create info when the chain is not empty
941 VkInstanceCreateInfo local_create_info;
942 if (!chain.empty()) {
943 local_create_info = *create_info;
944 chain.modify_create_info(local_create_info);
945 create_info = &local_create_info;
946 }
947
948 return chain.create(create_info, allocator, instance_out);
949}
950
951VkResult LayerChain::create_device(VkPhysicalDevice physical_dev,
952 const VkDeviceCreateInfo* create_info,
953 const VkAllocationCallbacks* allocator,
954 VkDevice* dev_out) {
955 LayerChain chain(false, (allocator)
956 ? *allocator
957 : driver::GetData(physical_dev).allocator);
958
959 VkResult result = chain.activate_layers(
960 create_info->ppEnabledLayerNames, create_info->enabledLayerCount,
961 create_info->ppEnabledExtensionNames,
962 create_info->enabledExtensionCount);
963 if (result != VK_SUCCESS)
964 return result;
965
966 // use a local create info when the chain is not empty
967 VkDeviceCreateInfo local_create_info;
968 if (!chain.empty()) {
969 local_create_info = *create_info;
970 chain.modify_create_info(local_create_info);
971 create_info = &local_create_info;
972 }
973
974 return chain.create(physical_dev, create_info, allocator, dev_out);
975}
976
977void LayerChain::destroy_instance(VkInstance instance,
978 const VkAllocationCallbacks* allocator) {
979 InstanceData& data = GetData(instance);
980
981 if (data.debug_callback != VK_NULL_HANDLE)
982 data.destroy_debug_callback(instance, data.debug_callback, allocator);
983
984 ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers);
985 uint32_t layer_count = data.layer_count;
986
987 VkAllocationCallbacks local_allocator;
988 if (!allocator)
989 local_allocator = driver::GetData(instance).allocator;
990
991 // this also destroys InstanceData
992 data.dispatch.DestroyInstance(instance, allocator);
993
994 destroy_layers(layers, layer_count,
995 (allocator) ? *allocator : local_allocator);
996}
997
998void LayerChain::destroy_device(VkDevice device,
999 const VkAllocationCallbacks* allocator) {
1000 DeviceData& data = GetData(device);
1001
1002 ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers);
1003 uint32_t layer_count = data.layer_count;
1004
1005 VkAllocationCallbacks local_allocator;
1006 if (!allocator)
1007 local_allocator = driver::GetData(device).allocator;
1008
1009 // this also destroys DeviceData
1010 data.dispatch.DestroyDevice(device, allocator);
1011
1012 destroy_layers(layers, layer_count,
1013 (allocator) ? *allocator : local_allocator);
1014}
1015
1016// ----------------------------------------------------------------------------
1017
1018bool EnsureInitialized() {
1019 static std::once_flag once_flag;
1020 static bool initialized;
1021
1022 std::call_once(once_flag, []() {
1023 if (driver::OpenHAL()) {
1024 DiscoverLayers();
1025 initialized = true;
1026 }
1027 });
1028
1029 return initialized;
1030}
1031
1032} // anonymous namespace
1033
1034VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1035 const VkAllocationCallbacks* pAllocator,
1036 VkInstance* pInstance) {
1037 if (!EnsureInitialized())
1038 return VK_ERROR_INITIALIZATION_FAILED;
1039
1040 return LayerChain::create_instance(pCreateInfo, pAllocator, pInstance);
1041}
1042
1043void DestroyInstance(VkInstance instance,
1044 const VkAllocationCallbacks* pAllocator) {
1045 if (instance != VK_NULL_HANDLE)
1046 LayerChain::destroy_instance(instance, pAllocator);
1047}
1048
1049VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1050 const VkDeviceCreateInfo* pCreateInfo,
1051 const VkAllocationCallbacks* pAllocator,
1052 VkDevice* pDevice) {
1053 return LayerChain::create_device(physicalDevice, pCreateInfo, pAllocator,
1054 pDevice);
1055}
1056
1057void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1058 if (device != VK_NULL_HANDLE)
1059 LayerChain::destroy_device(device, pAllocator);
1060}
1061
1062VkResult EnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
1063 VkLayerProperties* pProperties) {
1064 if (!EnsureInitialized())
1065 return VK_ERROR_INITIALIZATION_FAILED;
1066
1067 uint32_t count =
1068 EnumerateInstanceLayers(pProperties ? *pPropertyCount : 0, pProperties);
1069
1070 if (!pProperties || *pPropertyCount > count)
1071 *pPropertyCount = count;
1072
1073 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1074}
1075
1076VkResult EnumerateInstanceExtensionProperties(
1077 const char* pLayerName,
1078 uint32_t* pPropertyCount,
1079 VkExtensionProperties* pProperties) {
1080 if (!EnsureInitialized())
1081 return VK_ERROR_INITIALIZATION_FAILED;
1082
1083 if (pLayerName) {
1084 const VkExtensionProperties* props;
1085 uint32_t count;
1086 GetInstanceLayerExtensions(pLayerName, &props, &count);
1087
1088 if (!pProperties || *pPropertyCount > count)
1089 *pPropertyCount = count;
1090 if (pProperties)
1091 std::copy(props, props + *pPropertyCount, pProperties);
1092
1093 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1094 }
1095
1096 // TODO how about extensions from implicitly enabled layers?
1097 return vulkan::driver::EnumerateInstanceExtensionProperties(
1098 nullptr, pPropertyCount, pProperties);
1099}
1100
1101VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1102 uint32_t* pPropertyCount,
1103 VkLayerProperties* pProperties) {
1104 (void)physicalDevice;
1105
1106 uint32_t count =
1107 EnumerateDeviceLayers(pProperties ? *pPropertyCount : 0, pProperties);
1108
1109 if (!pProperties || *pPropertyCount > count)
1110 *pPropertyCount = count;
1111
1112 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1113}
1114
1115VkResult EnumerateDeviceExtensionProperties(
1116 VkPhysicalDevice physicalDevice,
1117 const char* pLayerName,
1118 uint32_t* pPropertyCount,
1119 VkExtensionProperties* pProperties) {
1120 if (pLayerName) {
1121 const VkExtensionProperties* props;
1122 uint32_t count;
1123 GetDeviceLayerExtensions(pLayerName, &props, &count);
1124
1125 if (!pProperties || *pPropertyCount > count)
1126 *pPropertyCount = count;
1127 if (pProperties)
1128 std::copy(props, props + *pPropertyCount, pProperties);
1129
1130 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1131 }
1132
1133 // TODO how about extensions from implicitly enabled layers?
1134 const InstanceData& data = GetData(physicalDevice);
1135 return data.dispatch.EnumerateDeviceExtensionProperties(
1136 physicalDevice, nullptr, pPropertyCount, pProperties);
1137}
1138
1139} // namespace api
1140} // namespace vulkan