1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Compressed texture tests.
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktTextureCompressedFormatTests.hpp"
27
28 #include "deString.h"
29 #include "deStringUtil.hpp"
30 #include "tcuCompressedTexture.hpp"
31 #include "tcuTexture.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuAstcUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vktTestGroupUtil.hpp"
36 #include "vktTextureTestUtil.hpp"
37 #include <string>
38 #include <vector>
39
40 namespace vkt
41 {
42 namespace texture
43 {
44 namespace
45 {
46
47 using namespace vk;
48 using namespace glu::TextureTestUtil;
49 using namespace texture::util;
50
51 using std::string;
52 using std::vector;
53 using tcu::Sampler;
54 using tcu::TestLog;
55
56 // Compressed formats
57 static const struct {
58 const VkFormat format;
59 } formats[] =
60 {
61 { VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK },
62 { VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK },
63 { VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK },
64 { VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK },
65 { VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK },
66 { VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK },
67
68 { VK_FORMAT_EAC_R11_UNORM_BLOCK },
69 { VK_FORMAT_EAC_R11_SNORM_BLOCK },
70 { VK_FORMAT_EAC_R11G11_UNORM_BLOCK },
71 { VK_FORMAT_EAC_R11G11_SNORM_BLOCK },
72
73 { VK_FORMAT_ASTC_4x4_UNORM_BLOCK },
74 { VK_FORMAT_ASTC_4x4_SRGB_BLOCK },
75 { VK_FORMAT_ASTC_5x4_UNORM_BLOCK },
76 { VK_FORMAT_ASTC_5x4_SRGB_BLOCK },
77 { VK_FORMAT_ASTC_5x5_UNORM_BLOCK },
78 { VK_FORMAT_ASTC_5x5_SRGB_BLOCK },
79 { VK_FORMAT_ASTC_6x5_UNORM_BLOCK },
80 { VK_FORMAT_ASTC_6x5_SRGB_BLOCK },
81 { VK_FORMAT_ASTC_6x6_UNORM_BLOCK },
82 { VK_FORMAT_ASTC_6x6_SRGB_BLOCK },
83 { VK_FORMAT_ASTC_8x5_UNORM_BLOCK },
84 { VK_FORMAT_ASTC_8x5_SRGB_BLOCK },
85 { VK_FORMAT_ASTC_8x6_UNORM_BLOCK },
86 { VK_FORMAT_ASTC_8x6_SRGB_BLOCK },
87 { VK_FORMAT_ASTC_8x8_UNORM_BLOCK },
88 { VK_FORMAT_ASTC_8x8_SRGB_BLOCK },
89 { VK_FORMAT_ASTC_10x5_UNORM_BLOCK },
90 { VK_FORMAT_ASTC_10x5_SRGB_BLOCK },
91 { VK_FORMAT_ASTC_10x6_UNORM_BLOCK },
92 { VK_FORMAT_ASTC_10x6_SRGB_BLOCK },
93 { VK_FORMAT_ASTC_10x8_UNORM_BLOCK },
94 { VK_FORMAT_ASTC_10x8_SRGB_BLOCK },
95 { VK_FORMAT_ASTC_10x10_UNORM_BLOCK },
96 { VK_FORMAT_ASTC_10x10_SRGB_BLOCK },
97 { VK_FORMAT_ASTC_12x10_UNORM_BLOCK },
98 { VK_FORMAT_ASTC_12x10_SRGB_BLOCK },
99 { VK_FORMAT_ASTC_12x12_UNORM_BLOCK },
100 { VK_FORMAT_ASTC_12x12_SRGB_BLOCK },
101
102 { VK_FORMAT_BC1_RGB_UNORM_BLOCK },
103 { VK_FORMAT_BC1_RGB_SRGB_BLOCK },
104 { VK_FORMAT_BC1_RGBA_UNORM_BLOCK },
105 { VK_FORMAT_BC1_RGBA_SRGB_BLOCK },
106 { VK_FORMAT_BC2_UNORM_BLOCK },
107 { VK_FORMAT_BC2_SRGB_BLOCK },
108 { VK_FORMAT_BC3_UNORM_BLOCK },
109 { VK_FORMAT_BC3_SRGB_BLOCK },
110 { VK_FORMAT_BC4_UNORM_BLOCK },
111 { VK_FORMAT_BC4_SNORM_BLOCK },
112 { VK_FORMAT_BC5_UNORM_BLOCK },
113 { VK_FORMAT_BC5_SNORM_BLOCK },
114 { VK_FORMAT_BC6H_UFLOAT_BLOCK },
115 { VK_FORMAT_BC6H_SFLOAT_BLOCK },
116 { VK_FORMAT_BC7_UNORM_BLOCK },
117 { VK_FORMAT_BC7_SRGB_BLOCK }
118 };
119
120 static const struct {
121 const int width;
122 const int height;
123 const int depth; // 2D test ignore depth value
124 const char* name;
125 } sizes[] =
126 {
127 { 128, 64, 8, "pot" },
128 { 51, 65, 17, "npot" },
129 };
130
131 static const struct {
132 const char* name;
133 const TextureBinding::ImageBackingMode backingMode;
134 } backingModes[] =
135 {
136 { "", TextureBinding::IMAGE_BACKING_MODE_REGULAR },
137 { "_sparse", TextureBinding::IMAGE_BACKING_MODE_SPARSE }
138 };
139
140 struct Compressed3DTestParameters : public Texture3DTestCaseParameters
141 {
142 Compressed3DTestParameters (void);
143 TextureBinding::ImageBackingMode backingMode;
144 };
145
Compressed3DTestParameters(void)146 Compressed3DTestParameters::Compressed3DTestParameters (void)
147 : backingMode(TextureBinding::IMAGE_BACKING_MODE_REGULAR)
148 {
149 }
150
151 struct Compressed2DTestParameters : public Texture2DTestCaseParameters
152 {
153 Compressed2DTestParameters (void);
154 TextureBinding::ImageBackingMode backingMode;
155 };
156
Compressed2DTestParameters(void)157 Compressed2DTestParameters::Compressed2DTestParameters (void)
158 : backingMode(TextureBinding::IMAGE_BACKING_MODE_REGULAR)
159 {
160 }
161
162 class Compressed2DTestInstance : public TestInstance
163 {
164 public:
165 typedef Compressed2DTestParameters ParameterType;
166
167 Compressed2DTestInstance (Context& context,
168 const ParameterType& testParameters);
169 tcu::TestStatus iterate (void);
170
171 private:
172 Compressed2DTestInstance (const Compressed2DTestInstance& other);
173 Compressed2DTestInstance& operator= (const Compressed2DTestInstance& other);
174
175 const ParameterType& m_testParameters;
176 const tcu::CompressedTexFormat m_compressedFormat;
177 TestTexture2DSp m_texture;
178 TextureRenderer m_renderer;
179 };
180
Compressed2DTestInstance(Context & context,const ParameterType & testParameters)181 Compressed2DTestInstance::Compressed2DTestInstance (Context& context,
182 const ParameterType& testParameters)
183 : TestInstance (context)
184 , m_testParameters (testParameters)
185 , m_compressedFormat (mapVkCompressedFormat(testParameters.format))
186 , m_texture (TestTexture2DSp(new pipeline::TestTexture2D(m_compressedFormat, testParameters.width, testParameters.height)))
187 , m_renderer (context, testParameters.sampleCount, testParameters.width, testParameters.height)
188 {
189 m_renderer.add2DTexture(m_texture, testParameters.aspectMask, testParameters.backingMode);
190 }
191
iterate(void)192 tcu::TestStatus Compressed2DTestInstance::iterate (void)
193 {
194 tcu::TestLog& log = m_context.getTestContext().getLog();
195 const pipeline::TestTexture2D& texture = m_renderer.get2DTexture(0);
196 const tcu::TextureFormat textureFormat = texture.getTextureFormat();
197 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(textureFormat);
198
199 ReferenceParams sampleParams (TEXTURETYPE_2D);
200 tcu::Surface rendered (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
201 vector<float> texCoord;
202
203 // Setup params for reference.
204 sampleParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
205 sampleParams.samplerType = SAMPLERTYPE_FLOAT;
206 sampleParams.lodMode = LODMODE_EXACT;
207
208 if (isAstcFormat(m_compressedFormat)
209 || m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK
210 || m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK)
211 {
212 sampleParams.colorBias = tcu::Vec4(0.0f);
213 sampleParams.colorScale = tcu::Vec4(1.0f);
214 }
215 else if (m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK)
216 {
217 sampleParams.colorBias = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f);
218 sampleParams.colorScale = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f);
219 }
220 else if (m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK)
221 {
222 sampleParams.colorBias = tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f);
223 sampleParams.colorScale = tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f);
224 }
225 else
226 {
227 sampleParams.colorBias = formatInfo.lookupBias;
228 sampleParams.colorScale = formatInfo.lookupScale;
229 }
230
231 log << TestLog::Message << "Compare reference value = " << sampleParams.ref << TestLog::EndMessage;
232
233 // Compute texture coordinates.
234 computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
235
236 m_renderer.renderQuad(rendered, 0, &texCoord[0], sampleParams);
237
238 // Compute reference.
239 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
240 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
241 tcu::Surface referenceFrame (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
242 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat), m_texture->getTexture(), &texCoord[0], sampleParams);
243
244 // Compare and log.
245 tcu::RGBA threshold;
246
247 if (isBcBitExactFormat(m_compressedFormat))
248 threshold = tcu::RGBA(1, 1, 1, 1);
249 else if (isBcFormat(m_compressedFormat))
250 threshold = tcu::RGBA(8, 8, 8, 8);
251 else
252 threshold = pixelFormat.getColorThreshold() + tcu::RGBA(2, 2, 2, 2);
253
254 const bool isOk = compareImages(log, referenceFrame, rendered, threshold);
255
256 return isOk ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Image verification failed");
257 }
258
259 class Compressed3DTestInstance : public TestInstance
260 {
261 public:
262 typedef Compressed3DTestParameters ParameterType;
263
264 Compressed3DTestInstance (Context& context,
265 const ParameterType& testParameters);
266 tcu::TestStatus iterate (void);
267
268 private:
269 Compressed3DTestInstance (const Compressed3DTestInstance& other);
270 Compressed3DTestInstance& operator= (const Compressed3DTestInstance& other);
271
272 const ParameterType& m_testParameters;
273 const tcu::CompressedTexFormat m_compressedFormat;
274 TestTexture3DSp m_texture3D;
275 TextureRenderer m_renderer3D;
276 };
277
Compressed3DTestInstance(Context & context,const ParameterType & testParameters)278 Compressed3DTestInstance::Compressed3DTestInstance (Context& context,
279 const ParameterType& testParameters)
280 : TestInstance (context)
281 , m_testParameters (testParameters)
282 , m_compressedFormat (mapVkCompressedFormat(testParameters.format))
283 , m_texture3D (TestTexture3DSp(new pipeline::TestTexture3D(m_compressedFormat, testParameters.width, testParameters.height, testParameters.depth)))
284 , m_renderer3D (context, testParameters.sampleCount, testParameters.width, testParameters.height, testParameters.depth, makeComponentMappingRGBA(), VK_IMAGE_TYPE_3D, VK_IMAGE_VIEW_TYPE_3D)
285 {
286 m_renderer3D.add3DTexture (m_texture3D, testParameters.aspectMask, testParameters.backingMode);
287
288 VkPhysicalDeviceFeatures physicalFeatures;
289 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &physicalFeatures);
290
291 if (tcu::isAstcFormat(m_compressedFormat))
292 {
293 if (!physicalFeatures.textureCompressionASTC_LDR)
294 throw tcu::NotSupportedError(std::string("Unsupported format: ") + getFormatName(testParameters.format));
295 }
296 else if (tcu::isEtcFormat(m_compressedFormat))
297 {
298 if (!physicalFeatures.textureCompressionETC2)
299 throw tcu::NotSupportedError(std::string("Unsupported format: ") + getFormatName(testParameters.format));
300 }
301 else if(tcu::isBcFormat(m_compressedFormat))
302 {
303 if (!physicalFeatures.textureCompressionBC)
304 throw tcu::NotSupportedError(std::string("Unsupported format: ") + getFormatName(testParameters.format));
305 }
306 else
307 {
308 DE_FATAL("Unsupported compressed format");
309 }
310 }
311
iterate(void)312 tcu::TestStatus Compressed3DTestInstance::iterate (void)
313 {
314 tcu::TestLog& log = m_context.getTestContext().getLog();
315 const pipeline::TestTexture3D& texture = m_renderer3D.get3DTexture(0);
316 const tcu::TextureFormat textureFormat = texture.getTextureFormat();
317 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(textureFormat);
318
319 ReferenceParams sampleParams (TEXTURETYPE_3D);
320 tcu::Surface rendered (m_renderer3D.getRenderWidth(), m_renderer3D.getRenderHeight());
321 vector<float> texCoord;
322
323 // Setup params for reference.
324 sampleParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
325 sampleParams.samplerType = SAMPLERTYPE_FLOAT;
326 sampleParams.lodMode = LODMODE_EXACT;
327
328 if (isAstcFormat(m_compressedFormat)
329 || m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK
330 || m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK)
331 {
332 sampleParams.colorBias = tcu::Vec4(0.0f);
333 sampleParams.colorScale = tcu::Vec4(1.0f);
334 }
335 else if (m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK)
336 {
337 sampleParams.colorBias = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f);
338 sampleParams.colorScale = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f);
339 }
340 else if (m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK)
341 {
342 sampleParams.colorBias = tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f);
343 sampleParams.colorScale = tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f);
344 }
345 else
346 {
347 sampleParams.colorBias = formatInfo.lookupBias;
348 sampleParams.colorScale = formatInfo.lookupScale;
349 }
350
351 log << TestLog::Message << "Compare reference value = " << sampleParams.ref << TestLog::EndMessage;
352
353 constexpr deUint32 slices = 3;
354 deUint32 sliceNdx = 0;
355 float z = 0;
356 bool isOk = false;
357 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
358 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
359 tcu::RGBA threshold;
360
361 if (isBcBitExactFormat(m_compressedFormat))
362 threshold = tcu::RGBA(1, 1, 1, 1);
363 else if (isBcSRGBFormat(m_compressedFormat))
364 threshold = tcu::RGBA(9, 9, 9, 9);
365 else if (isBcFormat(m_compressedFormat))
366 threshold = tcu::RGBA(8, 8, 8, 8);
367 else
368 threshold = pixelFormat.getColorThreshold() + tcu::RGBA(2, 2, 2, 2);
369
370 for (deUint32 s = 0; s < slices; ++s)
371 {
372 // Test different slices of 3D texture.
373
374 sliceNdx = (m_testParameters.depth - 1) * s / (slices - 1);
375
376 // Render texture.
377 z = ((float)sliceNdx + 0.5f) / (float)m_testParameters.depth;
378 computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, z), tcu::Vec3(1.0f, 1.0f, z), tcu::IVec3(0,1,2));
379 m_renderer3D.renderQuad(rendered, 0, &texCoord[0], sampleParams);
380
381 // Compute reference.
382 tcu::Surface referenceFrame (m_renderer3D.getRenderWidth(), m_renderer3D.getRenderHeight());
383 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat), m_texture3D->getTexture(), &texCoord[0], sampleParams);
384
385 // Compare and log.
386 isOk = compareImages(log, referenceFrame, rendered, threshold);
387
388 if (!isOk)
389 break;
390 }
391
392 return isOk ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Image verification failed");
393 }
394
395 } // anonymous
396
populateTextureCompressedFormatTests(tcu::TestCaseGroup * compressedTextureTests)397 void populateTextureCompressedFormatTests (tcu::TestCaseGroup* compressedTextureTests)
398 {
399 tcu::TestContext& testCtx = compressedTextureTests->getTestContext();
400
401 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); sizeNdx++)
402 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
403 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); backingNdx++)
404 {
405 const string formatStr = de::toString(getFormatStr(formats[formatNdx].format));
406 const string nameBase = de::toLower(formatStr.substr(10));
407
408 Compressed2DTestParameters testParameters;
409 testParameters.format = formats[formatNdx].format;
410 testParameters.backingMode = backingModes[backingNdx].backingMode;
411 testParameters.width = sizes[sizeNdx].width;
412 testParameters.height = sizes[sizeNdx].height;
413 testParameters.minFilter = tcu::Sampler::NEAREST;
414 testParameters.magFilter = tcu::Sampler::NEAREST;
415 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
416 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
417
418 compressedTextureTests->addChild(new TextureTestCase<Compressed2DTestInstance>(testCtx, (nameBase + "_2d_" + sizes[sizeNdx].name + backingModes[backingNdx].name).c_str(), (formatStr + ", TEXTURETYPE_2D").c_str(), testParameters));
419 }
420 }
421
populate3DTextureCompressedFormatTests(tcu::TestCaseGroup * compressedTextureTests)422 void populate3DTextureCompressedFormatTests (tcu::TestCaseGroup* compressedTextureTests)
423 {
424 tcu::TestContext& testCtx = compressedTextureTests->getTestContext();
425
426 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
427 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
428 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); ++backingNdx)
429 {
430 const string formatStr = de::toString(getFormatStr(formats[formatNdx].format));
431 const string nameBase = de::toLower(formatStr.substr(10));
432
433 Compressed3DTestParameters testParameters;
434 testParameters.format = formats[formatNdx].format;
435 testParameters.backingMode = backingModes[backingNdx].backingMode;
436 testParameters.width = sizes[sizeNdx].width;
437 testParameters.height = sizes[sizeNdx].height;
438 testParameters.depth = sizes[sizeNdx].depth;
439 testParameters.minFilter = tcu::Sampler::NEAREST;
440 testParameters.magFilter = tcu::Sampler::NEAREST;
441 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
442 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
443
444 compressedTextureTests->addChild(new TextureTestCase<Compressed3DTestInstance>(testCtx, (nameBase + "_3d_" + sizes[sizeNdx].name + backingModes[backingNdx].name).c_str(), (formatStr + ", TEXTURETYPE_3D").c_str(), testParameters));
445 }
446 }
447
createTextureCompressedFormatTests(tcu::TestContext & testCtx)448 tcu::TestCaseGroup* createTextureCompressedFormatTests (tcu::TestContext& testCtx)
449 {
450 return createTestGroup(testCtx, "compressed", "Texture compressed format tests.", populateTextureCompressedFormatTests);
451 }
452
create3DTextureCompressedFormatTests(tcu::TestContext & testCtx)453 tcu::TestCaseGroup* create3DTextureCompressedFormatTests (tcu::TestContext& testCtx)
454 {
455 return createTestGroup(testCtx, "compressed_3D", "3D texture compressed format tests.", populate3DTextureCompressedFormatTests);
456 }
457
458 } // texture
459 } // vkt
460