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 "tcuImageCompare.hpp"
32 #include "tcuTexture.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include "tcuVectorUtil.hpp"
35 #include "tcuAstcUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vktTestGroupUtil.hpp"
38 #include "vktTextureTestUtil.hpp"
39 #include <string>
40 #include <vector>
41
42 namespace vkt
43 {
44 namespace texture
45 {
46 namespace
47 {
48
49 using namespace vk;
50 using namespace glu::TextureTestUtil;
51 using namespace texture::util;
52
53 using std::string;
54 using std::vector;
55 using tcu::Sampler;
56 using tcu::TestLog;
57
58 // Compressed formats
59 static const struct
60 {
61 const VkFormat format;
62 } formats[] = {{VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK}, {VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK},
63 {VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK}, {VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK},
64 {VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK}, {VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK},
65
66 {VK_FORMAT_EAC_R11_UNORM_BLOCK}, {VK_FORMAT_EAC_R11_SNORM_BLOCK},
67 {VK_FORMAT_EAC_R11G11_UNORM_BLOCK}, {VK_FORMAT_EAC_R11G11_SNORM_BLOCK},
68
69 {VK_FORMAT_ASTC_4x4_UNORM_BLOCK}, {VK_FORMAT_ASTC_4x4_SRGB_BLOCK},
70 {VK_FORMAT_ASTC_5x4_UNORM_BLOCK}, {VK_FORMAT_ASTC_5x4_SRGB_BLOCK},
71 {VK_FORMAT_ASTC_5x5_UNORM_BLOCK}, {VK_FORMAT_ASTC_5x5_SRGB_BLOCK},
72 {VK_FORMAT_ASTC_6x5_UNORM_BLOCK}, {VK_FORMAT_ASTC_6x5_SRGB_BLOCK},
73 {VK_FORMAT_ASTC_6x6_UNORM_BLOCK}, {VK_FORMAT_ASTC_6x6_SRGB_BLOCK},
74 {VK_FORMAT_ASTC_8x5_UNORM_BLOCK}, {VK_FORMAT_ASTC_8x5_SRGB_BLOCK},
75 {VK_FORMAT_ASTC_8x6_UNORM_BLOCK}, {VK_FORMAT_ASTC_8x6_SRGB_BLOCK},
76 {VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, {VK_FORMAT_ASTC_8x8_SRGB_BLOCK},
77 {VK_FORMAT_ASTC_10x5_UNORM_BLOCK}, {VK_FORMAT_ASTC_10x5_SRGB_BLOCK},
78 {VK_FORMAT_ASTC_10x6_UNORM_BLOCK}, {VK_FORMAT_ASTC_10x6_SRGB_BLOCK},
79 {VK_FORMAT_ASTC_10x8_UNORM_BLOCK}, {VK_FORMAT_ASTC_10x8_SRGB_BLOCK},
80 {VK_FORMAT_ASTC_10x10_UNORM_BLOCK}, {VK_FORMAT_ASTC_10x10_SRGB_BLOCK},
81 {VK_FORMAT_ASTC_12x10_UNORM_BLOCK}, {VK_FORMAT_ASTC_12x10_SRGB_BLOCK},
82 {VK_FORMAT_ASTC_12x12_UNORM_BLOCK}, {VK_FORMAT_ASTC_12x12_SRGB_BLOCK},
83
84 {VK_FORMAT_BC1_RGB_UNORM_BLOCK}, {VK_FORMAT_BC1_RGB_SRGB_BLOCK},
85 {VK_FORMAT_BC1_RGBA_UNORM_BLOCK}, {VK_FORMAT_BC1_RGBA_SRGB_BLOCK},
86 {VK_FORMAT_BC2_UNORM_BLOCK}, {VK_FORMAT_BC2_SRGB_BLOCK},
87 {VK_FORMAT_BC3_UNORM_BLOCK}, {VK_FORMAT_BC3_SRGB_BLOCK},
88 {VK_FORMAT_BC4_UNORM_BLOCK}, {VK_FORMAT_BC4_SNORM_BLOCK},
89 {VK_FORMAT_BC5_UNORM_BLOCK}, {VK_FORMAT_BC5_SNORM_BLOCK},
90 {VK_FORMAT_BC6H_UFLOAT_BLOCK}, {VK_FORMAT_BC6H_SFLOAT_BLOCK},
91 {VK_FORMAT_BC7_UNORM_BLOCK}, {VK_FORMAT_BC7_SRGB_BLOCK}};
92
93 static const struct
94 {
95 const int width;
96 const int height;
97 const int depth; // 2D test ignore depth value
98 const bool mipmaps;
99 const char *name;
100 } sizes[] = {
101 {128, 64, 8, false, "pot"},
102 {51, 65, 17, false, "npot"},
103 {51, 65, 17, true, "npot_mip1"},
104 };
105
106 static const struct
107 {
108 const char *name;
109 const TextureBinding::ImageBackingMode backingMode;
110 } backingModes[] = {{"", TextureBinding::IMAGE_BACKING_MODE_REGULAR},
111 #ifndef CTS_USES_VULKANSC
112 {"_sparse", TextureBinding::IMAGE_BACKING_MODE_SPARSE}
113 #endif // CTS_USES_VULKANSC
114 };
115
116 struct Compressed3DTestParameters : public Texture3DTestCaseParameters
117 {
118 Compressed3DTestParameters(void);
119 TextureBinding::ImageBackingMode backingMode;
120 };
121
Compressed3DTestParameters(void)122 Compressed3DTestParameters::Compressed3DTestParameters(void) : backingMode(TextureBinding::IMAGE_BACKING_MODE_REGULAR)
123 {
124 }
125
126 struct Compressed2DTestParameters : public Texture2DTestCaseParameters
127 {
128 Compressed2DTestParameters(void);
129 TextureBinding::ImageBackingMode backingMode;
130 };
131
Compressed2DTestParameters(void)132 Compressed2DTestParameters::Compressed2DTestParameters(void) : backingMode(TextureBinding::IMAGE_BACKING_MODE_REGULAR)
133 {
134 }
135
136 class Compressed2DTestInstance : public TestInstance
137 {
138 public:
139 typedef Compressed2DTestParameters ParameterType;
140
141 Compressed2DTestInstance(Context &context, const ParameterType &testParameters);
142 tcu::TestStatus iterate(void);
143
144 private:
145 Compressed2DTestInstance(const Compressed2DTestInstance &other);
146 Compressed2DTestInstance &operator=(const Compressed2DTestInstance &other);
147
148 const ParameterType &m_testParameters;
149 const tcu::CompressedTexFormat m_compressedFormat;
150 TestTexture2DSp m_texture;
151 TextureRenderer m_renderer;
152 };
153
Compressed2DTestInstance(Context & context,const ParameterType & testParameters)154 Compressed2DTestInstance::Compressed2DTestInstance(Context &context, const ParameterType &testParameters)
155 : TestInstance(context)
156 , m_testParameters(testParameters)
157 , m_compressedFormat(mapVkCompressedFormat(testParameters.format))
158 , m_texture(
159 TestTexture2DSp(new pipeline::TestTexture2D(m_compressedFormat, testParameters.width, testParameters.height)))
160 , m_renderer(context, testParameters.sampleCount, testParameters.width, testParameters.height)
161 {
162 m_renderer.add2DTexture(m_texture, testParameters.aspectMask, testParameters.backingMode);
163 }
164
computeScaleAndBias(const tcu::ConstPixelBufferAccess & reference,const tcu::ConstPixelBufferAccess & result,tcu::Vec4 & scale,tcu::Vec4 & bias)165 static void computeScaleAndBias(const tcu::ConstPixelBufferAccess &reference, const tcu::ConstPixelBufferAccess &result,
166 tcu::Vec4 &scale, tcu::Vec4 &bias)
167 {
168 tcu::Vec4 minVal;
169 tcu::Vec4 maxVal;
170 const float eps = 0.0001f;
171
172 {
173 tcu::Vec4 refMin;
174 tcu::Vec4 refMax;
175 estimatePixelValueRange(reference, refMin, refMax);
176
177 minVal = refMin;
178 maxVal = refMax;
179 }
180
181 {
182 tcu::Vec4 resMin;
183 tcu::Vec4 resMax;
184
185 estimatePixelValueRange(result, resMin, resMax);
186
187 minVal[0] = de::min(minVal[0], resMin[0]);
188 minVal[1] = de::min(minVal[1], resMin[1]);
189 minVal[2] = de::min(minVal[2], resMin[2]);
190 minVal[3] = de::min(minVal[3], resMin[3]);
191
192 maxVal[0] = de::max(maxVal[0], resMax[0]);
193 maxVal[1] = de::max(maxVal[1], resMax[1]);
194 maxVal[2] = de::max(maxVal[2], resMax[2]);
195 maxVal[3] = de::max(maxVal[3], resMax[3]);
196 }
197
198 for (int c = 0; c < 4; c++)
199 {
200 if (maxVal[c] - minVal[c] < eps)
201 {
202 scale[c] = (maxVal[c] < eps) ? 1.0f : (1.0f / maxVal[c]);
203 bias[c] = (c == 3) ? (1.0f - maxVal[c] * scale[c]) : (0.0f - minVal[c] * scale[c]);
204 }
205 else
206 {
207 scale[c] = 1.0f / (maxVal[c] - minVal[c]);
208 bias[c] = 0.0f - minVal[c] * scale[c];
209 }
210 }
211 }
212
min(tcu::UVec4 a,tcu::UVec4 b)213 static inline tcu::UVec4 min(tcu::UVec4 a, tcu::UVec4 b)
214 {
215 return tcu::UVec4(deMin32(a[0], b[0]), deMin32(a[1], b[1]), deMin32(a[2], b[2]), deMin32(a[3], b[3]));
216 }
217
compareColor(tcu::RGBA reference,tcu::RGBA result,tcu::RGBA threshold,tcu::UVec4 & diff)218 static bool compareColor(tcu::RGBA reference, tcu::RGBA result, tcu::RGBA threshold, tcu::UVec4 &diff)
219 {
220 const tcu::IVec4 refPix = reference.toIVec();
221 const tcu::IVec4 cmpPix = result.toIVec();
222 const tcu::UVec4 thresholdVec = threshold.toIVec().cast<uint32_t>();
223 diff = abs(refPix - cmpPix).cast<uint32_t>();
224
225 return boolAll(lessThanEqual(diff, thresholdVec));
226 }
227
228 template <typename TextureType>
validateTexture(tcu::TestLog & log,const tcu::Surface & rendered,const TextureType & texture,const vector<float> & texCoord,uint32_t mipLevel,const tcu::PixelFormat & pixelFormat,const tcu::RGBA & colorThreshold,float coordThreshold,const ReferenceParams sampleParams)229 static bool validateTexture(tcu::TestLog &log, const tcu::Surface &rendered, const TextureType &texture,
230 const vector<float> &texCoord, uint32_t mipLevel, const tcu::PixelFormat &pixelFormat,
231 const tcu::RGBA &colorThreshold, float coordThreshold, const ReferenceParams sampleParams)
232 {
233 const uint32_t textureWidth = texture.getWidth() >> mipLevel;
234 const uint32_t textureHeight = texture.getHeight() >> mipLevel;
235 const uint32_t renderWidth = rendered.getWidth();
236 const uint32_t renderHeight = rendered.getHeight();
237
238 tcu::TextureLevel errorMaskStorage(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8),
239 renderWidth, renderHeight, 1);
240 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
241
242 tcu::UVec4 maxDiff(0u, 0u, 0u, 0u);
243 tcu::UVec4 smpDiff(0u, 0u, 0u, 0u);
244 tcu::UVec4 diff(0u, 0u, 0u, 0u);
245 bool isOk = true;
246
247 // Compute reference.
248 tcu::Surface referenceFrame(textureWidth, textureHeight);
249 glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat), texture, &texCoord[0],
250 sampleParams);
251
252 for (uint32_t x = 0; x < renderWidth; ++x)
253 {
254 for (uint32_t y = 0; y < renderHeight; ++y)
255 {
256 bool matchFound = false;
257 const tcu::RGBA rendered_color = rendered.getPixel(x, y);
258
259 const float fragX = ((float)x + 0.5f) / (float)renderWidth;
260 const float fragY = ((float)y + 0.5f) / (float)renderHeight;
261 const float samplePixX = fragX * (float)(textureWidth);
262 const float samplePixY = fragY * (float)(textureHeight);
263
264 const uint32_t sampleXMin = (int)(samplePixX - coordThreshold);
265 const uint32_t sampleXMax = (int)(samplePixX + coordThreshold);
266 const uint32_t sampleYMin = (int)(samplePixY - coordThreshold);
267 const uint32_t sampleYMax = (int)(samplePixY + coordThreshold);
268
269 // Compare color within given sample coordinates tolerance and return from included loops when match is found
270 for (uint32_t smpX = sampleXMin; smpX <= sampleXMax; ++smpX)
271 {
272 for (uint32_t smpY = sampleYMin; smpY <= sampleYMax; ++smpY)
273 {
274 const tcu::RGBA reference_color = referenceFrame.getPixel(smpX, smpY);
275
276 if (compareColor(reference_color, rendered_color, colorThreshold, diff))
277 matchFound = true;
278
279 smpDiff = min(smpDiff, diff);
280 }
281 }
282
283 maxDiff = tcu::max(maxDiff, smpDiff);
284 errorMask.setPixel(matchFound ? tcu::IVec4(0, 0xff, 0, 0xff) : tcu::IVec4(0xff, 0, 0, 0xff), x, y);
285
286 // Color mismatch
287 if (!matchFound)
288 {
289 isOk = false;
290 }
291 }
292 }
293
294 const tcu::ConstPixelBufferAccess result = rendered.getAccess();
295 const tcu::ConstPixelBufferAccess reference = referenceFrame.getAccess();
296 const char *imageSetName = "Result";
297 const char *imageSetDesc = "Image comparison result";
298 tcu::Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
299 tcu::Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);
300
301 if (!isOk)
302 {
303 // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
304 if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
305 tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
306 {
307 computeScaleAndBias(reference, result, pixelScale, pixelBias);
308 log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale
309 << " + " << pixelBias << TestLog::EndMessage;
310 }
311
312 log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff
313 << ", color threshold = " << colorThreshold.toIVec().cast<uint32_t>()
314 << ", coordinates threshold = " << coordThreshold << TestLog::EndMessage;
315
316 log << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
317 << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
318 }
319 else
320 {
321 if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
322 computePixelScaleBias(result, pixelScale, pixelBias);
323
324 log << TestLog::ImageSet(imageSetName, imageSetDesc)
325 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
326 }
327
328 return isOk;
329 }
330
iterate(void)331 tcu::TestStatus Compressed2DTestInstance::iterate(void)
332 {
333 tcu::TestLog &log = m_context.getTestContext().getLog();
334 const pipeline::TestTexture2D &texture = m_renderer.get2DTexture(0);
335 const tcu::TextureFormat textureFormat = texture.getTextureFormat();
336 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(textureFormat);
337 const uint32_t mipLevel = m_testParameters.mipmaps ? 1 : 0;
338
339 ReferenceParams sampleParams(TEXTURETYPE_2D);
340 tcu::Surface rendered(m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
341 vector<float> texCoord;
342
343 // Setup params for reference.
344 sampleParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT,
345 m_testParameters.minFilter, m_testParameters.magFilter);
346 sampleParams.samplerType = SAMPLERTYPE_FLOAT;
347 sampleParams.lodMode = LODMODE_EXACT;
348
349 if (m_testParameters.mipmaps)
350 {
351 sampleParams.minLod = (float)mipLevel;
352 sampleParams.maxLod = (float)mipLevel;
353 }
354
355 if (isAstcFormat(m_compressedFormat) || m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK ||
356 m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK)
357 {
358 sampleParams.colorBias = tcu::Vec4(0.0f);
359 sampleParams.colorScale = tcu::Vec4(1.0f);
360 }
361 else if (m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK)
362 {
363 sampleParams.colorBias = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f);
364 sampleParams.colorScale = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f);
365 }
366 else if (m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK)
367 {
368 sampleParams.colorBias = tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f);
369 sampleParams.colorScale = tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f);
370 }
371 else
372 {
373 sampleParams.colorBias = formatInfo.lookupBias;
374 sampleParams.colorScale = formatInfo.lookupScale;
375 }
376
377 log << TestLog::Message << "Compare reference value = " << sampleParams.ref << TestLog::EndMessage;
378
379 // Compute texture coordinates.
380 computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
381
382 m_renderer.renderQuad(rendered, 0, &texCoord[0], sampleParams);
383
384 // Compute reference.
385 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
386 const tcu::PixelFormat pixelFormat(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
387
388 #ifdef CTS_USES_VULKANSC
389 if (m_context.getTestContext().getCommandLine().isSubProcess())
390 #endif // CTS_USES_VULKANSC
391 {
392 // Compare and log.
393 tcu::RGBA threshold;
394
395 if (isBcBitExactFormat(m_compressedFormat))
396 threshold = tcu::RGBA(1, 1, 1, 1);
397 else if (isBcFormat(m_compressedFormat))
398 threshold = tcu::RGBA(8, 8, 8, 8);
399 else
400 threshold = pixelFormat.getColorThreshold() + tcu::RGBA(2, 2, 2, 2);
401
402 constexpr float coordThreshold = 0.01f;
403 const bool isOk = validateTexture(log, rendered, texture.getTexture(), texCoord, mipLevel, pixelFormat,
404 threshold, coordThreshold, sampleParams);
405
406 return isOk ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Image verification failed");
407 }
408 return tcu::TestStatus::pass("Pass");
409 }
410
411 class Compressed3DTestInstance : public TestInstance
412 {
413 public:
414 typedef Compressed3DTestParameters ParameterType;
415
416 Compressed3DTestInstance(Context &context, const ParameterType &testParameters);
417 tcu::TestStatus iterate(void);
418
419 private:
420 Compressed3DTestInstance(const Compressed3DTestInstance &other);
421 Compressed3DTestInstance &operator=(const Compressed3DTestInstance &other);
422
423 const ParameterType &m_testParameters;
424 const tcu::CompressedTexFormat m_compressedFormat;
425 TestTexture3DSp m_texture3D;
426 TextureRenderer m_renderer2D;
427 };
428
Compressed3DTestInstance(Context & context,const ParameterType & testParameters)429 Compressed3DTestInstance::Compressed3DTestInstance(Context &context, const ParameterType &testParameters)
430 : TestInstance(context)
431 , m_testParameters(testParameters)
432 , m_compressedFormat(mapVkCompressedFormat(testParameters.format))
433 , m_texture3D(TestTexture3DSp(new pipeline::TestTexture3D(m_compressedFormat, testParameters.width,
434 testParameters.height, testParameters.depth)))
435 , m_renderer2D(context, testParameters.sampleCount, testParameters.width, testParameters.height, 1,
436 makeComponentMappingRGBA(), VK_IMAGE_TYPE_2D, VK_IMAGE_VIEW_TYPE_2D)
437 {
438 m_renderer2D.add3DTexture(m_texture3D, testParameters.aspectMask, testParameters.backingMode);
439
440 VkPhysicalDeviceFeatures physicalFeatures;
441 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &physicalFeatures);
442
443 if (tcu::isAstcFormat(m_compressedFormat))
444 {
445 if (!physicalFeatures.textureCompressionASTC_LDR)
446 throw tcu::NotSupportedError(std::string("Unsupported format: ") + getFormatName(testParameters.format));
447 }
448 else if (tcu::isEtcFormat(m_compressedFormat))
449 {
450 if (!physicalFeatures.textureCompressionETC2)
451 throw tcu::NotSupportedError(std::string("Unsupported format: ") + getFormatName(testParameters.format));
452 }
453 else if (tcu::isBcFormat(m_compressedFormat))
454 {
455 if (!physicalFeatures.textureCompressionBC)
456 throw tcu::NotSupportedError(std::string("Unsupported format: ") + getFormatName(testParameters.format));
457 }
458 else
459 {
460 DE_FATAL("Unsupported compressed format");
461 }
462 }
463
iterate(void)464 tcu::TestStatus Compressed3DTestInstance::iterate(void)
465 {
466 tcu::TestLog &log = m_context.getTestContext().getLog();
467 const pipeline::TestTexture3D &texture = m_renderer2D.get3DTexture(0);
468 const tcu::TextureFormat textureFormat = texture.getTextureFormat();
469 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(textureFormat);
470 const uint32_t mipLevel = m_testParameters.mipmaps ? 1 : 0;
471
472 ReferenceParams sampleParams(TEXTURETYPE_3D);
473 tcu::Surface rendered(m_renderer2D.getRenderWidth(), m_renderer2D.getRenderHeight());
474 vector<float> texCoord;
475
476 // Setup params for reference.
477 sampleParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT,
478 m_testParameters.minFilter, m_testParameters.magFilter);
479 sampleParams.samplerType = SAMPLERTYPE_FLOAT;
480 sampleParams.lodMode = LODMODE_EXACT;
481
482 if (m_testParameters.mipmaps)
483 {
484 sampleParams.minLod = (float)mipLevel;
485 sampleParams.maxLod = (float)mipLevel;
486 }
487
488 if (isAstcFormat(m_compressedFormat) || m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK ||
489 m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK)
490 {
491 sampleParams.colorBias = tcu::Vec4(0.0f);
492 sampleParams.colorScale = tcu::Vec4(1.0f);
493 }
494 else if (m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK)
495 {
496 sampleParams.colorBias = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f);
497 sampleParams.colorScale = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f);
498 }
499 else if (m_compressedFormat == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK)
500 {
501 sampleParams.colorBias = tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f);
502 sampleParams.colorScale = tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f);
503 }
504 else
505 {
506 sampleParams.colorBias = formatInfo.lookupBias;
507 sampleParams.colorScale = formatInfo.lookupScale;
508 }
509
510 log << TestLog::Message << "Compare reference value = " << sampleParams.ref << TestLog::EndMessage;
511
512 constexpr uint32_t slices = 3;
513 uint32_t sliceNdx = 0;
514 float z = 0;
515 bool isOk = false;
516 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
517 const tcu::PixelFormat pixelFormat(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
518 tcu::RGBA threshold;
519
520 if (isBcBitExactFormat(m_compressedFormat))
521 threshold = tcu::RGBA(1, 1, 1, 1);
522 else if (isBcSRGBFormat(m_compressedFormat))
523 threshold = tcu::RGBA(9, 9, 9, 9);
524 else if (isBcFormat(m_compressedFormat))
525 threshold = tcu::RGBA(8, 8, 8, 8);
526 else
527 threshold = pixelFormat.getColorThreshold() + tcu::RGBA(2, 2, 2, 2);
528
529 for (uint32_t s = 0; s < slices; ++s)
530 {
531 // Test different slices of 3D texture.
532
533 sliceNdx = (m_testParameters.depth - 1) * s / (slices - 1);
534
535 // Render texture.
536 z = (((float)sliceNdx + 0.5f) / (float)(m_testParameters.depth >> mipLevel));
537 computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, z), tcu::Vec3(1.0f, 1.0f, z), tcu::IVec3(0, 1, 2));
538 m_renderer2D.renderQuad(rendered, 0, &texCoord[0], sampleParams);
539
540 // Compare and log.
541 #ifdef CTS_USES_VULKANSC
542 if (m_context.getTestContext().getCommandLine().isSubProcess())
543 #endif // CTS_USES_VULKANSC
544 {
545 constexpr float coordThreshold = 0.01f;
546 isOk = validateTexture(log, rendered, m_texture3D->getTexture(), texCoord, mipLevel, pixelFormat, threshold,
547 coordThreshold, sampleParams);
548
549 if (!isOk)
550 break;
551 }
552 }
553 return isOk ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Image verification failed");
554 }
555
556 } // namespace
557
populateTextureCompressedFormatTests(tcu::TestCaseGroup * compressedTextureTests)558 void populateTextureCompressedFormatTests(tcu::TestCaseGroup *compressedTextureTests)
559 {
560 tcu::TestContext &testCtx = compressedTextureTests->getTestContext();
561
562 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); sizeNdx++)
563 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
564 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); backingNdx++)
565 {
566 const string formatStr = de::toString(getFormatStr(formats[formatNdx].format));
567 const string nameBase = de::toLower(formatStr.substr(10));
568
569 Compressed2DTestParameters testParameters;
570 testParameters.format = formats[formatNdx].format;
571 testParameters.backingMode = backingModes[backingNdx].backingMode;
572 testParameters.width = sizes[sizeNdx].width;
573 testParameters.height = sizes[sizeNdx].height;
574 testParameters.minFilter = tcu::Sampler::NEAREST_MIPMAP_NEAREST;
575 testParameters.magFilter = tcu::Sampler::NEAREST;
576 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
577 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
578 testParameters.mipmaps = sizes[sizeNdx].mipmaps;
579
580 compressedTextureTests->addChild(new TextureTestCase<Compressed2DTestInstance>(
581 testCtx, (nameBase + "_2d_" + sizes[sizeNdx].name + backingModes[backingNdx].name).c_str(),
582 testParameters));
583 }
584 }
585
populate3DTextureCompressedFormatTests(tcu::TestCaseGroup * compressedTextureTests)586 void populate3DTextureCompressedFormatTests(tcu::TestCaseGroup *compressedTextureTests)
587 {
588 tcu::TestContext &testCtx = compressedTextureTests->getTestContext();
589
590 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
591 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
592 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); ++backingNdx)
593 {
594 const string formatStr = de::toString(getFormatStr(formats[formatNdx].format));
595 const string nameBase = de::toLower(formatStr.substr(10));
596
597 Compressed3DTestParameters testParameters;
598 testParameters.format = formats[formatNdx].format;
599 testParameters.backingMode = backingModes[backingNdx].backingMode;
600 testParameters.width = sizes[sizeNdx].width;
601 testParameters.height = sizes[sizeNdx].height;
602 testParameters.depth = sizes[sizeNdx].depth;
603 testParameters.minFilter = tcu::Sampler::NEAREST_MIPMAP_NEAREST;
604 testParameters.magFilter = tcu::Sampler::NEAREST;
605 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
606 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
607 testParameters.mipmaps = sizes[sizeNdx].mipmaps;
608
609 compressedTextureTests->addChild(new TextureTestCase<Compressed3DTestInstance>(
610 testCtx, (nameBase + "_3d_" + sizes[sizeNdx].name + backingModes[backingNdx].name).c_str(),
611 testParameters));
612 }
613 }
614
createTextureCompressedFormatTests(tcu::TestContext & testCtx)615 tcu::TestCaseGroup *createTextureCompressedFormatTests(tcu::TestContext &testCtx)
616 {
617 return createTestGroup(testCtx, "compressed", populateTextureCompressedFormatTests);
618 }
619
create3DTextureCompressedFormatTests(tcu::TestContext & testCtx)620 tcu::TestCaseGroup *create3DTextureCompressedFormatTests(tcu::TestContext &testCtx)
621 {
622 return createTestGroup(testCtx, "compressed_3D", populate3DTextureCompressedFormatTests);
623 }
624
625 } // namespace texture
626 } // namespace vkt
627