Add ASTC LDR error colour quality warning
Some hardware can output the HDR error colour (black) instead of the
LDR error colour (magenta). Valid compression blocks are rendered
correctly.
This change adds a second comparison mechanism if the initial *fast*
deMemCmp fails; the texture values are compared allowing for any value
matching an error colour to compare against the other error colour.
If such a match is detected the test will output a QualityWarning
instead of a Pass.
If the two compared values don't match, but are not both error colours
the test result is still a Fail.
Affects:
dEQP-VK.image.texel_view_compatible*astc*
Components: Vulkan
VK-GL-CTS issue: 1231
Change-Id: Ie14913de0f2f3cf7fed90c275e48c67181c1e7ff
(cherry picked from commit b038d43aa868be1e6d4471c6977984151ada3af5)
diff --git a/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp b/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp
index bb3a9e3..a6ae4df 100644
--- a/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp
+++ b/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp
@@ -51,6 +51,7 @@
#include "tcuSurface.hpp"
#include <vector>
+
using namespace vk;
namespace vkt
{
@@ -111,6 +112,7 @@
VkImageUsageFlags uncompressedImageUsage;
bool useMipmaps;
VkFormat formatForVerify;
+ bool formatIsASTC;
};
template<typename T>
@@ -128,6 +130,93 @@
const deUint32 SINGLE_LEVEL = 1u;
const deUint32 SINGLE_LAYER = 1u;
+enum BinaryCompareMode
+{
+ COMPARE_MODE_NORMAL,
+ COMPARE_MODE_ALLOW_ASTC_ERROR_COLOUR_WARNING,
+};
+
+enum BinaryCompareResult
+{
+ COMPARE_RESULT_OK,
+ COMPARE_RESULT_ASTC_QUALITY_WARNING,
+ COMPARE_RESULT_FAILED,
+};
+
+const deUint32 ASTC_LDR_ERROR_COLOUR = 0xFFFF00FF;
+const deUint32 ASTC_HDR_ERROR_COLOUR = 0x00000000;
+
+static BinaryCompareResult BinaryCompare(const void *reference,
+ const void *result,
+ VkDeviceSize sizeInBytes,
+ VkFormat formatForVerify,
+ BinaryCompareMode mode)
+{
+ DE_UNREF(formatForVerify);
+
+ // Compare quickly using deMemCmp
+ if (deMemCmp(reference, result, (size_t)sizeInBytes) == 0)
+ {
+ return COMPARE_RESULT_OK;
+ }
+ // If deMemCmp indicated a mismatch, we can re-check with a manual comparison of
+ // the ref and res images that allows for ASTC error colour mismatches if the ASTC
+ // comparison mode was selected. This slows down the affected ASTC tests if you
+ // didn't pass in the first comparison, but means in the general case the
+ // comparion is still fast.
+ else if (mode == COMPARE_MODE_ALLOW_ASTC_ERROR_COLOUR_WARNING)
+ {
+ bool bWarn = false;
+ bool bFail = false;
+ const deUint32 *pui32RefVal = (deUint32*)reference;
+ const deUint32 *pui32ResVal = (deUint32*)result;
+
+ DE_ASSERT(formatForVerify == VK_FORMAT_R8G8B8A8_UNORM);
+ size_t numPixels = (size_t)(sizeInBytes / 4) /* bytes */;
+ for (size_t i = 0; i < numPixels; i++)
+ {
+ const deUint32 ref = *pui32RefVal++;
+ const deUint32 res = *pui32ResVal++;
+
+ if (ref != res)
+ {
+ // QualityWarning !1231: If the astc pixel was the ASTC LDR error colour
+ // and the result image has the HDR error colour (or vice versa as the test
+ // cases below sometimes reverse the operands) then issue a quality warning
+ // instead of a failure.
+ if ((ref == ASTC_LDR_ERROR_COLOUR && res == ASTC_HDR_ERROR_COLOUR) ||
+ (ref == ASTC_HDR_ERROR_COLOUR && res == ASTC_LDR_ERROR_COLOUR))
+ {
+ bWarn = true;
+ }
+ else
+ {
+ bFail = true;
+ }
+ }
+ }
+
+ if (!bFail)
+ {
+ return (bWarn)
+ ? (COMPARE_RESULT_ASTC_QUALITY_WARNING)
+ : (COMPARE_RESULT_OK);
+ }
+ }
+
+ return COMPARE_RESULT_FAILED;
+}
+
+static bool FormatIsASTC(VkFormat format)
+{
+ return deInRange32(format, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_12x12_SRGB_BLOCK);
+}
+
+static TestStatus TestStatusASTCQualityWarning()
+{
+ return TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "ASTC HDR error colour output instead of LDR error colour");
+}
+
class BasicTranscodingTestInstance : public TestInstance
{
public:
@@ -153,6 +242,10 @@
const deUint32 m_levelCount;
const UVec3 m_layerSize;
+ // Detected error colour mismatch while verifying image. Output
+ // the ASTC quality warning instead of a pass
+ bool m_bASTCErrorColourMismatch;
+
private:
deUint32 findMipMapLevelCount ();
};
@@ -193,6 +286,7 @@
, m_blockHeight (getBlockHeight(m_parameters.formatCompressed))
, m_levelCount (findMipMapLevelCount())
, m_layerSize (getLayerSize(m_parameters.imageType, m_parameters.size))
+ , m_bASTCErrorColourMismatch(false)
{
DE_ASSERT(deLog2Floor32(m_parameters.size.x()) == deLog2Floor32(m_parameters.size.y()));
}
@@ -542,6 +636,13 @@
};
if (!decompressImage(*cmdBuffer, imageData, mipMapSizes))
return TestStatus::fail("Fail");
+
+ if (m_bASTCErrorColourMismatch)
+ {
+ DE_ASSERT(m_parameters.formatIsASTC);
+ return TestStatusASTCQualityWarning();
+ }
+
return TestStatus::pass("Pass");
}
@@ -907,7 +1008,7 @@
DE_NULL, // const void* pNext;
0u, // VkImageCreateFlags flags;
VK_IMAGE_TYPE_2D, // VkImageType imageType;
- VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
+ m_parameters.formatForVerify, // VkFormat format;
extentCompressed, // VkExtent3D extent;
1u, // deUint32 mipLevels;
1u, // deUint32 arrayLayers;
@@ -976,7 +1077,7 @@
Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
const Unique<VkPipeline> pipeline (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
- const VkDeviceSize bufferSize = getImageSizeBytes(IVec3((int)extentCompressed.width, (int)extentCompressed.height, (int)extentCompressed.depth), VK_FORMAT_R8G8B8A8_UNORM);
+ const VkDeviceSize bufferSize = getImageSizeBytes(IVec3((int)extentCompressed.width, (int)extentCompressed.height, (int)extentCompressed.depth), m_parameters.formatForVerify);
Buffer resultBuffer (vk, device, allocator,
makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
Buffer referenceBuffer (vk, device, allocator,
@@ -1162,7 +1263,18 @@
invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), bufferSize);
invalidateMappedMemoryRange(vk, device, referenceAlloc.getMemory(), referenceAlloc.getOffset(), bufferSize);
- if (deMemCmp(resultAlloc.getHostPtr(), referenceAlloc.getHostPtr(), (size_t)bufferSize) != 0)
+ BinaryCompareMode compareMode =
+ (m_parameters.formatIsASTC)
+ ?(COMPARE_MODE_ALLOW_ASTC_ERROR_COLOUR_WARNING)
+ :(COMPARE_MODE_NORMAL);
+
+ BinaryCompareResult res = BinaryCompare(referenceAlloc.getHostPtr(),
+ resultAlloc.getHostPtr(),
+ (size_t)bufferSize,
+ m_parameters.formatForVerify,
+ compareMode);
+
+ if (res == COMPARE_RESULT_FAILED)
{
ConstPixelBufferAccess resultPixels (mapVkFormat(decompressedImageInfo.format), decompressedImageInfo.extent.width, decompressedImageInfo.extent.height, decompressedImageInfo.extent.depth, resultAlloc.getHostPtr());
ConstPixelBufferAccess referencePixels (mapVkFormat(decompressedImageInfo.format), decompressedImageInfo.extent.width, decompressedImageInfo.extent.height, decompressedImageInfo.extent.depth, referenceAlloc.getHostPtr());
@@ -1170,6 +1282,10 @@
if(!fuzzyCompare(m_context.getTestContext().getLog(), "Image Comparison", "Image Comparison", resultPixels, referencePixels, 0.001f, tcu::COMPARE_LOG_EVERYTHING))
return false;
}
+ else if (res == COMPARE_RESULT_ASTC_QUALITY_WARNING)
+ {
+ m_bASTCErrorColourMismatch = true;
+ }
}
return true;
@@ -1420,6 +1536,12 @@
return TestStatus::fail("Images difference detected");
}
+ if (m_bASTCErrorColourMismatch)
+ {
+ DE_ASSERT(m_parameters.formatIsASTC);
+ return TestStatusASTCQualityWarning();
+ }
+
return TestStatus::pass("Pass");
}
@@ -2006,7 +2128,18 @@
const Allocation& resDstBufferAlloc = resDstBuffer->getAllocation();
invalidateMappedMemoryRange(vk, device, resDstBufferAlloc.getMemory(), resDstBufferAlloc.getOffset(), dstBufferSize);
- if (deMemCmp(refDstBufferAlloc.getHostPtr(), resDstBufferAlloc.getHostPtr(), (size_t)dstBufferSize) != 0)
+ BinaryCompareMode compareMode =
+ (m_parameters.formatIsASTC)
+ ?(COMPARE_MODE_ALLOW_ASTC_ERROR_COLOUR_WARNING)
+ :(COMPARE_MODE_NORMAL);
+
+ BinaryCompareResult res = BinaryCompare(refDstBufferAlloc.getHostPtr(),
+ resDstBufferAlloc.getHostPtr(),
+ dstBufferSize,
+ m_parameters.formatForVerify,
+ compareMode);
+
+ if (res == COMPARE_RESULT_FAILED)
{
// Do fuzzy to log error mask
invalidateMappedMemoryRange(vk, device, resDstBufferAlloc.getMemory(), resDstBufferAlloc.getOffset(), dstBufferSize);
@@ -2024,6 +2157,10 @@
return false;
}
+ else if (res == COMPARE_RESULT_ASTC_QUALITY_WARNING)
+ {
+ m_bASTCErrorColourMismatch = true;
+ }
}
return true;
@@ -2608,7 +2745,7 @@
!physicalDeviceFeatures.textureCompressionETC2)
TCU_THROW(NotSupportedError, "textureCompressionETC2 not supported");
- if (deInRange32(m_parameters.formatCompressed, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_12x12_SRGB_BLOCK) &&
+ if (m_parameters.formatIsASTC &&
!physicalDeviceFeatures.textureCompressionASTC_LDR)
TCU_THROW(NotSupportedError, "textureCompressionASTC_LDR not supported");
@@ -2919,7 +3056,8 @@
compressedImageViewUsageFlags[operationNdx],
uncompressedImageUsageFlags[operationNdx],
mipmapTest,
- VK_FORMAT_R8G8B8A8_UNORM
+ VK_FORMAT_R8G8B8A8_UNORM,
+ FormatIsASTC(formatCompressed)
};
compressedFormatGroup->addChild(new TexelViewCompatibleCase(testCtx, uncompressedFormatGroupName, "", parameters));