| {{/* |
| * Copyright 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */}} |
| |
| {{Include "../api/templates/vulkan_common.tmpl"}} |
| {{Global "clang-format" (Strings "clang-format" "-style=file")}} |
| {{Macro "DefineGlobals" $}} |
| {{$ | Macro "dispatch_gen.h" | Format (Global "clang-format") | Write "dispatch_gen.h" }} |
| {{$ | Macro "dispatch_gen.cpp" | Format (Global "clang-format") | Write "dispatch_gen.cpp"}} |
| |
| {{/* |
| ------------------------------------------------------------------------------- |
| dispatch_gen.h |
| ------------------------------------------------------------------------------- |
| */}} |
| {{define "dispatch_gen.h"}} |
| /* |
| •* Copyright 2015 The Android Open Source Project |
| •* |
| •* Licensed under the Apache License, Version 2.0 (the "License"); |
| •* you may not use this file except in compliance with the License. |
| •* You may obtain a copy of the License at |
| •* |
| •* http://www.apache.org/licenses/LICENSE-2.0 |
| •* |
| •* Unless required by applicable law or agreed to in writing, software |
| •* distributed under the License is distributed on an "AS IS" BASIS, |
| •* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| •* See the License for the specific language governing permissions and |
| •* limitations under the License. |
| •*/ |
| ¶ |
| // WARNING: This file is generated. See ../README.md for instructions. |
| ¶ |
| #include <vulkan/vk_android_native_buffer.h> |
| #include <vulkan/vulkan.h> |
| ¶ |
| namespace vulkan { |
| ¶ |
| struct DriverDispatchTable {« |
| // clang-format off |
| {{range $f := AllCommands $}} |
| {{if (Macro "IsInstanceDispatched" $f)}} |
| {{if not (Macro "IsLoaderFunction" $f)}} |
| {{Macro "FunctionPtrName" $f}} {{Macro "BaseName" $f}}; |
| {{end}} |
| {{end}} |
| {{end}} |
| |
| PFN_vkGetDeviceProcAddr GetDeviceProcAddr; |
| |
| PFN_vkDestroyDevice DestroyDevice; |
| PFN_vkGetDeviceQueue GetDeviceQueue; |
| PFN_vkAllocateCommandBuffers AllocateCommandBuffers; |
| |
| {{/* TODO(jessehall): Needed by swapchain code. Figure out a better way of |
| handling this that avoids the special case. Probably should rework |
| things so the driver dispatch table has all driver functions. Probably |
| need separate instance- and device-level copies, fill in all device- |
| dispatched functions in the device-level copies only, and change |
| GetDeviceProcAddr_Bottom to look in the already-loaded driver |
| dispatch table rather than forwarding to the driver's |
| vkGetDeviceProcAddr. */}} |
| PFN_vkCreateImage CreateImage; |
| PFN_vkDestroyImage DestroyImage; |
| |
| PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID; |
| PFN_vkAcquireImageANDROID AcquireImageANDROID; |
| PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID; |
| // clang-format on |
| »}; |
| ¶ |
| } // namespace vulkan |
| ¶{{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------- |
| dispatch_gen.cpp |
| ------------------------------------------------------------------------------- |
| */}} |
| {{define "dispatch_gen.cpp"}} |
| /* |
| •* Copyright 2015 The Android Open Source Project |
| •* |
| •* Licensed under the Apache License, Version 2.0 (the "License"); |
| •* you may not use this file except in compliance with the License. |
| •* You may obtain a copy of the License at |
| •* |
| •* http://www.apache.org/licenses/LICENSE-2.0 |
| •* |
| •* Unless required by applicable law or agreed to in writing, software |
| •* distributed under the License is distributed on an "AS IS" BASIS, |
| •* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| •* See the License for the specific language governing permissions and |
| •* limitations under the License. |
| •*/ |
| ¶ |
| // WARNING: This file is generated. See ../README.md for instructions. |
| ¶ |
| #include <log/log.h> |
| #include <algorithm> |
| #include "loader.h" |
| ¶ |
| #define UNLIKELY(expr) __builtin_expect((expr), 0) |
| ¶ |
| using namespace vulkan; |
| ¶ |
| namespace { |
| ¶ |
| struct NameProc { |
| const char* name; |
| PFN_vkVoidFunction proc; |
| }; |
| ¶ |
| PFN_vkVoidFunction Lookup(const char* name, const NameProc* begin, const NameProc* end) { |
| const auto& entry = std::lower_bound( |
| begin, end, name, |
| [](const NameProc& e, const char* n) { return strcmp(e.name, n) < 0; }); |
| if (entry == end || strcmp(entry->name, name) != 0) |
| return nullptr; |
| return entry->proc; |
| } |
| ¶ |
| template <size_t N> |
| PFN_vkVoidFunction Lookup(const char* name, const NameProc (&procs)[N]) { |
| return Lookup(name, procs, procs + N); |
| } |
| ¶ |
| const NameProc kLoaderBottomProcs[] = {« |
| // clang-format off |
| {{range $f := SortBy (AllCommands $) "FunctionName"}} |
| {{if (Macro "HasLoaderBottomImpl" $f)}} |
| {"{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>(§ |
| static_cast<{{Macro "FunctionPtrName" $f}}>(§ |
| {{Macro "BaseName" $f}}_Bottom))}, |
| {{end}} |
| {{end}} |
| // clang-format on |
| »}; |
| ¶ |
| } // anonymous namespace |
| ¶ |
| namespace vulkan { |
| ¶ |
| PFN_vkVoidFunction GetLoaderBottomProcAddr(const char* name) { |
| return Lookup(name, kLoaderBottomProcs); |
| } |
| ¶ |
| bool LoadDriverDispatchTable(VkInstance instance, |
| PFN_vkGetInstanceProcAddr get_proc_addr, |
| const InstanceExtensionSet& extensions, |
| DriverDispatchTable& dispatch) {« |
| bool success = true; |
| // clang-format off |
| {{range $f := AllCommands $}} |
| {{if (Macro "IsInstanceDispatched" $f)}} |
| {{if not (Macro "IsLoaderFunction" $f)}} |
| {{$ext := GetAnnotation $f "extension"}} |
| {{if $ext}} |
| if (extensions[{{Macro "ExtensionConstant" $ext}}]) { |
| {{end}} |
| dispatch.{{Macro "BaseName" $f}} = § |
| reinterpret_cast<{{Macro "FunctionPtrName" $f}}>(§ |
| get_proc_addr(instance, "{{$f.Name}}")); |
| if (UNLIKELY(!dispatch.{{Macro "BaseName" $f}})) { |
| ALOGE("missing driver proc: %s", "{{$f.Name}}"); |
| success = false; |
| } |
| {{if $ext}} |
| } |
| {{end}} |
| {{end}} |
| {{end}} |
| {{end}} |
| dispatch.GetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(get_proc_addr(instance, "vkGetDeviceProcAddr")); |
| if (UNLIKELY(!dispatch.GetDeviceProcAddr)) { |
| ALOGE("missing driver proc: %s", "vkGetDeviceProcAddr"); |
| success = false; |
| } |
| dispatch.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(get_proc_addr(instance, "vkDestroyDevice")); |
| if (UNLIKELY(!dispatch.DestroyDevice)) { |
| ALOGE("missing driver proc: %s", "vkDestroyDevice"); |
| success = false; |
| } |
| dispatch.GetDeviceQueue = reinterpret_cast<PFN_vkGetDeviceQueue>(get_proc_addr(instance, "vkGetDeviceQueue")); |
| if (UNLIKELY(!dispatch.GetDeviceQueue)) { |
| ALOGE("missing driver proc: %s", "vkGetDeviceQueue"); |
| success = false; |
| } |
| dispatch.AllocateCommandBuffers = reinterpret_cast<PFN_vkAllocateCommandBuffers>(get_proc_addr(instance, "vkAllocateCommandBuffers")); |
| if (UNLIKELY(!dispatch.AllocateCommandBuffers)) { |
| ALOGE("missing driver proc: %s", "vkAllocateCommandBuffers"); |
| success = false; |
| } |
| dispatch.CreateImage = reinterpret_cast<PFN_vkCreateImage>(get_proc_addr(instance, "vkCreateImage")); |
| if (UNLIKELY(!dispatch.CreateImage)) { |
| ALOGE("missing driver proc: %s", "vkCreateImage"); |
| success = false; |
| } |
| dispatch.DestroyImage = reinterpret_cast<PFN_vkDestroyImage>(get_proc_addr(instance, "vkDestroyImage")); |
| if (UNLIKELY(!dispatch.DestroyImage)) { |
| ALOGE("missing driver proc: %s", "vkDestroyImage"); |
| success = false; |
| } |
| dispatch.GetSwapchainGrallocUsageANDROID = reinterpret_cast<PFN_vkGetSwapchainGrallocUsageANDROID>(get_proc_addr(instance, "vkGetSwapchainGrallocUsageANDROID")); |
| if (UNLIKELY(!dispatch.GetSwapchainGrallocUsageANDROID)) { |
| ALOGE("missing driver proc: %s", "vkGetSwapchainGrallocUsageANDROID"); |
| success = false; |
| } |
| dispatch.AcquireImageANDROID = reinterpret_cast<PFN_vkAcquireImageANDROID>(get_proc_addr(instance, "vkAcquireImageANDROID")); |
| if (UNLIKELY(!dispatch.AcquireImageANDROID)) { |
| ALOGE("missing driver proc: %s", "vkAcquireImageANDROID"); |
| success = false; |
| } |
| dispatch.QueueSignalReleaseImageANDROID = reinterpret_cast<PFN_vkQueueSignalReleaseImageANDROID>(get_proc_addr(instance, "vkQueueSignalReleaseImageANDROID")); |
| if (UNLIKELY(!dispatch.QueueSignalReleaseImageANDROID)) { |
| ALOGE("missing driver proc: %s", "vkQueueSignalReleaseImageANDROID"); |
| success = false; |
| } |
| // clang-format on |
| return success; |
| »} |
| ¶ |
| } // namespace vulkan |
| ¶{{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------- |
| Map an extension name to InstanceExtension or DeviceExtension enum value |
| ------------------------------------------------------------------------------- |
| */}} |
| {{define "ExtensionConstant"}} |
| {{$name := index $.Arguments 0}} |
| {{ if (eq $name "VK_KHR_surface")}}kKHR_surface |
| {{else if (eq $name "VK_KHR_android_surface")}}kKHR_android_surface |
| {{else if (eq $name "VK_EXT_debug_report")}}kEXT_debug_report |
| {{end}} |
| {{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------- |
| Emits a function name without the "vk" prefix. |
| ------------------------------------------------------------------------------- |
| */}} |
| {{define "BaseName"}} |
| {{AssertType $ "Function"}} |
| {{TrimPrefix "vk" $.Name}} |
| {{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------ |
| Emit "true" for supported functions that undergo table dispatch. Only global |
| functions and functions handled in the loader top without calling into |
| lower layers are not dispatched. |
| ------------------------------------------------------------------------------ |
| */}} |
| {{define "IsInstanceDispatched"}} |
| {{AssertType $ "Function"}} |
| {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}} |
| {{if and (ne $.Name "vkEnumerateDeviceLayerProperties") (ne $.Name "vkGetInstanceProcAddr")}}true{{end}} |
| {{end}} |
| {{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------ |
| Emit "true" if a function is core or from a supportable extension. |
| ------------------------------------------------------------------------------ |
| */}} |
| {{define "IsFunctionSupported"}} |
| {{AssertType $ "Function"}} |
| {{if not (GetAnnotation $ "pfn")}} |
| {{$ext := GetAnnotation $ "extension"}} |
| {{if not $ext}}true |
| {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true |
| {{end}} |
| {{end}} |
| {{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------ |
| Reports whether an extension function is implemented entirely by the loader, |
| and not implemented by drivers. |
| ------------------------------------------------------------------------------ |
| */}} |
| {{define "IsLoaderFunction"}} |
| {{AssertType $ "Function"}} |
| |
| {{$ext := GetAnnotation $ "extension"}} |
| {{if $ext}} |
| {{Macro "IsLoaderExtension" $ext}} |
| {{end}} |
| {{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------- |
| Emit "true" if the loader has a bottom-level implementation for the function |
| which terminates the dispatch chain. |
| ------------------------------------------------------------------------------- |
| */}} |
| {{define "HasLoaderBottomImpl"}} |
| {{AssertType $ "Function"}} |
| |
| {{if (Macro "IsFunctionSupported" $)}} |
| {{ if (eq (Macro "Vtbl" $) "Instance")}}true |
| {{else if (Macro "IsLoaderFunction" $)}}true |
| {{else if (eq $.Name "vkCreateInstance")}}true |
| {{else if (eq $.Name "vkGetDeviceProcAddr")}}true |
| {{else if (eq $.Name "vkDestroyDevice")}}true |
| {{else if (eq $.Name "vkGetDeviceQueue")}}true |
| {{else if (eq $.Name "vkAllocateCommandBuffers")}}true |
| {{end}} |
| {{end}} |
| {{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------ |
| Emit "true" if an extension is unsupportable on Android. |
| ------------------------------------------------------------------------------ |
| */}} |
| {{define "IsExtensionBlacklisted"}} |
| {{$ext := index $.Arguments 0}} |
| {{ if eq $ext "VK_KHR_display"}}true |
| {{else if eq $ext "VK_KHR_display_swapchain"}}true |
| {{else if eq $ext "VK_KHR_xlib_surface"}}true |
| {{else if eq $ext "VK_KHR_xcb_surface"}}true |
| {{else if eq $ext "VK_KHR_wayland_surface"}}true |
| {{else if eq $ext "VK_KHR_mir_surface"}}true |
| {{else if eq $ext "VK_KHR_win32_surface"}}true |
| {{end}} |
| {{end}} |
| |
| |
| {{/* |
| ------------------------------------------------------------------------------ |
| Reports whether an extension is implemented entirely by the loader, |
| so drivers should not enumerate it. |
| ------------------------------------------------------------------------------ |
| */}} |
| {{define "IsLoaderExtension"}} |
| {{$ext := index $.Arguments 0}} |
| {{ if eq $ext "VK_KHR_surface"}}true |
| {{else if eq $ext "VK_KHR_swapchain"}}true |
| {{else if eq $ext "VK_KHR_android_surface"}}true |
| {{end}} |
| {{end}} |