• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * \brief Vulkan external memory utilities
20  *//*--------------------------------------------------------------------*/
21 
22 #include "vktExternalMemoryUtil.hpp"
23 
24 #include "vkQueryUtil.hpp"
25 
26 #ifndef CTS_USES_VULKANSC
27 
28 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
29 #	include <unistd.h>
30 #	include <fcntl.h>
31 #	include <errno.h>
32 #	include <sys/types.h>
33 #	include <sys/socket.h>
34 #endif
35 
36 #if (DE_OS == DE_OS_WIN32)
37 #	define WIN32_LEAN_AND_MEAN
38 #	define NOMINMAX
39 #	include <windows.h>
40 #endif
41 
42 #if (DE_OS == DE_OS_ANDROID)
43 #   include <sys/system_properties.h>
44 #endif
45 
46 #if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
47 #	include <android/hardware_buffer.h>
48 #	include "deDynamicLibrary.hpp"
49 #	define BUILT_WITH_ANDROID_HARDWARE_BUFFER 1
50 #endif
51 
52 
53 #if (DE_OS == DE_OS_FUCHSIA)
54 #	include <zircon/syscalls.h>
55 #	include <zircon/types.h>
56 #endif
57 
58 #include <limits>
59 
60 namespace vkt
61 {
62 namespace ExternalMemoryUtil
63 {
64 namespace
65 {
66 
67 constexpr int kInvalidFd = std::numeric_limits<int>::min();
68 
69 } // anonymous
70 
NativeHandle(void)71 NativeHandle::NativeHandle (void)
72 	: m_fd						(kInvalidFd)
73 	, m_zirconHandle			(0)
74 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
75 	, m_win32Handle				(DE_NULL)
76 	, m_androidHardwareBuffer	(DE_NULL)
77 	, m_hostPtr					(DE_NULL)
78 {
79 }
80 
NativeHandle(const NativeHandle & other)81 NativeHandle::NativeHandle (const NativeHandle& other)
82 	: m_fd						(kInvalidFd)
83 	, m_zirconHandle			(0)
84 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
85 	, m_win32Handle				(DE_NULL)
86 	, m_androidHardwareBuffer	(DE_NULL)
87 	, m_hostPtr					(DE_NULL)
88 {
89 	if (other.m_fd >= 0)
90 	{
91 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
92 		DE_ASSERT(!other.m_win32Handle.internal);
93 		DE_ASSERT(!other.m_androidHardwareBuffer.internal);
94 		m_fd = dup(other.m_fd);
95 		TCU_CHECK(m_fd >= 0);
96 #else
97 		DE_FATAL("Platform doesn't support file descriptors");
98 #endif
99 	}
100 	else if (other.m_zirconHandle.internal)
101 	{
102 #if (DE_OS == DE_OS_FUCHSIA)
103 		DE_ASSERT(!other.m_win32Handle.internal);
104 		zx_handle_duplicate(other.m_zirconHandle.internal, ZX_RIGHT_SAME_RIGHTS, &m_zirconHandle.internal);
105 #else
106 		DE_FATAL("Platform doesn't support zircon handles");
107 #endif
108 	}
109 	else if (other.m_win32Handle.internal)
110 	{
111 #if (DE_OS == DE_OS_WIN32)
112 		m_win32HandleType = other.m_win32HandleType;
113 
114 		switch (other.m_win32HandleType)
115 		{
116 			case WIN32HANDLETYPE_NT:
117 			{
118 				DE_ASSERT(other.m_fd == kInvalidFd);
119 				DE_ASSERT(!other.m_androidHardwareBuffer.internal);
120 
121 				const HANDLE process = ::GetCurrentProcess();
122 				::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS);
123 
124 				break;
125 			}
126 
127 			case WIN32HANDLETYPE_KMT:
128 			{
129 				m_win32Handle = other.m_win32Handle;
130 				break;
131 			}
132 
133 			default:
134 				DE_FATAL("Unknown win32 handle type");
135 		}
136 #else
137 		DE_FATAL("Platform doesn't support win32 handles");
138 #endif
139 	}
140 	else if (other.m_androidHardwareBuffer.internal)
141 	{
142 		DE_ASSERT(other.m_fd == kInvalidFd);
143 		DE_ASSERT(!other.m_win32Handle.internal);
144 		m_androidHardwareBuffer = other.m_androidHardwareBuffer;
145 
146 		if (AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance())
147 			ahbApi->acquire(m_androidHardwareBuffer);
148 		else
149 			DE_FATAL("Platform doesn't support Android Hardware Buffer handles");
150 	}
151 	else
152 		DE_FATAL("Native handle can't be duplicated");
153 }
154 
NativeHandle(int fd)155 NativeHandle::NativeHandle (int fd)
156 	: m_fd						(fd)
157 	, m_zirconHandle			(0)
158 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
159 	, m_win32Handle				(DE_NULL)
160 	, m_androidHardwareBuffer	(DE_NULL)
161 	, m_hostPtr					(DE_NULL)
162 {
163 }
164 
NativeHandle(Win32HandleType handleType,vk::pt::Win32Handle handle)165 NativeHandle::NativeHandle (Win32HandleType handleType, vk::pt::Win32Handle handle)
166 	: m_fd						(kInvalidFd)
167 	, m_zirconHandle			(0)
168 	, m_win32HandleType			(handleType)
169 	, m_win32Handle				(handle)
170 	, m_androidHardwareBuffer	(DE_NULL)
171 	, m_hostPtr					(DE_NULL)
172 {
173 }
174 
NativeHandle(vk::pt::AndroidHardwareBufferPtr buffer)175 NativeHandle::NativeHandle (vk::pt::AndroidHardwareBufferPtr buffer)
176 	: m_fd						(kInvalidFd)
177 	, m_zirconHandle			(0)
178 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
179 	, m_win32Handle				(DE_NULL)
180 	, m_androidHardwareBuffer	(buffer)
181 	, m_hostPtr					(DE_NULL)
182 {
183 }
184 
~NativeHandle(void)185 NativeHandle::~NativeHandle (void)
186 {
187 	reset();
188 }
189 
reset(void)190 void NativeHandle::reset (void)
191 {
192 	if (m_fd >= 0)
193 	{
194 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
195 		DE_ASSERT(!m_win32Handle.internal);
196 		DE_ASSERT(!m_androidHardwareBuffer.internal);
197 		::close(m_fd);
198 #else
199 		DE_FATAL("Platform doesn't support file descriptors");
200 #endif
201 	}
202 
203 	if (m_zirconHandle.internal != 0)
204 	{
205 #if (DE_OS == DE_OS_FUCHSIA)
206 		zx_handle_close(m_zirconHandle.internal);
207 #else
208 		DE_FATAL("Platform doesn't support fuchsia handles");
209 #endif
210 	}
211 
212 
213 	if (m_win32Handle.internal)
214 	{
215 #if (DE_OS == DE_OS_WIN32)
216 		switch (m_win32HandleType)
217 		{
218 			case WIN32HANDLETYPE_NT:
219 				DE_ASSERT(m_fd == kInvalidFd);
220 				DE_ASSERT(!m_androidHardwareBuffer.internal);
221 				::CloseHandle((HANDLE)m_win32Handle.internal);
222 				break;
223 
224 			case WIN32HANDLETYPE_KMT:
225 				break;
226 
227 			default:
228 				DE_FATAL("Unknown win32 handle type");
229 		}
230 #else
231 		DE_FATAL("Platform doesn't support win32 handles");
232 #endif
233 	}
234 	if (m_androidHardwareBuffer.internal)
235 	{
236 		DE_ASSERT(m_fd == kInvalidFd);
237 		DE_ASSERT(!m_win32Handle.internal);
238 
239 		if (AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance())
240 			ahbApi->release(m_androidHardwareBuffer);
241 		else
242 			DE_FATAL("Platform doesn't support Android Hardware Buffer handles");
243 	}
244 	m_fd					= kInvalidFd;
245 	m_zirconHandle			= vk::pt::zx_handle_t(0);
246 	m_win32Handle			= vk::pt::Win32Handle(DE_NULL);
247 	m_win32HandleType		= WIN32HANDLETYPE_LAST;
248 	m_androidHardwareBuffer	= vk::pt::AndroidHardwareBufferPtr(DE_NULL);
249 	m_hostPtr				= DE_NULL;
250 }
251 
operator =(int fd)252 NativeHandle& NativeHandle::operator= (int fd)
253 {
254 	reset();
255 
256 	m_fd = fd;
257 
258 	return *this;
259 }
260 
operator =(vk::pt::AndroidHardwareBufferPtr buffer)261 NativeHandle& NativeHandle::operator= (vk::pt::AndroidHardwareBufferPtr buffer)
262 {
263 	reset();
264 
265 	m_androidHardwareBuffer = buffer;
266 
267 	return *this;
268 }
269 
setWin32Handle(Win32HandleType type,vk::pt::Win32Handle handle)270 void NativeHandle::setWin32Handle (Win32HandleType type, vk::pt::Win32Handle handle)
271 {
272 	reset();
273 
274 	m_win32HandleType	= type;
275 	m_win32Handle		= handle;
276 }
277 
setZirconHandle(vk::pt::zx_handle_t zirconHandle)278 void NativeHandle::setZirconHandle (vk::pt::zx_handle_t zirconHandle)
279 {
280 	reset();
281 
282 	m_zirconHandle = zirconHandle;
283 }
284 
setHostPtr(void * hostPtr)285 void NativeHandle::setHostPtr(void* hostPtr)
286 {
287 	reset();
288 
289 	m_hostPtr = hostPtr;
290 }
291 
disown(void)292 void NativeHandle::disown (void)
293 {
294 	m_fd = kInvalidFd;
295 	m_zirconHandle = vk::pt::zx_handle_t(0);
296 	m_win32Handle = vk::pt::Win32Handle(DE_NULL);
297 	m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL);
298 	m_hostPtr = DE_NULL;
299 }
300 
getWin32Handle(void) const301 vk::pt::Win32Handle NativeHandle::getWin32Handle (void) const
302 {
303 	DE_ASSERT(m_fd == kInvalidFd);
304 	DE_ASSERT(!m_androidHardwareBuffer.internal);
305 	DE_ASSERT(m_hostPtr == DE_NULL);
306 
307 	return m_win32Handle;
308 }
309 
hasValidFd(void) const310 bool NativeHandle::hasValidFd (void) const
311 {
312 	return (m_fd != kInvalidFd);
313 }
314 
getFd(void) const315 int NativeHandle::getFd (void) const
316 {
317 	DE_ASSERT(!m_win32Handle.internal);
318 	DE_ASSERT(!m_androidHardwareBuffer.internal);
319 	DE_ASSERT(m_hostPtr == DE_NULL);
320 	return m_fd;
321 }
322 
getZirconHandle(void) const323 vk::pt::zx_handle_t NativeHandle::getZirconHandle (void) const
324 {
325 	DE_ASSERT(!m_win32Handle.internal);
326 	DE_ASSERT(!m_androidHardwareBuffer.internal);
327 
328 	return m_zirconHandle;
329 }
330 
331 
getAndroidHardwareBuffer(void) const332 vk::pt::AndroidHardwareBufferPtr NativeHandle::getAndroidHardwareBuffer (void) const
333 {
334 	DE_ASSERT(m_fd == kInvalidFd);
335 	DE_ASSERT(!m_win32Handle.internal);
336 	DE_ASSERT(m_hostPtr == DE_NULL);
337 	return m_androidHardwareBuffer;
338 }
339 
getHostPtr(void) const340 void* NativeHandle::getHostPtr(void) const
341 {
342 	DE_ASSERT(m_fd == kInvalidFd);
343 	DE_ASSERT(!m_win32Handle.internal);
344 	return m_hostPtr;
345 }
346 
externalSemaphoreTypeToName(vk::VkExternalSemaphoreHandleTypeFlagBits type)347 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type)
348 {
349 	switch (type)
350 	{
351 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
352 			return "opaque_fd";
353 
354 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
355 			return "opaque_win32";
356 
357 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
358 			return "opaque_win32_kmt";
359 
360 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT:
361 			return "d3d12_fenc";
362 
363 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
364 			return "sync_fd";
365 
366 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA:
367 			return "zircon_event";
368 
369 		default:
370 			DE_FATAL("Unknown external semaphore type");
371 			return DE_NULL;
372 	}
373 }
374 
externalFenceTypeToName(vk::VkExternalFenceHandleTypeFlagBits type)375 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type)
376 {
377 	switch (type)
378 	{
379 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
380 			return "opaque_fd";
381 
382 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
383 			return "opaque_win32";
384 
385 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
386 			return "opaque_win32_kmt";
387 
388 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
389 			return "sync_fd";
390 
391 		default:
392 			DE_FATAL("Unknown external fence type");
393 			return DE_NULL;
394 	}
395 }
396 
externalMemoryTypeToName(vk::VkExternalMemoryHandleTypeFlagBits type)397 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type)
398 {
399 	switch (type)
400 	{
401 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
402 			return "opaque_fd";
403 
404 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
405 			return "opaque_win32";
406 
407 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
408 			return "opaque_win32_kmt";
409 
410 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT:
411 			return "d3d11_texture";
412 
413 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT:
414 			return "d3d11_texture_kmt";
415 
416 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT:
417 			return "d3d12_heap";
418 
419 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT:
420 			return "d3d12_resource";
421 
422 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
423 			return "android_hardware_buffer";
424 
425 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
426 			return "dma_buf";
427 
428 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
429 			return "host_allocation";
430 
431 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA:
432 			return "zircon_vmo";
433 
434 
435 		default:
436 			DE_FATAL("Unknown external memory type");
437 			return DE_NULL;
438 	}
439 }
440 
isSupportedPermanence(vk::VkExternalSemaphoreHandleTypeFlagBits type,Permanence permanence)441 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBits	type,
442 							Permanence										permanence)
443 {
444 	switch (type)
445 	{
446 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
447 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
448 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
449 
450 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
451 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
452 
453 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
454 			return permanence == PERMANENCE_TEMPORARY;
455 
456 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA:
457 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
458 
459 		default:
460 			DE_FATAL("Unknown external semaphore type");
461 			return false;
462 	}
463 }
464 
getHandelTypeTransferences(vk::VkExternalSemaphoreHandleTypeFlagBits type)465 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBits type)
466 {
467 	switch (type)
468 	{
469 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
470 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
471 			return TRANSFERENCE_REFERENCE;
472 
473 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
474 			return TRANSFERENCE_REFERENCE;
475 
476 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
477 			return TRANSFERENCE_COPY;
478 
479 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA:
480 			return TRANSFERENCE_REFERENCE;
481 
482 		default:
483 			DE_FATAL("Unknown external semaphore type");
484 			return TRANSFERENCE_REFERENCE;
485 	}
486 }
487 
isSupportedPermanence(vk::VkExternalFenceHandleTypeFlagBits type,Permanence permanence)488 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBits	type,
489 							Permanence									permanence)
490 {
491 	switch (type)
492 	{
493 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
494 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
495 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
496 
497 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
498 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
499 
500 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
501 			return permanence == PERMANENCE_TEMPORARY;
502 
503 		default:
504 			DE_FATAL("Unknown external fence type");
505 			return false;
506 	}
507 }
508 
getHandelTypeTransferences(vk::VkExternalFenceHandleTypeFlagBits type)509 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBits type)
510 {
511 	switch (type)
512 	{
513 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
514 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
515 			return TRANSFERENCE_REFERENCE;
516 
517 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
518 			return TRANSFERENCE_REFERENCE;
519 
520 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
521 			return TRANSFERENCE_COPY;
522 
523 		default:
524 			DE_FATAL("Unknown external fence type");
525 			return TRANSFERENCE_REFERENCE;
526 	}
527 }
528 
getMemoryFd(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDeviceMemory memory,vk::VkExternalMemoryHandleTypeFlagBits externalType)529 int getMemoryFd (const vk::DeviceInterface&					vkd,
530 				 vk::VkDevice								device,
531 				 vk::VkDeviceMemory							memory,
532 				 vk::VkExternalMemoryHandleTypeFlagBits		externalType)
533 {
534 	const vk::VkMemoryGetFdInfoKHR	info	=
535 	{
536 		vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
537 		DE_NULL,
538 
539 		memory,
540 		externalType
541 	};
542 	int								fd		= kInvalidFd;
543 
544 	VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
545 	TCU_CHECK(fd >= 0);
546 
547 	return fd;
548 }
549 
getMemoryNative(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDeviceMemory memory,vk::VkExternalMemoryHandleTypeFlagBits externalType,NativeHandle & nativeHandle)550 void getMemoryNative (const vk::DeviceInterface&					vkd,
551 						 vk::VkDevice								device,
552 						 vk::VkDeviceMemory							memory,
553 						 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
554 						 NativeHandle&								nativeHandle)
555 {
556 	if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT
557 		|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)
558 	{
559 		const vk::VkMemoryGetFdInfoKHR	info	=
560 		{
561 			vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
562 			DE_NULL,
563 
564 			memory,
565 			externalType
566 		};
567 		int								fd		= kInvalidFd;
568 
569 		VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
570 		TCU_CHECK(fd >= 0);
571 		nativeHandle = fd;
572 	}
573 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
574 	{
575 		const vk::VkMemoryGetZirconHandleInfoFUCHSIA	info	=
576 		{
577 			vk::VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
578 			DE_NULL,
579 
580 			memory,
581 			externalType
582 		};
583 		vk::pt::zx_handle_t handle(0);
584 
585 		VK_CHECK(vkd.getMemoryZirconHandleFUCHSIA(device, &info, &handle));
586 		nativeHandle.setZirconHandle(handle);
587 	}
588 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
589 		|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
590 	{
591 		const vk::VkMemoryGetWin32HandleInfoKHR	info	=
592 		{
593 			vk::VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
594 			DE_NULL,
595 
596 			memory,
597 			externalType
598 		};
599 		vk::pt::Win32Handle						handle	(DE_NULL);
600 
601 		VK_CHECK(vkd.getMemoryWin32HandleKHR(device, &info, &handle));
602 
603 		switch (externalType)
604 		{
605 			case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
606 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
607 				break;
608 
609 			case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
610 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
611 				break;
612 
613 			default:
614 				DE_FATAL("Unknown external memory handle type");
615 		}
616 	}
617 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
618 	{
619 		if (!AndroidHardwareBufferExternalApi::getInstance())
620 		{
621 			TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
622 		}
623 		const vk::VkMemoryGetAndroidHardwareBufferInfoANDROID	info	=
624 		{
625 			vk::VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
626 			DE_NULL,
627 
628 			memory,
629 		};
630 		vk::pt::AndroidHardwareBufferPtr						ahb	(DE_NULL);
631 
632 		VK_CHECK(vkd.getMemoryAndroidHardwareBufferANDROID(device, &info, &ahb));
633 		TCU_CHECK(ahb.internal);
634 		nativeHandle = ahb;
635 	}
636 	else
637 		DE_FATAL("Unknown external memory handle type");
638 }
639 
createExportableFence(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkExternalFenceHandleTypeFlagBits externalType)640 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface&					vkd,
641 											 vk::VkDevice								device,
642 											 vk::VkExternalFenceHandleTypeFlagBits		externalType)
643 {
644 	const vk::VkExportFenceCreateInfo	exportCreateInfo	=
645 	{
646 		vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
647 		DE_NULL,
648 		(vk::VkExternalFenceHandleTypeFlags)externalType
649 	};
650 	const vk::VkFenceCreateInfo				createInfo			=
651 	{
652 		vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
653 		&exportCreateInfo,
654 		0u
655 	};
656 
657 	return vk::createFence(vkd, device, &createInfo);
658 }
659 
getFenceFd(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkFence fence,vk::VkExternalFenceHandleTypeFlagBits externalType)660 int getFenceFd (const vk::DeviceInterface&					vkd,
661 				vk::VkDevice								device,
662 				vk::VkFence									fence,
663 				vk::VkExternalFenceHandleTypeFlagBits		externalType)
664 {
665 	const vk::VkFenceGetFdInfoKHR	info	=
666 	{
667 		vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
668 		DE_NULL,
669 
670 		fence,
671 		externalType
672 	};
673 	int								fd	= kInvalidFd;
674 
675 	VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
676 	TCU_CHECK(fd >= 0);
677 
678 	return fd;
679 }
680 
getFenceNative(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkFence fence,vk::VkExternalFenceHandleTypeFlagBits externalType,NativeHandle & nativeHandle,bool expectFenceUnsignaled)681 void getFenceNative (const vk::DeviceInterface&					vkd,
682 					 vk::VkDevice								device,
683 					 vk::VkFence								fence,
684 					 vk::VkExternalFenceHandleTypeFlagBits		externalType,
685 					 NativeHandle&								nativeHandle,
686 					 bool										expectFenceUnsignaled)
687 {
688 	if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
689 		|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
690 	{
691 		const vk::VkFenceGetFdInfoKHR	info	=
692 		{
693 			vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
694 			DE_NULL,
695 
696 			fence,
697 			externalType
698 		};
699 		int								fd	= kInvalidFd;
700 
701 		VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
702 
703 		if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT)
704 		{
705 			TCU_CHECK(!expectFenceUnsignaled || (fd >= 0) || (fd == -1));
706 		}
707 		else
708 		{
709 			TCU_CHECK(fd >= 0);
710 		}
711 
712 		nativeHandle = fd;
713 	}
714 	else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
715 		|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
716 	{
717 		const vk::VkFenceGetWin32HandleInfoKHR	info	=
718 		{
719 			vk::VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR,
720 			DE_NULL,
721 
722 			fence,
723 			externalType
724 		};
725 		vk::pt::Win32Handle						handle	(DE_NULL);
726 
727 		VK_CHECK(vkd.getFenceWin32HandleKHR(device, &info, &handle));
728 
729 		switch (externalType)
730 		{
731 			case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
732 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
733 				break;
734 
735 			case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
736 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
737 				break;
738 
739 			default:
740 				DE_FATAL("Unknow external memory handle type");
741 		}
742 	}
743 	else
744 		DE_FATAL("Unknow external fence handle type");
745 }
746 
importFence(const vk::DeviceInterface & vkd,const vk::VkDevice device,const vk::VkFence fence,vk::VkExternalFenceHandleTypeFlagBits externalType,NativeHandle & handle,vk::VkFenceImportFlags flags)747 void importFence (const vk::DeviceInterface&				vkd,
748 				  const vk::VkDevice						device,
749 				  const vk::VkFence							fence,
750 				  vk::VkExternalFenceHandleTypeFlagBits		externalType,
751 				  NativeHandle&								handle,
752 				  vk::VkFenceImportFlags					flags)
753 {
754 	if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
755 		|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
756 	{
757 		const vk::VkImportFenceFdInfoKHR	importInfo	=
758 		{
759 			vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
760 			DE_NULL,
761 			fence,
762 			flags,
763 			externalType,
764 			handle.getFd()
765 		};
766 
767 		VK_CHECK(vkd.importFenceFdKHR(device, &importInfo));
768 		handle.disown();
769 	}
770 	else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
771 			|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
772 	{
773 		const vk::VkImportFenceWin32HandleInfoKHR	importInfo	=
774 		{
775 			vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR,
776 			DE_NULL,
777 			fence,
778 			flags,
779 			externalType,
780 			handle.getWin32Handle(),
781 			(vk::pt::Win32LPCWSTR)DE_NULL
782 		};
783 
784 		VK_CHECK(vkd.importFenceWin32HandleKHR(device, &importInfo));
785 		// \note Importing a fence payload from Windows handles does not transfer ownership of the handle to the Vulkan implementation,
786 		//   so we do not disown the handle until after all use has complete.
787 	}
788 	else
789 		DE_FATAL("Unknown fence external handle type");
790 }
791 
createAndImportFence(const vk::DeviceInterface & vkd,const vk::VkDevice device,vk::VkExternalFenceHandleTypeFlagBits externalType,NativeHandle & handle,vk::VkFenceImportFlags flags)792 vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface&				vkd,
793 											const vk::VkDevice						device,
794 											vk::VkExternalFenceHandleTypeFlagBits	externalType,
795 											NativeHandle&							handle,
796 											vk::VkFenceImportFlags					flags)
797 {
798 	vk::Move<vk::VkFence>	fence	(createFence(vkd, device));
799 
800 	importFence(vkd, device, *fence, externalType, handle, flags);
801 
802 	return fence;
803 }
804 
createExportableSemaphore(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkExternalSemaphoreHandleTypeFlagBits externalType)805 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface&					vkd,
806 													 vk::VkDevice								device,
807 													 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType)
808 {
809 	const vk::VkExportSemaphoreCreateInfo	exportCreateInfo	=
810 	{
811 		vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
812 		DE_NULL,
813 		(vk::VkExternalSemaphoreHandleTypeFlags)externalType
814 	};
815 	const vk::VkSemaphoreCreateInfo				createInfo			=
816 	{
817 		vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
818 		&exportCreateInfo,
819 		0u
820 	};
821 
822 	return vk::createSemaphore(vkd, device, &createInfo);
823 }
824 
createExportableSemaphoreType(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkSemaphoreType semaphoreType,vk::VkExternalSemaphoreHandleTypeFlagBits externalType)825 vk::Move<vk::VkSemaphore> createExportableSemaphoreType (const vk::DeviceInterface&					vkd,
826 														 vk::VkDevice								device,
827 														 vk::VkSemaphoreType						semaphoreType,
828 														 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType)
829 {
830 	const vk::VkSemaphoreTypeCreateInfo		semaphoreTypeCreateInfo	=
831 	{
832 		vk::VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
833 		DE_NULL,
834 		semaphoreType,
835 		0,
836 	};
837 	const vk::VkExportSemaphoreCreateInfo	exportCreateInfo	=
838 	{
839 		vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
840 		&semaphoreTypeCreateInfo,
841 		(vk::VkExternalSemaphoreHandleTypeFlags)externalType
842 	};
843 	const vk::VkSemaphoreCreateInfo				createInfo			=
844 	{
845 		vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
846 		&exportCreateInfo,
847 		0u
848 	};
849 
850 	return vk::createSemaphore(vkd, device, &createInfo);
851 }
852 
getSemaphoreFd(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkSemaphore semaphore,vk::VkExternalSemaphoreHandleTypeFlagBits externalType)853 int getSemaphoreFd (const vk::DeviceInterface&					vkd,
854 					vk::VkDevice								device,
855 					vk::VkSemaphore								semaphore,
856 					vk::VkExternalSemaphoreHandleTypeFlagBits	externalType)
857 {
858 	const vk::VkSemaphoreGetFdInfoKHR	info	=
859 	{
860 		vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
861 		DE_NULL,
862 
863 		semaphore,
864 		externalType
865 	};
866 	int										fd	= kInvalidFd;
867 
868 	VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
869 	TCU_CHECK(fd >= 0);
870 
871 	return fd;
872 }
873 
getSemaphoreNative(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkSemaphore semaphore,vk::VkExternalSemaphoreHandleTypeFlagBits externalType,NativeHandle & nativeHandle)874 void getSemaphoreNative (const vk::DeviceInterface&					vkd,
875 						 vk::VkDevice								device,
876 						 vk::VkSemaphore							semaphore,
877 						 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType,
878 						 NativeHandle&								nativeHandle)
879 {
880 	if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
881 		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
882 	{
883 		const vk::VkSemaphoreGetFdInfoKHR	info	=
884 		{
885 			vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
886 			DE_NULL,
887 
888 			semaphore,
889 			externalType
890 		};
891 		int										fd	= kInvalidFd;
892 
893 		VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
894 
895 		if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)
896 			TCU_CHECK(fd >= -1);
897 		else
898 			TCU_CHECK(fd >= 0);
899 
900 		nativeHandle = fd;
901 	}
902 	else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA)
903 	{
904 		const vk::VkSemaphoreGetZirconHandleInfoFUCHSIA	info	=
905 		{
906 			vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA,
907 			DE_NULL,
908 
909 			semaphore,
910 			externalType
911 		};
912 		vk::pt::zx_handle_t zirconHandle(0);
913 
914 		VK_CHECK(vkd.getSemaphoreZirconHandleFUCHSIA(device, &info, &zirconHandle));
915 		nativeHandle.setZirconHandle(zirconHandle);
916 	}
917 	else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
918 		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
919 	{
920 		const vk::VkSemaphoreGetWin32HandleInfoKHR	info	=
921 		{
922 			vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
923 			DE_NULL,
924 
925 			semaphore,
926 			externalType
927 		};
928 		vk::pt::Win32Handle							handle	(DE_NULL);
929 
930 		VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle));
931 
932 		switch (externalType)
933 		{
934 			case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
935 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
936 				break;
937 
938 			case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
939 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
940 				break;
941 
942 			default:
943 				DE_FATAL("Unknow external memory handle type");
944 		}
945 	}
946 	else
947 		DE_FATAL("Unknow external semaphore handle type");
948 }
949 
importSemaphore(const vk::DeviceInterface & vkd,const vk::VkDevice device,const vk::VkSemaphore semaphore,vk::VkExternalSemaphoreHandleTypeFlagBits externalType,NativeHandle & handle,vk::VkSemaphoreImportFlags flags)950 void importSemaphore (const vk::DeviceInterface&					vkd,
951 					  const vk::VkDevice							device,
952 					  const vk::VkSemaphore							semaphore,
953 					  vk::VkExternalSemaphoreHandleTypeFlagBits		externalType,
954 					  NativeHandle&									handle,
955 					  vk::VkSemaphoreImportFlags					flags)
956 {
957 	if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
958 		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
959 	{
960 		const vk::VkImportSemaphoreFdInfoKHR	importInfo	=
961 		{
962 			vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
963 			DE_NULL,
964 			semaphore,
965 			flags,
966 			externalType,
967 			handle.getFd()
968 		};
969 
970 		VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo));
971 		handle.disown();
972 	}
973 	else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA)
974 	{
975 		const vk::VkImportSemaphoreZirconHandleInfoFUCHSIA	importInfo	=
976 		{
977 			vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA,
978 			DE_NULL,
979 			semaphore,
980 			flags,
981 			externalType,
982 			handle.getZirconHandle()
983 		};
984 
985 		VK_CHECK(vkd.importSemaphoreZirconHandleFUCHSIA(device, &importInfo));
986 		handle.disown();
987 	}
988 	else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
989 			|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
990 	{
991 		const vk::VkImportSemaphoreWin32HandleInfoKHR	importInfo	=
992 		{
993 			vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
994 			DE_NULL,
995 			semaphore,
996 			flags,
997 			externalType,
998 			handle.getWin32Handle(),
999 			(vk::pt::Win32LPCWSTR)DE_NULL
1000 		};
1001 
1002 		VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo));
1003 		// \note Importing a semaphore payload from Windows handles does not transfer ownership of the handle to the Vulkan implementation,
1004 		//   so we do not disown the handle until after all use has complete.
1005 	}
1006 	else
1007 		DE_FATAL("Unknown semaphore external handle type");
1008 }
1009 
createAndImportSemaphore(const vk::DeviceInterface & vkd,const vk::VkDevice device,vk::VkExternalSemaphoreHandleTypeFlagBits externalType,NativeHandle & handle,vk::VkSemaphoreImportFlags flags)1010 vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface&						vkd,
1011 													const vk::VkDevice								device,
1012 													vk::VkExternalSemaphoreHandleTypeFlagBits		externalType,
1013 													NativeHandle&									handle,
1014 													vk::VkSemaphoreImportFlags						flags)
1015 {
1016 	vk::Move<vk::VkSemaphore>	semaphore	(createSemaphore(vkd, device));
1017 
1018 	importSemaphore(vkd, device, *semaphore, externalType, handle, flags);
1019 
1020 	return semaphore;
1021 }
1022 
chooseMemoryType(deUint32 bits)1023 deUint32 chooseMemoryType(deUint32 bits)
1024 {
1025 	if (bits == 0)
1026 		return 0;
1027 
1028 	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
1029 	{
1030 		if ((bits & (1u << memoryTypeIndex)) != 0)
1031 			return memoryTypeIndex;
1032 	}
1033 
1034 	DE_FATAL("No supported memory types");
1035 	return -1;
1036 }
1037 
chooseHostVisibleMemoryType(deUint32 bits,const vk::VkPhysicalDeviceMemoryProperties properties)1038 deUint32 chooseHostVisibleMemoryType (deUint32 bits, const vk::VkPhysicalDeviceMemoryProperties properties)
1039 {
1040 	DE_ASSERT(bits != 0);
1041 
1042 	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
1043 	{
1044 		if (((bits & (1u << memoryTypeIndex)) != 0) &&
1045 			((properties.memoryTypes[memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0))
1046 			return memoryTypeIndex;
1047 	}
1048 
1049 	TCU_THROW(NotSupportedError, "No supported memory type found");
1050 	return -1;
1051 }
1052 
getImageMemoryRequirements(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkImage image,vk::VkExternalMemoryHandleTypeFlagBits externalType)1053 vk::VkMemoryRequirements getImageMemoryRequirements (const vk::DeviceInterface& vkd,
1054 													 vk::VkDevice device,
1055 													 vk::VkImage image,
1056 													 vk::VkExternalMemoryHandleTypeFlagBits externalType)
1057 {
1058 	if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1059 	{
1060 		return { 0u, 0u, 0u };
1061 	}
1062 	else
1063 	{
1064 		return vk::getImageMemoryRequirements(vkd, device, image);
1065 	}
1066 }
1067 
allocateExportableMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDeviceSize allocationSize,deUint32 memoryTypeIndex,vk::VkExternalMemoryHandleTypeFlagBits externalType,vk::VkBuffer buffer)1068 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface&					vkd,
1069 													   vk::VkDevice									device,
1070 													   vk::VkDeviceSize								allocationSize,
1071 													   deUint32										memoryTypeIndex,
1072 													   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
1073 													   vk::VkBuffer									buffer)
1074 {
1075 	const vk::VkMemoryDedicatedAllocateInfo	dedicatedInfo	=
1076 	{
1077 		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1078 		DE_NULL,
1079 
1080 		(vk::VkImage)0,
1081 		buffer
1082 	};
1083 	const vk::VkExportMemoryAllocateInfo	exportInfo	=
1084 	{
1085 		vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
1086 		!!buffer ? &dedicatedInfo : DE_NULL,
1087 		(vk::VkExternalMemoryHandleTypeFlags)externalType
1088 	};
1089 	const vk::VkMemoryAllocateInfo			info		=
1090 	{
1091 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1092 		&exportInfo,
1093 		allocationSize,
1094 		memoryTypeIndex
1095 	};
1096 	return vk::allocateMemory(vkd, device, &info);
1097 }
1098 
allocateExportableMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDeviceSize allocationSize,deUint32 memoryTypeIndex,vk::VkExternalMemoryHandleTypeFlagBits externalType,vk::VkImage image)1099 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface&					vkd,
1100 													   vk::VkDevice									device,
1101 													   vk::VkDeviceSize								allocationSize,
1102 													   deUint32										memoryTypeIndex,
1103 													   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
1104 													   vk::VkImage									image)
1105 {
1106 	const vk::VkMemoryDedicatedAllocateInfo	dedicatedInfo	=
1107 	{
1108 		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1109 		DE_NULL,
1110 
1111 		image,
1112 		(vk::VkBuffer)0
1113 	};
1114 	const vk::VkExportMemoryAllocateInfo	exportInfo	=
1115 	{
1116 		vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
1117 		!!image ? &dedicatedInfo : DE_NULL,
1118 		(vk::VkExternalMemoryHandleTypeFlags)externalType
1119 	};
1120 	const vk::VkMemoryAllocateInfo			info		=
1121 	{
1122 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1123 		&exportInfo,
1124 		allocationSize,
1125 		memoryTypeIndex
1126 	};
1127 	return vk::allocateMemory(vkd, device, &info);
1128 }
1129 
importMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkBuffer buffer,vk::VkImage image,const vk::VkMemoryRequirements & requirements,vk::VkExternalMemoryHandleTypeFlagBits externalType,deUint32 memoryTypeIndex,NativeHandle & handle)1130 static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&				vkd,
1131 												  vk::VkDevice								device,
1132 												  vk::VkBuffer								buffer,
1133 												  vk::VkImage								image,
1134 												  const vk::VkMemoryRequirements&			requirements,
1135 												  vk::VkExternalMemoryHandleTypeFlagBits	externalType,
1136 												  deUint32									memoryTypeIndex,
1137 												  NativeHandle&								handle)
1138 {
1139 	const bool	isDedicated		= !!buffer || !!image;
1140 
1141 	DE_ASSERT(!buffer || !image);
1142 
1143 	if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT
1144 		|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)
1145 	{
1146 		const vk::VkImportMemoryFdInfoKHR			importInfo		=
1147 		{
1148 			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
1149 			DE_NULL,
1150 			externalType,
1151 			handle.getFd()
1152 		};
1153 		const vk::VkMemoryDedicatedAllocateInfo	dedicatedInfo	=
1154 		{
1155 			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1156 			&importInfo,
1157 			image,
1158 			buffer,
1159 		};
1160 		const vk::VkMemoryAllocateInfo				info			=
1161 		{
1162 			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1163 			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1164 			requirements.size,
1165 			(memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
1166 		};
1167 		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1168 
1169 		handle.disown();
1170 
1171 		return memory;
1172 	}
1173 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
1174 	{
1175 		const vk::VkImportMemoryZirconHandleInfoFUCHSIA			importInfo		=
1176 		{
1177 			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA,
1178 			DE_NULL,
1179 			externalType,
1180 			handle.getZirconHandle()
1181 		};
1182 		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo	=
1183 		{
1184 			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1185 			&importInfo,
1186 			image,
1187 			buffer,
1188 		};
1189 		const vk::VkMemoryAllocateInfo				info			=
1190 		{
1191 			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1192 			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1193 			requirements.size,
1194 			(memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
1195 		};
1196 		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1197 
1198 		handle.disown();
1199 
1200 		return memory;
1201 	}
1202 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
1203 			|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
1204 	{
1205 		const vk::VkImportMemoryWin32HandleInfoKHR	importInfo		=
1206 		{
1207 			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
1208 			DE_NULL,
1209 			externalType,
1210 			handle.getWin32Handle(),
1211 			(vk::pt::Win32LPCWSTR)DE_NULL
1212 		};
1213 		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo	=
1214 		{
1215 			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1216 			&importInfo,
1217 			image,
1218 			buffer,
1219 		};
1220 		const vk::VkMemoryAllocateInfo				info			=
1221 		{
1222 			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1223 			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1224 			requirements.size,
1225 			(memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits)  : memoryTypeIndex
1226 		};
1227 		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1228 
1229 		// The handle's owned reference must also be released. Do not discard the handle below.
1230 		if (externalType != vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT)
1231 			handle.disown();
1232 
1233 		return memory;
1234 	}
1235 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1236 	{
1237 		AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance();
1238 		if (!ahbApi)
1239 		{
1240 			TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
1241 		}
1242 
1243 		deUint32 ahbFormat = 0;
1244 		ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, DE_NULL, DE_NULL);
1245 		DE_ASSERT(ahbApi->ahbFormatIsBlob(ahbFormat) || image != 0);
1246 
1247 		vk::VkAndroidHardwareBufferPropertiesANDROID ahbProperties =
1248 		{
1249 			vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
1250 			DE_NULL,
1251 			0u,
1252 			0u
1253 		};
1254 
1255 		VK_CHECK(vkd.getAndroidHardwareBufferPropertiesANDROID(device, handle.getAndroidHardwareBuffer(), &ahbProperties));
1256 
1257 		vk::VkImportAndroidHardwareBufferInfoANDROID	importInfo =
1258 		{
1259 			vk::VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
1260 			DE_NULL,
1261 			handle.getAndroidHardwareBuffer()
1262 		};
1263 		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo =
1264 		{
1265 			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
1266 			&importInfo,
1267 			image,
1268 			buffer,
1269 		};
1270 		const vk::VkMemoryAllocateInfo					info =
1271 		{
1272 			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1273 			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1274 			ahbProperties.allocationSize,
1275 			(memoryTypeIndex == ~0U) ? chooseMemoryType(ahbProperties.memoryTypeBits)  : memoryTypeIndex
1276 		};
1277 		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1278 
1279 		return memory;
1280 	}
1281 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT)
1282 	{
1283 		DE_ASSERT(memoryTypeIndex != ~0U);
1284 
1285 		const vk::VkImportMemoryHostPointerInfoEXT	importInfo		=
1286 		{
1287 			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
1288 			DE_NULL,
1289 			externalType,
1290 			handle.getHostPtr()
1291 		};
1292 		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo	=
1293 		{
1294 			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1295 			&importInfo,
1296 			image,
1297 			buffer,
1298 		};
1299 		const vk::VkMemoryAllocateInfo					info =
1300 		{
1301 			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1302 			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1303 			requirements.size,
1304 			memoryTypeIndex
1305 		};
1306 		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1307 
1308 		return memory;
1309 	}
1310 	else
1311 	{
1312 		DE_FATAL("Unknown external memory type");
1313 		return vk::Move<vk::VkDeviceMemory>();
1314 	}
1315 }
1316 
importMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,const vk::VkMemoryRequirements & requirements,vk::VkExternalMemoryHandleTypeFlagBits externalType,deUint32 memoryTypeIndex,NativeHandle & handle)1317 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&					vkd,
1318 										   vk::VkDevice									device,
1319 										   const vk::VkMemoryRequirements&				requirements,
1320 										   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
1321 										   deUint32										memoryTypeIndex,
1322 										   NativeHandle&								handle)
1323 {
1324 	return importMemory(vkd, device, (vk::VkBuffer)0, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
1325 }
1326 
importDedicatedMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkBuffer buffer,const vk::VkMemoryRequirements & requirements,vk::VkExternalMemoryHandleTypeFlagBits externalType,deUint32 memoryTypeIndex,NativeHandle & handle)1327 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface&					vkd,
1328 													vk::VkDevice								device,
1329 													vk::VkBuffer								buffer,
1330 													const vk::VkMemoryRequirements&				requirements,
1331 													vk::VkExternalMemoryHandleTypeFlagBits		externalType,
1332 													deUint32									memoryTypeIndex,
1333 													NativeHandle&								handle)
1334 {
1335 	return importMemory(vkd, device, buffer, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
1336 }
1337 
importDedicatedMemory(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkImage image,const vk::VkMemoryRequirements & requirements,vk::VkExternalMemoryHandleTypeFlagBits externalType,deUint32 memoryTypeIndex,NativeHandle & handle)1338 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface&					vkd,
1339 													vk::VkDevice								device,
1340 													vk::VkImage									image,
1341 													const vk::VkMemoryRequirements&				requirements,
1342 													vk::VkExternalMemoryHandleTypeFlagBits		externalType,
1343 													deUint32									memoryTypeIndex,
1344 													NativeHandle&								handle)
1345 {
1346 	return importMemory(vkd, device, (vk::VkBuffer)0, image, requirements, externalType, memoryTypeIndex, handle);
1347 }
1348 
createExternalBuffer(const vk::DeviceInterface & vkd,vk::VkDevice device,deUint32 queueFamilyIndex,vk::VkExternalMemoryHandleTypeFlagBits externalType,vk::VkDeviceSize size,vk::VkBufferCreateFlags createFlags,vk::VkBufferUsageFlags usageFlags)1349 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface&					vkd,
1350 											 vk::VkDevice								device,
1351 											 deUint32									queueFamilyIndex,
1352 											 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
1353 											 vk::VkDeviceSize							size,
1354 											 vk::VkBufferCreateFlags					createFlags,
1355 											 vk::VkBufferUsageFlags						usageFlags)
1356 {
1357 	const vk::VkExternalMemoryBufferCreateInfo			externalCreateInfo	=
1358 	{
1359 		vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
1360 		DE_NULL,
1361 		(vk::VkExternalMemoryHandleTypeFlags)externalType
1362 	};
1363 	const vk::VkBufferCreateInfo						createInfo			=
1364 	{
1365 		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1366 		&externalCreateInfo,
1367 		createFlags,
1368 		size,
1369 		usageFlags,
1370 		vk::VK_SHARING_MODE_EXCLUSIVE,
1371 		1u,
1372 		&queueFamilyIndex
1373 	};
1374 
1375 	return vk::createBuffer(vkd, device, &createInfo);
1376 }
1377 
createExternalImage(const vk::DeviceInterface & vkd,vk::VkDevice device,deUint32 queueFamilyIndex,vk::VkExternalMemoryHandleTypeFlagBits externalType,vk::VkFormat format,deUint32 width,deUint32 height,vk::VkImageTiling tiling,vk::VkImageCreateFlags createFlags,vk::VkImageUsageFlags usageFlags,deUint32 mipLevels,deUint32 arrayLayers)1378 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface&					vkd,
1379 										   vk::VkDevice									device,
1380 										   deUint32										queueFamilyIndex,
1381 										   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
1382 										   vk::VkFormat									format,
1383 										   deUint32										width,
1384 										   deUint32										height,
1385 										   vk::VkImageTiling							tiling,
1386 										   vk::VkImageCreateFlags						createFlags,
1387 										   vk::VkImageUsageFlags						usageFlags,
1388 										   deUint32										mipLevels,
1389 										   deUint32										arrayLayers)
1390 {
1391 	if (createFlags & vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT && arrayLayers < 6u)
1392 		arrayLayers = 6u;
1393 
1394 	const vk::VkExternalMemoryImageCreateInfo		externalCreateInfo	=
1395 	{
1396 		vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
1397 		DE_NULL,
1398 		(vk::VkExternalMemoryHandleTypeFlags)externalType
1399 	};
1400 	const vk::VkImageCreateInfo						createInfo			=
1401 	{
1402 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1403 		&externalCreateInfo,
1404 		createFlags,
1405 		vk::VK_IMAGE_TYPE_2D,
1406 		format,
1407 		{ width, height, 1u, },
1408 		mipLevels,
1409 		arrayLayers,
1410 		vk::VK_SAMPLE_COUNT_1_BIT,
1411 		tiling,
1412 		usageFlags,
1413 		vk::VK_SHARING_MODE_EXCLUSIVE,
1414 		1,
1415 		&queueFamilyIndex,
1416 		vk::VK_IMAGE_LAYOUT_UNDEFINED
1417 	};
1418 
1419 	return vk::createImage(vkd, device, &createInfo);
1420 }
1421 
1422 #if (DE_OS == DE_OS_ANDROID)
1423 #  if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
1424 #      define BUILT_WITH_ANDROID_P_HARDWARE_BUFFER 1
1425 #  endif
1426 
androidGetSdkVersion()1427 static deInt32 androidGetSdkVersion()
1428 {
1429 	static deInt32 sdkVersion = -1;
1430 	if (sdkVersion < 0)
1431 	{
1432 		char value[128] = {0};
1433 		__system_property_get("ro.build.version.sdk", value);
1434 		sdkVersion = static_cast<deInt32>(strtol(value, DE_NULL, 10));
1435 		printf("SDK Version is %d\n", sdkVersion);
1436 	}
1437 	return sdkVersion;
1438 }
1439 
checkAnbApiBuild()1440 static deInt32 checkAnbApiBuild()
1441 {
1442 	deInt32 sdkVersion = androidGetSdkVersion();
1443 #if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1444 	// When testing AHB on Android-O and newer the CTS must be compiled against API26 or newer.
1445 	DE_TEST_ASSERT(!(sdkVersion >= 26)); /* __ANDROID_API_O__ */
1446 #endif // !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1447 #if !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1448 	// When testing AHB on Android-P and newer the CTS must be compiled against API28 or newer.
1449 	DE_TEST_ASSERT(!(sdkVersion >= 28)); /*__ANDROID_API_P__ */
1450 #endif // !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1451 	return sdkVersion;
1452 }
1453 
supportsAhb()1454 bool AndroidHardwareBufferExternalApi::supportsAhb()
1455 {
1456 	return (checkAnbApiBuild() >= __ANDROID_API_O__);
1457 }
1458 
supportsCubeMap()1459 bool AndroidHardwareBufferExternalApi::supportsCubeMap()
1460 {
1461 	return (checkAnbApiBuild() >= 28);
1462 }
1463 
AndroidHardwareBufferExternalApi()1464 AndroidHardwareBufferExternalApi::AndroidHardwareBufferExternalApi()
1465 {
1466 	deInt32 sdkVersion = checkAnbApiBuild();
1467 	if(sdkVersion >= __ANDROID_API_O__)
1468 	{
1469 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1470 		if (!loadAhbDynamicApis(sdkVersion))
1471 		{
1472 			// Couldn't load  Android AHB system APIs.
1473 			DE_TEST_ASSERT(false);
1474 		}
1475 #else
1476 		// Invalid Android AHB APIs configuration. Please check the instructions on how to build NDK for Android.
1477 		DE_TEST_ASSERT(false);
1478 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1479 	}
1480 }
1481 
~AndroidHardwareBufferExternalApi()1482 AndroidHardwareBufferExternalApi::~AndroidHardwareBufferExternalApi()
1483 {
1484 }
1485 
1486 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1487 typedef int  (*pfn_system_property_get)(const char *, char *);
1488 typedef int  (*pfnAHardwareBuffer_allocate)(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer);
1489 typedef void (*pfnAHardwareBuffer_describe)(const AHardwareBuffer* buffer, AHardwareBuffer_Desc* outDesc);
1490 typedef void (*pfnAHardwareBuffer_acquire)(AHardwareBuffer* buffer);
1491 typedef void (*pfnAHardwareBuffer_release)(AHardwareBuffer* buffer);
1492 
1493 struct AhbFunctions
1494 {
1495 	pfnAHardwareBuffer_allocate allocate;
1496 	pfnAHardwareBuffer_describe describe;
1497 	pfnAHardwareBuffer_acquire  acquire;
1498 	pfnAHardwareBuffer_release  release;
1499 };
1500 
1501 static AhbFunctions ahbFunctions;
1502 
ahbFunctionsLoaded(AhbFunctions * pAhbFunctions)1503 static bool ahbFunctionsLoaded(AhbFunctions* pAhbFunctions)
1504 {
1505 	static bool ahbApiLoaded = false;
1506 	if (ahbApiLoaded ||
1507 	    ((pAhbFunctions->allocate != DE_NULL) &&
1508 		(pAhbFunctions->describe != DE_NULL) &&
1509 		(pAhbFunctions->acquire  != DE_NULL) &&
1510 		(pAhbFunctions->release  != DE_NULL)))
1511 	{
1512 		ahbApiLoaded = true;
1513 		return true;
1514 	}
1515 	return false;
1516 }
1517 
loadAhbDynamicApis(deInt32 sdkVersion)1518 bool AndroidHardwareBufferExternalApi::loadAhbDynamicApis(deInt32 sdkVersion)
1519 {
1520 	if(sdkVersion >= __ANDROID_API_O__)
1521 	{
1522 		if (!ahbFunctionsLoaded(&ahbFunctions))
1523 		{
1524 			static de::DynamicLibrary libnativewindow("libnativewindow.so");
1525 			ahbFunctions.allocate = reinterpret_cast<pfnAHardwareBuffer_allocate>(libnativewindow.getFunction("AHardwareBuffer_allocate"));
1526 			ahbFunctions.describe = reinterpret_cast<pfnAHardwareBuffer_describe>(libnativewindow.getFunction("AHardwareBuffer_describe"));
1527 			ahbFunctions.acquire  = reinterpret_cast<pfnAHardwareBuffer_acquire>(libnativewindow.getFunction("AHardwareBuffer_acquire"));
1528 			ahbFunctions.release  = reinterpret_cast<pfnAHardwareBuffer_release>(libnativewindow.getFunction("AHardwareBuffer_release"));
1529 
1530 			return ahbFunctionsLoaded(&ahbFunctions);
1531 
1532 		}
1533 		else
1534 		{
1535 			return true;
1536 		}
1537 	}
1538 
1539 	return false;
1540 }
1541 
1542 class AndroidHardwareBufferExternalApi26 : public  AndroidHardwareBufferExternalApi
1543 {
1544 public:
1545 
1546 	virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32  height, deUint32 layers, deUint32  format, deUint64 usage);
1547 	virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer);
1548 	virtual void release(vk::pt::AndroidHardwareBufferPtr buffer);
1549 	virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer,
1550 				  deUint32* width,
1551 				  deUint32* height,
1552 				  deUint32* layers,
1553 				  deUint32* format,
1554 				  deUint64* usage,
1555 				  deUint32* stride);
1556 	virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag);
1557 	virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1558 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1559 	virtual deUint64 mustSupportAhbUsageFlags();
ahbFormatIsBlob(deUint32 ahbFormat)1560 	virtual bool     ahbFormatIsBlob(deUint32 ahbFormat) { return (ahbFormat == AHARDWAREBUFFER_FORMAT_BLOB); };
1561 
AndroidHardwareBufferExternalApi26()1562 	AndroidHardwareBufferExternalApi26() : AndroidHardwareBufferExternalApi() {};
~AndroidHardwareBufferExternalApi26()1563 	virtual ~AndroidHardwareBufferExternalApi26() {};
1564 
1565 private:
1566 	// Stop the compiler generating methods of copy the object
1567 	AndroidHardwareBufferExternalApi26(AndroidHardwareBufferExternalApi26 const& copy);            // Not Implemented
1568 	AndroidHardwareBufferExternalApi26& operator=(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented
1569 };
1570 
allocate(deUint32 width,deUint32 height,deUint32 layers,deUint32 format,deUint64 usage)1571 vk::pt::AndroidHardwareBufferPtr AndroidHardwareBufferExternalApi26::allocate(	deUint32 width,
1572 																				deUint32 height,
1573 																				deUint32 layers,
1574 																				deUint32 format,
1575 																				deUint64 usage)
1576 {
1577 	AHardwareBuffer_Desc hbufferdesc = {
1578 		width,
1579 		height,
1580 		layers,   // number of images
1581 		format,
1582 		usage,
1583 		0u,       // Stride in pixels, ignored for AHardwareBuffer_allocate()
1584 		0u,       // Initialize to zero, reserved for future use
1585 		0u        // Initialize to zero, reserved for future use
1586 	};
1587 
1588 	AHardwareBuffer* hbuffer  = DE_NULL;
1589 	ahbFunctions.allocate(&hbufferdesc, &hbuffer);
1590 
1591 	return vk::pt::AndroidHardwareBufferPtr(hbuffer);
1592 }
1593 
acquire(vk::pt::AndroidHardwareBufferPtr buffer)1594 void AndroidHardwareBufferExternalApi26::acquire(vk::pt::AndroidHardwareBufferPtr buffer)
1595 {
1596 	ahbFunctions.acquire(static_cast<AHardwareBuffer*>(buffer.internal));
1597 }
1598 
release(vk::pt::AndroidHardwareBufferPtr buffer)1599 void AndroidHardwareBufferExternalApi26::release(vk::pt::AndroidHardwareBufferPtr buffer)
1600 {
1601 	ahbFunctions.release(static_cast<AHardwareBuffer*>(buffer.internal));
1602 }
1603 
describe(const vk::pt::AndroidHardwareBufferPtr buffer,deUint32 * width,deUint32 * height,deUint32 * layers,deUint32 * format,deUint64 * usage,deUint32 * stride)1604 void AndroidHardwareBufferExternalApi26::describe( const vk::pt::AndroidHardwareBufferPtr buffer,
1605 													deUint32* width,
1606 													deUint32* height,
1607 													deUint32* layers,
1608 													deUint32* format,
1609 													deUint64* usage,
1610 													deUint32* stride)
1611 {
1612 	AHardwareBuffer_Desc desc;
1613 	ahbFunctions.describe(static_cast<const AHardwareBuffer*>(buffer.internal), &desc);
1614 	if (width)  *width  = desc.width;
1615 	if (height) *height = desc.height;
1616 	if (layers) *layers = desc.layers;
1617 	if (format) *format = desc.format;
1618 	if (usage)  *usage  = desc.usage;
1619 	if (stride) *stride = desc.stride;
1620 }
1621 
vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)1622 deUint64 AndroidHardwareBufferExternalApi26::vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)
1623 {
1624 	switch(vkFlags)
1625 	{
1626 	  case vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT:
1627 	  case vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT:
1628 		// No AHB equivalent.
1629 		return 0u;
1630 	  case vk::VK_IMAGE_USAGE_SAMPLED_BIT:
1631 		return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1632 	  case vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
1633 		return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1634 	  case vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:
1635 	  case vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT:
1636 		// Alias of AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER which is defined in later Android API versions.
1637 		return AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
1638 	  default:
1639 		  return 0u;
1640 	}
1641 }
1642 
vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)1643 deUint64 AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1644 {
1645 	switch(vkFlags)
1646 	{
1647 	  case vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT:
1648 	  case vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT:
1649 		// No AHB equivalent.
1650 		return 0u;
1651 	  case vk::VK_IMAGE_CREATE_PROTECTED_BIT:
1652 		return AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
1653 	  default:
1654 		return 0u;
1655 	}
1656 }
1657 
vkFormatToAhbFormat(vk::VkFormat vkFormat)1658 deUint32 AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1659 {
1660 	 switch(vkFormat)
1661 	 {
1662 	   case vk::VK_FORMAT_R8G8B8A8_UNORM:
1663 		 return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
1664 	   case vk::VK_FORMAT_R8G8B8_UNORM:
1665 		 return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
1666 	   case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
1667 		 return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
1668 	   case vk::VK_FORMAT_R16G16B16A16_SFLOAT:
1669 		 return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
1670 	   case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1671 		 return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
1672 	   default:
1673 		 return 0u;
1674 	 }
1675 }
1676 
mustSupportAhbUsageFlags()1677 deUint64 AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags()
1678 {
1679 	return (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT);
1680 }
1681 
1682 #if defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1683 class AndroidHardwareBufferExternalApi28 : public  AndroidHardwareBufferExternalApi26
1684 {
1685 public:
1686 
1687 	virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1688 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1689 	virtual deUint64 mustSupportAhbUsageFlags();
1690 
AndroidHardwareBufferExternalApi28()1691 	AndroidHardwareBufferExternalApi28() : AndroidHardwareBufferExternalApi26() {};
~AndroidHardwareBufferExternalApi28()1692 	virtual ~AndroidHardwareBufferExternalApi28() {};
1693 
1694 private:
1695 	// Stop the compiler generating methods of copy the object
1696 	AndroidHardwareBufferExternalApi28(AndroidHardwareBufferExternalApi28 const& copy);            // Not Implemented
1697 	AndroidHardwareBufferExternalApi28& operator=(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented
1698 };
1699 
vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)1700 deUint64 AndroidHardwareBufferExternalApi28::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1701 {
1702 	switch(vkFlags)
1703 	{
1704 	  case vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:
1705 		return AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
1706 	  default:
1707 		return AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vkFlags);
1708 	}
1709 }
1710 
vkFormatToAhbFormat(vk::VkFormat vkFormat)1711 deUint32 AndroidHardwareBufferExternalApi28::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1712 {
1713 	switch(vkFormat)
1714 	{
1715 	  case vk::VK_FORMAT_D16_UNORM:
1716 		return AHARDWAREBUFFER_FORMAT_D16_UNORM;
1717 	  case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
1718 		return AHARDWAREBUFFER_FORMAT_D24_UNORM;
1719 	  case vk::VK_FORMAT_D24_UNORM_S8_UINT:
1720 		return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
1721 	  case vk::VK_FORMAT_D32_SFLOAT:
1722 		return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
1723 	  case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
1724 		return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
1725 	  case vk::VK_FORMAT_S8_UINT:
1726 		return AHARDWAREBUFFER_FORMAT_S8_UINT;
1727 	  default:
1728 		return AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vkFormat);
1729 	}
1730 }
1731 
mustSupportAhbUsageFlags()1732 deUint64 AndroidHardwareBufferExternalApi28::mustSupportAhbUsageFlags()
1733 {
1734 	return AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags() | AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
1735 }
1736 
1737 #endif // defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1738 
1739 #if defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1740 class AndroidHardwareBufferExternalApi33 : public  AndroidHardwareBufferExternalApi28
1741 {
1742 public:
1743 
1744 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1745 
AndroidHardwareBufferExternalApi33()1746 	AndroidHardwareBufferExternalApi33() : AndroidHardwareBufferExternalApi28() {};
~AndroidHardwareBufferExternalApi33()1747 	virtual ~AndroidHardwareBufferExternalApi33() {};
1748 
1749 private:
1750 	// Stop the compiler generating methods of copy the object
1751 	AndroidHardwareBufferExternalApi33(AndroidHardwareBufferExternalApi33 const& copy);            // Not Implemented
1752 	AndroidHardwareBufferExternalApi33& operator=(AndroidHardwareBufferExternalApi33 const& copy); // Not Implemented
1753 };
1754 
vkFormatToAhbFormat(vk::VkFormat vkFormat)1755 deUint32 AndroidHardwareBufferExternalApi33::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1756 {
1757 	switch(vkFormat)
1758 	{
1759 	  case vk::VK_FORMAT_R8_UNORM:
1760 		return AHARDWAREBUFFER_FORMAT_R8_UNORM;
1761 	  default:
1762 		return AndroidHardwareBufferExternalApi28::vkFormatToAhbFormat(vkFormat);
1763 	}
1764 }
1765 
1766 #endif // defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1767 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1768 #endif // (DE_OS == DE_OS_ANDROID)
1769 
getInstance()1770 AndroidHardwareBufferExternalApi* AndroidHardwareBufferExternalApi::getInstance()
1771 {
1772 #if (DE_OS == DE_OS_ANDROID)
1773 	deInt32 sdkVersion = checkAnbApiBuild();
1774 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1775 #  if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
1776 	if (sdkVersion >= __ANDROID_API_P__ )
1777 	{
1778 		static AndroidHardwareBufferExternalApi28 api28Instance;
1779 		return &api28Instance;
1780 	}
1781 #  endif
1782 #  if defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
1783 	if (sdkVersion >= __ANDROID_API_O__ )
1784 	{
1785 		static AndroidHardwareBufferExternalApi26 api26Instance;
1786 		return &api26Instance;
1787 	}
1788 #  endif
1789 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1790 	DE_UNREF(sdkVersion);
1791 #endif // DE_OS == DE_OS_ANDROID
1792 	return DE_NULL;
1793 }
1794 
getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice)1795 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface&	vki,
1796 																								  vk::VkPhysicalDevice			physicalDevice)
1797 {
1798 	vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalProps =
1799 	{
1800 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT,
1801 		DE_NULL,
1802 		0u,
1803 	};
1804 
1805 	vk::VkPhysicalDeviceProperties2 props2;
1806 	deMemset(&props2, 0, sizeof(props2));
1807 	props2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1808 	props2.pNext = &externalProps;
1809 
1810 	vki.getPhysicalDeviceProperties2(physicalDevice, &props2);
1811 
1812 	return externalProps;
1813 }
1814 
1815 } // ExternalMemoryUtil
1816 } // vkt
1817 
1818 #endif // CTS_USES_VULKANSC
1819