blob: f7083c3146a647887fd00fc005afc0c9a09af4a1 [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
40#include <vulkan/vulkan.h>
41
42namespace vulkan
43namespace api
44
45struct InstanceDispatchTable {
46 // clang-format off
47 {{range $f := AllCommands $}}
48 {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}}
49 {{Macro "C++.DeclareDispatchTableEntry" $f}};
50 {{end}}
51 {{end}}
52 // clang-format on
53};
54
55struct DeviceDispatchTable {
56 // clang-format off
57 {{range $f := AllCommands $}}
58 {{if (Macro "api.IsDeviceDispatchTableEntry" $f)}}
59 {{Macro "C++.DeclareDispatchTableEntry" $f}};
60 {{end}}
61 {{end}}
62 // clang-format on
63};
64
65bool InitDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc);
66bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc);
67
68»} // namespace api
69»} // namespace vulkan
70
71#endif // LIBVULKAN_API_GEN_H
72¶{{end}}
73
74
75{{/*
76-------------------------------------------------------------------------------
77 api_gen.cpp
78-------------------------------------------------------------------------------
79*/}}
80{{define "api_gen.cpp"}}
81{{Macro "Copyright"}}
82
83// WARNING: This file is generated. See ../README.md for instructions.
84
85#include <string.h>
86#include <algorithm>
87#include <log/log.h>
88
89#include "api.h"
90
91namespace vulkan
92namespace api
93
94{{Macro "C++.DefineInitProcMacros" "dispatch"}}
95
96bool InitDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) {
97 auto& data = GetData(instance);
98 bool success = true;
99
100 // clang-format off
101 {{range $f := AllCommands $}}
102 {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}}
103 {{Macro "C++.InitProc" $f}}
104 {{end}}
105 {{end}}
106 // clang-format on
107
108 return success;
109}
110
111bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) {
112 auto& data = GetData(dev);
113 bool success = true;
114
115 // clang-format off
116 {{range $f := AllCommands $}}
117 {{if (Macro "api.IsDeviceDispatchTableEntry" $f)}}
118 {{Macro "C++.InitProc" $f}}
119 {{end}}
120 {{end}}
121 // clang-format on
122
123 return success;
124}
125
126»} // namespace api
127»} // namespace vulkan
128
129// clang-format off
130
131{{range $f := AllCommands $}}
132 {{if (Macro "IsFunctionExported" $f)}}
133 __attribute__((visibility("default")))
134 VKAPI_ATTR {{Node "Type" $f.Return}} {{$f.Name}}({{Macro "Parameters" $f}}) {
135 {{ if eq $f.Name "vkGetInstanceProcAddr"}}
136 {{Macro "api.C++.InterceptInstanceProcAddr" $}}
137 {{else if eq $f.Name "vkGetDeviceProcAddr"}}
138 {{Macro "api.C++.InterceptDeviceProcAddr" $}}
139 {{end}}
140
141 {{Macro "api.C++.Dispatch" $f}}
142 }
143
144 {{end}}
145{{end}}
146
147// clang-format on
148¶{{end}}
149
150
151{{/*
Chia-I Wueb7db122016-03-24 09:11:06 +0800152-------------------------------------------------------------------------------
153 driver_gen.h
154-------------------------------------------------------------------------------
155*/}}
156{{define "driver_gen.h"}}
157{{Macro "Copyright"}}
158
159// WARNING: This file is generated. See ../README.md for instructions.
160
161#ifndef LIBVULKAN_DRIVER_GEN_H
162#define LIBVULKAN_DRIVER_GEN_H
163
164#include <vulkan/vulkan.h>
165#include <vulkan/vk_android_native_buffer.h>
166
167namespace vulkan
168namespace driver
169
170{{Macro "driver.C++.DefineProcHookType"}}
171
172const ProcHook* GetProcHook(const char* name);
173ProcHook::Extension GetProcHookExtension(const char* name);
174
175»} // namespace driver
176»} // namespace vulkan
177
178#endif // LIBVULKAN_DRIVER_TABLE_H
179¶{{end}}
180
181
182{{/*
183-------------------------------------------------------------------------------
184 driver_gen.cpp
185-------------------------------------------------------------------------------
186*/}}
187{{define "driver_gen.cpp"}}
188{{Macro "Copyright"}}
189
190// WARNING: This file is generated. See ../README.md for instructions.
191
192#include <string.h>
193#include <algorithm>
194#include <log/log.h>
195
196#include "driver.h"
197#include "loader.h"
198
199namespace vulkan
200namespace driver
201
202namespace
203
204// clang-format off
205
206{{range $f := AllCommands $}}
207 {{Macro "driver.C++.DefineProcHookStubs" $f}}
208{{end}}
209// clang-format on
210
211const ProcHook g_proc_hooks[] = {
212 // clang-format off
213 {{range $f := SortBy (AllCommands $) "FunctionName"}}
214 {{if (Macro "driver.IsIntercepted" $f)}}
215 {{ if (Macro "IsGloballyDispatched" $f)}}
216 {{Macro "driver.C++.DefineGlobalProcHook" $f}}
217 {{else if (Macro "IsInstanceDispatched" $f)}}
218 {{Macro "driver.C++.DefineInstanceProcHook" $f}}
219 {{else if (Macro "IsDeviceDispatched" $f)}}
220 {{Macro "driver.C++.DefineDeviceProcHook" $f}}
221 {{end}}
222 {{end}}
223 {{end}}
224 // clang-format on
225};
226
227»} // anonymous
228
229const ProcHook* GetProcHook(const char* name) {
230 const auto& begin = g_proc_hooks;
231 const auto& end = g_proc_hooks +
232 sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
233 const auto hook = std::lower_bound(begin, end, name,
234 [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
235 return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
236}
237
238ProcHook::Extension GetProcHookExtension(const char* name) {
239 {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
240 // clang-format off
241 {{range $e := $exts}}
242 if (strcmp(name, "{{$e}}") == 0) return ProcHook::{{TrimPrefix "VK_" $e}};
243 {{end}}
244 // clang-format on
245 return ProcHook::EXTENSION_UNKNOWN;
246}
247
248»} // namespace driver
249»} // namespace vulkan
250
251// clang-format on
252¶{{end}}
253
254
255{{/*
Chia-I Wu0c203242016-03-15 13:44:51 +0800256------------------------------------------------------------------------------
257 Emits a declaration of a dispatch table entry.
258------------------------------------------------------------------------------
259*/}}
260{{define "C++.DeclareDispatchTableEntry"}}
261 {{AssertType $ "Function"}}
262
263 {{Macro "FunctionPtrName" $}} {{Macro "BaseName" $}}
264{{end}}
265
266
267{{/*
268-------------------------------------------------------------------------------
269 Emits macros to help initialize dispatch tables.
270-------------------------------------------------------------------------------
271*/}}
272{{define "C++.DefineInitProcMacros"}}
273 #define UNLIKELY(expr) __builtin_expect((expr), 0)
274
275 #define INIT_PROC(obj, proc) do { \
276 data.{{$}}.proc = reinterpret_cast<PFN_vk ## proc>( \
277 get_proc(obj, "vk" # proc)); \
278 if (UNLIKELY(!data.{{$}}.proc)) { \
279 ALOGE("missing " # obj " proc: vk" # proc); \
280 success = false; \
281 } \
282 } while(0)
283
284 // TODO do we want to point to a stub or nullptr when ext is not enabled?
285 #define INIT_PROC_EXT(ext, obj, proc) do { \
286 INIT_PROC(obj, proc); \
287 } while(0)
288{{end}}
289
290
291{{/*
292-------------------------------------------------------------------------------
293 Emits code to invoke INIT_PROC or INIT_PROC_EXT.
294-------------------------------------------------------------------------------
295*/}}
296{{define "C++.InitProc"}}
297 {{AssertType $ "Function"}}
298
299 {{$ext := GetAnnotation $ "extension"}}
300 {{if $ext}}
301 INIT_PROC_EXT({{Macro "BaseName" $ext}}, §
302 {{else}}
303 INIT_PROC
304 {{end}}
305
306 {{if (Macro "IsInstanceDispatched" $)}}
307 instance, §
308 {{else}}
309 dev, §
310 {{end}}
311
312 {{Macro "BaseName" $}});
313{{end}}
314
315
316{{/*
317------------------------------------------------------------------------------
318 Emits true if a function is exported and instance-dispatched.
319------------------------------------------------------------------------------
320*/}}
321{{define "api.IsInstanceDispatchTableEntry"}}
322 {{AssertType $ "Function"}}
323
324 {{if and (Macro "IsFunctionExported" $) (Macro "IsInstanceDispatched" $)}}
325 true
326 {{end}}
327{{end}}
328
329
330{{/*
331------------------------------------------------------------------------------
332 Emits true if a function is exported and device-dispatched.
333------------------------------------------------------------------------------
334*/}}
335{{define "api.IsDeviceDispatchTableEntry"}}
336 {{AssertType $ "Function"}}
337
338 {{if and (Macro "IsFunctionExported" $) (Macro "IsDeviceDispatched" $)}}
339 true
340 {{end}}
341{{end}}
342
343
344{{/*
345------------------------------------------------------------------------------
346 Emits true if a function is intercepted by vulkan::api.
347------------------------------------------------------------------------------
348*/}}
349{{define "api.IsIntercepted"}}
350 {{AssertType $ "Function"}}
351
352 {{if (Macro "IsFunctionSupported" $)}}
353 {{/* Global functions cannot be dispatched at all */}}
354 {{ if (Macro "IsGloballyDispatched" $)}}true
355
356 {{/* VkPhysicalDevice functions that manage device layers */}}
357 {{else if eq $.Name "vkCreateDevice"}}true
358 {{else if eq $.Name "vkEnumerateDeviceLayerProperties"}}true
359 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
360
361 {{/* Destroy functions of dispatchable objects */}}
362 {{else if eq $.Name "vkDestroyInstance"}}true
363 {{else if eq $.Name "vkDestroyDevice"}}true
364
365 {{end}}
366 {{end}}
367{{end}}
368
369
370{{/*
371------------------------------------------------------------------------------
372 Emits code for vkGetInstanceProcAddr for function interception.
373------------------------------------------------------------------------------
374*/}}
375{{define "api.C++.InterceptInstanceProcAddr"}}
376 {{AssertType $ "API"}}
377
378 // global functions
379 if (!instance) {
380 {{range $f := AllCommands $}}
381 {{if (Macro "IsGloballyDispatched" $f)}}
382 if (strcmp(pName, "{{$f.Name}}") == 0) return §
383 reinterpret_cast<PFN_vkVoidFunction>(§
384 vulkan::api::{{Macro "BaseName" $f}});
385 {{end}}
386 {{end}}
387
388 ALOGE("vkGetInstanceProcAddr called with %s without instance", pName);
389 return nullptr;
390 }
391
392 static const struct Hook {
393 const char* name;
394 PFN_vkVoidFunction proc;
395 } hooks[] = {
396 {{range $f := SortBy (AllCommands $) "FunctionName"}}
397 {{if (Macro "IsFunctionExported" $f)}}
398 {{/* hide global functions */}}
399 {{if (Macro "IsGloballyDispatched" $f)}}
400 { "{{$f.Name}}", nullptr },
401
402 {{/* redirect intercepted functions */}}
403 {{else if (Macro "api.IsIntercepted" $f)}}
404 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>(§
405 vulkan::api::{{Macro "BaseName" $f}}) },
406
407 {{/* redirect vkGetInstanceProcAddr to itself */}}
408 {{else if eq $f.Name "vkGetInstanceProcAddr"}}
409 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{$f.Name}}) },
410
411 {{/* redirect device functions to themselves as a workaround for
412 layers that do not intercept in their vkGetInstanceProcAddr */}}
413 {{else if (Macro "IsDeviceDispatched" $f)}}
414 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{$f.Name}}) },
415
416 {{end}}
417 {{end}}
418 {{end}}
419 };
420 // clang-format on
421 constexpr size_t count = sizeof(hooks) / sizeof(hooks[0]);
422 auto hook = std::lower_bound(
423 hooks, hooks + count, pName,
424 [](const Hook& h, const char* n) { return strcmp(h.name, n) < 0; });
425 if (hook < hooks + count && strcmp(hook->name, pName) == 0) {
426 if (!hook->proc)
427 ALOGE("vkGetInstanceProcAddr called with %s with instance", pName);
428 return hook->proc;
429 }
430 // clang-format off
431
432{{end}}
433
434
435{{/*
436------------------------------------------------------------------------------
437 Emits code for vkGetDeviceProcAddr for function interception.
438------------------------------------------------------------------------------
439*/}}
440{{define "api.C++.InterceptDeviceProcAddr"}}
441 {{AssertType $ "API"}}
442
443 if (device == VK_NULL_HANDLE) {
444 ALOGE("vkGetDeviceProcAddr called with invalid device");
445 return nullptr;
446 }
447
448 static const char* const known_non_device_names[] = {
449 {{range $f := SortBy (AllCommands $) "FunctionName"}}
450 {{if (Macro "IsFunctionSupported" $f)}}
451 {{if not (Macro "IsDeviceDispatched" $f)}}
452 "{{$f.Name}}",
453 {{end}}
454 {{end}}
455 {{end}}
456 };
457 // clang-format on
458 constexpr size_t count = sizeof(known_non_device_names) /
459 sizeof(known_non_device_names[0]);
460 if (!pName ||
461 std::binary_search(
462 known_non_device_names, known_non_device_names + count, pName,
463 [](const char* a, const char* b) { return (strcmp(a, b) < 0); })) {
464 ALOGE("vkGetDeviceProcAddr called with %s", pName);
465 return nullptr;
466 }
467 // clang-format off
468
469{{end}}
470
471
472{{/*
473------------------------------------------------------------------------------
474 Emits code to dispatch a function.
475------------------------------------------------------------------------------
476*/}}
477{{define "api.C++.Dispatch"}}
478 {{AssertType $ "Function"}}
479
480 {{if (Macro "api.IsIntercepted" $)}}// call into api.cpp{{end}}
481 {{if not (IsVoid $.Return.Type)}}return §{{end}}
482
483 {{if (Macro "api.IsIntercepted" $)}}
484 vulkan::api::§
485 {{else}}
486 {{$p0 := index $.CallParameters 0}}
487 vulkan::api::GetData({{$p0.Name}}).dispatch
488 {{end}}
489
490 {{Macro "BaseName" $}}({{Macro "Arguments" $}});
491{{end}}
492
493
494{{/*
Chia-I Wueb7db122016-03-24 09:11:06 +0800495------------------------------------------------------------------------------
496 Emits a list of extensions intercepted by vulkan::driver.
497------------------------------------------------------------------------------
498*/}}
499{{define "driver.InterceptedExtensions"}}
500VK_ANDROID_native_buffer
501VK_EXT_debug_report
502VK_KHR_android_surface
503VK_KHR_surface
504VK_KHR_swapchain
505{{end}}
506
507
508{{/*
509------------------------------------------------------------------------------
510 Emits true if an extension is intercepted by vulkan::driver.
511------------------------------------------------------------------------------
512*/}}
513{{define "driver.IsExtensionIntercepted"}}
514 {{$ext_name := index $.Arguments 0}}
515 {{$filters := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
516
517 {{range $f := $filters}}
518 {{if eq $ext_name $f}}true{{end}}
519 {{end}}
520{{end}}
521
522
523{{/*
524------------------------------------------------------------------------------
525 Emits true if a function is intercepted by vulkan::driver.
526------------------------------------------------------------------------------
527*/}}
528{{define "driver.IsIntercepted"}}
529 {{AssertType $ "Function"}}
530
531 {{if (Macro "IsFunctionSupported" $)}}
532 {{/* Create functions of dispatchable objects */}}
533 {{ if eq $.Name "vkCreateInstance"}}true
534 {{else if eq $.Name "vkCreateDevice"}}true
535 {{else if eq $.Name "vkGetDeviceQueue"}}true
536 {{else if eq $.Name "vkAllocateCommandBuffers"}}true
537
538 {{/* Destroy functions of dispatchable objects */}}
539 {{else if eq $.Name "vkDestroyInstance"}}true
540 {{else if eq $.Name "vkDestroyDevice"}}true
541
542 {{/* Enumeration of extensions */}}
543 {{else if eq $.Name "vkEnumerateInstanceExtensionProperties"}}true
544 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
545
546 {{/* We cache physical devices in loader.cpp */}}
547 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true
548
549 {{else if eq $.Name "vkGetInstanceProcAddr"}}true
550 {{else if eq $.Name "vkGetDeviceProcAddr"}}true
551
552 {{end}}
553
554 {{$ext := GetAnnotation $ "extension"}}
555 {{if $ext}}
556 {{Macro "driver.IsExtensionIntercepted" $ext}}
557 {{end}}
558
559 {{end}}
560{{end}}
561
562
563{{/*
564------------------------------------------------------------------------------
565 Emits true if a function needs ProcHook stubs.
566------------------------------------------------------------------------------
567*/}}
568{{define "driver.NeedProcHookStubs"}}
569 {{AssertType $ "Function"}}
570
571 {{if (Macro "driver.IsIntercepted" $)}}
572 {{$ext := GetAnnotation $ "extension"}}
573 {{if $ext}}
574 {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}}
575 {{end}}
576 {{end}}
577{{end}}
578
579
580{{/*
581-------------------------------------------------------------------------------
582 Emits definition of struct ProcHook.
583-------------------------------------------------------------------------------
584*/}}
585{{define "driver.C++.DefineProcHookType"}}
586 struct ProcHook {
587 enum Type {
588 GLOBAL,
589 INSTANCE,
590 DEVICE,
591 };
592
593 enum Extension {
594 {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
595 {{range $e := $exts}}
596 {{TrimPrefix "VK_" $e}},
597 {{end}}
598
599 EXTENSION_CORE, // valid bit
600 EXTENSION_COUNT,
601 EXTENSION_UNKNOWN,
602 };
603
604 const char* name;
605 Type type;
606 Extension extension;
607
608 PFN_vkVoidFunction proc;
609 PFN_vkVoidFunction disabled_proc; // nullptr for global hooks
610 PFN_vkVoidFunction checked_proc; // nullptr for global/instance hooks
611 };
612{{end}}
613
614
615{{/*
616-------------------------------------------------------------------------------
617 Emits definitions of stub functions for ProcHook.
618-------------------------------------------------------------------------------
619*/}}
620{{define "driver.C++.DefineProcHookStubs"}}
621 {{AssertType $ "Function"}}
622
623 {{if (Macro "driver.NeedProcHookStubs" $)}}
624 {{$ext := GetAnnotation $ "extension"}}
625 {{$ext_name := index $ext.Arguments 0}}
626
627 {{$base := (Macro "BaseName" $)}}
628 {{$unnamed_params := (ForEach $.CallParameters "ParameterType" | JoinWith ", ")}}
629
630 VKAPI_ATTR {{Node "Type" $.Return}} disabled{{$base}}({{$unnamed_params}}) {
631 ALOGE("{{$ext_name}} not enabled. {{$.Name}} not executed.");
632 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
633 }
634 {{if (Macro "IsDeviceDispatched" $)}}
635
636 VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) {
637 {{if not (IsVoid $.Return.Type)}}return §{{end}}
638
639 {{$p0 := index $.CallParameters 0}}
640 {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}}
641 (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) ? §
642 {{$base}}_Bottom({{Macro "Arguments" $}}) : §
643 disabled{{$base}}({{Macro "Arguments" $}});
644 }
645 {{end}}
646
647 {{end}}
648{{end}}
649
650
651{{/*
652-------------------------------------------------------------------------------
653 Emits definition of a global ProcHook.
654-------------------------------------------------------------------------------
655*/}}
656{{define "driver.C++.DefineGlobalProcHook"}}
657 {{AssertType $ "Function"}}
658
659 {{$base := (Macro "BaseName" $)}}
660
661 {{$ext := GetAnnotation $ "extension"}}
662 {{if $ext}}
663 {{Error "invalid global extension"}}
664 {{end}}
665
666 {
667 "{{$.Name}}",
668 ProcHook::GLOBAL,
669 ProcHook::EXTENSION_CORE,
670 {{if eq $.Name "vkEnumerateInstanceExtensionProperties"}}
671 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
672 {{else}}
673 reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
674 {{end}}
675 nullptr,
676 nullptr,
677 },
678{{end}}
679
680
681{{/*
682-------------------------------------------------------------------------------
683 Emits definition of an instance ProcHook.
684-------------------------------------------------------------------------------
685*/}}
686{{define "driver.C++.DefineInstanceProcHook"}}
687 {{AssertType $ "Function"}}
688
689 {{$base := (Macro "BaseName" $)}}
690
691 {
692 "{{$.Name}}",
693 ProcHook::INSTANCE,
694
695 {{$ext := GetAnnotation $ "extension"}}
696 {{if $ext}}
697 ProcHook::{{Macro "BaseName" $ext}},
698
699 {{if (Macro "IsExtensionInternal" $ext)}}
700 nullptr,
701 nullptr,
702 nullptr,
703 {{else}}
704 reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
705 reinterpret_cast<PFN_vkVoidFunction>(disabled{{$base}}),
706 nullptr,
707 {{end}}
708 {{else}}
709 ProcHook::EXTENSION_CORE,
710
711 {{if eq $.Name "vkGetInstanceProcAddr"}}
712 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
713 {{else}}
714 reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
715 {{end}}
716 nullptr,
717 nullptr,
718 {{end}}
719 },
720{{end}}
721
722
723{{/*
724-------------------------------------------------------------------------------
725 Emits definition of a device ProcHook.
726-------------------------------------------------------------------------------
727*/}}
728{{define "driver.C++.DefineDeviceProcHook"}}
729 {{AssertType $ "Function"}}
730
731 {{$base := (Macro "BaseName" $)}}
732
733 {
734 "{{$.Name}}",
735 ProcHook::DEVICE,
736
737 {{$ext := GetAnnotation $ "extension"}}
738 {{if $ext}}
739 ProcHook::{{Macro "BaseName" $ext}},
740
741 {{if (Macro "IsExtensionInternal" $ext)}}
742 nullptr,
743 nullptr,
744 nullptr,
745 {{else}}
746 reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
747 reinterpret_cast<PFN_vkVoidFunction>(disabled{{$base}}),
748 reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}),
749 {{end}}
750 {{else}}
751 ProcHook::EXTENSION_CORE,
752
753 {{if eq $.Name "vkGetDeviceProcAddr"}}
754 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
755 {{else}}
756 reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
757 {{end}}
758 nullptr,
759 nullptr,
760 {{end}}
761 },
762{{end}}
763
764
765{{/*
Chia-I Wu0c203242016-03-15 13:44:51 +0800766-------------------------------------------------------------------------------
767 Emits a function/extension name without the "vk"/"VK_" prefix.
768-------------------------------------------------------------------------------
769*/}}
770{{define "BaseName"}}
771 {{ if IsFunction $}}{{TrimPrefix "vk" $.Name}}
772 {{else if eq $.Name "extension"}}{{TrimPrefix "VK_" (index $.Arguments 0)}}
773 {{else}}{{Error "invalid use of BaseName"}}
774 {{end}}
775{{end}}
776
777
778{{/*
779-------------------------------------------------------------------------------
780 Emits a comma-separated list of C parameter names for the given command.
781-------------------------------------------------------------------------------
782*/}}
783{{define "Arguments"}}
784 {{AssertType $ "Function"}}
785
786 {{ForEach $.CallParameters "ParameterName" | JoinWith ", "}}
787{{end}}
788
789
790{{/*
791------------------------------------------------------------------------------
792------------------------------------------------------------------------------
793*/}}
794{{define "IsGloballyDispatched"}}
795 {{AssertType $ "Function"}}
796 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Global")}}
797 true
798 {{end}}
799{{end}}
800
801
802{{/*
803------------------------------------------------------------------------------
804 Emit "true" for supported functions that undergo table dispatch. Only global
805 functions and functions handled in the loader top without calling into
806 lower layers are not dispatched.
807------------------------------------------------------------------------------
808*/}}
809{{define "IsInstanceDispatched"}}
810 {{AssertType $ "Function"}}
811 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}}
812 true
813 {{end}}
814{{end}}
815
816
817{{/*
818------------------------------------------------------------------------------
819 Emit "true" for supported functions that can have device-specific dispatch.
820------------------------------------------------------------------------------
821*/}}
822{{define "IsDeviceDispatched"}}
823 {{AssertType $ "Function"}}
824 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Device")}}
825 true
826 {{end}}
827{{end}}
828
829
830{{/*
831------------------------------------------------------------------------------
832 Emit "true" if a function is core or from a supportable extension.
833------------------------------------------------------------------------------
834*/}}
835{{define "IsFunctionSupported"}}
836 {{AssertType $ "Function"}}
837 {{if not (GetAnnotation $ "pfn")}}
838 {{$ext := GetAnnotation $ "extension"}}
839 {{if not $ext}}true
840 {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true
841 {{end}}
842 {{end}}
843{{end}}
844
845
846{{/*
847------------------------------------------------------------------------------
848 Decides whether a function should be exported from the Android Vulkan
849 library. Functions in the core API and in loader extensions are exported.
850------------------------------------------------------------------------------
851*/}}
852{{define "IsFunctionExported"}}
853 {{AssertType $ "Function"}}
854
855 {{if (Macro "IsFunctionSupported" $)}}
856 {{$ext := GetAnnotation $ "extension"}}
857 {{if $ext}}
858 {{Macro "IsExtensionExported" $ext}}
859 {{else}}
860 true
861 {{end}}
862 {{end}}
863{{end}}
864
865
866{{/*
867------------------------------------------------------------------------------
868 Emit "true" if an extension is unsupportable on Android.
869------------------------------------------------------------------------------
870*/}}
871{{define "IsExtensionBlacklisted"}}
872 {{$ext := index $.Arguments 0}}
873 {{ if eq $ext "VK_KHR_display"}}true
874 {{else if eq $ext "VK_KHR_display_swapchain"}}true
875 {{else if eq $ext "VK_KHR_xlib_surface"}}true
876 {{else if eq $ext "VK_KHR_xcb_surface"}}true
877 {{else if eq $ext "VK_KHR_wayland_surface"}}true
878 {{else if eq $ext "VK_KHR_mir_surface"}}true
879 {{else if eq $ext "VK_KHR_win32_surface"}}true
880 {{end}}
881{{end}}
882
883
884{{/*
885------------------------------------------------------------------------------
886 Reports whether an extension is implemented entirely by the loader,
887 so drivers should not enumerate it.
888------------------------------------------------------------------------------
889*/}}
890{{define "IsExtensionExported"}}
891 {{$ext := index $.Arguments 0}}
892 {{ if eq $ext "VK_KHR_surface"}}true
893 {{else if eq $ext "VK_KHR_swapchain"}}true
894 {{else if eq $ext "VK_KHR_android_surface"}}true
895 {{end}}
896{{end}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800897
898
899{{/*
900------------------------------------------------------------------------------
901 Reports whether an extension is internal to the loader and drivers,
902 so the loader should not enumerate it.
903------------------------------------------------------------------------------
904*/}}
905{{define "IsExtensionInternal"}}
906 {{$ext := index $.Arguments 0}}
907 {{ if eq $ext "VK_ANDROID_native_buffer"}}true
908 {{end}}
909{{end}}