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