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