Home | History | Annotate | Download | only in internal
      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 
     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::Image("RefImage",	"Reference Image",	refImg)
     87 						   << TestLog::Image("CmpImage",	"Compare Image",	cmpImg)
     88 						   << TestLog::Image("ErrorMask",	"Error Mask",		errorMask);
     89 
     90 		m_testCtx.getLog() << TestLog::Float("Result", "Result metric", "", QP_KEY_TAG_NONE, result)
     91 						   << TestLog::Float("MinBound", "Minimum bound", "", QP_KEY_TAG_NONE, m_minBound)
     92 						   << TestLog::Float("MaxBound", "Maximum bound", "", QP_KEY_TAG_NONE, m_maxBound)
     93 						   << TestLog::Integer("CompareTime", "Comparison time", "us", QP_KEY_TAG_TIME, compareTime);
     94 
     95 		{
     96 			const bool isOk = de::inRange(result, m_minBound, m_maxBound);
     97 			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
     98 									isOk ? "Pass"				: "Metric out of bounds");
     99 		}
    100 
    101 		return STOP;
    102 	}
    103 
    104 private:
    105 	const std::string	m_refImg;
    106 	const std::string	m_cmpImg;
    107 	const float			m_minBound;
    108 	const float			m_maxBound;
    109 };
    110 
    111 class BilinearCompareCase : public tcu::TestCase
    112 {
    113 public:
    114 	BilinearCompareCase (tcu::TestContext& testCtx, const char* name, const char* refImg, const char* cmpImg, const tcu::RGBA& threshold, bool expectedResult)
    115 		: tcu::TestCase		(testCtx, name, "")
    116 		, m_refImg			(refImg)
    117 		, m_cmpImg			(cmpImg)
    118 		, m_threshold		(threshold)
    119 		, m_expectedResult	(expectedResult)
    120 	{
    121 	}
    122 
    123 	IterateResult iterate (void)
    124 	{
    125 		tcu::TextureLevel		refImg;
    126 		tcu::TextureLevel		cmpImg;
    127 		bool					result;
    128 		deUint64				compareTime	= 0;
    129 
    130 		loadImageRGBA8(refImg, m_testCtx.getArchive(), de::FilePath::join(BASE_DIR, m_refImg).getPath());
    131 		loadImageRGBA8(cmpImg, m_testCtx.getArchive(), de::FilePath::join(BASE_DIR, m_cmpImg).getPath());
    132 
    133 		{
    134 			const deUint64 startTime = deGetMicroseconds();
    135 			result = tcu::bilinearCompare(m_testCtx.getLog(), "CompareResult", "Image comparison result", refImg, cmpImg, m_threshold, tcu::COMPARE_LOG_EVERYTHING);
    136 			compareTime = deGetMicroseconds()-startTime;
    137 		}
    138 
    139 		m_testCtx.getLog() << TestLog::Integer("CompareTime", "Comparison time", "us", QP_KEY_TAG_TIME, compareTime);
    140 
    141 		{
    142 			const bool isOk = result == m_expectedResult;
    143 			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    144 									isOk ? "Pass"				: "Wrong comparison result");
    145 		}
    146 
    147 		return STOP;
    148 	}
    149 
    150 private:
    151 	const std::string		m_refImg;
    152 	const std::string		m_cmpImg;
    153 	const tcu::RGBA			m_threshold;
    154 	const bool				m_expectedResult;
    155 };
    156 
    157 class FuzzyComparisonMetricTests : public tcu::TestCaseGroup
    158 {
    159 public:
    160 	FuzzyComparisonMetricTests (tcu::TestContext& testCtx)
    161 		: tcu::TestCaseGroup(testCtx, "fuzzy_metric", "Fuzzy comparison metrics")
    162 	{
    163 	}
    164 
    165 	void init (void)
    166 	{
    167 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "identical",		"cube_ref.png",				"cube_ref.png",				0.0f,			0.000001f));
    168 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube",			"cube_ref.png",				"cube_cmp.png",				0.0029f,		0.0031f));
    169 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_2",			"cube_2_ref.png",			"cube_2_cmp.png",			0.0134f,		0.0140f));
    170 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_sphere",	"cube_sphere_ref.png",		"cube_sphere_cmp.png",		0.0730f,		0.0801f));
    171 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_nmap",		"cube_nmap_ref.png",		"cube_nmap_cmp.png",		0.0022f,		0.0025f));
    172 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_nmap_2",	"cube_nmap_2_ref.png",		"cube_nmap_2_cmp.png",		0.0172f,		0.0189f));
    173 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "earth_diffuse",	"earth_diffuse_ref.png",	"earth_diffuse_cmp.png",	0.0f,			0.00002f));
    174 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "eath_texture",	"earth_texture_ref.png",	"earth_texture_cmp.png",	0.0002f,		0.0003f));
    175 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "earth_spot",		"earth_spot_ref.png",		"earth_spot_cmp.png",		0.0015f,		0.0018f));
    176 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "earth_light",	"earth_light_ref.png",		"earth_light_cmp.png",		1.7050f,		1.7070f));
    177 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "lessThan0",		"lessThan0-reference.png",	"lessThan0-result.png",		0.0003f,		0.0004f));
    178 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "cube_sphere_2",	"cube_sphere_2_ref.png",	"cube_sphere_2_cmp.png",	0.0207f,		0.0230f));
    179 		addChild(new FuzzyComparisonMetricCase(m_testCtx, "earth_to_empty",	"earth_spot_ref.png",		"empty_256x256.png",		54951.0f,		54955.0f));
    180 	}
    181 };
    182 
    183 class BilinearCompareTests : public tcu::TestCaseGroup
    184 {
    185 public:
    186 	BilinearCompareTests (tcu::TestContext& testCtx)
    187 		: tcu::TestCaseGroup(testCtx, "bilinear_compare", "Bilinear Image Comparison Tests")
    188 	{
    189 	}
    190 
    191 	void init (void)
    192 	{
    193 		addChild(new BilinearCompareCase(m_testCtx, "identical",				"cube_ref.png",						"cube_ref.png",						tcu::RGBA(0,0,0,0),			true));
    194 		addChild(new BilinearCompareCase(m_testCtx, "empty_to_white",			"empty_256x256.png",				"white_256x256.png",				tcu::RGBA(7,7,7,2),			false));
    195 		addChild(new BilinearCompareCase(m_testCtx, "white_to_empty",			"white_256x256.png",				"empty_256x256.png",				tcu::RGBA(7,7,7,2),			false));
    196 		addChild(new BilinearCompareCase(m_testCtx, "cube",						"cube_ref.png",						"cube_cmp.png",						tcu::RGBA(7,7,7,2),			false));
    197 		addChild(new BilinearCompareCase(m_testCtx, "cube_2",					"cube_2_ref.png",					"cube_2_cmp.png",					tcu::RGBA(7,7,7,2),			false));
    198 		addChild(new BilinearCompareCase(m_testCtx, "cube_sphere",				"cube_sphere_ref.png",				"cube_sphere_cmp.png",				tcu::RGBA(7,7,7,2),			false));
    199 		addChild(new BilinearCompareCase(m_testCtx, "cube_nmap",				"cube_nmap_ref.png",				"cube_nmap_cmp.png",				tcu::RGBA(7,7,7,2),			false));
    200 		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));
    201 		addChild(new BilinearCompareCase(m_testCtx, "earth_diffuse",			"earth_diffuse_ref.png",			"earth_diffuse_cmp.png",			tcu::RGBA(20,20,20,2),		true));
    202 		addChild(new BilinearCompareCase(m_testCtx, "eath_texture",				"earth_texture_ref.png",			"earth_texture_cmp.png",			tcu::RGBA(7,7,7,2),			false));
    203 		addChild(new BilinearCompareCase(m_testCtx, "earth_spot",				"earth_spot_ref.png",				"earth_spot_cmp.png",				tcu::RGBA(7,7,7,2),			false));
    204 		addChild(new BilinearCompareCase(m_testCtx, "earth_light",				"earth_light_ref.png",				"earth_light_cmp.png",				tcu::RGBA(7,7,7,2),			false));
    205 		addChild(new BilinearCompareCase(m_testCtx, "lessThan0",				"lessThan0-reference.png",			"lessThan0-result.png",				tcu::RGBA(36,36,36,2),		true));
    206 		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));
    207 		addChild(new BilinearCompareCase(m_testCtx, "earth_to_empty",			"earth_spot_ref.png",				"empty_256x256.png",				tcu::RGBA(7,7,7,2),			false));
    208 		addChild(new BilinearCompareCase(m_testCtx, "texfilter",				"texfilter_ref.png",				"texfilter_cmp.png",				tcu::RGBA(7,7,7,2),			true));
    209 		addChild(new BilinearCompareCase(m_testCtx, "refract_vtx",				"refract_vtx_ref.png",				"refract_vtx_cmp.png",				tcu::RGBA(7,7,7,2),			true));
    210 		addChild(new BilinearCompareCase(m_testCtx, "refract_frag",				"refract_frag_ref.png",				"refract_frag_cmp.png",				tcu::RGBA(7,7,7,2),			true));
    211 		addChild(new BilinearCompareCase(m_testCtx, "lessthan_vtx",				"lessthan_vtx_ref.png",				"lessthan_vtx_cmp.png",				tcu::RGBA(7,7,7,2),			true));
    212 		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));
    213 		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));
    214 		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));
    215 		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));
    216 		addChild(new BilinearCompareCase(m_testCtx, "readpixels_msaa",			"readpixels_ref.png",				"readpixels_msaa.png",				tcu::RGBA(1,1,1,1),			true));
    217 	}
    218 };
    219 
    220 ImageCompareTests::ImageCompareTests (tcu::TestContext& testCtx)
    221 	: tcu::TestCaseGroup(testCtx, "image_compare", "Image comparison tests")
    222 {
    223 }
    224 
    225 ImageCompareTests::~ImageCompareTests (void)
    226 {
    227 }
    228 
    229 void ImageCompareTests::init (void)
    230 {
    231 	addChild(new FuzzyComparisonMetricTests	(m_testCtx));
    232 	addChild(new BilinearCompareTests		(m_testCtx));
    233 }
    234 
    235 } // dit
    236