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