1{{define "Copyright"}} 2/* 3•* Copyright 2016 The Android Open Source Project 4•* 5•* Licensed under the Apache License, Version 2.0 (the "License"); 6•* you may not use this file except in compliance with the License. 7•* You may obtain a copy of the License at 8•* 9•* http://www.apache.org/licenses/LICENSE-2.0 10•* 11•* Unless required by applicable law or agreed to in writing, software 12•* distributed under the License is distributed on an "AS IS" BASIS, 13•* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14•* See the License for the specific language governing permissions and 15•* limitations under the License. 16•*/ 17¶{{end}} 18 19{{Include "../api/templates/vulkan_common.tmpl"}} 20{{Global "clang-format" (Strings "clang-format" "-style=file")}} 21{{Macro "DefineGlobals" $}} 22{{$ | Macro "api_gen.h" | Format (Global "clang-format") | Write "api_gen.h" }} 23{{$ | Macro "api_gen.cpp" | Format (Global "clang-format") | Write "api_gen.cpp"}} 24{{$ | Macro "driver_gen.h" | Format (Global "clang-format") | Write "driver_gen.h"}} 25{{$ | Macro "driver_gen.cpp" | Format (Global "clang-format") | Write "driver_gen.cpp"}} 26 27{{/* 28------------------------------------------------------------------------------- 29 api_gen.h 30------------------------------------------------------------------------------- 31*/}} 32{{define "api_gen.h"}} 33{{Macro "Copyright"}} 34¶ 35// WARNING: This file is generated. See ../README.md for instructions. 36¶ 37#ifndef LIBVULKAN_API_GEN_H 38#define LIBVULKAN_API_GEN_H 39¶ 40#include <bitset> 41#include <vulkan/vulkan.h> 42#include "driver_gen.h" 43¶ 44namespace vulkan {« 45namespace api {« 46¶ 47struct InstanceDispatchTable { 48 // clang-format off 49 {{range $f := AllCommands $}} 50 {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}} 51 {{Macro "C++.DeclareTableEntry" $f}}; 52 {{end}} 53 {{end}} 54 // clang-format on 55}; 56¶ 57struct DeviceDispatchTable { 58 // clang-format off 59 {{range $f := AllCommands $}} 60 {{if (Macro "api.IsDeviceDispatchTableEntry" $f)}} 61 {{Macro "C++.DeclareTableEntry" $f}}; 62 {{end}} 63 {{end}} 64 // clang-format on 65}; 66¶ 67bool InitDispatchTable( 68 VkInstance instance, 69 PFN_vkGetInstanceProcAddr get_proc, 70 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions); 71bool InitDispatchTable( 72 VkDevice dev, 73 PFN_vkGetDeviceProcAddr get_proc, 74 const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions); 75¶ 76»} // namespace api 77»} // namespace vulkan 78¶ 79#endif // LIBVULKAN_API_GEN_H 80¶{{end}} 81 82 83{{/* 84------------------------------------------------------------------------------- 85 api_gen.cpp 86------------------------------------------------------------------------------- 87*/}} 88{{define "api_gen.cpp"}} 89{{Macro "Copyright"}} 90¶ 91// WARNING: This file is generated. See ../README.md for instructions. 92¶ 93#include <string.h> 94#include <algorithm> 95#include <log/log.h> 96¶ 97// to catch mismatches between vulkan.h and this file 98#undef VK_NO_PROTOTYPES 99#include "api.h" 100¶ 101namespace vulkan {« 102namespace api {« 103¶ 104{{Macro "C++.DefineInitProcMacro" "dispatch"}} 105¶ 106{{Macro "api.C++.DefineInitProcExtMacro"}} 107¶ 108namespace {« 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¶ 119bool 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¶ 137bool 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¶ 157namespace {« 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¶ 222namespace vulkan {« 223namespace driver {« 224¶ 225{{Macro "driver.C++.DefineProcHookType"}} 226¶ 227struct 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¶ 237struct 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¶ 247const ProcHook* GetProcHook(const char* name); 248ProcHook::Extension GetProcHookExtension(const char* name); 249¶ 250bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, 251 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions); 252bool 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¶ 278namespace vulkan {« 279namespace driver {« 280¶ 281namespace {« 282¶ 283// clang-format off 284¶ 285{{range $f := AllCommands $}} 286 {{Macro "driver.C++.DefineProcHookStub" $f}} 287{{end}} 288// clang-format on 289¶ 290const 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¶ 308const 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¶ 317ProcHook::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¶ 331bool 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¶ 348bool 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"}} 677VK_ANDROID_native_buffer 678VK_EXT_debug_report 679VK_KHR_android_surface 680VK_KHR_surface 681VK_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