Bugfix: Allow UBO sparse allocation larger than maxUniformBufferRange
authorMaciej Jesionowski <maciej.jesionowski@mobica.com>
Thu, 12 Jan 2017 12:42:45 +0000 (13:42 +0100)
committerPyry Haulos <phaulos@google.com>
Fri, 13 Jan 2017 20:19:31 +0000 (15:19 -0500)
Modified tests:
- dEQP-VK.sparse_resources.buffer.ubo.*

Fixes #573

Change-Id: I33d2098d5b6b783fa8293c7cb1af7e782b51df77

external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferTests.cpp

index f1ae906..fc9e7ee 100644 (file)
@@ -740,7 +740,6 @@ public:
                , m_aliased                                             ((flags & TEST_FLAG_ALIASED)   != 0)
                , m_residency                                   ((flags & TEST_FLAG_RESIDENCY) != 0)
                , m_nonResidentStrict                   ((flags & TEST_FLAG_NON_RESIDENT_STRICT) != 0)
-               , m_deviceProperties                    (getPhysicalDeviceProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()))
                , m_renderSize                                  (RENDER_SIZE, RENDER_SIZE)
                , m_colorFormat                                 (VK_FORMAT_R8G8B8A8_UNORM)
                , m_colorBufferSize                             (m_renderSize.x() * m_renderSize.y() * tcu::getPixelSize(mapVkFormat(m_colorFormat)))
@@ -756,7 +755,7 @@ public:
                if (m_aliased && !features.sparseResidencyAliased)
                        TCU_THROW(NotSupportedError, "Missing feature: sparseResidencyAliased");
 
-               if (m_nonResidentStrict && !m_deviceProperties.sparseProperties.residencyNonResidentStrict)
+               if (m_nonResidentStrict && !m_context.getDeviceProperties().sparseProperties.residencyNonResidentStrict)
                        TCU_THROW(NotSupportedError, "Missing sparse property: residencyNonResidentStrict");
 
                {
@@ -841,7 +840,6 @@ protected:
        const bool                                                      m_aliased;
        const bool                                                      m_residency;
        const bool                                                      m_nonResidentStrict;
-       const VkPhysicalDeviceProperties        m_deviceProperties;
 
        Queue                                                           m_sparseQueue;
        Queue                                                           m_universalQueue;
@@ -977,10 +975,7 @@ public:
                                        .addMemoryBind()
                                        .build(vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize));
 
-                               if (minAllocation->resourceSize > m_deviceProperties.limits.maxUniformBufferRange)
-                                       return tcu::TestStatus::fail("The smallest sparse UBO size exceeds maxUniformBufferRange limit");
-
-                               numMaxChunks = static_cast<deUint32>(m_deviceProperties.limits.maxUniformBufferRange / minAllocation->resourceSize);
+                               numMaxChunks = deMaxu32(static_cast<deUint32>(m_context.getDeviceProperties().limits.maxUniformBufferRange / minAllocation->resourceSize), 1u);
                        }
 
                        if (numMaxChunks < 4)
@@ -1007,7 +1002,7 @@ public:
                                        builder.addAliasedMemoryBind(0u, 0u);
 
                                sparseAllocation = builder.build(vk, getDevice(), getAllocator(), referenceBufferCreateInfo, minChunkSize);
-                               DE_ASSERT(sparseAllocation->resourceSize <= m_deviceProperties.limits.maxUniformBufferRange);
+                               DE_ASSERT(sparseAllocation->resourceSize <= m_context.getDeviceProperties().limits.maxUniformBufferRange);
                        }
 
                        // Create the buffer
@@ -1059,6 +1054,9 @@ public:
                        }
                }
 
+               // Make sure that we don't try to access a larger range than is allowed. This only applies to a single chunk case.
+               const deUint32 maxBufferRange = deMinu32(static_cast<deUint32>(sparseAllocation->resourceSize), m_context.getDeviceProperties().limits.maxUniformBufferRange);
+
                // Descriptor sets
                {
                        m_descriptorSetLayout = DescriptorSetLayoutBuilder()
@@ -1072,7 +1070,7 @@ public:
                        m_descriptorSet = makeDescriptorSet(vk, getDevice(), *m_descriptorPool, *m_descriptorSetLayout);
 
                        const VkBuffer                                  buffer                          = (m_aliased ? *sparseBufferAliased : *sparseBuffer);
-                       const VkDescriptorBufferInfo    sparseBufferInfo        = makeDescriptorBufferInfo(buffer, 0ull, sparseAllocation->resourceSize);
+                       const VkDescriptorBufferInfo    sparseBufferInfo        = makeDescriptorBufferInfo(buffer, 0ull, maxBufferRange);
 
                        DescriptorSetUpdateBuilder()
                                .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &sparseBufferInfo)
@@ -1102,7 +1100,7 @@ public:
                {
                        std::vector<deInt32> specializationData;
                        {
-                               const deUint32  numBufferEntries        = static_cast<deUint32>(sparseAllocation->resourceSize / sizeof(IVec4));
+                               const deUint32  numBufferEntries        = maxBufferRange / static_cast<deUint32>(sizeof(IVec4));
                                const deUint32  numEntriesPerChunk      = numBufferEntries / sparseAllocation->numResourceChunks;
 
                                specializationData.push_back(numBufferEntries);