Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / texture / vktTextureCompressedFormatTests.cpp
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
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
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
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
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
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
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>
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
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
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
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
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
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
641 tcu::TestCaseGroup* createTextureCompressedFormatTests (tcu::TestContext& testCtx)
642 {
643         return createTestGroup(testCtx, "compressed", "Texture compressed format tests.", populateTextureCompressedFormatTests);
644 }
645
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