Half-float texture interpolation tolerance is too small.
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / texture / vktTextureFilteringExplicitLodTests.cpp
index 495ec58..979103e 100644 (file)
@@ -50,6 +50,7 @@
 #include "deMath.h"
 #include "deStringUtil.hpp"
 #include "deUniquePtr.hpp"
+#include "deSharedPtr.hpp"
 
 #include <sstream>
 #include <string>
@@ -67,87 +68,46 @@ using std::string;
 namespace
 {
 
-tcu::FloatFormat getConversionPrecision (VkFormat format)
+std::vector<de::SharedPtr<tcu::FloatFormat>> getPrecision (VkFormat format, int fpPrecisionDelta)
 {
-       const tcu::FloatFormat  reallyLow       (0, 0, 8, false, tcu::YES);
-       const tcu::FloatFormat  fp16            (-14, 15, 10, false);
-       const tcu::FloatFormat  fp32            (-126, 127, 23, true);
+       std::vector<de::SharedPtr<tcu::FloatFormat>>    floatFormats;
+       de::SharedPtr<tcu::FloatFormat>                                 fp16                    (new tcu::FloatFormat(-14, 15, std::max(0, 10 + fpPrecisionDelta), false, tcu::YES));
+       de::SharedPtr<tcu::FloatFormat>                                 fp32                    (new tcu::FloatFormat(-126, 127, std::max(0, 23 + fpPrecisionDelta), true));
+       const tcu::TextureFormat                                                tcuFormat               = mapVkFormat(format);
+       const tcu::TextureChannelClass                                  channelClass    = tcu::getTextureChannelClass(tcuFormat.type);
+       const tcu::IVec4                                                                channelDepth    = tcu::getTextureFormatBitDepth(tcuFormat);
 
-       switch (format)
+       for (int channelIdx = 0; channelIdx < 4; channelIdx++)
        {
-           case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
-               case VK_FORMAT_R5G6B5_UNORM_PACK16:
-               case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
-                       return reallyLow;
-
-               case VK_FORMAT_R8_UNORM:
-               case VK_FORMAT_R8_SNORM:
-               case VK_FORMAT_R8G8_UNORM:
-               case VK_FORMAT_R8G8_SNORM:
-               case VK_FORMAT_R8G8B8A8_UNORM:
-               case VK_FORMAT_R8G8B8A8_SNORM:
-               case VK_FORMAT_B8G8R8A8_UNORM:
-               case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
-               case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
-               case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
-                       return fp16;
-
-               case VK_FORMAT_R16_SFLOAT:
-               case VK_FORMAT_R16G16_SFLOAT:
-               case VK_FORMAT_R16G16B16A16_SFLOAT:
-                       return fp16;
-
-               case VK_FORMAT_R32_SFLOAT:
-               case VK_FORMAT_R32G32_SFLOAT:
-               case VK_FORMAT_R32G32B32A32_SFLOAT:
-                       return fp32;
-
-               default:
-                       DE_FATAL("Precision not defined for format");
-                       return fp32;
-       }
-}
+               switch(channelClass)
+               {
+                       case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+                               floatFormats.push_back(de::SharedPtr<tcu::FloatFormat>(new tcu::NormalizedFormat(std::max(0,channelDepth[channelIdx] + fpPrecisionDelta - 1))));
+                               break;
 
-tcu::FloatFormat getFilteringPrecision (VkFormat format)
-{
-       const tcu::FloatFormat  reallyLow       (0, 0, 6, false, tcu::YES);
-       const tcu::FloatFormat  low                     (0, 0, 7, false, tcu::YES);
-       const tcu::FloatFormat  fp16            (-14, 15, 10, false);
-       const tcu::FloatFormat  fp32            (-126, 127, 23, true);
+                       case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+                               floatFormats.push_back(de::SharedPtr<tcu::FloatFormat>(new tcu::NormalizedFormat(std::max(0,channelDepth[channelIdx] + fpPrecisionDelta))));
+                               break;
 
-       switch (format)
-       {
-           case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
-               case VK_FORMAT_R5G6B5_UNORM_PACK16:
-               case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
-                       return reallyLow;
-
-               case VK_FORMAT_R8_UNORM:
-               case VK_FORMAT_R8_SNORM:
-               case VK_FORMAT_R8G8_UNORM:
-               case VK_FORMAT_R8G8_SNORM:
-               case VK_FORMAT_R8G8B8A8_UNORM:
-               case VK_FORMAT_R8G8B8A8_SNORM:
-               case VK_FORMAT_B8G8R8A8_UNORM:
-               case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
-               case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
-               case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
-                       return low;
-
-               case VK_FORMAT_R16_SFLOAT:
-               case VK_FORMAT_R16G16_SFLOAT:
-               case VK_FORMAT_R16G16B16A16_SFLOAT:
-                       return fp16;
-
-               case VK_FORMAT_R32_SFLOAT:
-               case VK_FORMAT_R32G32_SFLOAT:
-               case VK_FORMAT_R32G32B32A32_SFLOAT:
-                       return fp32;
+                       case TEXTURECHANNELCLASS_FLOATING_POINT:
+                               if (channelDepth[channelIdx] == 16)
+                               {
+                                       floatFormats.push_back(fp16);
+                               }
+                               else
+                               {
+                                       DE_ASSERT(channelDepth[channelIdx] == 32 || channelDepth[channelIdx] == 0);
+                                       floatFormats.push_back(fp32);
+                               }
+                               break;
 
-               default:
-                       DE_FATAL("Precision not defined for format");
-                       return fp32;
+                       default:
+                               DE_FATAL("Unexpected channel class.");
+                       break;
+               };
        }
+
+       return floatFormats;
 }
 
 using namespace shaderexecutor;
@@ -359,10 +319,6 @@ void initializeImage(Context& ctx, VkImage im, const ConstPixelBufferAccess* pba
        de::UniquePtr<Allocation> bufMem(ctx.getDefaultAllocator().allocate(bufMemReq, MemoryRequirement::HostVisible));
        VK_CHECK(vkd.bindBufferMemory(dev, buf.get(), bufMem->getMemory(), bufMem->getOffset()));
 
-       Unique<VkCommandPool> copyPool(createCommandPool(vkd, dev, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, uqfi));
-
-       Unique<VkCommandBuffer> copyBuffer(allocateCommandBuffer(vkd, dev, *copyPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
-
        std::vector<VkBufferImageCopy> copyRegions;
 
        deUint8* const bufMapPtr = reinterpret_cast<deUint8*>(bufMem->getHostPtr());
@@ -379,8 +335,6 @@ void initializeImage(Context& ctx, VkImage im, const ConstPixelBufferAccess* pba
 
                deMemcpy(bufCurPtr, pba[level].getDataPtr(), copySize);
 
-           flushMappedMemoryRange(vkd, dev, bufMem->getMemory(), bufMem->getOffset() + (bufCurPtr - bufMapPtr), copySize);
-
                const VkImageSubresourceLayers curSubresource =
                {
                        VK_IMAGE_ASPECT_COLOR_BIT,
@@ -404,81 +358,9 @@ void initializeImage(Context& ctx, VkImage im, const ConstPixelBufferAccess* pba
                bufCurPtr += copySize;
        }
 
-       beginCommandBuffer(vkd, copyBuffer.get());
+       flushAlloc(vkd, dev, *bufMem);
 
-       const VkImageSubresourceRange imMemBarSubRange =
-       {
-               VK_IMAGE_ASPECT_COLOR_BIT,
-               0,
-               (deUint32)imParams.levels,
-               0,
-               (deUint32)imParams.arrayLayers
-       };
-
-       VkImageMemoryBarrier imMemBar =
-       {
-               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-               DE_NULL,
-               0,
-               VK_ACCESS_TRANSFER_WRITE_BIT,
-               VK_IMAGE_LAYOUT_UNDEFINED,
-               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-               VK_QUEUE_FAMILY_IGNORED,
-               VK_QUEUE_FAMILY_IGNORED,
-               im,
-               imMemBarSubRange
-       };
-
-       VkBufferMemoryBarrier bufMemBar =
-       {
-               VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
-               DE_NULL,
-               VK_ACCESS_HOST_WRITE_BIT,
-               VK_ACCESS_TRANSFER_READ_BIT,
-               VK_QUEUE_FAMILY_IGNORED,
-               VK_QUEUE_FAMILY_IGNORED,
-               buf.get(),
-               0,
-               bufSize
-       };
-
-       vkd.cmdPipelineBarrier(copyBuffer.get(),
-                                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                                                  0,
-                                                  0,
-                                                  DE_NULL,
-                                                  1,
-                                                  &bufMemBar,
-                                                  1,
-                                                  &imMemBar);
-
-       vkd.cmdCopyBufferToImage(copyBuffer.get(),
-                                                        buf.get(),
-                                                        im,
-                                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                        (deUint32)copyRegions.size(),
-                                                        &copyRegions[0]);
-
-       imMemBar.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-       imMemBar.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
-       imMemBar.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
-       imMemBar.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-
-       vkd.cmdPipelineBarrier(copyBuffer.get(),
-                                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                                                  0,
-                                                  0,
-                                                  DE_NULL,
-                                                  0,
-                                                  DE_NULL,
-                                                  1,
-                                                  &imMemBar);
-
-       endCommandBuffer(vkd, copyBuffer.get());
-
-       submitCommandsAndWait(vkd, dev, ctx.getUniversalQueue(), copyBuffer.get());
+       copyBufferToImage(vkd, dev, ctx.getUniversalQueue(), ctx.getUniversalQueueFamilyIndex(), buf.get(), bufSize, copyRegions, DE_NULL, VK_IMAGE_ASPECT_COLOR_BIT, imParams.levels, imParams.arrayLayers, im);
 }
 
 struct TestCaseData
@@ -634,7 +516,7 @@ protected:
        bool                                                            isSupported                                             (void);
        void                                                            createResources                                 (void);
        void                                                            execute                                                 (void);
-       bool                                                            verify                                                  (void);
+       TestStatus                                                      verify                                                  (void);
 
        tcu::Sampler                                            mapTcuSampler                                   (void) const;
 
@@ -709,7 +591,7 @@ TestStatus TextureFilteringTestInstance::runTest (void)
                                                                                << TestLog::EndMessage;
 
     startTime = deGetMicroseconds();
-       bool result = verify();
+       TestStatus result = verify();
     endTime = deGetMicroseconds();
 
        m_context.getTestContext().getLog() << TestLog::Message
@@ -718,58 +600,78 @@ TestStatus TextureFilteringTestInstance::runTest (void)
                                                                                << "us"
                                                                                << TestLog::EndMessage;
 
-       if (result)
-       {
-               return TestStatus::pass("Success");
-       }
-       else
-       {
-               // \todo [2016-06-24 collinbaker] Print report if verification fails
-               return TestStatus::fail("Verification failed");
-       }
+       return result;
 }
 
-bool TextureFilteringTestInstance::verify (void)
+TestStatus TextureFilteringTestInstance::verify (void)
 {
        // \todo [2016-06-24 collinbaker] Handle cubemaps
 
-       const int                               coordBits                       = (int)m_context.getDeviceProperties().limits.subTexelPrecisionBits;
-       const int                               mipmapBits                      = (int)m_context.getDeviceProperties().limits.mipmapPrecisionBits;
-       const int                               maxPrintedFailures      = 5;
-       int                                             failCount                       = 0;
-
-       const SampleVerifier    verifier                        (m_imParams,
-                                                                                                m_samplerParams,
-                                                                                                m_sampleLookupSettings,
-                                                                                                coordBits,
-                                                                                                mipmapBits,
-                                                                                                getConversionPrecision(m_imParams.format),
-                                                                                                getFilteringPrecision(m_imParams.format),
-                                                                                                m_levels);
-
+       const int                                                                               coordBits                       = (int)m_context.getDeviceProperties().limits.subTexelPrecisionBits;
+       const int                                                                               mipmapBits                      = (int)m_context.getDeviceProperties().limits.mipmapPrecisionBits;
+       const int                                                                               maxPrintedFailures      = 5;
+       int                                                                                             failCount                       = 0;
+       int                                                                                             warningCount            = 0;
+       const tcu::TextureFormat                                                tcuFormat                       = mapVkFormat(m_imParams.format);
+       std::vector<de::SharedPtr<tcu::FloatFormat>>    strictPrecision         = getPrecision(m_imParams.format, 0);
+       std::vector<de::SharedPtr<tcu::FloatFormat>>    relaxedPrecision        = tcuFormat.type == tcu::TextureFormat::HALF_FLOAT ? getPrecision(m_imParams.format, -6) : getPrecision(m_imParams.format, -2);
+       const bool                                                                              allowRelaxedPrecision   = (tcuFormat.type == tcu::TextureFormat::HALF_FLOAT || tcuFormat.type == tcu::TextureFormat::SNORM_INT8) &&
+               (m_samplerParams.minFilter == VK_FILTER_LINEAR || m_samplerParams.magFilter == VK_FILTER_LINEAR);
+
+       const SampleVerifier                    verifier                        (m_imParams,
+                                                                                                                m_samplerParams,
+                                                                                                                m_sampleLookupSettings,
+                                                                                                                coordBits,
+                                                                                                                mipmapBits,
+                                                                                                                strictPrecision,
+                                                                                                                strictPrecision,
+                                                                                                                m_levels);
+
+       const SampleVerifier                    relaxedVerifier         (m_imParams,
+                                                                                                                m_samplerParams,
+                                                                                                                m_sampleLookupSettings,
+                                                                                                                coordBits,
+                                                                                                                mipmapBits,
+                                                                                                                strictPrecision,
+                                                                                                                relaxedPrecision,
+                                                                                                                m_levels);
 
        for (deUint32 sampleNdx = 0; sampleNdx < m_numSamples; ++sampleNdx)
        {
-               if (!verifier.verifySample(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx]))
+               bool compareOK = verifier.verifySample(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx]);
+               if (compareOK)
+                       continue;
+               if (allowRelaxedPrecision)
                {
-                       if (failCount++ < maxPrintedFailures)
+                       m_context.getTestContext().getLog()
+                               << tcu::TestLog::Message
+                               << "Warning: Strict validation failed, re-trying with lower precision for SNORM8 format or half float"
+                               << tcu::TestLog::EndMessage;
+
+                       compareOK = relaxedVerifier.verifySample(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx]);
+                       if (compareOK)
                        {
-                               // Re-run with report logging
-                               std::string report;
-                               verifier.verifySampleReport(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx], report);
-
-                               m_context.getTestContext().getLog()
-                                       << TestLog::Section("Failed sample", "Failed sample")
-                                       << TestLog::Message
-                                       << "Sample " << sampleNdx << ".\n"
-                                       << "\tCoordinate: " << m_sampleArguments[sampleNdx].coord << "\n"
-                                       << "\tLOD: " << m_sampleArguments[sampleNdx].lod << "\n"
-                                       << "\tGPU Result: " << m_resultSamples[sampleNdx] << "\n\n"
-                                       << "Failure report:\n" << report << "\n"
-                                       << TestLog::EndMessage
-                                       << TestLog::EndSection;
+                               warningCount++;
+                               continue;
                        }
                }
+               if ( failCount++ < maxPrintedFailures )
+               {
+                       // Re-run with report logging
+                       std::string report;
+                       verifier.verifySampleReport(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx], report);
+
+                       m_context.getTestContext().getLog()
+                               << TestLog::Section("Failed sample", "Failed sample")
+                               << TestLog::Message
+                               << "Sample " << sampleNdx << ".\n"
+                               << "\tCoordinate: " << m_sampleArguments[sampleNdx].coord << "\n"
+                               << "\tLOD: " << m_sampleArguments[sampleNdx].lod << "\n"
+                               << "\tGPU Result: " << m_resultSamples[sampleNdx] << "\n\n"
+                               << "Failure report:\n" << report << "\n"
+                               << TestLog::EndMessage
+                               << TestLog::EndSection;
+               }
        }
 
        m_context.getTestContext().getLog()
@@ -777,7 +679,12 @@ bool TextureFilteringTestInstance::verify (void)
                << "Passed " << m_numSamples - failCount << " out of " << m_numSamples << "."
                << TestLog::EndMessage;
 
-       return failCount == 0;
+       if (failCount > 0)
+               return TestStatus::fail("Verification failed");
+       else if (warningCount > 0)
+               return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Inaccurate filtering results");
+
+       return TestStatus::pass("Success");
 }
 
 void TextureFilteringTestInstance::execute (void)