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 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"}} 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 705VK_ANDROID_external_memory_android_hardware_buffer 706VK_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------------------------------------------------------------------------------ 771 Emits the ProcHook enum for core Vulkan API verions. 772------------------------------------------------------------------------------ 773*/}} 774{{define "driver.GetProcHookEnum"}} 775 {{if GetAnnotation $ "vulkan1_1"}}ProcHook::EXTENSION_CORE_1_1 776 {{else}}ProcHook::EXTENSION_CORE_1_0 777 {{end}} 778{{end}} 779 780 781{{/* 782------------------------------------------------------------------------------ 783 Emits true if a function needs a ProcHook stub. 784------------------------------------------------------------------------------ 785*/}} 786{{define "driver.NeedProcHookStub"}} 787 {{AssertType $ "Function"}} 788 789 {{if and (Macro "driver.IsIntercepted" $) (Macro "IsDeviceDispatched" $)}} 790 {{$ext := GetAnnotation $ "extension"}} 791 {{if $ext}} 792 {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}} 793 {{end}} 794 795 {{if GetAnnotation $ "vulkan1_1"}}true{{end}} 796 {{end}} 797{{end}} 798 799 800{{/* 801------------------------------------------------------------------------------- 802 Emits definition of struct ProcHook. 803------------------------------------------------------------------------------- 804*/}} 805{{define "driver.C++.DefineProcHookType"}} 806 struct ProcHook { 807 enum Type { 808 GLOBAL, 809 INSTANCE, 810 DEVICE, 811 }; 812 813 enum Extension { 814 {{$exts := Strings (Macro "driver.KnownExtensions") | SplitOn "\n"}} 815 {{range $e := $exts}} 816 {{TrimPrefix "VK_" $e}}, 817 {{end}} 818 ¶ 819 EXTENSION_CORE_1_0, 820 EXTENSION_CORE_1_1, 821 EXTENSION_COUNT, 822 EXTENSION_UNKNOWN, 823 }; 824 ¶ 825 const char* name; 826 Type type; 827 Extension extension; 828 ¶ 829 PFN_vkVoidFunction proc; 830 PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks 831 }; 832{{end}} 833 834 835{{/* 836------------------------------------------------------------------------------- 837 Emits INIT_PROC_EXT macro for vulkan::driver. 838------------------------------------------------------------------------------- 839*/}} 840{{define "driver.C++.DefineInitProcExtMacro"}} 841 #define INIT_PROC_EXT(ext, required, obj, proc) do { \ 842 if (extensions[ProcHook::ext]) \ 843 INIT_PROC(required, obj, proc); \ 844 } while(0) 845{{end}} 846 847 848{{/* 849------------------------------------------------------------------------------- 850 Emits a stub for ProcHook::checked_proc. 851------------------------------------------------------------------------------- 852*/}} 853{{define "driver.C++.DefineProcHookStub"}} 854 {{AssertType $ "Function"}} 855 856 {{if (Macro "driver.NeedProcHookStub" $)}} 857 {{$ext_name := Strings ("")}} 858 {{$ext_hook := Strings ("")}} 859 {{$ext := GetAnnotation $ "extension"}} 860 {{if $ext}} 861 {{$ext_name = index $ext.Arguments 0}} 862 {{$ext_hook = Strings ("ProcHook::") (Macro "BaseName" $ext)}} 863 {{else}} 864 {{$ext_name = Strings ("VK_VERSION_1_0")}} 865 {{$ext_hook = (Macro "driver.GetProcHookEnum" $)}} 866 {{end}} 867 868 {{$base := (Macro "BaseName" $)}} 869 870 VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) { 871 {{$p0 := index $.CallParameters 0}} 872 873 if (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) { 874 {{if not (IsVoid $.Return.Type)}}return §{{end}} 875 {{$base}}({{Macro "Arguments" $}}); 876 } else { 877 Logger({{$p0.Name}}).Err({{$p0.Name}}, "{{$ext_name}} not enabled. {{$.Name}} not executed."); 878 {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}} 879 } 880 } 881 ¶ 882 {{end}} 883{{end}} 884 885 886{{/* 887------------------------------------------------------------------------------- 888 Emits definition of a global ProcHook. 889------------------------------------------------------------------------------- 890*/}} 891{{define "driver.C++.DefineGlobalProcHook"}} 892 {{AssertType $ "Function"}} 893 894 {{$base := (Macro "BaseName" $)}} 895 896 {{$ext := GetAnnotation $ "extension"}} 897 {{if $ext}} 898 {{Error "invalid global extension"}} 899 {{end}} 900 901 { 902 "{{$.Name}}", 903 ProcHook::GLOBAL, 904 {{Macro "driver.GetProcHookEnum" $}}, 905 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 906 nullptr, 907 }, 908{{end}} 909 910 911{{/* 912------------------------------------------------------------------------------- 913 Emits definition of an instance ProcHook. 914------------------------------------------------------------------------------- 915*/}} 916{{define "driver.C++.DefineInstanceProcHook"}} 917 {{AssertType $ "Function"}} 918 919 {{$base := (Macro "BaseName" $)}} 920 921 { 922 "{{$.Name}}", 923 ProcHook::INSTANCE, 924 925 {{$ext := GetAnnotation $ "extension"}} 926 {{if $ext}} 927 ProcHook::{{Macro "BaseName" $ext}}, 928 929 {{if (Macro "IsExtensionInternal" $ext)}} 930 nullptr, 931 nullptr, 932 {{else}} 933 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 934 nullptr, 935 {{end}} 936 {{else}} 937 {{Macro "driver.GetProcHookEnum" $}}, 938 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 939 nullptr, 940 {{end}} 941 }, 942{{end}} 943 944 945{{/* 946------------------------------------------------------------------------------- 947 Emits definition of a device ProcHook. 948------------------------------------------------------------------------------- 949*/}} 950{{define "driver.C++.DefineDeviceProcHook"}} 951 {{AssertType $ "Function"}} 952 953 {{$base := (Macro "BaseName" $)}} 954 955 { 956 "{{$.Name}}", 957 ProcHook::DEVICE, 958 959 {{$ext := GetAnnotation $ "extension"}} 960 {{if or $ext (GetAnnotation $ "vulkan1_1")}} 961 {{if $ext}} 962 ProcHook::{{Macro "BaseName" $ext}}, 963 {{if Macro "IsExtensionInternal" $ext}} 964 nullptr, 965 nullptr, 966 {{else}} 967 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 968 reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}), 969 {{end}} 970 {{else}} 971 {{Macro "driver.GetProcHookEnum" $}}, 972 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 973 reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}), 974 {{end}} 975 {{else}} 976 {{Macro "driver.GetProcHookEnum" $}}, 977 reinterpret_cast<PFN_vkVoidFunction>({{$base}}), 978 nullptr, 979 {{end}} 980 }, 981{{end}} 982 983 984{{/* 985------------------------------------------------------------------------------- 986 Emits true if a function is needed by vulkan::driver. 987------------------------------------------------------------------------------- 988*/}} 989{{define "driver.IsDriverTableEntry"}} 990 {{AssertType $ "Function"}} 991 992 {{if (Macro "IsFunctionSupported" $)}} 993 {{/* Create functions of dispatchable objects */}} 994 {{ if eq $.Name "vkCreateDevice"}}true 995 {{else if eq $.Name "vkGetDeviceQueue"}}true 996 {{else if eq $.Name "vkGetDeviceQueue2"}}true 997 {{else if eq $.Name "vkAllocateCommandBuffers"}}true 998 999 {{/* Destroy functions of dispatchable objects */}} 1000 {{else if eq $.Name "vkDestroyInstance"}}true 1001 {{else if eq $.Name "vkDestroyDevice"}}true 1002 1003 {{/* Enumeration of extensions */}} 1004 {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true 1005 1006 {{/* We cache physical devices in loader.cpp */}} 1007 {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true 1008 {{else if eq $.Name "vkEnumeratePhysicalDeviceGroups"}}true 1009 1010 {{else if eq $.Name "vkGetInstanceProcAddr"}}true 1011 {{else if eq $.Name "vkGetDeviceProcAddr"}}true 1012 1013 {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}} 1014 {{else if eq $.Name "vkCreateImage"}}true 1015 {{else if eq $.Name "vkDestroyImage"}}true 1016 1017 {{else if eq $.Name "vkGetPhysicalDeviceProperties"}}true 1018 {{else if eq $.Name "vkGetPhysicalDeviceProperties2"}}true 1019 {{else if eq $.Name "vkGetPhysicalDeviceProperties2KHR"}}true 1020 1021 {{/* VK_KHR_swapchain v69 requirement */}} 1022 {{else if eq $.Name "vkBindImageMemory2"}}true 1023 {{else if eq $.Name "vkBindImageMemory2KHR"}}true 1024 {{end}} 1025 1026 {{$ext := GetAnnotation $ "extension"}} 1027 {{if $ext}} 1028 {{$ext_name := index $ext.Arguments 0}} 1029 {{ if eq $ext_name "VK_ANDROID_native_buffer"}}true 1030 {{else if eq $ext_name "VK_EXT_debug_report"}}true 1031 {{end}} 1032 {{end}} 1033 {{end}} 1034{{end}} 1035 1036 1037{{/* 1038------------------------------------------------------------------------------ 1039 Emits true if an instance-dispatched function is needed by vulkan::driver. 1040------------------------------------------------------------------------------ 1041*/}} 1042{{define "driver.IsInstanceDriverTableEntry"}} 1043 {{AssertType $ "Function"}} 1044 1045 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}} 1046 true 1047 {{end}} 1048{{end}} 1049 1050 1051{{/* 1052------------------------------------------------------------------------------ 1053 Emits true if a device-dispatched function is needed by vulkan::driver. 1054------------------------------------------------------------------------------ 1055*/}} 1056{{define "driver.IsDeviceDriverTableEntry"}} 1057 {{AssertType $ "Function"}} 1058 1059 {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}} 1060 true 1061 {{end}} 1062{{end}} 1063 1064 1065{{/* 1066------------------------------------------------------------------------------- 1067 Emits a function/extension name without the "vk"/"VK_" prefix. 1068------------------------------------------------------------------------------- 1069*/}} 1070{{define "BaseName"}} 1071 {{ if IsFunction $}}{{TrimPrefix "vk" $.Name}} 1072 {{else if eq $.Name "extension"}}{{TrimPrefix "VK_" (index $.Arguments 0)}} 1073 {{else}}{{Error "invalid use of BaseName"}} 1074 {{end}} 1075{{end}} 1076 1077 1078{{/* 1079------------------------------------------------------------------------------- 1080 Emits a comma-separated list of C parameter names for the given command. 1081------------------------------------------------------------------------------- 1082*/}} 1083{{define "Arguments"}} 1084 {{AssertType $ "Function"}} 1085 1086 {{ForEach $.CallParameters "ParameterName" | JoinWith ", "}} 1087{{end}} 1088 1089 1090{{/* 1091------------------------------------------------------------------------------ 1092------------------------------------------------------------------------------ 1093*/}} 1094{{define "IsGloballyDispatched"}} 1095 {{AssertType $ "Function"}} 1096 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Global")}} 1097 true 1098 {{end}} 1099{{end}} 1100 1101 1102{{/* 1103------------------------------------------------------------------------------ 1104 Emit "true" for supported functions that undergo table dispatch. Only global 1105 functions and functions handled in the loader top without calling into 1106 lower layers are not dispatched. 1107------------------------------------------------------------------------------ 1108*/}} 1109{{define "IsInstanceDispatched"}} 1110 {{AssertType $ "Function"}} 1111 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}} 1112 true 1113 {{end}} 1114{{end}} 1115 1116 1117{{/* 1118------------------------------------------------------------------------------ 1119 Emit "true" for supported functions that can have device-specific dispatch. 1120------------------------------------------------------------------------------ 1121*/}} 1122{{define "IsDeviceDispatched"}} 1123 {{AssertType $ "Function"}} 1124 {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Device")}} 1125 true 1126 {{end}} 1127{{end}} 1128 1129 1130{{/* 1131------------------------------------------------------------------------------ 1132 Emit "true" if a function is core or from a supportable extension. 1133------------------------------------------------------------------------------ 1134*/}} 1135{{define "IsFunctionSupported"}} 1136 {{AssertType $ "Function"}} 1137 {{if not (GetAnnotation $ "pfn")}} 1138 {{$ext := GetAnnotation $ "extension"}} 1139 {{if not $ext}}true 1140 {{else if not (Macro "IsExtensionBlocked" $ext)}}true 1141 {{end}} 1142 {{end}} 1143{{end}} 1144 1145 1146{{/* 1147------------------------------------------------------------------------------ 1148 Decides whether a function should be exported from the Android Vulkan 1149 library. Functions in the core API and in loader extensions are exported. 1150------------------------------------------------------------------------------ 1151*/}} 1152{{define "IsFunctionExported"}} 1153 {{AssertType $ "Function"}} 1154 1155 {{if (Macro "IsFunctionSupported" $)}} 1156 {{$ext := GetAnnotation $ "extension"}} 1157 {{if $ext}} 1158 {{Macro "IsExtensionExported" $ext}} 1159 {{else}} 1160 true 1161 {{end}} 1162 {{end}} 1163{{end}} 1164 1165 1166{{/* 1167------------------------------------------------------------------------------ 1168 Emit "true" if an extension is unsupportable on Android. 1169------------------------------------------------------------------------------ 1170*/}} 1171{{define "IsExtensionBlocked"}} 1172 {{$ext := index $.Arguments 0}} 1173 {{ if eq $ext "VK_KHR_display"}}true 1174 {{else if eq $ext "VK_KHR_display_swapchain"}}true 1175 {{else if eq $ext "VK_KHR_mir_surface"}}true 1176 {{else if eq $ext "VK_KHR_xcb_surface"}}true 1177 {{else if eq $ext "VK_KHR_xlib_surface"}}true 1178 {{else if eq $ext "VK_KHR_wayland_surface"}}true 1179 {{else if eq $ext "VK_KHR_win32_surface"}}true 1180 {{else if eq $ext "VK_KHR_external_memory_win32"}}true 1181 {{else if eq $ext "VK_KHR_win32_keyed_mutex"}}true 1182 {{else if eq $ext "VK_KHR_external_semaphore_win32"}}true 1183 {{else if eq $ext "VK_KHR_external_fence_win32"}}true 1184 {{else if eq $ext "VK_EXT_acquire_xlib_display"}}true 1185 {{else if eq $ext "VK_EXT_direct_mode_display"}}true 1186 {{else if eq $ext "VK_EXT_display_surface_counter"}}true 1187 {{else if eq $ext "VK_EXT_display_control"}}true 1188 {{else if eq $ext "VK_FUCHSIA_imagepipe_surface"}}true 1189 {{else if eq $ext "VK_MVK_ios_surface"}}true 1190 {{else if eq $ext "VK_MVK_macos_surface"}}true 1191 {{else if eq $ext "VK_NN_vi_surface"}}true 1192 {{else if eq $ext "VK_NV_external_memory_win32"}}true 1193 {{else if eq $ext "VK_NV_win32_keyed_mutex"}}true 1194 {{end}} 1195{{end}} 1196 1197 1198{{/* 1199------------------------------------------------------------------------------ 1200 Reports whether an extension has functions exported by the loader. 1201 E.g. applications can directly link to an extension function. 1202------------------------------------------------------------------------------ 1203*/}} 1204{{define "IsExtensionExported"}} 1205 {{$ext := index $.Arguments 0}} 1206 {{ if eq $ext "VK_KHR_surface"}}true 1207 {{else if eq $ext "VK_KHR_swapchain"}}true 1208 {{else if eq $ext "VK_KHR_android_surface"}}true 1209 {{else if eq $ext "VK_ANDROID_external_memory_android_hardware_buffer"}}true 1210 {{end}} 1211{{end}} 1212 1213 1214{{/* 1215------------------------------------------------------------------------------ 1216 Reports whether an extension is internal to the loader and drivers, 1217 so the loader should not enumerate it. 1218------------------------------------------------------------------------------ 1219*/}} 1220{{define "IsExtensionInternal"}} 1221 {{$ext := index $.Arguments 0}} 1222 {{ if eq $ext "VK_ANDROID_native_buffer"}}true 1223 {{end}} 1224{{end}} 1225