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