• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"}}
3435// WARNING: This file is generated. See ../README.md for instructions.
3637#ifndef LIBVULKAN_API_GEN_H
38#define LIBVULKAN_API_GEN_H
3940#include <bitset>
41#include <vulkan/vulkan.h>
42#include "driver_gen.h"
4344namespace vulkan {«
45namespace api {«
4647struct 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};
5657struct 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};
6667bool 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);
7576»} // namespace api
77»} // namespace vulkan
7879#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"}}
9091// WARNING: This file is generated. See ../README.md for instructions.
9293#include <string.h>
9495#include <algorithm>
9697#include <log/log.h>
9899// to catch mismatches between vulkan.h and this file
100#undef VK_NO_PROTOTYPES
101#include "api.h"
102103namespace vulkan {«
104namespace api {«
105106{{Macro "C++.DefineInitProcMacro" "dispatch"}}
107108{{Macro "api.C++.DefineInitProcExtMacro"}}
109110namespace {«
111112// clang-format off
113114{{range $f := AllCommands $}}
115  {{Macro "api.C++.DefineExtensionStub" $f}}
116{{end}}
117// clang-format on
118119»} // anonymous
120121bool 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;
127128    // 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
135136    return success;
137}
138139bool 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;
145146    // 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
153154    return success;
155}
156157// clang-format off
158159namespace {«
160161// 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}}
167168{{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    }
179180  {{end}}
181{{end}}
182183»}  // anonymous namespace
184185// clang-format on
186187»} // namespace api
188»} // namespace vulkan
189190// clang-format off
191192{{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    }
199200  {{end}}
201{{end}}
202203// clang-format on
204¶{{end}}
205
206
207{{/*
208-------------------------------------------------------------------------------
209  driver_gen.h
210-------------------------------------------------------------------------------
211*/}}
212{{define "driver_gen.h"}}
213{{Macro "Copyright"}}
214215// WARNING: This file is generated. See ../README.md for instructions.
216217#ifndef LIBVULKAN_DRIVER_GEN_H
218#define LIBVULKAN_DRIVER_GEN_H
219220#include <bitset>
221#include <vulkan/vulkan.h>
222#include <vulkan/vk_android_native_buffer.h>
223224namespace vulkan {«
225namespace driver {«
226227{{Macro "driver.C++.DefineProcHookType"}}
228229struct 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};
238239struct 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};
248249const ProcHook* GetProcHook(const char* name);
250ProcHook::Extension GetProcHookExtension(const char* name);
251252bool 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);
256257»} // namespace driver
258»} // namespace vulkan
259260#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"}}
271272// WARNING: This file is generated. See ../README.md for instructions.
273274#include <string.h>
275276#include <algorithm>
277278#include <log/log.h>
279280#include "driver.h"
281282namespace vulkan {«
283namespace driver {«
284285namespace {«
286287// clang-format off
288289{{range $f := AllCommands $}}
290  {{Macro "driver.C++.DefineProcHookStub" $f}}
291{{end}}
292// clang-format on
293294const 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};
309310»} // anonymous
311312const 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}
320321ProcHook::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}
330331{{Macro "C++.DefineInitProcMacro" "driver"}}
332333{{Macro "driver.C++.DefineInitProcExtMacro"}}
334335bool 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;
340341    // 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
348349    return success;
350}
351352bool 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;
357358    // 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
365366    return success;
367}
368369»} // namespace driver
370»} // namespace vulkan
371372// 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)
395396  #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    }
533534  {{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}}
554555    ALOGE("invalid vkGetInstanceProcAddr(VK_NULL_HANDLE, \"%s\") call", pName);
556    return nullptr;
557  }
558559  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
601602{{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  }
617618  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
640641  {{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}}
654655{{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
706{{end}}
707
708
709{{/*
710------------------------------------------------------------------------------
711  Emits true if an extension is intercepted by vulkan::driver.
712------------------------------------------------------------------------------
713*/}}
714{{define "driver.IsExtensionIntercepted"}}
715  {{$ext_name := index $.Arguments 0}}
716  {{$filters := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
717
718  {{range $f := $filters}}
719    {{if eq $ext_name $f}}true{{end}}
720  {{end}}
721{{end}}
722
723
724{{/*
725------------------------------------------------------------------------------
726  Emits true if a function is intercepted by vulkan::driver.
727------------------------------------------------------------------------------
728*/}}
729{{define "driver.IsIntercepted"}}
730  {{AssertType $ "Function"}}
731
732  {{if (Macro "IsFunctionSupported" $)}}
733    {{/* Create functions of dispatchable objects */}}
734    {{     if eq $.Name "vkCreateInstance"}}true
735    {{else if eq $.Name "vkCreateDevice"}}true
736    {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true
737    {{else if eq $.Name "vkEnumeratePhysicalDeviceGroups"}}true
738    {{else if eq $.Name "vkGetDeviceQueue"}}true
739    {{else if eq $.Name "vkGetDeviceQueue2"}}true
740    {{else if eq $.Name "vkAllocateCommandBuffers"}}true
741
742    {{/* Destroy functions of dispatchable objects */}}
743    {{else if eq $.Name "vkDestroyInstance"}}true
744    {{else if eq $.Name "vkDestroyDevice"}}true
745
746    {{/* Enumeration of extensions */}}
747    {{else if eq $.Name "vkEnumerateInstanceExtensionProperties"}}true
748    {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
749
750    {{else if eq $.Name "vkGetInstanceProcAddr"}}true
751    {{else if eq $.Name "vkGetDeviceProcAddr"}}true
752
753    {{end}}
754
755    {{$ext := GetAnnotation $ "extension"}}
756    {{if $ext}}
757      {{Macro "driver.IsExtensionIntercepted" $ext}}
758    {{end}}
759
760  {{end}}
761{{end}}
762
763
764{{/*
765------------------------------------------------------------------------------
766  Emits true if a function needs a ProcHook stub.
767------------------------------------------------------------------------------
768*/}}
769{{define "driver.NeedProcHookStub"}}
770  {{AssertType $ "Function"}}
771
772  {{if and (Macro "driver.IsIntercepted" $) (Macro "IsDeviceDispatched" $)}}
773    {{$ext := GetAnnotation $ "extension"}}
774    {{if $ext}}
775      {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}}
776    {{end}}
777  {{end}}
778{{end}}
779
780
781{{/*
782-------------------------------------------------------------------------------
783  Emits definition of struct ProcHook.
784-------------------------------------------------------------------------------
785*/}}
786{{define "driver.C++.DefineProcHookType"}}
787  struct ProcHook {
788      enum Type {
789        GLOBAL,
790        INSTANCE,
791        DEVICE,
792      };
793
794      enum Extension {
795        {{$exts := Strings (Macro "driver.KnownExtensions") | SplitOn "\n"}}
796        {{range $e := $exts}}
797          {{TrimPrefix "VK_" $e}},
798        {{end}}
799800        EXTENSION_CORE, // valid bit
801        EXTENSION_COUNT,
802        EXTENSION_UNKNOWN,
803      };
804805      const char* name;
806      Type type;
807      Extension extension;
808809      PFN_vkVoidFunction proc;
810      PFN_vkVoidFunction checked_proc;  // always nullptr for non-device hooks
811  };
812{{end}}
813
814
815{{/*
816-------------------------------------------------------------------------------
817  Emits INIT_PROC_EXT macro for vulkan::driver.
818-------------------------------------------------------------------------------
819*/}}
820{{define "driver.C++.DefineInitProcExtMacro"}}
821  #define INIT_PROC_EXT(ext, required, obj, proc) do {          \
822      if (extensions[ProcHook::ext])                            \
823        INIT_PROC(required, obj, proc);                         \
824  } while(0)
825{{end}}
826
827
828{{/*
829-------------------------------------------------------------------------------
830  Emits a stub for ProcHook::checked_proc.
831-------------------------------------------------------------------------------
832*/}}
833{{define "driver.C++.DefineProcHookStub"}}
834  {{AssertType $ "Function"}}
835
836  {{if (Macro "driver.NeedProcHookStub" $)}}
837    {{$ext := GetAnnotation $ "extension"}}
838    {{$ext_name := index $ext.Arguments 0}}
839
840    {{$base := (Macro "BaseName" $)}}
841
842    VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) {
843      {{$p0 := index $.CallParameters 0}}
844      {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}}
845
846      if (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) {
847        {{if not (IsVoid $.Return.Type)}}return §{{end}}
848        {{$base}}({{Macro "Arguments" $}});
849      } else {
850        Logger({{$p0.Name}}).Err({{$p0.Name}}, "{{$ext_name}} not enabled. {{$.Name}} not executed.");
851        {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
852      }
853    }
854855  {{end}}
856{{end}}
857
858
859{{/*
860-------------------------------------------------------------------------------
861  Emits definition of a global ProcHook.
862-------------------------------------------------------------------------------
863*/}}
864{{define "driver.C++.DefineGlobalProcHook"}}
865  {{AssertType $ "Function"}}
866
867  {{$base := (Macro "BaseName" $)}}
868
869  {{$ext := GetAnnotation $ "extension"}}
870  {{if $ext}}
871    {{Error "invalid global extension"}}
872  {{end}}
873
874  {
875    "{{$.Name}}",
876    ProcHook::GLOBAL,
877    ProcHook::EXTENSION_CORE,
878    reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
879    nullptr,
880  },
881{{end}}
882
883
884{{/*
885-------------------------------------------------------------------------------
886  Emits definition of an instance ProcHook.
887-------------------------------------------------------------------------------
888*/}}
889{{define "driver.C++.DefineInstanceProcHook"}}
890  {{AssertType $ "Function"}}
891
892  {{$base := (Macro "BaseName" $)}}
893
894  {
895    "{{$.Name}}",
896    ProcHook::INSTANCE,
897
898    {{$ext := GetAnnotation $ "extension"}}
899    {{if $ext}}
900      ProcHook::{{Macro "BaseName" $ext}},
901
902      {{if (Macro "IsExtensionInternal" $ext)}}
903        nullptr,
904        nullptr,
905      {{else}}
906        reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
907        nullptr,
908      {{end}}
909    {{else}}
910      ProcHook::EXTENSION_CORE,
911      reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
912      nullptr,
913    {{end}}
914  },
915{{end}}
916
917
918{{/*
919-------------------------------------------------------------------------------
920  Emits definition of a device ProcHook.
921-------------------------------------------------------------------------------
922*/}}
923{{define "driver.C++.DefineDeviceProcHook"}}
924  {{AssertType $ "Function"}}
925
926  {{$base := (Macro "BaseName" $)}}
927
928  {
929    "{{$.Name}}",
930    ProcHook::DEVICE,
931
932    {{$ext := GetAnnotation $ "extension"}}
933    {{if $ext}}
934      ProcHook::{{Macro "BaseName" $ext}},
935
936      {{if (Macro "IsExtensionInternal" $ext)}}
937        nullptr,
938        nullptr,
939      {{else}}
940        reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
941        reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}),
942      {{end}}
943    {{else}}
944      ProcHook::EXTENSION_CORE,
945      reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
946      nullptr,
947    {{end}}
948  },
949{{end}}
950
951
952{{/*
953-------------------------------------------------------------------------------
954  Emits true if a function is needed by vulkan::driver.
955-------------------------------------------------------------------------------
956*/}}
957{{define "driver.IsDriverTableEntry"}}
958  {{AssertType $ "Function"}}
959
960  {{if (Macro "IsFunctionSupported" $)}}
961    {{/* Create functions of dispatchable objects */}}
962    {{     if eq $.Name "vkCreateDevice"}}true
963    {{else if eq $.Name "vkGetDeviceQueue"}}true
964    {{else if eq $.Name "vkGetDeviceQueue2"}}true
965    {{else if eq $.Name "vkAllocateCommandBuffers"}}true
966
967    {{/* Destroy functions of dispatchable objects */}}
968    {{else if eq $.Name "vkDestroyInstance"}}true
969    {{else if eq $.Name "vkDestroyDevice"}}true
970
971    {{/* Enumeration of extensions */}}
972    {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
973
974    {{/* We cache physical devices in loader.cpp */}}
975    {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true
976    {{else if eq $.Name "vkEnumeratePhysicalDeviceGroups"}}true
977
978    {{else if eq $.Name "vkGetInstanceProcAddr"}}true
979    {{else if eq $.Name "vkGetDeviceProcAddr"}}true
980
981    {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}}
982    {{else if eq $.Name "vkCreateImage"}}true
983    {{else if eq $.Name "vkDestroyImage"}}true
984
985    {{else if eq $.Name "vkGetPhysicalDeviceProperties"}}true
986    {{else if eq $.Name "vkGetPhysicalDeviceProperties2"}}true
987    {{else if eq $.Name "vkGetPhysicalDeviceProperties2KHR"}}true
988    {{end}}
989
990    {{$ext := GetAnnotation $ "extension"}}
991    {{if $ext}}
992      {{$ext_name := index $ext.Arguments 0}}
993      {{     if eq $ext_name "VK_ANDROID_native_buffer"}}true
994      {{else if eq $ext_name "VK_EXT_debug_report"}}true
995      {{end}}
996    {{end}}
997  {{end}}
998{{end}}
999
1000
1001{{/*
1002------------------------------------------------------------------------------
1003  Emits true if an instance-dispatched function is needed by vulkan::driver.
1004------------------------------------------------------------------------------
1005*/}}
1006{{define "driver.IsInstanceDriverTableEntry"}}
1007  {{AssertType $ "Function"}}
1008
1009  {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}}
1010    true
1011  {{end}}
1012{{end}}
1013
1014
1015{{/*
1016------------------------------------------------------------------------------
1017  Emits true if a device-dispatched function is needed by vulkan::driver.
1018------------------------------------------------------------------------------
1019*/}}
1020{{define "driver.IsDeviceDriverTableEntry"}}
1021  {{AssertType $ "Function"}}
1022
1023  {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}}
1024    true
1025  {{end}}
1026{{end}}
1027
1028
1029{{/*
1030-------------------------------------------------------------------------------
1031  Emits a function/extension name without the "vk"/"VK_" prefix.
1032-------------------------------------------------------------------------------
1033*/}}
1034{{define "BaseName"}}
1035  {{     if IsFunction $}}{{TrimPrefix "vk" $.Name}}
1036  {{else if eq $.Name "extension"}}{{TrimPrefix "VK_" (index $.Arguments 0)}}
1037  {{else}}{{Error "invalid use of BaseName"}}
1038  {{end}}
1039{{end}}
1040
1041
1042{{/*
1043-------------------------------------------------------------------------------
1044  Emits a comma-separated list of C parameter names for the given command.
1045-------------------------------------------------------------------------------
1046*/}}
1047{{define "Arguments"}}
1048  {{AssertType $ "Function"}}
1049
1050  {{ForEach $.CallParameters "ParameterName" | JoinWith ", "}}
1051{{end}}
1052
1053
1054{{/*
1055------------------------------------------------------------------------------
1056------------------------------------------------------------------------------
1057*/}}
1058{{define "IsGloballyDispatched"}}
1059  {{AssertType $ "Function"}}
1060  {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Global")}}
1061    true
1062  {{end}}
1063{{end}}
1064
1065
1066{{/*
1067------------------------------------------------------------------------------
1068  Emit "true" for supported functions that undergo table dispatch. Only global
1069  functions and functions handled in the loader top without calling into
1070  lower layers are not dispatched.
1071------------------------------------------------------------------------------
1072*/}}
1073{{define "IsInstanceDispatched"}}
1074  {{AssertType $ "Function"}}
1075  {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}}
1076    true
1077  {{end}}
1078{{end}}
1079
1080
1081{{/*
1082------------------------------------------------------------------------------
1083  Emit "true" for supported functions that can have device-specific dispatch.
1084------------------------------------------------------------------------------
1085*/}}
1086{{define "IsDeviceDispatched"}}
1087  {{AssertType $ "Function"}}
1088  {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Device")}}
1089    true
1090  {{end}}
1091{{end}}
1092
1093
1094{{/*
1095------------------------------------------------------------------------------
1096  Emit "true" if a function is core or from a supportable extension.
1097------------------------------------------------------------------------------
1098*/}}
1099{{define "IsFunctionSupported"}}
1100  {{AssertType $ "Function"}}
1101  {{if not (GetAnnotation $ "pfn")}}
1102    {{$ext := GetAnnotation $ "extension"}}
1103    {{if not $ext}}true
1104    {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true
1105    {{end}}
1106  {{end}}
1107{{end}}
1108
1109
1110{{/*
1111------------------------------------------------------------------------------
1112  Decides whether a function should be exported from the Android Vulkan
1113  library. Functions in the core API and in loader extensions are exported.
1114------------------------------------------------------------------------------
1115*/}}
1116{{define "IsFunctionExported"}}
1117  {{AssertType $ "Function"}}
1118
1119  {{if (Macro "IsFunctionSupported" $)}}
1120    {{$ext := GetAnnotation $ "extension"}}
1121    {{if $ext}}
1122      {{Macro "IsExtensionExported" $ext}}
1123    {{else}}
1124      true
1125    {{end}}
1126  {{end}}
1127{{end}}
1128
1129
1130{{/*
1131------------------------------------------------------------------------------
1132  Emit "true" if an extension is unsupportable on Android.
1133------------------------------------------------------------------------------
1134*/}}
1135{{define "IsExtensionBlacklisted"}}
1136  {{$ext := index $.Arguments 0}}
1137  {{     if eq $ext "VK_KHR_display"}}true
1138  {{else if eq $ext "VK_KHR_display_swapchain"}}true
1139  {{else if eq $ext "VK_KHR_mir_surface"}}true
1140  {{else if eq $ext "VK_KHR_xcb_surface"}}true
1141  {{else if eq $ext "VK_KHR_xlib_surface"}}true
1142  {{else if eq $ext "VK_KHR_wayland_surface"}}true
1143  {{else if eq $ext "VK_KHR_win32_surface"}}true
1144  {{else if eq $ext "VK_KHR_external_memory_win32"}}true
1145  {{else if eq $ext "VK_KHR_win32_keyed_mutex"}}true
1146  {{else if eq $ext "VK_KHR_external_semaphore_win32"}}true
1147  {{else if eq $ext "VK_KHR_external_fence_win32"}}true
1148  {{else if eq $ext "VK_EXT_acquire_xlib_display"}}true
1149  {{else if eq $ext "VK_EXT_direct_mode_display"}}true
1150  {{else if eq $ext "VK_EXT_display_surface_counter"}}true
1151  {{else if eq $ext "VK_EXT_display_control"}}true
1152  {{else if eq $ext "VK_MVK_ios_surface"}}true
1153  {{else if eq $ext "VK_MVK_macos_surface"}}true
1154  {{else if eq $ext "VK_NN_vi_surface"}}true
1155  {{else if eq $ext "VK_NV_external_memory_win32"}}true
1156  {{else if eq $ext "VK_NV_win32_keyed_mutex"}}true
1157  {{end}}
1158{{end}}
1159
1160
1161{{/*
1162------------------------------------------------------------------------------
1163  Reports whether an extension has functions exported by the loader.
1164  E.g. applications can directly link to an extension function.
1165------------------------------------------------------------------------------
1166*/}}
1167{{define "IsExtensionExported"}}
1168  {{$ext := index $.Arguments 0}}
1169  {{     if eq $ext "VK_KHR_surface"}}true
1170  {{else if eq $ext "VK_KHR_swapchain"}}true
1171  {{else if eq $ext "VK_KHR_android_surface"}}true
1172  {{else if eq $ext "VK_ANDROID_external_memory_android_hardware_buffer"}}true
1173  {{end}}
1174{{end}}
1175
1176
1177{{/*
1178------------------------------------------------------------------------------
1179  Reports whether an extension is internal to the loader and drivers,
1180  so the loader should not enumerate it.
1181------------------------------------------------------------------------------
1182*/}}
1183{{define "IsExtensionInternal"}}
1184  {{$ext := index $.Arguments 0}}
1185  {{     if eq $ext "VK_ANDROID_native_buffer"}}true
1186  {{end}}
1187{{end}}
1188