1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * \brief Vulkan external memory API tests
20 *//*--------------------------------------------------------------------*/
22 #include "vktApiExternalMemoryTests.hpp"
24 #include "vktTestCaseUtil.hpp"
25 #include "vkRefUtil.hpp"
26 #include "vkDeviceUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkPlatform.hpp"
29 #include "vkMemUtil.hpp"
31 #include "tcuTestLog.hpp"
33 #include "deUniquePtr.hpp"
34 #include "deStringUtil.hpp"
35 #include "deRandom.hpp"
39 #include "vktExternalMemoryUtil.hpp"
41 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
45 # include <sys/types.h>
46 # include <sys/socket.h>
49 #if (DE_OS == DE_OS_WIN32)
50 # define WIN32_LEAN_AND_MEAN
56 using namespace vkt::ExternalMemoryUtil;
65 vk::VkMemoryDedicatedRequirementsKHR getMemoryDedicatedRequirements (const vk::DeviceInterface& vkd,
69 const vk::VkBufferMemoryRequirementsInfo2KHR requirementInfo =
71 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR,
75 vk::VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
77 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,
82 vk::VkMemoryRequirements2KHR requirements =
84 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,
85 &dedicatedRequirements,
89 vkd.getBufferMemoryRequirements2KHR(device, &requirementInfo, &requirements);
91 return dedicatedRequirements;
94 vk::VkMemoryDedicatedRequirementsKHR getMemoryDedicatedRequirements (const vk::DeviceInterface& vkd,
98 const vk::VkImageMemoryRequirementsInfo2KHR requirementInfo =
100 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR,
104 vk::VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
106 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,
111 vk::VkMemoryRequirements2KHR requirements =
113 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,
114 &dedicatedRequirements,
118 vkd.getImageMemoryRequirements2KHR(device, &requirementInfo, &requirements);
120 return dedicatedRequirements;
123 void writeHostMemory (const vk::DeviceInterface& vkd,
125 vk::VkDeviceMemory memory,
129 void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);
131 deMemcpy(ptr, data, size);
133 vkd.unmapMemory(device, memory);
136 void checkHostMemory (const vk::DeviceInterface& vkd,
138 vk::VkDeviceMemory memory,
142 void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);
144 if (deMemCmp(ptr, data, size) != 0)
145 TCU_FAIL("Memory contents don't match");
147 vkd.unmapMemory(device, memory);
150 std::vector<deUint8> genTestData (deUint32 seed, size_t size)
152 de::Random rng (seed);
153 std::vector<deUint8> data (size);
155 for (size_t ndx = 0; ndx < size; ndx++)
157 data[ndx] = rng.getUint8();
163 deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki,
164 vk::VkPhysicalDevice device,
165 vk::VkQueueFlags requireFlags)
167 const std::vector<vk::VkQueueFamilyProperties> properties (vk::getPhysicalDeviceQueueFamilyProperties(vki, device));
169 for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < (deUint32)properties.size(); queueFamilyIndex++)
171 if ((properties[queueFamilyIndex].queueFlags & requireFlags) == requireFlags)
172 return queueFamilyIndex;
175 TCU_THROW(NotSupportedError, "Queue type not supported");
178 vk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface& vkp,
179 const vk::VkExternalSemaphoreHandleTypeFlagsKHR externalSemaphoreTypes,
180 const vk::VkExternalMemoryHandleTypeFlagsKHR externalMemoryTypes,
181 const vk::VkExternalFenceHandleTypeFlagsKHR externalFenceTypes)
183 std::vector<std::string> instanceExtensions;
185 instanceExtensions.push_back("VK_KHR_get_physical_device_properties2");
187 if (externalSemaphoreTypes != 0)
188 instanceExtensions.push_back("VK_KHR_external_semaphore_capabilities");
190 if (externalMemoryTypes != 0)
191 instanceExtensions.push_back("VK_KHR_external_memory_capabilities");
193 if (externalFenceTypes != 0)
194 instanceExtensions.push_back("VK_KHR_external_fence_capabilities");
198 return vk::createDefaultInstance(vkp, std::vector<std::string>(), instanceExtensions);
200 catch (const vk::Error& error)
202 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
203 TCU_THROW(NotSupportedError, "Required extensions not supported");
209 vk::Move<vk::VkDevice> createDevice (const vk::InstanceInterface& vki,
210 vk::VkPhysicalDevice physicalDevice,
211 const vk::VkExternalSemaphoreHandleTypeFlagsKHR externalSemaphoreTypes,
212 const vk::VkExternalMemoryHandleTypeFlagsKHR externalMemoryTypes,
213 const vk::VkExternalFenceHandleTypeFlagsKHR externalFenceTypes,
214 deUint32 queueFamilyIndex,
215 bool useDedicatedAllocs = false)
217 std::vector<const char*> deviceExtensions;
219 if ((externalSemaphoreTypes
220 & (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
221 | vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)) != 0)
223 deviceExtensions.push_back("VK_KHR_external_semaphore_fd");
226 if ((externalFenceTypes
227 & (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR
228 | vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)) != 0)
230 deviceExtensions.push_back("VK_KHR_external_fence_fd");
233 if (useDedicatedAllocs)
235 deviceExtensions.push_back("VK_KHR_dedicated_allocation");
236 deviceExtensions.push_back("VK_KHR_get_memory_requirements2");
239 if ((externalMemoryTypes
240 & vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR) != 0)
242 deviceExtensions.push_back("VK_KHR_external_memory_fd");
245 if ((externalSemaphoreTypes
246 & (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
247 | vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)) != 0)
249 deviceExtensions.push_back("VK_KHR_external_semaphore_win32");
252 if ((externalFenceTypes
253 & (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
254 | vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)) != 0)
256 deviceExtensions.push_back("VK_KHR_external_fence_win32");
259 if ((externalMemoryTypes
260 & (vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
261 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR
262 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR
263 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR
264 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR
265 | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR)) != 0)
267 deviceExtensions.push_back("VK_KHR_external_memory_win32");
270 const float priority = 0.5f;
271 const vk::VkDeviceQueueCreateInfo queues[] =
274 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
283 const vk::VkDeviceCreateInfo deviceCreateInfo =
285 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
289 DE_LENGTH_OF_ARRAY(queues),
295 (deUint32)deviceExtensions.size(),
296 deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],
302 return vk::createDevice(vki, physicalDevice, &deviceCreateInfo);
304 catch (const vk::Error& error)
306 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
307 TCU_THROW(NotSupportedError, "Required extensions not supported");
313 vk::VkQueue getQueue (const vk::DeviceInterface& vkd,
315 deUint32 queueFamilyIndex)
319 vkd.getDeviceQueue(device, queueFamilyIndex, 0, &queue);
324 void checkSemaphoreSupport (const vk::InstanceInterface& vki,
325 vk::VkPhysicalDevice device,
326 vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType)
328 const vk::VkPhysicalDeviceExternalSemaphoreInfoKHR info =
330 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR,
334 vk::VkExternalSemaphorePropertiesKHR properties =
336 vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR,
343 vki.getPhysicalDeviceExternalSemaphorePropertiesKHR(device, &info, &properties);
345 if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) == 0)
346 TCU_THROW(NotSupportedError, "Semaphore doesn't support exporting in external type");
348 if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR) == 0)
349 TCU_THROW(NotSupportedError, "Semaphore doesn't support importing in external type");
352 void checkFenceSupport (const vk::InstanceInterface& vki,
353 vk::VkPhysicalDevice device,
354 vk::VkExternalFenceHandleTypeFlagBitsKHR externalType)
356 const vk::VkPhysicalDeviceExternalFenceInfoKHR info =
358 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR,
362 vk::VkExternalFencePropertiesKHR properties =
364 vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR,
371 vki.getPhysicalDeviceExternalFencePropertiesKHR(device, &info, &properties);
373 if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) == 0)
374 TCU_THROW(NotSupportedError, "Fence doesn't support exporting in external type");
376 if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR) == 0)
377 TCU_THROW(NotSupportedError, "Fence doesn't support importing in external type");
380 void checkBufferSupport (const vk::InstanceInterface& vki,
381 vk::VkPhysicalDevice device,
382 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
383 vk::VkBufferViewCreateFlags createFlag,
384 vk::VkBufferUsageFlags usageFlag,
387 const vk::VkPhysicalDeviceExternalBufferInfoKHR info =
389 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR,
396 vk::VkExternalBufferPropertiesKHR properties =
398 vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR,
404 vki.getPhysicalDeviceExternalBufferPropertiesKHR(device, &info, &properties);
406 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) == 0)
407 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting buffer");
409 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) == 0)
410 TCU_THROW(NotSupportedError, "External handle type doesn't support importing buffer");
412 if (!dedicated && (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0)
413 TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
416 void checkImageSupport (const vk::InstanceInterface& vki,
417 vk::VkPhysicalDevice device,
418 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
419 vk::VkImageViewCreateFlags createFlag,
420 vk::VkImageUsageFlags usageFlag,
422 vk::VkImageTiling tiling,
425 const vk::VkPhysicalDeviceExternalImageFormatInfoKHR externalInfo =
427 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR,
431 const vk::VkPhysicalDeviceImageFormatInfo2KHR info =
433 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
437 vk::VK_IMAGE_TYPE_2D,
442 vk::VkExternalImageFormatPropertiesKHR externalProperties =
444 vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
448 vk::VkImageFormatProperties2KHR properties =
450 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR,
461 vki.getPhysicalDeviceImageFormatProperties2KHR(device, &info, &properties);
463 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) == 0)
464 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting image");
466 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) == 0)
467 TCU_THROW(NotSupportedError, "External handle type doesn't support importing image");
469 if (!dedicated && (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0)
470 TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
473 void submitDummySignal (const vk::DeviceInterface& vkd,
475 vk::VkSemaphore semaphore)
477 const vk::VkSubmitInfo submit =
479 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
493 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
496 void submitDummyWait (const vk::DeviceInterface& vkd,
498 vk::VkSemaphore semaphore)
500 const vk::VkPipelineStageFlags stage = vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
501 const vk::VkSubmitInfo submit =
503 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
517 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
520 void submitDummySignal (const vk::DeviceInterface& vkd,
524 const vk::VkSubmitInfo submit =
526 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
540 VK_CHECK(vkd.queueSubmit(queue, 1, &submit, fence));
543 tcu::TestStatus testSemaphoreQueries (Context& context, vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType)
545 const vk::PlatformInterface& vkp (context.getPlatformInterface());
546 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, externalType, 0u, 0u));
547 const vk::InstanceDriver vki (vkp, *instance);
548 const vk::VkPhysicalDevice device (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
550 TestLog& log = context.getTestContext().getLog();
552 const vk::VkPhysicalDeviceExternalSemaphoreInfoKHR info =
554 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR,
558 vk::VkExternalSemaphorePropertiesKHR properties =
560 vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR,
567 vki.getPhysicalDeviceExternalSemaphorePropertiesKHR(device, &info, &properties);
568 log << TestLog::Message << properties << TestLog::EndMessage;
570 TCU_CHECK(properties.pNext == DE_NULL);
571 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR);
573 return tcu::TestStatus::pass("Pass");
576 struct SemaphoreTestConfig
578 SemaphoreTestConfig (vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType_,
579 Permanence permanence_)
580 : externalType (externalType_)
581 , permanence (permanence_)
585 vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType;
586 Permanence permanence;
589 tcu::TestStatus testSemaphoreWin32Create (Context& context,
590 const SemaphoreTestConfig config)
592 #if (DE_OS == DE_OS_WIN32)
593 const Transference transference (getHandelTypeTransferences(config.externalType));
594 const vk::PlatformInterface& vkp (context.getPlatformInterface());
595 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
596 const vk::InstanceDriver vki (vkp, *instance);
597 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
598 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
600 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
603 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
604 const vk::DeviceDriver vkd (vki, *device);
605 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
606 const vk::VkExportSemaphoreWin32HandleInfoKHR win32ExportInfo =
608 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
611 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
612 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
615 const vk::VkExportSemaphoreCreateInfoKHR exportCreateInfo=
617 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR,
619 (vk::VkExternalMemoryHandleTypeFlagsKHR)config.externalType
621 const vk::VkSemaphoreCreateInfo createInfo =
623 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
627 const vk::Unique<vk::VkSemaphore> semaphore (vk::createSemaphore(vkd, *device, &createInfo));
629 if (transference == TRANSFERENCE_COPY)
630 submitDummySignal(vkd, queue, *semaphore);
632 NativeHandle handleA;
633 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);
636 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
637 const vk::Unique<vk::VkSemaphore> semaphoreA (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
639 if (transference == TRANSFERENCE_COPY)
640 submitDummyWait(vkd, queue, *semaphoreA);
641 else if (transference == TRANSFERENCE_REFERENCE)
643 submitDummySignal(vkd, queue, *semaphore);
644 submitDummyWait(vkd, queue, *semaphoreA);
647 DE_FATAL("Unknown transference.");
649 VK_CHECK(vkd.queueWaitIdle(queue));
652 return tcu::TestStatus::pass("Pass");
657 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
661 tcu::TestStatus testSemaphoreImportTwice (Context& context,
662 const SemaphoreTestConfig config)
664 const Transference transference (getHandelTypeTransferences(config.externalType));
665 const vk::PlatformInterface& vkp (context.getPlatformInterface());
666 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
667 const vk::InstanceDriver vki (vkp, *instance);
668 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
669 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
671 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
674 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
675 const vk::DeviceDriver vkd (vki, *device);
676 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
677 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
679 if (transference == TRANSFERENCE_COPY)
680 submitDummySignal(vkd, queue, *semaphore);
682 NativeHandle handleA;
683 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);
686 NativeHandle handleB (handleA);
687 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
688 const vk::Unique<vk::VkSemaphore> semaphoreA (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
689 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
691 if (transference == TRANSFERENCE_COPY)
692 submitDummyWait(vkd, queue, *semaphoreA);
693 else if (transference == TRANSFERENCE_REFERENCE)
695 submitDummySignal(vkd, queue, *semaphoreA);
696 submitDummyWait(vkd, queue, *semaphoreB);
699 DE_FATAL("Unknown transference.");
701 VK_CHECK(vkd.queueWaitIdle(queue));
704 return tcu::TestStatus::pass("Pass");
708 tcu::TestStatus testSemaphoreImportReimport (Context& context,
709 const SemaphoreTestConfig config)
711 const Transference transference (getHandelTypeTransferences(config.externalType));
712 const vk::PlatformInterface& vkp (context.getPlatformInterface());
713 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
714 const vk::InstanceDriver vki (vkp, *instance);
715 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
716 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
718 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
721 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
722 const vk::DeviceDriver vkd (vki, *device);
723 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
725 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
727 if (transference == TRANSFERENCE_COPY)
728 submitDummySignal(vkd, queue, *semaphoreA);
730 NativeHandle handleA;
731 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);
733 NativeHandle handleB (handleA);
734 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
735 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
737 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handleB, flags);
739 if (transference == TRANSFERENCE_COPY)
740 submitDummyWait(vkd, queue, *semaphoreB);
741 else if (transference == TRANSFERENCE_REFERENCE)
743 submitDummySignal(vkd, queue, *semaphoreA);
744 submitDummyWait(vkd, queue, *semaphoreB);
747 DE_FATAL("Unknown transference.");
749 VK_CHECK(vkd.queueWaitIdle(queue));
751 return tcu::TestStatus::pass("Pass");
755 tcu::TestStatus testSemaphoreSignalExportImportWait (Context& context,
756 const SemaphoreTestConfig config)
758 const vk::PlatformInterface& vkp (context.getPlatformInterface());
759 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
760 const vk::InstanceDriver vki (vkp, *instance);
761 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
762 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
764 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
767 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
768 const vk::DeviceDriver vkd (vki, *device);
769 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
770 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
772 submitDummySignal(vkd, queue, *semaphoreA);
777 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
780 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
781 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
782 submitDummyWait(vkd, queue, *semaphoreB);
784 VK_CHECK(vkd.queueWaitIdle(queue));
788 return tcu::TestStatus::pass("Pass");
792 tcu::TestStatus testSemaphoreExportSignalImportWait (Context& context,
793 const SemaphoreTestConfig config)
795 const vk::PlatformInterface& vkp (context.getPlatformInterface());
796 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
797 const vk::InstanceDriver vki (vkp, *instance);
798 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
799 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
800 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
802 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
803 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
806 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
807 const vk::DeviceDriver vkd (vki, *device);
808 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
810 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
813 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
815 submitDummySignal(vkd, queue, *semaphoreA);
818 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
820 submitDummyWait(vkd, queue, *semaphoreB);
821 VK_CHECK(vkd.queueWaitIdle(queue));
825 return tcu::TestStatus::pass("Pass");
829 tcu::TestStatus testSemaphoreExportImportSignalWait (Context& context,
830 const SemaphoreTestConfig config)
832 const vk::PlatformInterface& vkp (context.getPlatformInterface());
833 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
834 const vk::InstanceDriver vki (vkp, *instance);
835 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
836 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
838 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
839 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
842 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
843 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
844 const vk::DeviceDriver vkd (vki, *device);
845 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
847 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
850 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
852 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
854 submitDummySignal(vkd, queue, *semaphoreA);
855 submitDummyWait(vkd, queue, *semaphoreB);
857 VK_CHECK(vkd.queueWaitIdle(queue));
859 return tcu::TestStatus::pass("Pass");
863 tcu::TestStatus testSemaphoreSignalImport (Context& context,
864 const SemaphoreTestConfig config)
866 const Transference transference (getHandelTypeTransferences(config.externalType));
867 const vk::PlatformInterface& vkp (context.getPlatformInterface());
868 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
869 const vk::InstanceDriver vki (vkp, *instance);
870 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
871 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
873 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
876 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
877 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
878 const vk::DeviceDriver vkd (vki, *device);
879 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
881 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
882 const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(vkd, *device));
885 submitDummySignal(vkd, queue, *semaphoreB);
886 VK_CHECK(vkd.queueWaitIdle(queue));
888 if (transference == TRANSFERENCE_COPY)
889 submitDummySignal(vkd, queue, *semaphoreA);
891 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
893 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);
895 if (transference == TRANSFERENCE_COPY)
896 submitDummyWait(vkd, queue, *semaphoreB);
897 else if (transference == TRANSFERENCE_REFERENCE)
899 submitDummySignal(vkd, queue, *semaphoreA);
900 submitDummyWait(vkd, queue, *semaphoreB);
903 DE_FATAL("Unknown transference.");
905 VK_CHECK(vkd.queueWaitIdle(queue));
907 return tcu::TestStatus::pass("Pass");
911 tcu::TestStatus testSemaphoreSignalWaitImport (Context& context,
912 const SemaphoreTestConfig config)
914 const Transference transference (getHandelTypeTransferences(config.externalType));
915 const vk::PlatformInterface& vkp (context.getPlatformInterface());
916 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
917 const vk::InstanceDriver vki (vkp, *instance);
918 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
919 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
921 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
924 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
925 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
926 const vk::DeviceDriver vkd (vki, *device);
927 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
929 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
930 const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(vkd, *device));
933 if (transference == TRANSFERENCE_COPY)
934 submitDummySignal(vkd, queue, *semaphoreA);
936 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
938 submitDummySignal(vkd, queue, *semaphoreB);
939 submitDummyWait(vkd, queue, *semaphoreB);
941 VK_CHECK(vkd.queueWaitIdle(queue));
943 importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);
945 if (transference == TRANSFERENCE_COPY)
946 submitDummyWait(vkd, queue, *semaphoreB);
947 else if (transference == TRANSFERENCE_REFERENCE)
949 submitDummySignal(vkd, queue, *semaphoreA);
950 submitDummyWait(vkd, queue, *semaphoreB);
953 DE_FATAL("Unknown transference.");
955 VK_CHECK(vkd.queueWaitIdle(queue));
957 return tcu::TestStatus::pass("Pass");
961 tcu::TestStatus testSemaphoreMultipleExports (Context& context,
962 const SemaphoreTestConfig config)
964 const size_t exportCount = 4 * 1024;
965 const Transference transference (getHandelTypeTransferences(config.externalType));
966 const vk::PlatformInterface& vkp (context.getPlatformInterface());
967 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
968 const vk::InstanceDriver vki (vkp, *instance);
969 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
970 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
972 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
975 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
976 const vk::DeviceDriver vkd (vki, *device);
977 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
978 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
980 for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
984 if (transference == TRANSFERENCE_COPY)
985 submitDummySignal(vkd, queue, *semaphore);
987 getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handle);
990 submitDummySignal(vkd, queue, *semaphore);
991 submitDummyWait(vkd, queue, *semaphore);
993 VK_CHECK(vkd.queueWaitIdle(queue));
996 return tcu::TestStatus::pass("Pass");
999 tcu::TestStatus testSemaphoreMultipleImports (Context& context,
1000 const SemaphoreTestConfig config)
1002 const size_t importCount = 4 * 1024;
1003 const Transference transference (getHandelTypeTransferences(config.externalType));
1004 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1005 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1006 const vk::InstanceDriver vki (vkp, *instance);
1007 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1008 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1010 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1013 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1014 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1015 const vk::DeviceDriver vkd (vki, *device);
1016 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1017 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1018 NativeHandle handleA;
1020 if (transference == TRANSFERENCE_COPY)
1021 submitDummySignal(vkd, queue, *semaphoreA);
1023 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);
1025 for (size_t importNdx = 0; importNdx < importCount; importNdx++)
1027 NativeHandle handleB (handleA);
1028 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
1031 if (transference == TRANSFERENCE_COPY)
1033 importSemaphore(vkd, *device, *semaphoreA, config.externalType, handleA, flags);
1034 submitDummyWait(vkd, queue, *semaphoreA);
1036 else if (transference == TRANSFERENCE_REFERENCE)
1038 submitDummySignal(vkd, queue, *semaphoreA);
1039 submitDummyWait(vkd, queue, *semaphoreA);
1042 DE_FATAL("Unknown transference.");
1044 VK_CHECK(vkd.queueWaitIdle(queue));
1047 return tcu::TestStatus::pass("Pass");
1050 tcu::TestStatus testSemaphoreTransference (Context& context,
1051 const SemaphoreTestConfig config)
1053 const Transference transference (getHandelTypeTransferences(config.externalType));
1054 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1055 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1056 const vk::InstanceDriver vki (vkp, *instance);
1057 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1058 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1060 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1063 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1064 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1065 const vk::DeviceDriver vkd (vki, *device);
1066 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1068 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1069 NativeHandle handle;
1071 submitDummySignal(vkd, queue, *semaphoreA);
1073 getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
1076 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
1078 if (config.permanence == PERMANENCE_PERMANENT)
1080 if (transference == TRANSFERENCE_COPY)
1082 submitDummySignal(vkd, queue, *semaphoreA);
1083 submitDummyWait(vkd, queue, *semaphoreB);
1084 VK_CHECK(vkd.queueWaitIdle(queue));
1086 submitDummySignal(vkd, queue, *semaphoreB);
1088 submitDummyWait(vkd, queue, *semaphoreA);
1089 submitDummyWait(vkd, queue, *semaphoreB);
1090 VK_CHECK(vkd.queueWaitIdle(queue));
1092 else if (transference== TRANSFERENCE_REFERENCE)
1094 submitDummyWait(vkd, queue, *semaphoreB);
1095 VK_CHECK(vkd.queueWaitIdle(queue));
1097 submitDummySignal(vkd, queue, *semaphoreA);
1098 submitDummyWait(vkd, queue, *semaphoreB);
1100 submitDummySignal(vkd, queue, *semaphoreB);
1101 submitDummyWait(vkd, queue, *semaphoreA);
1102 VK_CHECK(vkd.queueWaitIdle(queue));
1105 DE_FATAL("Unknown transference.");
1107 else if (config.permanence == PERMANENCE_TEMPORARY)
1109 if (transference == TRANSFERENCE_COPY)
1111 submitDummySignal(vkd, queue, *semaphoreA);
1112 submitDummyWait(vkd, queue, *semaphoreB);
1113 VK_CHECK(vkd.queueWaitIdle(queue));
1115 submitDummySignal(vkd, queue, *semaphoreB);
1117 submitDummyWait(vkd, queue, *semaphoreA);
1118 submitDummyWait(vkd, queue, *semaphoreB);
1119 VK_CHECK(vkd.queueWaitIdle(queue));
1121 else if (transference== TRANSFERENCE_REFERENCE)
1123 submitDummyWait(vkd, queue, *semaphoreB);
1124 VK_CHECK(vkd.queueWaitIdle(queue));
1126 submitDummySignal(vkd, queue, *semaphoreA);
1127 submitDummySignal(vkd, queue, *semaphoreB);
1129 submitDummyWait(vkd, queue, *semaphoreB);
1130 submitDummyWait(vkd, queue, *semaphoreA);
1131 VK_CHECK(vkd.queueWaitIdle(queue));
1134 DE_FATAL("Unknown transference.");
1137 DE_FATAL("Unknown permanence.");
1140 return tcu::TestStatus::pass("Pass");
1144 tcu::TestStatus testSemaphoreFdDup (Context& context,
1145 const SemaphoreTestConfig config)
1147 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1148 const Transference transference (getHandelTypeTransferences(config.externalType));
1149 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1150 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1151 const vk::InstanceDriver vki (vkp, *instance);
1152 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1153 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1155 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1158 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1159 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1160 const vk::DeviceDriver vkd (vki, *device);
1161 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1163 TestLog& log = context.getTestContext().getLog();
1164 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1166 if (transference == TRANSFERENCE_COPY)
1167 submitDummySignal(vkd, queue, *semaphoreA);
1170 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1171 NativeHandle newFd (dup(fd.getFd()));
1173 if (newFd.getFd() < 0)
1174 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1176 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for semaphores fd");
1179 const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));
1181 if (transference == TRANSFERENCE_COPY)
1182 submitDummyWait(vkd, queue, *semaphoreB);
1183 else if (transference == TRANSFERENCE_REFERENCE)
1185 submitDummySignal(vkd, queue, *semaphoreA);
1186 submitDummyWait(vkd, queue, *semaphoreB);
1189 DE_FATAL("Unknown permanence.");
1193 VK_CHECK(vkd.queueWaitIdle(queue));
1195 return tcu::TestStatus::pass("Pass");
1200 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
1204 tcu::TestStatus testSemaphoreFdDup2 (Context& context,
1205 const SemaphoreTestConfig config)
1207 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1208 const Transference transference (getHandelTypeTransferences(config.externalType));
1209 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1210 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1211 const vk::InstanceDriver vki (vkp, *instance);
1212 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1213 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1215 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1218 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1219 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1220 const vk::DeviceDriver vkd (vki, *device);
1221 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1223 TestLog& log = context.getTestContext().getLog();
1224 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1225 const vk::Unique<vk::VkSemaphore> semaphoreB (createExportableSemaphore(vkd, *device, config.externalType));
1227 if (transference == TRANSFERENCE_COPY)
1229 submitDummySignal(vkd, queue, *semaphoreA);
1230 submitDummySignal(vkd, queue, *semaphoreB);
1234 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1235 NativeHandle secondFd (getSemaphoreFd(vkd, *device, *semaphoreB, config.externalType));
1236 int newFd (dup2(fd.getFd(), secondFd.getFd()));
1239 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1241 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");
1244 const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));
1246 if (transference == TRANSFERENCE_COPY)
1247 submitDummyWait(vkd, queue, *semaphoreC);
1248 else if (transference == TRANSFERENCE_REFERENCE)
1250 submitDummySignal(vkd, queue, *semaphoreA);
1251 submitDummyWait(vkd, queue, *semaphoreC);
1254 DE_FATAL("Unknown permanence.");
1258 VK_CHECK(vkd.queueWaitIdle(queue));
1260 return tcu::TestStatus::pass("Pass");
1265 TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
1269 tcu::TestStatus testSemaphoreFdDup3 (Context& context,
1270 const SemaphoreTestConfig config)
1272 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
1273 const Transference transference (getHandelTypeTransferences(config.externalType));
1274 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1275 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1276 const vk::InstanceDriver vki (vkp, *instance);
1277 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1278 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1280 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1283 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1284 const vk::DeviceDriver vkd (vki, *device);
1285 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1287 TestLog& log = context.getTestContext().getLog();
1288 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType));
1289 const vk::Unique<vk::VkSemaphore> semaphoreB (createExportableSemaphore(vkd, *device, config.externalType));
1291 if (transference == TRANSFERENCE_COPY)
1293 submitDummySignal(vkd, queue, *semaphoreA);
1294 submitDummySignal(vkd, queue, *semaphoreB);
1298 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1299 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphoreA, config.externalType));
1300 NativeHandle secondFd (getSemaphoreFd(vkd, *device, *semaphoreB, config.externalType));
1301 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
1304 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
1306 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");
1309 const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));
1311 if (transference == TRANSFERENCE_COPY)
1312 submitDummyWait(vkd, queue, *semaphoreC);
1313 else if (transference == TRANSFERENCE_REFERENCE)
1315 submitDummySignal(vkd, queue, *semaphoreA);
1316 submitDummyWait(vkd, queue, *semaphoreC);
1319 DE_FATAL("Unknown permanence.");
1323 VK_CHECK(vkd.queueWaitIdle(queue));
1325 return tcu::TestStatus::pass("Pass");
1330 TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
1334 tcu::TestStatus testSemaphoreFdSendOverSocket (Context& context,
1335 const SemaphoreTestConfig config)
1337 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
1338 const Transference transference (getHandelTypeTransferences(config.externalType));
1339 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1340 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, config.externalType, 0u, 0u));
1341 const vk::InstanceDriver vki (vkp, *instance);
1342 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1343 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1345 checkSemaphoreSupport(vki, physicalDevice, config.externalType);
1348 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
1349 const vk::DeviceDriver vkd (vki, *device);
1350 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1352 TestLog& log = context.getTestContext().getLog();
1353 const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType));
1355 if (transference == TRANSFERENCE_COPY)
1356 submitDummySignal(vkd, queue, *semaphore);
1358 const NativeHandle fd (getSemaphoreFd(vkd, *device, *semaphore, config.externalType));
1363 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
1365 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
1366 TCU_FAIL("Failed to create socket pair");
1370 const NativeHandle srcSocket (sv[0]);
1371 const NativeHandle dstSocket (sv[1]);
1372 std::string sendData ("deqp");
1376 const int fdRaw (fd.getFd());
1379 char buffer[CMSG_SPACE(sizeof(int))];
1380 iovec iov = { &sendData[0], sendData.length()};
1382 deMemset(&msg, 0, sizeof(msg));
1384 msg.msg_control = buffer;
1385 msg.msg_controllen = sizeof(buffer);
1389 cmsg = CMSG_FIRSTHDR(&msg);
1390 cmsg->cmsg_level = SOL_SOCKET;
1391 cmsg->cmsg_type = SCM_RIGHTS;
1392 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
1394 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
1395 msg.msg_controllen = cmsg->cmsg_len;
1397 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
1399 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
1400 TCU_FAIL("Failed to send fd over socket");
1407 char buffer[CMSG_SPACE(sizeof(int))];
1408 std::string recvData (4, '\0');
1409 iovec iov = { &recvData[0], recvData.length() };
1411 deMemset(&msg, 0, sizeof(msg));
1413 msg.msg_control = buffer;
1414 msg.msg_controllen = sizeof(buffer);
1418 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
1422 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
1423 TCU_FAIL("Failed to recv fd over socket");
1426 else if (bytes != (ssize_t)sendData.length())
1428 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
1432 const vk::VkSemaphoreImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkSemaphoreImportFlagBitsKHR)0u;
1433 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
1435 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
1436 NativeHandle newFd (newFd_);
1438 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
1439 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
1440 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
1441 TCU_CHECK(recvData == sendData);
1442 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
1445 const vk::Unique<vk::VkSemaphore> newSemaphore (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));
1447 if (transference == TRANSFERENCE_COPY)
1448 submitDummyWait(vkd, queue, *newSemaphore);
1449 else if (transference == TRANSFERENCE_REFERENCE)
1451 submitDummySignal(vkd, queue, *newSemaphore);
1452 submitDummyWait(vkd, queue, *newSemaphore);
1455 DE_FATAL("Unknown permanence.");
1457 VK_CHECK(vkd.queueWaitIdle(queue));
1465 return tcu::TestStatus::pass("Pass");
1469 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
1473 tcu::TestStatus testFenceQueries (Context& context, vk::VkExternalFenceHandleTypeFlagBitsKHR externalType)
1475 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1476 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, externalType));
1477 const vk::InstanceDriver vki (vkp, *instance);
1478 const vk::VkPhysicalDevice device (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1480 TestLog& log = context.getTestContext().getLog();
1482 const vk::VkPhysicalDeviceExternalFenceInfoKHR info =
1484 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR,
1488 vk::VkExternalFencePropertiesKHR properties =
1490 vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR,
1497 vki.getPhysicalDeviceExternalFencePropertiesKHR(device, &info, &properties);
1498 log << TestLog::Message << properties << TestLog::EndMessage;
1500 TCU_CHECK(properties.pNext == DE_NULL);
1501 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR);
1503 return tcu::TestStatus::pass("Pass");
1506 struct FenceTestConfig
1508 FenceTestConfig (vk::VkExternalFenceHandleTypeFlagBitsKHR externalType_,
1509 Permanence permanence_)
1510 : externalType (externalType_)
1511 , permanence (permanence_)
1515 vk::VkExternalFenceHandleTypeFlagBitsKHR externalType;
1516 Permanence permanence;
1520 tcu::TestStatus testFenceWin32Create (Context& context,
1521 const FenceTestConfig config)
1523 #if (DE_OS == DE_OS_WIN32)
1524 const Transference transference (getHandelTypeTransferences(config.externalType));
1525 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1526 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1527 const vk::InstanceDriver vki (vkp, *instance);
1528 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1529 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1531 checkFenceSupport(vki, physicalDevice, config.externalType);
1534 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1535 const vk::DeviceDriver vkd (vki, *device);
1536 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1537 const vk::VkExportFenceWin32HandleInfoKHR win32ExportInfo =
1539 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR,
1542 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
1543 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
1546 const vk::VkExportFenceCreateInfoKHR exportCreateInfo=
1548 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR,
1550 (vk::VkExternalFenceHandleTypeFlagsKHR)config.externalType
1552 const vk::VkFenceCreateInfo createInfo =
1554 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1558 const vk::Unique<vk::VkFence> fence (vk::createFence(vkd, *device, &createInfo));
1560 if (transference == TRANSFERENCE_COPY)
1561 submitDummySignal(vkd, queue, *fence);
1563 NativeHandle handleA;
1564 getFenceNative(vkd, *device, *fence, config.externalType, handleA);
1567 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1568 const vk::Unique<vk::VkFence> fenceA (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1570 if (transference == TRANSFERENCE_COPY)
1571 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1572 else if (transference == TRANSFERENCE_REFERENCE)
1574 submitDummySignal(vkd, queue, *fence);
1575 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1578 DE_FATAL("Unknown transference.");
1580 VK_CHECK(vkd.queueWaitIdle(queue));
1583 return tcu::TestStatus::pass("Pass");
1588 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
1592 tcu::TestStatus testFenceImportTwice (Context& context,
1593 const FenceTestConfig config)
1595 const Transference transference (getHandelTypeTransferences(config.externalType));
1596 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1597 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1598 const vk::InstanceDriver vki (vkp, *instance);
1599 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1600 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1602 checkFenceSupport(vki, physicalDevice, config.externalType);
1605 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1606 const vk::DeviceDriver vkd (vki, *device);
1607 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1608 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
1610 if (transference == TRANSFERENCE_COPY)
1611 submitDummySignal(vkd, queue, *fence);
1613 NativeHandle handleA;
1614 getFenceNative(vkd, *device, *fence, config.externalType, handleA);
1617 NativeHandle handleB (handleA);
1618 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1619 const vk::Unique<vk::VkFence> fenceA (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1620 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleB, flags));
1622 if (transference == TRANSFERENCE_COPY)
1623 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1624 else if (transference == TRANSFERENCE_REFERENCE)
1626 submitDummySignal(vkd, queue, *fenceA);
1627 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1630 DE_FATAL("Unknown transference.");
1632 VK_CHECK(vkd.queueWaitIdle(queue));
1635 return tcu::TestStatus::pass("Pass");
1639 tcu::TestStatus testFenceImportReimport (Context& context,
1640 const FenceTestConfig config)
1642 const Transference transference (getHandelTypeTransferences(config.externalType));
1643 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1644 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1645 const vk::InstanceDriver vki (vkp, *instance);
1646 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1647 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1649 checkFenceSupport(vki, physicalDevice, config.externalType);
1652 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1653 const vk::DeviceDriver vkd (vki, *device);
1654 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1656 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1658 if (transference == TRANSFERENCE_COPY)
1659 submitDummySignal(vkd, queue, *fenceA);
1661 NativeHandle handleA;
1662 getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);
1664 NativeHandle handleB (handleA);
1665 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1666 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleA, flags));
1668 importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
1670 if (transference == TRANSFERENCE_COPY)
1671 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1672 else if (transference == TRANSFERENCE_REFERENCE)
1674 submitDummySignal(vkd, queue, *fenceA);
1675 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1678 DE_FATAL("Unknown transference.");
1680 VK_CHECK(vkd.queueWaitIdle(queue));
1682 return tcu::TestStatus::pass("Pass");
1686 tcu::TestStatus testFenceSignalExportImportWait (Context& context,
1687 const FenceTestConfig config)
1689 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1690 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1691 const vk::InstanceDriver vki (vkp, *instance);
1692 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1693 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1695 checkFenceSupport(vki, physicalDevice, config.externalType);
1698 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1699 const vk::DeviceDriver vkd (vki, *device);
1700 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1701 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1703 submitDummySignal(vkd, queue, *fenceA);
1706 NativeHandle handle;
1708 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1711 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1712 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1713 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1715 VK_CHECK(vkd.queueWaitIdle(queue));
1719 return tcu::TestStatus::pass("Pass");
1723 tcu::TestStatus testFenceExportSignalImportWait (Context& context,
1724 const FenceTestConfig config)
1726 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1727 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1728 const vk::InstanceDriver vki (vkp, *instance);
1729 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1730 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1731 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1733 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
1734 checkFenceSupport(vki, physicalDevice, config.externalType);
1737 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1738 const vk::DeviceDriver vkd (vki, *device);
1739 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1741 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1742 NativeHandle handle;
1744 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1746 submitDummySignal(vkd, queue, *fenceA);
1749 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1751 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1752 VK_CHECK(vkd.queueWaitIdle(queue));
1756 return tcu::TestStatus::pass("Pass");
1760 tcu::TestStatus testFenceExportImportSignalWait (Context& context,
1761 const FenceTestConfig config)
1763 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1764 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1765 const vk::InstanceDriver vki (vkp, *instance);
1766 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1767 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1769 DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
1770 checkFenceSupport(vki, physicalDevice, config.externalType);
1773 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1774 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1775 const vk::DeviceDriver vkd (vki, *device);
1776 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1778 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1779 NativeHandle handle;
1781 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1783 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
1785 submitDummySignal(vkd, queue, *fenceA);
1786 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1788 VK_CHECK(vkd.queueWaitIdle(queue));
1790 return tcu::TestStatus::pass("Pass");
1794 tcu::TestStatus testFenceSignalImport (Context& context,
1795 const FenceTestConfig config)
1797 const Transference transference (getHandelTypeTransferences(config.externalType));
1798 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1799 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1800 const vk::InstanceDriver vki (vkp, *instance);
1801 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1802 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1804 checkFenceSupport(vki, physicalDevice, config.externalType);
1807 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1808 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1809 const vk::DeviceDriver vkd (vki, *device);
1810 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1812 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1813 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1814 NativeHandle handle;
1816 submitDummySignal(vkd, queue, *fenceB);
1817 VK_CHECK(vkd.queueWaitIdle(queue));
1819 if (transference == TRANSFERENCE_COPY)
1820 submitDummySignal(vkd, queue, *fenceA);
1822 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1824 importFence(vkd, *device, *fenceB, config.externalType, handle, flags);
1826 if (transference == TRANSFERENCE_COPY)
1827 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1828 else if (transference == TRANSFERENCE_REFERENCE)
1830 submitDummySignal(vkd, queue, *fenceA);
1831 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1834 DE_FATAL("Unknown transference.");
1836 VK_CHECK(vkd.queueWaitIdle(queue));
1838 return tcu::TestStatus::pass("Pass");
1842 tcu::TestStatus testFenceReset (Context& context,
1843 const FenceTestConfig config)
1845 const Transference transference (getHandelTypeTransferences(config.externalType));
1846 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1847 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1848 const vk::InstanceDriver vki (vkp, *instance);
1849 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1850 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1852 checkFenceSupport(vki, physicalDevice, config.externalType);
1855 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1856 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1857 const vk::DeviceDriver vkd (vki, *device);
1858 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1860 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1861 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1862 const vk::Unique<vk::VkFence> fenceC (createFence(vkd, *device));
1863 NativeHandle handle;
1865 submitDummySignal(vkd, queue, *fenceB);
1866 VK_CHECK(vkd.queueWaitIdle(queue));
1868 submitDummySignal(vkd, queue, *fenceA);
1870 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1872 NativeHandle handleB (handle);
1873 importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
1875 importFence(vkd, *device, *fenceC, config.externalType, handle, flags);
1877 VK_CHECK(vkd.queueWaitIdle(queue));
1878 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
1880 if (config.permanence == PERMANENCE_TEMPORARY || transference == TRANSFERENCE_COPY)
1882 // vkResetFences() should restore fenceBs prior payload and reset that no affecting fenceCs payload
1883 // or fenceB should be separate copy of the payload and not affect fenceC
1884 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
1886 // vkResetFences() should have restored fenceBs prior state and should be now reset
1887 // or fenceB should have it's separate payload
1888 submitDummySignal(vkd, queue, *fenceB);
1889 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1891 else if (config.permanence == PERMANENCE_PERMANENT)
1893 DE_ASSERT(transference == TRANSFERENCE_REFERENCE);
1895 // Reset fences should have reset all of the fences
1896 submitDummySignal(vkd, queue, *fenceC);
1898 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
1899 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1900 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
1903 DE_FATAL("Unknown permanence");
1905 VK_CHECK(vkd.queueWaitIdle(queue));
1907 return tcu::TestStatus::pass("Pass");
1911 tcu::TestStatus testFenceSignalWaitImport (Context& context,
1912 const FenceTestConfig config)
1914 const Transference transference (getHandelTypeTransferences(config.externalType));
1915 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1916 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1917 const vk::InstanceDriver vki (vkp, *instance);
1918 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1919 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1921 checkFenceSupport(vki, physicalDevice, config.externalType);
1924 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
1925 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1926 const vk::DeviceDriver vkd (vki, *device);
1927 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1929 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
1930 const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device));
1931 NativeHandle handle;
1933 if (transference == TRANSFERENCE_COPY)
1934 submitDummySignal(vkd, queue, *fenceA);
1936 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
1938 submitDummySignal(vkd, queue, *fenceB);
1939 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1941 VK_CHECK(vkd.queueWaitIdle(queue));
1943 importFence(vkd, *device, *fenceB, config.externalType, handle, flags);
1945 if (transference == TRANSFERENCE_COPY)
1946 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1947 else if (transference == TRANSFERENCE_REFERENCE)
1949 submitDummySignal(vkd, queue, *fenceA);
1950 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
1953 DE_FATAL("Unknown transference.");
1955 VK_CHECK(vkd.queueWaitIdle(queue));
1957 return tcu::TestStatus::pass("Pass");
1961 tcu::TestStatus testFenceMultipleExports (Context& context,
1962 const FenceTestConfig config)
1964 const size_t exportCount = 4 * 1024;
1965 const Transference transference (getHandelTypeTransferences(config.externalType));
1966 const vk::PlatformInterface& vkp (context.getPlatformInterface());
1967 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
1968 const vk::InstanceDriver vki (vkp, *instance);
1969 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
1970 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
1972 checkFenceSupport(vki, physicalDevice, config.externalType);
1975 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
1976 const vk::DeviceDriver vkd (vki, *device);
1977 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
1978 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
1980 for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
1982 NativeHandle handle;
1984 if (transference == TRANSFERENCE_COPY)
1985 submitDummySignal(vkd, queue, *fence);
1987 getFenceNative(vkd, *device, *fence, config.externalType, handle);
1990 submitDummySignal(vkd, queue, *fence);
1991 VK_CHECK(vkd.waitForFences(*device, 1u, &*fence, VK_TRUE, ~0ull));
1993 VK_CHECK(vkd.queueWaitIdle(queue));
1996 return tcu::TestStatus::pass("Pass");
1999 tcu::TestStatus testFenceMultipleImports (Context& context,
2000 const FenceTestConfig config)
2002 const size_t importCount = 4 * 1024;
2003 const Transference transference (getHandelTypeTransferences(config.externalType));
2004 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2005 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2006 const vk::InstanceDriver vki (vkp, *instance);
2007 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2008 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2010 checkFenceSupport(vki, physicalDevice, config.externalType);
2013 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2014 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2015 const vk::DeviceDriver vkd (vki, *device);
2016 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2017 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2018 NativeHandle handleA;
2020 if (transference == TRANSFERENCE_COPY)
2021 submitDummySignal(vkd, queue, *fenceA);
2023 getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);
2025 for (size_t importNdx = 0; importNdx < importCount; importNdx++)
2027 NativeHandle handleB (handleA);
2028 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handleB, flags));
2031 if (transference == TRANSFERENCE_COPY)
2033 importFence(vkd, *device, *fenceA, config.externalType, handleA, flags);
2034 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2036 else if (transference == TRANSFERENCE_REFERENCE)
2038 submitDummySignal(vkd, queue, *fenceA);
2039 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2042 DE_FATAL("Unknown transference.");
2044 VK_CHECK(vkd.queueWaitIdle(queue));
2047 return tcu::TestStatus::pass("Pass");
2050 tcu::TestStatus testFenceTransference (Context& context,
2051 const FenceTestConfig config)
2053 const Transference transference (getHandelTypeTransferences(config.externalType));
2054 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2055 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2056 const vk::InstanceDriver vki (vkp, *instance);
2057 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2058 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2060 checkFenceSupport(vki, physicalDevice, config.externalType);
2063 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2064 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2065 const vk::DeviceDriver vkd (vki, *device);
2066 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2068 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2069 NativeHandle handle;
2071 submitDummySignal(vkd, queue, *fenceA);
2073 getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
2076 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags));
2078 if (config.permanence == PERMANENCE_PERMANENT)
2080 if (transference == TRANSFERENCE_COPY)
2082 submitDummySignal(vkd, queue, *fenceA);
2083 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2084 VK_CHECK(vkd.queueWaitIdle(queue));
2086 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2087 submitDummySignal(vkd, queue, *fenceB);
2089 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2090 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2091 VK_CHECK(vkd.queueWaitIdle(queue));
2093 else if (transference== TRANSFERENCE_REFERENCE)
2095 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2096 VK_CHECK(vkd.queueWaitIdle(queue));
2098 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2099 submitDummySignal(vkd, queue, *fenceA);
2100 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2102 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
2103 submitDummySignal(vkd, queue, *fenceB);
2104 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2105 VK_CHECK(vkd.queueWaitIdle(queue));
2108 DE_FATAL("Unknown transference.");
2110 else if (config.permanence == PERMANENCE_TEMPORARY)
2112 if (transference == TRANSFERENCE_COPY)
2114 submitDummySignal(vkd, queue, *fenceA);
2115 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2116 VK_CHECK(vkd.queueWaitIdle(queue));
2118 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2119 submitDummySignal(vkd, queue, *fenceB);
2121 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2122 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2123 VK_CHECK(vkd.queueWaitIdle(queue));
2125 else if (transference == TRANSFERENCE_REFERENCE)
2127 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2128 VK_CHECK(vkd.queueWaitIdle(queue));
2130 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
2131 VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
2132 submitDummySignal(vkd, queue, *fenceA);
2133 submitDummySignal(vkd, queue, *fenceB);
2135 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2136 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
2137 VK_CHECK(vkd.queueWaitIdle(queue));
2140 DE_FATAL("Unknown transference.");
2143 DE_FATAL("Unknown permanence.");
2146 return tcu::TestStatus::pass("Pass");
2150 tcu::TestStatus testFenceFdDup (Context& context,
2151 const FenceTestConfig config)
2153 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2154 const Transference transference (getHandelTypeTransferences(config.externalType));
2155 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2156 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2157 const vk::InstanceDriver vki (vkp, *instance);
2158 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2159 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2161 checkFenceSupport(vki, physicalDevice, config.externalType);
2164 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2165 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2166 const vk::DeviceDriver vkd (vki, *device);
2167 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2169 TestLog& log = context.getTestContext().getLog();
2170 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2172 if (transference == TRANSFERENCE_COPY)
2173 submitDummySignal(vkd, queue, *fenceA);
2176 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2177 NativeHandle newFd (dup(fd.getFd()));
2179 if (newFd.getFd() < 0)
2180 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2182 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for fences fd");
2185 const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, newFd, flags));
2187 if (transference == TRANSFERENCE_COPY)
2188 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2189 else if (transference == TRANSFERENCE_REFERENCE)
2191 submitDummySignal(vkd, queue, *fenceA);
2192 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
2195 DE_FATAL("Unknown permanence.");
2199 VK_CHECK(vkd.queueWaitIdle(queue));
2201 return tcu::TestStatus::pass("Pass");
2206 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2210 tcu::TestStatus testFenceFdDup2 (Context& context,
2211 const FenceTestConfig config)
2213 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2214 const Transference transference (getHandelTypeTransferences(config.externalType));
2215 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2216 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2217 const vk::InstanceDriver vki (vkp, *instance);
2218 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2219 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2221 checkFenceSupport(vki, physicalDevice, config.externalType);
2224 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2225 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2226 const vk::DeviceDriver vkd (vki, *device);
2227 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2229 TestLog& log = context.getTestContext().getLog();
2230 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2231 const vk::Unique<vk::VkFence> fenceB (createExportableFence(vkd, *device, config.externalType));
2233 if (transference == TRANSFERENCE_COPY)
2235 submitDummySignal(vkd, queue, *fenceA);
2236 submitDummySignal(vkd, queue, *fenceB);
2240 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2241 NativeHandle secondFd (getFenceFd(vkd, *device, *fenceB, config.externalType));
2242 int newFd (dup2(fd.getFd(), secondFd.getFd()));
2245 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2247 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");
2250 const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));
2252 if (transference == TRANSFERENCE_COPY)
2253 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2254 else if (transference == TRANSFERENCE_REFERENCE)
2256 submitDummySignal(vkd, queue, *fenceA);
2257 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2260 DE_FATAL("Unknown permanence.");
2264 VK_CHECK(vkd.queueWaitIdle(queue));
2266 return tcu::TestStatus::pass("Pass");
2271 TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
2275 tcu::TestStatus testFenceFdDup3 (Context& context,
2276 const FenceTestConfig config)
2278 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
2279 const Transference transference (getHandelTypeTransferences(config.externalType));
2280 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2281 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2282 const vk::InstanceDriver vki (vkp, *instance);
2283 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2284 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2286 checkFenceSupport(vki, physicalDevice, config.externalType);
2289 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2290 const vk::DeviceDriver vkd (vki, *device);
2291 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2293 TestLog& log = context.getTestContext().getLog();
2294 const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType));
2295 const vk::Unique<vk::VkFence> fenceB (createExportableFence(vkd, *device, config.externalType));
2297 if (transference == TRANSFERENCE_COPY)
2299 submitDummySignal(vkd, queue, *fenceA);
2300 submitDummySignal(vkd, queue, *fenceB);
2304 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2305 const NativeHandle fd (getFenceFd(vkd, *device, *fenceA, config.externalType));
2306 NativeHandle secondFd (getFenceFd(vkd, *device, *fenceB, config.externalType));
2307 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
2310 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2312 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");
2315 const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));
2317 if (transference == TRANSFERENCE_COPY)
2318 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2319 else if (transference == TRANSFERENCE_REFERENCE)
2321 submitDummySignal(vkd, queue, *fenceA);
2322 VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
2325 DE_FATAL("Unknown permanence.");
2329 VK_CHECK(vkd.queueWaitIdle(queue));
2331 return tcu::TestStatus::pass("Pass");
2336 TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
2340 tcu::TestStatus testFenceFdSendOverSocket (Context& context,
2341 const FenceTestConfig config)
2343 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2344 const Transference transference (getHandelTypeTransferences(config.externalType));
2345 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2346 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, 0u, config.externalType));
2347 const vk::InstanceDriver vki (vkp, *instance);
2348 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2349 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2351 checkFenceSupport(vki, physicalDevice, config.externalType);
2354 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
2355 const vk::DeviceDriver vkd (vki, *device);
2356 const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex));
2358 TestLog& log = context.getTestContext().getLog();
2359 const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType));
2361 if (transference == TRANSFERENCE_COPY)
2362 submitDummySignal(vkd, queue, *fence);
2364 const NativeHandle fd (getFenceFd(vkd, *device, *fence, config.externalType));
2369 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
2371 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
2372 TCU_FAIL("Failed to create socket pair");
2376 const NativeHandle srcSocket (sv[0]);
2377 const NativeHandle dstSocket (sv[1]);
2378 std::string sendData ("deqp");
2382 const int fdRaw (fd.getFd());
2385 char buffer[CMSG_SPACE(sizeof(int))];
2386 iovec iov = { &sendData[0], sendData.length()};
2388 deMemset(&msg, 0, sizeof(msg));
2390 msg.msg_control = buffer;
2391 msg.msg_controllen = sizeof(buffer);
2395 cmsg = CMSG_FIRSTHDR(&msg);
2396 cmsg->cmsg_level = SOL_SOCKET;
2397 cmsg->cmsg_type = SCM_RIGHTS;
2398 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
2400 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
2401 msg.msg_controllen = cmsg->cmsg_len;
2403 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
2405 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
2406 TCU_FAIL("Failed to send fd over socket");
2413 char buffer[CMSG_SPACE(sizeof(int))];
2414 std::string recvData (4, '\0');
2415 iovec iov = { &recvData[0], recvData.length() };
2417 deMemset(&msg, 0, sizeof(msg));
2419 msg.msg_control = buffer;
2420 msg.msg_controllen = sizeof(buffer);
2424 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
2428 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
2429 TCU_FAIL("Failed to recv fd over socket");
2432 else if (bytes != (ssize_t)sendData.length())
2434 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
2438 const vk::VkFenceImportFlagsKHR flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT_KHR : (vk::VkFenceImportFlagBitsKHR)0u;
2439 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
2441 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
2442 NativeHandle newFd (newFd_);
2444 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
2445 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
2446 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
2447 TCU_CHECK(recvData == sendData);
2448 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
2451 const vk::Unique<vk::VkFence> newFence (createAndImportFence(vkd, *device, config.externalType, newFd, flags));
2453 if (transference == TRANSFERENCE_COPY)
2454 VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
2455 else if (transference == TRANSFERENCE_REFERENCE)
2457 submitDummySignal(vkd, queue, *newFence);
2458 VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
2461 DE_FATAL("Unknown permanence.");
2463 VK_CHECK(vkd.queueWaitIdle(queue));
2471 return tcu::TestStatus::pass("Pass");
2475 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
2479 tcu::TestStatus testBufferQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType)
2481 const vk::VkBufferCreateFlags createFlags[] =
2484 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
2485 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
2486 vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
2488 const vk::VkBufferUsageFlags usageFlags[] =
2490 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
2491 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2492 vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
2493 vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
2494 vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
2495 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
2496 vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
2497 vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
2498 vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
2500 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2501 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, externalType, 0u));
2502 const vk::InstanceDriver vki (vkp, *instance);
2503 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2504 const vk::VkPhysicalDeviceFeatures deviceFeatures (vk::getPhysicalDeviceFeatures(vki, physicalDevice));
2505 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2507 // VkDevice is only created if physical device claims to support any of these types.
2508 vk::Move<vk::VkDevice> device;
2509 de::MovePtr<vk::DeviceDriver> vkd;
2510 bool deviceHasDedicated = false;
2512 TestLog& log = context.getTestContext().getLog();
2514 for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
2515 for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
2517 const vk::VkBufferViewCreateFlags createFlag = createFlags[createFlagNdx];
2518 const vk::VkBufferUsageFlags usageFlag = usageFlags[usageFlagNdx];
2519 const vk::VkPhysicalDeviceExternalBufferInfoKHR info =
2521 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR,
2527 vk::VkExternalBufferPropertiesKHR properties =
2529 vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR,
2534 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != 0) &&
2535 (deviceFeatures.sparseBinding == VK_FALSE))
2538 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) != 0) &&
2539 (deviceFeatures.sparseResidencyAliased == VK_FALSE))
2542 if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
2543 (deviceFeatures.sparseResidencyBuffer == VK_FALSE))
2546 vki.getPhysicalDeviceExternalBufferPropertiesKHR(physicalDevice, &info, &properties);
2548 log << TestLog::Message << properties << TestLog::EndMessage;
2550 TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR);
2551 TCU_CHECK(properties.pNext == DE_NULL);
2552 // \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?
2554 if ((properties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) != 0)
2556 const bool requiresDedicated = (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0;
2558 if (!device || (requiresDedicated && !deviceHasDedicated))
2560 // \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
2563 device = createDevice(vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
2564 vkd = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vki, *device));
2565 deviceHasDedicated = requiresDedicated;
2567 catch (const tcu::NotSupportedError& e)
2570 TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
2575 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) != 0)
2577 DE_ASSERT(!!device);
2580 if (deviceHasDedicated)
2582 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(*vkd, *device, queueFamilyIndex, externalType, 1024u, createFlag, usageFlag));
2583 const vk::VkMemoryDedicatedRequirementsKHR reqs (getMemoryDedicatedRequirements(*vkd, *device, *buffer));
2584 const bool propertiesRequiresDedicated = (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0;
2585 const bool objectRequiresDedicated = (reqs.requiresDedicatedAllocation != VK_FALSE);
2587 if (propertiesRequiresDedicated != objectRequiresDedicated)
2588 TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
2592 // We can't query whether dedicated memory is required or not on per-object basis.
2593 // This check should be redundant as the code above tries to create device with
2594 // VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
2595 // is required. However, checking again doesn't hurt.
2596 TCU_CHECK((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) == 0);
2601 return tcu::TestStatus::pass("Pass");
2604 struct MemoryTestConfig
2606 MemoryTestConfig (vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType_,
2609 : externalType (externalType_)
2610 , hostVisible (hostVisible_)
2611 , dedicated (dedicated_)
2615 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType;
2620 #if (DE_OS == DE_OS_WIN32)
2621 deUint32 chooseMemoryType (deUint32 bits)
2624 TCU_THROW(NotSupportedError, "No compatible memory type found");
2626 return deCtz32(bits);
2630 tcu::TestStatus testMemoryWin32Create (Context& context, MemoryTestConfig config)
2632 #if (DE_OS == DE_OS_WIN32)
2633 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2634 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2635 const vk::InstanceDriver vki (vkp, *instance);
2636 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2637 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2638 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2639 const vk::DeviceDriver vkd (vki, *device);
2640 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2641 const deUint32 seed = 1261033864u;
2642 const vk::VkDeviceSize bufferSize = 1024;
2643 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2645 const vk::VkPhysicalDeviceMemoryProperties memoryProps = vk::getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2646 const deUint32 compatibleMemTypes = vk::getCompatibleMemoryTypes(memoryProps, config.hostVisible ? vk::MemoryRequirement::HostVisible : vk::MemoryRequirement::Any);
2648 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2650 // \note Buffer is only allocated to get memory requirements
2651 deUint32 exportedMemoryTypeIndex = ~0U;
2652 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2653 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2654 const vk::VkExportMemoryWin32HandleInfoKHR win32Info =
2656 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
2659 (vk::pt::Win32SecurityAttributesPtr)DE_NULL,
2660 DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
2663 const vk::VkExportMemoryAllocateInfoKHR exportInfo =
2665 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
2667 (vk::VkExternalMemoryHandleTypeFlagsKHR)config.externalType
2670 exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits & compatibleMemTypes);
2671 const vk::VkMemoryAllocateInfo info =
2673 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2676 exportedMemoryTypeIndex
2678 const vk::Unique<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, *device, &info));
2679 NativeHandle handleA;
2681 if (config.hostVisible)
2682 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2684 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2687 const vk::Unique<vk::VkDeviceMemory> memoryA (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleA));
2689 if (config.hostVisible)
2691 const std::vector<deUint8> testDataA (genTestData(seed ^ 124798807u, (size_t)bufferSize));
2692 const std::vector<deUint8> testDataB (genTestData(seed ^ 970834278u, (size_t)bufferSize));
2694 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
2695 checkHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2697 writeHostMemory(vkd, *device, *memoryA, testDataA.size(), &testDataA[0]);
2698 writeHostMemory(vkd, *device, *memory, testDataA.size(), &testDataB[0]);
2700 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
2701 checkHostMemory(vkd, *device, *memory, testData.size(), &testDataB[0]);
2705 return tcu::TestStatus::pass("Pass");
2709 TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
2713 tcu::TestStatus testMemoryImportTwice (Context& context, MemoryTestConfig config)
2715 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2716 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2717 const vk::InstanceDriver vki (vkp, *instance);
2718 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2719 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2720 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2721 const vk::DeviceDriver vkd (vki, *device);
2722 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2723 const deUint32 seed = 1261033864u;
2724 const vk::VkDeviceSize bufferSize = 1024;
2725 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2727 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2729 deUint32 exportedMemoryTypeIndex = ~0U;
2730 // \note Buffer is only allocated to get memory requirements
2731 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2732 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2733 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2734 NativeHandle handleA;
2736 if (config.hostVisible)
2737 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2739 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2742 NativeHandle handleB (handleA);
2743 const vk::Unique<vk::VkDeviceMemory> memoryA (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleA));
2744 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleB));
2746 if (config.hostVisible)
2748 const std::vector<deUint8> testDataA (genTestData(seed ^ 124798807u, (size_t)bufferSize));
2749 const std::vector<deUint8> testDataB (genTestData(seed ^ 970834278u, (size_t)bufferSize));
2751 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
2752 checkHostMemory(vkd, *device, *memoryB, testData.size(), &testData[0]);
2754 writeHostMemory(vkd, *device, *memoryA, testData.size(), &testDataA[0]);
2755 writeHostMemory(vkd, *device, *memoryB, testData.size(), &testDataB[0]);
2757 checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
2758 checkHostMemory(vkd, *device, *memory, testData.size(), &testDataB[0]);
2762 return tcu::TestStatus::pass("Pass");
2765 tcu::TestStatus testMemoryMultimpleImports (Context& context, MemoryTestConfig config)
2767 const size_t count = 4 * 1024;
2768 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2769 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2770 const vk::InstanceDriver vki (vkp, *instance);
2771 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2772 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2773 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2774 const vk::DeviceDriver vkd (vki, *device);
2775 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2776 const vk::VkDeviceSize bufferSize = 1024;
2778 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2780 deUint32 exportedMemoryTypeIndex = ~0U;
2781 // \note Buffer is only allocated to get memory requirements
2782 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2783 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2784 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2785 NativeHandle handleA;
2787 getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
2789 for (size_t ndx = 0; ndx < count; ndx++)
2791 NativeHandle handleB (handleA);
2792 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleB));
2795 return tcu::TestStatus::pass("Pass");
2798 tcu::TestStatus testMemoryMultimpleExports (Context& context, MemoryTestConfig config)
2800 const size_t count = 4 * 1024;
2801 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2802 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2803 const vk::InstanceDriver vki (vkp, *instance);
2804 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2805 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2806 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2807 const vk::DeviceDriver vkd (vki, *device);
2808 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2809 const vk::VkDeviceSize bufferSize = 1024;
2811 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2813 deUint32 exportedMemoryTypeIndex = ~0U;
2814 // \note Buffer is only allocated to get memory requirements
2815 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2816 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2817 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2819 for (size_t ndx = 0; ndx < count; ndx++)
2821 NativeHandle handle;
2822 getMemoryNative(vkd, *device, *memory, config.externalType, handle);
2825 return tcu::TestStatus::pass("Pass");
2828 tcu::TestStatus testMemoryFdDup (Context& context, MemoryTestConfig config)
2830 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2831 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2832 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2833 const vk::InstanceDriver vki (vkp, *instance);
2834 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2835 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2838 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2839 const vk::DeviceDriver vkd (vki, *device);
2841 TestLog& log = context.getTestContext().getLog();
2842 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2843 const vk::VkDeviceSize bufferSize = 1024;
2844 const deUint32 seed = 851493858u;
2845 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2847 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2849 deUint32 exportedMemoryTypeIndex = ~0U;
2850 // \note Buffer is only allocated to get memory requirements
2851 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2852 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2853 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2855 if (config.hostVisible)
2856 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2858 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
2859 NativeHandle newFd (dup(fd.getFd()));
2861 if (newFd.getFd() < 0)
2862 log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2864 TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for memorys fd");
2867 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, newFd));
2869 if (config.hostVisible)
2871 const std::vector<deUint8> testDataA (genTestData(seed ^ 672929437u, (size_t)bufferSize));
2873 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
2875 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
2876 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
2880 return tcu::TestStatus::pass("Pass");
2885 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2889 tcu::TestStatus testMemoryFdDup2 (Context& context, MemoryTestConfig config)
2891 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
2892 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2893 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2894 const vk::InstanceDriver vki (vkp, *instance);
2895 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2896 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2899 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2900 const vk::DeviceDriver vkd (vki, *device);
2902 TestLog& log = context.getTestContext().getLog();
2903 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2904 const vk::VkDeviceSize bufferSize = 1024;
2905 const deUint32 seed = 224466865u;
2906 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2908 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2910 deUint32 exportedMemoryTypeIndex = ~0U;
2911 // \note Buffer is only allocated to get memory requirements
2912 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2913 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2914 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2916 if (config.hostVisible)
2917 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2919 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
2920 NativeHandle secondFd (getMemoryFd(vkd, *device, *memory, config.externalType));
2921 const int newFd (dup2(fd.getFd(), secondFd.getFd()));
2924 log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2926 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for memorys fd");
2929 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, secondFd));
2931 if (config.hostVisible)
2933 const std::vector<deUint8> testDataA (genTestData(seed ^ 99012346u, (size_t)bufferSize));
2935 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
2937 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
2938 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
2942 return tcu::TestStatus::pass("Pass");
2947 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
2951 tcu::TestStatus testMemoryFdDup3 (Context& context, MemoryTestConfig config)
2953 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
2954 const vk::PlatformInterface& vkp (context.getPlatformInterface());
2955 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
2956 const vk::InstanceDriver vki (vkp, *instance);
2957 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
2958 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
2961 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
2962 const vk::DeviceDriver vkd (vki, *device);
2964 TestLog& log = context.getTestContext().getLog();
2965 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2966 const vk::VkDeviceSize bufferSize = 1024;
2967 const deUint32 seed = 2554088961u;
2968 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
2970 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
2972 deUint32 exportedMemoryTypeIndex = ~0U;
2973 // \note Buffer is only allocated to get memory requirements
2974 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
2975 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
2976 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
2978 if (config.hostVisible)
2979 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
2981 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
2982 NativeHandle secondFd (getMemoryFd(vkd, *device, *memory, config.externalType));
2983 const int newFd (dup3(fd.getFd(), secondFd.getFd(), 0));
2986 log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
2988 TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for memorys fd");
2991 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, secondFd));
2993 if (config.hostVisible)
2995 const std::vector<deUint8> testDataA (genTestData(seed ^ 4210342378u, (size_t)bufferSize));
2997 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
2999 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
3000 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
3004 return tcu::TestStatus::pass("Pass");
3009 TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
3013 tcu::TestStatus testMemoryFdSendOverSocket (Context& context, MemoryTestConfig config)
3015 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
3016 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3017 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3018 const vk::InstanceDriver vki (vkp, *instance);
3019 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3020 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3023 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
3024 const vk::DeviceDriver vkd (vki, *device);
3026 TestLog& log = context.getTestContext().getLog();
3027 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3028 const vk::VkDeviceSize bufferSize = 1024;
3029 const deUint32 seed = 3403586456u;
3030 const std::vector<deUint8> testData (genTestData(seed, (size_t)bufferSize));
3032 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3034 deUint32 exportedMemoryTypeIndex = ~0U;
3035 // \note Buffer is only allocated to get memory requirements
3036 const vk::Unique<vk::VkBuffer> buffer (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3037 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *buffer));
3038 const vk::Unique<vk::VkDeviceMemory> memory (allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
3040 if (config.hostVisible)
3041 writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
3043 const NativeHandle fd (getMemoryFd(vkd, *device, *memory, config.externalType));
3048 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
3050 log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
3051 TCU_FAIL("Failed to create socket pair");
3055 const NativeHandle srcSocket (sv[0]);
3056 const NativeHandle dstSocket (sv[1]);
3057 std::string sendData ("deqp");
3061 const int fdRaw (fd.getFd());
3064 char tmpBuffer[CMSG_SPACE(sizeof(int))];
3065 iovec iov = { &sendData[0], sendData.length()};
3067 deMemset(&msg, 0, sizeof(msg));
3069 msg.msg_control = tmpBuffer;
3070 msg.msg_controllen = sizeof(tmpBuffer);
3074 cmsg = CMSG_FIRSTHDR(&msg);
3075 cmsg->cmsg_level = SOL_SOCKET;
3076 cmsg->cmsg_type = SCM_RIGHTS;
3077 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
3079 deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
3080 msg.msg_controllen = cmsg->cmsg_len;
3082 if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
3084 log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
3085 TCU_FAIL("Failed to send fd over socket");
3092 char tmpBuffer[CMSG_SPACE(sizeof(int))];
3093 std::string recvData (4, '\0');
3094 iovec iov = { &recvData[0], recvData.length() };
3096 deMemset(&msg, 0, sizeof(msg));
3098 msg.msg_control = tmpBuffer;
3099 msg.msg_controllen = sizeof(tmpBuffer);
3103 const ssize_t bytes = recvmsg(dstSocket.getFd(), &msg, 0);
3107 log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
3108 TCU_FAIL("Failed to recv fd over socket");
3111 else if (bytes != (ssize_t)sendData.length())
3113 TCU_FAIL("recvmsg() returned unpexpected number of bytes");
3117 const cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
3119 deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
3120 NativeHandle newFd (newFd_);
3122 TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
3123 TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
3124 TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
3125 TCU_CHECK(recvData == sendData);
3126 TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
3129 const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, newFd));
3131 if (config.hostVisible)
3133 const std::vector<deUint8> testDataA (genTestData(seed ^ 23478978u, (size_t)bufferSize));
3135 checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
3137 writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
3138 checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
3147 return tcu::TestStatus::pass("Pass");
3151 TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
3155 struct BufferTestConfig
3157 BufferTestConfig (vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType_,
3159 : externalType (externalType_)
3160 , dedicated (dedicated_)
3164 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType;
3168 tcu::TestStatus testBufferBindExportImportBind (Context& context,
3169 const BufferTestConfig config)
3171 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3172 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3173 const vk::InstanceDriver vki (vkp, *instance);
3174 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3175 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3176 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3177 const vk::DeviceDriver vkd (vki, *device);
3178 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3179 const vk::VkDeviceSize bufferSize = 1024;
3181 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3183 deUint32 exportedMemoryTypeIndex = ~0U;
3184 // \note Buffer is only allocated to get memory requirements
3185 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3186 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3187 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
3188 NativeHandle handle;
3190 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3192 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3195 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3196 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3198 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3201 return tcu::TestStatus::pass("Pass");
3204 tcu::TestStatus testBufferExportBindImportBind (Context& context,
3205 const BufferTestConfig config)
3207 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3208 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3209 const vk::InstanceDriver vki (vkp, *instance);
3210 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3211 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3212 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3213 const vk::DeviceDriver vkd (vki, *device);
3214 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3215 const vk::VkDeviceSize bufferSize = 1024;
3217 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3219 deUint32 exportedMemoryTypeIndex = ~0U;
3220 // \note Buffer is only allocated to get memory requirements
3221 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3222 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3223 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
3224 NativeHandle handle;
3226 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3227 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3230 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3231 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3233 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3236 return tcu::TestStatus::pass("Pass");
3239 tcu::TestStatus testBufferExportImportBindBind (Context& context,
3240 const BufferTestConfig config)
3242 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3243 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3244 const vk::InstanceDriver vki (vkp, *instance);
3245 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3246 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3247 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3248 const vk::DeviceDriver vkd (vki, *device);
3249 const vk::VkBufferUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3250 const vk::VkDeviceSize bufferSize = 1024;
3252 checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
3254 deUint32 exportedMemoryTypeIndex = ~0U;
3255 // \note Buffer is only allocated to get memory requirements
3256 const vk::Unique<vk::VkBuffer> bufferA (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3257 const vk::VkMemoryRequirements requirements (getBufferMemoryRequirements(vkd, *device, *bufferA));
3258 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
3259 NativeHandle handle;
3261 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3264 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3265 const vk::Unique<vk::VkBuffer> bufferB (createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
3267 VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
3268 VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
3271 return tcu::TestStatus::pass("Pass");
3274 tcu::TestStatus testImageQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType)
3276 const vk::VkImageCreateFlags createFlags[] =
3279 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
3280 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
3281 vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
3282 vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
3283 vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
3284 vk::VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR
3286 const vk::VkImageUsageFlags usageFlags[] =
3288 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
3289 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3290 vk::VK_IMAGE_USAGE_SAMPLED_BIT,
3291 vk::VK_IMAGE_USAGE_STORAGE_BIT,
3292 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
3293 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
3294 vk::VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
3295 vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
3297 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3298 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, externalType, 0u));
3299 const vk::InstanceDriver vki (vkp, *instance);
3300 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3301 const vk::VkPhysicalDeviceFeatures deviceFeatures (vk::getPhysicalDeviceFeatures(vki, physicalDevice));
3302 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3304 // VkDevice is only created if physical device claims to support any of these types.
3305 vk::Move<vk::VkDevice> device;
3306 de::MovePtr<vk::DeviceDriver> vkd;
3307 bool deviceHasDedicated = false;
3309 TestLog& log = context.getTestContext().getLog();
3311 for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
3312 for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
3314 const vk::VkImageViewCreateFlags createFlag = createFlags[createFlagNdx];
3315 const vk::VkImageUsageFlags usageFlag = usageFlags[usageFlagNdx];
3316 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3317 const vk::VkImageType type = vk::VK_IMAGE_TYPE_2D;
3318 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3319 const vk::VkPhysicalDeviceExternalImageFormatInfoKHR externalInfo =
3321 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR,
3325 const vk::VkPhysicalDeviceImageFormatInfo2KHR info =
3327 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
3336 vk::VkExternalImageFormatPropertiesKHR externalProperties =
3338 vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
3342 vk::VkImageFormatProperties2KHR properties =
3344 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR,
3345 &externalProperties,
3355 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0) &&
3356 (deviceFeatures.sparseBinding == VK_FALSE))
3359 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
3360 (deviceFeatures.sparseResidencyImage2D == VK_FALSE))
3363 if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) != 0) &&
3364 (deviceFeatures.sparseResidencyAliased == VK_FALSE))
3367 vki.getPhysicalDeviceImageFormatProperties2KHR(physicalDevice, &info, &properties);
3369 log << TestLog::Message << externalProperties << TestLog::EndMessage;
3370 TCU_CHECK(externalProperties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR);
3371 TCU_CHECK(externalProperties.pNext == DE_NULL);
3372 // \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?
3374 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) != 0)
3376 const bool requiresDedicated = (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0;
3378 if (!device || (requiresDedicated && !deviceHasDedicated))
3380 // \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
3383 device = createDevice(vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
3384 vkd = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vki, *device));
3385 deviceHasDedicated = requiresDedicated;
3387 catch (const tcu::NotSupportedError& e)
3390 TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
3395 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) != 0)
3397 DE_ASSERT(!!device);
3400 if (deviceHasDedicated)
3402 const vk::Unique<vk::VkImage> image (createExternalImage(*vkd, *device, queueFamilyIndex, externalType, format, 16u, 16u, tiling, createFlag, usageFlag));
3403 const vk::VkMemoryDedicatedRequirementsKHR reqs (getMemoryDedicatedRequirements(*vkd, *device, *image));
3404 const bool propertiesRequiresDedicated = (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0;
3405 const bool objectRequiresDedicated = (reqs.requiresDedicatedAllocation != VK_FALSE);
3407 if (propertiesRequiresDedicated != objectRequiresDedicated)
3408 TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
3412 // We can't query whether dedicated memory is required or not on per-object basis.
3413 // This check should be redundant as the code above tries to create device with
3414 // VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
3415 // is required. However, checking again doesn't hurt.
3416 TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) == 0);
3421 return tcu::TestStatus::pass("Pass");
3424 struct ImageTestConfig
3426 ImageTestConfig (vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType_,
3428 : externalType (externalType_)
3429 , dedicated (dedicated_)
3433 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType;
3437 tcu::TestStatus testImageBindExportImportBind (Context& context,
3438 const ImageTestConfig config)
3440 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3441 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3442 const vk::InstanceDriver vki (vkp, *instance);
3443 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3444 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3445 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3446 const vk::DeviceDriver vkd (vki, *device);
3447 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3448 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3449 const deUint32 width = 64u;
3450 const deUint32 height = 64u;
3451 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3453 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3455 deUint32 exportedMemoryTypeIndex = ~0U;
3456 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3457 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3458 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
3459 NativeHandle handle;
3461 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3463 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3466 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3467 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3469 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3472 return tcu::TestStatus::pass("Pass");
3475 tcu::TestStatus testImageExportBindImportBind (Context& context,
3476 const ImageTestConfig config)
3478 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3479 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3480 const vk::InstanceDriver vki (vkp, *instance);
3481 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3482 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3483 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3484 const vk::DeviceDriver vkd (vki, *device);
3485 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3486 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3487 const deUint32 width = 64u;
3488 const deUint32 height = 64u;
3489 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3491 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3493 deUint32 exportedMemoryTypeIndex = ~0U;
3494 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3495 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3496 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
3497 NativeHandle handle;
3499 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3500 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3503 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3504 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3506 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3509 return tcu::TestStatus::pass("Pass");
3512 tcu::TestStatus testImageExportImportBindBind (Context& context,
3513 const ImageTestConfig config)
3515 const vk::PlatformInterface& vkp (context.getPlatformInterface());
3516 const vk::Unique<vk::VkInstance> instance (createInstance(vkp, 0u, config.externalType, 0u));
3517 const vk::InstanceDriver vki (vkp, *instance);
3518 const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
3519 const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u));
3520 const vk::Unique<vk::VkDevice> device (createDevice(vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
3521 const vk::DeviceDriver vkd (vki, *device);
3522 const vk::VkImageUsageFlags usage = vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3523 const vk::VkFormat format = vk::VK_FORMAT_R8G8B8A8_UNORM;
3524 const deUint32 width = 64u;
3525 const deUint32 height = 64u;
3526 const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL;
3528 checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
3530 deUint32 exportedMemoryTypeIndex = ~0U;
3531 // \note Image is only allocated to get memory requirements
3532 const vk::Unique<vk::VkImage> imageA (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3533 const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *imageA));
3534 const vk::Unique<vk::VkDeviceMemory> memoryA (allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
3535 NativeHandle handle;
3537 getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
3540 const vk::Unique<vk::VkDeviceMemory> memoryB (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
3541 const vk::Unique<vk::VkImage> imageB (createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
3543 VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
3544 VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
3547 return tcu::TestStatus::pass("Pass");
3549 de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx, vk::VkExternalFenceHandleTypeFlagBitsKHR externalType)
3553 const char* const name;
3554 const Permanence permanence;
3557 { "temporary", PERMANENCE_TEMPORARY },
3558 { "permanent", PERMANENCE_PERMANENT }
3561 de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, externalFenceTypeToName(externalType), externalFenceTypeToName(externalType)));
3563 addFunctionCase(fenceGroup.get(), "info", "Test external fence queries.", testFenceQueries, externalType);
3565 for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
3567 const Permanence permanence (permanences[permanenceNdx].permanence);
3568 const char* const permanenceName (permanences[permanenceNdx].name);
3569 const FenceTestConfig config (externalType, permanence);
3571 if (!isSupportedPermanence(externalType, permanence))
3574 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
3575 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
3577 addFunctionCase(fenceGroup.get(), std::string("create_win32_") + permanenceName, "Test creating fence with win32 properties.", testFenceWin32Create, config);
3580 addFunctionCase(fenceGroup.get(), std::string("import_twice_") + permanenceName, "Test importing fence twice.", testFenceImportTwice, config);
3581 addFunctionCase(fenceGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported fence.", testFenceImportReimport, config);
3582 addFunctionCase(fenceGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing fence multiple times.", testFenceMultipleImports, config);
3583 addFunctionCase(fenceGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", testFenceSignalExportImportWait, config);
3584 addFunctionCase(fenceGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the fence.", testFenceSignalImport, config);
3585 addFunctionCase(fenceGroup.get(), std::string("reset_") + permanenceName, "Test resetting the fence.", testFenceReset, config);
3586 addFunctionCase(fenceGroup.get(), std::string("transference_") + permanenceName, "Test fences transference.", testFenceTransference, config);
3588 if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR
3589 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
3591 // \note Not supported on WIN32 handles
3592 addFunctionCase(fenceGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting fence multiple times.", testFenceMultipleExports, config);
3594 addFunctionCase(fenceGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported fence.", testFenceFdDup, config);
3595 addFunctionCase(fenceGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported fence.", testFenceFdDup2, config);
3596 addFunctionCase(fenceGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported fence.", testFenceFdDup3, config);
3597 addFunctionCase(fenceGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending fence fd over socket.", testFenceFdSendOverSocket, config);
3600 if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
3602 addFunctionCase(fenceGroup.get(), std::string("signal_wait_import_") + permanenceName, "Test signaling and then waiting for the the sepmahore.", testFenceSignalWaitImport, config);
3603 addFunctionCase(fenceGroup.get(), std::string("export_signal_import_wait_") + permanenceName, "Test exporting, signaling, importing and waiting for the fence.", testFenceExportSignalImportWait, config);
3604 addFunctionCase(fenceGroup.get(), std::string("export_import_signal_wait_") + permanenceName, "Test exporting, importing, signaling and waiting for the fence.", testFenceExportImportSignalWait, config);
3611 de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx)
3613 de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, "fence", "Tests for external fences."));
3615 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR).release());
3616 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR).release());
3617 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR).release());
3618 fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR).release());
3623 de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx, vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType)
3627 const char* const name;
3628 const Permanence permanence;
3631 { "temporary", PERMANENCE_TEMPORARY },
3632 { "permanent", PERMANENCE_PERMANENT }
3635 de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, externalSemaphoreTypeToName(externalType), externalSemaphoreTypeToName(externalType)));
3637 addFunctionCase(semaphoreGroup.get(), "info", "Test external semaphore queries.", testSemaphoreQueries, externalType);
3639 for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
3641 const Permanence permanence (permanences[permanenceNdx].permanence);
3642 const char* const permanenceName (permanences[permanenceNdx].name);
3643 const SemaphoreTestConfig config (externalType, permanence);
3645 if (!isSupportedPermanence(externalType, permanence))
3648 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
3649 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
3651 addFunctionCase(semaphoreGroup.get(), std::string("create_win32_") + permanenceName, "Test creating semaphore with win32 properties.", testSemaphoreWin32Create, config);
3654 addFunctionCase(semaphoreGroup.get(), std::string("import_twice_") + permanenceName, "Test importing semaphore twice.", testSemaphoreImportTwice, config);
3655 addFunctionCase(semaphoreGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported semaphore.", testSemaphoreImportReimport, config);
3656 addFunctionCase(semaphoreGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing semaphore multiple times.", testSemaphoreMultipleImports, config);
3657 addFunctionCase(semaphoreGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", testSemaphoreSignalExportImportWait, config);
3658 addFunctionCase(semaphoreGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the semaphore.", testSemaphoreSignalImport, config);
3659 addFunctionCase(semaphoreGroup.get(), std::string("transference_") + permanenceName, "Test semaphores transference.", testSemaphoreTransference, config);
3661 if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
3662 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
3664 // \note Not supported on WIN32 handles
3665 addFunctionCase(semaphoreGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting semaphore multiple times.", testSemaphoreMultipleExports, config);
3667 addFunctionCase(semaphoreGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported semaphore.", testSemaphoreFdDup, config);
3668 addFunctionCase(semaphoreGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported semaphore.", testSemaphoreFdDup2, config);
3669 addFunctionCase(semaphoreGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported semaphore.", testSemaphoreFdDup3, config);
3670 addFunctionCase(semaphoreGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending semaphore fd over socket.", testSemaphoreFdSendOverSocket, config);
3673 if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
3675 addFunctionCase(semaphoreGroup.get(), std::string("signal_wait_import_") + permanenceName, "Test signaling and then waiting for the the sepmahore.", testSemaphoreSignalWaitImport, config);
3676 addFunctionCase(semaphoreGroup.get(), std::string("export_signal_import_wait_") + permanenceName, "Test exporting, signaling, importing and waiting for the semaphore.", testSemaphoreExportSignalImportWait, config);
3677 addFunctionCase(semaphoreGroup.get(), std::string("export_import_signal_wait_") + permanenceName, "Test exporting, importing, signaling and waiting for the semaphore.", testSemaphoreExportImportSignalWait, config);
3681 return semaphoreGroup;
3684 de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx)
3686 de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, "semaphore", "Tests for external semaphores."));
3688 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR).release());
3689 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR).release());
3690 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR).release());
3691 semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR).release());
3693 return semaphoreGroup;
3696 de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx, vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType)
3698 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, externalMemoryTypeToName(externalType), "Tests for external memory"));
3700 for (size_t dedicatedNdx = 0; dedicatedNdx < 2; dedicatedNdx++)
3702 const bool dedicated (dedicatedNdx == 1);
3703 de::MovePtr<tcu::TestCaseGroup> dedicatedGroup (new tcu::TestCaseGroup(testCtx, dedicated ? "dedicated" : "suballocated", ""));
3705 for (size_t hostVisibleNdx = 0; hostVisibleNdx < 2; hostVisibleNdx++)
3707 const bool hostVisible (hostVisibleNdx == 1);
3708 de::MovePtr<tcu::TestCaseGroup> hostVisibleGroup (new tcu::TestCaseGroup(testCtx, hostVisible ? "host_visible" : "device_only", ""));
3709 const MemoryTestConfig memoryConfig (externalType, hostVisible, dedicated);
3711 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
3712 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
3714 addFunctionCase(hostVisibleGroup.get(), "create_win32", "Test creating memory with win32 properties .", testMemoryWin32Create, memoryConfig);
3717 addFunctionCase(hostVisibleGroup.get(), "import_twice", "Test importing memory object twice.", testMemoryImportTwice, memoryConfig);
3718 addFunctionCase(hostVisibleGroup.get(), "import_multiple_times", "Test importing memory object multiple times.", testMemoryMultimpleImports, memoryConfig);
3720 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
3722 addFunctionCase(hostVisibleGroup.get(), "dup", "Test calling dup() on exported memory.", testMemoryFdDup, memoryConfig);
3723 addFunctionCase(hostVisibleGroup.get(), "dup2", "Test calling dup2() on exported memory.", testMemoryFdDup2, memoryConfig);
3724 addFunctionCase(hostVisibleGroup.get(), "dup3", "Test calling dup3() on exported memory.", testMemoryFdDup3, memoryConfig);
3725 addFunctionCase(hostVisibleGroup.get(), "send_over_socket", "Test sending memory fd over socket.", testMemoryFdSendOverSocket, memoryConfig);
3726 // \note Not supported on WIN32 handles
3727 addFunctionCase(hostVisibleGroup.get(), "export_multiple_times", "Test exporting memory multiple times.", testMemoryMultimpleExports, memoryConfig);
3730 dedicatedGroup->addChild(hostVisibleGroup.release());
3734 de::MovePtr<tcu::TestCaseGroup> bufferGroup (new tcu::TestCaseGroup(testCtx, "buffer", ""));
3735 const BufferTestConfig bufferConfig (externalType, dedicated);
3737 addFunctionCase(bufferGroup.get(), "info", "External buffer memory info query.", testBufferQueries, externalType);
3738 addFunctionCase(bufferGroup.get(), "bind_export_import_bind", "Test binding, exporting, importing and binding buffer.", testBufferBindExportImportBind, bufferConfig);
3739 addFunctionCase(bufferGroup.get(), "export_bind_import_bind", "Test exporting, binding, importing and binding buffer.", testBufferExportBindImportBind, bufferConfig);
3740 addFunctionCase(bufferGroup.get(), "export_import_bind_bind", "Test exporting, importind and binding buffer.", testBufferExportImportBindBind, bufferConfig);
3742 dedicatedGroup->addChild(bufferGroup.release());
3746 de::MovePtr<tcu::TestCaseGroup> imageGroup (new tcu::TestCaseGroup(testCtx, "image", ""));
3747 const ImageTestConfig imageConfig (externalType, dedicated);
3749 addFunctionCase(imageGroup.get(), "info", "External image memory info query.", testImageQueries, externalType);
3750 addFunctionCase(imageGroup.get(), "bind_export_import_bind", "Test binding, exporting, importing and binding image.", testImageBindExportImportBind, imageConfig);
3751 addFunctionCase(imageGroup.get(), "export_bind_import_bind", "Test exporting, binding, importing and binding image.", testImageExportBindImportBind, imageConfig);
3752 addFunctionCase(imageGroup.get(), "export_import_bind_bind", "Test exporting, importind and binding image.", testImageExportImportBindBind, imageConfig);
3754 dedicatedGroup->addChild(imageGroup.release());
3757 group->addChild(dedicatedGroup.release());
3763 de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx)
3765 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "memory", "Tests for external memory"));
3767 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR).release());
3768 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR).release());
3769 group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR).release());
3776 tcu::TestCaseGroup* createExternalMemoryTests (tcu::TestContext& testCtx)
3778 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "external", "Tests for external Vulkan objects"));
3780 group->addChild(createSemaphoreTests(testCtx).release());
3781 group->addChild(createMemoryTests(testCtx).release());
3782 group->addChild(createFenceTests(testCtx).release());
3784 return group.release();