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