1 //
2 // Copyright (C) 2024 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #ifndef VULKAN_XML_H_
18 #define VULKAN_XML_H_
19
20 #include <unistd.h>
21
22 #include <cstdint>
23
24 #include "berberis/base/bit_util.h"
25 #include "berberis/base/struct_check.h"
26 #ifndef BERBERIS_LAYOUT_CHECK_ONLY
27 #include "berberis/guest_abi/function_wrappers.h"
28 #include "berberis/guest_abi/guest_arguments.h"
29 #include "berberis/guest_abi/guest_function_wrapper_signature.h"
30 #include "berberis/guest_abi/guest_params.h"
31 #include "berberis/guest_abi/guest_type.h"
32 #include "berberis/guest_state/guest_addr.h"
33 #include "berberis/guest_state/guest_state.h"
34 #include "berberis/runtime_primitives/guest_function_wrapper_impl.h"
35 #include "berberis/runtime_primitives/host_code.h"
36 #include "berberis/runtime_primitives/host_function_wrapper_impl.h"
37 #include "berberis/runtime_primitives/runtime_library.h"
38
39 #include "binary_search.h"
40 #endif
41
42 // Note: we only need these defines at the end of xvulkan_xml-inl.h and would like to not include it
43 // prematurely but vulkan_xml_define.h couldn't be included from vulkan_xml-inl.h when these two
44 // files are in different filegroups.
45 #include "vulkan_xml_define.h"
46
47 // These are explicitly written here as a workaround. These are platform types that are missing
48 // from vulkan_types. They are implicitly declared in the berberis namespace because the Vulkan
49 // structures that include them use the "struct X* y;" field syntax. However, they belong in the
50 // global namespace to avoid conflicts in files that include the host headers for these types,
51 // which are included via vulkan/vulkan.h.
52 struct AHardwareBuffer;
53 struct ANativeWindow;
54 struct Display;
55 struct wl_display;
56 struct xcb_connection_t;
57
58 namespace berberis {
59
60 #ifndef BERBERIS_LAYOUT_CHECK_ONLY
61
62 template <typename ResultType, typename... ArgumentType>
WrapGuestFunctionIfNeeded(GuestType<ResultType (*)(ArgumentType...)> func,const char * name)63 inline ResultType (*WrapGuestFunctionIfNeeded(GuestType<ResultType (*)(ArgumentType...)> func,
64 const char* name))(ArgumentType...) {
65 auto host_func =
66 reinterpret_cast<ResultType (*)(ArgumentType...)>(UnwrapHostFunction(ToGuestAddr(func)));
67 if (host_func) {
68 return host_func;
69 }
70 return WrapGuestFunction(func, name);
71 }
72
73 template <GuestAbi::CallingConventionsVariant kCallingConventionsVariant = GuestAbi::kDefaultAbi,
74 typename Func>
WrapHostFunctionIfNeeded(Func func,const char * name)75 inline GuestType<Func> WrapHostFunctionIfNeeded(Func func, const char* name) {
76 auto host_func = UnwrapHostFunction(ToGuestAddr(func));
77 if (!host_func) {
78 WrapHostFunction(func, name);
79 }
80 return func;
81 }
82
83 class GuestHolderBase {
84 public:
85 GuestHolderBase() = default;
86 virtual ~GuestHolderBase() = default;
87 };
88
89 class HostHolderBase {
90 public:
91 HostHolderBase() = default;
92 virtual ~HostHolderBase() = default;
93 };
94
95 // Note: anonymous namespace is subtly different from static: each anonymous namespace has internal
96 // unique name, but is imported into encompassing namespace.
97 //
98 // It's unclear whether it's valid to declare function in one such namespace and then define in the
99 // other one: MSVC says it's impossible, other compilers allow that.
100 //
101 // But even compilers which support such use are confused when friend delaration is used.
102 //
103 // Use of “static” works without any surprises: https://godbolt.org/z/sczb7r5Gn
104 static const void* ConvertOptionalStructures(GuestType<const void*> head,
105 std::unique_ptr<HostHolderBase>& holder,
106 bool& out_of_memory);
107 static void* ConvertOptionalStructures(GuestType<void*> head,
108 std::unique_ptr<HostHolderBase>& holder,
109 bool& out_of_memory);
110 static GuestType<const void*> ConvertOptionalStructures(const void* head,
111 std::unique_ptr<GuestHolderBase>& holder,
112 bool& out_of_memory);
113 static GuestType<void*> ConvertOptionalStructures(void* head,
114 std::unique_ptr<GuestHolderBase>& holder,
115 bool& out_of_memory);
116 #endif // BERBERIS_LAYOUT_CHECK_ONLY
117
118 namespace {
119
120 #define BERBERIS_VK_DEFINE_HANDLE(name) using name = struct name##_T*
121
122 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || \
123 defined(_M_X64) || defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || \
124 defined(__powerpc64__)
125 #define BERBERIS_VK_DEFINE_NON_DISPATCHABLE_HANDLE(name) \
126 BERBERIS_VK_DEFINE_HANDLE(name)
127 #else
128 #define BERBERIS_VK_DEFINE_NON_DISPATCHABLE_HANDLE(name) using name = std::uint64_t
129 #endif
130
131 #if defined(_WIN32)
132 // On Windows, Vulkan commands use the stdcall convention
133 #define BERBERIS_VKAPI_PTR __stdcall
134 #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
135 // 32bit Android ARMv6 or earlier don't support Vulkan by design.
136 #error "Vulkan isn't supported for the 'armeabi' NDK ABI"
137 #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
138 // 32bit Android ARMv7+ are using aapcs-vfp.
139 #define BERBERIS_VKAPI_PTR __attribute__((pcs("aapcs-vfp")))
140 #else
141 // On other platforms, use the default calling convention
142 #define BERBERIS_VKAPI_PTR
143 #endif
144
145 // API Constants.
146 // TODO(232598137): Parse them from XML instead.
147 constexpr uint32_t BERBERIS_VK_TRUE = 1;
148 constexpr uint32_t BERBERIS_VK_FALSE = 0;
149
150 #include "vulkan_xml-inl.h" // generated file NOLINT [build/include]
151
152 #endif // VULKAN_XML_H_
153