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