• 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 #  if defined(__ANDROID_API_T__) && (DE_ANDROID_API >= __ANDROID_API_T__)
1427 #      define BUILT_WITH_ANDROID_T_HARDWARE_BUFFER 1
1428 #  endif
1429 #  if defined(__ANDROID_API_U__) && (DE_ANDROID_API >= __ANDROID_API_U__)
1430 #      define BUILT_WITH_ANDROID_U_HARDWARE_BUFFER 1
1431 #  endif
1432 
androidGetSdkVersion()1433 static deInt32 androidGetSdkVersion()
1434 {
1435 	static deInt32 sdkVersion = -1;
1436 	if (sdkVersion < 0)
1437 	{
1438 		char value[128] = {0};
1439 		__system_property_get("ro.build.version.sdk", value);
1440 		sdkVersion = static_cast<deInt32>(strtol(value, DE_NULL, 10));
1441 		printf("SDK Version is %d\n", sdkVersion);
1442 	}
1443 	return sdkVersion;
1444 }
1445 
checkAnbApiBuild()1446 static deInt32 checkAnbApiBuild()
1447 {
1448 	deInt32 sdkVersion = androidGetSdkVersion();
1449 #if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1450 	// When testing AHB on Android-O and newer the CTS must be compiled against API26 or newer.
1451 	DE_TEST_ASSERT(!(sdkVersion >= 26)); /* __ANDROID_API_O__ */
1452 #endif // !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1453 #if !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1454 	// When testing AHB on Android-P and newer the CTS must be compiled against API28 or newer.
1455 	DE_TEST_ASSERT(!(sdkVersion >= 28)); /*__ANDROID_API_P__ */
1456 #endif // !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1457 #if !defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1458 	// When testing AHB on Android-T and newer the CTS must be compiled against API33 or newer.
1459 	DE_TEST_ASSERT(!(sdkVersion >= 33)); /*__ANDROID_API_T__ */
1460 #endif // !defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1461 #if !defined(BUILT_WITH_ANDROID_U_HARDWARE_BUFFER)
1462 	// When testing AHB on Android-U and newer the CTS must be compiled against API34 or newer.
1463 	DE_TEST_ASSERT(!(sdkVersion >= 34)); /*__ANDROID_API_U__ */
1464 #endif // !defined(BUILT_WITH_ANDROID_U_HARDWARE_BUFFER)
1465 	return sdkVersion;
1466 }
1467 
supportsAhb()1468 bool AndroidHardwareBufferExternalApi::supportsAhb()
1469 {
1470 	return (checkAnbApiBuild() >= __ANDROID_API_O__);
1471 }
1472 
supportsCubeMap()1473 bool AndroidHardwareBufferExternalApi::supportsCubeMap()
1474 {
1475 	return (checkAnbApiBuild() >= 28);
1476 }
1477 
AndroidHardwareBufferExternalApi()1478 AndroidHardwareBufferExternalApi::AndroidHardwareBufferExternalApi()
1479 {
1480 	deInt32 sdkVersion = checkAnbApiBuild();
1481 	if(sdkVersion >= __ANDROID_API_O__)
1482 	{
1483 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1484 		if (!loadAhbDynamicApis(sdkVersion))
1485 		{
1486 			// Couldn't load  Android AHB system APIs.
1487 			DE_TEST_ASSERT(false);
1488 		}
1489 #else
1490 		// Invalid Android AHB APIs configuration. Please check the instructions on how to build NDK for Android.
1491 		DE_TEST_ASSERT(false);
1492 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1493 	}
1494 }
1495 
~AndroidHardwareBufferExternalApi()1496 AndroidHardwareBufferExternalApi::~AndroidHardwareBufferExternalApi()
1497 {
1498 }
1499 
1500 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1501 typedef int  (*pfn_system_property_get)(const char *, char *);
1502 typedef int  (*pfnAHardwareBuffer_allocate)(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer);
1503 typedef void (*pfnAHardwareBuffer_describe)(const AHardwareBuffer* buffer, AHardwareBuffer_Desc* outDesc);
1504 typedef void (*pfnAHardwareBuffer_acquire)(AHardwareBuffer* buffer);
1505 typedef void (*pfnAHardwareBuffer_release)(AHardwareBuffer* buffer);
1506 
1507 struct AhbFunctions
1508 {
1509 	pfnAHardwareBuffer_allocate allocate;
1510 	pfnAHardwareBuffer_describe describe;
1511 	pfnAHardwareBuffer_acquire  acquire;
1512 	pfnAHardwareBuffer_release  release;
1513 };
1514 
1515 static AhbFunctions ahbFunctions;
1516 
ahbFunctionsLoaded(AhbFunctions * pAhbFunctions)1517 static bool ahbFunctionsLoaded(AhbFunctions* pAhbFunctions)
1518 {
1519 	static bool ahbApiLoaded = false;
1520 	if (ahbApiLoaded ||
1521 	    ((pAhbFunctions->allocate != DE_NULL) &&
1522 		(pAhbFunctions->describe != DE_NULL) &&
1523 		(pAhbFunctions->acquire  != DE_NULL) &&
1524 		(pAhbFunctions->release  != DE_NULL)))
1525 	{
1526 		ahbApiLoaded = true;
1527 		return true;
1528 	}
1529 	return false;
1530 }
1531 
loadAhbDynamicApis(deInt32 sdkVersion)1532 bool AndroidHardwareBufferExternalApi::loadAhbDynamicApis(deInt32 sdkVersion)
1533 {
1534 	if(sdkVersion >= __ANDROID_API_O__)
1535 	{
1536 		if (!ahbFunctionsLoaded(&ahbFunctions))
1537 		{
1538 			static de::DynamicLibrary libnativewindow("libnativewindow.so");
1539 			ahbFunctions.allocate = reinterpret_cast<pfnAHardwareBuffer_allocate>(libnativewindow.getFunction("AHardwareBuffer_allocate"));
1540 			ahbFunctions.describe = reinterpret_cast<pfnAHardwareBuffer_describe>(libnativewindow.getFunction("AHardwareBuffer_describe"));
1541 			ahbFunctions.acquire  = reinterpret_cast<pfnAHardwareBuffer_acquire>(libnativewindow.getFunction("AHardwareBuffer_acquire"));
1542 			ahbFunctions.release  = reinterpret_cast<pfnAHardwareBuffer_release>(libnativewindow.getFunction("AHardwareBuffer_release"));
1543 
1544 			return ahbFunctionsLoaded(&ahbFunctions);
1545 
1546 		}
1547 		else
1548 		{
1549 			return true;
1550 		}
1551 	}
1552 
1553 	return false;
1554 }
1555 
1556 class AndroidHardwareBufferExternalApi26 : public  AndroidHardwareBufferExternalApi
1557 {
1558 public:
1559 
1560 	virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32  height, deUint32 layers, deUint32  format, deUint64 usage);
1561 	virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer);
1562 	virtual void release(vk::pt::AndroidHardwareBufferPtr buffer);
1563 	virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer,
1564 				  deUint32* width,
1565 				  deUint32* height,
1566 				  deUint32* layers,
1567 				  deUint32* format,
1568 				  deUint64* usage,
1569 				  deUint32* stride);
1570 	virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag);
1571 	virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1572 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1573 	virtual deUint64 mustSupportAhbUsageFlags();
ahbFormatIsBlob(deUint32 ahbFormat)1574 	virtual bool     ahbFormatIsBlob(deUint32 ahbFormat) { return (ahbFormat == AHARDWAREBUFFER_FORMAT_BLOB); };
1575 
AndroidHardwareBufferExternalApi26()1576 	AndroidHardwareBufferExternalApi26() : AndroidHardwareBufferExternalApi() {};
~AndroidHardwareBufferExternalApi26()1577 	virtual ~AndroidHardwareBufferExternalApi26() {};
1578 
1579 private:
1580 	// Stop the compiler generating methods of copy the object
1581 	AndroidHardwareBufferExternalApi26(AndroidHardwareBufferExternalApi26 const& copy);            // Not Implemented
1582 	AndroidHardwareBufferExternalApi26& operator=(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented
1583 };
1584 
allocate(deUint32 width,deUint32 height,deUint32 layers,deUint32 format,deUint64 usage)1585 vk::pt::AndroidHardwareBufferPtr AndroidHardwareBufferExternalApi26::allocate(	deUint32 width,
1586 																				deUint32 height,
1587 																				deUint32 layers,
1588 																				deUint32 format,
1589 																				deUint64 usage)
1590 {
1591 	AHardwareBuffer_Desc hbufferdesc = {
1592 		width,
1593 		height,
1594 		layers,   // number of images
1595 		format,
1596 		usage,
1597 		0u,       // Stride in pixels, ignored for AHardwareBuffer_allocate()
1598 		0u,       // Initialize to zero, reserved for future use
1599 		0u        // Initialize to zero, reserved for future use
1600 	};
1601 
1602 	AHardwareBuffer* hbuffer  = DE_NULL;
1603 	ahbFunctions.allocate(&hbufferdesc, &hbuffer);
1604 
1605 	return vk::pt::AndroidHardwareBufferPtr(hbuffer);
1606 }
1607 
acquire(vk::pt::AndroidHardwareBufferPtr buffer)1608 void AndroidHardwareBufferExternalApi26::acquire(vk::pt::AndroidHardwareBufferPtr buffer)
1609 {
1610 	ahbFunctions.acquire(static_cast<AHardwareBuffer*>(buffer.internal));
1611 }
1612 
release(vk::pt::AndroidHardwareBufferPtr buffer)1613 void AndroidHardwareBufferExternalApi26::release(vk::pt::AndroidHardwareBufferPtr buffer)
1614 {
1615 	ahbFunctions.release(static_cast<AHardwareBuffer*>(buffer.internal));
1616 }
1617 
describe(const vk::pt::AndroidHardwareBufferPtr buffer,deUint32 * width,deUint32 * height,deUint32 * layers,deUint32 * format,deUint64 * usage,deUint32 * stride)1618 void AndroidHardwareBufferExternalApi26::describe( const vk::pt::AndroidHardwareBufferPtr buffer,
1619 													deUint32* width,
1620 													deUint32* height,
1621 													deUint32* layers,
1622 													deUint32* format,
1623 													deUint64* usage,
1624 													deUint32* stride)
1625 {
1626 	AHardwareBuffer_Desc desc;
1627 	ahbFunctions.describe(static_cast<const AHardwareBuffer*>(buffer.internal), &desc);
1628 	if (width)  *width  = desc.width;
1629 	if (height) *height = desc.height;
1630 	if (layers) *layers = desc.layers;
1631 	if (format) *format = desc.format;
1632 	if (usage)  *usage  = desc.usage;
1633 	if (stride) *stride = desc.stride;
1634 }
1635 
vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)1636 deUint64 AndroidHardwareBufferExternalApi26::vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)
1637 {
1638 	switch(vkFlags)
1639 	{
1640 	  case vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT:
1641 	  case vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT:
1642 		// No AHB equivalent.
1643 		return 0u;
1644 	  case vk::VK_IMAGE_USAGE_SAMPLED_BIT:
1645 		return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1646 	  case vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
1647 		return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1648 	  case vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:
1649 	  case vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT:
1650 		// Alias of AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER which is defined in later Android API versions.
1651 		return AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
1652 	  default:
1653 		  return 0u;
1654 	}
1655 }
1656 
vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)1657 deUint64 AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1658 {
1659 	switch(vkFlags)
1660 	{
1661 	  case vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT:
1662 	  case vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT:
1663 		// No AHB equivalent.
1664 		return 0u;
1665 	  case vk::VK_IMAGE_CREATE_PROTECTED_BIT:
1666 		return AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
1667 	  default:
1668 		return 0u;
1669 	}
1670 }
1671 
vkFormatToAhbFormat(vk::VkFormat vkFormat)1672 deUint32 AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1673 {
1674 	 switch(vkFormat)
1675 	 {
1676 	   case vk::VK_FORMAT_R8G8B8A8_UNORM:
1677 		 return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
1678 	   case vk::VK_FORMAT_R8G8B8_UNORM:
1679 		 return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
1680 	   case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
1681 		 return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
1682 	   case vk::VK_FORMAT_R16G16B16A16_SFLOAT:
1683 		 return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
1684 	   case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1685 		 return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
1686 	   default:
1687 		 return 0u;
1688 	 }
1689 }
1690 
mustSupportAhbUsageFlags()1691 deUint64 AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags()
1692 {
1693 	return (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT);
1694 }
1695 
1696 #if defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1697 class AndroidHardwareBufferExternalApi28 : public  AndroidHardwareBufferExternalApi26
1698 {
1699 public:
1700 
1701 	virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1702 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1703 	virtual deUint64 mustSupportAhbUsageFlags();
1704 
AndroidHardwareBufferExternalApi28()1705 	AndroidHardwareBufferExternalApi28() : AndroidHardwareBufferExternalApi26() {};
~AndroidHardwareBufferExternalApi28()1706 	virtual ~AndroidHardwareBufferExternalApi28() {};
1707 
1708 private:
1709 	// Stop the compiler generating methods of copy the object
1710 	AndroidHardwareBufferExternalApi28(AndroidHardwareBufferExternalApi28 const& copy);            // Not Implemented
1711 	AndroidHardwareBufferExternalApi28& operator=(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented
1712 };
1713 
vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)1714 deUint64 AndroidHardwareBufferExternalApi28::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1715 {
1716 	switch(vkFlags)
1717 	{
1718 	  case vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:
1719 		return AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
1720 	  default:
1721 		return AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vkFlags);
1722 	}
1723 }
1724 
vkFormatToAhbFormat(vk::VkFormat vkFormat)1725 deUint32 AndroidHardwareBufferExternalApi28::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1726 {
1727 	switch(vkFormat)
1728 	{
1729 	  case vk::VK_FORMAT_D16_UNORM:
1730 		return AHARDWAREBUFFER_FORMAT_D16_UNORM;
1731 	  case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
1732 		return AHARDWAREBUFFER_FORMAT_D24_UNORM;
1733 	  case vk::VK_FORMAT_D24_UNORM_S8_UINT:
1734 		return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
1735 	  case vk::VK_FORMAT_D32_SFLOAT:
1736 		return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
1737 	  case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
1738 		return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
1739 	  case vk::VK_FORMAT_S8_UINT:
1740 		return AHARDWAREBUFFER_FORMAT_S8_UINT;
1741 	  default:
1742 		return AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vkFormat);
1743 	}
1744 }
1745 
mustSupportAhbUsageFlags()1746 deUint64 AndroidHardwareBufferExternalApi28::mustSupportAhbUsageFlags()
1747 {
1748 	return AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags() | AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
1749 }
1750 
1751 #endif // defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1752 
1753 #if defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1754 class AndroidHardwareBufferExternalApi33 : public  AndroidHardwareBufferExternalApi28
1755 {
1756 public:
1757 
1758 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1759 
AndroidHardwareBufferExternalApi33()1760 	AndroidHardwareBufferExternalApi33() : AndroidHardwareBufferExternalApi28() {};
~AndroidHardwareBufferExternalApi33()1761 	virtual ~AndroidHardwareBufferExternalApi33() {};
1762 
1763 private:
1764 	// Stop the compiler generating methods of copy the object
1765 	AndroidHardwareBufferExternalApi33(AndroidHardwareBufferExternalApi33 const& copy);            // Not Implemented
1766 	AndroidHardwareBufferExternalApi33& operator=(AndroidHardwareBufferExternalApi33 const& copy); // Not Implemented
1767 };
1768 
vkFormatToAhbFormat(vk::VkFormat vkFormat)1769 deUint32 AndroidHardwareBufferExternalApi33::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1770 {
1771 	switch(vkFormat)
1772 	{
1773 	  case vk::VK_FORMAT_R8_UNORM:
1774 		return AHARDWAREBUFFER_FORMAT_R8_UNORM;
1775 	  default:
1776 		return AndroidHardwareBufferExternalApi28::vkFormatToAhbFormat(vkFormat);
1777 	}
1778 }
1779 
1780 #endif // defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1781 
1782 #if defined(BUILT_WITH_ANDROID_U_HARDWARE_BUFFER)
1783 class AndroidHardwareBufferExternalApi34 : public  AndroidHardwareBufferExternalApi33
1784 {
1785 public:
1786 
1787 	virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1788 
AndroidHardwareBufferExternalApi34()1789 	AndroidHardwareBufferExternalApi34() : AndroidHardwareBufferExternalApi33() {};
~AndroidHardwareBufferExternalApi34()1790 	virtual ~AndroidHardwareBufferExternalApi34() {};
1791 
1792 private:
1793 	// Stop the compiler generating methods of copy the object
1794 	AndroidHardwareBufferExternalApi34(AndroidHardwareBufferExternalApi34 const& copy);            // Not Implemented
1795 	AndroidHardwareBufferExternalApi34& operator=(AndroidHardwareBufferExternalApi34 const& copy); // Not Implemented
1796 };
1797 
vkFormatToAhbFormat(vk::VkFormat vkFormat)1798 deUint32 AndroidHardwareBufferExternalApi34::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1799 {
1800 	switch(vkFormat)
1801 	{
1802 	  case vk::VK_FORMAT_R16_UINT:
1803 		return AHARDWAREBUFFER_FORMAT_R16_UINT;
1804 	  case vk::VK_FORMAT_R16G16_UINT:
1805 		return AHARDWAREBUFFER_FORMAT_R16G16_UINT;
1806 	  case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
1807 		return AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM;
1808 	  default:
1809 		return AndroidHardwareBufferExternalApi33::vkFormatToAhbFormat(vkFormat);
1810 	}
1811 }
1812 
1813 #endif // defined(BUILT_WITH_ANDROID_U_HARDWARE_BUFFER)
1814 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1815 #endif // (DE_OS == DE_OS_ANDROID)
1816 
getInstance()1817 AndroidHardwareBufferExternalApi* AndroidHardwareBufferExternalApi::getInstance()
1818 {
1819 #if (DE_OS == DE_OS_ANDROID)
1820 	deInt32 sdkVersion = checkAnbApiBuild();
1821 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1822 #  if defined(__ANDROID_API_U__) && (DE_ANDROID_API >= __ANDROID_API_U__)
1823 	if (sdkVersion >= __ANDROID_API_U__ )
1824 	{
1825 		static AndroidHardwareBufferExternalApi34 api34Instance;
1826 		return &api34Instance;
1827 	}
1828 #  endif
1829 #  if defined(__ANDROID_API_T__) && (DE_ANDROID_API >= __ANDROID_API_T__)
1830 	if (sdkVersion >= __ANDROID_API_T__ )
1831 	{
1832 		static AndroidHardwareBufferExternalApi33 api33Instance;
1833 		return &api33Instance;
1834 	}
1835 #  endif
1836 #  if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
1837 	if (sdkVersion >= __ANDROID_API_P__ )
1838 	{
1839 		static AndroidHardwareBufferExternalApi28 api28Instance;
1840 		return &api28Instance;
1841 	}
1842 #  endif
1843 #  if defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
1844 	if (sdkVersion >= __ANDROID_API_O__ )
1845 	{
1846 		static AndroidHardwareBufferExternalApi26 api26Instance;
1847 		return &api26Instance;
1848 	}
1849 #  endif
1850 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1851 	DE_UNREF(sdkVersion);
1852 #endif // DE_OS == DE_OS_ANDROID
1853 	return DE_NULL;
1854 }
1855 
getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice)1856 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface&	vki,
1857 																								  vk::VkPhysicalDevice			physicalDevice)
1858 {
1859 	vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalProps =
1860 	{
1861 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT,
1862 		DE_NULL,
1863 		0u,
1864 	};
1865 
1866 	vk::VkPhysicalDeviceProperties2 props2;
1867 	deMemset(&props2, 0, sizeof(props2));
1868 	props2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1869 	props2.pNext = &externalProps;
1870 
1871 	vki.getPhysicalDeviceProperties2(physicalDevice, &props2);
1872 
1873 	return externalProps;
1874 }
1875 
1876 } // ExternalMemoryUtil
1877 } // vkt
1878 
1879 #endif // CTS_USES_VULKANSC
1880