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
androidGetSdkVersion()1427 static deInt32 androidGetSdkVersion()
1428 {
1429 static deInt32 sdkVersion = -1;
1430 if (sdkVersion < 0)
1431 {
1432 char value[128] = {0};
1433 __system_property_get("ro.build.version.sdk", value);
1434 sdkVersion = static_cast<deInt32>(strtol(value, DE_NULL, 10));
1435 printf("SDK Version is %d\n", sdkVersion);
1436 }
1437 return sdkVersion;
1438 }
1439
checkAnbApiBuild()1440 static deInt32 checkAnbApiBuild()
1441 {
1442 deInt32 sdkVersion = androidGetSdkVersion();
1443 #if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1444 // When testing AHB on Android-O and newer the CTS must be compiled against API26 or newer.
1445 DE_TEST_ASSERT(!(sdkVersion >= 26)); /* __ANDROID_API_O__ */
1446 #endif // !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1447 #if !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1448 // When testing AHB on Android-P and newer the CTS must be compiled against API28 or newer.
1449 DE_TEST_ASSERT(!(sdkVersion >= 28)); /*__ANDROID_API_P__ */
1450 #endif // !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1451 return sdkVersion;
1452 }
1453
supportsAhb()1454 bool AndroidHardwareBufferExternalApi::supportsAhb()
1455 {
1456 return (checkAnbApiBuild() >= __ANDROID_API_O__);
1457 }
1458
supportsCubeMap()1459 bool AndroidHardwareBufferExternalApi::supportsCubeMap()
1460 {
1461 return (checkAnbApiBuild() >= 28);
1462 }
1463
AndroidHardwareBufferExternalApi()1464 AndroidHardwareBufferExternalApi::AndroidHardwareBufferExternalApi()
1465 {
1466 deInt32 sdkVersion = checkAnbApiBuild();
1467 if(sdkVersion >= __ANDROID_API_O__)
1468 {
1469 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1470 if (!loadAhbDynamicApis(sdkVersion))
1471 {
1472 // Couldn't load Android AHB system APIs.
1473 DE_TEST_ASSERT(false);
1474 }
1475 #else
1476 // Invalid Android AHB APIs configuration. Please check the instructions on how to build NDK for Android.
1477 DE_TEST_ASSERT(false);
1478 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1479 }
1480 }
1481
~AndroidHardwareBufferExternalApi()1482 AndroidHardwareBufferExternalApi::~AndroidHardwareBufferExternalApi()
1483 {
1484 }
1485
1486 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1487 typedef int (*pfn_system_property_get)(const char *, char *);
1488 typedef int (*pfnAHardwareBuffer_allocate)(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer);
1489 typedef void (*pfnAHardwareBuffer_describe)(const AHardwareBuffer* buffer, AHardwareBuffer_Desc* outDesc);
1490 typedef void (*pfnAHardwareBuffer_acquire)(AHardwareBuffer* buffer);
1491 typedef void (*pfnAHardwareBuffer_release)(AHardwareBuffer* buffer);
1492
1493 struct AhbFunctions
1494 {
1495 pfnAHardwareBuffer_allocate allocate;
1496 pfnAHardwareBuffer_describe describe;
1497 pfnAHardwareBuffer_acquire acquire;
1498 pfnAHardwareBuffer_release release;
1499 };
1500
1501 static AhbFunctions ahbFunctions;
1502
ahbFunctionsLoaded(AhbFunctions * pAhbFunctions)1503 static bool ahbFunctionsLoaded(AhbFunctions* pAhbFunctions)
1504 {
1505 static bool ahbApiLoaded = false;
1506 if (ahbApiLoaded ||
1507 ((pAhbFunctions->allocate != DE_NULL) &&
1508 (pAhbFunctions->describe != DE_NULL) &&
1509 (pAhbFunctions->acquire != DE_NULL) &&
1510 (pAhbFunctions->release != DE_NULL)))
1511 {
1512 ahbApiLoaded = true;
1513 return true;
1514 }
1515 return false;
1516 }
1517
loadAhbDynamicApis(deInt32 sdkVersion)1518 bool AndroidHardwareBufferExternalApi::loadAhbDynamicApis(deInt32 sdkVersion)
1519 {
1520 if(sdkVersion >= __ANDROID_API_O__)
1521 {
1522 if (!ahbFunctionsLoaded(&ahbFunctions))
1523 {
1524 static de::DynamicLibrary libnativewindow("libnativewindow.so");
1525 ahbFunctions.allocate = reinterpret_cast<pfnAHardwareBuffer_allocate>(libnativewindow.getFunction("AHardwareBuffer_allocate"));
1526 ahbFunctions.describe = reinterpret_cast<pfnAHardwareBuffer_describe>(libnativewindow.getFunction("AHardwareBuffer_describe"));
1527 ahbFunctions.acquire = reinterpret_cast<pfnAHardwareBuffer_acquire>(libnativewindow.getFunction("AHardwareBuffer_acquire"));
1528 ahbFunctions.release = reinterpret_cast<pfnAHardwareBuffer_release>(libnativewindow.getFunction("AHardwareBuffer_release"));
1529
1530 return ahbFunctionsLoaded(&ahbFunctions);
1531
1532 }
1533 else
1534 {
1535 return true;
1536 }
1537 }
1538
1539 return false;
1540 }
1541
1542 class AndroidHardwareBufferExternalApi26 : public AndroidHardwareBufferExternalApi
1543 {
1544 public:
1545
1546 virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32 height, deUint32 layers, deUint32 format, deUint64 usage);
1547 virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer);
1548 virtual void release(vk::pt::AndroidHardwareBufferPtr buffer);
1549 virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer,
1550 deUint32* width,
1551 deUint32* height,
1552 deUint32* layers,
1553 deUint32* format,
1554 deUint64* usage,
1555 deUint32* stride);
1556 virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag);
1557 virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1558 virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1559 virtual deUint64 mustSupportAhbUsageFlags();
ahbFormatIsBlob(deUint32 ahbFormat)1560 virtual bool ahbFormatIsBlob(deUint32 ahbFormat) { return (ahbFormat == AHARDWAREBUFFER_FORMAT_BLOB); };
1561
AndroidHardwareBufferExternalApi26()1562 AndroidHardwareBufferExternalApi26() : AndroidHardwareBufferExternalApi() {};
~AndroidHardwareBufferExternalApi26()1563 virtual ~AndroidHardwareBufferExternalApi26() {};
1564
1565 private:
1566 // Stop the compiler generating methods of copy the object
1567 AndroidHardwareBufferExternalApi26(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented
1568 AndroidHardwareBufferExternalApi26& operator=(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented
1569 };
1570
allocate(deUint32 width,deUint32 height,deUint32 layers,deUint32 format,deUint64 usage)1571 vk::pt::AndroidHardwareBufferPtr AndroidHardwareBufferExternalApi26::allocate( deUint32 width,
1572 deUint32 height,
1573 deUint32 layers,
1574 deUint32 format,
1575 deUint64 usage)
1576 {
1577 AHardwareBuffer_Desc hbufferdesc = {
1578 width,
1579 height,
1580 layers, // number of images
1581 format,
1582 usage,
1583 0u, // Stride in pixels, ignored for AHardwareBuffer_allocate()
1584 0u, // Initialize to zero, reserved for future use
1585 0u // Initialize to zero, reserved for future use
1586 };
1587
1588 AHardwareBuffer* hbuffer = DE_NULL;
1589 ahbFunctions.allocate(&hbufferdesc, &hbuffer);
1590
1591 return vk::pt::AndroidHardwareBufferPtr(hbuffer);
1592 }
1593
acquire(vk::pt::AndroidHardwareBufferPtr buffer)1594 void AndroidHardwareBufferExternalApi26::acquire(vk::pt::AndroidHardwareBufferPtr buffer)
1595 {
1596 ahbFunctions.acquire(static_cast<AHardwareBuffer*>(buffer.internal));
1597 }
1598
release(vk::pt::AndroidHardwareBufferPtr buffer)1599 void AndroidHardwareBufferExternalApi26::release(vk::pt::AndroidHardwareBufferPtr buffer)
1600 {
1601 ahbFunctions.release(static_cast<AHardwareBuffer*>(buffer.internal));
1602 }
1603
describe(const vk::pt::AndroidHardwareBufferPtr buffer,deUint32 * width,deUint32 * height,deUint32 * layers,deUint32 * format,deUint64 * usage,deUint32 * stride)1604 void AndroidHardwareBufferExternalApi26::describe( const vk::pt::AndroidHardwareBufferPtr buffer,
1605 deUint32* width,
1606 deUint32* height,
1607 deUint32* layers,
1608 deUint32* format,
1609 deUint64* usage,
1610 deUint32* stride)
1611 {
1612 AHardwareBuffer_Desc desc;
1613 ahbFunctions.describe(static_cast<const AHardwareBuffer*>(buffer.internal), &desc);
1614 if (width) *width = desc.width;
1615 if (height) *height = desc.height;
1616 if (layers) *layers = desc.layers;
1617 if (format) *format = desc.format;
1618 if (usage) *usage = desc.usage;
1619 if (stride) *stride = desc.stride;
1620 }
1621
vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)1622 deUint64 AndroidHardwareBufferExternalApi26::vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)
1623 {
1624 switch(vkFlags)
1625 {
1626 case vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT:
1627 case vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT:
1628 // No AHB equivalent.
1629 return 0u;
1630 case vk::VK_IMAGE_USAGE_SAMPLED_BIT:
1631 return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1632 case vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
1633 return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1634 case vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:
1635 case vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT:
1636 // Alias of AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER which is defined in later Android API versions.
1637 return AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
1638 default:
1639 return 0u;
1640 }
1641 }
1642
vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)1643 deUint64 AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1644 {
1645 switch(vkFlags)
1646 {
1647 case vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT:
1648 case vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT:
1649 // No AHB equivalent.
1650 return 0u;
1651 case vk::VK_IMAGE_CREATE_PROTECTED_BIT:
1652 return AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
1653 default:
1654 return 0u;
1655 }
1656 }
1657
vkFormatToAhbFormat(vk::VkFormat vkFormat)1658 deUint32 AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1659 {
1660 switch(vkFormat)
1661 {
1662 case vk::VK_FORMAT_R8G8B8A8_UNORM:
1663 return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
1664 case vk::VK_FORMAT_R8G8B8_UNORM:
1665 return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
1666 case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
1667 return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
1668 case vk::VK_FORMAT_R16G16B16A16_SFLOAT:
1669 return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
1670 case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1671 return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
1672 default:
1673 return 0u;
1674 }
1675 }
1676
mustSupportAhbUsageFlags()1677 deUint64 AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags()
1678 {
1679 return (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT);
1680 }
1681
1682 #if defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1683 class AndroidHardwareBufferExternalApi28 : public AndroidHardwareBufferExternalApi26
1684 {
1685 public:
1686
1687 virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1688 virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1689 virtual deUint64 mustSupportAhbUsageFlags();
1690
AndroidHardwareBufferExternalApi28()1691 AndroidHardwareBufferExternalApi28() : AndroidHardwareBufferExternalApi26() {};
~AndroidHardwareBufferExternalApi28()1692 virtual ~AndroidHardwareBufferExternalApi28() {};
1693
1694 private:
1695 // Stop the compiler generating methods of copy the object
1696 AndroidHardwareBufferExternalApi28(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented
1697 AndroidHardwareBufferExternalApi28& operator=(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented
1698 };
1699
vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)1700 deUint64 AndroidHardwareBufferExternalApi28::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1701 {
1702 switch(vkFlags)
1703 {
1704 case vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:
1705 return AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
1706 default:
1707 return AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vkFlags);
1708 }
1709 }
1710
vkFormatToAhbFormat(vk::VkFormat vkFormat)1711 deUint32 AndroidHardwareBufferExternalApi28::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1712 {
1713 switch(vkFormat)
1714 {
1715 case vk::VK_FORMAT_D16_UNORM:
1716 return AHARDWAREBUFFER_FORMAT_D16_UNORM;
1717 case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
1718 return AHARDWAREBUFFER_FORMAT_D24_UNORM;
1719 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
1720 return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
1721 case vk::VK_FORMAT_D32_SFLOAT:
1722 return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
1723 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
1724 return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
1725 case vk::VK_FORMAT_S8_UINT:
1726 return AHARDWAREBUFFER_FORMAT_S8_UINT;
1727 default:
1728 return AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vkFormat);
1729 }
1730 }
1731
mustSupportAhbUsageFlags()1732 deUint64 AndroidHardwareBufferExternalApi28::mustSupportAhbUsageFlags()
1733 {
1734 return AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags() | AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
1735 }
1736
1737 #endif // defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1738
1739 #if defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1740 class AndroidHardwareBufferExternalApi33 : public AndroidHardwareBufferExternalApi28
1741 {
1742 public:
1743
1744 virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1745
AndroidHardwareBufferExternalApi33()1746 AndroidHardwareBufferExternalApi33() : AndroidHardwareBufferExternalApi28() {};
~AndroidHardwareBufferExternalApi33()1747 virtual ~AndroidHardwareBufferExternalApi33() {};
1748
1749 private:
1750 // Stop the compiler generating methods of copy the object
1751 AndroidHardwareBufferExternalApi33(AndroidHardwareBufferExternalApi33 const& copy); // Not Implemented
1752 AndroidHardwareBufferExternalApi33& operator=(AndroidHardwareBufferExternalApi33 const& copy); // Not Implemented
1753 };
1754
vkFormatToAhbFormat(vk::VkFormat vkFormat)1755 deUint32 AndroidHardwareBufferExternalApi33::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1756 {
1757 switch(vkFormat)
1758 {
1759 case vk::VK_FORMAT_R8_UNORM:
1760 return AHARDWAREBUFFER_FORMAT_R8_UNORM;
1761 default:
1762 return AndroidHardwareBufferExternalApi28::vkFormatToAhbFormat(vkFormat);
1763 }
1764 }
1765
1766 #endif // defined(BUILT_WITH_ANDROID_T_HARDWARE_BUFFER)
1767 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1768 #endif // (DE_OS == DE_OS_ANDROID)
1769
getInstance()1770 AndroidHardwareBufferExternalApi* AndroidHardwareBufferExternalApi::getInstance()
1771 {
1772 #if (DE_OS == DE_OS_ANDROID)
1773 deInt32 sdkVersion = checkAnbApiBuild();
1774 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1775 # if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
1776 if (sdkVersion >= __ANDROID_API_P__ )
1777 {
1778 static AndroidHardwareBufferExternalApi28 api28Instance;
1779 return &api28Instance;
1780 }
1781 # endif
1782 # if defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
1783 if (sdkVersion >= __ANDROID_API_O__ )
1784 {
1785 static AndroidHardwareBufferExternalApi26 api26Instance;
1786 return &api26Instance;
1787 }
1788 # endif
1789 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1790 DE_UNREF(sdkVersion);
1791 #endif // DE_OS == DE_OS_ANDROID
1792 return DE_NULL;
1793 }
1794
getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface & vki,vk::VkPhysicalDevice physicalDevice)1795 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT getPhysicalDeviceExternalMemoryHostProperties(const vk::InstanceInterface& vki,
1796 vk::VkPhysicalDevice physicalDevice)
1797 {
1798 vk::VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalProps =
1799 {
1800 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT,
1801 DE_NULL,
1802 0u,
1803 };
1804
1805 vk::VkPhysicalDeviceProperties2 props2;
1806 deMemset(&props2, 0, sizeof(props2));
1807 props2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1808 props2.pNext = &externalProps;
1809
1810 vki.getPhysicalDeviceProperties2(physicalDevice, &props2);
1811
1812 return externalProps;
1813 }
1814
1815 } // ExternalMemoryUtil
1816 } // vkt
1817
1818 #endif // CTS_USES_VULKANSC
1819