blob: 1f7054949cfa13ac4e34e9afac623d45bd93cb17 [file] [log] [blame]
Chia-I Wu0c203242016-03-15 13:44:51 +08001{{define "Copyright"}}
2/*
3•* Copyright 2016 The Android Open Source Project
4•*
5•* Licensed under the Apache License, Version 2.0 (the "License");
6•* you may not use this file except in compliance with the License.
7•* You may obtain a copy of the License at
8•*
9•* http://www.apache.org/licenses/LICENSE-2.0
10•*
11•* Unless required by applicable law or agreed to in writing, software
12•* distributed under the License is distributed on an "AS IS" BASIS,
13•* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14•* See the License for the specific language governing permissions and
15•* limitations under the License.
16•*/
17¶{{end}}
18
19{{Include "../api/templates/vulkan_common.tmpl"}}
20{{Global "clang-format" (Strings "clang-format" "-style=file")}}
21{{Macro "DefineGlobals" $}}
22{{$ | Macro "api_gen.h" | Format (Global "clang-format") | Write "api_gen.h" }}
23{{$ | Macro "api_gen.cpp" | Format (Global "clang-format") | Write "api_gen.cpp"}}
Chia-I Wueb7db122016-03-24 09:11:06 +080024{{$ | Macro "driver_gen.h" | Format (Global "clang-format") | Write "driver_gen.h"}}
25{{$ | Macro "driver_gen.cpp" | Format (Global "clang-format") | Write "driver_gen.cpp"}}
Chia-I Wu0c203242016-03-15 13:44:51 +080026
27{{/*
28-------------------------------------------------------------------------------
29 api_gen.h
30-------------------------------------------------------------------------------
31*/}}
32{{define "api_gen.h"}}
33{{Macro "Copyright"}}
34
35// WARNING: This file is generated. See ../README.md for instructions.
36
37#ifndef LIBVULKAN_API_GEN_H
38#define LIBVULKAN_API_GEN_H
39
Chia-I Wu8925efd2016-04-13 15:13:21 +080040#include <bitset>
Chia-I Wu0c203242016-03-15 13:44:51 +080041#include <vulkan/vulkan.h>
Chia-I Wu8925efd2016-04-13 15:13:21 +080042#include "driver_gen.h"
Chia-I Wu0c203242016-03-15 13:44:51 +080043
44namespace vulkan
45namespace api
46
47struct InstanceDispatchTable {
48 // clang-format off
49 {{range $f := AllCommands $}}
50 {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}}
Chia-I Wucc5e2762016-03-24 13:01:16 +080051 {{Macro "C++.DeclareTableEntry" $f}};
Chia-I Wu0c203242016-03-15 13:44:51 +080052 {{end}}
53 {{end}}
54 // clang-format on
55};
56
57struct DeviceDispatchTable {
58 // clang-format off
59 {{range $f := AllCommands $}}
60 {{if (Macro "api.IsDeviceDispatchTableEntry" $f)}}
Chia-I Wucc5e2762016-03-24 13:01:16 +080061 {{Macro "C++.DeclareTableEntry" $f}};
Chia-I Wu0c203242016-03-15 13:44:51 +080062 {{end}}
63 {{end}}
64 // clang-format on
65};
66
Chia-I Wu8925efd2016-04-13 15:13:21 +080067bool InitDispatchTable(
68 VkInstance instance,
69 PFN_vkGetInstanceProcAddr get_proc,
70 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions);
71bool InitDispatchTable(
72 VkDevice dev,
73 PFN_vkGetDeviceProcAddr get_proc,
74 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions);
Chia-I Wu0c203242016-03-15 13:44:51 +080075
76»} // namespace api
77»} // namespace vulkan
78
79#endif // LIBVULKAN_API_GEN_H
80¶{{end}}
81
82
83{{/*
84-------------------------------------------------------------------------------
85 api_gen.cpp
86-------------------------------------------------------------------------------
87*/}}
88{{define "api_gen.cpp"}}
89{{Macro "Copyright"}}
90
91// WARNING: This file is generated. See ../README.md for instructions.
92
93#include <string.h>
94#include <algorithm>
95#include <log/log.h>
96
97#include "api.h"
98
99namespace vulkan
100namespace api
101
Chia-I Wucc5e2762016-03-24 13:01:16 +0800102{{Macro "C++.DefineInitProcMacro" "dispatch"}}
103
104{{Macro "api.C++.DefineInitProcExtMacro"}}
Chia-I Wu0c203242016-03-15 13:44:51 +0800105
Chia-I Wu8925efd2016-04-13 15:13:21 +0800106namespace
107
108// clang-format off
109
110{{range $f := AllCommands $}}
111 {{Macro "api.C++.DefineExtensionStub" $f}}
112{{end}}
113// clang-format on
114
115»} // anonymous
116
117bool InitDispatchTable(
118 VkInstance instance,
119 PFN_vkGetInstanceProcAddr get_proc,
120 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800121 auto& data = GetData(instance);
122 bool success = true;
123
124 // clang-format off
125 {{range $f := AllCommands $}}
126 {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}}
127 {{Macro "C++.InitProc" $f}}
128 {{end}}
129 {{end}}
130 // clang-format on
131
132 return success;
133}
134
Chia-I Wu8925efd2016-04-13 15:13:21 +0800135bool InitDispatchTable(
136 VkDevice dev,
137 PFN_vkGetDeviceProcAddr get_proc,
138 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800139 auto& data = GetData(dev);
140 bool success = true;
141
142 // clang-format off
143 {{range $f := AllCommands $}}
144 {{if (Macro "api.IsDeviceDispatchTableEntry" $f)}}
145 {{Macro "C++.InitProc" $f}}
146 {{end}}
147 {{end}}
148 // clang-format on
149
150 return success;
151}
152
153»} // namespace api
154»} // namespace vulkan
155
156// clang-format off
157
158{{range $f := AllCommands $}}
159 {{if (Macro "IsFunctionExported" $f)}}
160 __attribute__((visibility("default")))
161 VKAPI_ATTR {{Node "Type" $f.Return}} {{$f.Name}}({{Macro "Parameters" $f}}) {
162 {{ if eq $f.Name "vkGetInstanceProcAddr"}}
163 {{Macro "api.C++.InterceptInstanceProcAddr" $}}
164 {{else if eq $f.Name "vkGetDeviceProcAddr"}}
165 {{Macro "api.C++.InterceptDeviceProcAddr" $}}
166 {{end}}
167
168 {{Macro "api.C++.Dispatch" $f}}
169 }
170
171 {{end}}
172{{end}}
173
174// clang-format on
175¶{{end}}
176
177
178{{/*
Chia-I Wueb7db122016-03-24 09:11:06 +0800179-------------------------------------------------------------------------------
180 driver_gen.h
181-------------------------------------------------------------------------------
182*/}}
183{{define "driver_gen.h"}}
184{{Macro "Copyright"}}
185
186// WARNING: This file is generated. See ../README.md for instructions.
187
188#ifndef LIBVULKAN_DRIVER_GEN_H
189#define LIBVULKAN_DRIVER_GEN_H
190
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800191#include <bitset>
Chia-I Wueb7db122016-03-24 09:11:06 +0800192#include <vulkan/vulkan.h>
193#include <vulkan/vk_android_native_buffer.h>
194
195namespace vulkan
196namespace driver
197
198{{Macro "driver.C++.DefineProcHookType"}}
199
Chia-I Wucc5e2762016-03-24 13:01:16 +0800200struct InstanceDriverTable {
201 // clang-format off
202 {{range $f := AllCommands $}}
203 {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}}
204 {{Macro "C++.DeclareTableEntry" $f}};
205 {{end}}
206 {{end}}
207 // clang-format on
208};
209
210struct DeviceDriverTable {
211 // clang-format off
212 {{range $f := AllCommands $}}
213 {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}}
214 {{Macro "C++.DeclareTableEntry" $f}};
215 {{end}}
216 {{end}}
217 // clang-format on
218};
219
Chia-I Wueb7db122016-03-24 09:11:06 +0800220const ProcHook* GetProcHook(const char* name);
221ProcHook::Extension GetProcHookExtension(const char* name);
222
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800223bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc,
224 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions);
225bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc,
226 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions);
Chia-I Wucc5e2762016-03-24 13:01:16 +0800227
Chia-I Wueb7db122016-03-24 09:11:06 +0800228»} // namespace driver
229»} // namespace vulkan
230
231#endif // LIBVULKAN_DRIVER_TABLE_H
232¶{{end}}
233
234
235{{/*
236-------------------------------------------------------------------------------
237 driver_gen.cpp
238-------------------------------------------------------------------------------
239*/}}
240{{define "driver_gen.cpp"}}
241{{Macro "Copyright"}}
242
243// WARNING: This file is generated. See ../README.md for instructions.
244
245#include <string.h>
246#include <algorithm>
247#include <log/log.h>
248
249#include "driver.h"
Chia-I Wueb7db122016-03-24 09:11:06 +0800250
251namespace vulkan
252namespace driver
253
254namespace
255
256// clang-format off
257
258{{range $f := AllCommands $}}
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800259 {{Macro "driver.C++.DefineProcHookStub" $f}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800260{{end}}
261// clang-format on
262
263const ProcHook g_proc_hooks[] = {
264 // clang-format off
265 {{range $f := SortBy (AllCommands $) "FunctionName"}}
266 {{if (Macro "driver.IsIntercepted" $f)}}
267 {{ if (Macro "IsGloballyDispatched" $f)}}
268 {{Macro "driver.C++.DefineGlobalProcHook" $f}}
269 {{else if (Macro "IsInstanceDispatched" $f)}}
270 {{Macro "driver.C++.DefineInstanceProcHook" $f}}
271 {{else if (Macro "IsDeviceDispatched" $f)}}
272 {{Macro "driver.C++.DefineDeviceProcHook" $f}}
273 {{end}}
274 {{end}}
275 {{end}}
276 // clang-format on
277};
278
279»} // anonymous
280
281const ProcHook* GetProcHook(const char* name) {
282 const auto& begin = g_proc_hooks;
283 const auto& end = g_proc_hooks +
284 sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
285 const auto hook = std::lower_bound(begin, end, name,
286 [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
287 return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
288}
289
290ProcHook::Extension GetProcHookExtension(const char* name) {
291 {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
292 // clang-format off
293 {{range $e := $exts}}
294 if (strcmp(name, "{{$e}}") == 0) return ProcHook::{{TrimPrefix "VK_" $e}};
295 {{end}}
296 // clang-format on
297 return ProcHook::EXTENSION_UNKNOWN;
298}
299
Chia-I Wucc5e2762016-03-24 13:01:16 +0800300{{Macro "C++.DefineInitProcMacro" "driver"}}
301
302{{Macro "driver.C++.DefineInitProcExtMacro"}}
303
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800304bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc,
305 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800306{
307 auto& data = GetData(instance);
308 bool success = true;
309
310 // clang-format off
311 {{range $f := AllCommands $}}
312 {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}}
313 {{Macro "C++.InitProc" $f}}
314 {{end}}
315 {{end}}
316 // clang-format on
317
318 return success;
319}
320
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800321bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc,
322 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800323{
324 auto& data = GetData(dev);
325 bool success = true;
326
327 // clang-format off
328 {{range $f := AllCommands $}}
329 {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}}
330 {{Macro "C++.InitProc" $f}}
331 {{end}}
332 {{end}}
333 // clang-format on
334
335 return success;
336}
337
Chia-I Wueb7db122016-03-24 09:11:06 +0800338»} // namespace driver
339»} // namespace vulkan
340
341// clang-format on
342¶{{end}}
343
344
345{{/*
Chia-I Wu0c203242016-03-15 13:44:51 +0800346------------------------------------------------------------------------------
Chia-I Wucc5e2762016-03-24 13:01:16 +0800347 Emits a declaration of a dispatch/driver table entry.
Chia-I Wu0c203242016-03-15 13:44:51 +0800348------------------------------------------------------------------------------
349*/}}
Chia-I Wucc5e2762016-03-24 13:01:16 +0800350{{define "C++.DeclareTableEntry"}}
Chia-I Wu0c203242016-03-15 13:44:51 +0800351 {{AssertType $ "Function"}}
352
353 {{Macro "FunctionPtrName" $}} {{Macro "BaseName" $}}
354{{end}}
355
356
357{{/*
358-------------------------------------------------------------------------------
Chia-I Wucc5e2762016-03-24 13:01:16 +0800359 Emits INIT_PROC macro.
Chia-I Wu0c203242016-03-15 13:44:51 +0800360-------------------------------------------------------------------------------
361*/}}
Chia-I Wucc5e2762016-03-24 13:01:16 +0800362{{define "C++.DefineInitProcMacro"}}
Chia-I Wu0c203242016-03-15 13:44:51 +0800363 #define UNLIKELY(expr) __builtin_expect((expr), 0)
364
365 #define INIT_PROC(obj, proc) do { \
366 data.{{$}}.proc = reinterpret_cast<PFN_vk ## proc>( \
367 get_proc(obj, "vk" # proc)); \
368 if (UNLIKELY(!data.{{$}}.proc)) { \
369 ALOGE("missing " # obj " proc: vk" # proc); \
370 success = false; \
371 } \
372 } while(0)
Chia-I Wu0c203242016-03-15 13:44:51 +0800373{{end}}
374
375
376{{/*
377-------------------------------------------------------------------------------
378 Emits code to invoke INIT_PROC or INIT_PROC_EXT.
379-------------------------------------------------------------------------------
380*/}}
381{{define "C++.InitProc"}}
382 {{AssertType $ "Function"}}
383
384 {{$ext := GetAnnotation $ "extension"}}
385 {{if $ext}}
386 INIT_PROC_EXT({{Macro "BaseName" $ext}}, §
387 {{else}}
388 INIT_PROC
389 {{end}}
390
391 {{if (Macro "IsInstanceDispatched" $)}}
392 instance, §
393 {{else}}
394 dev, §
395 {{end}}
396
397 {{Macro "BaseName" $}});
398{{end}}
399
400
401{{/*
402------------------------------------------------------------------------------
403 Emits true if a function is exported and instance-dispatched.
404------------------------------------------------------------------------------
405*/}}
406{{define "api.IsInstanceDispatchTableEntry"}}
407 {{AssertType $ "Function"}}
408
409 {{if and (Macro "IsFunctionExported" $) (Macro "IsInstanceDispatched" $)}}
410 true
411 {{end}}
412{{end}}
413
414
415{{/*
416------------------------------------------------------------------------------
417 Emits true if a function is exported and device-dispatched.
418------------------------------------------------------------------------------
419*/}}
420{{define "api.IsDeviceDispatchTableEntry"}}
421 {{AssertType $ "Function"}}
422
423 {{if and (Macro "IsFunctionExported" $) (Macro "IsDeviceDispatched" $)}}
424 true
425 {{end}}
426{{end}}
427
428
429{{/*
430------------------------------------------------------------------------------
431 Emits true if a function is intercepted by vulkan::api.
432------------------------------------------------------------------------------
433*/}}
434{{define "api.IsIntercepted"}}
435 {{AssertType $ "Function"}}
436
437 {{if (Macro "IsFunctionSupported" $)}}
438 {{/* Global functions cannot be dispatched at all */}}
439 {{ if (Macro "IsGloballyDispatched" $)}}true
440
441 {{/* VkPhysicalDevice functions that manage device layers */}}
442 {{else if eq $.Name "vkCreateDevice"}}true
443 {{else if eq $.Name "vkEnumerateDeviceLayerProperties"}}true
444 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
445
446 {{/* Destroy functions of dispatchable objects */}}
447 {{else if eq $.Name "vkDestroyInstance"}}true
448 {{else if eq $.Name "vkDestroyDevice"}}true
449
450 {{end}}
451 {{end}}
452{{end}}
453
454
455{{/*
Chia-I Wucc5e2762016-03-24 13:01:16 +0800456-------------------------------------------------------------------------------
457 Emits INIT_PROC_EXT macro for vulkan::api.
458-------------------------------------------------------------------------------
459*/}}
460{{define "api.C++.DefineInitProcExtMacro"}}
Chia-I Wu8925efd2016-04-13 15:13:21 +0800461 // Exported extension functions may be invoked even when their extensions
462 // are disabled. Dispatch to stubs when that happens.
Chia-I Wucc5e2762016-03-24 13:01:16 +0800463 #define INIT_PROC_EXT(ext, obj, proc) do { \
Chia-I Wu8925efd2016-04-13 15:13:21 +0800464 if (extensions[driver::ProcHook::ext]) \
465 INIT_PROC(obj, proc); \
466 else \
467 data.dispatch.proc = disabled ## proc; \
Chia-I Wucc5e2762016-03-24 13:01:16 +0800468 } while(0)
469{{end}}
470
471
472{{/*
Chia-I Wu8925efd2016-04-13 15:13:21 +0800473-------------------------------------------------------------------------------
474 Emits a stub for an exported extension function.
475-------------------------------------------------------------------------------
476*/}}
477{{define "api.C++.DefineExtensionStub"}}
478 {{AssertType $ "Function"}}
479
480 {{$ext := GetAnnotation $ "extension"}}
481 {{if and $ext (Macro "IsFunctionExported" $)}}
482 {{$ext_name := index $ext.Arguments 0}}
483
484 {{$base := (Macro "BaseName" $)}}
Chia-I Wu8925efd2016-04-13 15:13:21 +0800485
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800486 {{$p0 := (index $.CallParameters 0)}}
487 {{$ptail := (Tail 1 $.CallParameters)}}
488
489 {{$first_type := (Macro "Parameter" $p0)}}
490 {{$tail_types := (ForEach $ptail "ParameterType" | JoinWith ", ")}}
491
492 VKAPI_ATTR {{Node "Type" $.Return}} disabled{{$base}}({{$first_type}}, {{$tail_types}}) {
493 driver::Logger({{$p0.Name}}).Err({{$p0.Name}}, §
494 "{{$ext_name}} not enabled. Exported {{$.Name}} not executed.");
Chia-I Wu8925efd2016-04-13 15:13:21 +0800495 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
496 }
497
498 {{end}}
499{{end}}
500
501
502{{/*
Chia-I Wu0c203242016-03-15 13:44:51 +0800503------------------------------------------------------------------------------
504 Emits code for vkGetInstanceProcAddr for function interception.
505------------------------------------------------------------------------------
506*/}}
507{{define "api.C++.InterceptInstanceProcAddr"}}
508 {{AssertType $ "API"}}
509
510 // global functions
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800511 if (instance == VK_NULL_HANDLE) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800512 {{range $f := AllCommands $}}
513 {{if (Macro "IsGloballyDispatched" $f)}}
514 if (strcmp(pName, "{{$f.Name}}") == 0) return §
515 reinterpret_cast<PFN_vkVoidFunction>(§
516 vulkan::api::{{Macro "BaseName" $f}});
517 {{end}}
518 {{end}}
519
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800520 ALOGE("invalid vkGetInstanceProcAddr(VK_NULL_HANDLE, \"%s\") call", pName);
Chia-I Wu0c203242016-03-15 13:44:51 +0800521 return nullptr;
522 }
523
524 static const struct Hook {
525 const char* name;
526 PFN_vkVoidFunction proc;
527 } hooks[] = {
528 {{range $f := SortBy (AllCommands $) "FunctionName"}}
529 {{if (Macro "IsFunctionExported" $f)}}
530 {{/* hide global functions */}}
531 {{if (Macro "IsGloballyDispatched" $f)}}
532 { "{{$f.Name}}", nullptr },
533
534 {{/* redirect intercepted functions */}}
535 {{else if (Macro "api.IsIntercepted" $f)}}
536 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>(§
537 vulkan::api::{{Macro "BaseName" $f}}) },
538
539 {{/* redirect vkGetInstanceProcAddr to itself */}}
540 {{else if eq $f.Name "vkGetInstanceProcAddr"}}
541 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{$f.Name}}) },
542
543 {{/* redirect device functions to themselves as a workaround for
544 layers that do not intercept in their vkGetInstanceProcAddr */}}
545 {{else if (Macro "IsDeviceDispatched" $f)}}
546 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{$f.Name}}) },
547
548 {{end}}
549 {{end}}
550 {{end}}
551 };
552 // clang-format on
553 constexpr size_t count = sizeof(hooks) / sizeof(hooks[0]);
554 auto hook = std::lower_bound(
555 hooks, hooks + count, pName,
556 [](const Hook& h, const char* n) { return strcmp(h.name, n) < 0; });
557 if (hook < hooks + count && strcmp(hook->name, pName) == 0) {
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800558 if (!hook->proc) {
559 vulkan::driver::Logger(instance).Err(
560 instance, "invalid vkGetInstanceProcAddr(%p, \"%s\") call",
561 instance, pName);
562 }
Chia-I Wu0c203242016-03-15 13:44:51 +0800563 return hook->proc;
564 }
565 // clang-format off
566
567{{end}}
568
569
570{{/*
571------------------------------------------------------------------------------
572 Emits code for vkGetDeviceProcAddr for function interception.
573------------------------------------------------------------------------------
574*/}}
575{{define "api.C++.InterceptDeviceProcAddr"}}
576 {{AssertType $ "API"}}
577
578 if (device == VK_NULL_HANDLE) {
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800579 ALOGE("invalid vkGetDeviceProcAddr(VK_NULL_HANDLE, ...) call");
Chia-I Wu0c203242016-03-15 13:44:51 +0800580 return nullptr;
581 }
582
583 static const char* const known_non_device_names[] = {
584 {{range $f := SortBy (AllCommands $) "FunctionName"}}
585 {{if (Macro "IsFunctionSupported" $f)}}
586 {{if not (Macro "IsDeviceDispatched" $f)}}
587 "{{$f.Name}}",
588 {{end}}
589 {{end}}
590 {{end}}
591 };
592 // clang-format on
593 constexpr size_t count = sizeof(known_non_device_names) /
594 sizeof(known_non_device_names[0]);
595 if (!pName ||
596 std::binary_search(
597 known_non_device_names, known_non_device_names + count, pName,
598 [](const char* a, const char* b) { return (strcmp(a, b) < 0); })) {
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800599 vulkan::driver::Logger(device).Err
600 device, "invalid vkGetDeviceProcAddr(%p, \"%s\") call", device
601 (pName) ? pName : "(null)");
Chia-I Wu0c203242016-03-15 13:44:51 +0800602 return nullptr;
603 }
604 // clang-format off
605
Chia-I Wuc56603e2016-04-12 11:16:17 +0800606 {{range $f := AllCommands $}}
607 {{if (Macro "IsDeviceDispatched" $f)}}
608 {{ if (Macro "api.IsIntercepted" $f)}}
609 if (strcmp(pName, "{{$f.Name}}") == 0) return §
610 reinterpret_cast<PFN_vkVoidFunction>(§
611 vulkan::api::{{Macro "BaseName" $f}});
612 {{else if eq $f.Name "vkGetDeviceProcAddr"}}
613 if (strcmp(pName, "{{$f.Name}}") == 0) return §
614 reinterpret_cast<PFN_vkVoidFunction>(§
615 {{$f.Name}});
616 {{end}}
617 {{end}}
618 {{end}}
619
Chia-I Wu0c203242016-03-15 13:44:51 +0800620{{end}}
621
622
623{{/*
624------------------------------------------------------------------------------
625 Emits code to dispatch a function.
626------------------------------------------------------------------------------
627*/}}
628{{define "api.C++.Dispatch"}}
629 {{AssertType $ "Function"}}
630
631 {{if (Macro "api.IsIntercepted" $)}}// call into api.cpp{{end}}
632 {{if not (IsVoid $.Return.Type)}}return §{{end}}
633
634 {{if (Macro "api.IsIntercepted" $)}}
635 vulkan::api::§
636 {{else}}
637 {{$p0 := index $.CallParameters 0}}
638 vulkan::api::GetData({{$p0.Name}}).dispatch
639 {{end}}
640
641 {{Macro "BaseName" $}}({{Macro "Arguments" $}});
642{{end}}
643
644
645{{/*
Chia-I Wueb7db122016-03-24 09:11:06 +0800646------------------------------------------------------------------------------
647 Emits a list of extensions intercepted by vulkan::driver.
648------------------------------------------------------------------------------
649*/}}
650{{define "driver.InterceptedExtensions"}}
651VK_ANDROID_native_buffer
652VK_EXT_debug_report
653VK_KHR_android_surface
654VK_KHR_surface
655VK_KHR_swapchain
656{{end}}
657
658
659{{/*
660------------------------------------------------------------------------------
661 Emits true if an extension is intercepted by vulkan::driver.
662------------------------------------------------------------------------------
663*/}}
664{{define "driver.IsExtensionIntercepted"}}
665 {{$ext_name := index $.Arguments 0}}
666 {{$filters := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
667
668 {{range $f := $filters}}
669 {{if eq $ext_name $f}}true{{end}}
670 {{end}}
671{{end}}
672
673
674{{/*
675------------------------------------------------------------------------------
676 Emits true if a function is intercepted by vulkan::driver.
677------------------------------------------------------------------------------
678*/}}
679{{define "driver.IsIntercepted"}}
680 {{AssertType $ "Function"}}
681
682 {{if (Macro "IsFunctionSupported" $)}}
683 {{/* Create functions of dispatchable objects */}}
684 {{ if eq $.Name "vkCreateInstance"}}true
685 {{else if eq $.Name "vkCreateDevice"}}true
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800686 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true
Chia-I Wueb7db122016-03-24 09:11:06 +0800687 {{else if eq $.Name "vkGetDeviceQueue"}}true
688 {{else if eq $.Name "vkAllocateCommandBuffers"}}true
689
690 {{/* Destroy functions of dispatchable objects */}}
691 {{else if eq $.Name "vkDestroyInstance"}}true
692 {{else if eq $.Name "vkDestroyDevice"}}true
693
694 {{/* Enumeration of extensions */}}
695 {{else if eq $.Name "vkEnumerateInstanceExtensionProperties"}}true
696 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
697
Chia-I Wueb7db122016-03-24 09:11:06 +0800698 {{else if eq $.Name "vkGetInstanceProcAddr"}}true
699 {{else if eq $.Name "vkGetDeviceProcAddr"}}true
700
701 {{end}}
702
703 {{$ext := GetAnnotation $ "extension"}}
704 {{if $ext}}
705 {{Macro "driver.IsExtensionIntercepted" $ext}}
706 {{end}}
707
708 {{end}}
709{{end}}
710
711
712{{/*
713------------------------------------------------------------------------------
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800714 Emits true if a function needs a ProcHook stub.
Chia-I Wueb7db122016-03-24 09:11:06 +0800715------------------------------------------------------------------------------
716*/}}
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800717{{define "driver.NeedProcHookStub"}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800718 {{AssertType $ "Function"}}
719
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800720 {{if and (Macro "driver.IsIntercepted" $) (Macro "IsDeviceDispatched" $)}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800721 {{$ext := GetAnnotation $ "extension"}}
722 {{if $ext}}
723 {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}}
724 {{end}}
725 {{end}}
726{{end}}
727
728
729{{/*
730-------------------------------------------------------------------------------
731 Emits definition of struct ProcHook.
732-------------------------------------------------------------------------------
733*/}}
734{{define "driver.C++.DefineProcHookType"}}
735 struct ProcHook {
736 enum Type {
737 GLOBAL,
738 INSTANCE,
739 DEVICE,
740 };
741
742 enum Extension {
743 {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
744 {{range $e := $exts}}
745 {{TrimPrefix "VK_" $e}},
746 {{end}}
747
748 EXTENSION_CORE, // valid bit
749 EXTENSION_COUNT,
750 EXTENSION_UNKNOWN,
751 };
752
753 const char* name;
754 Type type;
755 Extension extension;
756
757 PFN_vkVoidFunction proc;
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800758 PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks
Chia-I Wueb7db122016-03-24 09:11:06 +0800759 };
760{{end}}
761
762
763{{/*
764-------------------------------------------------------------------------------
Chia-I Wucc5e2762016-03-24 13:01:16 +0800765 Emits INIT_PROC_EXT macro for vulkan::driver.
766-------------------------------------------------------------------------------
767*/}}
768{{define "driver.C++.DefineInitProcExtMacro"}}
769 #define INIT_PROC_EXT(ext, obj, proc) do { \
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800770 if (extensions[ProcHook::ext]) \
Chia-I Wucc5e2762016-03-24 13:01:16 +0800771 INIT_PROC(obj, proc); \
772 } while(0)
773{{end}}
774
775
776{{/*
777-------------------------------------------------------------------------------
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800778 Emits a stub for ProcHook::checked_proc.
Chia-I Wueb7db122016-03-24 09:11:06 +0800779-------------------------------------------------------------------------------
780*/}}
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800781{{define "driver.C++.DefineProcHookStub"}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800782 {{AssertType $ "Function"}}
783
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800784 {{if (Macro "driver.NeedProcHookStub" $)}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800785 {{$ext := GetAnnotation $ "extension"}}
786 {{$ext_name := index $ext.Arguments 0}}
787
788 {{$base := (Macro "BaseName" $)}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800789
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800790 VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) {
791 {{$p0 := index $.CallParameters 0}}
792 {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800793
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800794 if (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) {
795 {{if not (IsVoid $.Return.Type)}}return §{{end}}
796 {{$base}}({{Macro "Arguments" $}});
797 } else {
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800798 Logger({{$p0.Name}}).Err({{$p0.Name}}, "{{$ext_name}} not enabled. {{$.Name}} not executed.");
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800799 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800800 }
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800801 }
Chia-I Wueb7db122016-03-24 09:11:06 +0800802
803 {{end}}
804{{end}}
805
806
807{{/*
808-------------------------------------------------------------------------------
809 Emits definition of a global ProcHook.
810-------------------------------------------------------------------------------
811*/}}
812{{define "driver.C++.DefineGlobalProcHook"}}
813 {{AssertType $ "Function"}}
814
815 {{$base := (Macro "BaseName" $)}}
816
817 {{$ext := GetAnnotation $ "extension"}}
818 {{if $ext}}
819 {{Error "invalid global extension"}}
820 {{end}}
821
822 {
823 "{{$.Name}}",
824 ProcHook::GLOBAL,
825 ProcHook::EXTENSION_CORE,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800826 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
Chia-I Wueb7db122016-03-24 09:11:06 +0800827 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800828 },
829{{end}}
830
831
832{{/*
833-------------------------------------------------------------------------------
834 Emits definition of an instance ProcHook.
835-------------------------------------------------------------------------------
836*/}}
837{{define "driver.C++.DefineInstanceProcHook"}}
838 {{AssertType $ "Function"}}
839
840 {{$base := (Macro "BaseName" $)}}
841
842 {
843 "{{$.Name}}",
844 ProcHook::INSTANCE,
845
846 {{$ext := GetAnnotation $ "extension"}}
847 {{if $ext}}
848 ProcHook::{{Macro "BaseName" $ext}},
849
850 {{if (Macro "IsExtensionInternal" $ext)}}
851 nullptr,
852 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800853 {{else}}
Chia-I Wu62262232016-03-26 07:06:44 +0800854 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
Chia-I Wueb7db122016-03-24 09:11:06 +0800855 nullptr,
856 {{end}}
857 {{else}}
858 ProcHook::EXTENSION_CORE,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800859 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
Chia-I Wueb7db122016-03-24 09:11:06 +0800860 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800861 {{end}}
862 },
863{{end}}
864
865
866{{/*
867-------------------------------------------------------------------------------
868 Emits definition of a device ProcHook.
869-------------------------------------------------------------------------------
870*/}}
871{{define "driver.C++.DefineDeviceProcHook"}}
872 {{AssertType $ "Function"}}
873
874 {{$base := (Macro "BaseName" $)}}
875
876 {
877 "{{$.Name}}",
878 ProcHook::DEVICE,
879
880 {{$ext := GetAnnotation $ "extension"}}
881 {{if $ext}}
882 ProcHook::{{Macro "BaseName" $ext}},
883
884 {{if (Macro "IsExtensionInternal" $ext)}}
885 nullptr,
886 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800887 {{else}}
Chia-I Wu62262232016-03-26 07:06:44 +0800888 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
Chia-I Wueb7db122016-03-24 09:11:06 +0800889 reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}),
890 {{end}}
891 {{else}}
Chia-I Wu4901db72016-03-24 16:38:58 +0800892 ProcHook::EXTENSION_CORE,
893 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
894 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800895 {{end}}
896 },
897{{end}}
898
899
900{{/*
Chia-I Wu0c203242016-03-15 13:44:51 +0800901-------------------------------------------------------------------------------
Chia-I Wucc5e2762016-03-24 13:01:16 +0800902 Emits true if a function is needed by vulkan::driver.
903-------------------------------------------------------------------------------
904*/}}
905{{define "driver.IsDriverTableEntry"}}
906 {{AssertType $ "Function"}}
907
908 {{if (Macro "IsFunctionSupported" $)}}
909 {{/* Create functions of dispatchable objects */}}
910 {{ if eq $.Name "vkCreateDevice"}}true
911 {{else if eq $.Name "vkGetDeviceQueue"}}true
912 {{else if eq $.Name "vkAllocateCommandBuffers"}}true
913
914 {{/* Destroy functions of dispatchable objects */}}
915 {{else if eq $.Name "vkDestroyInstance"}}true
916 {{else if eq $.Name "vkDestroyDevice"}}true
917
Chia-I Wu4901db72016-03-24 16:38:58 +0800918 {{else if eq $.Name "vkEnumerateDeviceLayerProperties"}}true
919
Chia-I Wucc5e2762016-03-24 13:01:16 +0800920 {{/* Enumeration of extensions */}}
921 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
922
923 {{/* We cache physical devices in loader.cpp */}}
924 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true
925
926 {{else if eq $.Name "vkGetInstanceProcAddr"}}true
927 {{else if eq $.Name "vkGetDeviceProcAddr"}}true
928
929 {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}}
930 {{else if eq $.Name "vkCreateImage"}}true
931 {{else if eq $.Name "vkDestroyImage"}}true
932
933 {{end}}
934
935 {{$ext := GetAnnotation $ "extension"}}
936 {{if $ext}}
937 {{$ext_name := index $ext.Arguments 0}}
938 {{ if eq $ext_name "VK_ANDROID_native_buffer"}}true
939 {{else if eq $ext_name "VK_EXT_debug_report"}}true
940 {{end}}
941 {{end}}
942 {{end}}
943{{end}}
944
945
946{{/*
947------------------------------------------------------------------------------
948 Emits true if an instance-dispatched function is needed by vulkan::driver.
949------------------------------------------------------------------------------
950*/}}
951{{define "driver.IsInstanceDriverTableEntry"}}
952 {{AssertType $ "Function"}}
953
954 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}}
955 true
956 {{end}}
957{{end}}
958
959
960{{/*
961------------------------------------------------------------------------------
962 Emits true if a device-dispatched function is needed by vulkan::driver.
963------------------------------------------------------------------------------
964*/}}
965{{define "driver.IsDeviceDriverTableEntry"}}
966 {{AssertType $ "Function"}}
967
968 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}}
969 true
970 {{end}}
971{{end}}
972
973
974{{/*
975-------------------------------------------------------------------------------
Chia-I Wu0c203242016-03-15 13:44:51 +0800976 Emits a function/extension name without the "vk"/"VK_" prefix.
977-------------------------------------------------------------------------------
978*/}}
979{{define "BaseName"}}
980 {{ if IsFunction $}}{{TrimPrefix "vk" $.Name}}
981 {{else if eq $.Name "extension"}}{{TrimPrefix "VK_" (index $.Arguments 0)}}
982 {{else}}{{Error "invalid use of BaseName"}}
983 {{end}}
984{{end}}
985
986
987{{/*
988-------------------------------------------------------------------------------
989 Emits a comma-separated list of C parameter names for the given command.
990-------------------------------------------------------------------------------
991*/}}
992{{define "Arguments"}}
993 {{AssertType $ "Function"}}
994
995 {{ForEach $.CallParameters "ParameterName" | JoinWith ", "}}
996{{end}}
997
998
999{{/*
1000------------------------------------------------------------------------------
1001------------------------------------------------------------------------------
1002*/}}
1003{{define "IsGloballyDispatched"}}
1004 {{AssertType $ "Function"}}
1005 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Global")}}
1006 true
1007 {{end}}
1008{{end}}
1009
1010
1011{{/*
1012------------------------------------------------------------------------------
1013 Emit "true" for supported functions that undergo table dispatch. Only global
1014 functions and functions handled in the loader top without calling into
1015 lower layers are not dispatched.
1016------------------------------------------------------------------------------
1017*/}}
1018{{define "IsInstanceDispatched"}}
1019 {{AssertType $ "Function"}}
1020 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}}
1021 true
1022 {{end}}
1023{{end}}
1024
1025
1026{{/*
1027------------------------------------------------------------------------------
1028 Emit "true" for supported functions that can have device-specific dispatch.
1029------------------------------------------------------------------------------
1030*/}}
1031{{define "IsDeviceDispatched"}}
1032 {{AssertType $ "Function"}}
1033 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Device")}}
1034 true
1035 {{end}}
1036{{end}}
1037
1038
1039{{/*
1040------------------------------------------------------------------------------
1041 Emit "true" if a function is core or from a supportable extension.
1042------------------------------------------------------------------------------
1043*/}}
1044{{define "IsFunctionSupported"}}
1045 {{AssertType $ "Function"}}
1046 {{if not (GetAnnotation $ "pfn")}}
1047 {{$ext := GetAnnotation $ "extension"}}
1048 {{if not $ext}}true
1049 {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true
1050 {{end}}
1051 {{end}}
1052{{end}}
1053
1054
1055{{/*
1056------------------------------------------------------------------------------
1057 Decides whether a function should be exported from the Android Vulkan
1058 library. Functions in the core API and in loader extensions are exported.
1059------------------------------------------------------------------------------
1060*/}}
1061{{define "IsFunctionExported"}}
1062 {{AssertType $ "Function"}}
1063
1064 {{if (Macro "IsFunctionSupported" $)}}
1065 {{$ext := GetAnnotation $ "extension"}}
1066 {{if $ext}}
1067 {{Macro "IsExtensionExported" $ext}}
1068 {{else}}
1069 true
1070 {{end}}
1071 {{end}}
1072{{end}}
1073
1074
1075{{/*
1076------------------------------------------------------------------------------
1077 Emit "true" if an extension is unsupportable on Android.
1078------------------------------------------------------------------------------
1079*/}}
1080{{define "IsExtensionBlacklisted"}}
1081 {{$ext := index $.Arguments 0}}
1082 {{ if eq $ext "VK_KHR_display"}}true
1083 {{else if eq $ext "VK_KHR_display_swapchain"}}true
1084 {{else if eq $ext "VK_KHR_xlib_surface"}}true
1085 {{else if eq $ext "VK_KHR_xcb_surface"}}true
1086 {{else if eq $ext "VK_KHR_wayland_surface"}}true
1087 {{else if eq $ext "VK_KHR_mir_surface"}}true
1088 {{else if eq $ext "VK_KHR_win32_surface"}}true
1089 {{end}}
1090{{end}}
1091
1092
1093{{/*
1094------------------------------------------------------------------------------
1095 Reports whether an extension is implemented entirely by the loader,
1096 so drivers should not enumerate it.
1097------------------------------------------------------------------------------
1098*/}}
1099{{define "IsExtensionExported"}}
1100 {{$ext := index $.Arguments 0}}
1101 {{ if eq $ext "VK_KHR_surface"}}true
1102 {{else if eq $ext "VK_KHR_swapchain"}}true
1103 {{else if eq $ext "VK_KHR_android_surface"}}true
1104 {{end}}
1105{{end}}
Chia-I Wueb7db122016-03-24 09:11:06 +08001106
1107
1108{{/*
1109------------------------------------------------------------------------------
1110 Reports whether an extension is internal to the loader and drivers,
1111 so the loader should not enumerate it.
1112------------------------------------------------------------------------------
1113*/}}
1114{{define "IsExtensionInternal"}}
1115 {{$ext := index $.Arguments 0}}
1116 {{ if eq $ext "VK_ANDROID_native_buffer"}}true
1117 {{end}}
1118{{end}}