blob: 4d30bbb96548cb9be677b950071e61740ecf3edb [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>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070030
31#include <android/log.h>
Chia-I Wu0c203242016-03-15 13:44:51 +080032#include <cutils/properties.h>
Chia-I Wu0c203242016-03-15 13:44:51 +080033
34#include <vulkan/vk_layer_interface.h>
35#include "api.h"
36#include "driver.h"
Chia-I Wuc96880f2016-03-26 06:56:45 +080037#include "layers_extensions.h"
Chia-I Wu0c203242016-03-15 13:44:51 +080038
39namespace vulkan {
40namespace api {
41
42namespace {
43
44// Provide overridden layer names when there are implicit layers. No effect
45// otherwise.
46class OverrideLayerNames {
47 public:
48 OverrideLayerNames(bool is_instance, const VkAllocationCallbacks& allocator)
49 : is_instance_(is_instance),
50 allocator_(allocator),
51 scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
52 names_(nullptr),
53 name_count_(0),
54 implicit_layers_() {
55 implicit_layers_.result = VK_SUCCESS;
56 }
57
58 ~OverrideLayerNames() {
59 allocator_.pfnFree(allocator_.pUserData, names_);
60 allocator_.pfnFree(allocator_.pUserData, implicit_layers_.elements);
61 allocator_.pfnFree(allocator_.pUserData, implicit_layers_.name_pool);
62 }
63
Chia-I Wu026b8fa2016-04-11 13:44:13 +080064 VkResult Parse(const char* const* names, uint32_t count) {
65 AddImplicitLayers();
Chia-I Wu0c203242016-03-15 13:44:51 +080066
67 const auto& arr = implicit_layers_;
68 if (arr.result != VK_SUCCESS)
69 return arr.result;
70
71 // no need to override when there is no implicit layer
72 if (!arr.count)
73 return VK_SUCCESS;
74
Chia-I Wu026b8fa2016-04-11 13:44:13 +080075 names_ = AllocateNameArray(arr.count + count);
Chia-I Wu0c203242016-03-15 13:44:51 +080076 if (!names_)
77 return VK_ERROR_OUT_OF_HOST_MEMORY;
78
79 // add implicit layer names
80 for (uint32_t i = 0; i < arr.count; i++)
Chia-I Wu026b8fa2016-04-11 13:44:13 +080081 names_[i] = GetImplicitLayerName(i);
Chia-I Wu0c203242016-03-15 13:44:51 +080082
83 name_count_ = arr.count;
84
85 // add explicit layer names
86 for (uint32_t i = 0; i < count; i++) {
87 // ignore explicit layers that are also implicit
Chia-I Wu026b8fa2016-04-11 13:44:13 +080088 if (IsImplicitLayer(names[i]))
Chia-I Wu0c203242016-03-15 13:44:51 +080089 continue;
90
91 names_[name_count_++] = names[i];
92 }
93
94 return VK_SUCCESS;
95 }
96
Chia-I Wu026b8fa2016-04-11 13:44:13 +080097 const char* const* Names() const { return names_; }
Chia-I Wu0c203242016-03-15 13:44:51 +080098
Chia-I Wu026b8fa2016-04-11 13:44:13 +080099 uint32_t Count() const { return name_count_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800100
101 private:
102 struct ImplicitLayer {
103 int priority;
104 size_t name_offset;
105 };
106
107 struct ImplicitLayerArray {
108 ImplicitLayer* elements;
109 uint32_t max_count;
110 uint32_t count;
111
112 char* name_pool;
113 size_t max_pool_size;
114 size_t pool_size;
115
116 VkResult result;
117 };
118
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800119 void AddImplicitLayers() {
Chia-I Wuc3a28912016-04-14 11:55:51 +0800120 if (!is_instance_ || !driver::Debuggable())
Chia-I Wu0c203242016-03-15 13:44:51 +0800121 return;
122
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800123 ParseDebugVulkanLayers();
124 property_list(ParseDebugVulkanLayer, this);
Chia-I Wu0c203242016-03-15 13:44:51 +0800125
126 // sort by priorities
127 auto& arr = implicit_layers_;
128 std::sort(arr.elements, arr.elements + arr.count,
129 [](const ImplicitLayer& a, const ImplicitLayer& b) {
130 return (a.priority < b.priority);
131 });
132 }
133
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800134 void ParseDebugVulkanLayers() {
Chia-I Wu0c203242016-03-15 13:44:51 +0800135 // debug.vulkan.layers specifies colon-separated layer names
136 char prop[PROPERTY_VALUE_MAX];
137 if (!property_get("debug.vulkan.layers", prop, ""))
138 return;
139
140 // assign negative/high priorities to them
141 int prio = -PROPERTY_VALUE_MAX;
142
143 const char* p = prop;
144 const char* delim;
145 while ((delim = strchr(p, ':'))) {
146 if (delim > p)
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800147 AddImplicitLayer(prio, p, static_cast<size_t>(delim - p));
Chia-I Wu0c203242016-03-15 13:44:51 +0800148
149 prio++;
150 p = delim + 1;
151 }
152
153 if (p[0] != '\0')
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800154 AddImplicitLayer(prio, p, strlen(p));
Chia-I Wu0c203242016-03-15 13:44:51 +0800155 }
156
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800157 static void ParseDebugVulkanLayer(const char* key,
158 const char* val,
159 void* user_data) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800160 static const char prefix[] = "debug.vulkan.layer.";
161 const size_t prefix_len = sizeof(prefix) - 1;
162
163 if (strncmp(key, prefix, prefix_len) || val[0] == '\0')
164 return;
165 key += prefix_len;
166
167 // debug.vulkan.layer.<priority>
168 int priority = -1;
169 if (key[0] >= '0' && key[0] <= '9')
170 priority = atoi(key);
171
172 if (priority < 0) {
173 ALOGW("Ignored implicit layer %s with invalid priority %s", val,
174 key);
175 return;
176 }
177
178 OverrideLayerNames& override_layers =
179 *reinterpret_cast<OverrideLayerNames*>(user_data);
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800180 override_layers.AddImplicitLayer(priority, val, strlen(val));
Chia-I Wu0c203242016-03-15 13:44:51 +0800181 }
182
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800183 void AddImplicitLayer(int priority, const char* name, size_t len) {
184 if (!GrowImplicitLayerArray(1, 0))
Chia-I Wu0c203242016-03-15 13:44:51 +0800185 return;
186
187 auto& arr = implicit_layers_;
188 auto& layer = arr.elements[arr.count++];
189
190 layer.priority = priority;
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800191 layer.name_offset = AddImplicitLayerName(name, len);
Chia-I Wu0c203242016-03-15 13:44:51 +0800192
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800193 ALOGV("Added implicit layer %s", GetImplicitLayerName(arr.count - 1));
Chia-I Wu0c203242016-03-15 13:44:51 +0800194 }
195
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800196 size_t AddImplicitLayerName(const char* name, size_t len) {
197 if (!GrowImplicitLayerArray(0, len + 1))
Chia-I Wu0c203242016-03-15 13:44:51 +0800198 return 0;
199
200 // add the name to the pool
201 auto& arr = implicit_layers_;
202 size_t offset = arr.pool_size;
203 char* dst = arr.name_pool + offset;
204
205 std::copy(name, name + len, dst);
206 dst[len] = '\0';
207
208 arr.pool_size += len + 1;
209
210 return offset;
211 }
212
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800213 bool GrowImplicitLayerArray(uint32_t layer_count, size_t name_size) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800214 const uint32_t initial_max_count = 16;
215 const size_t initial_max_pool_size = 512;
216
217 auto& arr = implicit_layers_;
218
219 // grow the element array if needed
220 while (arr.count + layer_count > arr.max_count) {
221 uint32_t new_max_count =
222 (arr.max_count) ? (arr.max_count << 1) : initial_max_count;
223 void* new_mem = nullptr;
224
225 if (new_max_count > arr.max_count) {
226 new_mem = allocator_.pfnReallocation(
227 allocator_.pUserData, arr.elements,
228 sizeof(ImplicitLayer) * new_max_count,
229 alignof(ImplicitLayer), scope_);
230 }
231
232 if (!new_mem) {
233 arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
234 arr.count = 0;
235 return false;
236 }
237
238 arr.elements = reinterpret_cast<ImplicitLayer*>(new_mem);
239 arr.max_count = new_max_count;
240 }
241
242 // grow the name pool if needed
243 while (arr.pool_size + name_size > arr.max_pool_size) {
244 size_t new_max_pool_size = (arr.max_pool_size)
245 ? (arr.max_pool_size << 1)
246 : initial_max_pool_size;
247 void* new_mem = nullptr;
248
249 if (new_max_pool_size > arr.max_pool_size) {
250 new_mem = allocator_.pfnReallocation(
251 allocator_.pUserData, arr.name_pool, new_max_pool_size,
252 alignof(char), scope_);
253 }
254
255 if (!new_mem) {
256 arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
257 arr.pool_size = 0;
258 return false;
259 }
260
261 arr.name_pool = reinterpret_cast<char*>(new_mem);
262 arr.max_pool_size = new_max_pool_size;
263 }
264
265 return true;
266 }
267
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800268 const char* GetImplicitLayerName(uint32_t index) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800269 const auto& arr = implicit_layers_;
270
271 // this may return nullptr when arr.result is not VK_SUCCESS
272 return implicit_layers_.name_pool + arr.elements[index].name_offset;
273 }
274
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800275 bool IsImplicitLayer(const char* name) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800276 const auto& arr = implicit_layers_;
277
278 for (uint32_t i = 0; i < arr.count; i++) {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800279 if (strcmp(name, GetImplicitLayerName(i)) == 0)
Chia-I Wu0c203242016-03-15 13:44:51 +0800280 return true;
281 }
282
283 return false;
284 }
285
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800286 const char** AllocateNameArray(uint32_t count) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800287 return reinterpret_cast<const char**>(allocator_.pfnAllocation(
288 allocator_.pUserData, sizeof(const char*) * count,
289 alignof(const char*), scope_));
290 }
291
292 const bool is_instance_;
293 const VkAllocationCallbacks& allocator_;
294 const VkSystemAllocationScope scope_;
295
296 const char** names_;
297 uint32_t name_count_;
298
299 ImplicitLayerArray implicit_layers_;
300};
301
302// Provide overridden extension names when there are implicit extensions.
303// No effect otherwise.
304//
305// This is used only to enable VK_EXT_debug_report.
306class OverrideExtensionNames {
307 public:
308 OverrideExtensionNames(bool is_instance,
309 const VkAllocationCallbacks& allocator)
310 : is_instance_(is_instance),
311 allocator_(allocator),
312 scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
313 names_(nullptr),
314 name_count_(0),
315 install_debug_callback_(false) {}
316
317 ~OverrideExtensionNames() {
318 allocator_.pfnFree(allocator_.pUserData, names_);
319 }
320
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800321 VkResult Parse(const char* const* names, uint32_t count) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800322 // this is only for debug.vulkan.enable_callback
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800323 if (!EnableDebugCallback())
Chia-I Wu0c203242016-03-15 13:44:51 +0800324 return VK_SUCCESS;
325
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800326 names_ = AllocateNameArray(count + 1);
Chia-I Wu0c203242016-03-15 13:44:51 +0800327 if (!names_)
328 return VK_ERROR_OUT_OF_HOST_MEMORY;
329
330 std::copy(names, names + count, names_);
331
332 name_count_ = count;
333 names_[name_count_++] = "VK_EXT_debug_report";
334
335 install_debug_callback_ = true;
336
337 return VK_SUCCESS;
338 }
339
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800340 const char* const* Names() const { return names_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800341
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800342 uint32_t Count() const { return name_count_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800343
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800344 bool InstallDebugCallback() const { return install_debug_callback_; }
Chia-I Wu0c203242016-03-15 13:44:51 +0800345
346 private:
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800347 bool EnableDebugCallback() const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800348 return (is_instance_ && driver::Debuggable() &&
349 property_get_bool("debug.vulkan.enable_callback", false));
350 }
351
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800352 const char** AllocateNameArray(uint32_t count) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800353 return reinterpret_cast<const char**>(allocator_.pfnAllocation(
354 allocator_.pUserData, sizeof(const char*) * count,
355 alignof(const char*), scope_));
356 }
357
358 const bool is_instance_;
359 const VkAllocationCallbacks& allocator_;
360 const VkSystemAllocationScope scope_;
361
362 const char** names_;
363 uint32_t name_count_;
364 bool install_debug_callback_;
365};
366
367// vkCreateInstance and vkCreateDevice helpers with support for layer
368// chaining.
369class LayerChain {
370 public:
Chia-I Wuc3a28912016-04-14 11:55:51 +0800371 struct ActiveLayer {
372 LayerRef ref;
373 union {
374 VkLayerInstanceLink instance_link;
375 VkLayerDeviceLink device_link;
376 };
377 };
378
Chia-I Wueef27fa2016-04-11 13:52:39 +0800379 static VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
380 const VkAllocationCallbacks* allocator,
381 VkInstance* instance_out);
Chia-I Wu0c203242016-03-15 13:44:51 +0800382
Chia-I Wueef27fa2016-04-11 13:52:39 +0800383 static VkResult CreateDevice(VkPhysicalDevice physical_dev,
384 const VkDeviceCreateInfo* create_info,
385 const VkAllocationCallbacks* allocator,
386 VkDevice* dev_out);
Chia-I Wu0c203242016-03-15 13:44:51 +0800387
Chia-I Wueef27fa2016-04-11 13:52:39 +0800388 static void DestroyInstance(VkInstance instance,
389 const VkAllocationCallbacks* allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +0800390
Chia-I Wueef27fa2016-04-11 13:52:39 +0800391 static void DestroyDevice(VkDevice dev,
392 const VkAllocationCallbacks* allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +0800393
Chia-I Wuc3a28912016-04-14 11:55:51 +0800394 static const ActiveLayer* GetActiveLayers(VkPhysicalDevice physical_dev,
395 uint32_t& count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800396
Chia-I Wuc3a28912016-04-14 11:55:51 +0800397 private:
Chia-I Wua4a05552016-05-05 11:57:23 +0800398 LayerChain(bool is_instance,
399 const driver::DebugReportLogger& logger,
400 const VkAllocationCallbacks& allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +0800401 ~LayerChain();
402
Chia-I Wueef27fa2016-04-11 13:52:39 +0800403 VkResult ActivateLayers(const char* const* layer_names,
404 uint32_t layer_count,
405 const char* const* extension_names,
406 uint32_t extension_count);
Chia-I Wuc3a28912016-04-14 11:55:51 +0800407 VkResult ActivateLayers(VkPhysicalDevice physical_dev,
408 const char* const* layer_names,
409 uint32_t layer_count,
410 const char* const* extension_names,
411 uint32_t extension_count);
Chia-I Wueef27fa2016-04-11 13:52:39 +0800412 ActiveLayer* AllocateLayerArray(uint32_t count) const;
413 VkResult LoadLayer(ActiveLayer& layer, const char* name);
414 void SetupLayerLinks();
Chia-I Wu0c203242016-03-15 13:44:51 +0800415
Chia-I Wueef27fa2016-04-11 13:52:39 +0800416 bool Empty() const;
417 void ModifyCreateInfo(VkInstanceCreateInfo& info);
418 void ModifyCreateInfo(VkDeviceCreateInfo& info);
Chia-I Wu0c203242016-03-15 13:44:51 +0800419
Chia-I Wueef27fa2016-04-11 13:52:39 +0800420 VkResult Create(const VkInstanceCreateInfo* create_info,
Chia-I Wu0c203242016-03-15 13:44:51 +0800421 const VkAllocationCallbacks* allocator,
422 VkInstance* instance_out);
423
Chia-I Wueef27fa2016-04-11 13:52:39 +0800424 VkResult Create(VkPhysicalDevice physical_dev,
Chia-I Wu0c203242016-03-15 13:44:51 +0800425 const VkDeviceCreateInfo* create_info,
426 const VkAllocationCallbacks* allocator,
427 VkDevice* dev_out);
428
Chia-I Wueef27fa2016-04-11 13:52:39 +0800429 VkResult ValidateExtensions(const char* const* extension_names,
430 uint32_t extension_count);
431 VkResult ValidateExtensions(VkPhysicalDevice physical_dev,
432 const char* const* extension_names,
433 uint32_t extension_count);
434 VkExtensionProperties* AllocateDriverExtensionArray(uint32_t count) const;
435 bool IsLayerExtension(const char* name) const;
436 bool IsDriverExtension(const char* name) const;
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800437
Chia-I Wu0c203242016-03-15 13:44:51 +0800438 template <typename DataType>
Chia-I Wueef27fa2016-04-11 13:52:39 +0800439 void StealLayers(DataType& data);
Chia-I Wu0c203242016-03-15 13:44:51 +0800440
Chia-I Wueef27fa2016-04-11 13:52:39 +0800441 static void DestroyLayers(ActiveLayer* layers,
442 uint32_t count,
443 const VkAllocationCallbacks& allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +0800444
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800445 static VKAPI_ATTR VkResult SetInstanceLoaderData(VkInstance instance,
446 void* object);
447 static VKAPI_ATTR VkResult SetDeviceLoaderData(VkDevice device,
448 void* object);
449
Chia-I Wu0c203242016-03-15 13:44:51 +0800450 static VKAPI_ATTR VkBool32
Chia-I Wueef27fa2016-04-11 13:52:39 +0800451 DebugReportCallback(VkDebugReportFlagsEXT flags,
452 VkDebugReportObjectTypeEXT obj_type,
453 uint64_t obj,
454 size_t location,
455 int32_t msg_code,
456 const char* layer_prefix,
457 const char* msg,
458 void* user_data);
Chia-I Wu0c203242016-03-15 13:44:51 +0800459
460 const bool is_instance_;
Chia-I Wua4a05552016-05-05 11:57:23 +0800461 const driver::DebugReportLogger& logger_;
Chia-I Wu0c203242016-03-15 13:44:51 +0800462 const VkAllocationCallbacks& allocator_;
463
464 OverrideLayerNames override_layers_;
465 OverrideExtensionNames override_extensions_;
466
467 ActiveLayer* layers_;
468 uint32_t layer_count_;
469
470 PFN_vkGetInstanceProcAddr get_instance_proc_addr_;
471 PFN_vkGetDeviceProcAddr get_device_proc_addr_;
472
473 union {
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800474 VkLayerInstanceCreateInfo instance_chain_info_[2];
475 VkLayerDeviceCreateInfo device_chain_info_[2];
Chia-I Wu0c203242016-03-15 13:44:51 +0800476 };
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800477
478 VkExtensionProperties* driver_extensions_;
479 uint32_t driver_extension_count_;
Chia-I Wu8925efd2016-04-13 15:13:21 +0800480 std::bitset<driver::ProcHook::EXTENSION_COUNT> enabled_extensions_;
Chia-I Wu0c203242016-03-15 13:44:51 +0800481};
482
Chia-I Wua4a05552016-05-05 11:57:23 +0800483LayerChain::LayerChain(bool is_instance,
484 const driver::DebugReportLogger& logger,
485 const VkAllocationCallbacks& allocator)
Chia-I Wu0c203242016-03-15 13:44:51 +0800486 : is_instance_(is_instance),
Chia-I Wua4a05552016-05-05 11:57:23 +0800487 logger_(logger),
Chia-I Wu0c203242016-03-15 13:44:51 +0800488 allocator_(allocator),
489 override_layers_(is_instance, allocator),
490 override_extensions_(is_instance, allocator),
491 layers_(nullptr),
492 layer_count_(0),
493 get_instance_proc_addr_(nullptr),
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800494 get_device_proc_addr_(nullptr),
495 driver_extensions_(nullptr),
Chia-I Wu8925efd2016-04-13 15:13:21 +0800496 driver_extension_count_(0) {
497 enabled_extensions_.set(driver::ProcHook::EXTENSION_CORE);
498}
Chia-I Wu0c203242016-03-15 13:44:51 +0800499
500LayerChain::~LayerChain() {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800501 allocator_.pfnFree(allocator_.pUserData, driver_extensions_);
Chia-I Wueef27fa2016-04-11 13:52:39 +0800502 DestroyLayers(layers_, layer_count_, allocator_);
Chia-I Wu0c203242016-03-15 13:44:51 +0800503}
504
Chia-I Wueef27fa2016-04-11 13:52:39 +0800505VkResult LayerChain::ActivateLayers(const char* const* layer_names,
506 uint32_t layer_count,
507 const char* const* extension_names,
508 uint32_t extension_count) {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800509 VkResult result = override_layers_.Parse(layer_names, layer_count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800510 if (result != VK_SUCCESS)
511 return result;
512
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800513 result = override_extensions_.Parse(extension_names, extension_count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800514 if (result != VK_SUCCESS)
515 return result;
516
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800517 if (override_layers_.Count()) {
518 layer_names = override_layers_.Names();
519 layer_count = override_layers_.Count();
Chia-I Wu0c203242016-03-15 13:44:51 +0800520 }
521
522 if (!layer_count) {
523 // point head of chain to the driver
524 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
Chia-I Wu0c203242016-03-15 13:44:51 +0800525
526 return VK_SUCCESS;
527 }
528
Chia-I Wueef27fa2016-04-11 13:52:39 +0800529 layers_ = AllocateLayerArray(layer_count);
Chia-I Wu0c203242016-03-15 13:44:51 +0800530 if (!layers_)
531 return VK_ERROR_OUT_OF_HOST_MEMORY;
532
533 // load layers
534 for (uint32_t i = 0; i < layer_count; i++) {
Chia-I Wueef27fa2016-04-11 13:52:39 +0800535 result = LoadLayer(layers_[i], layer_names[i]);
Chia-I Wu0c203242016-03-15 13:44:51 +0800536 if (result != VK_SUCCESS)
537 return result;
538
539 // count loaded layers for proper destructions on errors
540 layer_count_++;
541 }
542
Chia-I Wueef27fa2016-04-11 13:52:39 +0800543 SetupLayerLinks();
Chia-I Wu0c203242016-03-15 13:44:51 +0800544
545 return VK_SUCCESS;
546}
547
Chia-I Wuc3a28912016-04-14 11:55:51 +0800548VkResult LayerChain::ActivateLayers(VkPhysicalDevice physical_dev,
549 const char* const* layer_names,
550 uint32_t layer_count,
551 const char* const* extension_names,
552 uint32_t extension_count) {
553 uint32_t instance_layer_count;
554 const ActiveLayer* instance_layers =
555 GetActiveLayers(physical_dev, instance_layer_count);
556
557 // log a message if the application device layer array is not empty nor an
558 // exact match of the instance layer array.
559 if (layer_count) {
560 bool exact_match = (instance_layer_count == layer_count);
561 if (exact_match) {
562 for (uint32_t i = 0; i < instance_layer_count; i++) {
563 const Layer& l = *instance_layers[i].ref;
564 if (strcmp(GetLayerProperties(l).layerName, layer_names[i])) {
565 exact_match = false;
566 break;
567 }
568 }
569 }
570
571 if (!exact_match) {
Chia-I Wua4a05552016-05-05 11:57:23 +0800572 logger_.Warn(physical_dev,
573 "Device layers disagree with instance layers and are "
574 "overridden by instance layers");
Chia-I Wuc3a28912016-04-14 11:55:51 +0800575 }
576 }
577
578 VkResult result =
579 override_extensions_.Parse(extension_names, extension_count);
580 if (result != VK_SUCCESS)
581 return result;
582
583 if (!instance_layer_count) {
584 // point head of chain to the driver
585 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
586 get_device_proc_addr_ = driver::GetDeviceProcAddr;
587
588 return VK_SUCCESS;
589 }
590
591 layers_ = AllocateLayerArray(instance_layer_count);
592 if (!layers_)
593 return VK_ERROR_OUT_OF_HOST_MEMORY;
594
595 for (uint32_t i = 0; i < instance_layer_count; i++) {
596 const Layer& l = *instance_layers[i].ref;
597
598 // no need to and cannot chain non-global layers
599 if (!IsLayerGlobal(l))
600 continue;
601
602 // this never fails
603 new (&layers_[layer_count_++]) ActiveLayer{GetLayerRef(l), {}};
604 }
605
Chia-I Wu61b25fd2016-05-27 10:18:25 +0800606 // this may happen when all layers are non-global ones
607 if (!layer_count_) {
608 get_instance_proc_addr_ = driver::GetInstanceProcAddr;
609 get_device_proc_addr_ = driver::GetDeviceProcAddr;
610 return VK_SUCCESS;
611 }
612
Chia-I Wuc3a28912016-04-14 11:55:51 +0800613 SetupLayerLinks();
614
615 return VK_SUCCESS;
616}
617
Chia-I Wueef27fa2016-04-11 13:52:39 +0800618LayerChain::ActiveLayer* LayerChain::AllocateLayerArray(uint32_t count) const {
Chia-I Wu0c203242016-03-15 13:44:51 +0800619 VkSystemAllocationScope scope = (is_instance_)
620 ? VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
Chia-I Wuc3a28912016-04-14 11:55:51 +0800621 : VK_SYSTEM_ALLOCATION_SCOPE_COMMAND;
Chia-I Wu0c203242016-03-15 13:44:51 +0800622
623 return reinterpret_cast<ActiveLayer*>(allocator_.pfnAllocation(
624 allocator_.pUserData, sizeof(ActiveLayer) * count, alignof(ActiveLayer),
625 scope));
626}
627
Chia-I Wueef27fa2016-04-11 13:52:39 +0800628VkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) {
Chia-I Wud6e6f512016-04-28 07:39:32 +0800629 const Layer* l = FindLayer(name);
Chia-I Wuc3a28912016-04-14 11:55:51 +0800630 if (!l) {
Chia-I Wua4a05552016-05-05 11:57:23 +0800631 logger_.Err(VK_NULL_HANDLE, "Failed to find layer %s", name);
Chia-I Wud6e6f512016-04-28 07:39:32 +0800632 return VK_ERROR_LAYER_NOT_PRESENT;
633 }
634
Chia-I Wudab25652016-04-28 07:15:51 +0800635 new (&layer) ActiveLayer{GetLayerRef(*l), {}};
Chia-I Wu0c203242016-03-15 13:44:51 +0800636 if (!layer.ref) {
Chia-I Wud6e6f512016-04-28 07:39:32 +0800637 ALOGW("Failed to open layer %s", name);
Chia-I Wu0c203242016-03-15 13:44:51 +0800638 layer.ref.~LayerRef();
639 return VK_ERROR_LAYER_NOT_PRESENT;
640 }
641
Chia-I Wuc3a28912016-04-14 11:55:51 +0800642 ALOGI("Loaded layer %s", name);
Chia-I Wu0c203242016-03-15 13:44:51 +0800643
644 return VK_SUCCESS;
645}
646
Chia-I Wueef27fa2016-04-11 13:52:39 +0800647void LayerChain::SetupLayerLinks() {
Chia-I Wu0c203242016-03-15 13:44:51 +0800648 if (is_instance_) {
649 for (uint32_t i = 0; i < layer_count_; i++) {
650 ActiveLayer& layer = layers_[i];
651
652 // point head of chain to the first layer
653 if (i == 0)
654 get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
655
656 // point tail of chain to the driver
657 if (i == layer_count_ - 1) {
658 layer.instance_link.pNext = nullptr;
659 layer.instance_link.pfnNextGetInstanceProcAddr =
660 driver::GetInstanceProcAddr;
661 break;
662 }
663
664 const ActiveLayer& next = layers_[i + 1];
665
666 // const_cast as some naughty layers want to modify our links!
667 layer.instance_link.pNext =
668 const_cast<VkLayerInstanceLink*>(&next.instance_link);
669 layer.instance_link.pfnNextGetInstanceProcAddr =
670 next.ref.GetGetInstanceProcAddr();
671 }
672 } else {
673 for (uint32_t i = 0; i < layer_count_; i++) {
674 ActiveLayer& layer = layers_[i];
675
676 // point head of chain to the first layer
677 if (i == 0) {
678 get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
679 get_device_proc_addr_ = layer.ref.GetGetDeviceProcAddr();
680 }
681
682 // point tail of chain to the driver
683 if (i == layer_count_ - 1) {
684 layer.device_link.pNext = nullptr;
685 layer.device_link.pfnNextGetInstanceProcAddr =
686 driver::GetInstanceProcAddr;
687 layer.device_link.pfnNextGetDeviceProcAddr =
688 driver::GetDeviceProcAddr;
689 break;
690 }
691
692 const ActiveLayer& next = layers_[i + 1];
693
694 // const_cast as some naughty layers want to modify our links!
695 layer.device_link.pNext =
696 const_cast<VkLayerDeviceLink*>(&next.device_link);
697 layer.device_link.pfnNextGetInstanceProcAddr =
698 next.ref.GetGetInstanceProcAddr();
699 layer.device_link.pfnNextGetDeviceProcAddr =
700 next.ref.GetGetDeviceProcAddr();
701 }
702 }
703}
704
Chia-I Wueef27fa2016-04-11 13:52:39 +0800705bool LayerChain::Empty() const {
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800706 return (!layer_count_ && !override_layers_.Count() &&
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800707 !override_extensions_.Count());
Chia-I Wu0c203242016-03-15 13:44:51 +0800708}
709
Chia-I Wueef27fa2016-04-11 13:52:39 +0800710void LayerChain::ModifyCreateInfo(VkInstanceCreateInfo& info) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800711 if (layer_count_) {
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800712 auto& link_info = instance_chain_info_[1];
713 link_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
714 link_info.pNext = info.pNext;
715 link_info.function = VK_LAYER_FUNCTION_LINK;
716 link_info.u.pLayerInfo = &layers_[0].instance_link;
Chia-I Wu0c203242016-03-15 13:44:51 +0800717
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800718 auto& cb_info = instance_chain_info_[0];
719 cb_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
720 cb_info.pNext = &link_info;
721 cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK;
722 cb_info.u.pfnSetInstanceLoaderData = SetInstanceLoaderData;
Chia-I Wu0c203242016-03-15 13:44:51 +0800723
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800724 info.pNext = &cb_info;
Chia-I Wu0c203242016-03-15 13:44:51 +0800725 }
726
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800727 if (override_layers_.Count()) {
728 info.enabledLayerCount = override_layers_.Count();
729 info.ppEnabledLayerNames = override_layers_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800730 }
731
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800732 if (override_extensions_.Count()) {
733 info.enabledExtensionCount = override_extensions_.Count();
734 info.ppEnabledExtensionNames = override_extensions_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800735 }
736}
737
Chia-I Wueef27fa2016-04-11 13:52:39 +0800738void LayerChain::ModifyCreateInfo(VkDeviceCreateInfo& info) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800739 if (layer_count_) {
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800740 auto& link_info = device_chain_info_[1];
741 link_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
742 link_info.pNext = info.pNext;
743 link_info.function = VK_LAYER_FUNCTION_LINK;
744 link_info.u.pLayerInfo = &layers_[0].device_link;
Chia-I Wu0c203242016-03-15 13:44:51 +0800745
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800746 auto& cb_info = device_chain_info_[0];
747 cb_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
748 cb_info.pNext = &link_info;
749 cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK;
750 cb_info.u.pfnSetDeviceLoaderData = SetDeviceLoaderData;
Chia-I Wu0c203242016-03-15 13:44:51 +0800751
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800752 info.pNext = &cb_info;
Chia-I Wu0c203242016-03-15 13:44:51 +0800753 }
754
Chia-I Wu026b8fa2016-04-11 13:44:13 +0800755 if (override_layers_.Count()) {
756 info.enabledLayerCount = override_layers_.Count();
757 info.ppEnabledLayerNames = override_layers_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800758 }
759
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800760 if (override_extensions_.Count()) {
761 info.enabledExtensionCount = override_extensions_.Count();
762 info.ppEnabledExtensionNames = override_extensions_.Names();
Chia-I Wu0c203242016-03-15 13:44:51 +0800763 }
764}
765
Chia-I Wueef27fa2016-04-11 13:52:39 +0800766VkResult LayerChain::Create(const VkInstanceCreateInfo* create_info,
Chia-I Wu0c203242016-03-15 13:44:51 +0800767 const VkAllocationCallbacks* allocator,
768 VkInstance* instance_out) {
Chia-I Wueef27fa2016-04-11 13:52:39 +0800769 VkResult result = ValidateExtensions(create_info->ppEnabledExtensionNames,
770 create_info->enabledExtensionCount);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800771 if (result != VK_SUCCESS)
772 return result;
773
Chia-I Wu0c203242016-03-15 13:44:51 +0800774 // call down the chain
775 PFN_vkCreateInstance create_instance =
776 reinterpret_cast<PFN_vkCreateInstance>(
777 get_instance_proc_addr_(VK_NULL_HANDLE, "vkCreateInstance"));
778 VkInstance instance;
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800779 result = create_instance(create_info, allocator, &instance);
Chia-I Wu0c203242016-03-15 13:44:51 +0800780 if (result != VK_SUCCESS)
781 return result;
782
783 // initialize InstanceData
784 InstanceData& data = GetData(instance);
Chia-I Wu0c203242016-03-15 13:44:51 +0800785
Chia-I Wu8925efd2016-04-13 15:13:21 +0800786 if (!InitDispatchTable(instance, get_instance_proc_addr_,
787 enabled_extensions_)) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800788 if (data.dispatch.DestroyInstance)
789 data.dispatch.DestroyInstance(instance, allocator);
790
791 return VK_ERROR_INITIALIZATION_FAILED;
792 }
793
794 // install debug report callback
Chia-I Wuc3fa20c2016-04-11 13:47:31 +0800795 if (override_extensions_.InstallDebugCallback()) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800796 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
797 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
798 get_instance_proc_addr_(instance,
799 "vkCreateDebugReportCallbackEXT"));
800 data.destroy_debug_callback =
801 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
802 get_instance_proc_addr_(instance,
803 "vkDestroyDebugReportCallbackEXT"));
804 if (!create_debug_report_callback || !data.destroy_debug_callback) {
805 ALOGE("Broken VK_EXT_debug_report support");
806 data.dispatch.DestroyInstance(instance, allocator);
807 return VK_ERROR_INITIALIZATION_FAILED;
808 }
809
810 VkDebugReportCallbackCreateInfoEXT debug_callback_info = {};
811 debug_callback_info.sType =
812 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
813 debug_callback_info.flags =
814 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
Chia-I Wueef27fa2016-04-11 13:52:39 +0800815 debug_callback_info.pfnCallback = DebugReportCallback;
Chia-I Wu0c203242016-03-15 13:44:51 +0800816
817 VkDebugReportCallbackEXT debug_callback;
818 result = create_debug_report_callback(instance, &debug_callback_info,
819 nullptr, &debug_callback);
820 if (result != VK_SUCCESS) {
821 ALOGE("Failed to install debug report callback");
822 data.dispatch.DestroyInstance(instance, allocator);
823 return VK_ERROR_INITIALIZATION_FAILED;
824 }
825
826 data.debug_callback = debug_callback;
827
828 ALOGI("Installed debug report callback");
829 }
830
Chia-I Wueef27fa2016-04-11 13:52:39 +0800831 StealLayers(data);
Chia-I Wu0c203242016-03-15 13:44:51 +0800832
833 *instance_out = instance;
834
835 return VK_SUCCESS;
836}
837
Chia-I Wueef27fa2016-04-11 13:52:39 +0800838VkResult LayerChain::Create(VkPhysicalDevice physical_dev,
Chia-I Wu0c203242016-03-15 13:44:51 +0800839 const VkDeviceCreateInfo* create_info,
840 const VkAllocationCallbacks* allocator,
841 VkDevice* dev_out) {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800842 VkResult result =
Chia-I Wueef27fa2016-04-11 13:52:39 +0800843 ValidateExtensions(physical_dev, create_info->ppEnabledExtensionNames,
844 create_info->enabledExtensionCount);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800845 if (result != VK_SUCCESS)
846 return result;
847
Chia-I Wu0c203242016-03-15 13:44:51 +0800848 // call down the chain
Chia-I Wuc3a28912016-04-14 11:55:51 +0800849 PFN_vkCreateDevice create_device =
850 GetData(physical_dev).dispatch.CreateDevice;
Chia-I Wu0c203242016-03-15 13:44:51 +0800851 VkDevice dev;
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800852 result = create_device(physical_dev, create_info, allocator, &dev);
Chia-I Wu0c203242016-03-15 13:44:51 +0800853 if (result != VK_SUCCESS)
854 return result;
855
856 // initialize DeviceData
857 DeviceData& data = GetData(dev);
Chia-I Wu0c203242016-03-15 13:44:51 +0800858
Chia-I Wu8925efd2016-04-13 15:13:21 +0800859 if (!InitDispatchTable(dev, get_device_proc_addr_, enabled_extensions_)) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800860 if (data.dispatch.DestroyDevice)
861 data.dispatch.DestroyDevice(dev, allocator);
862
863 return VK_ERROR_INITIALIZATION_FAILED;
864 }
865
Chia-I Wuc3a28912016-04-14 11:55:51 +0800866 // no StealLayers so that active layers are destroyed with this
867 // LayerChain
Chia-I Wu0c203242016-03-15 13:44:51 +0800868 *dev_out = dev;
869
870 return VK_SUCCESS;
871}
872
Chia-I Wueef27fa2016-04-11 13:52:39 +0800873VkResult LayerChain::ValidateExtensions(const char* const* extension_names,
874 uint32_t extension_count) {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800875 if (!extension_count)
876 return VK_SUCCESS;
877
878 // query driver instance extensions
879 uint32_t count;
880 VkResult result =
881 EnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
882 if (result == VK_SUCCESS && count) {
Chia-I Wueef27fa2016-04-11 13:52:39 +0800883 driver_extensions_ = AllocateDriverExtensionArray(count);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800884 result = (driver_extensions_) ? EnumerateInstanceExtensionProperties(
885 nullptr, &count, driver_extensions_)
886 : VK_ERROR_OUT_OF_HOST_MEMORY;
887 }
888 if (result != VK_SUCCESS)
889 return result;
890
891 driver_extension_count_ = count;
892
893 for (uint32_t i = 0; i < extension_count; i++) {
894 const char* name = extension_names[i];
Chia-I Wueef27fa2016-04-11 13:52:39 +0800895 if (!IsLayerExtension(name) && !IsDriverExtension(name)) {
Chia-I Wua4a05552016-05-05 11:57:23 +0800896 logger_.Err(VK_NULL_HANDLE,
897 "Failed to enable missing instance extension %s", name);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800898 return VK_ERROR_EXTENSION_NOT_PRESENT;
899 }
Chia-I Wu8925efd2016-04-13 15:13:21 +0800900
901 auto ext_bit = driver::GetProcHookExtension(name);
902 if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN)
903 enabled_extensions_.set(ext_bit);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800904 }
905
906 return VK_SUCCESS;
907}
908
Chia-I Wueef27fa2016-04-11 13:52:39 +0800909VkResult LayerChain::ValidateExtensions(VkPhysicalDevice physical_dev,
910 const char* const* extension_names,
911 uint32_t extension_count) {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800912 if (!extension_count)
913 return VK_SUCCESS;
914
915 // query driver device extensions
916 uint32_t count;
917 VkResult result = EnumerateDeviceExtensionProperties(physical_dev, nullptr,
918 &count, nullptr);
919 if (result == VK_SUCCESS && count) {
Chia-I Wueef27fa2016-04-11 13:52:39 +0800920 driver_extensions_ = AllocateDriverExtensionArray(count);
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800921 result = (driver_extensions_)
922 ? EnumerateDeviceExtensionProperties(
923 physical_dev, 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(physical_dev,
935 "Failed to enable missing device 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 +0800947VkExtensionProperties* LayerChain::AllocateDriverExtensionArray(
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800948 uint32_t count) const {
949 return reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
950 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
951 alignof(VkExtensionProperties), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
952}
953
Chia-I Wueef27fa2016-04-11 13:52:39 +0800954bool LayerChain::IsLayerExtension(const char* name) const {
Chia-I Wudab25652016-04-28 07:15:51 +0800955 if (is_instance_) {
956 for (uint32_t i = 0; i < layer_count_; i++) {
957 const ActiveLayer& layer = layers_[i];
958 if (FindLayerInstanceExtension(*layer.ref, name))
959 return true;
960 }
961 } else {
962 for (uint32_t i = 0; i < layer_count_; i++) {
963 const ActiveLayer& layer = layers_[i];
964 if (FindLayerDeviceExtension(*layer.ref, name))
965 return true;
966 }
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800967 }
968
969 return false;
970}
971
Chia-I Wueef27fa2016-04-11 13:52:39 +0800972bool LayerChain::IsDriverExtension(const char* name) const {
Chia-I Wu1f8f46b2016-04-06 14:17:48 +0800973 for (uint32_t i = 0; i < driver_extension_count_; i++) {
974 if (strcmp(driver_extensions_[i].extensionName, name) == 0)
975 return true;
976 }
977
978 return false;
979}
980
Chia-I Wu0c203242016-03-15 13:44:51 +0800981template <typename DataType>
Chia-I Wueef27fa2016-04-11 13:52:39 +0800982void LayerChain::StealLayers(DataType& data) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800983 data.layers = layers_;
984 data.layer_count = layer_count_;
985
986 layers_ = nullptr;
987 layer_count_ = 0;
988}
989
Chia-I Wueef27fa2016-04-11 13:52:39 +0800990void LayerChain::DestroyLayers(ActiveLayer* layers,
991 uint32_t count,
992 const VkAllocationCallbacks& allocator) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800993 for (uint32_t i = 0; i < count; i++)
994 layers[i].ref.~LayerRef();
995
996 allocator.pfnFree(allocator.pUserData, layers);
997}
998
Chia-I Wu94a2c0e2016-04-13 10:20:59 +0800999VkResult LayerChain::SetInstanceLoaderData(VkInstance instance, void* object) {
1000 driver::InstanceDispatchable dispatchable =
1001 reinterpret_cast<driver::InstanceDispatchable>(object);
1002
1003 return (driver::SetDataInternal(dispatchable, &driver::GetData(instance)))
1004 ? VK_SUCCESS
1005 : VK_ERROR_INITIALIZATION_FAILED;
1006}
1007
1008VkResult LayerChain::SetDeviceLoaderData(VkDevice device, void* object) {
1009 driver::DeviceDispatchable dispatchable =
1010 reinterpret_cast<driver::DeviceDispatchable>(object);
1011
1012 return (driver::SetDataInternal(dispatchable, &driver::GetData(device)))
1013 ? VK_SUCCESS
1014 : VK_ERROR_INITIALIZATION_FAILED;
1015}
1016
Chia-I Wueef27fa2016-04-11 13:52:39 +08001017VkBool32 LayerChain::DebugReportCallback(VkDebugReportFlagsEXT flags,
1018 VkDebugReportObjectTypeEXT obj_type,
1019 uint64_t obj,
1020 size_t location,
1021 int32_t msg_code,
1022 const char* layer_prefix,
1023 const char* msg,
1024 void* user_data) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001025 int prio;
1026
1027 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
1028 prio = ANDROID_LOG_ERROR;
1029 else if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT |
1030 VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT))
1031 prio = ANDROID_LOG_WARN;
1032 else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
1033 prio = ANDROID_LOG_INFO;
1034 else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
1035 prio = ANDROID_LOG_DEBUG;
1036 else
1037 prio = ANDROID_LOG_UNKNOWN;
1038
1039 LOG_PRI(prio, LOG_TAG, "[%s] Code %d : %s", layer_prefix, msg_code, msg);
1040
1041 (void)obj_type;
1042 (void)obj;
1043 (void)location;
1044 (void)user_data;
1045
1046 return false;
1047}
1048
Chia-I Wueef27fa2016-04-11 13:52:39 +08001049VkResult LayerChain::CreateInstance(const VkInstanceCreateInfo* create_info,
1050 const VkAllocationCallbacks* allocator,
1051 VkInstance* instance_out) {
Chia-I Wua4a05552016-05-05 11:57:23 +08001052 LayerChain chain(true, driver::DebugReportLogger(*create_info),
Chia-I Wu0c203242016-03-15 13:44:51 +08001053 (allocator) ? *allocator : driver::GetDefaultAllocator());
1054
Chia-I Wueef27fa2016-04-11 13:52:39 +08001055 VkResult result = chain.ActivateLayers(create_info->ppEnabledLayerNames,
1056 create_info->enabledLayerCount,
1057 create_info->ppEnabledExtensionNames,
1058 create_info->enabledExtensionCount);
Chia-I Wu0c203242016-03-15 13:44:51 +08001059 if (result != VK_SUCCESS)
1060 return result;
1061
1062 // use a local create info when the chain is not empty
1063 VkInstanceCreateInfo local_create_info;
Chia-I Wueef27fa2016-04-11 13:52:39 +08001064 if (!chain.Empty()) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001065 local_create_info = *create_info;
Chia-I Wueef27fa2016-04-11 13:52:39 +08001066 chain.ModifyCreateInfo(local_create_info);
Chia-I Wu0c203242016-03-15 13:44:51 +08001067 create_info = &local_create_info;
1068 }
1069
Chia-I Wueef27fa2016-04-11 13:52:39 +08001070 return chain.Create(create_info, allocator, instance_out);
Chia-I Wu0c203242016-03-15 13:44:51 +08001071}
1072
Chia-I Wueef27fa2016-04-11 13:52:39 +08001073VkResult LayerChain::CreateDevice(VkPhysicalDevice physical_dev,
1074 const VkDeviceCreateInfo* create_info,
1075 const VkAllocationCallbacks* allocator,
1076 VkDevice* dev_out) {
Chia-I Wua4a05552016-05-05 11:57:23 +08001077 LayerChain chain(
1078 false, driver::Logger(physical_dev),
1079 (allocator) ? *allocator : driver::GetData(physical_dev).allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +08001080
Chia-I Wuc3a28912016-04-14 11:55:51 +08001081 VkResult result = chain.ActivateLayers(
1082 physical_dev, create_info->ppEnabledLayerNames,
1083 create_info->enabledLayerCount, create_info->ppEnabledExtensionNames,
1084 create_info->enabledExtensionCount);
Chia-I Wu0c203242016-03-15 13:44:51 +08001085 if (result != VK_SUCCESS)
1086 return result;
1087
1088 // use a local create info when the chain is not empty
1089 VkDeviceCreateInfo local_create_info;
Chia-I Wueef27fa2016-04-11 13:52:39 +08001090 if (!chain.Empty()) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001091 local_create_info = *create_info;
Chia-I Wueef27fa2016-04-11 13:52:39 +08001092 chain.ModifyCreateInfo(local_create_info);
Chia-I Wu0c203242016-03-15 13:44:51 +08001093 create_info = &local_create_info;
1094 }
1095
Chia-I Wueef27fa2016-04-11 13:52:39 +08001096 return chain.Create(physical_dev, create_info, allocator, dev_out);
Chia-I Wu0c203242016-03-15 13:44:51 +08001097}
1098
Chia-I Wueef27fa2016-04-11 13:52:39 +08001099void LayerChain::DestroyInstance(VkInstance instance,
1100 const VkAllocationCallbacks* allocator) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001101 InstanceData& data = GetData(instance);
1102
1103 if (data.debug_callback != VK_NULL_HANDLE)
1104 data.destroy_debug_callback(instance, data.debug_callback, allocator);
1105
1106 ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers);
1107 uint32_t layer_count = data.layer_count;
1108
1109 VkAllocationCallbacks local_allocator;
1110 if (!allocator)
1111 local_allocator = driver::GetData(instance).allocator;
1112
1113 // this also destroys InstanceData
1114 data.dispatch.DestroyInstance(instance, allocator);
1115
Chia-I Wueef27fa2016-04-11 13:52:39 +08001116 DestroyLayers(layers, layer_count,
1117 (allocator) ? *allocator : local_allocator);
Chia-I Wu0c203242016-03-15 13:44:51 +08001118}
1119
Chia-I Wueef27fa2016-04-11 13:52:39 +08001120void LayerChain::DestroyDevice(VkDevice device,
1121 const VkAllocationCallbacks* allocator) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001122 DeviceData& data = GetData(device);
Chia-I Wu0c203242016-03-15 13:44:51 +08001123 // this also destroys DeviceData
1124 data.dispatch.DestroyDevice(device, allocator);
Chia-I Wuc3a28912016-04-14 11:55:51 +08001125}
Chia-I Wu0c203242016-03-15 13:44:51 +08001126
Chia-I Wuc3a28912016-04-14 11:55:51 +08001127const LayerChain::ActiveLayer* LayerChain::GetActiveLayers(
1128 VkPhysicalDevice physical_dev,
1129 uint32_t& count) {
1130 count = GetData(physical_dev).layer_count;
1131 return reinterpret_cast<const ActiveLayer*>(GetData(physical_dev).layers);
Chia-I Wu0c203242016-03-15 13:44:51 +08001132}
1133
1134// ----------------------------------------------------------------------------
1135
1136bool EnsureInitialized() {
1137 static std::once_flag once_flag;
1138 static bool initialized;
1139
1140 std::call_once(once_flag, []() {
1141 if (driver::OpenHAL()) {
1142 DiscoverLayers();
1143 initialized = true;
1144 }
1145 });
1146
1147 return initialized;
1148}
1149
1150} // anonymous namespace
1151
1152VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1153 const VkAllocationCallbacks* pAllocator,
1154 VkInstance* pInstance) {
1155 if (!EnsureInitialized())
1156 return VK_ERROR_INITIALIZATION_FAILED;
1157
Chia-I Wueef27fa2016-04-11 13:52:39 +08001158 return LayerChain::CreateInstance(pCreateInfo, pAllocator, pInstance);
Chia-I Wu0c203242016-03-15 13:44:51 +08001159}
1160
1161void DestroyInstance(VkInstance instance,
1162 const VkAllocationCallbacks* pAllocator) {
1163 if (instance != VK_NULL_HANDLE)
Chia-I Wueef27fa2016-04-11 13:52:39 +08001164 LayerChain::DestroyInstance(instance, pAllocator);
Chia-I Wu0c203242016-03-15 13:44:51 +08001165}
1166
1167VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1168 const VkDeviceCreateInfo* pCreateInfo,
1169 const VkAllocationCallbacks* pAllocator,
1170 VkDevice* pDevice) {
Chia-I Wueef27fa2016-04-11 13:52:39 +08001171 return LayerChain::CreateDevice(physicalDevice, pCreateInfo, pAllocator,
1172 pDevice);
Chia-I Wu0c203242016-03-15 13:44:51 +08001173}
1174
1175void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1176 if (device != VK_NULL_HANDLE)
Chia-I Wueef27fa2016-04-11 13:52:39 +08001177 LayerChain::DestroyDevice(device, pAllocator);
Chia-I Wu0c203242016-03-15 13:44:51 +08001178}
1179
1180VkResult EnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
1181 VkLayerProperties* pProperties) {
1182 if (!EnsureInitialized())
1183 return VK_ERROR_INITIALIZATION_FAILED;
1184
Chia-I Wu25700b42016-04-28 06:36:09 +08001185 uint32_t count = GetLayerCount();
Chia-I Wu0c203242016-03-15 13:44:51 +08001186
Chia-I Wu25700b42016-04-28 06:36:09 +08001187 if (!pProperties) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001188 *pPropertyCount = count;
Chia-I Wu25700b42016-04-28 06:36:09 +08001189 return VK_SUCCESS;
1190 }
Chia-I Wu0c203242016-03-15 13:44:51 +08001191
Chia-I Wu25700b42016-04-28 06:36:09 +08001192 uint32_t copied = std::min(*pPropertyCount, count);
1193 for (uint32_t i = 0; i < copied; i++)
1194 pProperties[i] = GetLayerProperties(GetLayer(i));
1195 *pPropertyCount = copied;
1196
1197 return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE;
Chia-I Wu0c203242016-03-15 13:44:51 +08001198}
1199
1200VkResult EnumerateInstanceExtensionProperties(
1201 const char* pLayerName,
1202 uint32_t* pPropertyCount,
1203 VkExtensionProperties* pProperties) {
1204 if (!EnsureInitialized())
1205 return VK_ERROR_INITIALIZATION_FAILED;
1206
1207 if (pLayerName) {
Chia-I Wu04c65512016-04-27 09:54:02 +08001208 const Layer* layer = FindLayer(pLayerName);
Chia-I Wu6184b202016-04-27 11:57:53 +08001209 if (!layer)
1210 return VK_ERROR_LAYER_NOT_PRESENT;
1211
1212 uint32_t count;
1213 const VkExtensionProperties* props =
1214 GetLayerInstanceExtensions(*layer, count);
Chia-I Wu0c203242016-03-15 13:44:51 +08001215
1216 if (!pProperties || *pPropertyCount > count)
1217 *pPropertyCount = count;
1218 if (pProperties)
1219 std::copy(props, props + *pPropertyCount, pProperties);
1220
1221 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1222 }
1223
1224 // TODO how about extensions from implicitly enabled layers?
1225 return vulkan::driver::EnumerateInstanceExtensionProperties(
1226 nullptr, pPropertyCount, pProperties);
1227}
1228
1229VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1230 uint32_t* pPropertyCount,
1231 VkLayerProperties* pProperties) {
Chia-I Wuc3a28912016-04-14 11:55:51 +08001232 uint32_t count;
1233 const LayerChain::ActiveLayer* layers =
1234 LayerChain::GetActiveLayers(physicalDevice, count);
Chia-I Wu0c203242016-03-15 13:44:51 +08001235
Chia-I Wu25700b42016-04-28 06:36:09 +08001236 if (!pProperties) {
Chia-I Wu0c203242016-03-15 13:44:51 +08001237 *pPropertyCount = count;
Chia-I Wu25700b42016-04-28 06:36:09 +08001238 return VK_SUCCESS;
1239 }
Chia-I Wu0c203242016-03-15 13:44:51 +08001240
Chia-I Wuc3a28912016-04-14 11:55:51 +08001241 uint32_t copied = std::min(*pPropertyCount, count);
1242 for (uint32_t i = 0; i < copied; i++)
1243 pProperties[i] = GetLayerProperties(*layers[i].ref);
Chia-I Wu25700b42016-04-28 06:36:09 +08001244 *pPropertyCount = copied;
1245
1246 return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE;
Chia-I Wu0c203242016-03-15 13:44:51 +08001247}
1248
1249VkResult EnumerateDeviceExtensionProperties(
1250 VkPhysicalDevice physicalDevice,
1251 const char* pLayerName,
1252 uint32_t* pPropertyCount,
1253 VkExtensionProperties* pProperties) {
1254 if (pLayerName) {
Chia-I Wuc3a28912016-04-14 11:55:51 +08001255 // EnumerateDeviceLayerProperties enumerates active layers for
1256 // backward compatibility. The extension query here should work for
1257 // all layers.
Chia-I Wu04c65512016-04-27 09:54:02 +08001258 const Layer* layer = FindLayer(pLayerName);
Chia-I Wuc3a28912016-04-14 11:55:51 +08001259 if (!layer)
Chia-I Wu6184b202016-04-27 11:57:53 +08001260 return VK_ERROR_LAYER_NOT_PRESENT;
1261
1262 uint32_t count;
1263 const VkExtensionProperties* props =
1264 GetLayerDeviceExtensions(*layer, count);
Chia-I Wu0c203242016-03-15 13:44:51 +08001265
1266 if (!pProperties || *pPropertyCount > count)
1267 *pPropertyCount = count;
1268 if (pProperties)
1269 std::copy(props, props + *pPropertyCount, pProperties);
1270
1271 return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
1272 }
1273
1274 // TODO how about extensions from implicitly enabled layers?
1275 const InstanceData& data = GetData(physicalDevice);
1276 return data.dispatch.EnumerateDeviceExtensionProperties(
1277 physicalDevice, nullptr, pPropertyCount, pProperties);
1278}
1279
1280} // namespace api
1281} // namespace vulkan