Merge in bugfixes from Khronos repository
authorJeannot Breton <jbreton@nvidia.com>
Mon, 21 Mar 2016 17:49:51 +0000 (17:49 +0000)
committerandroid-build-merger <android-build-merger@google.com>
Mon, 21 Mar 2016 17:49:51 +0000 (17:49 +0000)
am: 45cb571

* commit '45cb57100923ca89c36455f832398557d4877ff8':
  clamp allocation size based on heap size
  dEQP-VK.spirv_assembly.instruction.compute.*: avoid platform-dependent rounding in tests for OpCopyObjectGroup, OpPhiGroup, SelectionControlGroup and FunctionControlGroup.
  Add new --deqp-log-flush command line option

external/vulkancts/README.md
external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
framework/common/tcuCommandLine.cpp
framework/common/tcuTestHierarchyUtil.cpp
framework/qphelper/qpTestLog.c
framework/qphelper/qpTestLog.h
framework/qphelper/qpXmlWriter.c
framework/qphelper/qpXmlWriter.h

index 65561e9..7985148 100644 (file)
@@ -134,6 +134,11 @@ can be selected with:
 
        --deqp-vk-device-id=<value>
 
+To speed up the conformance run on some platforms the following command line
+option may be used to disable frequent fflush() calls to the output logs:
+
+       --deqp-log-flush=disable
+
 No other command line options are allowed.
 
 ### Win32
index 6b36cce..f4dc86e 100644 (file)
@@ -50,6 +50,8 @@ namespace api
 namespace
 {
 
+static const deUint32  MAX_BUFFER_SIZE_DIVISOR = 16;
+
 struct BufferCaseParameters
 {
        VkBufferUsageFlags      usage;
@@ -97,16 +99,19 @@ private:
 
  tcu::TestStatus BufferTestInstance::bufferCreateAndAllocTest (VkDeviceSize size)
 {
-       const VkDevice                  vkDevice                        = m_context.getDevice();
-       const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
-       Move<VkBuffer>                  testBuffer;
-       VkMemoryRequirements    memReqs;
-       Move<VkDeviceMemory>    memory;
-       const deUint32                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
+       const VkPhysicalDevice          vkPhysicalDevice        = m_context.getPhysicalDevice();
+       const InstanceInterface&        vkInstance                      = m_context.getInstanceInterface();
+       const VkDevice                          vkDevice                        = m_context.getDevice();
+       const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
+       Move<VkBuffer>                          testBuffer;
+       VkMemoryRequirements            memReqs;
+       Move<VkDeviceMemory>            memory;
+       const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
+       const VkPhysicalDeviceMemoryProperties  memoryProperties = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice);
 
        // Create buffer
        {
-               const VkBufferCreateInfo                bufferParams            =
+               VkBufferCreateInfo              bufferParams            =
                {
                        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
                        DE_NULL,
@@ -120,7 +125,7 @@ private:
 
                try
                {
-                       testBuffer = createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
+                       testBuffer = createBuffer(vk, vkDevice, &bufferParams);
                }
                catch (const vk::Error& error)
                {
@@ -129,6 +134,27 @@ private:
 
                vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
 
+               const deUint32          heapTypeIndex   = (deUint32)deCtz32(memReqs.memoryTypeBits);
+               const VkMemoryType      memoryType              = memoryProperties.memoryTypes[heapTypeIndex];
+               const VkMemoryHeap      memoryHeap              = memoryProperties.memoryHeaps[memoryType.heapIndex];
+               const VkDeviceSize      maxBufferSize   = memoryHeap.size / MAX_BUFFER_SIZE_DIVISOR;
+               // If the requested size is too large, clamp it based on the selected heap size
+               if (size > maxBufferSize)
+               {
+                       size = maxBufferSize;
+                       bufferParams.size = size;
+                       try
+                       {
+                               // allocate a new buffer with the adjusted size, the old one will be destroyed by the smart pointer
+                               testBuffer = createBuffer(vk, vkDevice, &bufferParams);
+                       }
+                       catch (const vk::Error& error)
+                       {
+                               return tcu::TestStatus::fail("Buffer creation failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")");
+                       }
+                       vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
+               }
+
                if (size > memReqs.size)
                {
                        std::ostringstream errorMsg;
@@ -250,14 +276,10 @@ tcu::TestStatus BufferTestInstance::iterate (void)
        {
                const VkPhysicalDevice                                  vkPhysicalDevice        = m_context.getPhysicalDevice();
                const InstanceInterface&                                vkInstance                      = m_context.getInstanceInterface();
-               const VkPhysicalDeviceMemoryProperties  memoryProperties        = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice);
                VkPhysicalDeviceProperties      props;
 
                vkInstance.getPhysicalDeviceProperties(vkPhysicalDevice, &props);
-
-               const VkDeviceSize maxTestBufferSize = de::min((VkDeviceSize) props.limits.maxTexelBufferElements, memoryProperties.memoryHeaps[memoryProperties.memoryTypes[0].heapIndex].size / 16);
-
-               testStatus = bufferCreateAndAllocTest(maxTestBufferSize);
+               testStatus = bufferCreateAndAllocTest((VkDeviceSize) props.limits.maxTexelBufferElements);
        }
 
        return testStatus;
index 6e6426c..0e731a2 100644 (file)
@@ -101,6 +101,18 @@ static void fillRandomScalars (de::Random& rnd, T minValue, T maxValue, void* ds
                typedPtr[offset + ndx] = randomScalar<T>(rnd, minValue, maxValue);
 }
 
+static void floorAll (vector<float>& values)
+{
+       for (size_t i = 0; i < values.size(); i++)
+               values[i] = deFloatFloor(values[i]);
+}
+
+static void floorAll (vector<Vec4>& values)
+{
+       for (size_t i = 0; i < values.size(); i++)
+               values[i] = floor(values[i]);
+}
+
 struct CaseParameter
 {
        const char*             name;
@@ -571,6 +583,9 @@ tcu::TestCaseGroup* createOpCopyMemoryGroup (tcu::TestContext& testCtx)
 
        fillRandomScalars(rnd, -200.f, 200.f, &inputFloats1[0], numElements * 4);
 
+       // CPU might not use the same rounding mode as the GPU. Use whole numbers to avoid rounding differences.
+       floorAll(inputFloats1);
+
        for (size_t ndx = 0; ndx < numElements; ++ndx)
                outputFloats1[ndx] = inputFloats1[ndx] + Vec4(0.f, 0.5f, 1.5f, 2.5f);
 
@@ -777,6 +792,9 @@ tcu::TestCaseGroup* createOpCopyObjectGroup (tcu::TestContext& testCtx)
 
        fillRandomScalars(rnd, -200.f, 200.f, &inputFloats[0], numElements);
 
+       // CPU might not use the same rounding mode as the GPU. Use whole numbers to avoid rounding differences.
+       floorAll(inputFloats);
+
        for (size_t ndx = 0; ndx < numElements; ++ndx)
                outputFloats[ndx] = inputFloats[ndx] + 7.5f;
 
@@ -1037,15 +1055,12 @@ tcu::TestCaseGroup* createDecorationGroupGroup (tcu::TestContext& testCtx)
        fillRandomScalars(rnd, -300.f, 300.f, &inputFloats3[0], numElements);
        fillRandomScalars(rnd, -300.f, 300.f, &inputFloats4[0], numElements);
 
-
-       for (size_t ndx = 0; ndx < numElements; ++ndx)
-       {
-               inputFloats0[ndx] = deFloatFloor(inputFloats0[ndx]);
-               inputFloats1[ndx] = deFloatFloor(inputFloats1[ndx]);
-               inputFloats2[ndx] = deFloatFloor(inputFloats2[ndx]);
-               inputFloats3[ndx] = deFloatFloor(inputFloats3[ndx]);
-               inputFloats4[ndx] = deFloatFloor(inputFloats4[ndx]);
-       }
+       // CPU might not use the same rounding mode as the GPU. Use whole numbers to avoid rounding differences.
+       floorAll(inputFloats0);
+       floorAll(inputFloats1);
+       floorAll(inputFloats2);
+       floorAll(inputFloats3);
+       floorAll(inputFloats4);
 
        for (size_t ndx = 0; ndx < numElements; ++ndx)
                outputFloats[ndx] = inputFloats0[ndx] + inputFloats1[ndx] + inputFloats2[ndx] + inputFloats3[ndx] + inputFloats4[ndx];
@@ -1396,6 +1411,9 @@ tcu::TestCaseGroup* createOpPhiGroup (tcu::TestContext& testCtx)
 
        fillRandomScalars(rnd, -300.f, 300.f, &inputFloats[0], numElements);
 
+       // CPU might not use the same rounding mode as the GPU. Use whole numbers to avoid rounding differences.
+       floorAll(inputFloats);
+
        for (size_t ndx = 0; ndx < numElements; ++ndx)
        {
                switch (ndx % 3)
@@ -1598,8 +1616,8 @@ tcu::TestCaseGroup* createBlockOrderGroup (tcu::TestContext& testCtx)
 
        fillRandomScalars(rnd, -100.f, 100.f, &inputFloats[0], numElements);
 
-       for (size_t ndx = 0; ndx < numElements; ++ndx)
-               inputFloats[ndx] = deFloatFloor(inputFloats[ndx]);
+       // CPU might not use the same rounding mode as the GPU. Use whole numbers to avoid rounding differences.
+       floorAll(inputFloats);
 
        for (size_t ndx = 0; ndx <= 50; ++ndx)
                outputFloats[ndx] = -inputFloats[ndx];
@@ -2928,6 +2946,9 @@ tcu::TestCaseGroup* createSelectionControlGroup (tcu::TestContext& testCtx)
 
        fillRandomScalars(rnd, -100.f, 100.f, &inputFloats[0], numElements);
 
+       // CPU might not use the same rounding mode as the GPU. Use whole numbers to avoid rounding differences.
+       floorAll(inputFloats);
+
        for (size_t ndx = 0; ndx < numElements; ++ndx)
                outputFloats[ndx] = inputFloats[ndx] + (inputFloats[ndx] > 10.f ? 1.f : -1.f);
 
@@ -3020,6 +3041,9 @@ tcu::TestCaseGroup* createFunctionControlGroup (tcu::TestContext& testCtx)
 
        fillRandomScalars(rnd, -100.f, 100.f, &inputFloats[0], numElements);
 
+       // CPU might not use the same rounding mode as the GPU. Use whole numbers to avoid rounding differences.
+       floorAll(inputFloats);
+
        for (size_t ndx = 0; ndx < numElements; ++ndx)
                outputFloats[ndx] = inputFloats[ndx] + 10.f;
 
index b41ef7b..ba267d5 100644 (file)
@@ -84,6 +84,7 @@ DE_DECLARE_COMMAND_LINE_OPT(LogImages,                                        bool);
 DE_DECLARE_COMMAND_LINE_OPT(LogShaderSources,                  bool);
 DE_DECLARE_COMMAND_LINE_OPT(TestOOM,                                   bool);
 DE_DECLARE_COMMAND_LINE_OPT(VKDeviceID,                                        int);
+DE_DECLARE_COMMAND_LINE_OPT(LogFlush,                                  bool);
 
 static void parseIntList (const char* src, std::vector<int>* dst)
 {
@@ -168,7 +169,8 @@ void registerOptions (de::cmdline::Parser& parser)
                << Option<VKDeviceID>                   (DE_NULL,       "deqp-vk-device-id",                    "Vulkan device ID (IDs start from 1)",                                                                  "1")
                << Option<LogImages>                    (DE_NULL,       "deqp-log-images",                              "Enable or disable logging of result images",           s_enableNames,          "enable")
                << Option<LogShaderSources>             (DE_NULL,       "deqp-log-shader-sources",              "Enable or disable logging of shader sources",          s_enableNames,          "enable")
-               << Option<TestOOM>                              (DE_NULL,       "deqp-test-oom",                                "Run tests that exhaust memory on purpose",                     s_enableNames,          TEST_OOM_DEFAULT);
+               << Option<TestOOM>                              (DE_NULL,       "deqp-test-oom",                                "Run tests that exhaust memory on purpose",                     s_enableNames,          TEST_OOM_DEFAULT)
+               << Option<LogFlush>             (DE_NULL,   "deqp-log-flush",               "Enable or disable log file fflush",                s_enableNames,      "enable");
 }
 
 void registerLegacyOptions (de::cmdline::Parser& parser)
@@ -725,6 +727,9 @@ bool CommandLine::parse (int argc, const char* const* argv)
        if (!m_cmdLine.getOption<opt::LogShaderSources>())
                m_logFlags |= QP_TEST_LOG_EXCLUDE_SHADER_SOURCES;
 
+       if (!m_cmdLine.getOption<opt::LogFlush>())
+               m_logFlags |= QP_TEST_LOG_NO_FLUSH;
+
        if ((m_cmdLine.hasOption<opt::CasePath>()?1:0) +
                (m_cmdLine.hasOption<opt::CaseList>()?1:0) +
                (m_cmdLine.hasOption<opt::CaseListFile>()?1:0) +
index dc21619..34882eb 100644 (file)
@@ -146,7 +146,7 @@ void writeXmlCaselistsToFiles (TestPackageRoot& root, TestContext& testCtx, cons
                        if (!file)
                                throw Exception("Failed to open " + filename);
 
-                       writer = qpXmlWriter_createFileWriter(file, DE_FALSE);
+                       writer = qpXmlWriter_createFileWriter(file, DE_FALSE, DE_FALSE);
                        if (!writer)
                                throw Exception("XML writer creation failed");
 
index 26c7923..327e232 100644 (file)
@@ -350,7 +350,7 @@ qpTestLog* qpTestLog_createFileLog (const char* fileName, deUint32 flags)
        }
 
        log->flags                      = flags;
-       log->writer                     = qpXmlWriter_createFileWriter(log->outputFile, 0);
+       log->writer                     = qpXmlWriter_createFileWriter(log->outputFile, 0, !(flags & QP_TEST_LOG_NO_FLUSH));
        log->lock                       = deMutex_create(DE_NULL);
        log->isSessionOpen      = DE_FALSE;
        log->isCaseOpen         = DE_FALSE;
@@ -419,7 +419,8 @@ deBool qpTestLog_startCase (qpTestLog* log, const char* testCasePath, qpTestCase
        /* Flush XML and write out #beginTestCaseResult. */
        qpXmlWriter_flush(log->writer);
        fprintf(log->outputFile, "\n#beginTestCaseResult %s\n", testCasePath);
-       qpTestLog_flushFile(log);
+       if (!(log->flags & QP_TEST_LOG_NO_FLUSH))
+               qpTestLog_flushFile(log);
 
        log->isCaseOpen = DE_TRUE;
 
@@ -473,7 +474,8 @@ deBool qpTestLog_endCase (qpTestLog* log, qpTestResult result, const char* resul
        /* Flush XML and write #endTestCaseResult. */
        qpXmlWriter_flush(log->writer);
        fprintf(log->outputFile, "\n#endTestCaseResult\n");
-       qpTestLog_flushFile(log);
+       if (!(log->flags & QP_TEST_LOG_NO_FLUSH))
+               qpTestLog_flushFile(log);
 
        log->isCaseOpen = DE_FALSE;
 
index aa74fa7..f12454f 100644 (file)
@@ -133,7 +133,8 @@ typedef enum qpImageFormat_e
 typedef enum qpTestLogFlag_e
 {
        QP_TEST_LOG_EXCLUDE_IMAGES                      = (1<<0),               /*!< Do not log images. This reduces log size considerably.                     */
-       QP_TEST_LOG_EXCLUDE_SHADER_SOURCES      = (1<<1)                /*!< Do not log shader sources. Helps to reduce log size further.       */
+       QP_TEST_LOG_EXCLUDE_SHADER_SOURCES      = (1<<1),               /*!< Do not log shader sources. Helps to reduce log size further.       */
+       QP_TEST_LOG_NO_FLUSH                            = (1<<2)                /*!< Do not do a fflush after writing the log.                                          */
 } qpTestLogFlag;
 
 /* Shader type. */
index 6921dab..97ee987 100644 (file)
@@ -36,6 +36,7 @@
 struct qpXmlWriter_s
 {
        FILE*                           outputFile;
+       deBool                          flushAfterWrite;
 
        deBool                          xmlPrevIsStartElement;
        deBool                          xmlIsWriting;
@@ -114,12 +115,13 @@ static deBool writeEscaped (qpXmlWriter* writer, const char* str)
                }
        } while (!isEOS);
 
-       fflush(writer->outputFile);
+       if (writer->flushAfterWrite)
+               fflush(writer->outputFile);
        DE_ASSERT(d == &buf[0]); /* buffer must be empty */
        return DE_TRUE;
 }
 
-qpXmlWriter* qpXmlWriter_createFileWriter (FILE* outputFile, deBool useCompression)
+qpXmlWriter* qpXmlWriter_createFileWriter (FILE* outputFile, deBool useCompression, deBool flushAfterWrite)
 {
        qpXmlWriter* writer = (qpXmlWriter*)deCalloc(sizeof(qpXmlWriter));
        if (!writer)
@@ -128,6 +130,7 @@ qpXmlWriter* qpXmlWriter_createFileWriter (FILE* outputFile, deBool useCompressi
        DE_UNREF(useCompression); /* no compression supported. */
 
        writer->outputFile = outputFile;
+       writer->flushAfterWrite = flushAfterWrite;
 
        return writer;
 }
index ebba428..bb63bde 100644 (file)
@@ -85,9 +85,10 @@ DE_INLINE qpXmlAttribute qpSetBoolAttrib (const char* name, deBool value)
  * \brief Create a file based XML Writer instance
  * \param fileName Name of the file
  * \param useCompression Set to DE_TRUE to use compression, if supported by implementation
+ * \param flushAfterWrite Set to DE_TRUE to call fflush after writing each XML token
  * \return qpXmlWriter instance, or DE_NULL if cannot create file
  *//*--------------------------------------------------------------------*/
-qpXmlWriter*   qpXmlWriter_createFileWriter (FILE* outFile, deBool useCompression);
+qpXmlWriter*   qpXmlWriter_createFileWriter (FILE* outFile, deBool useCompression, deBool flushAfterWrite);
 
 /*--------------------------------------------------------------------*//*!
  * \brief XML Writer instance