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