code-generator.tmpl revision eb7db124e46da9a9210cf868353f5ea79502ffec
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 <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{{/* 152------------------------------------------------------------------------------- 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{{/* 256------------------------------------------------------------------------------ 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{{/* 495------------------------------------------------------------------------------ 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{{/* 766------------------------------------------------------------------------------- 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}} 897 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}} 910