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