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