Fix memory commitment tests for devices with no lazily allocated memory
authorRicardo Garcia <rgarcia@igalia.com>
Fri, 21 Jun 2019 09:30:02 +0000 (11:30 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Wed, 3 Jul 2019 09:37:26 +0000 (05:37 -0400)
Make every memory commitment test fail with NotSupportedError when the
physical device does not support lazily allocated memory.

In addition, check memoryTypeCount and memoryHeapCount in every call to
getPhysicalDeviceMemoryProperties so as to be able to iterate safely
over the result later.

Affected tests:
dEQP-VK.api.get_memory_commitment.*

Components: Framework, Vulkan
VK-GL-CTS issue: 1841

Change-Id: I527eb9176cb7450fbb7acccae94478e27159da79

external/vulkancts/framework/vulkan/vkQueryUtil.cpp
external/vulkancts/modules/vulkan/api/vktApiGetMemoryCommitment.cpp

index 690fdf1..717d889 100644 (file)
@@ -29,6 +29,7 @@
 #include "deSTLUtil.hpp"
 
 #include <vector>
+#include <sstream>
 
 namespace vk
 {
@@ -171,6 +172,23 @@ VkPhysicalDeviceMemoryProperties getPhysicalDeviceMemoryProperties (const Instan
        deMemset(&properties, 0, sizeof(properties));
 
        vk.getPhysicalDeviceMemoryProperties(physicalDevice, &properties);
+
+       if (properties.memoryTypeCount > VK_MAX_MEMORY_TYPES)
+       {
+               std::ostringstream msg;
+               msg << "Invalid memoryTypeCount in VkPhysicalDeviceMemoryProperties (got " << properties.memoryTypeCount
+                       << ", max " << VK_MAX_MEMORY_TYPES << ")";
+               TCU_FAIL(msg.str());
+       }
+
+       if (properties.memoryHeapCount > VK_MAX_MEMORY_HEAPS)
+       {
+               std::ostringstream msg;
+               msg << "Invalid memoryHeapCount in VkPhysicalDeviceMemoryProperties (got " << properties.memoryHeapCount
+                       << ", max " << VK_MAX_MEMORY_HEAPS << ")";
+               TCU_FAIL(msg.str());
+       }
+
        return properties;
 }
 
index 0bfe1f3..ff22d09 100644 (file)
@@ -52,12 +52,27 @@ struct MemoryCommitmentCaseParams
        deUint32        elementOffset;
 };
 
+namespace
+{
+
+std::vector<deUint32> getMemoryTypeIndices (VkMemoryPropertyFlags propertyFlag, const VkPhysicalDeviceMemoryProperties& pMemoryProperties)
+{
+       std::vector<deUint32> indices;
+       for (deUint32 typeIndex = 0u; typeIndex < pMemoryProperties.memoryTypeCount; ++typeIndex)
+       {
+               if ((pMemoryProperties.memoryTypes[typeIndex].propertyFlags & propertyFlag) == propertyFlag)
+                       indices.push_back(typeIndex);
+       }
+       return indices;
+}
+
+}
+
 class MemoryCommitmentTestInstance : public vkt::TestInstance
 {
 public:
                                                                        MemoryCommitmentTestInstance    (Context& context, MemoryCommitmentCaseParams testCase);
        tcu::TestStatus                                 iterate                                                 (void);
-       deUint32                                                getMemoryTypeIndex                              (VkMemoryPropertyFlags propertyFlag, VkPhysicalDeviceMemoryProperties pMemoryProperties);
        Move<VkCommandPool>                             createCommandPool                               () const;
        Move<VkCommandBuffer>                   allocatePrimaryCommandBuffer    (VkCommandPool commandPool) const;
        bool                                                    isDeviceMemoryCommitmentOk              (const VkMemoryRequirements memoryRequirements);
@@ -98,7 +113,7 @@ tcu::TestStatus MemoryCommitmentTestInstance::iterate(void)
        const VkPhysicalDevice                                  physicalDevice                  = m_context.getPhysicalDevice();
        const InstanceInterface&                                vki                                             = m_context.getInstanceInterface();
        const VkPhysicalDeviceMemoryProperties  pMemoryProperties               = getPhysicalDeviceMemoryProperties(vki,physicalDevice);
-       const deUint32                                                  memoryTypeIndex                 = getMemoryTypeIndex(propertyFlag, pMemoryProperties);
+       const std::vector<deUint32>                             memoryTypeIndices               = getMemoryTypeIndices(propertyFlag, pMemoryProperties);
        Allocator&                                                              memAlloc                                = m_context.getDefaultAllocator();
        bool                                                                    isMemoryAllocationOK    = false;
        const deUint32                                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
@@ -116,8 +131,9 @@ tcu::TestStatus MemoryCommitmentTestInstance::iterate(void)
        Move<VkShaderModule>                                    fragmentShaderModule;
        Move<VkPipeline>                                                graphicsPipelines;
 
-       if (memoryTypeIndex == static_cast<deUint32>(-1))
-               TCU_THROW(NotSupportedError, "Lazily allocated bit is not supported");
+       // Note we can still fail later if none of lazily allocated memory types can be used with the image below.
+       if (memoryTypeIndices.empty())
+               TCU_THROW(NotSupportedError, "Lazily allocated bit is not supported by any memory type");
 
        const VkImageCreateInfo imageParams                     =
        {
@@ -368,58 +384,48 @@ tcu::TestStatus MemoryCommitmentAllocateOnlyTestInstance::iterate(void)
        const DeviceInterface&                                  vkd                                             = m_context.getDeviceInterface();
        const VkPhysicalDeviceMemoryProperties  pMemoryProperties               = getPhysicalDeviceMemoryProperties(vki,physicalDevice);
        const VkMemoryPropertyFlags                             propertyFlag                    = VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
+       const std::vector<deUint32>                             memoryTypeIndices               = getMemoryTypeIndices(propertyFlag, pMemoryProperties);
        const int                                                               arrayLength                             = 10;
        VkDeviceSize                                                    pCommittedMemoryInBytes = 0u;
        VkDeviceSize                                                    allocSize[arrayLength];
 
+       if (memoryTypeIndices.empty())
+               TCU_THROW(NotSupportedError, "Lazily allocated bit is not supported by any memory type");
+
        // generating random allocation sizes
        for (int i = 0; i < arrayLength; ++i)
        {
                allocSize[i] = rand() % 1000 + 1;
        }
 
-       for (deUint32 memoryTypeIndex = 0u; memoryTypeIndex < VK_MAX_MEMORY_TYPES; ++memoryTypeIndex) //for memoryTypes
+       for (const auto memoryTypeIndex : memoryTypeIndices)
        {
-               if((pMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & propertyFlag) == propertyFlag) //if supports Lazy allocation
+               for (int i = 0; i < arrayLength; ++i)
                {
-                       for (int i = 0; i < arrayLength; ++i)
+                       const VkMemoryAllocateInfo      memAllocInfo =
                        {
-                               const VkMemoryAllocateInfo      memAllocInfo =
-                               {
-                                       VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, //      VkStructureType         sType
-                                       NULL,                                                                   //      const void*                     pNext
-                                       allocSize[i],                                                   //      VkDeviceSize            allocationSize
-                                       memoryTypeIndex                                                 //      deUint32                        memoryTypeIndex
-                               };
-
-                               Move<VkDeviceMemory> memory = allocateMemory(vkd, device, &memAllocInfo, (const VkAllocationCallbacks*)DE_NULL);
-
-                               vkd.getDeviceMemoryCommitment(device, memory.get(), &pCommittedMemoryInBytes);
-                               if(pCommittedMemoryInBytes != 0)
-                               {
-                                       tcu::TestLog& log = m_context.getTestContext().getLog();
-                                       log << TestLog::Message << "Warning: Memory commitment not null before binding." << TestLog::EndMessage;
-                               }
-                               if(pCommittedMemoryInBytes > allocSize[i])
-                                       return tcu::TestStatus::fail("Fail");
+                               VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, //      VkStructureType         sType
+                               NULL,                                                                   //      const void*                     pNext
+                               allocSize[i],                                                   //      VkDeviceSize            allocationSize
+                               memoryTypeIndex                                                 //      deUint32                        memoryTypeIndex
+                       };
+
+                       Move<VkDeviceMemory> memory = allocateMemory(vkd, device, &memAllocInfo, (const VkAllocationCallbacks*)DE_NULL);
 
+                       vkd.getDeviceMemoryCommitment(device, memory.get(), &pCommittedMemoryInBytes);
+                       if(pCommittedMemoryInBytes != 0)
+                       {
+                               tcu::TestLog& log = m_context.getTestContext().getLog();
+                               log << TestLog::Message << "Warning: Memory commitment not null before binding." << TestLog::EndMessage;
                        }
+                       if(pCommittedMemoryInBytes > allocSize[i])
+                               return tcu::TestStatus::fail("Fail");
+
                }
        }
        return tcu::TestStatus::pass("Pass");
 }
 
-deUint32 MemoryCommitmentTestInstance::getMemoryTypeIndex(VkMemoryPropertyFlags propertyFlag, VkPhysicalDeviceMemoryProperties pMemoryProperties)
-{
-       for (deUint32 memoryTypeIndex = 0u; memoryTypeIndex < VK_MAX_MEMORY_TYPES; ++memoryTypeIndex)
-       {
-               if((pMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & propertyFlag) == propertyFlag)
-                       return memoryTypeIndex;
-       }
-
-       return static_cast<deUint32>(-1);
-}
-
 void MemoryCommitmentTestCase::initPrograms (SourceCollections& programCollection) const
 {
        programCollection.glslSources.add("vert") << glu::VertexSource(