1/*-------------------------------------------------------------------------
2 * drawElements Internal Test Module
3 * ---------------------------------
4 *
5 * Copyright 2016 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 ASTC tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "ditAstcTests.hpp"
25
26#include "tcuCompressedTexture.hpp"
27#include "tcuAstcUtil.hpp"
28
29#include "deUniquePtr.hpp"
30#include "deStringUtil.hpp"
31
32namespace dit
33{
34
35using std::string;
36using std::vector;
37using namespace tcu;
38
39namespace
40{
41
42class AstcCase : public tcu::TestCase
43{
44public:
45								AstcCase		(tcu::TestContext& testCtx, CompressedTexFormat format);
46
47	IterateResult				iterate			(void);
48
49private:
50	const CompressedTexFormat	m_format;
51};
52
53static const string getASTCFormatShortName (CompressedTexFormat format)
54{
55	DE_ASSERT(isAstcFormat(format));
56	const IVec3 blockSize = getBlockPixelSize(format);
57	DE_ASSERT(blockSize.z() == 1);
58
59	return de::toString(blockSize.x()) + "x" + de::toString(blockSize.y()) + (tcu::isAstcSRGBFormat(format) ? "_srgb" : "");
60}
61
62AstcCase::AstcCase (tcu::TestContext& testCtx, CompressedTexFormat format)
63	: tcu::TestCase	(testCtx, getASTCFormatShortName(format).c_str(), "")
64	, m_format		(format)
65{
66}
67
68void testDecompress (CompressedTexFormat format, TexDecompressionParams::AstcMode mode, size_t numBlocks, const deUint8* data)
69{
70	const IVec3						blockPixelSize			= getBlockPixelSize(format);
71	const TexDecompressionParams	decompressionParams		(mode);
72	const TextureFormat				uncompressedFormat		= getUncompressedFormat(format);
73	TextureLevel					texture					(uncompressedFormat, blockPixelSize.x()*(int)numBlocks, blockPixelSize.y());
74
75	decompress(texture.getAccess(), format, data, decompressionParams);
76}
77
78void testDecompress (CompressedTexFormat format, size_t numBlocks, const deUint8* data)
79{
80	testDecompress(format, TexDecompressionParams::ASTCMODE_LDR, numBlocks, data);
81
82	if (!isAstcSRGBFormat(format))
83		testDecompress(format, TexDecompressionParams::ASTCMODE_HDR, numBlocks, data);
84}
85
86void verifyBlocksValid (CompressedTexFormat format, TexDecompressionParams::AstcMode mode, size_t numBlocks, const deUint8* data)
87{
88	for (size_t blockNdx = 0; blockNdx < numBlocks; blockNdx++)
89	{
90		if (!astc::isValidBlock(data + blockNdx*astc::BLOCK_SIZE_BYTES, format, mode))
91			TCU_FAIL("Invalid ASTC block was generated");
92	}
93}
94
95inline size_t getNumBlocksFromBytes (size_t numBytes)
96{
97	TCU_CHECK(numBytes % astc::BLOCK_SIZE_BYTES == 0);
98	return (numBytes / astc::BLOCK_SIZE_BYTES);
99}
100
101AstcCase::IterateResult AstcCase::iterate (void)
102{
103	vector<deUint8> generatedData;
104
105	// Verify that can generate & decode data with all BlockTestType's
106	for (int blockTestTypeNdx = 0; blockTestTypeNdx < astc::BLOCK_TEST_TYPE_LAST; blockTestTypeNdx++)
107	{
108		const astc::BlockTestType	blockTestType	= (const astc::BlockTestType)blockTestTypeNdx;
109
110		if (astc::isBlockTestTypeHDROnly(blockTestType) && isAstcSRGBFormat(m_format))
111			continue;
112
113		generatedData.clear();
114		astc::generateBlockCaseTestData(generatedData, m_format, blockTestType);
115
116		testDecompress(m_format, getNumBlocksFromBytes(generatedData.size()), &generatedData[0]);
117
118		// All but random case should generate only valid blocks
119		if (blockTestType != astc::BLOCK_TEST_TYPE_RANDOM)
120		{
121			// \note CEMS generates HDR blocks as well
122			if (!astc::isBlockTestTypeHDROnly(blockTestType) &&
123				(blockTestType != astc::BLOCK_TEST_TYPE_CEMS))
124				verifyBlocksValid(m_format, TexDecompressionParams::ASTCMODE_LDR, getNumBlocksFromBytes(generatedData.size()), &generatedData[0]);
125
126			if (!isAstcSRGBFormat(m_format))
127				verifyBlocksValid(m_format, TexDecompressionParams::ASTCMODE_HDR, getNumBlocksFromBytes(generatedData.size()), &generatedData[0]);
128		}
129	}
130
131	// Verify generating void extent blocks (format-independent)
132	{
133		const size_t		numBlocks		= 1024;
134
135		generatedData.resize(numBlocks*astc::BLOCK_SIZE_BYTES);
136		astc::generateDummyVoidExtentBlocks(&generatedData[0], numBlocks);
137
138		testDecompress(m_format, numBlocks, &generatedData[0]);
139
140		verifyBlocksValid(m_format, TexDecompressionParams::ASTCMODE_LDR, numBlocks, &generatedData[0]);
141
142		if (!isAstcSRGBFormat(m_format))
143			verifyBlocksValid(m_format, TexDecompressionParams::ASTCMODE_HDR, numBlocks, &generatedData[0]);
144	}
145
146	// Verify generating dummy normal blocks
147	{
148		const size_t		numBlocks			= 1024;
149		const IVec3			blockPixelSize		= getBlockPixelSize(m_format);
150
151		generatedData.resize(numBlocks*astc::BLOCK_SIZE_BYTES);
152		astc::generateDummyNormalBlocks(&generatedData[0], numBlocks, blockPixelSize.x(), blockPixelSize.y());
153
154		testDecompress(m_format, numBlocks, &generatedData[0]);
155
156		verifyBlocksValid(m_format, TexDecompressionParams::ASTCMODE_LDR, numBlocks, &generatedData[0]);
157
158		if (!isAstcSRGBFormat(m_format))
159			verifyBlocksValid(m_format, TexDecompressionParams::ASTCMODE_HDR, numBlocks, &generatedData[0]);
160	}
161
162	// Verify generating random valid blocks
163	for (int astcModeNdx = 0; astcModeNdx < TexDecompressionParams::ASTCMODE_LAST; astcModeNdx++)
164	{
165		const TexDecompressionParams::AstcMode	mode		= (TexDecompressionParams::AstcMode)astcModeNdx;
166		const size_t							numBlocks	= 1024;
167
168		if (mode == tcu::TexDecompressionParams::ASTCMODE_HDR && isAstcFormat(m_format))
169			continue; // sRGB is not supported in HDR mode
170
171		generatedData.resize(numBlocks*astc::BLOCK_SIZE_BYTES);
172		astc::generateRandomValidBlocks(&generatedData[0], numBlocks, m_format, mode, deInt32Hash(m_format) ^ deInt32Hash(mode));
173
174		testDecompress(m_format, numBlocks, &generatedData[0]);
175
176		verifyBlocksValid(m_format, mode, numBlocks, &generatedData[0]);
177	}
178
179	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All checks passed");
180	return STOP;
181}
182
183} // anonymous
184
185tcu::TestCaseGroup* createAstcTests (tcu::TestContext& testCtx)
186{
187	de::MovePtr<tcu::TestCaseGroup>	astcTests	(new tcu::TestCaseGroup(testCtx, "astc", "Tests for ASTC Utilities"));
188
189	for (int formatNdx = 0; formatNdx < COMPRESSEDTEXFORMAT_LAST; formatNdx++)
190	{
191		const CompressedTexFormat	format	= (CompressedTexFormat)formatNdx;
192
193		if (isAstcFormat(format))
194			astcTests->addChild(new AstcCase(testCtx, format));
195	}
196
197	return astcTests.release();
198}
199
200} // dit
201