blob: 307f0e41a91633752a185813f7e10a8f06e2fa54 [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
Chia-I Wu3e654dc2016-05-20 16:15:06 +080097// to catch mismatches between vulkan.h and this file
98#undef VK_NO_PROTOTYPES
Chia-I Wu0c203242016-03-15 13:44:51 +080099#include "api.h"
100
101namespace vulkan
102namespace api
103
Chia-I Wucc5e2762016-03-24 13:01:16 +0800104{{Macro "C++.DefineInitProcMacro" "dispatch"}}
105
106{{Macro "api.C++.DefineInitProcExtMacro"}}
Chia-I Wu0c203242016-03-15 13:44:51 +0800107
Chia-I Wu8925efd2016-04-13 15:13:21 +0800108namespace
109
110// clang-format off
111
112{{range $f := AllCommands $}}
113 {{Macro "api.C++.DefineExtensionStub" $f}}
114{{end}}
115// clang-format on
116
117»} // anonymous
118
119bool InitDispatchTable(
120 VkInstance instance,
121 PFN_vkGetInstanceProcAddr get_proc,
122 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800123 auto& data = GetData(instance);
124 bool success = true;
125
126 // clang-format off
127 {{range $f := AllCommands $}}
128 {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}}
129 {{Macro "C++.InitProc" $f}}
130 {{end}}
131 {{end}}
132 // clang-format on
133
134 return success;
135}
136
Chia-I Wu8925efd2016-04-13 15:13:21 +0800137bool InitDispatchTable(
138 VkDevice dev,
139 PFN_vkGetDeviceProcAddr get_proc,
140 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800141 auto& data = GetData(dev);
142 bool success = true;
143
144 // clang-format off
145 {{range $f := AllCommands $}}
146 {{if (Macro "api.IsDeviceDispatchTableEntry" $f)}}
147 {{Macro "C++.InitProc" $f}}
148 {{end}}
149 {{end}}
150 // clang-format on
151
152 return success;
153}
154
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800155// clang-format off
156
157namespace
158
159// forward declarations needed by GetInstanceProcAddr and GetDeviceProcAddr
160{{range $f := AllCommands $}}
161 {{if and (Macro "IsFunctionExported" $f) (not (Macro "api.IsIntercepted" $f))}}
162 VKAPI_ATTR {{Node "Type" $f.Return}} {{Macro "BaseName" $f}}({{Macro "Parameters" $f}});
163 {{end}}
164{{end}}
165
166{{range $f := AllCommands $}}
167 {{if and (Macro "IsFunctionExported" $f) (not (Macro "api.IsIntercepted" $f))}}
168 VKAPI_ATTR {{Node "Type" $f.Return}} {{Macro "BaseName" $f}}({{Macro "Parameters" $f}}) {
169 {{ if eq $f.Name "vkGetInstanceProcAddr"}}
170 {{Macro "api.C++.InterceptInstanceProcAddr" $}}
171 {{else if eq $f.Name "vkGetDeviceProcAddr"}}
172 {{Macro "api.C++.InterceptDeviceProcAddr" $}}
173 {{end}}
174
175 {{Macro "api.C++.Dispatch" $f}}
176 }
177
178 {{end}}
179{{end}}
180
181»} // anonymous namespace
182
183// clang-format on
184
Chia-I Wu0c203242016-03-15 13:44:51 +0800185»} // namespace api
186»} // namespace vulkan
187
188// clang-format off
189
190{{range $f := AllCommands $}}
191 {{if (Macro "IsFunctionExported" $f)}}
192 __attribute__((visibility("default")))
193 VKAPI_ATTR {{Node "Type" $f.Return}} {{$f.Name}}({{Macro "Parameters" $f}}) {
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800194 {{if not (IsVoid $f.Return.Type)}}return §{{end}}
195 vulkan::api::{{Macro "BaseName" $f}}({{Macro "Arguments" $f}});
Chia-I Wu0c203242016-03-15 13:44:51 +0800196 }
197
198 {{end}}
199{{end}}
200
201// clang-format on
202¶{{end}}
203
204
205{{/*
Chia-I Wueb7db122016-03-24 09:11:06 +0800206-------------------------------------------------------------------------------
207 driver_gen.h
208-------------------------------------------------------------------------------
209*/}}
210{{define "driver_gen.h"}}
211{{Macro "Copyright"}}
212
213// WARNING: This file is generated. See ../README.md for instructions.
214
215#ifndef LIBVULKAN_DRIVER_GEN_H
216#define LIBVULKAN_DRIVER_GEN_H
217
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800218#include <bitset>
Chia-I Wueb7db122016-03-24 09:11:06 +0800219#include <vulkan/vulkan.h>
220#include <vulkan/vk_android_native_buffer.h>
221
222namespace vulkan
223namespace driver
224
225{{Macro "driver.C++.DefineProcHookType"}}
226
Chia-I Wucc5e2762016-03-24 13:01:16 +0800227struct InstanceDriverTable {
228 // clang-format off
229 {{range $f := AllCommands $}}
230 {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}}
231 {{Macro "C++.DeclareTableEntry" $f}};
232 {{end}}
233 {{end}}
234 // clang-format on
235};
236
237struct DeviceDriverTable {
238 // clang-format off
239 {{range $f := AllCommands $}}
240 {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}}
241 {{Macro "C++.DeclareTableEntry" $f}};
242 {{end}}
243 {{end}}
244 // clang-format on
245};
246
Chia-I Wueb7db122016-03-24 09:11:06 +0800247const ProcHook* GetProcHook(const char* name);
248ProcHook::Extension GetProcHookExtension(const char* name);
249
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800250bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc,
251 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions);
252bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc,
253 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions);
Chia-I Wucc5e2762016-03-24 13:01:16 +0800254
Chia-I Wueb7db122016-03-24 09:11:06 +0800255»} // namespace driver
256»} // namespace vulkan
257
258#endif // LIBVULKAN_DRIVER_TABLE_H
259¶{{end}}
260
261
262{{/*
263-------------------------------------------------------------------------------
264 driver_gen.cpp
265-------------------------------------------------------------------------------
266*/}}
267{{define "driver_gen.cpp"}}
268{{Macro "Copyright"}}
269
270// WARNING: This file is generated. See ../README.md for instructions.
271
272#include <string.h>
273#include <algorithm>
274#include <log/log.h>
275
276#include "driver.h"
Chia-I Wueb7db122016-03-24 09:11:06 +0800277
278namespace vulkan
279namespace driver
280
281namespace
282
283// clang-format off
284
285{{range $f := AllCommands $}}
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800286 {{Macro "driver.C++.DefineProcHookStub" $f}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800287{{end}}
288// clang-format on
289
290const ProcHook g_proc_hooks[] = {
291 // clang-format off
292 {{range $f := SortBy (AllCommands $) "FunctionName"}}
293 {{if (Macro "driver.IsIntercepted" $f)}}
294 {{ if (Macro "IsGloballyDispatched" $f)}}
295 {{Macro "driver.C++.DefineGlobalProcHook" $f}}
296 {{else if (Macro "IsInstanceDispatched" $f)}}
297 {{Macro "driver.C++.DefineInstanceProcHook" $f}}
298 {{else if (Macro "IsDeviceDispatched" $f)}}
299 {{Macro "driver.C++.DefineDeviceProcHook" $f}}
300 {{end}}
301 {{end}}
302 {{end}}
303 // clang-format on
304};
305
306»} // anonymous
307
308const ProcHook* GetProcHook(const char* name) {
309 const auto& begin = g_proc_hooks;
310 const auto& end = g_proc_hooks +
311 sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
312 const auto hook = std::lower_bound(begin, end, name,
313 [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
314 return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
315}
316
317ProcHook::Extension GetProcHookExtension(const char* name) {
318 {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
319 // clang-format off
320 {{range $e := $exts}}
321 if (strcmp(name, "{{$e}}") == 0) return ProcHook::{{TrimPrefix "VK_" $e}};
322 {{end}}
323 // clang-format on
324 return ProcHook::EXTENSION_UNKNOWN;
325}
326
Chia-I Wucc5e2762016-03-24 13:01:16 +0800327{{Macro "C++.DefineInitProcMacro" "driver"}}
328
329{{Macro "driver.C++.DefineInitProcExtMacro"}}
330
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800331bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc,
332 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800333{
334 auto& data = GetData(instance);
335 bool success = true;
336
337 // clang-format off
338 {{range $f := AllCommands $}}
339 {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}}
340 {{Macro "C++.InitProc" $f}}
341 {{end}}
342 {{end}}
343 // clang-format on
344
345 return success;
346}
347
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800348bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc,
349 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800350{
351 auto& data = GetData(dev);
352 bool success = true;
353
354 // clang-format off
355 {{range $f := AllCommands $}}
356 {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}}
357 {{Macro "C++.InitProc" $f}}
358 {{end}}
359 {{end}}
360 // clang-format on
361
362 return success;
363}
364
Chia-I Wueb7db122016-03-24 09:11:06 +0800365»} // namespace driver
366»} // namespace vulkan
367
368// clang-format on
369¶{{end}}
370
371
372{{/*
Chia-I Wu0c203242016-03-15 13:44:51 +0800373------------------------------------------------------------------------------
Chia-I Wucc5e2762016-03-24 13:01:16 +0800374 Emits a declaration of a dispatch/driver table entry.
Chia-I Wu0c203242016-03-15 13:44:51 +0800375------------------------------------------------------------------------------
376*/}}
Chia-I Wucc5e2762016-03-24 13:01:16 +0800377{{define "C++.DeclareTableEntry"}}
Chia-I Wu0c203242016-03-15 13:44:51 +0800378 {{AssertType $ "Function"}}
379
380 {{Macro "FunctionPtrName" $}} {{Macro "BaseName" $}}
381{{end}}
382
383
384{{/*
385-------------------------------------------------------------------------------
Chia-I Wucc5e2762016-03-24 13:01:16 +0800386 Emits INIT_PROC macro.
Chia-I Wu0c203242016-03-15 13:44:51 +0800387-------------------------------------------------------------------------------
388*/}}
Chia-I Wucc5e2762016-03-24 13:01:16 +0800389{{define "C++.DefineInitProcMacro"}}
Chia-I Wu0c203242016-03-15 13:44:51 +0800390 #define UNLIKELY(expr) __builtin_expect((expr), 0)
391
392 #define INIT_PROC(obj, proc) do { \
393 data.{{$}}.proc = reinterpret_cast<PFN_vk ## proc>( \
394 get_proc(obj, "vk" # proc)); \
395 if (UNLIKELY(!data.{{$}}.proc)) { \
396 ALOGE("missing " # obj " proc: vk" # proc); \
397 success = false; \
398 } \
399 } while(0)
Chia-I Wu0c203242016-03-15 13:44:51 +0800400{{end}}
401
402
403{{/*
404-------------------------------------------------------------------------------
405 Emits code to invoke INIT_PROC or INIT_PROC_EXT.
406-------------------------------------------------------------------------------
407*/}}
408{{define "C++.InitProc"}}
409 {{AssertType $ "Function"}}
410
411 {{$ext := GetAnnotation $ "extension"}}
412 {{if $ext}}
413 INIT_PROC_EXT({{Macro "BaseName" $ext}}, §
414 {{else}}
415 INIT_PROC
416 {{end}}
417
418 {{if (Macro "IsInstanceDispatched" $)}}
419 instance, §
420 {{else}}
421 dev, §
422 {{end}}
423
424 {{Macro "BaseName" $}});
425{{end}}
426
427
428{{/*
429------------------------------------------------------------------------------
430 Emits true if a function is exported and instance-dispatched.
431------------------------------------------------------------------------------
432*/}}
433{{define "api.IsInstanceDispatchTableEntry"}}
434 {{AssertType $ "Function"}}
435
436 {{if and (Macro "IsFunctionExported" $) (Macro "IsInstanceDispatched" $)}}
437 true
438 {{end}}
439{{end}}
440
441
442{{/*
443------------------------------------------------------------------------------
444 Emits true if a function is exported and device-dispatched.
445------------------------------------------------------------------------------
446*/}}
447{{define "api.IsDeviceDispatchTableEntry"}}
448 {{AssertType $ "Function"}}
449
450 {{if and (Macro "IsFunctionExported" $) (Macro "IsDeviceDispatched" $)}}
451 true
452 {{end}}
453{{end}}
454
455
456{{/*
457------------------------------------------------------------------------------
458 Emits true if a function is intercepted by vulkan::api.
459------------------------------------------------------------------------------
460*/}}
461{{define "api.IsIntercepted"}}
462 {{AssertType $ "Function"}}
463
464 {{if (Macro "IsFunctionSupported" $)}}
465 {{/* Global functions cannot be dispatched at all */}}
466 {{ if (Macro "IsGloballyDispatched" $)}}true
467
468 {{/* VkPhysicalDevice functions that manage device layers */}}
469 {{else if eq $.Name "vkCreateDevice"}}true
470 {{else if eq $.Name "vkEnumerateDeviceLayerProperties"}}true
471 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
472
473 {{/* Destroy functions of dispatchable objects */}}
474 {{else if eq $.Name "vkDestroyInstance"}}true
475 {{else if eq $.Name "vkDestroyDevice"}}true
476
477 {{end}}
478 {{end}}
479{{end}}
480
481
482{{/*
Chia-I Wucc5e2762016-03-24 13:01:16 +0800483-------------------------------------------------------------------------------
484 Emits INIT_PROC_EXT macro for vulkan::api.
485-------------------------------------------------------------------------------
486*/}}
487{{define "api.C++.DefineInitProcExtMacro"}}
Chia-I Wu8925efd2016-04-13 15:13:21 +0800488 // Exported extension functions may be invoked even when their extensions
489 // are disabled. Dispatch to stubs when that happens.
Chia-I Wucc5e2762016-03-24 13:01:16 +0800490 #define INIT_PROC_EXT(ext, obj, proc) do { \
Chia-I Wu8925efd2016-04-13 15:13:21 +0800491 if (extensions[driver::ProcHook::ext]) \
492 INIT_PROC(obj, proc); \
493 else \
494 data.dispatch.proc = disabled ## proc; \
Chia-I Wucc5e2762016-03-24 13:01:16 +0800495 } while(0)
496{{end}}
497
498
499{{/*
Chia-I Wu8925efd2016-04-13 15:13:21 +0800500-------------------------------------------------------------------------------
501 Emits a stub for an exported extension function.
502-------------------------------------------------------------------------------
503*/}}
504{{define "api.C++.DefineExtensionStub"}}
505 {{AssertType $ "Function"}}
506
507 {{$ext := GetAnnotation $ "extension"}}
508 {{if and $ext (Macro "IsFunctionExported" $)}}
509 {{$ext_name := index $ext.Arguments 0}}
510
511 {{$base := (Macro "BaseName" $)}}
Chia-I Wu8925efd2016-04-13 15:13:21 +0800512
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800513 {{$p0 := (index $.CallParameters 0)}}
514 {{$ptail := (Tail 1 $.CallParameters)}}
515
516 {{$first_type := (Macro "Parameter" $p0)}}
517 {{$tail_types := (ForEach $ptail "ParameterType" | JoinWith ", ")}}
518
519 VKAPI_ATTR {{Node "Type" $.Return}} disabled{{$base}}({{$first_type}}, {{$tail_types}}) {
520 driver::Logger({{$p0.Name}}).Err({{$p0.Name}}, §
521 "{{$ext_name}} not enabled. Exported {{$.Name}} not executed.");
Chia-I Wu8925efd2016-04-13 15:13:21 +0800522 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
523 }
524
525 {{end}}
526{{end}}
527
528
529{{/*
Chia-I Wu0c203242016-03-15 13:44:51 +0800530------------------------------------------------------------------------------
531 Emits code for vkGetInstanceProcAddr for function interception.
532------------------------------------------------------------------------------
533*/}}
534{{define "api.C++.InterceptInstanceProcAddr"}}
535 {{AssertType $ "API"}}
536
537 // global functions
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800538 if (instance == VK_NULL_HANDLE) {
Chia-I Wu0c203242016-03-15 13:44:51 +0800539 {{range $f := AllCommands $}}
540 {{if (Macro "IsGloballyDispatched" $f)}}
541 if (strcmp(pName, "{{$f.Name}}") == 0) return §
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800542 reinterpret_cast<PFN_vkVoidFunction>({{Macro "BaseName" $f}});
Chia-I Wu0c203242016-03-15 13:44:51 +0800543 {{end}}
544 {{end}}
545
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800546 ALOGE("invalid vkGetInstanceProcAddr(VK_NULL_HANDLE, \"%s\") call", pName);
Chia-I Wu0c203242016-03-15 13:44:51 +0800547 return nullptr;
548 }
549
550 static const struct Hook {
551 const char* name;
552 PFN_vkVoidFunction proc;
553 } hooks[] = {
554 {{range $f := SortBy (AllCommands $) "FunctionName"}}
555 {{if (Macro "IsFunctionExported" $f)}}
556 {{/* hide global functions */}}
557 {{if (Macro "IsGloballyDispatched" $f)}}
558 { "{{$f.Name}}", nullptr },
559
560 {{/* redirect intercepted functions */}}
561 {{else if (Macro "api.IsIntercepted" $f)}}
562 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>(§
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800563 {{Macro "BaseName" $f}}) },
Chia-I Wu0c203242016-03-15 13:44:51 +0800564
565 {{/* redirect vkGetInstanceProcAddr to itself */}}
566 {{else if eq $f.Name "vkGetInstanceProcAddr"}}
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800567 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{Macro "BaseName" $f}}) },
Chia-I Wu0c203242016-03-15 13:44:51 +0800568
569 {{/* redirect device functions to themselves as a workaround for
570 layers that do not intercept in their vkGetInstanceProcAddr */}}
571 {{else if (Macro "IsDeviceDispatched" $f)}}
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800572 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{Macro "BaseName" $f}}) },
Chia-I Wu0c203242016-03-15 13:44:51 +0800573
574 {{end}}
575 {{end}}
576 {{end}}
577 };
578 // clang-format on
579 constexpr size_t count = sizeof(hooks) / sizeof(hooks[0]);
580 auto hook = std::lower_bound(
581 hooks, hooks + count, pName,
582 [](const Hook& h, const char* n) { return strcmp(h.name, n) < 0; });
583 if (hook < hooks + count && strcmp(hook->name, pName) == 0) {
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800584 if (!hook->proc) {
585 vulkan::driver::Logger(instance).Err(
586 instance, "invalid vkGetInstanceProcAddr(%p, \"%s\") call",
587 instance, pName);
588 }
Chia-I Wu0c203242016-03-15 13:44:51 +0800589 return hook->proc;
590 }
591 // clang-format off
592
593{{end}}
594
595
596{{/*
597------------------------------------------------------------------------------
598 Emits code for vkGetDeviceProcAddr for function interception.
599------------------------------------------------------------------------------
600*/}}
601{{define "api.C++.InterceptDeviceProcAddr"}}
602 {{AssertType $ "API"}}
603
604 if (device == VK_NULL_HANDLE) {
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800605 ALOGE("invalid vkGetDeviceProcAddr(VK_NULL_HANDLE, ...) call");
Chia-I Wu0c203242016-03-15 13:44:51 +0800606 return nullptr;
607 }
608
609 static const char* const known_non_device_names[] = {
610 {{range $f := SortBy (AllCommands $) "FunctionName"}}
611 {{if (Macro "IsFunctionSupported" $f)}}
612 {{if not (Macro "IsDeviceDispatched" $f)}}
613 "{{$f.Name}}",
614 {{end}}
615 {{end}}
616 {{end}}
617 };
618 // clang-format on
619 constexpr size_t count = sizeof(known_non_device_names) /
620 sizeof(known_non_device_names[0]);
621 if (!pName ||
622 std::binary_search(
623 known_non_device_names, known_non_device_names + count, pName,
624 [](const char* a, const char* b) { return (strcmp(a, b) < 0); })) {
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800625 vulkan::driver::Logger(device).Err
626 device, "invalid vkGetDeviceProcAddr(%p, \"%s\") call", device
627 (pName) ? pName : "(null)");
Chia-I Wu0c203242016-03-15 13:44:51 +0800628 return nullptr;
629 }
630 // clang-format off
631
Chia-I Wuc56603e2016-04-12 11:16:17 +0800632 {{range $f := AllCommands $}}
633 {{if (Macro "IsDeviceDispatched" $f)}}
634 {{ if (Macro "api.IsIntercepted" $f)}}
635 if (strcmp(pName, "{{$f.Name}}") == 0) return §
636 reinterpret_cast<PFN_vkVoidFunction>(§
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800637 {{Macro "BaseName" $f}});
Chia-I Wuc56603e2016-04-12 11:16:17 +0800638 {{else if eq $f.Name "vkGetDeviceProcAddr"}}
639 if (strcmp(pName, "{{$f.Name}}") == 0) return §
640 reinterpret_cast<PFN_vkVoidFunction>(§
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800641 {{Macro "BaseName" $f}});
Chia-I Wuc56603e2016-04-12 11:16:17 +0800642 {{end}}
643 {{end}}
644 {{end}}
645
Chia-I Wu0c203242016-03-15 13:44:51 +0800646{{end}}
647
648
649{{/*
650------------------------------------------------------------------------------
651 Emits code to dispatch a function.
652------------------------------------------------------------------------------
653*/}}
654{{define "api.C++.Dispatch"}}
655 {{AssertType $ "Function"}}
Chia-I Wu0c203242016-03-15 13:44:51 +0800656 {{if (Macro "api.IsIntercepted" $)}}
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800657 {{Error "$.Name should not be generated"}}
Chia-I Wu0c203242016-03-15 13:44:51 +0800658 {{end}}
659
Chia-I Wu3e654dc2016-05-20 16:15:06 +0800660 {{if not (IsVoid $.Return.Type)}}return §{{end}}
661
662 {{$p0 := index $.CallParameters 0}}
663 GetData({{$p0.Name}}).dispatch
Chia-I Wu0c203242016-03-15 13:44:51 +0800664 {{Macro "BaseName" $}}({{Macro "Arguments" $}});
665{{end}}
666
667
668{{/*
Chia-I Wueb7db122016-03-24 09:11:06 +0800669------------------------------------------------------------------------------
670 Emits a list of extensions intercepted by vulkan::driver.
671------------------------------------------------------------------------------
672*/}}
673{{define "driver.InterceptedExtensions"}}
674VK_ANDROID_native_buffer
675VK_EXT_debug_report
676VK_KHR_android_surface
677VK_KHR_surface
678VK_KHR_swapchain
679{{end}}
680
681
682{{/*
683------------------------------------------------------------------------------
684 Emits true if an extension is intercepted by vulkan::driver.
685------------------------------------------------------------------------------
686*/}}
687{{define "driver.IsExtensionIntercepted"}}
688 {{$ext_name := index $.Arguments 0}}
689 {{$filters := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
690
691 {{range $f := $filters}}
692 {{if eq $ext_name $f}}true{{end}}
693 {{end}}
694{{end}}
695
696
697{{/*
698------------------------------------------------------------------------------
699 Emits true if a function is intercepted by vulkan::driver.
700------------------------------------------------------------------------------
701*/}}
702{{define "driver.IsIntercepted"}}
703 {{AssertType $ "Function"}}
704
705 {{if (Macro "IsFunctionSupported" $)}}
706 {{/* Create functions of dispatchable objects */}}
707 {{ if eq $.Name "vkCreateInstance"}}true
708 {{else if eq $.Name "vkCreateDevice"}}true
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800709 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true
Chia-I Wueb7db122016-03-24 09:11:06 +0800710 {{else if eq $.Name "vkGetDeviceQueue"}}true
711 {{else if eq $.Name "vkAllocateCommandBuffers"}}true
712
713 {{/* Destroy functions of dispatchable objects */}}
714 {{else if eq $.Name "vkDestroyInstance"}}true
715 {{else if eq $.Name "vkDestroyDevice"}}true
716
717 {{/* Enumeration of extensions */}}
718 {{else if eq $.Name "vkEnumerateInstanceExtensionProperties"}}true
719 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
720
Chia-I Wueb7db122016-03-24 09:11:06 +0800721 {{else if eq $.Name "vkGetInstanceProcAddr"}}true
722 {{else if eq $.Name "vkGetDeviceProcAddr"}}true
723
724 {{end}}
725
726 {{$ext := GetAnnotation $ "extension"}}
727 {{if $ext}}
728 {{Macro "driver.IsExtensionIntercepted" $ext}}
729 {{end}}
730
731 {{end}}
732{{end}}
733
734
735{{/*
736------------------------------------------------------------------------------
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800737 Emits true if a function needs a ProcHook stub.
Chia-I Wueb7db122016-03-24 09:11:06 +0800738------------------------------------------------------------------------------
739*/}}
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800740{{define "driver.NeedProcHookStub"}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800741 {{AssertType $ "Function"}}
742
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800743 {{if and (Macro "driver.IsIntercepted" $) (Macro "IsDeviceDispatched" $)}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800744 {{$ext := GetAnnotation $ "extension"}}
745 {{if $ext}}
746 {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}}
747 {{end}}
748 {{end}}
749{{end}}
750
751
752{{/*
753-------------------------------------------------------------------------------
754 Emits definition of struct ProcHook.
755-------------------------------------------------------------------------------
756*/}}
757{{define "driver.C++.DefineProcHookType"}}
758 struct ProcHook {
759 enum Type {
760 GLOBAL,
761 INSTANCE,
762 DEVICE,
763 };
764
765 enum Extension {
766 {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
767 {{range $e := $exts}}
768 {{TrimPrefix "VK_" $e}},
769 {{end}}
770
771 EXTENSION_CORE, // valid bit
772 EXTENSION_COUNT,
773 EXTENSION_UNKNOWN,
774 };
775
776 const char* name;
777 Type type;
778 Extension extension;
779
780 PFN_vkVoidFunction proc;
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800781 PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks
Chia-I Wueb7db122016-03-24 09:11:06 +0800782 };
783{{end}}
784
785
786{{/*
787-------------------------------------------------------------------------------
Chia-I Wucc5e2762016-03-24 13:01:16 +0800788 Emits INIT_PROC_EXT macro for vulkan::driver.
789-------------------------------------------------------------------------------
790*/}}
791{{define "driver.C++.DefineInitProcExtMacro"}}
792 #define INIT_PROC_EXT(ext, obj, proc) do { \
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800793 if (extensions[ProcHook::ext]) \
Chia-I Wucc5e2762016-03-24 13:01:16 +0800794 INIT_PROC(obj, proc); \
795 } while(0)
796{{end}}
797
798
799{{/*
800-------------------------------------------------------------------------------
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800801 Emits a stub for ProcHook::checked_proc.
Chia-I Wueb7db122016-03-24 09:11:06 +0800802-------------------------------------------------------------------------------
803*/}}
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800804{{define "driver.C++.DefineProcHookStub"}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800805 {{AssertType $ "Function"}}
806
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800807 {{if (Macro "driver.NeedProcHookStub" $)}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800808 {{$ext := GetAnnotation $ "extension"}}
809 {{$ext_name := index $ext.Arguments 0}}
810
811 {{$base := (Macro "BaseName" $)}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800812
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800813 VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) {
814 {{$p0 := index $.CallParameters 0}}
815 {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800816
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800817 if (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) {
818 {{if not (IsVoid $.Return.Type)}}return §{{end}}
819 {{$base}}({{Macro "Arguments" $}});
820 } else {
Chia-I Wu5beb2ac2016-05-04 16:37:23 +0800821 Logger({{$p0.Name}}).Err({{$p0.Name}}, "{{$ext_name}} not enabled. {{$.Name}} not executed.");
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800822 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
Chia-I Wueb7db122016-03-24 09:11:06 +0800823 }
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800824 }
Chia-I Wueb7db122016-03-24 09:11:06 +0800825
826 {{end}}
827{{end}}
828
829
830{{/*
831-------------------------------------------------------------------------------
832 Emits definition of a global ProcHook.
833-------------------------------------------------------------------------------
834*/}}
835{{define "driver.C++.DefineGlobalProcHook"}}
836 {{AssertType $ "Function"}}
837
838 {{$base := (Macro "BaseName" $)}}
839
840 {{$ext := GetAnnotation $ "extension"}}
841 {{if $ext}}
842 {{Error "invalid global extension"}}
843 {{end}}
844
845 {
846 "{{$.Name}}",
847 ProcHook::GLOBAL,
848 ProcHook::EXTENSION_CORE,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800849 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
Chia-I Wueb7db122016-03-24 09:11:06 +0800850 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800851 },
852{{end}}
853
854
855{{/*
856-------------------------------------------------------------------------------
857 Emits definition of an instance ProcHook.
858-------------------------------------------------------------------------------
859*/}}
860{{define "driver.C++.DefineInstanceProcHook"}}
861 {{AssertType $ "Function"}}
862
863 {{$base := (Macro "BaseName" $)}}
864
865 {
866 "{{$.Name}}",
867 ProcHook::INSTANCE,
868
869 {{$ext := GetAnnotation $ "extension"}}
870 {{if $ext}}
871 ProcHook::{{Macro "BaseName" $ext}},
872
873 {{if (Macro "IsExtensionInternal" $ext)}}
874 nullptr,
875 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800876 {{else}}
Chia-I Wu62262232016-03-26 07:06:44 +0800877 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
Chia-I Wueb7db122016-03-24 09:11:06 +0800878 nullptr,
879 {{end}}
880 {{else}}
881 ProcHook::EXTENSION_CORE,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800882 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
Chia-I Wueb7db122016-03-24 09:11:06 +0800883 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800884 {{end}}
885 },
886{{end}}
887
888
889{{/*
890-------------------------------------------------------------------------------
891 Emits definition of a device ProcHook.
892-------------------------------------------------------------------------------
893*/}}
894{{define "driver.C++.DefineDeviceProcHook"}}
895 {{AssertType $ "Function"}}
896
897 {{$base := (Macro "BaseName" $)}}
898
899 {
900 "{{$.Name}}",
901 ProcHook::DEVICE,
902
903 {{$ext := GetAnnotation $ "extension"}}
904 {{if $ext}}
905 ProcHook::{{Macro "BaseName" $ext}},
906
907 {{if (Macro "IsExtensionInternal" $ext)}}
908 nullptr,
909 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800910 {{else}}
Chia-I Wu62262232016-03-26 07:06:44 +0800911 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
Chia-I Wueb7db122016-03-24 09:11:06 +0800912 reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}),
913 {{end}}
914 {{else}}
Chia-I Wu4901db72016-03-24 16:38:58 +0800915 ProcHook::EXTENSION_CORE,
916 reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
917 nullptr,
Chia-I Wueb7db122016-03-24 09:11:06 +0800918 {{end}}
919 },
920{{end}}
921
922
923{{/*
Chia-I Wu0c203242016-03-15 13:44:51 +0800924-------------------------------------------------------------------------------
Chia-I Wucc5e2762016-03-24 13:01:16 +0800925 Emits true if a function is needed by vulkan::driver.
926-------------------------------------------------------------------------------
927*/}}
928{{define "driver.IsDriverTableEntry"}}
929 {{AssertType $ "Function"}}
930
931 {{if (Macro "IsFunctionSupported" $)}}
932 {{/* Create functions of dispatchable objects */}}
933 {{ if eq $.Name "vkCreateDevice"}}true
934 {{else if eq $.Name "vkGetDeviceQueue"}}true
935 {{else if eq $.Name "vkAllocateCommandBuffers"}}true
936
937 {{/* Destroy functions of dispatchable objects */}}
938 {{else if eq $.Name "vkDestroyInstance"}}true
939 {{else if eq $.Name "vkDestroyDevice"}}true
940
Chia-I Wu4901db72016-03-24 16:38:58 +0800941 {{else if eq $.Name "vkEnumerateDeviceLayerProperties"}}true
942
Chia-I Wucc5e2762016-03-24 13:01:16 +0800943 {{/* Enumeration of extensions */}}
944 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
945
946 {{/* We cache physical devices in loader.cpp */}}
947 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true
948
949 {{else if eq $.Name "vkGetInstanceProcAddr"}}true
950 {{else if eq $.Name "vkGetDeviceProcAddr"}}true
951
952 {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}}
953 {{else if eq $.Name "vkCreateImage"}}true
954 {{else if eq $.Name "vkDestroyImage"}}true
955
956 {{end}}
957
958 {{$ext := GetAnnotation $ "extension"}}
959 {{if $ext}}
960 {{$ext_name := index $ext.Arguments 0}}
961 {{ if eq $ext_name "VK_ANDROID_native_buffer"}}true
962 {{else if eq $ext_name "VK_EXT_debug_report"}}true
963 {{end}}
964 {{end}}
965 {{end}}
966{{end}}
967
968
969{{/*
970------------------------------------------------------------------------------
971 Emits true if an instance-dispatched function is needed by vulkan::driver.
972------------------------------------------------------------------------------
973*/}}
974{{define "driver.IsInstanceDriverTableEntry"}}
975 {{AssertType $ "Function"}}
976
977 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}}
978 true
979 {{end}}
980{{end}}
981
982
983{{/*
984------------------------------------------------------------------------------
985 Emits true if a device-dispatched function is needed by vulkan::driver.
986------------------------------------------------------------------------------
987*/}}
988{{define "driver.IsDeviceDriverTableEntry"}}
989 {{AssertType $ "Function"}}
990
991 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}}
992 true
993 {{end}}
994{{end}}
995
996
997{{/*
998-------------------------------------------------------------------------------
Chia-I Wu0c203242016-03-15 13:44:51 +0800999 Emits a function/extension name without the "vk"/"VK_" prefix.
1000-------------------------------------------------------------------------------
1001*/}}
1002{{define "BaseName"}}
1003 {{ if IsFunction $}}{{TrimPrefix "vk" $.Name}}
1004 {{else if eq $.Name "extension"}}{{TrimPrefix "VK_" (index $.Arguments 0)}}
1005 {{else}}{{Error "invalid use of BaseName"}}
1006 {{end}}
1007{{end}}
1008
1009
1010{{/*
1011-------------------------------------------------------------------------------
1012 Emits a comma-separated list of C parameter names for the given command.
1013-------------------------------------------------------------------------------
1014*/}}
1015{{define "Arguments"}}
1016 {{AssertType $ "Function"}}
1017
1018 {{ForEach $.CallParameters "ParameterName" | JoinWith ", "}}
1019{{end}}
1020
1021
1022{{/*
1023------------------------------------------------------------------------------
1024------------------------------------------------------------------------------
1025*/}}
1026{{define "IsGloballyDispatched"}}
1027 {{AssertType $ "Function"}}
1028 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Global")}}
1029 true
1030 {{end}}
1031{{end}}
1032
1033
1034{{/*
1035------------------------------------------------------------------------------
1036 Emit "true" for supported functions that undergo table dispatch. Only global
1037 functions and functions handled in the loader top without calling into
1038 lower layers are not dispatched.
1039------------------------------------------------------------------------------
1040*/}}
1041{{define "IsInstanceDispatched"}}
1042 {{AssertType $ "Function"}}
1043 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}}
1044 true
1045 {{end}}
1046{{end}}
1047
1048
1049{{/*
1050------------------------------------------------------------------------------
1051 Emit "true" for supported functions that can have device-specific dispatch.
1052------------------------------------------------------------------------------
1053*/}}
1054{{define "IsDeviceDispatched"}}
1055 {{AssertType $ "Function"}}
1056 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Device")}}
1057 true
1058 {{end}}
1059{{end}}
1060
1061
1062{{/*
1063------------------------------------------------------------------------------
1064 Emit "true" if a function is core or from a supportable extension.
1065------------------------------------------------------------------------------
1066*/}}
1067{{define "IsFunctionSupported"}}
1068 {{AssertType $ "Function"}}
1069 {{if not (GetAnnotation $ "pfn")}}
1070 {{$ext := GetAnnotation $ "extension"}}
1071 {{if not $ext}}true
1072 {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true
1073 {{end}}
1074 {{end}}
1075{{end}}
1076
1077
1078{{/*
1079------------------------------------------------------------------------------
1080 Decides whether a function should be exported from the Android Vulkan
1081 library. Functions in the core API and in loader extensions are exported.
1082------------------------------------------------------------------------------
1083*/}}
1084{{define "IsFunctionExported"}}
1085 {{AssertType $ "Function"}}
1086
1087 {{if (Macro "IsFunctionSupported" $)}}
1088 {{$ext := GetAnnotation $ "extension"}}
1089 {{if $ext}}
1090 {{Macro "IsExtensionExported" $ext}}
1091 {{else}}
1092 true
1093 {{end}}
1094 {{end}}
1095{{end}}
1096
1097
1098{{/*
1099------------------------------------------------------------------------------
1100 Emit "true" if an extension is unsupportable on Android.
1101------------------------------------------------------------------------------
1102*/}}
1103{{define "IsExtensionBlacklisted"}}
1104 {{$ext := index $.Arguments 0}}
1105 {{ if eq $ext "VK_KHR_display"}}true
1106 {{else if eq $ext "VK_KHR_display_swapchain"}}true
1107 {{else if eq $ext "VK_KHR_xlib_surface"}}true
1108 {{else if eq $ext "VK_KHR_xcb_surface"}}true
1109 {{else if eq $ext "VK_KHR_wayland_surface"}}true
1110 {{else if eq $ext "VK_KHR_mir_surface"}}true
1111 {{else if eq $ext "VK_KHR_win32_surface"}}true
1112 {{end}}
1113{{end}}
1114
1115
1116{{/*
1117------------------------------------------------------------------------------
1118 Reports whether an extension is implemented entirely by the loader,
1119 so drivers should not enumerate it.
1120------------------------------------------------------------------------------
1121*/}}
1122{{define "IsExtensionExported"}}
1123 {{$ext := index $.Arguments 0}}
1124 {{ if eq $ext "VK_KHR_surface"}}true
1125 {{else if eq $ext "VK_KHR_swapchain"}}true
1126 {{else if eq $ext "VK_KHR_android_surface"}}true
1127 {{end}}
1128{{end}}
Chia-I Wueb7db122016-03-24 09:11:06 +08001129
1130
1131{{/*
1132------------------------------------------------------------------------------
1133 Reports whether an extension is internal to the loader and drivers,
1134 so the loader should not enumerate it.
1135------------------------------------------------------------------------------
1136*/}}
1137{{define "IsExtensionInternal"}}
1138 {{$ext := index $.Arguments 0}}
1139 {{ if eq $ext "VK_ANDROID_native_buffer"}}true
1140 {{end}}
1141{{end}}