Fix 32-bit statistic query tests using 64 bits
authorRicardo Garcia <rgarcia@igalia.com>
Fri, 14 Feb 2020 12:37:43 +0000 (13:37 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Tue, 3 Mar 2020 11:43:53 +0000 (06:43 -0500)
This commit fixes the 32/64-bit split in the statistics query group that
tried to use vkGetQueryPoolResults with different bit widths but were
actually always using 64-bits.

Note: the intermediate reset results that are copied to a buffer in some
tests always use the 64-bit flag. This is expected.

Affected tests:
dEQP-VK.query_pool.statistics_query.*

Components: Vulkan
VK-GL-CTS issue: 2215

Change-Id: Ib73ae9fbd8fbaf1ec9195090e20ec4392dc62444

external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp

index 08bb2d2..da4cd0e 100644 (file)
@@ -125,8 +125,10 @@ std::string outputTypeToGLString (const VkPrimitiveTopology& outputType)
        }
 }
 
+using Pair32                                           = pair<deUint32, deUint32>;
+using Pair64                                           = pair<deUint64, deUint64>;
 using ResultsVector                                    = vector<deUint64>;
-using ResultsVectorWithAvailability    = vector<pair<deUint64, deUint64>>;
+using ResultsVectorWithAvailability    = vector<Pair64>;
 
 // Get query pool results as a vector. Note results are always converted to
 // deUint64, but the actual vkGetQueryPoolResults call will use the 64-bits flag
@@ -150,9 +152,15 @@ vk::VkResult GetQueryPoolResultsVector(
        {
                using IntermediateVector = vector<deUint32>;
 
-               IntermediateVector      intermediate(queryCount, 0u);
+               IntermediateVector      intermediate(queryCount);
+
+               // Try to preserve existing data if possible.
+               std::transform(begin(output), end(output), begin(intermediate), [](deUint64 v) { return static_cast<deUint32>(v); });
+
                constexpr size_t        stride          = sizeof(decltype(intermediate)::value_type);
                const size_t            totalSize       = stride * intermediate.size();
+
+               // Get and copy results.
                result = vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, intermediate.data(), stride, flags);
                std::copy(begin(intermediate), end(intermediate), begin(output));
        }
@@ -178,19 +186,40 @@ vk::VkResult GetQueryPoolResultsVector(
        }
        else
        {
-               using IntermediateVector = vector<pair<deUint32, deUint32>>;
+               using IntermediateVector = vector<Pair32>;
+
+               IntermediateVector      intermediate(queryCount);
+
+               // Try to preserve existing output data if possible.
+               std::transform(begin(output), end(output), begin(intermediate), [](const Pair64& p) { return Pair32{static_cast<deUint32>(p.first), static_cast<deUint32>(p.second)}; });
 
-               IntermediateVector      intermediate(queryCount, pair<deUint32, deUint32>(0u, 0u));
                constexpr size_t        stride          = sizeof(decltype(intermediate)::value_type);
                const size_t            totalSize       = stride * intermediate.size();
+
+               // Get and copy.
                result = vk.getQueryPoolResults(device, queryPool, firstQuery, queryCount, totalSize, intermediate.data(), stride, flags);
-               std::transform(begin(intermediate), end(intermediate), begin(output),
-                       [](const pair<deUint32, deUint32>& p) { return pair<deUint64, deUint64>(p.first, p.second); });
+               std::transform(begin(intermediate), end(intermediate), begin(output), [](const Pair32& p) { return Pair64{p.first, p.second}; });
        }
 
        return result;
 }
 
+// Generic parameters structure.
+struct GenericParameters
+{
+       ResetType       resetType;
+       deBool          query64Bits;
+
+       GenericParameters (ResetType resetType_, deBool query64Bits_)
+               : resetType{resetType_}, query64Bits{query64Bits_}
+               {}
+
+       VkQueryResultFlags querySizeFlags () const
+       {
+               return (query64Bits ? static_cast<VkQueryResultFlags>(vk::VK_QUERY_RESULT_64_BIT) : 0u);
+       }
+};
+
 void beginSecondaryCommandBuffer (const DeviceInterface&                               vk,
                                                                  const VkCommandBuffer                                 commandBuffer,
                                                                  const VkQueryPipelineStatisticFlags   queryFlags,
@@ -351,21 +380,18 @@ tcu::TestStatus   StatisticQueryTestInstance::verifyUnavailable ()
 class ComputeInvocationsTestInstance : public StatisticQueryTestInstance
 {
 public:
-       struct ParametersCompute
+       struct ParametersCompute : public GenericParameters
        {
-               ParametersCompute(const tcu::UVec3& localSize_, const tcu::UVec3& groupSize_, const std::string& shaderName_, ResetType resetType_, deBool query64Bits_)
-                       : localSize(localSize_)
+               ParametersCompute (const tcu::UVec3& localSize_, const tcu::UVec3& groupSize_, const std::string& shaderName_, ResetType resetType_, deBool query64Bits_)
+                       : GenericParameters{resetType_, query64Bits_}
+                       , localSize(localSize_)
                        , groupSize(groupSize_)
                        , shaderName(shaderName_)
-                       , resetType(resetType_)
-                       , query64Bits(query64Bits_)
                        {}
 
                tcu::UVec3      localSize;
                tcu::UVec3      groupSize;
                std::string     shaderName;
-               ResetType       resetType;
-               deBool          query64Bits;
        };
                                                        ComputeInvocationsTestInstance          (Context& context, const std::vector<ParametersCompute>& parameters);
        tcu::TestStatus                 iterate                                                         (void);
@@ -531,21 +557,21 @@ tcu::TestStatus ComputeInvocationsTestInstance::executeTest (const VkCommandPool
                if (m_parameters[0].resetType == RESET_TYPE_NORMAL)
                {
                        ResultsVector data;
-                       VK_CHECK(GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT)));
+                       VK_CHECK(GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags())));
                        if (getComputeExecution(m_parameters[parametersNdx]) != data[0])
                                return tcu::TestStatus::fail("QueryPoolResults incorrect");
                }
                else if (m_parameters[0].resetType == RESET_TYPE_HOST)
                {
                        ResultsVectorWithAvailability data;
-                       VK_CHECK(GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
+                       VK_CHECK(GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
                        if (getComputeExecution(m_parameters[parametersNdx]) != data[0].first || data[0].second == 0)
                                return tcu::TestStatus::fail("QueryPoolResults incorrect");
 
                        deUint64 temp = data[0].first;
 
                        vk.resetQueryPool(device, *queryPool, 0, 1u);
-                       vk::VkResult res = GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
+                       vk::VkResult res = GetQueryPoolResultsVector(data, vk, device, *queryPool, 0u, 1u, (m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
                        /* From Vulkan spec:
                         *
                         * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
@@ -717,21 +743,21 @@ tcu::TestStatus ComputeInvocationsSecondaryTestInstance::checkResult (const de::
                if (m_parameters[0].resetType == RESET_TYPE_NORMAL)
                {
                        ResultsVector results;
-                       VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT)));
+                       VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags())));
                        if (expected != results[0])
                                return tcu::TestStatus::fail("QueryPoolResults incorrect");
                }
                else if (m_parameters[0].resetType == RESET_TYPE_HOST)
                {
                        ResultsVectorWithAvailability results;
-                       VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
+                       VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (VK_QUERY_RESULT_WAIT_BIT | m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
                        if (expected != results[0].first || results[0].second == 0u)
                                return tcu::TestStatus::fail("QueryPoolResults incorrect");
 
                        deUint64 temp = results[0].first;
 
                        vk.resetQueryPool(device, queryPool, 0u, 1u);
-                       vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
+                       vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, 1u, (m_parameters[0].querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
                        /* From Vulkan spec:
                         *
                         * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
@@ -925,19 +951,18 @@ public:
                tcu::Vec4       position;
                tcu::Vec4       color;
        };
-       struct  ParametersGraphic
+
+       struct ParametersGraphic : public GenericParameters
        {
-                       ParametersGraphic (const VkQueryPipelineStatisticFlags queryStatisticFlags_, const VkPrimitiveTopology primitiveTopology_, const ResetType resetType_, const deBool query64Bits_, const deBool vertexOnlyPipe_ = DE_FALSE)
-                       : queryStatisticFlags   (queryStatisticFlags_)
+               ParametersGraphic (const VkQueryPipelineStatisticFlags queryStatisticFlags_, const VkPrimitiveTopology primitiveTopology_, const ResetType resetType_, const deBool query64Bits_, const deBool vertexOnlyPipe_ = DE_FALSE)
+                       : GenericParameters             {resetType_, query64Bits_}
+                       , queryStatisticFlags   (queryStatisticFlags_)
                        , primitiveTopology             (primitiveTopology_)
-                       , resetType                             (resetType_)
-                       , query64Bits                   (query64Bits_)
                        , vertexOnlyPipe                (vertexOnlyPipe_)
-               {}
+                       {}
+
                VkQueryPipelineStatisticFlags   queryStatisticFlags;
                VkPrimitiveTopology                             primitiveTopology;
-               ResetType                                               resetType;
-               deBool                                                  query64Bits;
                deBool                                                  vertexOnlyPipe;
        };
                                                                                        GraphicBasicTestInstance                        (vkt::Context&                                  context,
@@ -1350,7 +1375,7 @@ tcu::TestStatus VertexShaderTestInstance::checkResult (VkQueryPool queryPool)
        if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL)
        {
                ResultsVector results(queryCount, 0u);
-               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT)));
+               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
                if (results[0] < expectedMin)
                        return tcu::TestStatus::fail("QueryPoolResults incorrect");
                if (queryCount > 1)
@@ -1363,7 +1388,7 @@ tcu::TestStatus VertexShaderTestInstance::checkResult (VkQueryPool queryPool)
        else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
        {
                ResultsVectorWithAvailability results(queryCount, pair<deUint64, deUint64>(0u,0u));
-               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
+               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
                if (results[0].first < expectedMin || results[0].second == 0)
                        return tcu::TestStatus::fail("QueryPoolResults incorrect");
 
@@ -1377,7 +1402,7 @@ tcu::TestStatus VertexShaderTestInstance::checkResult (VkQueryPool queryPool)
                deUint64 temp = results[0].first;
 
                vk.resetQueryPool(device, queryPool, 0, queryCount);
-               vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
+               vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
                /* From Vulkan spec:
                 *
                 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
@@ -1816,7 +1841,7 @@ tcu::TestStatus GeometryShaderTestInstance::checkResult (VkQueryPool queryPool)
        if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL)
        {
                ResultsVector results(queryCount, 0u);
-               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT)));
+               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
                if (results[0] < expectedMin)
                        return tcu::TestStatus::fail("QueryPoolResults incorrect");
                if (queryCount > 1)
@@ -1829,7 +1854,7 @@ tcu::TestStatus GeometryShaderTestInstance::checkResult (VkQueryPool queryPool)
        else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
        {
                ResultsVectorWithAvailability results(queryCount, pair<deUint64, deUint64>(0u, 0u));
-               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
+               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
                if (results[0].first < expectedMin || results[0].second == 0u)
                        return tcu::TestStatus::fail("QueryPoolResults incorrect");
 
@@ -1843,7 +1868,7 @@ tcu::TestStatus GeometryShaderTestInstance::checkResult (VkQueryPool queryPool)
                deUint64 temp = results[0].first;
 
                vk.resetQueryPool(device, queryPool, 0, queryCount);
-               vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
+               vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
                /* From Vulkan spec:
                 *
                 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
@@ -2244,7 +2269,7 @@ tcu::TestStatus TessellationShaderTestInstance::checkResult (VkQueryPool queryPo
        if (m_parametersGraphic.resetType == RESET_TYPE_NORMAL)
        {
                ResultsVector results(queryCount, 0u);
-               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT)));
+               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags())));
                if (results[0] < expectedMin)
                        return tcu::TestStatus::fail("QueryPoolResults incorrect");
                if (queryCount > 1)
@@ -2260,7 +2285,7 @@ tcu::TestStatus TessellationShaderTestInstance::checkResult (VkQueryPool queryPo
        else if (m_parametersGraphic.resetType == RESET_TYPE_HOST)
        {
                ResultsVectorWithAvailability results(queryCount, pair<deUint64,deUint64>(0u,0u));
-               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
+               VK_CHECK(GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_WAIT_BIT | m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)));
                if (results[0].first < expectedMin || results[0].second == 0u)
                        return tcu::TestStatus::fail("QueryPoolResults incorrect");
 
@@ -2274,7 +2299,7 @@ tcu::TestStatus TessellationShaderTestInstance::checkResult (VkQueryPool queryPo
                deUint64 temp = results[0].first;
 
                vk.resetQueryPool(device, queryPool, 0, queryCount);
-               vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
+               vk::VkResult res = GetQueryPoolResultsVector(results, vk, device, queryPool, 0u, queryCount, (m_parametersGraphic.querySizeFlags() | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
                /* From Vulkan spec:
                 *
                 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData