blob: d4ced56bb52ce3951800c0818aadb570aad6c58e [file] [log] [blame]
Jesse Hall04f4f472015-08-16 19:51:04 -07001{{Include "../api/templates/vulkan_common.tmpl"}}
2{{Global "clang-format" (Strings "clang-format" "-style=file")}}
3{{Macro "DefineGlobals" $}}
4{{$ | Macro "get_proc_addr.cpp" | Format (Global "clang-format") | Write "get_proc_addr.cpp"}}
5
6
7{{/*
8-------------------------------------------------------------------------------
9 Entry point
10-------------------------------------------------------------------------------
11*/}}
12{{define "get_proc_addr.cpp"}}
13/*
14 * Copyright 2015 The Android Open Source Project
15 *
16 * Licensed under the Apache License, Version 2.0 (the "License");
17 * you may not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 *
20 * http://www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an "AS IS" BASIS,
24 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28
29// This file is generated. Do not edit manually!
30// To regenerate: $ apic template ../api/vulkan.api get_proc_addr.cpp.tmpl
31// Requires apic from https://android.googlesource.com/platform/tools/gpu/.
32
33#include <algorithm>
34#include <log/log.h>
35#include "loader.h"
36using namespace vulkan;
37
38#define UNLIKELY(expr) __builtin_expect((expr), 0)
39
40namespace {
41
42struct NameProcEntry {
43 const char* name;
44 PFN_vkVoidFunction proc;
45};
46
47struct NameOffsetEntry {
48 const char* name;
49 size_t offset;
50};
51
52template <typename TEntry, size_t N>
53const TEntry* FindProcEntry(const TEntry(&table)[N], const char* name) {
54 auto entry = std::lower_bound(
55 table, table + N, name,
56 [](const TEntry& e, const char* n) { return strcmp(e.name, n) < 0; });
57 if (entry != (table + N) && strcmp(entry->name, name) == 0)
58 return entry;
59 return nullptr;
60}
61
62const NameProcEntry kInstanceProcTbl[] =
63 // clang-format off
64 {{range $f := SortBy (AllCommands $) "FunctionName"}}
65 {{if eq (Macro "Vtbl" $f) "Instance"}}
66 {"{{Macro "FunctionName" $f}}", reinterpret_cast<PFN_vkVoidFunction>({{Macro "FunctionName" $f}})},
67 {{end}}
68 {{end}}
69 // clang-format on
70»};
71
72const NameProcEntry kDeviceProcTbl[] =
73 // clang-format off
74 {{range $f := SortBy (AllCommands $) "FunctionName"}}
75 {{if eq (Macro "Vtbl" $f) "Device"}}
76 {"{{Macro "FunctionName" $f}}", reinterpret_cast<PFN_vkVoidFunction>({{Macro "FunctionName" $f}})},
77 {{end}}
78 {{end}}
79 // clang-format on
80»};
81
82const NameOffsetEntry kInstanceOffsetTbl[] =
83 // clang-format off
84 {{range $f := SortBy (AllCommands $) "FunctionName"}}
85 {{if eq (Macro "Vtbl" $f) "Instance"}}
86 {"{{Macro "FunctionName" $f}}", offsetof(InstanceVtbl, {{TrimPrefix "vk" (Macro "FunctionName" $f)}})},
87 {{end}}
88 {{end}}
89 // clang-format on
90»};
91
92const NameOffsetEntry kDeviceOffsetTbl[] =
93 // clang-format off
94 {{range $f := SortBy (AllCommands $) "FunctionName"}}
95 {{if eq (Macro "Vtbl" $f) "Device"}}
96 {"{{Macro "FunctionName" $f}}", offsetof(DeviceVtbl, {{TrimPrefix "vk" (Macro "FunctionName" $f)}})},
97 {{end}}
98 {{end}}
99 // clang-format on
100»};
101
102} // namespace
103
104namespace vulkan {
105
106PFN_vkVoidFunction GetGlobalInstanceProcAddr(const char* name) {
107 if (strcmp(name, "vkGetDeviceProcAddr") == 0)
108 return reinterpret_cast<PFN_vkVoidFunction>(vkGetDeviceProcAddr);
109 const NameProcEntry* entry = FindProcEntry(kInstanceProcTbl, name);
110 return entry ? entry->proc : nullptr;
111}
112
113PFN_vkVoidFunction GetGlobalDeviceProcAddr(const char* name) {
114 const NameProcEntry* entry = FindProcEntry(kDeviceProcTbl, name);
115 return entry ? entry->proc : nullptr;
116}
117
118PFN_vkVoidFunction GetSpecificInstanceProcAddr(const InstanceVtbl* vtbl,
119 const char* name) {
120 const NameOffsetEntry* entry = FindProcEntry(kInstanceOffsetTbl, name);
121 if (!entry)
122 return nullptr;
123 const unsigned char* base = reinterpret_cast<const unsigned char*>(vtbl);
124 return reinterpret_cast<PFN_vkVoidFunction>(
125 const_cast<unsigned char*>(base) + entry->offset);
126}
127
128PFN_vkVoidFunction GetSpecificDeviceProcAddr(const DeviceVtbl* vtbl,
129 const char* name) {
130 const NameOffsetEntry* entry = FindProcEntry(kDeviceOffsetTbl, name);
131 if (!entry)
132 return nullptr;
133 const unsigned char* base = reinterpret_cast<const unsigned char*>(vtbl);
134 return reinterpret_cast<PFN_vkVoidFunction>(
135 const_cast<unsigned char*>(base) + entry->offset);
136}
137
138bool LoadInstanceVtbl(VkInstance instance,
139 PFN_vkGetInstanceProcAddr get_proc_addr,
140 InstanceVtbl& vtbl)
141 bool success = true;
142 // clang-format off
143 {{range $f := AllCommands $}}
144 {{if eq (Macro "Vtbl" $f) "Instance"}}
145 vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}} = §
146 reinterpret_cast<{{Macro "FunctionPtrName" $f}}>(§
147 get_proc_addr(instance, "{{Macro "FunctionName" $f}}"));
148 if (UNLIKELY(!vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}})) {
149 ALOGE("missing instance proc: %s", "{{Macro "FunctionName" $f}}");
150 success = false;
151 }
152 {{end}}
153 {{end}}
154 // clang-format on
155 return success;
156»}
157
158bool LoadDeviceVtbl(VkDevice device,
159 PFN_vkGetDeviceProcAddr get_proc_addr,
160 DeviceVtbl& vtbl)
161 bool success = true;
162 // clang-format off
163 {{range $f := AllCommands $}}
164 {{if eq (Macro "Vtbl" $f) "Device"}}
165 vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}} = §
166 reinterpret_cast<{{Macro "FunctionPtrName" $f}}>(§
167 get_proc_addr(device, "{{Macro "FunctionName" $f}}"));
168 if (UNLIKELY(!vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}})) {
169 ALOGE("missing device proc: %s", "{{Macro "FunctionName" $f}}");
170 success = false;
171 }
172 {{end}}
173 {{end}}
174 // clang-format on
175 return success;
176»}
177
178} // namespace vulkan
179
180{{end}}