• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "surface_type.h"
32 #include "native_buffer.h"
33 
34 #ifndef CTS_USES_VULKANSC
35 
36 namespace vkt
37 {
38 
39 namespace ExternalMemoryUtil
40 {
41 
42 
43 class NativeHandle
44 {
45 public:
46 	enum Win32HandleType
47 	{
48 		WIN32HANDLETYPE_NT = 0,
49 		WIN32HANDLETYPE_KMT,
50 
51 		WIN32HANDLETYPE_LAST
52 	};
53 
54 										NativeHandle				(void);
55 										NativeHandle				(const NativeHandle& other);
56 										NativeHandle				(int fd);
57 										NativeHandle				(Win32HandleType type, vk::pt::Win32Handle handle);
58 										NativeHandle				(vk::pt::AndroidHardwareBufferPtr buffer);
59 										NativeHandle				(vk::pt::OHOSNativeBufferPtr buffer);
60 										~NativeHandle				(void);
61 
62 	NativeHandle&						operator=					(int fd);
63 	NativeHandle&						operator=					(vk::pt::AndroidHardwareBufferPtr buffer);
64 	NativeHandle&						operator=					(vk::pt::OHOSNativeBufferPtr buffer);
65 
66 	void								setZirconHandle				(vk::pt::zx_handle_t zirconHandle);
67 	void								setWin32Handle				(Win32HandleType type, vk::pt::Win32Handle handle);
68 	vk::pt::Win32Handle					getWin32Handle				(void) const;
69 	void								setHostPtr					(void* hostPtr);
70 	void*								getHostPtr					(void) const;
71 	bool								hasValidFd					(void) const;
72 	int									getFd						(void) const;
73 	vk::pt::AndroidHardwareBufferPtr	getAndroidHardwareBuffer	(void) const;
74 	vk::pt::OHOSNativeBufferPtr			GetOhosNativeBuffer			(void) const;
75 	vk::pt::zx_handle_t					getZirconHandle				(void) const;
76 	void								disown						(void);
77 	void								reset						(void);
78 
79 private:
80 	int									m_fd;
81 	vk::pt::zx_handle_t					m_zirconHandle;
82 	Win32HandleType						m_win32HandleType;
83 	vk::pt::Win32Handle					m_win32Handle;
84 	vk::pt::AndroidHardwareBufferPtr	m_androidHardwareBuffer;
85 	void*								m_hostPtr;
86 	vk::pt::OHOSNativeBufferPtr			m_ohosNativeBuffer;
87 	// Disabled
88 	NativeHandle&						operator=					(const NativeHandle&);
89 };
90 
91 class BufferExternalApi
92 {
93 public:
~BufferExternalApi()94 	virtual ~BufferExternalApi(){};
95 };
96 
97 class OHOSNativeBufferExternalApi:public BufferExternalApi
98 {
99 public:
OHOSNativeBufferExternalApi()100 	OHOSNativeBufferExternalApi(){};
101 
102 	/**
103 	 * getInstance obtains the object, that provides an interface to AHB system APIs .
104 	 * If the AHB system API is not supported or if it is not built as supported with the CTS,
105 	 * then this function would return a null object.
106 	 */
107 	static OHOSNativeBufferExternalApi* getInstance();
108 
109 	deUint64 MustSupportOHOSUsageFlags();
110 
111 	deUint64 VKUsageToOHOSUsage(vk::VkImageUsageFlagBits vkFlag);
112 
113 	deUint64 VKCreateToOHOSUsage(vk::VkImageCreateFlagBits vkFlag);
114 
115 	vk::pt::OHOSNativeBufferPtr Allocate(deUint32 width, deUint32  height, deUint32  format, deUint64 usage);
116 
117 	deUint32 VKFormatToOHOSFormat(vk::VkFormat vkFormat);
118 
119 	int32_t Release(vk::pt::OHOSNativeBufferPtr buffer);
120 
121 	int32_t Acquire(vk::pt::OHOSNativeBufferPtr buffer);
122 
123 	void Describe(vk::pt::OHOSNativeBufferPtr buffer,
124 									deUint32* width,
125 									deUint32* height,
126 									deUint32* format,
127 									deUint64* usage,
128 									deUint32* stride);
129 
~OHOSNativeBufferExternalApi()130 	virtual ~OHOSNativeBufferExternalApi() override {};
131 };
132 
133 class AndroidHardwareBufferExternalApi:public BufferExternalApi
134 {
135 public:
136 
137 	/**
138 	 * getInstance obtains the object, that provides an interface to AHB system APIs .
139 	 * If the AHB system API is not supported or if it is not built as supported with the CTS,
140 	 * then this function would return a null object.
141 	 */
142 	static AndroidHardwareBufferExternalApi* getInstance();
143 
144 	/* Is AndroidHardwareBuffer supported? */
145 	static bool supportsAhb();
146 
147 	/* Are Cube maps supported on current api level? */
148 	static bool supportsCubeMap();
149 
150 	/**
151 	 * Allocates a buffer that backs an AHardwareBuffer using the passed parameter as follows:
152 	 * width;      - width in pixels
153 	 * height;     - height in pixels
154 	 * layers;     - number of images
155 	 * format;     - One of AHARDWAREBUFFER_FORMAT_*
156 	 * usage;      - Combination of AHARDWAREBUFFER_USAGE_*
157 	 *
158 	 * Returns a valid AndroidHardwareBufferPtr object on success, or an null AndroidHardwareBufferPtr if
159 	 * the allocation fails for any reason.
160 	 */
161 	virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32  height, deUint32 layers, deUint32  format, deUint64 usage) = 0;
162 
163 	/**
164 	 * Acquire a reference on the given AHardwareBuffer object.  This prevents the
165 	 * object from being deleted until the last reference is removed.
166 	 */
167 	virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer) = 0;
168 
169 	/**
170 	 * Remove a reference that was previously acquired with
171 	 * AHardwareBuffer_acquire().
172 	 */
173 	virtual void release(vk::pt::AndroidHardwareBufferPtr buffer) = 0;
174 
175 	/**
176 	 * Return a description of the AHardwareBuffer in the passed in the following fields, if not NULL:
177 	 * width;      - width in pixels
178 	 * height;     - height in pixels
179 	 * layers;     - number of images
180 	 * format;     - One of AHARDWAREBUFFER_FORMAT_*
181 	 * usage;      - Combination of AHARDWAREBUFFER_USAGE_*
182 	 *
183 	 */
184 	virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer,
185 				  deUint32* width,
186 				  deUint32* height,
187 				  deUint32* layers,
188 				  deUint32* format,
189 				  deUint64* usage,
190 				  deUint32* stride) = 0;
191 
192 
193 	virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag) = 0;
194 	virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag) = 0;
195 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat) = 0;
196 	virtual deUint64 mustSupportAhbUsageFlags() = 0;
197 	virtual bool     ahbFormatIsBlob(deUint32 format) = 0;
198 
199 	virtual ~AndroidHardwareBufferExternalApi() override;
200 
201 protected:
202 	// Protected Constructor
203 	AndroidHardwareBufferExternalApi();
204 
205 private:
206 	// Stop the compiler generating methods of copy the object
207 	AndroidHardwareBufferExternalApi(AndroidHardwareBufferExternalApi const& copy);            // Not Implemented
208 	AndroidHardwareBufferExternalApi& operator=(AndroidHardwareBufferExternalApi const& copy); // Not Implemented
209 
210 	static bool loadAhbDynamicApis(deInt32 sdkVersion);
211 };
212 
213 const char*						externalSemaphoreTypeToName	(vk::VkExternalSemaphoreHandleTypeFlagBits	type);
214 const char*						externalFenceTypeToName		(vk::VkExternalFenceHandleTypeFlagBits		type);
215 const char*						externalMemoryTypeToName	(vk::VkExternalMemoryHandleTypeFlagBits		type);
216 
217 enum Permanence
218 {
219 	PERMANENCE_PERMANENT = 0,
220 	PERMANENCE_TEMPORARY
221 };
222 
223 enum Transference
224 {
225 	TRANSFERENCE_COPY = 0,
226 	TRANSFERENCE_REFERENCE
227 };
228 
229 struct ExternalHostMemory
230 {
ExternalHostMemoryvkt::ExternalMemoryUtil::ExternalHostMemory231 	ExternalHostMemory(vk::VkDeviceSize aSize, vk::VkDeviceSize aAlignment)
232 		: size(deAlignSize(static_cast<size_t>(aSize), static_cast<size_t>(aAlignment)))
233 	{
234 		data = deAlignedMalloc(this->size, static_cast<size_t>(aAlignment));
235 	}
236 
~ExternalHostMemoryvkt::ExternalMemoryUtil::ExternalHostMemory237 	~ExternalHostMemory()
238 	{
239 		if (data != DE_NULL)
240 		{
241 			deAlignedFree(data);
242 		}
243 	}
244 
245 	size_t	size;
246 	void*	data;
247 };
248 
249 bool							isSupportedPermanence				(vk::VkExternalSemaphoreHandleTypeFlagBits	type,
250 																	 Permanence									permanence);
251 Transference					getHandelTypeTransferences			(vk::VkExternalSemaphoreHandleTypeFlagBits	type);
252 
253 bool							isSupportedPermanence				(vk::VkExternalFenceHandleTypeFlagBits		type,
254 																	 Permanence									permanence);
255 Transference					getHandelTypeTransferences			(vk::VkExternalFenceHandleTypeFlagBits		type);
256 
257 int								getMemoryFd							(const vk::DeviceInterface&					vkd,
258 																	 vk::VkDevice								device,
259 																	 vk::VkDeviceMemory							memory,
260 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType);
261 
262 void							getMemoryNative						(const vk::DeviceInterface&					vkd,
263 																	 vk::VkDevice								device,
264 																	 vk::VkDeviceMemory							memory,
265 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
266 																	 NativeHandle&								nativeHandle);
267 
268 vk::Move<vk::VkSemaphore>		createExportableSemaphore			(const vk::DeviceInterface&					vkd,
269 																	 vk::VkDevice								device,
270 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType);
271 
272 vk::Move<vk::VkSemaphore>		createExportableSemaphoreType		(const vk::DeviceInterface&					vkd,
273 																	 vk::VkDevice								device,
274 																	 vk::VkSemaphoreType						semaphoreType,
275 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType);
276 
277 int								getSemaphoreFd						(const vk::DeviceInterface&					vkd,
278 																	 vk::VkDevice								device,
279 																	 vk::VkSemaphore							semaphore,
280 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType);
281 
282 void							getSemaphoreNative					(const vk::DeviceInterface&					vkd,
283 																	 vk::VkDevice								device,
284 																	 vk::VkSemaphore							semaphore,
285 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType,
286 																	 NativeHandle&								nativeHandle);
287 
288 void							importSemaphore						(const vk::DeviceInterface&					vkd,
289 																	 const vk::VkDevice							device,
290 																	 const vk::VkSemaphore						semaphore,
291 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType,
292 																	 NativeHandle&								handle,
293 																	 vk::VkSemaphoreImportFlags					flags);
294 
295 vk::Move<vk::VkSemaphore>		createAndImportSemaphore			(const vk::DeviceInterface&					vkd,
296 																	 const vk::VkDevice							device,
297 																	 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType,
298 																	 NativeHandle&								handle,
299 																	 vk::VkSemaphoreImportFlags					flags);
300 
301 vk::Move<vk::VkFence>			createExportableFence				(const vk::DeviceInterface&					vkd,
302 																	 vk::VkDevice								device,
303 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType);
304 
305 int								getFenceFd							(const vk::DeviceInterface&					vkd,
306 																	 vk::VkDevice								device,
307 																	 vk::VkFence								fence,
308 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType);
309 
310 void							getFenceNative						(const vk::DeviceInterface&					vkd,
311 																	 vk::VkDevice								device,
312 																	 vk::VkFence								fence,
313 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType,
314 																	 NativeHandle&								nativeHandle,
315 																	 bool expectFenceUnsignaled = true);
316 
317 void							importFence							(const vk::DeviceInterface&					vkd,
318 																	 const vk::VkDevice							device,
319 																	 const vk::VkFence							fence,
320 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType,
321 																	 NativeHandle&								handle,
322 																	 vk::VkFenceImportFlags						flags);
323 
324 vk::Move<vk::VkFence>			createAndImportFence				(const vk::DeviceInterface&					vkd,
325 																	 const vk::VkDevice							device,
326 																	 vk::VkExternalFenceHandleTypeFlagBits		externalType,
327 																	 NativeHandle&								handle,
328 																	 vk::VkFenceImportFlags						flags);
329 
330 deUint32						chooseMemoryType					(deUint32									bits);
331 
332 deUint32						chooseHostVisibleMemoryType			(deUint32									bits,
333 																	 const vk::VkPhysicalDeviceMemoryProperties	properties);
334 
335 vk::VkMemoryRequirements		getImageMemoryRequirements			(const vk::DeviceInterface& vkd,
336 																	 vk::VkDevice device,
337 																	 vk::VkImage image,
338 																	 vk::VkExternalMemoryHandleTypeFlagBits externalType);
339 
340 // If buffer is not null use dedicated allocation
341 vk::Move<vk::VkDeviceMemory>	allocateExportableMemory			(const vk::DeviceInterface&					vkd,
342 																	 vk::VkDevice								device,
343 																	 vk::VkDeviceSize							allocationSize,
344 																	 deUint32									memoryTypeIndex,
345 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
346 																	 vk::VkBuffer								buffer);
347 
348 // If image is not null use dedicated allocation
349 vk::Move<vk::VkDeviceMemory>	allocateExportableMemory			(const vk::DeviceInterface&					vkd,
350 																	 vk::VkDevice								device,
351 																	 vk::VkDeviceSize							allocationSize,
352 																	 deUint32									memoryTypeIndex,
353 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
354 																	 vk::VkImage								image);
355 
356 /*
357 // \note hostVisible argument is strict. Setting it to false will cause NotSupportedError to be thrown if non-host visible memory doesn't exist.
358 // If buffer is not null use dedicated allocation
359 vk::Move<vk::VkDeviceMemory>	allocateExportableMemory			(const vk::InstanceInterface&				vki,
360 																	 vk::VkPhysicalDevice						physicalDevice,
361 																	 const vk::DeviceInterface&					vkd,
362 																	 vk::VkDevice								device,
363 																	 const vk::VkMemoryRequirements&			requirements,
364 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
365 																	 bool										hostVisible,
366 																	 vk::VkBuffer								buffer,
367 																	 deUint32&									exportedMemoryTypeIndex);
368 */
369 
370 vk::Move<vk::VkDeviceMemory>	importMemory						(const vk::DeviceInterface&					vkd,
371 																	 vk::VkDevice								device,
372 																	 const vk::VkMemoryRequirements&			requirements,
373 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
374 																	 deUint32									memoryTypeIndex,
375 																	 NativeHandle&								handle);
376 
377 vk::Move<vk::VkDeviceMemory>	importDedicatedMemory				(const vk::DeviceInterface&					vkd,
378 																	 vk::VkDevice								device,
379 																	 vk::VkBuffer								buffer,
380 																	 const vk::VkMemoryRequirements&			requirements,
381 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
382 																	 deUint32									memoryTypeIndex,
383 																	 NativeHandle&								handle);
384 
385 vk::Move<vk::VkDeviceMemory>	importDedicatedMemory				(const vk::DeviceInterface&					vkd,
386 																	 vk::VkDevice								device,
387 																	 vk::VkImage								image,
388 																	 const vk::VkMemoryRequirements&			requirements,
389 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
390 																	 deUint32									memoryTypeIndex,
391 																	 NativeHandle&								handle);
392 
393 vk::Move<vk::VkBuffer>			createExternalBuffer				(const vk::DeviceInterface&					vkd,
394 																	 vk::VkDevice								device,
395 																	 deUint32									queueFamilyIndex,
396 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
397 																	 vk::VkDeviceSize							size,
398 																	 vk::VkBufferCreateFlags					createFlags,
399 																	 vk::VkBufferUsageFlags						usageFlags);
400 
401 vk::Move<vk::VkImage>			createExternalImage					(const vk::DeviceInterface&					vkd,
402 																	 vk::VkDevice								device,
403 																	 deUint32									queueFamilyIndex,
404 																	 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
405 																	 vk::VkFormat								format,
406 																	 deUint32									width,
407 																	 deUint32									height,
408 																	 vk::VkImageTiling							tiling,
409 																	 vk::VkImageCreateFlags						createFlags,
410 																	 vk::VkImageUsageFlags						usageFlags,
411 																	 deUint32									mipLevels = 1u,
412 																	 deUint32									arrayLayers = 1u);
413 
414 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface&	vki,
415 																								  vk::VkPhysicalDevice			physicalDevice);
416 
417 } // ExternalMemoryUtil
418 
419 } // vkt
420 
421 #endif // CTS_USES_VULKANSC
422 
423 #endif // _VKTEXTERNALMEMORYUTIL_HPP
424