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