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¶ 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¶ 103namespace vulkan {« 104namespace api {« 105¶ 106{{Macro "C++.DefineInitProcMacro" "dispatch"}} 107¶ 108{{Macro "api.C++.DefineInitProcExtMacro"}} 109¶ 110namespace {« 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¶ 121bool 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¶ 139bool 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¶ 159namespace {« 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¶ 224namespace vulkan {« 225namespace driver {« 226¶ 227{{Macro "driver.C++.DefineProcHookType"}} 228¶ 229struct 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¶ 239struct 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¶ 249const ProcHook* GetProcHook(const char* name); 250ProcHook::Extension GetProcHookExtension(const char* name); 251¶ 252bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, 253 const std::bitset<ProcHook::EXTENSION_COUNT> &extensions); 254bool 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¶ 282namespace vulkan {« 283namespace driver {« 284¶ 285namespace {« 286¶ 287// clang-format off 288¶ 289{{range $f := AllCommands $}} 290 {{Macro "driver.C++.DefineProcHookStub" $f}} 291{{end}} 292// clang-format on 293¶ 294const 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¶ 312const 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¶ 321ProcHook::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¶ 335bool 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¶ 352bool 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}}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"}} 683VK_ANDROID_native_buffer 684VK_EXT_debug_report 685VK_EXT_hdr_metadata 686VK_EXT_swapchain_colorspace 687VK_GOOGLE_display_timing 688VK_KHR_android_surface 689VK_KHR_incremental_present 690VK_KHR_shared_presentable_image 691VK_KHR_surface 692VK_KHR_swapchain 693VK_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"}} 704VK_KHR_get_physical_device_properties2 705{{end}} 706 707 708{{/* 709------------------------------------------------------------------------------ 710 Emits true if an extension is intercepted by vulkan::driver. 711------------------------------------------------------------------------------ 712*/}} 713{{define "driver.IsExtensionIntercepted"}} 714 {{$ext_name := index $.Arguments 0}} 715 {{$filters := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}} 716 717 {{range $f := $filters}} 718 {{if eq $ext_name $f}}true{{end}} 719 {{end}} 720{{end}} 721 722 723{{/* 724------------------------------------------------------------------------------ 725 Emits true if a function is intercepted by vulkan::driver. 726------------------------------------------------------------------------------ 727*/}} 728{{define "driver.IsIntercepted"}} 729 {{AssertType $ "Function"}} 730 731 {{if (Macro "IsFunctionSupported" $)}} 732 {{/* Create functions of dispatchable objects */}} 733 {{ if eq $.Name "vkCreateInstance"}}true 734 {{else if eq $.Name "vkCreateDevice"}}true 735 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true 736 {{else if eq $.Name "vkGetDeviceQueue"}}true 737 {{else if eq $.Name "vkAllocateCommandBuffers"}}true 738 739 {{/* Destroy functions of dispatchable objects */}} 740 {{else if eq $.Name "vkDestroyInstance"}}true 741 {{else if eq $.Name "vkDestroyDevice"}}true 742 743 {{/* Enumeration of extensions */}} 744 {{else if eq $.Name "vkEnumerateInstanceExtensionProperties"}}true 745 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true 746 747 {{else if eq $.Name "vkGetInstanceProcAddr"}}true 748 {{else if eq $.Name "vkGetDeviceProcAddr"}}true 749 750 {{end}} 751 752 {{$ext := GetAnnotation $ "extension"}} 753 {{if $ext}} 754 {{Macro "driver.IsExtensionIntercepted" $ext}} 755 {{end}} 756 757 {{end}} 758{{end}} 759 760 761{{/* 762------------------------------------------------------------------------------ 763 Emits true if a function needs a ProcHook stub. 764------------------------------------------------------------------------------ 765*/}} 766{{define "driver.NeedProcHookStub"}} 767 {{AssertType $ "Function"}} 768 769 {{if and (Macro "driver.IsIntercepted" $) (Macro "IsDeviceDispatched" $)}} 770 {{$ext := GetAnnotation $ "extension"}} 771 {{if $ext}} 772 {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}} 773 {{end}} 774 {{end}} 775{{end}} 776 777 778{{/* 779------------------------------------------------------------------------------- 780 Emits definition of struct ProcHook. 781------------------------------------------------------------------------------- 782*/}} 783{{define "driver.C++.DefineProcHookType"}} 784 struct ProcHook { 785 enum Type { 786 GLOBAL, 787 INSTANCE, 788 DEVICE, 789 }; 790 791 enum Extension { 792 {{$exts := Strings (Macro "driver.KnownExtensions") | SplitOn "\n"}} 793 {{range $e := $exts}} 794 {{TrimPrefix "VK_" $e}}, 795 {{end}} 796 ¶ 797 EXTENSION_CORE, // valid bit 798 EXTENSION_COUNT, 799 EXTENSION_UNKNOWN, 800 }; 801 ¶ 802 const char* name; 803 Type type; 804 Extension extension; 805 ¶ 806 PFN_vkVoidFunction proc; 807 PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks 808 }; 809{{end}} 810 811 812{{/* 813------------------------------------------------------------------------------- 814 Emits INIT_PROC_EXT macro for vulkan::driver. 815------------------------------------------------------------------------------- 816*/}} 817{{define "driver.C++.DefineInitProcExtMacro"}} 818 #define INIT_PROC_EXT(ext, required, obj, proc) do { \ 819 if (extensions[ProcHook::ext]) \ 820 INIT_PROC(required, obj, proc); \ 821 } while(0) 822{{end}} 823 824 825{{/* 826------------------------------------------------------------------------------- 827 Emits a stub for ProcHook::checked_proc. 828------------------------------------------------------------------------------- 829*/}} 830{{define "driver.C++.DefineProcHookStub"}} 831 {{AssertType $ "Function"}} 832 833 {{if (Macro "driver.NeedProcHookStub" $)}} 834 {{$ext := GetAnnotation $ "extension"}} 835 {{$ext_name := index $ext.Arguments 0}} 836 837 {{$base := (Macro "BaseName" $)}} 838 839 VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) { 840 {{$p0 := index $.CallParameters 0}} 841 {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}} 842 843 if (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) { 844 {{if not (IsVoid $.Return.Type)}}return §{{end}} 845 {{$base}}({{Macro "Arguments" $}}); 846 } else { 847 Logger({{$p0.Name}}).Err({{$p0.Name}}, "{{$ext_name}} not enabled. {{$.Name}} not executed."); 848 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}} 849 } 850 } 851 ¶ 852 {{end}} 853{{end}} 854 855 856{{/* 857------------------------------------------------------------------------------- 858 Emits definition of a global ProcHook. 859------------------------------------------------------------------------------- 860*/}} 861{{define "driver.C++.DefineGlobalProcHook"}} 862 {{AssertType $ "Function"}} 863 864 {{$base := (Macro "BaseName" $)}} 865 866 {{$ext := GetAnnotation $ "extension"}} 867 {{if $ext}} 868 {{Error "invalid global extension"}} 869 {{end}} 870 871 { 872 "{{$.Name}}", 873 ProcHook::GLOBAL, 874 ProcHook::EXTENSION_CORE, 875 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 876 nullptr, 877 }, 878{{end}} 879 880 881{{/* 882------------------------------------------------------------------------------- 883 Emits definition of an instance ProcHook. 884------------------------------------------------------------------------------- 885*/}} 886{{define "driver.C++.DefineInstanceProcHook"}} 887 {{AssertType $ "Function"}} 888 889 {{$base := (Macro "BaseName" $)}} 890 891 { 892 "{{$.Name}}", 893 ProcHook::INSTANCE, 894 895 {{$ext := GetAnnotation $ "extension"}} 896 {{if $ext}} 897 ProcHook::{{Macro "BaseName" $ext}}, 898 899 {{if (Macro "IsExtensionInternal" $ext)}} 900 nullptr, 901 nullptr, 902 {{else}} 903 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 904 nullptr, 905 {{end}} 906 {{else}} 907 ProcHook::EXTENSION_CORE, 908 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 909 nullptr, 910 {{end}} 911 }, 912{{end}} 913 914 915{{/* 916------------------------------------------------------------------------------- 917 Emits definition of a device ProcHook. 918------------------------------------------------------------------------------- 919*/}} 920{{define "driver.C++.DefineDeviceProcHook"}} 921 {{AssertType $ "Function"}} 922 923 {{$base := (Macro "BaseName" $)}} 924 925 { 926 "{{$.Name}}", 927 ProcHook::DEVICE, 928 929 {{$ext := GetAnnotation $ "extension"}} 930 {{if $ext}} 931 ProcHook::{{Macro "BaseName" $ext}}, 932 933 {{if (Macro "IsExtensionInternal" $ext)}} 934 nullptr, 935 nullptr, 936 {{else}} 937 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 938 reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}), 939 {{end}} 940 {{else}} 941 ProcHook::EXTENSION_CORE, 942 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 943 nullptr, 944 {{end}} 945 }, 946{{end}} 947 948 949{{/* 950------------------------------------------------------------------------------- 951 Emits true if a function is needed by vulkan::driver. 952------------------------------------------------------------------------------- 953*/}} 954{{define "driver.IsDriverTableEntry"}} 955 {{AssertType $ "Function"}} 956 957 {{if (Macro "IsFunctionSupported" $)}} 958 {{/* Create functions of dispatchable objects */}} 959 {{ if eq $.Name "vkCreateDevice"}}true 960 {{else if eq $.Name "vkGetDeviceQueue"}}true 961 {{else if eq $.Name "vkAllocateCommandBuffers"}}true 962 963 {{/* Destroy functions of dispatchable objects */}} 964 {{else if eq $.Name "vkDestroyInstance"}}true 965 {{else if eq $.Name "vkDestroyDevice"}}true 966 967 {{/* Enumeration of extensions */}} 968 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true 969 970 {{/* We cache physical devices in loader.cpp */}} 971 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true 972 973 {{else if eq $.Name "vkGetInstanceProcAddr"}}true 974 {{else if eq $.Name "vkGetDeviceProcAddr"}}true 975 976 {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}} 977 {{else if eq $.Name "vkCreateImage"}}true 978 {{else if eq $.Name "vkDestroyImage"}}true 979 980 {{else if eq $.Name "vkGetPhysicalDeviceProperties"}}true 981 {{else if eq $.Name "vkGetPhysicalDeviceProperties2KHR"}}true 982 {{end}} 983 984 {{$ext := GetAnnotation $ "extension"}} 985 {{if $ext}} 986 {{$ext_name := index $ext.Arguments 0}} 987 {{ if eq $ext_name "VK_ANDROID_native_buffer"}}true 988 {{else if eq $ext_name "VK_EXT_debug_report"}}true 989 {{end}} 990 {{end}} 991 {{end}} 992{{end}} 993 994 995{{/* 996------------------------------------------------------------------------------ 997 Emits true if an instance-dispatched function is needed by vulkan::driver. 998------------------------------------------------------------------------------ 999*/}} 1000{{define "driver.IsInstanceDriverTableEntry"}} 1001 {{AssertType $ "Function"}} 1002 1003 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}} 1004 true 1005 {{end}} 1006{{end}} 1007 1008 1009{{/* 1010------------------------------------------------------------------------------ 1011 Emits true if a device-dispatched function is needed by vulkan::driver. 1012------------------------------------------------------------------------------ 1013*/}} 1014{{define "driver.IsDeviceDriverTableEntry"}} 1015 {{AssertType $ "Function"}} 1016 1017 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}} 1018 true 1019 {{end}} 1020{{end}} 1021 1022 1023{{/* 1024------------------------------------------------------------------------------- 1025 Emits a function/extension name without the "vk"/"VK_" prefix. 1026------------------------------------------------------------------------------- 1027*/}} 1028{{define "BaseName"}} 1029 {{ if IsFunction $}}{{TrimPrefix "vk" $.Name}} 1030 {{else if eq $.Name "extension"}}{{TrimPrefix "VK_" (index $.Arguments 0)}} 1031 {{else}}{{Error "invalid use of BaseName"}} 1032 {{end}} 1033{{end}} 1034 1035 1036{{/* 1037------------------------------------------------------------------------------- 1038 Emits a comma-separated list of C parameter names for the given command. 1039------------------------------------------------------------------------------- 1040*/}} 1041{{define "Arguments"}} 1042 {{AssertType $ "Function"}} 1043 1044 {{ForEach $.CallParameters "ParameterName" | JoinWith ", "}} 1045{{end}} 1046 1047 1048{{/* 1049------------------------------------------------------------------------------ 1050------------------------------------------------------------------------------ 1051*/}} 1052{{define "IsGloballyDispatched"}} 1053 {{AssertType $ "Function"}} 1054 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Global")}} 1055 true 1056 {{end}} 1057{{end}} 1058 1059 1060{{/* 1061------------------------------------------------------------------------------ 1062 Emit "true" for supported functions that undergo table dispatch. Only global 1063 functions and functions handled in the loader top without calling into 1064 lower layers are not dispatched. 1065------------------------------------------------------------------------------ 1066*/}} 1067{{define "IsInstanceDispatched"}} 1068 {{AssertType $ "Function"}} 1069 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}} 1070 true 1071 {{end}} 1072{{end}} 1073 1074 1075{{/* 1076------------------------------------------------------------------------------ 1077 Emit "true" for supported functions that can have device-specific dispatch. 1078------------------------------------------------------------------------------ 1079*/}} 1080{{define "IsDeviceDispatched"}} 1081 {{AssertType $ "Function"}} 1082 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Device")}} 1083 true 1084 {{end}} 1085{{end}} 1086 1087 1088{{/* 1089------------------------------------------------------------------------------ 1090 Emit "true" if a function is core or from a supportable extension. 1091------------------------------------------------------------------------------ 1092*/}} 1093{{define "IsFunctionSupported"}} 1094 {{AssertType $ "Function"}} 1095 {{if not (GetAnnotation $ "pfn")}} 1096 {{$ext := GetAnnotation $ "extension"}} 1097 {{if not $ext}}true 1098 {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true 1099 {{end}} 1100 {{end}} 1101{{end}} 1102 1103 1104{{/* 1105------------------------------------------------------------------------------ 1106 Decides whether a function should be exported from the Android Vulkan 1107 library. Functions in the core API and in loader extensions are exported. 1108------------------------------------------------------------------------------ 1109*/}} 1110{{define "IsFunctionExported"}} 1111 {{AssertType $ "Function"}} 1112 1113 {{if (Macro "IsFunctionSupported" $)}} 1114 {{$ext := GetAnnotation $ "extension"}} 1115 {{if $ext}} 1116 {{Macro "IsExtensionExported" $ext}} 1117 {{else}} 1118 true 1119 {{end}} 1120 {{end}} 1121{{end}} 1122 1123 1124{{/* 1125------------------------------------------------------------------------------ 1126 Emit "true" if an extension is unsupportable on Android. 1127------------------------------------------------------------------------------ 1128*/}} 1129{{define "IsExtensionBlacklisted"}} 1130 {{$ext := index $.Arguments 0}} 1131 {{ if eq $ext "VK_KHR_display"}}true 1132 {{else if eq $ext "VK_KHR_display_swapchain"}}true 1133 {{else if eq $ext "VK_KHR_mir_surface"}}true 1134 {{else if eq $ext "VK_KHR_xcb_surface"}}true 1135 {{else if eq $ext "VK_KHR_xlib_surface"}}true 1136 {{else if eq $ext "VK_KHR_wayland_surface"}}true 1137 {{else if eq $ext "VK_KHR_win32_surface"}}true 1138 {{else if eq $ext "VK_KHX_external_memory_win32"}}true 1139 {{else if eq $ext "VK_KHX_win32_keyed_mutex"}}true 1140 {{else if eq $ext "VK_KHX_external_semaphore_win32"}}true 1141 {{else if eq $ext "VK_EXT_acquire_xlib_display"}}true 1142 {{else if eq $ext "VK_EXT_direct_mode_display"}}true 1143 {{else if eq $ext "VK_EXT_display_surface_counter"}}true 1144 {{else if eq $ext "VK_EXT_display_control"}}true 1145 {{else if eq $ext "VK_MVK_ios_surface"}}true 1146 {{else if eq $ext "VK_MVK_macos_surface"}}true 1147 {{else if eq $ext "VK_NN_vi_surface"}}true 1148 {{else if eq $ext "VK_NV_external_memory_win32"}}true 1149 {{else if eq $ext "VK_NV_win32_keyed_mutex"}}true 1150 {{end}} 1151{{end}} 1152 1153 1154{{/* 1155------------------------------------------------------------------------------ 1156 Reports whether an extension has functions exported by the loader. 1157 E.g. applications can directly link to an extension function. 1158 Currently only support WSI extensions this way. 1159------------------------------------------------------------------------------ 1160*/}} 1161{{define "IsExtensionExported"}} 1162 {{$ext := index $.Arguments 0}} 1163 {{ if eq $ext "VK_KHR_surface"}}true 1164 {{else if eq $ext "VK_KHR_swapchain"}}true 1165 {{else if eq $ext "VK_KHR_android_surface"}}true 1166 {{end}} 1167{{end}} 1168 1169 1170{{/* 1171------------------------------------------------------------------------------ 1172 Reports whether an extension is internal to the loader and drivers, 1173 so the loader should not enumerate it. 1174------------------------------------------------------------------------------ 1175*/}} 1176{{define "IsExtensionInternal"}} 1177 {{$ext := index $.Arguments 0}} 1178 {{ if eq $ext "VK_ANDROID_native_buffer"}}true 1179 {{end}} 1180{{end}} 1181