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