Check required peer memory features in sparse resources device group tests
authorMaciej Jesionowski <maciej.jesionowski@amd.com>
Fri, 29 Jun 2018 09:52:54 +0000 (11:52 +0200)
committerMaciej Jesionowski <maciej.jesionowski@amd.com>
Mon, 2 Jul 2018 10:33:45 +0000 (12:33 +0200)
This is a minimal fix to these cases to not use the memory in unsupported way.
The tests will return NotSupported if the required features are missing.

Affects:
dEQP-VK.sparse_resources.*device_group*

VK-GL-CTS issue: 1252

Components: Vulkan

Change-Id: Ia55509eef39c30e2283ba41d87ce55294edf6a17

external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferMemoryAliasing.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseBinding.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseResidency.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferTests.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseResidency.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp

index 31660c4..a7d81ad 100644 (file)
@@ -225,11 +225,24 @@ tcu::TestStatus BufferSparseMemoryAliasingInstance::iterate (void)
 
                DE_ASSERT((bufferMemRequirements.size % bufferMemRequirements.alignment) == 0);
 
-               const deUint32 memoryType = findMatchingMemoryType(instance, physicalDevice, bufferMemRequirements, MemoryRequirement::Any);
+               const deUint32 memoryType = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), bufferMemRequirements, MemoryRequirement::Any);
 
                if (memoryType == NO_MATCH_FOUND)
                        return tcu::TestStatus::fail("No matching memory type found");
 
+               if (firstDeviceID != secondDeviceID)
+               {
+                       VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                       const deUint32                          heapIndex = getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
+                       deviceInterface.getDeviceGroupPeerMemoryFeatures(getDevice(), heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                       if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT)    == 0) ||
+                               ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT) == 0))
+                       {
+                               TCU_THROW(NotSupportedError, "Peer memory does not support COPY_SRC and GENERIC_DST");
+                       }
+               }
+
                const VkSparseMemoryBind sparseMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(), bufferMemRequirements.size, memoryType, 0u);
 
                Move<VkDeviceMemory> deviceMemoryPtr(check<VkDeviceMemory>(sparseMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL));
index 623ab6f..b645af5 100644 (file)
@@ -168,11 +168,24 @@ tcu::TestStatus BufferSparseBindingInstance::iterate (void)
                {
                        std::vector<VkSparseMemoryBind> sparseMemoryBinds;
                        const deUint32                                  numSparseBinds = static_cast<deUint32>(bufferMemRequirement.size / bufferMemRequirement.alignment);
-                       const deUint32                                  memoryType         = findMatchingMemoryType(instance, physicalDevice, bufferMemRequirement, MemoryRequirement::Any);
+                       const deUint32                                  memoryType         = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), bufferMemRequirement, MemoryRequirement::Any);
 
                        if (memoryType == NO_MATCH_FOUND)
                                return tcu::TestStatus::fail("No matching memory type found");
 
+                       if (firstDeviceID != secondDeviceID)
+                       {
+                               VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                               const deUint32                          heapIndex = getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
+                               deviceInterface.getDeviceGroupPeerMemoryFeatures(getDevice(), heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                               if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT) == 0) ||
+                                       ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_DST_BIT) == 0))
+                               {
+                                       TCU_THROW(NotSupportedError, "Peer memory does not support COPY_SRC and COPY_DST");
+                               }
+                       }
+
                        {
                                const VkMemoryAllocateInfo allocateInfo =
                                {
index 4f7f486..a4de1be 100644 (file)
@@ -133,15 +133,13 @@ public:
 
 private:
        const deUint32  m_bufferSize;
-       const deUint32  m_useDeviceGroups;
 };
 
 BufferSparseResidencyInstance::BufferSparseResidencyInstance (Context&                 context,
                                                                                                                          const deUint32        bufferSize,
                                                                                                                          const bool            useDeviceGroups)
-       : SparseResourcesBaseInstance   (context)
+       : SparseResourcesBaseInstance   (context, useDeviceGroups)
        , m_bufferSize                                  (bufferSize)
-       , m_useDeviceGroups                             (useDeviceGroups)
 {
 }
 
@@ -213,11 +211,24 @@ tcu::TestStatus BufferSparseResidencyInstance::iterate (void)
 
                {
                        std::vector<VkSparseMemoryBind>         sparseMemoryBinds;
-                       const deUint32                                          memoryType              = findMatchingMemoryType(instance, physicalDevice, bufferMemRequirements, MemoryRequirement::Any);
+                       const deUint32                                          memoryType              = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), bufferMemRequirements, MemoryRequirement::Any);
 
                        if (memoryType == NO_MATCH_FOUND)
                                return tcu::TestStatus::fail("No matching memory type found");
 
+                       if (firstDeviceID != secondDeviceID)
+                       {
+                               VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                               const deUint32                          heapIndex = getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
+                               deviceInterface.getDeviceGroupPeerMemoryFeatures(getDevice(), heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                               if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT)    == 0) ||
+                                       ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT) == 0))
+                               {
+                                       TCU_THROW(NotSupportedError, "Peer memory does not support COPY_SRC and GENERIC_DST");
+                               }
+                       }
+
                        for (deUint32 sparseBindNdx = 0; sparseBindNdx < numSparseSlots; sparseBindNdx += 2)
                        {
                                const VkSparseMemoryBind sparseMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(), bufferMemRequirements.alignment, memoryType, bufferMemRequirements.alignment * sparseBindNdx);
@@ -239,7 +250,7 @@ tcu::TestStatus BufferSparseResidencyInstance::iterate (void)
                        const VkBindSparseInfo bindSparseInfo =
                        {
                                VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,                                             //VkStructureType                                                       sType;
-                               m_useDeviceGroups ? &devGroupBindSparseInfo : DE_NULL,  //const void*                                                           pNext;
+                               usingDeviceGroups() ? &devGroupBindSparseInfo : DE_NULL,//const void*                                                           pNext;
                                0u,                                                                                                             //deUint32                                                                      waitSemaphoreCount;
                                DE_NULL,                                                                                                //const VkSemaphore*                                            pWaitSemaphores;
                                1u,                                                                                                             //deUint32                                                                      bufferBindCount;
@@ -366,7 +377,7 @@ tcu::TestStatus BufferSparseResidencyInstance::iterate (void)
 
                // Submit transfer commands for execution and wait for completion
                submitCommandsAndWait(deviceInterface, getDevice(), computeQueue.queueHandle, *commandBuffer, 1u, &bufferMemoryBindSemaphore.get(),
-                       waitStageBits, 0, DE_NULL, m_useDeviceGroups, firstDeviceID);
+                       waitStageBits, 0, DE_NULL, usingDeviceGroups(), firstDeviceID);
 
                // Retrieve data from output buffer to host memory
                invalidateMappedMemoryRange(deviceInterface, getDevice(), outputBufferAlloc->getMemory(), outputBufferAlloc->getOffset(), m_bufferSize);
index 58e20e0..bb545b3 100644 (file)
@@ -89,6 +89,8 @@ struct SparseAllocation
        VkDeviceSize                                            resourceSize;           //!< buffer size in bytes
        std::vector<AllocationSp>                       allocations;            //!< actual allocated memory
        std::vector<VkSparseMemoryBind>         memoryBinds;            //!< memory binds backing the resource
+       deUint32                                                        memoryType;                     //!< memory type (same for all allocations)
+       deUint32                                                        heapIndex;                      //!< memory heap index
 };
 
 //! Utility to lay out memory allocations for a sparse buffer, including holes and aliased regions.
@@ -106,7 +108,9 @@ public:
        SparseAllocationBuilder&        addAliasedMemoryBind    (const deUint32 allocationNdx, const deUint32 chunkOffset, const deUint32 numChunks = 1u);
        SparseAllocationBuilder&        addMemoryAllocation             (void);
 
-       MovePtr<SparseAllocation>       build                                   (const DeviceInterface&         vk,
+       MovePtr<SparseAllocation>       build                                   (const InstanceInterface&       instanceInterface,
+                                                                                                                const VkPhysicalDevice         physicalDevice,
+                                                                                                                const DeviceInterface&         vk,
                                                                                                                 const VkDevice                         device,
                                                                                                                 Allocator&                                     allocator,
                                                                                                                 VkBufferCreateInfo                     referenceCreateInfo,            //!< buffer size is ignored in this info
@@ -199,17 +203,13 @@ SparseAllocationBuilder& SparseAllocationBuilder::addAliasedMemoryBind    (const de
        return *this;
 }
 
-inline VkMemoryRequirements requirementsWithSize (VkMemoryRequirements requirements, const VkDeviceSize size)
-{
-       requirements.size = size;
-       return requirements;
-}
-
-MovePtr<SparseAllocation> SparseAllocationBuilder::build (const DeviceInterface&       vk,
-                                                                                                                 const VkDevice                        device,
-                                                                                                                 Allocator&                            allocator,
-                                                                                                                 VkBufferCreateInfo            referenceCreateInfo,
-                                                                                                                 const VkDeviceSize            minChunkSize) const
+MovePtr<SparseAllocation> SparseAllocationBuilder::build (const InstanceInterface&                     instanceInterface,
+                                                                                                                 const VkPhysicalDevice                        physicalDevice,
+                                                                                                                 const DeviceInterface&                        vk,
+                                                                                                                 const VkDevice                                        device,
+                                                                                                                 Allocator&                                            allocator,
+                                                                                                                 VkBufferCreateInfo                            referenceCreateInfo,
+                                                                                                                 const VkDeviceSize                            minChunkSize) const
 {
 
        MovePtr<SparseAllocation>       sparseAllocation                        (new SparseAllocation());
@@ -218,11 +218,19 @@ MovePtr<SparseAllocation> SparseAllocationBuilder::build (const DeviceInterface&
        const Unique<VkBuffer>          refBuffer                                       (createBuffer(vk, device, &referenceCreateInfo));
        const VkMemoryRequirements      memoryRequirements                      = getBufferMemoryRequirements(vk, device, *refBuffer);
        const VkDeviceSize                      chunkSize                                       = std::max(memoryRequirements.alignment, static_cast<VkDeviceSize>(deAlign64(minChunkSize, memoryRequirements.alignment)));
+       const deUint32                          memoryTypeNdx                           = findMatchingMemoryType(instanceInterface, physicalDevice, memoryRequirements, MemoryRequirement::Any);
+       VkMemoryAllocateInfo            allocInfo                                       =
+       {
+               VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, //      VkStructureType                 sType;
+               DE_NULL,                                                                //      const void*                             pNext;
+               memoryRequirements.size,                                //      VkDeviceSize                    allocationSize;
+               memoryTypeNdx,                                                  //      deUint32                                memoryTypeIndex;
+       };
 
        for (std::vector<deUint32>::const_iterator numChunksIter = m_chunksPerAllocation.begin(); numChunksIter != m_chunksPerAllocation.end(); ++numChunksIter)
        {
-               sparseAllocation->allocations.push_back(makeDeSharedPtr(
-                       allocator.allocate(requirementsWithSize(memoryRequirements, *numChunksIter * chunkSize), MemoryRequirement::Any)));
+               allocInfo.allocationSize = *numChunksIter * chunkSize;
+               sparseAllocation->allocations.push_back(makeDeSharedPtr(allocator.allocate(allocInfo, (VkDeviceSize)0)));
        }
 
        for (std::vector<MemoryBind>::const_iterator memBindIter = m_memoryBinds.begin(); memBindIter != m_memoryBinds.end(); ++memBindIter)
@@ -242,6 +250,8 @@ MovePtr<SparseAllocation> SparseAllocationBuilder::build (const DeviceInterface&
 
        sparseAllocation->resourceSize          = referenceCreateInfo.size;
        sparseAllocation->numResourceChunks = m_resourceChunkNdx;
+       sparseAllocation->memoryType            = memoryTypeNdx;
+       sparseAllocation->heapIndex                     = getHeapIndexForMemoryType(instanceInterface, physicalDevice, memoryTypeNdx);
 
        return sparseAllocation;
 }
@@ -964,6 +974,7 @@ public:
 
        tcu::TestStatus iterate (void)
        {
+               const InstanceInterface&        instance                        = m_context.getInstanceInterface();
                const DeviceInterface&          vk                                      = getDeviceInterface();
                MovePtr<SparseAllocation>       sparseAllocation;
                Move<VkBuffer>                          sparseBuffer;
@@ -986,7 +997,7 @@ public:
                                {
                                        const UniquePtr<SparseAllocation> minAllocation(SparseAllocationBuilder()
                                                .addMemoryBind()
-                                               .build(vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize));
+                                               .build(instance, getPhysicalDevice(secondDeviceID), vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize));
 
                                        numMaxChunks = deMaxu32(static_cast<deUint32>(m_context.getDeviceProperties().limits.maxUniformBufferRange / minAllocation->resourceSize), 1u);
                                }
@@ -995,7 +1006,7 @@ public:
                                {
                                        sparseAllocation = SparseAllocationBuilder()
                                                .addMemoryBind()
-                                               .build(vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize);
+                                               .build(instance, getPhysicalDevice(secondDeviceID), vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize);
                                }
                                else
                                {
@@ -1014,10 +1025,22 @@ public:
                                        if (m_aliased)
                                                builder.addAliasedMemoryBind(0u, 0u);
 
-                                       sparseAllocation = builder.build(vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize);
+                                       sparseAllocation = builder.build(instance, getPhysicalDevice(secondDeviceID), vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize);
                                        DE_ASSERT(sparseAllocation->resourceSize <= m_context.getDeviceProperties().limits.maxUniformBufferRange);
                                }
 
+                               if (firstDeviceID != secondDeviceID)
+                               {
+                                       VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                                       vk.getDeviceGroupPeerMemoryFeatures(getDevice(), sparseAllocation->heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                                       if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_DST_BIT)    == 0) ||
+                                               ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT) == 0))
+                                       {
+                                               TCU_THROW(NotSupportedError, "Peer memory does not support COPY_DST and GENERIC_SRC");
+                                       }
+                               }
+
                                // Create the buffer
                                referenceBufferCreateInfo.size  = sparseAllocation->resourceSize;
                                sparseBuffer                                    = makeBuffer(vk, getDevice(), referenceBufferCreateInfo);
@@ -1244,9 +1267,16 @@ class DrawGridTestInstance : public SparseBufferTestInstance
 public:
        DrawGridTestInstance (Context& context, const TestFlags flags, const VkBufferUsageFlags usage, const VkDeviceSize minChunkSize)
                : SparseBufferTestInstance      (context, flags)
+               , m_bufferUsage                         (usage)
+               , m_minChunkSize                        (minChunkSize)
+       {
+       }
+
+       void createResources (deUint32 memoryDeviceIndex)
        {
-               const DeviceInterface&  vk                                                      = getDeviceInterface();
-               VkBufferCreateInfo              referenceBufferCreateInfo       = getSparseBufferCreateInfo(usage);
+               const InstanceInterface&        instance                                        = m_context.getInstanceInterface();
+               const DeviceInterface&          vk                                                      = getDeviceInterface();
+               VkBufferCreateInfo                      referenceBufferCreateInfo       = getSparseBufferCreateInfo(m_bufferUsage);
 
                {
                        // Allocate two chunks, each covering half of the viewport
@@ -1264,20 +1294,17 @@ public:
                        if (m_aliased)
                                builder.addAliasedMemoryBind(0u, 0u);
 
-                       m_sparseAllocation      = builder.build(vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize);
+                       m_sparseAllocation      = builder.build(instance, getPhysicalDevice(memoryDeviceIndex), vk, getDevice(), getAllocator(), referenceBufferCreateInfo, m_minChunkSize);
                }
 
                // Create the buffer
                referenceBufferCreateInfo.size  = m_sparseAllocation->resourceSize;
                m_sparseBuffer                                  = makeBuffer(vk, getDevice(), referenceBufferCreateInfo);
 
-
                m_perDrawBufferOffset   = m_sparseAllocation->resourceSize / m_sparseAllocation->numResourceChunks;
                m_stagingBufferSize             = 2 * m_perDrawBufferOffset;
                m_stagingBuffer                 = makeBuffer(vk, getDevice(), makeBufferCreateInfo(m_stagingBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
                m_stagingBufferAlloc    = bindBuffer(vk, getDevice(), getAllocator(), *m_stagingBuffer, MemoryRequirement::HostVisible);
-
-
        }
 
        tcu::TestStatus iterate (void)
@@ -1289,6 +1316,20 @@ public:
                        const deUint32  firstDeviceID   = physDevID;
                        const deUint32  secondDeviceID  = (firstDeviceID + 1) % m_numPhysicalDevices;
 
+                       createResources(secondDeviceID);
+
+                       if (firstDeviceID != secondDeviceID)
+                       {
+                               VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                               vk.getDeviceGroupPeerMemoryFeatures(getDevice(), m_sparseAllocation->heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                               if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_DST_BIT)    == 0) ||
+                                       ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT) == 0))
+                               {
+                                       TCU_THROW(NotSupportedError, "Peer memory does not support COPY_DST and GENERIC_SRC");
+                               }
+                       }
+
                        // Bind the memory
                        bindSparseBuffer(vk, getDevice(), m_sparseQueue.queueHandle, *m_sparseBuffer, *m_sparseAllocation, usingDeviceGroups(), firstDeviceID, secondDeviceID);
 
@@ -1344,6 +1385,9 @@ public:
 protected:
        virtual void                            initializeBuffers               (void) = 0;
 
+       const VkBufferUsageFlags        m_bufferUsage;
+       const VkDeviceSize                      m_minChunkSize;
+
        VkDeviceSize                            m_perDrawBufferOffset;
 
        VkDeviceSize                            m_stagingBufferSize;
index 5662d4b..246bf08 100644 (file)
@@ -276,7 +276,7 @@ tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void)
                        const VkMemoryRequirements imageMemoryRequirements = getImageMemoryRequirements(deviceInterface, getDevice(), *imageRead);
 
                        // Check if required image memory size does not exceed device limits
-                       if (imageMemoryRequirements.size > getPhysicalDeviceProperties(instance, physicalDevice).limits.sparseAddressSpaceSize)
+                       if (imageMemoryRequirements.size > getPhysicalDeviceProperties(instance, getPhysicalDevice(secondDeviceID)).limits.sparseAddressSpaceSize)
                                TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits");
 
                        DE_ASSERT((imageMemoryRequirements.size % imageMemoryRequirements.alignment) == 0);
@@ -298,11 +298,25 @@ tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void)
 
                        DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
 
-                       const deUint32 memoryType = findMatchingMemoryType(instance, physicalDevice, imageMemoryRequirements, MemoryRequirement::Any);
+                       const deUint32 memoryType = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageMemoryRequirements, MemoryRequirement::Any);
 
                        if (memoryType == NO_MATCH_FOUND)
                                return tcu::TestStatus::fail("No matching memory type found");
 
+                       if (firstDeviceID != secondDeviceID)
+                       {
+                               VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                               const deUint32                          heapIndex = getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
+                               deviceInterface.getDeviceGroupPeerMemoryFeatures(getDevice(), heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                               if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT)    == 0) ||
+                                       ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_DST_BIT)    == 0) ||
+                                       ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT) == 0))
+                               {
+                                       TCU_THROW(NotSupportedError, "Peer memory does not support COPY_SRC, COPY_DST, and GENERIC_DST");
+                               }
+                       }
+
                        // Bind memory for each layer
                        for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
                        {
index 77968a6..123bb1a 100644 (file)
@@ -199,7 +199,7 @@ tcu::TestStatus ImageSparseBindingInstance::iterate (void)
                const VkMemoryRequirements imageSparseMemRequirements = getImageMemoryRequirements(deviceInterface, getDevice(), *imageSparse);
 
                // Check if required image memory size does not exceed device limits
-               if (imageSparseMemRequirements.size > getPhysicalDeviceProperties(instance, physicalDevice).limits.sparseAddressSpaceSize)
+               if (imageSparseMemRequirements.size > getPhysicalDeviceProperties(instance, getPhysicalDevice(secondDeviceID)).limits.sparseAddressSpaceSize)
                        TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits");
 
                DE_ASSERT((imageSparseMemRequirements.size % imageSparseMemRequirements.alignment) == 0);
@@ -207,11 +207,24 @@ tcu::TestStatus ImageSparseBindingInstance::iterate (void)
                {
                        std::vector<VkSparseMemoryBind> sparseMemoryBinds;
                        const deUint32                                  numSparseBinds  = static_cast<deUint32>(imageSparseMemRequirements.size / imageSparseMemRequirements.alignment);
-                       const deUint32                                  memoryType              = findMatchingMemoryType(instance, physicalDevice, imageSparseMemRequirements, MemoryRequirement::Any);
+                       const deUint32                                  memoryType              = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageSparseMemRequirements, MemoryRequirement::Any);
 
                        if (memoryType == NO_MATCH_FOUND)
                                return tcu::TestStatus::fail("No matching memory type found");
 
+                       if (firstDeviceID != secondDeviceID)
+                       {
+                               VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                               const deUint32                          heapIndex = getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
+                               deviceInterface.getDeviceGroupPeerMemoryFeatures(getDevice(), heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                               if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT) == 0) ||
+                                       ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_DST_BIT) == 0))
+                               {
+                                       TCU_THROW(NotSupportedError, "Peer memory does not support COPY_SRC and COPY_DST");
+                               }
+                       }
+
                        for (deUint32 sparseBindNdx = 0; sparseBindNdx < numSparseBinds; ++sparseBindNdx)
                        {
                                const VkSparseMemoryBind sparseMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(),
index ac24d9b..184832a 100644 (file)
@@ -303,11 +303,24 @@ tcu::TestStatus ImageSparseResidencyInstance::iterate (void)
                        std::vector<VkSparseImageMemoryBind> imageResidencyMemoryBinds;
                        std::vector<VkSparseMemoryBind>          imageMipTailMemoryBinds;
 
-                       const deUint32                                           memoryType = findMatchingMemoryType(instance, physicalDevice, imageMemoryRequirements, MemoryRequirement::Any);
+                       const deUint32                                           memoryType = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageMemoryRequirements, MemoryRequirement::Any);
 
                        if (memoryType == NO_MATCH_FOUND)
                                return tcu::TestStatus::fail("No matching memory type found");
 
+                       if (firstDeviceID != secondDeviceID)
+                       {
+                               VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                               const deUint32                          heapIndex = getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
+                               deviceInterface.getDeviceGroupPeerMemoryFeatures(getDevice(), heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                               if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT)    == 0) ||
+                                       ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT) == 0))
+                               {
+                                       TCU_THROW(NotSupportedError, "Peer memory does not support COPY_SRC and GENERIC_DST");
+                               }
+                       }
+
                        // Bind device memory for each aspect
                        for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
                        {
index d96089b..093572f 100644 (file)
@@ -239,11 +239,24 @@ tcu::TestStatus MipmapSparseResidencyInstance::iterate (void)
                        std::vector<VkSparseImageMemoryBind>    imageResidencyMemoryBinds;
                        std::vector<VkSparseMemoryBind>                 imageMipTailMemoryBinds;
 
-                       const deUint32                                                  memoryType = findMatchingMemoryType(instance, physicalDevice, imageMemoryRequirements, MemoryRequirement::Any);
+                       const deUint32                                                  memoryType = findMatchingMemoryType(instance, getPhysicalDevice(secondDeviceID), imageMemoryRequirements, MemoryRequirement::Any);
 
                        if (memoryType == NO_MATCH_FOUND)
                                return tcu::TestStatus::fail("No matching memory type found");
 
+                       if (firstDeviceID != secondDeviceID)
+                       {
+                               VkPeerMemoryFeatureFlags        peerMemoryFeatureFlags = (VkPeerMemoryFeatureFlags)0;
+                               const deUint32                          heapIndex = getHeapIndexForMemoryType(instance, getPhysicalDevice(secondDeviceID), memoryType);
+                               deviceInterface.getDeviceGroupPeerMemoryFeatures(getDevice(), heapIndex, firstDeviceID, secondDeviceID, &peerMemoryFeatureFlags);
+
+                               if (((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT) == 0) ||
+                                       ((peerMemoryFeatureFlags & VK_PEER_MEMORY_FEATURE_COPY_DST_BIT) == 0))
+                               {
+                                       TCU_THROW(NotSupportedError, "Peer memory does not support COPY_SRC and COPY_DST");
+                               }
+                       }
+
                        // Bind memory for each layer
                        for (deUint32 layerNdx = 0; layerNdx < imageSparseInfo.arrayLayers; ++layerNdx)
                        {
index 9770767..5ccb6d6 100644 (file)
@@ -904,6 +904,15 @@ deUint32 findMatchingMemoryType (const InstanceInterface&          instance,
        return NO_MATCH_FOUND;
 }
 
+deUint32 getHeapIndexForMemoryType (const InstanceInterface&   instance,
+                                                                       const VkPhysicalDevice          physicalDevice,
+                                                                       const deUint32                          memoryType)
+{
+       const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
+       DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
+       return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
+}
+
 bool checkSparseSupportForImageType (const InstanceInterface&  instance,
                                                                         const VkPhysicalDevice         physicalDevice,
                                                                         const ImageType                        imageType)
index b1aaa26..d72b8c2 100644 (file)
@@ -281,6 +281,10 @@ deUint32                                           findMatchingMemoryType                          (const vk::InstanceInterface&           instance,
                                                                                                                                         const vk::VkMemoryRequirements&        objectMemoryRequirements,
                                                                                                                                         const vk::MemoryRequirement&           memoryRequirement);
 
+deUint32                                               getHeapIndexForMemoryType                       (const vk::InstanceInterface&           instance,
+                                                                                                                                        const vk::VkPhysicalDevice                     physicalDevice,
+                                                                                                                                        const deUint32                                         memoryType);
+
 bool                                                   checkSparseSupportForImageType          (const vk::InstanceInterface&           instance,
                                                                                                                                         const vk::VkPhysicalDevice                     physicalDevice,
                                                                                                                                         const ImageType                                        imageType);