code-generator.tmpl revision 36cc00a1739f7d926cc20671ae9900a5460dd6ae
1{{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"}} 24{{$ | 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"}} 26 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 <bitset> 41#include <vulkan/vulkan.h> 42#include "driver_gen.h" 43¶ 44namespace vulkan {« 45namespace api {« 46¶ 47struct InstanceDispatchTable { 48 // clang-format off 49 {{range $f := AllCommands $}} 50 {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}} 51 {{Macro "C++.DeclareTableEntry" $f}}; 52 {{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)}} 61 {{Macro "C++.DeclareTableEntry" $f}}; 62 {{end}} 63 {{end}} 64 // clang-format on 65}; 66¶ 67bool 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); 75¶ 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¶ 102{{Macro "C++.DefineInitProcMacro" "dispatch"}} 103¶ 104{{Macro "api.C++.DefineInitProcExtMacro"}} 105¶ 106namespace {« 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) { 121 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¶ 135bool InitDispatchTable( 136 VkDevice dev, 137 PFN_vkGetDeviceProcAddr get_proc, 138 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions) { 139 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{{/* 179------------------------------------------------------------------------------- 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¶ 191#include <bitset> 192#include <vulkan/vulkan.h> 193#include <vulkan/vk_android_native_buffer.h> 194¶ 195namespace vulkan {« 196namespace driver {« 197¶ 198{{Macro "driver.C++.DefineProcHookType"}} 199¶ 200struct 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¶ 220const ProcHook* GetProcHook(const char* name); 221ProcHook::Extension GetProcHookExtension(const char* name); 222¶ 223bool 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); 227¶ 228»} // 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" 250¶ 251namespace vulkan {« 252namespace driver {« 253¶ 254namespace {« 255¶ 256// clang-format off 257¶ 258{{range $f := AllCommands $}} 259 {{Macro "driver.C++.DefineProcHookStub" $f}} 260{{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¶ 300{{Macro "C++.DefineInitProcMacro" "driver"}} 301¶ 302{{Macro "driver.C++.DefineInitProcExtMacro"}} 303¶ 304bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, 305 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions) 306{ 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¶ 321bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc, 322 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions) 323{ 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¶ 338»} // namespace driver 339»} // namespace vulkan 340¶ 341// clang-format on 342¶{{end}} 343 344 345{{/* 346------------------------------------------------------------------------------ 347 Emits a declaration of a dispatch/driver table entry. 348------------------------------------------------------------------------------ 349*/}} 350{{define "C++.DeclareTableEntry"}} 351 {{AssertType $ "Function"}} 352 353 {{Macro "FunctionPtrName" $}} {{Macro "BaseName" $}} 354{{end}} 355 356 357{{/* 358------------------------------------------------------------------------------- 359 Emits INIT_PROC macro. 360------------------------------------------------------------------------------- 361*/}} 362{{define "C++.DefineInitProcMacro"}} 363 #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) 373{{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{{/* 456------------------------------------------------------------------------------- 457 Emits INIT_PROC_EXT macro for vulkan::api. 458------------------------------------------------------------------------------- 459*/}} 460{{define "api.C++.DefineInitProcExtMacro"}} 461 // Exported extension functions may be invoked even when their extensions 462 // are disabled. Dispatch to stubs when that happens. 463 #define INIT_PROC_EXT(ext, obj, proc) do { \ 464 if (extensions[driver::ProcHook::ext]) \ 465 INIT_PROC(obj, proc); \ 466 else \ 467 data.dispatch.proc = disabled ## proc; \ 468 } while(0) 469{{end}} 470 471 472{{/* 473------------------------------------------------------------------------------- 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" $)}} 485 {{$unnamed_params := (ForEach $.CallParameters "ParameterType" | JoinWith ", ")}} 486 487 VKAPI_ATTR {{Node "Type" $.Return}} disabled{{$base}}({{$unnamed_params}}) { 488 ALOGE("{{$ext_name}} not enabled. {{$.Name}} not executed."); 489 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}} 490 } 491 ¶ 492 {{end}} 493{{end}} 494 495 496{{/* 497------------------------------------------------------------------------------ 498 Emits code for vkGetInstanceProcAddr for function interception. 499------------------------------------------------------------------------------ 500*/}} 501{{define "api.C++.InterceptInstanceProcAddr"}} 502 {{AssertType $ "API"}} 503 504 // global functions 505 if (!instance) { 506 {{range $f := AllCommands $}} 507 {{if (Macro "IsGloballyDispatched" $f)}} 508 if (strcmp(pName, "{{$f.Name}}") == 0) return § 509 reinterpret_cast<PFN_vkVoidFunction>(§ 510 vulkan::api::{{Macro "BaseName" $f}}); 511 {{end}} 512 {{end}} 513 ¶ 514 ALOGE("vkGetInstanceProcAddr called with %s without instance", pName); 515 return nullptr; 516 } 517 ¶ 518 static const struct Hook { 519 const char* name; 520 PFN_vkVoidFunction proc; 521 } hooks[] = { 522 {{range $f := SortBy (AllCommands $) "FunctionName"}} 523 {{if (Macro "IsFunctionExported" $f)}} 524 {{/* hide global functions */}} 525 {{if (Macro "IsGloballyDispatched" $f)}} 526 { "{{$f.Name}}", nullptr }, 527 528 {{/* redirect intercepted functions */}} 529 {{else if (Macro "api.IsIntercepted" $f)}} 530 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>(§ 531 vulkan::api::{{Macro "BaseName" $f}}) }, 532 533 {{/* redirect vkGetInstanceProcAddr to itself */}} 534 {{else if eq $f.Name "vkGetInstanceProcAddr"}} 535 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{$f.Name}}) }, 536 537 {{/* redirect device functions to themselves as a workaround for 538 layers that do not intercept in their vkGetInstanceProcAddr */}} 539 {{else if (Macro "IsDeviceDispatched" $f)}} 540 { "{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>({{$f.Name}}) }, 541 542 {{end}} 543 {{end}} 544 {{end}} 545 }; 546 // clang-format on 547 constexpr size_t count = sizeof(hooks) / sizeof(hooks[0]); 548 auto hook = std::lower_bound( 549 hooks, hooks + count, pName, 550 [](const Hook& h, const char* n) { return strcmp(h.name, n) < 0; }); 551 if (hook < hooks + count && strcmp(hook->name, pName) == 0) { 552 if (!hook->proc) 553 ALOGE("vkGetInstanceProcAddr called with %s with instance", pName); 554 return hook->proc; 555 } 556 // clang-format off 557 ¶ 558{{end}} 559 560 561{{/* 562------------------------------------------------------------------------------ 563 Emits code for vkGetDeviceProcAddr for function interception. 564------------------------------------------------------------------------------ 565*/}} 566{{define "api.C++.InterceptDeviceProcAddr"}} 567 {{AssertType $ "API"}} 568 569 if (device == VK_NULL_HANDLE) { 570 ALOGE("vkGetDeviceProcAddr called with invalid device"); 571 return nullptr; 572 } 573 ¶ 574 static const char* const known_non_device_names[] = { 575 {{range $f := SortBy (AllCommands $) "FunctionName"}} 576 {{if (Macro "IsFunctionSupported" $f)}} 577 {{if not (Macro "IsDeviceDispatched" $f)}} 578 "{{$f.Name}}", 579 {{end}} 580 {{end}} 581 {{end}} 582 }; 583 // clang-format on 584 constexpr size_t count = sizeof(known_non_device_names) / 585 sizeof(known_non_device_names[0]); 586 if (!pName || 587 std::binary_search( 588 known_non_device_names, known_non_device_names + count, pName, 589 [](const char* a, const char* b) { return (strcmp(a, b) < 0); })) { 590 ALOGE("vkGetDeviceProcAddr called with %s", (pName) ? pName : "(null)"); 591 return nullptr; 592 } 593 // clang-format off 594 ¶ 595 {{range $f := AllCommands $}} 596 {{if (Macro "IsDeviceDispatched" $f)}} 597 {{ if (Macro "api.IsIntercepted" $f)}} 598 if (strcmp(pName, "{{$f.Name}}") == 0) return § 599 reinterpret_cast<PFN_vkVoidFunction>(§ 600 vulkan::api::{{Macro "BaseName" $f}}); 601 {{else if eq $f.Name "vkGetDeviceProcAddr"}} 602 if (strcmp(pName, "{{$f.Name}}") == 0) return § 603 reinterpret_cast<PFN_vkVoidFunction>(§ 604 {{$f.Name}}); 605 {{end}} 606 {{end}} 607 {{end}} 608 ¶ 609{{end}} 610 611 612{{/* 613------------------------------------------------------------------------------ 614 Emits code to dispatch a function. 615------------------------------------------------------------------------------ 616*/}} 617{{define "api.C++.Dispatch"}} 618 {{AssertType $ "Function"}} 619 620 {{if (Macro "api.IsIntercepted" $)}}// call into api.cpp{{end}} 621 {{if not (IsVoid $.Return.Type)}}return §{{end}} 622 623 {{if (Macro "api.IsIntercepted" $)}} 624 vulkan::api::§ 625 {{else}} 626 {{$p0 := index $.CallParameters 0}} 627 vulkan::api::GetData({{$p0.Name}}).dispatch.§ 628 {{end}} 629 630 {{Macro "BaseName" $}}({{Macro "Arguments" $}}); 631{{end}} 632 633 634{{/* 635------------------------------------------------------------------------------ 636 Emits a list of extensions intercepted by vulkan::driver. 637------------------------------------------------------------------------------ 638*/}} 639{{define "driver.InterceptedExtensions"}} 640VK_ANDROID_native_buffer 641VK_EXT_debug_report 642VK_KHR_android_surface 643VK_KHR_surface 644VK_KHR_swapchain 645{{end}} 646 647 648{{/* 649------------------------------------------------------------------------------ 650 Emits true if an extension is intercepted by vulkan::driver. 651------------------------------------------------------------------------------ 652*/}} 653{{define "driver.IsExtensionIntercepted"}} 654 {{$ext_name := index $.Arguments 0}} 655 {{$filters := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}} 656 657 {{range $f := $filters}} 658 {{if eq $ext_name $f}}true{{end}} 659 {{end}} 660{{end}} 661 662 663{{/* 664------------------------------------------------------------------------------ 665 Emits true if a function is intercepted by vulkan::driver. 666------------------------------------------------------------------------------ 667*/}} 668{{define "driver.IsIntercepted"}} 669 {{AssertType $ "Function"}} 670 671 {{if (Macro "IsFunctionSupported" $)}} 672 {{/* Create functions of dispatchable objects */}} 673 {{ if eq $.Name "vkCreateInstance"}}true 674 {{else if eq $.Name "vkCreateDevice"}}true 675 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true 676 {{else if eq $.Name "vkGetDeviceQueue"}}true 677 {{else if eq $.Name "vkAllocateCommandBuffers"}}true 678 679 {{/* Destroy functions of dispatchable objects */}} 680 {{else if eq $.Name "vkDestroyInstance"}}true 681 {{else if eq $.Name "vkDestroyDevice"}}true 682 683 {{/* Enumeration of extensions */}} 684 {{else if eq $.Name "vkEnumerateInstanceExtensionProperties"}}true 685 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true 686 687 {{else if eq $.Name "vkGetInstanceProcAddr"}}true 688 {{else if eq $.Name "vkGetDeviceProcAddr"}}true 689 690 {{end}} 691 692 {{$ext := GetAnnotation $ "extension"}} 693 {{if $ext}} 694 {{Macro "driver.IsExtensionIntercepted" $ext}} 695 {{end}} 696 697 {{end}} 698{{end}} 699 700 701{{/* 702------------------------------------------------------------------------------ 703 Emits true if a function needs a ProcHook stub. 704------------------------------------------------------------------------------ 705*/}} 706{{define "driver.NeedProcHookStub"}} 707 {{AssertType $ "Function"}} 708 709 {{if and (Macro "driver.IsIntercepted" $) (Macro "IsDeviceDispatched" $)}} 710 {{$ext := GetAnnotation $ "extension"}} 711 {{if $ext}} 712 {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}} 713 {{end}} 714 {{end}} 715{{end}} 716 717 718{{/* 719------------------------------------------------------------------------------- 720 Emits definition of struct ProcHook. 721------------------------------------------------------------------------------- 722*/}} 723{{define "driver.C++.DefineProcHookType"}} 724 struct ProcHook { 725 enum Type { 726 GLOBAL, 727 INSTANCE, 728 DEVICE, 729 }; 730 731 enum Extension { 732 {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}} 733 {{range $e := $exts}} 734 {{TrimPrefix "VK_" $e}}, 735 {{end}} 736 ¶ 737 EXTENSION_CORE, // valid bit 738 EXTENSION_COUNT, 739 EXTENSION_UNKNOWN, 740 }; 741 ¶ 742 const char* name; 743 Type type; 744 Extension extension; 745 ¶ 746 PFN_vkVoidFunction proc; 747 PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks 748 }; 749{{end}} 750 751 752{{/* 753------------------------------------------------------------------------------- 754 Emits INIT_PROC_EXT macro for vulkan::driver. 755------------------------------------------------------------------------------- 756*/}} 757{{define "driver.C++.DefineInitProcExtMacro"}} 758 #define INIT_PROC_EXT(ext, obj, proc) do { \ 759 if (extensions[ProcHook::ext]) \ 760 INIT_PROC(obj, proc); \ 761 } while(0) 762{{end}} 763 764 765{{/* 766------------------------------------------------------------------------------- 767 Emits a stub for ProcHook::checked_proc. 768------------------------------------------------------------------------------- 769*/}} 770{{define "driver.C++.DefineProcHookStub"}} 771 {{AssertType $ "Function"}} 772 773 {{if (Macro "driver.NeedProcHookStub" $)}} 774 {{$ext := GetAnnotation $ "extension"}} 775 {{$ext_name := index $ext.Arguments 0}} 776 777 {{$base := (Macro "BaseName" $)}} 778 {{$unnamed_params := (ForEach $.CallParameters "ParameterType" | JoinWith ", ")}} 779 780 VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) { 781 {{$p0 := index $.CallParameters 0}} 782 {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}} 783 784 if (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) { 785 {{if not (IsVoid $.Return.Type)}}return §{{end}} 786 {{$base}}({{Macro "Arguments" $}}); 787 } else { 788 ALOGE("{{$ext_name}} not enabled. {{$.Name}} not executed."); 789 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}} 790 } 791 } 792 ¶ 793 {{end}} 794{{end}} 795 796 797{{/* 798------------------------------------------------------------------------------- 799 Emits definition of a global ProcHook. 800------------------------------------------------------------------------------- 801*/}} 802{{define "driver.C++.DefineGlobalProcHook"}} 803 {{AssertType $ "Function"}} 804 805 {{$base := (Macro "BaseName" $)}} 806 807 {{$ext := GetAnnotation $ "extension"}} 808 {{if $ext}} 809 {{Error "invalid global extension"}} 810 {{end}} 811 812 { 813 "{{$.Name}}", 814 ProcHook::GLOBAL, 815 ProcHook::EXTENSION_CORE, 816 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 817 nullptr, 818 }, 819{{end}} 820 821 822{{/* 823------------------------------------------------------------------------------- 824 Emits definition of an instance ProcHook. 825------------------------------------------------------------------------------- 826*/}} 827{{define "driver.C++.DefineInstanceProcHook"}} 828 {{AssertType $ "Function"}} 829 830 {{$base := (Macro "BaseName" $)}} 831 832 { 833 "{{$.Name}}", 834 ProcHook::INSTANCE, 835 836 {{$ext := GetAnnotation $ "extension"}} 837 {{if $ext}} 838 ProcHook::{{Macro "BaseName" $ext}}, 839 840 {{if (Macro "IsExtensionInternal" $ext)}} 841 nullptr, 842 nullptr, 843 {{else}} 844 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 845 nullptr, 846 {{end}} 847 {{else}} 848 ProcHook::EXTENSION_CORE, 849 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 850 nullptr, 851 {{end}} 852 }, 853{{end}} 854 855 856{{/* 857------------------------------------------------------------------------------- 858 Emits definition of a device ProcHook. 859------------------------------------------------------------------------------- 860*/}} 861{{define "driver.C++.DefineDeviceProcHook"}} 862 {{AssertType $ "Function"}} 863 864 {{$base := (Macro "BaseName" $)}} 865 866 { 867 "{{$.Name}}", 868 ProcHook::DEVICE, 869 870 {{$ext := GetAnnotation $ "extension"}} 871 {{if $ext}} 872 ProcHook::{{Macro "BaseName" $ext}}, 873 874 {{if (Macro "IsExtensionInternal" $ext)}} 875 nullptr, 876 nullptr, 877 {{else}} 878 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 879 reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}), 880 {{end}} 881 {{else}} 882 ProcHook::EXTENSION_CORE, 883 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 884 nullptr, 885 {{end}} 886 }, 887{{end}} 888 889 890{{/* 891------------------------------------------------------------------------------- 892 Emits true if a function is needed by vulkan::driver. 893------------------------------------------------------------------------------- 894*/}} 895{{define "driver.IsDriverTableEntry"}} 896 {{AssertType $ "Function"}} 897 898 {{if (Macro "IsFunctionSupported" $)}} 899 {{/* Create functions of dispatchable objects */}} 900 {{ if eq $.Name "vkCreateDevice"}}true 901 {{else if eq $.Name "vkGetDeviceQueue"}}true 902 {{else if eq $.Name "vkAllocateCommandBuffers"}}true 903 904 {{/* Destroy functions of dispatchable objects */}} 905 {{else if eq $.Name "vkDestroyInstance"}}true 906 {{else if eq $.Name "vkDestroyDevice"}}true 907 908 {{else if eq $.Name "vkEnumerateDeviceLayerProperties"}}true 909 910 {{/* Enumeration of extensions */}} 911 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true 912 913 {{/* We cache physical devices in loader.cpp */}} 914 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true 915 916 {{else if eq $.Name "vkGetInstanceProcAddr"}}true 917 {{else if eq $.Name "vkGetDeviceProcAddr"}}true 918 919 {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}} 920 {{else if eq $.Name "vkCreateImage"}}true 921 {{else if eq $.Name "vkDestroyImage"}}true 922 923 {{end}} 924 925 {{$ext := GetAnnotation $ "extension"}} 926 {{if $ext}} 927 {{$ext_name := index $ext.Arguments 0}} 928 {{ if eq $ext_name "VK_ANDROID_native_buffer"}}true 929 {{else if eq $ext_name "VK_EXT_debug_report"}}true 930 {{end}} 931 {{end}} 932 {{end}} 933{{end}} 934 935 936{{/* 937------------------------------------------------------------------------------ 938 Emits true if an instance-dispatched function is needed by vulkan::driver. 939------------------------------------------------------------------------------ 940*/}} 941{{define "driver.IsInstanceDriverTableEntry"}} 942 {{AssertType $ "Function"}} 943 944 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}} 945 true 946 {{end}} 947{{end}} 948 949 950{{/* 951------------------------------------------------------------------------------ 952 Emits true if a device-dispatched function is needed by vulkan::driver. 953------------------------------------------------------------------------------ 954*/}} 955{{define "driver.IsDeviceDriverTableEntry"}} 956 {{AssertType $ "Function"}} 957 958 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}} 959 true 960 {{end}} 961{{end}} 962 963 964{{/* 965------------------------------------------------------------------------------- 966 Emits a function/extension name without the "vk"/"VK_" prefix. 967------------------------------------------------------------------------------- 968*/}} 969{{define "BaseName"}} 970 {{ if IsFunction $}}{{TrimPrefix "vk" $.Name}} 971 {{else if eq $.Name "extension"}}{{TrimPrefix "VK_" (index $.Arguments 0)}} 972 {{else}}{{Error "invalid use of BaseName"}} 973 {{end}} 974{{end}} 975 976 977{{/* 978------------------------------------------------------------------------------- 979 Emits a comma-separated list of C parameter names for the given command. 980------------------------------------------------------------------------------- 981*/}} 982{{define "Arguments"}} 983 {{AssertType $ "Function"}} 984 985 {{ForEach $.CallParameters "ParameterName" | JoinWith ", "}} 986{{end}} 987 988 989{{/* 990------------------------------------------------------------------------------ 991------------------------------------------------------------------------------ 992*/}} 993{{define "IsGloballyDispatched"}} 994 {{AssertType $ "Function"}} 995 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Global")}} 996 true 997 {{end}} 998{{end}} 999 1000 1001{{/* 1002------------------------------------------------------------------------------ 1003 Emit "true" for supported functions that undergo table dispatch. Only global 1004 functions and functions handled in the loader top without calling into 1005 lower layers are not dispatched. 1006------------------------------------------------------------------------------ 1007*/}} 1008{{define "IsInstanceDispatched"}} 1009 {{AssertType $ "Function"}} 1010 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}} 1011 true 1012 {{end}} 1013{{end}} 1014 1015 1016{{/* 1017------------------------------------------------------------------------------ 1018 Emit "true" for supported functions that can have device-specific dispatch. 1019------------------------------------------------------------------------------ 1020*/}} 1021{{define "IsDeviceDispatched"}} 1022 {{AssertType $ "Function"}} 1023 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Device")}} 1024 true 1025 {{end}} 1026{{end}} 1027 1028 1029{{/* 1030------------------------------------------------------------------------------ 1031 Emit "true" if a function is core or from a supportable extension. 1032------------------------------------------------------------------------------ 1033*/}} 1034{{define "IsFunctionSupported"}} 1035 {{AssertType $ "Function"}} 1036 {{if not (GetAnnotation $ "pfn")}} 1037 {{$ext := GetAnnotation $ "extension"}} 1038 {{if not $ext}}true 1039 {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true 1040 {{end}} 1041 {{end}} 1042{{end}} 1043 1044 1045{{/* 1046------------------------------------------------------------------------------ 1047 Decides whether a function should be exported from the Android Vulkan 1048 library. Functions in the core API and in loader extensions are exported. 1049------------------------------------------------------------------------------ 1050*/}} 1051{{define "IsFunctionExported"}} 1052 {{AssertType $ "Function"}} 1053 1054 {{if (Macro "IsFunctionSupported" $)}} 1055 {{$ext := GetAnnotation $ "extension"}} 1056 {{if $ext}} 1057 {{Macro "IsExtensionExported" $ext}} 1058 {{else}} 1059 true 1060 {{end}} 1061 {{end}} 1062{{end}} 1063 1064 1065{{/* 1066------------------------------------------------------------------------------ 1067 Emit "true" if an extension is unsupportable on Android. 1068------------------------------------------------------------------------------ 1069*/}} 1070{{define "IsExtensionBlacklisted"}} 1071 {{$ext := index $.Arguments 0}} 1072 {{ if eq $ext "VK_KHR_display"}}true 1073 {{else if eq $ext "VK_KHR_display_swapchain"}}true 1074 {{else if eq $ext "VK_KHR_xlib_surface"}}true 1075 {{else if eq $ext "VK_KHR_xcb_surface"}}true 1076 {{else if eq $ext "VK_KHR_wayland_surface"}}true 1077 {{else if eq $ext "VK_KHR_mir_surface"}}true 1078 {{else if eq $ext "VK_KHR_win32_surface"}}true 1079 {{end}} 1080{{end}} 1081 1082 1083{{/* 1084------------------------------------------------------------------------------ 1085 Reports whether an extension is implemented entirely by the loader, 1086 so drivers should not enumerate it. 1087------------------------------------------------------------------------------ 1088*/}} 1089{{define "IsExtensionExported"}} 1090 {{$ext := index $.Arguments 0}} 1091 {{ if eq $ext "VK_KHR_surface"}}true 1092 {{else if eq $ext "VK_KHR_swapchain"}}true 1093 {{else if eq $ext "VK_KHR_android_surface"}}true 1094 {{end}} 1095{{end}} 1096 1097 1098{{/* 1099------------------------------------------------------------------------------ 1100 Reports whether an extension is internal to the loader and drivers, 1101 so the loader should not enumerate it. 1102------------------------------------------------------------------------------ 1103*/}} 1104{{define "IsExtensionInternal"}} 1105 {{$ext := index $.Arguments 0}} 1106 {{ if eq $ext "VK_ANDROID_native_buffer"}}true 1107 {{end}} 1108{{end}} 1109