1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group 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.
21 * \brief Synchronization tests for resources shared between instances.
22 *//*--------------------------------------------------------------------*/
24 #include "vktSynchronizationCrossInstanceSharingTests.hpp"
26 #include "vkDeviceUtil.hpp"
27 #include "vkPlatform.hpp"
28 #include "vkCmdUtil.hpp"
29 #include "vktTestCaseUtil.hpp"
30 #include "deSharedPtr.hpp"
32 #include "vktSynchronizationUtil.hpp"
33 #include "vktSynchronizationOperation.hpp"
34 #include "vktSynchronizationOperationTestData.hpp"
35 #include "vktSynchronizationOperationResources.hpp"
36 #include "vktExternalMemoryUtil.hpp"
37 #include "vktTestGroupUtil.hpp"
39 #include "tcuResultCollector.hpp"
40 #include "tcuTestLog.hpp"
43 using namespace vkt::ExternalMemoryUtil;
47 namespace synchronization
56 TestConfig (const ResourceDescription& resource_,
57 OperationName writeOp_,
58 OperationName readOp_,
59 vk::VkExternalMemoryHandleTypeFlagBits memoryHandleType_,
60 vk::VkExternalSemaphoreHandleTypeFlagBits semaphoreHandleType_,
62 : resource (resource_)
65 , memoryHandleType (memoryHandleType_)
66 , semaphoreHandleType (semaphoreHandleType_)
67 , dedicated (dedicated_)
71 const ResourceDescription resource;
72 const OperationName writeOp;
73 const OperationName readOp;
74 const vk::VkExternalMemoryHandleTypeFlagBits memoryHandleType;
75 const vk::VkExternalSemaphoreHandleTypeFlagBits semaphoreHandleType;
79 // A helper class to test for extensions upfront and throw not supported to speed up test runtimes compared to failing only
80 // after creating unnecessary vkInstances. A common example of this is win32 platforms taking a long time to run _fd tests.
81 class NotSupportedChecker
84 NotSupportedChecker (const Context& context,
86 const OperationSupport& writeOp,
87 const OperationSupport& readOp)
90 // Check instance support
91 requireInstanceExtension("VK_KHR_get_physical_device_properties2");
93 requireInstanceExtension("VK_KHR_external_semaphore_capabilities");
94 requireInstanceExtension("VK_KHR_external_memory_capabilities");
96 // Check device support
98 requireDeviceExtension("VK_KHR_dedicated_allocation");
100 requireDeviceExtension("VK_KHR_external_semaphore");
101 requireDeviceExtension("VK_KHR_external_memory");
103 if (config.memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR
104 || config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
105 || config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
107 requireDeviceExtension("VK_KHR_external_semaphore_fd");
108 requireDeviceExtension("VK_KHR_external_memory_fd");
111 if (config.memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
112 || config.memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR
113 || config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
114 || config.semaphoreHandleType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
116 requireDeviceExtension("VK_KHR_external_semaphore_win32");
117 requireDeviceExtension("VK_KHR_external_memory_win32");
120 TestLog& log = context.getTestContext().getLog();
121 const vk::InstanceInterface& vki = context.getInstanceInterface();
122 const vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
124 // Check resource support
125 if (config.resource.type == RESOURCE_TYPE_IMAGE)
127 const vk::VkPhysicalDeviceExternalImageFormatInfo externalInfo =
129 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
131 config.memoryHandleType
133 const vk::VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
135 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
137 config.resource.imageFormat,
138 config.resource.imageType,
139 vk::VK_IMAGE_TILING_OPTIMAL,
140 readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
143 vk::VkExternalImageFormatProperties externalProperties =
145 vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
149 vk::VkImageFormatProperties2 formatProperties =
151 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
163 const vk::VkResult res = vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &formatProperties);
165 if (res == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
166 TCU_THROW(NotSupportedError, "Image format not supported");
168 VK_CHECK(res); // Check other errors
171 log << TestLog::Message << "External image format properties: " << imageFormatInfo << "\n"<< externalProperties << TestLog::EndMessage;
173 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) == 0)
174 TCU_THROW(NotSupportedError, "Exporting image resource not supported");
176 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) == 0)
177 TCU_THROW(NotSupportedError, "Importing image resource not supported");
179 if (!config.dedicated && (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0)
181 TCU_THROW(NotSupportedError, "Handle requires dedicated allocation, but test uses suballocated memory");
186 const vk::VkPhysicalDeviceExternalBufferInfo info =
188 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
192 readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
193 config.memoryHandleType
195 vk::VkExternalBufferProperties properties =
197 vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
201 vki.getPhysicalDeviceExternalBufferProperties(physicalDevice, &info, &properties);
203 log << TestLog::Message << "External buffer properties: " << info << "\n" << properties << TestLog::EndMessage;
205 if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) == 0
206 || (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR) == 0)
207 TCU_THROW(NotSupportedError, "Exporting and importing memory type not supported");
209 if (!config.dedicated && (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR) != 0)
211 TCU_THROW(NotSupportedError, "Handle requires dedicated allocation, but test uses suballocated memory");
215 // Check semaphore support
217 const vk::VkPhysicalDeviceExternalSemaphoreInfo info =
219 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
221 config.semaphoreHandleType
224 vk::VkExternalSemaphoreProperties properties =
226 vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
233 vki.getPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &info, &properties);
235 log << TestLog::Message << info << "\n" << properties << TestLog::EndMessage;
237 if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) == 0
238 || (properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR) == 0)
239 TCU_THROW(NotSupportedError, "Exporting and importing semaphore type not supported");
244 void requireDeviceExtension(const char* name) const
246 if (!de::contains(m_context.getDeviceExtensions().begin(), m_context.getDeviceExtensions().end(), name))
247 TCU_THROW(NotSupportedError, (std::string(name) + " is not supported").c_str());
250 void requireInstanceExtension(const char* name) const
252 if (!de::contains(m_context.getInstanceExtensions().begin(), m_context.getInstanceExtensions().end(), name))
253 TCU_THROW(NotSupportedError, (std::string(name) + " is not supported").c_str());
256 const Context& m_context;
259 bool checkQueueFlags (vk::VkQueueFlags availableFlags, const vk::VkQueueFlags neededFlags)
261 if ((availableFlags & (vk::VK_QUEUE_GRAPHICS_BIT | vk::VK_QUEUE_COMPUTE_BIT)) != 0)
262 availableFlags |= vk::VK_QUEUE_TRANSFER_BIT;
264 return (availableFlags & neededFlags) != 0;
267 class SimpleAllocation : public vk::Allocation
270 SimpleAllocation (const vk::DeviceInterface& vkd,
272 const vk::VkDeviceMemory memory);
273 ~SimpleAllocation (void);
276 const vk::DeviceInterface& m_vkd;
277 const vk::VkDevice m_device;
280 SimpleAllocation::SimpleAllocation (const vk::DeviceInterface& vkd,
282 const vk::VkDeviceMemory memory)
283 : Allocation (memory, 0, DE_NULL)
289 SimpleAllocation::~SimpleAllocation (void)
291 m_vkd.freeMemory(m_device, getMemory(), DE_NULL);
297 DeviceId (deUint32 vendorId,
298 deUint32 driverVersion,
299 const deUint8 driverUUID[VK_UUID_SIZE],
300 const deUint8 deviceUUID[VK_UUID_SIZE]);
302 bool operator== (const DeviceId& other) const;
303 bool operator|= (const DeviceId& other) const;
306 const deUint32 m_vendorId;
307 const deUint32 m_driverVersion;
308 deUint8 m_driverUUID[VK_UUID_SIZE];
309 deUint8 m_deviceUUID[VK_UUID_SIZE];
312 DeviceId::DeviceId (deUint32 vendorId,
313 deUint32 driverVersion,
314 const deUint8 driverUUID[VK_UUID_SIZE],
315 const deUint8 deviceUUID[VK_UUID_SIZE])
316 : m_vendorId (vendorId)
317 , m_driverVersion (driverVersion)
319 deMemcpy(m_driverUUID, driverUUID, sizeof(m_driverUUID));
320 deMemcpy(m_deviceUUID, deviceUUID, sizeof(m_deviceUUID));
323 bool DeviceId::operator== (const DeviceId& other) const
328 if (m_vendorId != other.m_vendorId)
331 if (m_driverVersion != other.m_driverVersion)
334 if (deMemCmp(m_driverUUID, other.m_driverUUID, sizeof(m_driverUUID)) != 0)
337 return deMemCmp(m_deviceUUID, other.m_deviceUUID, sizeof(m_deviceUUID)) == 0;
340 DeviceId getDeviceId (const vk::InstanceInterface& vki,
341 vk::VkPhysicalDevice physicalDevice)
343 vk::VkPhysicalDeviceIDProperties propertiesId;
344 vk::VkPhysicalDeviceProperties2 properties;
346 deMemset(&properties, 0, sizeof(properties));
347 deMemset(&propertiesId, 0, sizeof(propertiesId));
349 propertiesId.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
351 properties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
352 properties.pNext = &propertiesId;
354 vki.getPhysicalDeviceProperties2(physicalDevice, &properties);
356 return DeviceId(properties.properties.vendorID, properties.properties.driverVersion, propertiesId.driverUUID, propertiesId.deviceUUID);
359 vk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface& vkp, deUint32 version)
363 std::vector<std::string> extensions;
364 if (!vk::isCoreInstanceExtension(version, "VK_KHR_get_physical_device_properties2"))
365 extensions.push_back("VK_KHR_get_physical_device_properties2");
366 if (!vk::isCoreInstanceExtension(version, "VK_KHR_external_semaphore_capabilities"))
367 extensions.push_back("VK_KHR_external_semaphore_capabilities");
368 if (!vk::isCoreInstanceExtension(version, "VK_KHR_external_memory_capabilities"))
369 extensions.push_back("VK_KHR_external_memory_capabilities");
371 return vk::createDefaultInstance(vkp, version, std::vector<std::string>(), extensions);
373 catch (const vk::Error& error)
375 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
376 TCU_THROW(NotSupportedError, "Required external memory extensions not supported by the instance");
382 vk::VkPhysicalDevice getPhysicalDevice (const vk::InstanceInterface& vki,
383 vk::VkInstance instance,
384 const tcu::CommandLine& cmdLine)
386 return vk::chooseDevice(vki, instance, cmdLine);
389 vk::VkPhysicalDevice getPhysicalDevice (const vk::InstanceInterface& vki, vk::VkInstance instance, const DeviceId& deviceId)
391 const std::vector<vk::VkPhysicalDevice> devices (vk::enumeratePhysicalDevices(vki, instance));
393 for (size_t deviceNdx = 0; deviceNdx < devices.size(); deviceNdx++)
395 if (deviceId == getDeviceId(vki, devices[deviceNdx]))
396 return devices[deviceNdx];
399 TCU_FAIL("No matching device found");
401 return (vk::VkPhysicalDevice)0;
404 vk::Move<vk::VkDevice> createDevice (const Context& context,
405 const vk::PlatformInterface& vkp,
406 vk::VkInstance instance,
407 const vk::InstanceInterface& vki,
408 const vk::VkPhysicalDevice physicalDevice)
410 const float priority = 0.0f;
411 const std::vector<vk::VkQueueFamilyProperties> queueFamilyProperties = vk::getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
412 std::vector<deUint32> queueFamilyIndices (queueFamilyProperties.size(), 0xFFFFFFFFu);
413 std::vector<const char*> extensions;
415 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation"))
416 extensions.push_back("VK_KHR_dedicated_allocation");
418 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_get_memory_requirements2"))
419 extensions.push_back("VK_KHR_get_memory_requirements2");
421 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_external_semaphore"))
422 extensions.push_back("VK_KHR_external_semaphore");
423 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_external_memory"))
424 extensions.push_back("VK_KHR_external_memory");
426 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_external_semaphore_fd"))
427 extensions.push_back("VK_KHR_external_semaphore_fd");
428 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_external_memory_fd"))
429 extensions.push_back("VK_KHR_external_memory_fd");
431 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_external_semaphore_win32"))
432 extensions.push_back("VK_KHR_external_semaphore_win32");
433 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_external_memory_win32"))
434 extensions.push_back("VK_KHR_external_memory_win32");
438 std::vector<vk::VkDeviceQueueCreateInfo> queues;
440 for (size_t ndx = 0; ndx < queueFamilyProperties.size(); ndx++)
442 const vk::VkDeviceQueueCreateInfo createInfo =
444 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
453 queues.push_back(createInfo);
456 const vk::VkDeviceCreateInfo createInfo =
458 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
462 (deUint32)queues.size(),
468 (deUint32)extensions.size(),
469 extensions.empty() ? DE_NULL : &extensions[0],
473 return vk::createDevice(vkp, instance, vki, physicalDevice, &createInfo);
475 catch (const vk::Error& error)
477 if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
478 TCU_THROW(NotSupportedError, "Required extensions not supported");
484 // Class to wrap a singleton instance and device
485 class InstanceAndDevice
487 InstanceAndDevice (const Context& context)
488 : m_instance (createInstance(context.getPlatformInterface(), context.getUsedApiVersion()))
489 , m_vki (context.getPlatformInterface(), *m_instance)
490 , m_physicalDevice (getPhysicalDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
491 , m_logicalDevice (createDevice(context, context.getPlatformInterface(), *m_instance, m_vki, m_physicalDevice))
497 static const vk::Unique<vk::VkInstance>& getInstanceA(const Context& context)
500 m_instanceA = SharedPtr<InstanceAndDevice>(new InstanceAndDevice(context));
502 return m_instanceA->m_instance;
504 static const Unique<vk::VkInstance>& getInstanceB(const Context& context)
507 m_instanceB = SharedPtr<InstanceAndDevice>(new InstanceAndDevice(context));
509 return m_instanceB->m_instance;
511 static const Unique<vk::VkDevice>& getDeviceA()
513 DE_ASSERT(m_instanceA);
514 return m_instanceA->m_logicalDevice;
516 static const Unique<vk::VkDevice>& getDeviceB()
518 DE_ASSERT(m_instanceB);
519 return m_instanceB->m_logicalDevice;
522 static void destroy()
529 const Unique<vk::VkInstance> m_instance;
530 const vk::InstanceDriver m_vki;
531 const vk::VkPhysicalDevice m_physicalDevice;
532 const Unique<vk::VkDevice> m_logicalDevice;
534 static SharedPtr<InstanceAndDevice> m_instanceA;
535 static SharedPtr<InstanceAndDevice> m_instanceB;
537 SharedPtr<InstanceAndDevice> InstanceAndDevice::m_instanceA;
538 SharedPtr<InstanceAndDevice> InstanceAndDevice::m_instanceB;
541 vk::VkQueue getQueue (const vk::DeviceInterface& vkd,
542 const vk::VkDevice device,
543 deUint32 familyIndex)
547 vkd.getDeviceQueue(device, familyIndex, 0u, &queue);
552 vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vkd,
554 deUint32 queueFamilyIndex)
556 const vk::VkCommandPoolCreateInfo createInfo =
558 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
565 return vk::createCommandPool(vkd, device, &createInfo);
568 vk::Move<vk::VkCommandBuffer> createCommandBuffer (const vk::DeviceInterface& vkd,
570 vk::VkCommandPool commandPool)
572 const vk::VkCommandBufferLevel level = vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY;
573 const vk::VkCommandBufferAllocateInfo allocateInfo =
575 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
583 return vk::allocateCommandBuffer(vkd, device, &allocateInfo);
586 de::MovePtr<vk::Allocation> allocateAndBindMemory (const vk::DeviceInterface& vkd,
589 vk::VkExternalMemoryHandleTypeFlagBits externalType,
590 deUint32& exportedMemoryTypeIndex,
592 bool getMemReq2Supported)
594 vk::VkMemoryRequirements memoryRequirements = { 0u, 0u, 0u, };
596 if (getMemReq2Supported)
598 const vk::VkBufferMemoryRequirementsInfo2 requirementInfo =
600 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
604 vk::VkMemoryDedicatedRequirements dedicatedRequirements =
606 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
611 vk::VkMemoryRequirements2 requirements =
613 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
614 &dedicatedRequirements,
617 vkd.getBufferMemoryRequirements2(device, &requirementInfo, &requirements);
619 if (!dedicated && dedicatedRequirements.requiresDedicatedAllocation)
620 TCU_THROW(NotSupportedError, "Memory requires dedicated allocation");
622 memoryRequirements = requirements.memoryRequirements;
626 vkd.getBufferMemoryRequirements(device, buffer, &memoryRequirements);
630 vk::Move<vk::VkDeviceMemory> memory = allocateExportableMemory(vkd, device, memoryRequirements, externalType, dedicated ? buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex);
631 VK_CHECK(vkd.bindBufferMemory(device, buffer, *memory, 0u));
633 return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
636 de::MovePtr<vk::Allocation> allocateAndBindMemory (const vk::DeviceInterface& vkd,
639 vk::VkExternalMemoryHandleTypeFlagBits externalType,
640 deUint32& exportedMemoryTypeIndex,
642 bool getMemReq2Supported)
644 vk::VkMemoryRequirements memoryRequirements = { 0u, 0u, 0u, };
646 if (getMemReq2Supported)
648 const vk::VkImageMemoryRequirementsInfo2 requirementInfo =
650 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
654 vk::VkMemoryDedicatedRequirements dedicatedRequirements =
656 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
661 vk::VkMemoryRequirements2 requirements =
663 vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
664 &dedicatedRequirements,
667 vkd.getImageMemoryRequirements2(device, &requirementInfo, &requirements);
669 if (!dedicated && dedicatedRequirements.requiresDedicatedAllocation)
670 TCU_THROW(NotSupportedError, "Memory requires dedicated allocation");
672 memoryRequirements = requirements.memoryRequirements;
676 vkd.getImageMemoryRequirements(device, image, &memoryRequirements);
679 vk::Move<vk::VkDeviceMemory> memory = allocateExportableMemory(vkd, device, memoryRequirements, externalType, dedicated ? image : (vk::VkImage)0, exportedMemoryTypeIndex);
680 VK_CHECK(vkd.bindImageMemory(device, image, *memory, 0u));
682 return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
685 de::MovePtr<Resource> createResource (const vk::DeviceInterface& vkd,
687 const ResourceDescription& resourceDesc,
688 const std::vector<deUint32>& queueFamilyIndices,
689 const OperationSupport& readOp,
690 const OperationSupport& writeOp,
691 vk::VkExternalMemoryHandleTypeFlagBits externalType,
692 deUint32& exportedMemoryTypeIndex,
694 bool getMemReq2Supported)
696 if (resourceDesc.type == RESOURCE_TYPE_IMAGE)
698 const vk::VkExtent3D extent =
700 (deUint32)resourceDesc.size.x(),
701 de::max(1u, (deUint32)resourceDesc.size.y()),
702 de::max(1u, (deUint32)resourceDesc.size.z())
704 const vk::VkImageSubresourceRange subresourceRange =
706 resourceDesc.imageAspect,
712 const vk::VkImageSubresourceLayers subresourceLayers =
714 resourceDesc.imageAspect,
719 const vk::VkExternalMemoryImageCreateInfo externalInfo =
721 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
723 (vk::VkExternalMemoryHandleTypeFlags)externalType
725 const vk::VkImageCreateInfo createInfo =
727 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
731 resourceDesc.imageType,
732 resourceDesc.imageFormat,
736 vk::VK_SAMPLE_COUNT_1_BIT,
737 vk::VK_IMAGE_TILING_OPTIMAL,
738 readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
739 vk::VK_SHARING_MODE_EXCLUSIVE,
741 (deUint32)queueFamilyIndices.size(),
742 &queueFamilyIndices[0],
743 vk::VK_IMAGE_LAYOUT_UNDEFINED
746 vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &createInfo);
747 de::MovePtr<vk::Allocation> allocation = allocateAndBindMemory(vkd, device, *image, externalType, exportedMemoryTypeIndex, dedicated, getMemReq2Supported);
749 return de::MovePtr<Resource>(new Resource(image, allocation, extent, resourceDesc.imageType, resourceDesc.imageFormat, subresourceRange, subresourceLayers));
753 const vk::VkDeviceSize offset = 0u;
754 const vk::VkDeviceSize size = static_cast<vk::VkDeviceSize>(resourceDesc.size.x());
755 const vk::VkBufferUsageFlags usage = readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags();
756 const vk:: VkExternalMemoryBufferCreateInfo externalInfo =
758 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
760 (vk::VkExternalMemoryHandleTypeFlags)externalType
762 const vk::VkBufferCreateInfo createInfo =
764 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
770 vk::VK_SHARING_MODE_EXCLUSIVE,
771 (deUint32)queueFamilyIndices.size(),
772 &queueFamilyIndices[0]
774 vk::Move<vk::VkBuffer> buffer = vk::createBuffer(vkd, device, &createInfo);
775 de::MovePtr<vk::Allocation> allocation = allocateAndBindMemory(vkd, device, *buffer, externalType, exportedMemoryTypeIndex, dedicated, getMemReq2Supported);
777 return de::MovePtr<Resource>(new Resource(resourceDesc.type, buffer, allocation, offset, size));
781 de::MovePtr<vk::Allocation> importAndBindMemory (const vk::DeviceInterface& vkd,
784 NativeHandle& nativeHandle,
785 vk::VkExternalMemoryHandleTypeFlagBits externalType,
786 deUint32 exportedMemoryTypeIndex,
789 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vkd, device, buffer);
790 vk::Move<vk::VkDeviceMemory> memory = dedicated
791 ? importDedicatedMemory(vkd, device, buffer, requirements, externalType, exportedMemoryTypeIndex, nativeHandle)
792 : importMemory(vkd, device, requirements, externalType, exportedMemoryTypeIndex, nativeHandle);
794 VK_CHECK(vkd.bindBufferMemory(device, buffer, *memory, 0u));
796 return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
799 de::MovePtr<vk::Allocation> importAndBindMemory (const vk::DeviceInterface& vkd,
802 NativeHandle& nativeHandle,
803 vk::VkExternalMemoryHandleTypeFlagBits externalType,
804 deUint32 exportedMemoryTypeIndex,
807 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vkd, device, image);
808 vk::Move<vk::VkDeviceMemory> memory = dedicated
809 ? importDedicatedMemory(vkd, device, image, requirements, externalType, exportedMemoryTypeIndex, nativeHandle)
810 : importMemory(vkd, device, requirements, externalType, exportedMemoryTypeIndex, nativeHandle);
811 VK_CHECK(vkd.bindImageMemory(device, image, *memory, 0u));
813 return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
816 de::MovePtr<Resource> importResource (const vk::DeviceInterface& vkd,
818 const ResourceDescription& resourceDesc,
819 const std::vector<deUint32>& queueFamilyIndices,
820 const OperationSupport& readOp,
821 const OperationSupport& writeOp,
822 NativeHandle& nativeHandle,
823 vk::VkExternalMemoryHandleTypeFlagBits externalType,
824 deUint32 exportedMemoryTypeIndex,
827 if (resourceDesc.type == RESOURCE_TYPE_IMAGE)
829 const vk::VkExtent3D extent =
831 (deUint32)resourceDesc.size.x(),
832 de::max(1u, (deUint32)resourceDesc.size.y()),
833 de::max(1u, (deUint32)resourceDesc.size.z())
835 const vk::VkImageSubresourceRange subresourceRange =
837 resourceDesc.imageAspect,
843 const vk::VkImageSubresourceLayers subresourceLayers =
845 resourceDesc.imageAspect,
850 const vk:: VkExternalMemoryImageCreateInfo externalInfo =
852 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
854 (vk::VkExternalMemoryHandleTypeFlags)externalType
856 const vk::VkImageCreateInfo createInfo =
858 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
862 resourceDesc.imageType,
863 resourceDesc.imageFormat,
867 vk::VK_SAMPLE_COUNT_1_BIT,
868 vk::VK_IMAGE_TILING_OPTIMAL,
869 readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
870 vk::VK_SHARING_MODE_EXCLUSIVE,
872 (deUint32)queueFamilyIndices.size(),
873 &queueFamilyIndices[0],
874 vk::VK_IMAGE_LAYOUT_UNDEFINED
877 vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &createInfo);
878 de::MovePtr<vk::Allocation> allocation = importAndBindMemory(vkd, device, *image, nativeHandle, externalType, exportedMemoryTypeIndex, dedicated);
880 return de::MovePtr<Resource>(new Resource(image, allocation, extent, resourceDesc.imageType, resourceDesc.imageFormat, subresourceRange, subresourceLayers));
884 const vk::VkDeviceSize offset = 0u;
885 const vk::VkDeviceSize size = static_cast<vk::VkDeviceSize>(resourceDesc.size.x());
886 const vk::VkBufferUsageFlags usage = readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags();
887 const vk:: VkExternalMemoryBufferCreateInfo externalInfo =
889 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
891 (vk::VkExternalMemoryHandleTypeFlags)externalType
893 const vk::VkBufferCreateInfo createInfo =
895 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
901 vk::VK_SHARING_MODE_EXCLUSIVE,
902 (deUint32)queueFamilyIndices.size(),
903 &queueFamilyIndices[0]
905 vk::Move<vk::VkBuffer> buffer = vk::createBuffer(vkd, device, &createInfo);
906 de::MovePtr<vk::Allocation> allocation = importAndBindMemory(vkd, device, *buffer, nativeHandle, externalType, exportedMemoryTypeIndex, dedicated);
908 return de::MovePtr<Resource>(new Resource(resourceDesc.type, buffer, allocation, offset, size));
912 void recordWriteBarrier (const vk::DeviceInterface& vkd,
913 vk::VkCommandBuffer commandBuffer,
914 const Resource& resource,
915 const SyncInfo& writeSync,
916 deUint32 writeQueueFamilyIndex,
917 const SyncInfo& readSync)
919 const vk::VkPipelineStageFlags srcStageMask = writeSync.stageMask;
920 const vk::VkAccessFlags srcAccessMask = writeSync.accessMask;
922 const vk::VkPipelineStageFlags dstStageMask = readSync.stageMask;
923 const vk::VkAccessFlags dstAccessMask = readSync.accessMask;
925 const vk::VkDependencyFlags dependencyFlags = 0;
927 if (resource.getType() == RESOURCE_TYPE_IMAGE)
929 const vk::VkImageMemoryBarrier barrier =
931 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
937 writeSync.imageLayout,
938 readSync.imageLayout,
940 writeQueueFamilyIndex,
941 VK_QUEUE_FAMILY_EXTERNAL,
943 resource.getImage().handle,
944 resource.getImage().subresourceRange
947 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, (const vk::VkImageMemoryBarrier*)&barrier);
951 const vk::VkBufferMemoryBarrier barrier =
953 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
959 writeQueueFamilyIndex,
960 VK_QUEUE_FAMILY_EXTERNAL,
962 resource.getBuffer().handle,
967 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, (const vk::VkBufferMemoryBarrier*)&barrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
971 void recordReadBarrier (const vk::DeviceInterface& vkd,
972 vk::VkCommandBuffer commandBuffer,
973 const Resource& resource,
974 const SyncInfo& writeSync,
975 const SyncInfo& readSync,
976 deUint32 readQueueFamilyIndex)
978 const vk::VkPipelineStageFlags srcStageMask = readSync.stageMask;
979 const vk::VkAccessFlags srcAccessMask = readSync.accessMask;
981 const vk::VkPipelineStageFlags dstStageMask = readSync.stageMask;
982 const vk::VkAccessFlags dstAccessMask = readSync.accessMask;
984 const vk::VkDependencyFlags dependencyFlags = 0;
986 if (resource.getType() == RESOURCE_TYPE_IMAGE)
988 const vk::VkImageMemoryBarrier barrier =
990 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
996 writeSync.imageLayout,
997 readSync.imageLayout,
999 VK_QUEUE_FAMILY_EXTERNAL,
1000 readQueueFamilyIndex,
1002 resource.getImage().handle,
1003 resource.getImage().subresourceRange
1006 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, (const vk::VkImageMemoryBarrier*)&barrier);
1010 const vk::VkBufferMemoryBarrier barrier =
1012 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1018 VK_QUEUE_FAMILY_EXTERNAL,
1019 readQueueFamilyIndex,
1021 resource.getBuffer().handle,
1026 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, (const vk::VkBufferMemoryBarrier*)&barrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
1030 std::vector<deUint32> getFamilyIndices (const std::vector<vk::VkQueueFamilyProperties>& properties)
1032 std::vector<deUint32> indices (properties.size(), 0);
1034 for (deUint32 ndx = 0; ndx < properties.size(); ndx++)
1040 class SharingTestInstance : public TestInstance
1043 SharingTestInstance (Context& context,
1046 virtual tcu::TestStatus iterate (void);
1049 const TestConfig m_config;
1050 const de::UniquePtr<OperationSupport> m_supportWriteOp;
1051 const de::UniquePtr<OperationSupport> m_supportReadOp;
1052 const NotSupportedChecker m_notSupportedChecker; // Must declare before VkInstance to effectively reduce runtimes!
1054 const vk::Unique<vk::VkInstance>& m_instanceA;
1056 const vk::InstanceDriver m_vkiA;
1057 const vk::VkPhysicalDevice m_physicalDeviceA;
1058 const std::vector<vk::VkQueueFamilyProperties> m_queueFamiliesA;
1059 const std::vector<deUint32> m_queueFamilyIndicesA;
1061 const bool m_getMemReq2Supported;
1063 const vk::Unique<vk::VkDevice>& m_deviceA;
1064 const vk::DeviceDriver m_vkdA;
1066 const vk::Unique<vk::VkInstance>& m_instanceB;
1067 const vk::InstanceDriver m_vkiB;
1068 const vk::VkPhysicalDevice m_physicalDeviceB;
1069 const std::vector<vk::VkQueueFamilyProperties> m_queueFamiliesB;
1070 const std::vector<deUint32> m_queueFamilyIndicesB;
1071 const vk::Unique<vk::VkDevice>& m_deviceB;
1072 const vk::DeviceDriver m_vkdB;
1074 const vk::VkExternalSemaphoreHandleTypeFlagBits m_semaphoreHandleType;
1075 const vk::VkExternalMemoryHandleTypeFlagBits m_memoryHandleType;
1077 // \todo Should this be moved to the group same way as in the other tests?
1078 PipelineCacheData m_pipelineCacheData;
1079 tcu::ResultCollector m_resultCollector;
1084 SharingTestInstance::SharingTestInstance (Context& context,
1086 : TestInstance (context)
1088 , m_supportWriteOp (makeOperationSupport(config.writeOp, config.resource))
1089 , m_supportReadOp (makeOperationSupport(config.readOp, config.resource))
1090 , m_notSupportedChecker (context, m_config, *m_supportWriteOp, *m_supportReadOp)
1092 , m_instanceA (InstanceAndDevice::getInstanceA(context))
1094 , m_vkiA (context.getPlatformInterface(), *m_instanceA) // \todo [2017-06-13 pyry] Provide correct extension list
1095 , m_physicalDeviceA (getPhysicalDevice(m_vkiA, *m_instanceA, context.getTestContext().getCommandLine()))
1096 , m_queueFamiliesA (vk::getPhysicalDeviceQueueFamilyProperties(m_vkiA, m_physicalDeviceA))
1097 , m_queueFamilyIndicesA (getFamilyIndices(m_queueFamiliesA))
1098 , m_getMemReq2Supported (vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_get_memory_requirements2"))
1099 , m_deviceA (InstanceAndDevice::getDeviceA())
1100 , m_vkdA (context.getPlatformInterface(), *m_instanceA, *m_deviceA)
1102 , m_instanceB (InstanceAndDevice::getInstanceB(context))
1104 , m_vkiB (context.getPlatformInterface(), *m_instanceB) // \todo [2017-06-13 pyry] Provide correct extension list
1105 , m_physicalDeviceB (getPhysicalDevice(m_vkiB, *m_instanceB, getDeviceId(m_vkiA, m_physicalDeviceA)))
1106 , m_queueFamiliesB (vk::getPhysicalDeviceQueueFamilyProperties(m_vkiB, m_physicalDeviceB))
1107 , m_queueFamilyIndicesB (getFamilyIndices(m_queueFamiliesB))
1108 , m_deviceB (InstanceAndDevice::getDeviceB())
1109 , m_vkdB (context.getPlatformInterface(), *m_instanceB, *m_deviceB)
1111 , m_semaphoreHandleType (m_config.semaphoreHandleType)
1112 , m_memoryHandleType (m_config.memoryHandleType)
1114 , m_resultCollector (context.getTestContext().getLog())
1120 tcu::TestStatus SharingTestInstance::iterate (void)
1122 TestLog& log (m_context.getTestContext().getLog());
1126 const deUint32 queueFamilyA = (deUint32)m_queueANdx;
1127 const deUint32 queueFamilyB = (deUint32)m_queueBNdx;
1129 const tcu::ScopedLogSection queuePairSection (log,
1130 "WriteQueue-" + de::toString(queueFamilyA) + "-ReadQueue-" + de::toString(queueFamilyB),
1131 "WriteQueue-" + de::toString(queueFamilyA) + "-ReadQueue-" + de::toString(queueFamilyB));
1133 const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(m_vkdA, *m_deviceA, m_semaphoreHandleType));
1134 const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(m_vkdB, *m_deviceB));
1136 deUint32 exportedMemoryTypeIndex = ~0U;
1137 const de::UniquePtr<Resource> resourceA (createResource(m_vkdA, *m_deviceA, m_config.resource, m_queueFamilyIndicesA, *m_supportReadOp, *m_supportWriteOp, m_memoryHandleType, exportedMemoryTypeIndex, m_config.dedicated, m_getMemReq2Supported));
1139 NativeHandle nativeMemoryHandle;
1140 getMemoryNative(m_vkdA, *m_deviceA, resourceA->getMemory(), m_memoryHandleType, nativeMemoryHandle);
1142 const de::UniquePtr<Resource> resourceB (importResource(m_vkdB, *m_deviceB, m_config.resource, m_queueFamilyIndicesB, *m_supportReadOp, *m_supportWriteOp, nativeMemoryHandle, m_memoryHandleType, exportedMemoryTypeIndex, m_config.dedicated));
1145 const vk::VkQueue queueA (getQueue(m_vkdA, *m_deviceA, queueFamilyA));
1146 const vk::Unique<vk::VkCommandPool> commandPoolA (createCommandPool(m_vkdA, *m_deviceA, queueFamilyA));
1147 const vk::Unique<vk::VkCommandBuffer> commandBufferA (createCommandBuffer(m_vkdA, *m_deviceA, *commandPoolA));
1148 vk::SimpleAllocator allocatorA (m_vkdA, *m_deviceA, vk::getPhysicalDeviceMemoryProperties(m_vkiA, m_physicalDeviceA));
1149 const std::vector<std::string> deviceExtensionsA;
1150 OperationContext operationContextA (m_context.getUsedApiVersion(), m_vkiA, m_vkdA, m_physicalDeviceA, *m_deviceA, allocatorA, deviceExtensionsA, m_context.getBinaryCollection(), m_pipelineCacheData);
1152 if (!checkQueueFlags(m_queueFamiliesA[m_queueANdx].queueFlags , m_supportWriteOp->getQueueFlags(operationContextA)))
1153 TCU_THROW(NotSupportedError, "Operation not supported by the source queue");
1155 const vk::VkQueue queueB (getQueue(m_vkdB, *m_deviceB, queueFamilyB));
1156 const vk::Unique<vk::VkCommandPool> commandPoolB (createCommandPool(m_vkdB, *m_deviceB, queueFamilyB));
1157 const vk::Unique<vk::VkCommandBuffer> commandBufferB (createCommandBuffer(m_vkdB, *m_deviceB, *commandPoolB));
1158 vk::SimpleAllocator allocatorB (m_vkdB, *m_deviceB, vk::getPhysicalDeviceMemoryProperties(m_vkiB, m_physicalDeviceB));
1159 const std::vector<std::string> deviceExtensionsB;
1160 OperationContext operationContextB (m_context.getUsedApiVersion(), m_vkiB, m_vkdB, m_physicalDeviceB, *m_deviceB, allocatorB, deviceExtensionsB, m_context.getBinaryCollection(), m_pipelineCacheData);
1162 if (!checkQueueFlags(m_queueFamiliesB[m_queueBNdx].queueFlags , m_supportReadOp->getQueueFlags(operationContextB)))
1163 TCU_THROW(NotSupportedError, "Operation not supported by the destination queue");
1165 const de::UniquePtr<Operation> writeOp (m_supportWriteOp->build(operationContextA, *resourceA));
1166 const de::UniquePtr<Operation> readOp (m_supportReadOp->build(operationContextB, *resourceB));
1168 const SyncInfo writeSync = writeOp->getSyncInfo();
1169 const SyncInfo readSync = readOp->getSyncInfo();
1171 beginCommandBuffer(m_vkdA, *commandBufferA);
1172 writeOp->recordCommands(*commandBufferA);
1173 recordWriteBarrier(m_vkdA, *commandBufferA, *resourceA, writeSync, queueFamilyA, readSync);
1174 endCommandBuffer(m_vkdA, *commandBufferA);
1176 beginCommandBuffer(m_vkdB, *commandBufferB);
1177 recordReadBarrier(m_vkdB, *commandBufferB, *resourceB, writeSync, readSync, queueFamilyB);
1178 readOp->recordCommands(*commandBufferB);
1179 endCommandBuffer(m_vkdB, *commandBufferB);
1182 const vk::VkCommandBuffer commandBuffer = *commandBufferA;
1183 const vk::VkSemaphore semaphore = *semaphoreA;
1184 const vk::VkSubmitInfo submitInfo =
1186 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1199 VK_CHECK(m_vkdA.queueSubmit(queueA, 1u, &submitInfo, DE_NULL));
1202 NativeHandle nativeSemaphoreHandle;
1204 getSemaphoreNative(m_vkdA, *m_deviceA, *semaphoreA, m_semaphoreHandleType, nativeSemaphoreHandle);
1205 importSemaphore(m_vkdB, *m_deviceB, *semaphoreB, m_semaphoreHandleType, nativeSemaphoreHandle, 0u);
1209 const vk::VkCommandBuffer commandBuffer = *commandBufferB;
1210 const vk::VkSemaphore semaphore = *semaphoreB;
1211 const vk::VkPipelineStageFlags dstStage = readSync.stageMask;
1212 const vk::VkSubmitInfo submitInfo =
1214 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1227 VK_CHECK(m_vkdB.queueSubmit(queueB, 1u, &submitInfo, DE_NULL));
1230 VK_CHECK(m_vkdA.queueWaitIdle(queueA));
1231 VK_CHECK(m_vkdB.queueWaitIdle(queueB));
1234 const Data expected = writeOp->getData();
1235 const Data actual = readOp->getData();
1237 DE_ASSERT(expected.size == actual.size);
1239 if (0 != deMemCmp(expected.data, actual.data, expected.size))
1241 const size_t maxBytesLogged = 256;
1242 std::ostringstream expectedData;
1243 std::ostringstream actualData;
1246 // Find first byte difference
1247 for (; actual.data[byteNdx] == expected.data[byteNdx]; byteNdx++)
1252 log << TestLog::Message << "First different byte at offset: " << byteNdx << TestLog::EndMessage;
1254 // Log 8 previous bytes before the first incorrect byte
1257 expectedData << "... ";
1258 actualData << "... ";
1265 for (size_t i = 0; i < maxBytesLogged && byteNdx < expected.size; i++, byteNdx++)
1267 expectedData << (i > 0 ? ", " : "") << (deUint32)expected.data[byteNdx];
1268 actualData << (i > 0 ? ", " : "") << (deUint32)actual.data[byteNdx];
1271 if (expected.size > byteNdx)
1273 expectedData << "...";
1274 actualData << "...";
1277 log << TestLog::Message << "Expected data: (" << expectedData.str() << ")" << TestLog::EndMessage;
1278 log << TestLog::Message << "Actual data: (" << actualData.str() << ")" << TestLog::EndMessage;
1280 m_resultCollector.fail("Memory contents don't match");
1284 catch (const tcu::NotSupportedError& error)
1286 log << TestLog::Message << "Not supported: " << error.getMessage() << TestLog::EndMessage;
1288 catch (const tcu::TestError& error)
1290 m_resultCollector.fail(std::string("Exception: ") + error.getMessage());
1293 // Move to next queue
1297 if (m_queueBNdx >= m_queueFamiliesB.size())
1301 if (m_queueANdx >= m_queueFamiliesA.size())
1303 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1309 return tcu::TestStatus::incomplete();
1313 return tcu::TestStatus::incomplete();
1319 void init (vk::SourceCollections& dst, TestConfig config) const
1321 const de::UniquePtr<OperationSupport> readOp (makeOperationSupport(config.readOp, config.resource));
1322 const de::UniquePtr<OperationSupport> writeOp (makeOperationSupport(config.writeOp, config.resource));
1324 readOp->initPrograms(dst);
1325 writeOp->initPrograms(dst);
1331 static void createTests (tcu::TestCaseGroup* group)
1333 tcu::TestContext& testCtx = group->getTestContext();
1336 vk::VkExternalMemoryHandleTypeFlagBits memoryType;
1337 vk::VkExternalSemaphoreHandleTypeFlagBits semaphoreType;
1338 const char* nameSuffix;
1342 vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
1343 vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
1347 vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
1348 vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
1352 vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
1353 vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
1357 vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
1358 vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
1363 for (size_t dedicatedNdx = 0; dedicatedNdx < 2; dedicatedNdx++)
1365 const bool dedicated (dedicatedNdx == 1);
1366 de::MovePtr<tcu::TestCaseGroup> dedicatedGroup (new tcu::TestCaseGroup(testCtx, dedicated ? "dedicated" : "suballocated", ""));
1368 for (size_t writeOpNdx = 0; writeOpNdx < DE_LENGTH_OF_ARRAY(s_writeOps); ++writeOpNdx)
1369 for (size_t readOpNdx = 0; readOpNdx < DE_LENGTH_OF_ARRAY(s_readOps); ++readOpNdx)
1371 const OperationName writeOp = s_writeOps[writeOpNdx];
1372 const OperationName readOp = s_readOps[readOpNdx];
1373 const std::string opGroupName = getOperationName(writeOp) + "_" + getOperationName(readOp);
1376 de::MovePtr<tcu::TestCaseGroup> opGroup (new tcu::TestCaseGroup(testCtx, opGroupName.c_str(), ""));
1378 for (size_t resourceNdx = 0; resourceNdx < DE_LENGTH_OF_ARRAY(s_resources); ++resourceNdx)
1380 const ResourceDescription& resource = s_resources[resourceNdx];
1382 for (size_t caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
1384 if (isResourceSupported(writeOp, resource) && isResourceSupported(readOp, resource))
1386 const TestConfig config (resource, writeOp, readOp, cases[caseNdx].memoryType, cases[caseNdx].semaphoreType, dedicated);
1387 std::string name = getResourceName(resource) + cases[caseNdx].nameSuffix;
1389 opGroup->addChild(new InstanceFactory1<SharingTestInstance, TestConfig, Progs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, "", Progs(), config));
1396 dedicatedGroup->addChild(opGroup.release());
1399 group->addChild(dedicatedGroup.release());
1403 static void cleanupGroup (tcu::TestCaseGroup* group)
1406 // Destroy singleton object
1407 InstanceAndDevice::destroy();
1410 tcu::TestCaseGroup* createCrossInstanceSharingTest (tcu::TestContext& testCtx)
1412 return createTestGroup(testCtx, "cross_instance", "", createTests, cleanupGroup);
1415 } // synchronization