1 /*------------------------------------------------------------------------- 2 * drawElements Internal Test Module 3 * --------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Image comparison tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "ditImageCompareTests.hpp" 25 #include "tcuResource.hpp" 26 #include "tcuImageCompare.hpp" 27 #include "tcuFuzzyImageCompare.hpp" 28 #include "tcuImageIO.hpp" 29 #include "tcuTexture.hpp" 30 #include "tcuTestLog.hpp" 31 #include "tcuTextureUtil.hpp" 32 #include "tcuRGBA.hpp" 33 #include "deFilePath.hpp" 34 #include "deClock.h" 35 36 namespace dit 37 { 38 39 using tcu::TestLog; 40 41 static const char* BASE_DIR = "data/imagecompare"; 42 43 static void loadImageRGBA8 (tcu::TextureLevel& dst, const tcu::Archive& archive, const char* path) 44 { 45 tcu::TextureLevel tmp; 46 tcu::ImageIO::loadImage(tmp, archive, path); 47 48 dst.setStorage(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), tmp.getWidth(), tmp.getHeight()); 49 tcu::copy(dst, tmp); 50 } 51 52 class FuzzyComparisonMetricCase : public tcu::TestCase 53 { 54 public: 55 FuzzyComparisonMetricCase (tcu::TestContext& testCtx, const char* name, const char* refImg, const char* cmpImg, const float minBound, const float maxBound) 56 : tcu::TestCase (testCtx, name, "") 57 , m_refImg (refImg) 58 , m_cmpImg (cmpImg) 59 , m_minBound (minBound) 60 , m_maxBound (maxBound) 61 { 62 } 63 64 IterateResult iterate (void) 65 { 66 tcu::TextureLevel refImg; 67 tcu::TextureLevel cmpImg; 68 tcu::TextureLevel errorMask; 69 tcu::FuzzyCompareParams params; 70 float result = 0.0f; 71 deUint64 compareTime = 0; 72 73 params.maxSampleSkip = 0; 74 75 tcu::ImageIO::loadImage(refImg, m_testCtx.getArchive(), de::FilePath::join(BASE_DIR, m_refImg).getPath()); 76 tcu::ImageIO::loadImage(cmpImg, m_testCtx.getArchive(), de::FilePath::join(BASE_DIR, m_cmpImg).getPath()); 77 78 errorMask.setStorage(refImg.getFormat(), refImg.getWidth(), refImg.getHeight(), refImg.getDepth()); 79 80 { 81 const deUint64 startTime = deGetMicroseconds(); 82 result = tcu::fuzzyCompare(params, refImg, cmpImg, errorMask); 83 compareTime = deGetMicroseconds()-startTime; 84 } 85 86 m_testCtx.getLog() << TestLog::Float("Result", "Result metric", "", QP_KEY_TAG_NONE, result) 87 << TestLog::Float("MinBound", "Minimum bound", "", QP_KEY_TAG_NONE, m_minBound) 88 << TestLog::Float("MaxBound", "Maximum bound", "", QP_KEY_TAG_NONE, m_maxBound) 89 << TestLog::Integer("CompareTime", "Comparison time", "us", QP_KEY_TAG_TIME, compareTime); 90 91 { 92 const bool isOk = de::inRange(result, m_minBound, m_maxBound); 93 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 94 isOk ? "Pass" : "Metric out of bounds"); 95 } 96 97 return STOP; 98 } 99 100 private: 101 const std::string m_refImg; 102 const std::string m_cmpImg; 103 const float m_minBound; 104 const float m_maxBound; 105 }; 106 107 class BilinearCompareCase : public tcu::TestCase 108 { 109 public: 110 BilinearCompareCase (tcu::TestContext& testCtx, const char* name, const char* refImg, const char* cmpImg, const tcu::RGBA& threshold, bool expectedResult) 111 : tcu::TestCase (testCtx, name, "") 112 , m_refImg (refImg) 113 , m_cmpImg (cmpImg) 114 , m_threshold (threshold) 115 , m_expectedResult (expectedResult) 116 { 117 } 118 119 IterateResult iterate (void) 120 { 121 tcu::TextureLevel refImg; 122 tcu::TextureLevel cmpImg; 123 bool result; 124 deUint64 compareTime = 0; 125 126 loadImageRGBA8(refImg, m_testCtx.getArchive(), de::FilePath::join(BASE_DIR, m_refImg).getPath()); 127 loadImageRGBA8(cmpImg, m_testCtx.getArchive(), de::FilePath::join(BASE_DIR, m_cmpImg).getPath()); 128 129 { 130 const deUint64 startTime = deGetMicroseconds(); 131 result = tcu::bilinearCompare(m_testCtx.getLog(), "CompareResult", "Image comparison result", refImg, cmpImg, m_threshold, tcu::COMPARE_LOG_EVERYTHING); 132 compareTime = deGetMicroseconds()-startTime; 133 } 134 135 m_testCtx.getLog() << TestLog::Integer("CompareTime", "Comparison time", "us", QP_KEY_TAG_TIME, compareTime); 136 137 { 138 const bool isOk = result == m_expectedResult; 139 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 140 isOk ? "Pass" : "Wrong comparison result"); 141 } 142 143 return STOP; 144 } 145 146 private: 147 const std::string m_refImg; 148 const std::string m_cmpImg; 149 const tcu::RGBA m_threshold; 150 const bool m_expectedResult; 151 }; 152 153 class FuzzyComparisonMetricTests : public tcu::TestCaseGroup 154 { 155 public: 156 FuzzyComparisonMetricTests (tcu::TestContext& testCtx) 157 : tcu::TestCaseGroup(testCtx, "fuzzy_metric", "Fuzzy comparison metrics") 158 { 159 } 160 161 void init (void) 162 { 163 addChild(new FuzzyComparisonMetricCase(m_testCtx, "identical", "cube_ref.png", "cube_ref.png", 0.0f, 0.000001f)); 164 addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube", "cube_ref.png", "cube_cmp.png", 0.0029f, 0.0031f)); 165 addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_2", "cube_2_ref.png", "cube_2_cmp.png", 0.0134f, 0.0140f)); 166 addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_sphere", "cube_sphere_ref.png", "cube_sphere_cmp.png", 0.0730f, 0.0801f)); 167 addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_nmap", "cube_nmap_ref.png", "cube_nmap_cmp.png", 0.0024f, 0.0025f)); 168 addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_nmap_2", "cube_nmap_2_ref.png", "cube_nmap_2_cmp.png", 0.0172f, 0.0189f)); 169 addChild(new FuzzyComparisonMetricCase(m_testCtx, "earth_diffuse", "earth_diffuse_ref.png", "earth_diffuse_cmp.png", 0.0f, 0.00002f)); 170 addChild(new FuzzyComparisonMetricCase(m_testCtx, "eath_texture", "earth_texture_ref.png", "earth_texture_cmp.png", 0.0002f, 0.0003f)); 171 addChild(new FuzzyComparisonMetricCase(m_testCtx, "earth_spot", "earth_spot_ref.png", "earth_spot_cmp.png", 0.0015f, 0.0018f)); 172 addChild(new FuzzyComparisonMetricCase(m_testCtx, "earth_light", "earth_light_ref.png", "earth_light_cmp.png", 1.7050f, 1.7070f)); 173 addChild(new FuzzyComparisonMetricCase(m_testCtx, "lessThan0", "lessThan0-reference.png", "lessThan0-result.png", 0.0003f, 0.0004f)); 174 addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_sphere_2", "cube_sphere_2_ref.png", "cube_sphere_2_cmp.png", 0.0207f, 0.0230f)); 175 addChild(new FuzzyComparisonMetricCase(m_testCtx, "earth_to_empty", "earth_spot_ref.png", "empty_256x256.png", 77074.0f, 77076.0f)); 176 } 177 }; 178 179 class BilinearCompareTests : public tcu::TestCaseGroup 180 { 181 public: 182 BilinearCompareTests (tcu::TestContext& testCtx) 183 : tcu::TestCaseGroup(testCtx, "bilinear_compare", "Bilinear Image Comparison Tests") 184 { 185 } 186 187 void init (void) 188 { 189 addChild(new BilinearCompareCase(m_testCtx, "identical", "cube_ref.png", "cube_ref.png", tcu::RGBA(0,0,0,0), true)); 190 addChild(new BilinearCompareCase(m_testCtx, "empty_to_white", "empty_256x256.png", "white_256x256.png", tcu::RGBA(7,7,7,2), false)); 191 addChild(new BilinearCompareCase(m_testCtx, "white_to_empty", "white_256x256.png", "empty_256x256.png", tcu::RGBA(7,7,7,2), false)); 192 addChild(new BilinearCompareCase(m_testCtx, "cube", "cube_ref.png", "cube_cmp.png", tcu::RGBA(7,7,7,2), false)); 193 addChild(new BilinearCompareCase(m_testCtx, "cube_2", "cube_2_ref.png", "cube_2_cmp.png", tcu::RGBA(7,7,7,2), false)); 194 addChild(new BilinearCompareCase(m_testCtx, "cube_sphere", "cube_sphere_ref.png", "cube_sphere_cmp.png", tcu::RGBA(7,7,7,2), false)); 195 addChild(new BilinearCompareCase(m_testCtx, "cube_nmap", "cube_nmap_ref.png", "cube_nmap_cmp.png", tcu::RGBA(7,7,7,2), false)); 196 addChild(new BilinearCompareCase(m_testCtx, "cube_nmap_2", "cube_nmap_2_ref.png", "cube_nmap_2_cmp.png", tcu::RGBA(7,7,7,2), false)); 197 addChild(new BilinearCompareCase(m_testCtx, "earth_diffuse", "earth_diffuse_ref.png", "earth_diffuse_cmp.png", tcu::RGBA(20,20,20,2), true)); 198 addChild(new BilinearCompareCase(m_testCtx, "eath_texture", "earth_texture_ref.png", "earth_texture_cmp.png", tcu::RGBA(7,7,7,2), false)); 199 addChild(new BilinearCompareCase(m_testCtx, "earth_spot", "earth_spot_ref.png", "earth_spot_cmp.png", tcu::RGBA(7,7,7,2), false)); 200 addChild(new BilinearCompareCase(m_testCtx, "earth_light", "earth_light_ref.png", "earth_light_cmp.png", tcu::RGBA(7,7,7,2), false)); 201 addChild(new BilinearCompareCase(m_testCtx, "lessThan0", "lessThan0-reference.png", "lessThan0-result.png", tcu::RGBA(36,36,36,2), true)); 202 addChild(new BilinearCompareCase(m_testCtx, "cube_sphere_2", "cube_sphere_2_ref.png", "cube_sphere_2_cmp.png", tcu::RGBA(7,7,7,2), false)); 203 addChild(new BilinearCompareCase(m_testCtx, "earth_to_empty", "earth_spot_ref.png", "empty_256x256.png", tcu::RGBA(7,7,7,2), false)); 204 addChild(new BilinearCompareCase(m_testCtx, "texfilter", "texfilter_ref.png", "texfilter_cmp.png", tcu::RGBA(7,7,7,2), true)); 205 addChild(new BilinearCompareCase(m_testCtx, "refract_vtx", "refract_vtx_ref.png", "refract_vtx_cmp.png", tcu::RGBA(7,7,7,2), true)); 206 addChild(new BilinearCompareCase(m_testCtx, "refract_frag", "refract_frag_ref.png", "refract_frag_cmp.png", tcu::RGBA(7,7,7,2), true)); 207 addChild(new BilinearCompareCase(m_testCtx, "lessthan_vtx", "lessthan_vtx_ref.png", "lessthan_vtx_cmp.png", tcu::RGBA(7,7,7,2), true)); 208 addChild(new BilinearCompareCase(m_testCtx, "2_units_2d", "2_units_2d_ref.png", "2_units_2d_cmp.png", tcu::RGBA(7,7,7,2), false)); 209 addChild(new BilinearCompareCase(m_testCtx, "4_units_cube_vtx", "4_units_cube_ref.png", "4_units_cube_cmp.png", tcu::RGBA(7,7,7,2), false)); 210 addChild(new BilinearCompareCase(m_testCtx, "texfilter_vtx_nearest", "texfilter_vtx_nearest_ref.png", "texfilter_vtx_nearest_cmp.png", tcu::RGBA(7,7,7,2), false)); 211 addChild(new BilinearCompareCase(m_testCtx, "texfilter_vtx_linear", "texfilter_vtx_linear_ref.png", "texfilter_vtx_linear_cmp.png", tcu::RGBA(7,7,7,2), false)); 212 addChild(new BilinearCompareCase(m_testCtx, "readpixels_msaa", "readpixels_ref.png", "readpixels_msaa.png", tcu::RGBA(1,1,1,1), true)); 213 } 214 }; 215 216 ImageCompareTests::ImageCompareTests (tcu::TestContext& testCtx) 217 : tcu::TestCaseGroup(testCtx, "image_compare", "Image comparison tests") 218 { 219 } 220 221 ImageCompareTests::~ImageCompareTests (void) 222 { 223 } 224 225 void ImageCompareTests::init (void) 226 { 227 addChild(new FuzzyComparisonMetricTests (m_testCtx)); 228 addChild(new BilinearCompareTests (m_testCtx)); 229 } 230 231 } // dit 232