1 #ifndef _VKTEXTERNALMEMORYUTIL_HPP
2 #define _VKTEXTERNALMEMORYUTIL_HPP
3 /*-------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2016 Google Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * \brief Vulkan external memory utilities
22  *//*--------------------------------------------------------------------*/
23 
24 #include "tcuDefs.hpp"
25 
26 #include "vkPlatform.hpp"
27 #include "vkRefUtil.hpp"
28 
29 #include "deMemory.h"
30 #include "deInt32.h"
31 
32 namespace vkt
33 {
34 namespace ExternalMemoryUtil
35 {
36 
37 class NativeHandle
38 {
39 public:
40 	enum Win32HandleType
41 	{
42 		WIN32HANDLETYPE_NT = 0,
43 		WIN32HANDLETYPE_KMT,
44 
45 		WIN32HANDLETYPE_LAST
46 	};
47 
48 										NativeHandle				(void);
49 										NativeHandle				(const NativeHandle& other);
50 										NativeHandle				(int fd);
51 										NativeHandle				(Win32HandleType type, vk::pt::Win32Handle handle);
52 										NativeHandle				(vk::pt::AndroidHardwareBufferPtr buffer);
53 										~NativeHandle				(void);
54 
55 	NativeHandle&						operator=					(int fd);
56 	NativeHandle&						operator=					(vk::pt::AndroidHardwareBufferPtr buffer);
57 
58 	void								setWin32Handle				(Win32HandleType type, vk::pt::Win32Handle handle);
59 	vk::pt::Win32Handle					getWin32Handle				(void) const;
60 	void								setHostPtr					(void* hostPtr);
61 	void*								getHostPtr					(void) const;
62 	int									getFd						(void) const;
63 	vk::pt::AndroidHardwareBufferPtr	getAndroidHardwareBuffer	(void) const;
64 	void								disown						(void);
65 	void								reset						(void);
66 
67 private:
68 	int									m_fd;
69 	Win32HandleType						m_win32HandleType;
70 	vk::pt::Win32Handle					m_win32Handle;
71 	vk::pt::AndroidHardwareBufferPtr	m_androidHardwareBuffer;
72 	void*								m_hostPtr;
73 
74 	// Disabled
75 	NativeHandle&						operator=					(const NativeHandle&);
76 };
77 
78 class AndroidHardwareBufferExternalApi
79 {
80 public:
81 
82 	/**
83 	 * getInstance obtains the object, that provides an interface to AHB system APIs .
84 	 * If the AHB system API is not supported or if it is not built as supported with the CTS,
85 	 * then this function would return a null object.
86 	 */
87 	static AndroidHardwareBufferExternalApi* getInstance();
88 
89 	/* Is AndroidHardwareBuffer supported? */
90 	static bool supportsAhb();
91 
92 	/* Are Cube maps supported on current api level? */
93 	static bool supportsCubeMap();
94 
95 	/**
96 	 * Allocates a buffer that backs an AHardwareBuffer using the passed parameter as follows:
97 	 * width;      - width in pixels
98 	 * height;     - height in pixels
99 	 * layers;     - number of images
100 	 * format;     - One of AHARDWAREBUFFER_FORMAT_*
101 	 * usage;      - Combination of AHARDWAREBUFFER_USAGE_*
102 	 *
103 	 * Returns a valid AndroidHardwareBufferPtr object on success, or an null AndroidHardwareBufferPtr if
104 	 * the allocation fails for any reason.
105 	 */
106 	virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32  height, deUint32 layers, deUint32  format, deUint64 usage) = 0;
107 
108 	/**
109 	 * Acquire a reference on the given AHardwareBuffer object.  This prevents the
110 	 * object from being deleted until the last reference is removed.
111 	 */
112 	virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer) = 0;
113 
114 	/**
115 	 * Remove a reference that was previously acquired with
116 	 * AHardwareBuffer_acquire().
117 	 */
118 	virtual void release(vk::pt::AndroidHardwareBufferPtr buffer) = 0;
119 
120 	/**
121 	 * Return a description of the AHardwareBuffer in the passed in the following fields, if not NULL:
122 	 * width;      - width in pixels
123 	 * height;     - height in pixels
124 	 * layers;     - number of images
125 	 * format;     - One of AHARDWAREBUFFER_FORMAT_*
126 	 * usage;      - Combination of AHARDWAREBUFFER_USAGE_*
127 	 *
128 	 */
129 	virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer,
130 				  deUint32* width,
131 				  deUint32* height,
132 				  deUint32* layers,
133 				  deUint32* format,
134 				  deUint64* usage,
135 				  deUint32* stride) = 0;
136 
137 
138 	virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag) = 0;
139 	virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag) = 0;
140 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat) = 0;
141 	virtual deUint64 mustSupportAhbUsageFlags() = 0;
142 	virtual bool     ahbFormatIsBlob(deUint32 format) = 0;
143 
144 	virtual ~AndroidHardwareBufferExternalApi();
145 
146 protected:
147 	// Protected Constructor
148 	AndroidHardwareBufferExternalApi();
149 
150 private:
151 	// Stop the compiler generating methods of copy the object
152 	AndroidHardwareBufferExternalApi(AndroidHardwareBufferExternalApi const& copy);            // Not Implemented
153 	AndroidHardwareBufferExternalApi& operator=(AndroidHardwareBufferExternalApi const& copy); // Not Implemented
154 
155 	static bool loadAhbDynamicApis(deInt32 sdkVersion);
156 };
157 
158 const char*						externalSemaphoreTypeToName	(vk::VkExternalSemaphoreHandleTypeFlagBits	type);
159 const char*						externalFenceTypeToName		(vk::VkExternalFenceHandleTypeFlagBits		type);
160 const char*						externalMemoryTypeToName	(vk::VkExternalMemoryHandleTypeFlagBits		type);
161 
162 enum Permanence
163 {
164 	PERMANENCE_PERMANENT = 0,
165 	PERMANENCE_TEMPORARY
166 };
167 
168 enum Transference
169 {
170 	TRANSFERENCE_COPY = 0,
171 	TRANSFERENCE_REFERENCE
172 };
173 
174 struct ExternalHostMemory
175 {
ExternalHostMemoryvkt::ExternalMemoryUtil::ExternalHostMemory176 	ExternalHostMemory(vk::VkDeviceSize aSize, vk::VkDeviceSize aAlignment)
177 		: size(deAlignSize(static_cast<size_t>(aSize), static_cast<size_t>(aAlignment)))
178 	{
179 		data = deAlignedMalloc(this->size, static_cast<size_t>(aAlignment));
180 	}
181 
~ExternalHostMemoryvkt::ExternalMemoryUtil::ExternalHostMemory182 	~ExternalHostMemory()
183 	{
184 		if (data != DE_NULL)
185 		{
186 			deAlignedFree(data);
187 		}
188 	}
189 
190 	size_t	size;
191 	void*	data;
192 };
193 
194 bool							isSupportedPermanence				(vk::VkExternalSemaphoreHandleTypeFlagBits	type,
195 																	 Permanence									permanence);
196 Transference					getHandelTypeTransferences			(vk::VkExternalSemaphoreHandleTypeFlagBits	type);
197 
198 bool							isSupportedPermanence				(vk::VkExternalFenceHandleTypeFlagBits		type,
199 																	 Permanence									permanence);
200 Transference					getHandelTypeTransferences			(vk::VkExternalFenceHandleTypeFlagBits		type);
201 
202 int								getMemoryFd							(const vk::DeviceInterface&					vkd,
203 																	 vk::VkDevice								device,
204 																	 vk::VkDeviceMemory							memory,
205 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType);
206 
207 void							getMemoryNative						(const vk::DeviceInterface&					vkd,
208 																	 vk::VkDevice								device,
209 																	 vk::VkDeviceMemory							memory,
210 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
211 																	 NativeHandle&								nativeHandle);
212 
213 vk::Move<vk::VkSemaphore>		createExportableSemaphore			(const vk::DeviceInterface&					vkd,
214 																	 vk::VkDevice								device,
215 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType);
216 
217 vk::Move<vk::VkSemaphore>		createExportableSemaphoreType		(const vk::DeviceInterface&					vkd,
218 																	 vk::VkDevice								device,
219 																	 vk::VkSemaphoreType						semaphoreType,
220 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType);
221 
222 int								getSemaphoreFd						(const vk::DeviceInterface&					vkd,
223 																	 vk::VkDevice								device,
224 																	 vk::VkSemaphore							semaphore,
225 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType);
226 
227 void							getSemaphoreNative					(const vk::DeviceInterface&					vkd,
228 																	 vk::VkDevice								device,
229 																	 vk::VkSemaphore							semaphore,
230 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType,
231 																	 NativeHandle&								nativeHandle);
232 
233 void							importSemaphore						(const vk::DeviceInterface&					vkd,
234 																	 const vk::VkDevice							device,
235 																	 const vk::VkSemaphore						semaphore,
236 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType,
237 																	 NativeHandle&								handle,
238 																	 vk::VkSemaphoreImportFlags					flags);
239 
240 vk::Move<vk::VkSemaphore>		createAndImportSemaphore			(const vk::DeviceInterface&					vkd,
241 																	 const vk::VkDevice							device,
242 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType,
243 																	 NativeHandle&								handle,
244 																	 vk::VkSemaphoreImportFlags					flags);
245 
246 vk::Move<vk::VkFence>			createExportableFence				(const vk::DeviceInterface&					vkd,
247 																	 vk::VkDevice								device,
248 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType);
249 
250 int								getFenceFd							(const vk::DeviceInterface&					vkd,
251 																	 vk::VkDevice								device,
252 																	 vk::VkFence								fence,
253 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType);
254 
255 void							getFenceNative						(const vk::DeviceInterface&					vkd,
256 																	 vk::VkDevice								device,
257 																	 vk::VkFence								fence,
258 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType,
259 																	 NativeHandle&								nativeHandle,
260 																	 bool expectFenceUnsignaled = true);
261 
262 void							importFence							(const vk::DeviceInterface&					vkd,
263 																	 const vk::VkDevice							device,
264 																	 const vk::VkFence							fence,
265 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType,
266 																	 NativeHandle&								handle,
267 																	 vk::VkFenceImportFlags						flags);
268 
269 vk::Move<vk::VkFence>			createAndImportFence				(const vk::DeviceInterface&					vkd,
270 																	 const vk::VkDevice							device,
271 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType,
272 																	 NativeHandle&								handle,
273 																	 vk::VkFenceImportFlags						flags);
274 
275 deUint32						chooseMemoryType					(deUint32									bits);
276 
277 deUint32						chooseHostVisibleMemoryType			(deUint32									bits,
278 																	 const vk::VkPhysicalDeviceMemoryProperties	properties);
279 
280 vk::VkMemoryRequirements		getImageMemoryRequirements			(const vk::DeviceInterface& vkd,
281 																	 vk::VkDevice device,
282 																	 vk::VkImage image,
283 																	 vk::VkExternalMemoryHandleTypeFlagBits externalType);
284 
285 // If buffer is not null use dedicated allocation
286 vk::Move<vk::VkDeviceMemory>	allocateExportableMemory			(const vk::DeviceInterface&					vkd,
287 																	 vk::VkDevice								device,
288 																	 vk::VkDeviceSize							allocationSize,
289 																	 deUint32									memoryTypeIndex,
290 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
291 																	 vk::VkBuffer								buffer);
292 
293 // If image is not null use dedicated allocation
294 vk::Move<vk::VkDeviceMemory>	allocateExportableMemory			(const vk::DeviceInterface&					vkd,
295 																	 vk::VkDevice								device,
296 																	 vk::VkDeviceSize							allocationSize,
297 																	 deUint32									memoryTypeIndex,
298 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
299 																	 vk::VkImage								image);
300 
301 /*
302 // \note hostVisible argument is strict. Setting it to false will cause NotSupportedError to be thrown if non-host visible memory doesn't exist.
303 // If buffer is not null use dedicated allocation
304 vk::Move<vk::VkDeviceMemory>	allocateExportableMemory			(const vk::InstanceInterface&				vki,
305 																	 vk::VkPhysicalDevice						physicalDevice,
306 																	 const vk::DeviceInterface&					vkd,
307 																	 vk::VkDevice								device,
308 																	 const vk::VkMemoryRequirements&			requirements,
309 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
310 																	 bool										hostVisible,
311 																	 vk::VkBuffer								buffer,
312 																	 deUint32&									exportedMemoryTypeIndex);
313 */
314 
315 vk::Move<vk::VkDeviceMemory>	importMemory						(const vk::DeviceInterface&					vkd,
316 																	 vk::VkDevice								device,
317 																	 const vk::VkMemoryRequirements&			requirements,
318 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
319 																	 deUint32									memoryTypeIndex,
320 																	 NativeHandle&								handle);
321 
322 vk::Move<vk::VkDeviceMemory>	importDedicatedMemory				(const vk::DeviceInterface&					vkd,
323 																	 vk::VkDevice								device,
324 																	 vk::VkBuffer								buffer,
325 																	 const vk::VkMemoryRequirements&			requirements,
326 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
327 																	 deUint32									memoryTypeIndex,
328 																	 NativeHandle&								handle);
329 
330 vk::Move<vk::VkDeviceMemory>	importDedicatedMemory				(const vk::DeviceInterface&					vkd,
331 																	 vk::VkDevice								device,
332 																	 vk::VkImage								image,
333 																	 const vk::VkMemoryRequirements&			requirements,
334 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
335 																	 deUint32									memoryTypeIndex,
336 																	 NativeHandle&								handle);
337 
338 vk::Move<vk::VkBuffer>			createExternalBuffer				(const vk::DeviceInterface&					vkd,
339 																	 vk::VkDevice								device,
340 																	 deUint32									queueFamilyIndex,
341 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
342 																	 vk::VkDeviceSize							size,
343 																	 vk::VkBufferCreateFlags					createFlags,
344 																	 vk::VkBufferUsageFlags						usageFlags);
345 
346 vk::Move<vk::VkImage>			createExternalImage					(const vk::DeviceInterface&					vkd,
347 																	 vk::VkDevice								device,
348 																	 deUint32									queueFamilyIndex,
349 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
350 																	 vk::VkFormat								format,
351 																	 deUint32									width,
352 																	 deUint32									height,
353 																	 vk::VkImageTiling							tiling,
354 																	 vk::VkImageCreateFlags						createFlags,
355 																	 vk::VkImageUsageFlags						usageFlags,
356 																	 deUint32									mipLevels = 1u,
357 																	 deUint32									arrayLayers = 1u);
358 
359 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface&	vki,
360 																								  vk::VkPhysicalDevice			physicalDevice);
361 
362 } // ExternalMemoryUtil
363 } // vkt
364 
365 #endif // _VKTEXTERNALMEMORYUTIL_HPP
366