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