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