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