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 = "internal/data/imagecompare";
42
loadImageRGBA8(tcu::TextureLevel & dst,const tcu::Archive & archive,const char * path)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:
FuzzyComparisonMetricCase(tcu::TestContext & testCtx,const char * name,const char * refImg,const char * cmpImg,const float minBound,const float maxBound)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
iterate(void)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:
BilinearCompareCase(tcu::TestContext & testCtx,const char * name,const char * refImg,const char * cmpImg,const tcu::RGBA & threshold,bool expectedResult)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
iterate(void)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:
FuzzyComparisonMetricTests(tcu::TestContext & testCtx)156 FuzzyComparisonMetricTests (tcu::TestContext& testCtx)
157 : tcu::TestCaseGroup(testCtx, "fuzzy_metric", "Fuzzy comparison metrics")
158 {
159 }
160
init(void)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:
BilinearCompareTests(tcu::TestContext & testCtx)182 BilinearCompareTests (tcu::TestContext& testCtx)
183 : tcu::TestCaseGroup(testCtx, "bilinear_compare", "Bilinear Image Comparison Tests")
184 {
185 }
186
init(void)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
ImageCompareTests(tcu::TestContext & testCtx)216 ImageCompareTests::ImageCompareTests (tcu::TestContext& testCtx)
217 : tcu::TestCaseGroup(testCtx, "image_compare", "Image comparison tests")
218 {
219 }
220
~ImageCompareTests(void)221 ImageCompareTests::~ImageCompareTests (void)
222 {
223 }
224
init(void)225 void ImageCompareTests::init (void)
226 {
227 addChild(new FuzzyComparisonMetricTests (m_testCtx));
228 addChild(new BilinearCompareTests (m_testCtx));
229 }
230
231 } // dit
232