Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / texture / vktTextureConversionTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  * Copyright (c) 2020 Google Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Texture conversion tests.
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktTextureConversionTests.hpp"
26 #include "vktAmberTestCase.hpp"
27 #include "vktTestGroupUtil.hpp"
28 #include "vktTextureTestUtil.hpp"
29 #include "vkImageUtil.hpp"
30 #include "tcuTexture.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuVectorUtil.hpp"
33 #include "deSharedPtr.hpp"
34
35 #include <cmath>
36 #include <memory>
37
38 namespace vkt
39 {
40 namespace texture
41 {
42
43 using namespace vk;
44
45 namespace
46 {
47
48 using namespace texture::util;
49 using namespace glu::TextureTestUtil;
50
51 class SnormLinearClampInstance : public TestInstance
52 {
53 public:
54         struct Params
55         {
56                 VkFormat        format;
57                 int                     width;
58                 int                     height;
59         };
60                                                         SnormLinearClampInstance        (vkt::Context&                                  context,
61                                                                                                                  de::SharedPtr<Params>                  params);
62
63         virtual tcu::TestStatus iterate                                         (void) override;
64
65 protected:
66         tcu::IVec4                              computeColorDistance            () const;
67         bool                                    verifyPixels                            (const tcu::PixelBufferAccess&  rendered,
68                                                                                                                  const tcu::PixelBufferAccess&  reference,
69                                                                                                                  const ReferenceParams&                 samplerParams,
70                                                                                                                  const std::vector<float>&              texCoords)              const;
71
72         static int                              lim                                                     (const tcu::TextureFormat&              format,
73                                                                                                                  int                                                    channelIdx);
74
75 private:
76         const de::SharedPtr<Params>     m_params;
77         const tcu::TextureFormat        m_inFormat;
78         const VkFormat                          m_outFormat;
79         TestTexture2DSp                         m_hwTexture;
80         tcu::Texture2D                          m_swTexture;
81         TextureRenderer                         m_renderer;
82
83         const tcu::IVec4                        m_cd;
84         const tcu::IVec4                        m_a;
85         const tcu::IVec4                        m_b;
86         const tcu::IVec4                        m_c;
87         const tcu::IVec4                        m_d;
88
89 public:
90         static const int                        textureWidth    = 7;
91         static const int                        textureHeight   = 7;
92 };
93
94 SnormLinearClampInstance::SnormLinearClampInstance (vkt::Context& context, de::SharedPtr<Params> params)
95         : TestInstance  (context)
96         , m_params              (params)
97         , m_inFormat    (mapVkFormat(m_params->format))
98         , m_outFormat   (VK_FORMAT_R32G32B32A32_SFLOAT)
99         , m_hwTexture   (TestTexture2DSp(new pipeline::TestTexture2D(m_inFormat, textureWidth, textureHeight)))
100         , m_swTexture   (m_inFormat, textureWidth, textureHeight, 1)
101         , m_renderer    (context, VK_SAMPLE_COUNT_1_BIT, m_params->width, m_params->height, 1u, makeComponentMappingRGBA(), VK_IMAGE_TYPE_2D, VK_IMAGE_VIEW_TYPE_2D, m_outFormat)
102         , m_cd                  (computeColorDistance())
103         , m_a                   (lim(m_inFormat, 0),                    lim(m_inFormat, 1)+m_cd[1]*2,   lim(m_inFormat, 2),                             lim(m_inFormat, 3)+m_cd[3]*2)
104         , m_b                   (lim(m_inFormat, 0)+m_cd[0]*2,  lim(m_inFormat, 1),                             lim(m_inFormat, 2)+m_cd[2]*2,   lim(m_inFormat, 3)                      )
105         , m_c                   (lim(m_inFormat, 0)+m_cd[0]*1,  lim(m_inFormat, 1)+m_cd[1]*1,   lim(m_inFormat, 2)+m_cd[2]*1,   lim(m_inFormat, 3)+m_cd[3]*1)
106         , m_d                   (lim(m_inFormat, 0),                    lim(m_inFormat, 1),                             lim(m_inFormat, 2),                             lim(m_inFormat, 3)                      )
107 {
108         tcu::IVec4 data[textureWidth * textureHeight] =
109         {
110                 m_a, m_b, m_c, m_d, m_c, m_b, m_a,
111                 m_b, m_a, m_c, m_d, m_c, m_a, m_b,
112                 m_c, m_c, m_c, m_d, m_c, m_c, m_c,
113                 m_d, m_d, m_d, m_c, m_d, m_d, m_d,
114                 m_c, m_c, m_c, m_d, m_c, m_c, m_c,
115                 m_b, m_a, m_c, m_d, m_c, m_a, m_b,
116                 m_a, m_b, m_c, m_d, m_c, m_b, m_a,
117         };
118
119         m_swTexture.allocLevel(0);
120
121         const tcu::PixelBufferAccess& swAccess  = m_swTexture.getLevel(0);
122         const tcu::PixelBufferAccess& hwAccess  = m_hwTexture->getLevel(0, 0);
123
124         for (int y = 0; y < textureHeight; ++y)
125         {
126                 for (int x = 0; x < textureWidth; ++x)
127                 {
128                         swAccess.setPixel(data[y*textureWidth+x], x, y);
129                         hwAccess.setPixel(data[y*textureWidth+x], x, y);
130                 }
131         }
132
133         m_renderer.add2DTexture(m_hwTexture, VK_IMAGE_ASPECT_COLOR_BIT, TextureBinding::ImageBackingMode::IMAGE_BACKING_MODE_REGULAR);
134 }
135
136 int SnormLinearClampInstance::lim (const tcu::TextureFormat& format, int channelIdx)
137 {
138         auto   channelBits(getTextureFormatBitDepth(format));
139         return channelBits[channelIdx] ? (-deIntMaxValue32(channelBits[channelIdx])) : (-1);
140 }
141
142 tcu::IVec4 SnormLinearClampInstance::computeColorDistance () const
143 {
144         return tcu::IVec4
145         (
146                 static_cast<int>(std::floor(static_cast<float>(-lim(m_inFormat, 0)) / 127.0f)),
147                 static_cast<int>(std::floor(static_cast<float>(-lim(m_inFormat, 0)) / 127.0f)),
148                 static_cast<int>(std::floor(static_cast<float>(-lim(m_inFormat, 0)) / 127.0f)),
149                 static_cast<int>(std::floor(static_cast<float>(-lim(m_inFormat, 0)) / 127.0f))
150         );
151 }
152
153 bool SnormLinearClampInstance::verifyPixels     (const tcu::PixelBufferAccess& rendered, const tcu::PixelBufferAccess& reference, const ReferenceParams& samplerParams, const std::vector<float>& texCoords) const
154 {
155         tcu::LodPrecision                               lodPrec;
156         tcu::LookupPrecision                    lookupPrec;
157
158         const int                                               nuc                             (getNumUsedChannels(m_inFormat.order));
159         const int                                               width                   (m_renderer.getRenderWidth());
160         const int                                               height                  (m_renderer.getRenderHeight());
161
162         const tcu::IVec4                                colorDistance   (computeColorDistance());
163         std::unique_ptr<deUint8[]>              errorMaskData   (new deUint8[width * height * 4 * 4]);
164         tcu::PixelBufferAccess                  errorMask               (mapVkFormat(m_outFormat), width, height, 1, errorMaskData.get());
165
166
167         lodPrec.derivateBits                    = 18;
168         lodPrec.lodBits                                 = 5;
169
170         lookupPrec.uvwBits                              = tcu::IVec3(5,5,0);
171         lookupPrec.coordBits                    = tcu::IVec3(20,20,0);
172         lookupPrec.colorMask                    = tcu::BVec4(nuc >= 1, nuc >= 2, nuc >=3, nuc >= 4);
173         lookupPrec.colorThreshold               = tcu::Vec4(0.9f/float(colorDistance[0]),
174                                                                                                 0.9f/float(colorDistance[1]),
175                                                                                                 0.9f/float(colorDistance[2]),
176                                                                                                 0.9f/float(colorDistance[3]));
177
178         const int numFailedPixels               = glu::TextureTestUtil::computeTextureLookupDiff(rendered, reference, errorMask,
179                                                                                                                                                                          m_swTexture, texCoords.data(), samplerParams,
180                                                                                                                                                                          lookupPrec, lodPrec, /*watchDog*/nullptr);
181         if (numFailedPixels)
182         {
183                 const int       numTotalPixels  = width * height;
184                 auto&           log                             = m_context.getTestContext().getLog();
185                 const auto      formatName              = de::toLower(std::string(getFormatName(m_params->format)).substr(10));
186
187                 log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
188                 log << tcu::TestLog::Message << "       " << float(numFailedPixels * 100)/float(numTotalPixels) << "% failed from " << numTotalPixels << " compared pixel count." << tcu::TestLog::EndMessage;
189                 log << tcu::TestLog::Message << "       ColorThreshold: " << lookupPrec.colorThreshold << ", ColorMask: " << lookupPrec.colorMask << tcu::TestLog::EndMessage;
190
191                 log << tcu::TestLog::ImageSet("VerifyResult", "Verification result");
192                 {
193                         log << tcu::TestLog::Image("Res_"+formatName, "Rendered image", rendered);
194                         log << tcu::TestLog::Image("Ref_"+formatName, "Reference image", reference);
195                         log << tcu::TestLog::Image("Err_"+formatName, "Error mask image", errorMask);
196                 }
197                 log << tcu::TestLog::EndImageSet;
198         }
199
200         int numOutOfRangePixels                 = 0;
201         for (int y = 0; y < height; ++y)
202         {
203                 for (int x = 0; x < width; ++x)
204                 {
205                         const auto px = rendered.getPixel(x, y);
206                         if (tcu::boolAny(tcu::lessThan(px, tcu::Vec4(-1.0f))) || tcu::boolAny(tcu::greaterThan(px, tcu::Vec4(+1.0f))))
207                                 ++numOutOfRangePixels;
208                 }
209         }
210
211         if (numOutOfRangePixels)
212         {
213                 auto&           log                                     = m_context.getTestContext().getLog();
214                 log << tcu::TestLog::Message << "ERROR: Found " << numOutOfRangePixels << " out of range [-1.0f, +1.0f]." << tcu::TestLog::EndMessage;
215         }
216
217         return (numFailedPixels == 0 && numOutOfRangePixels == 0);
218 }
219
220 tcu::TestStatus SnormLinearClampInstance::iterate (void)
221 {
222         std::vector<float>                              texCoords               (8);
223         ReferenceParams                                 samplerParams   (TEXTURETYPE_2D);
224         tcu::TextureFormat                              resultFormat    (mapVkFormat(m_outFormat));
225
226         // Setup renderers.
227         const int                                               width                   (m_renderer.getRenderWidth());
228         const int                                               height                  (m_renderer.getRenderHeight());
229         std::unique_ptr<deUint8[]>              renderedData    (new deUint8[width * height * 4 * 4]);
230         std::unique_ptr<deUint8[]>              referenceData   (new deUint8[width * height * 4 * 4]);
231         tcu::PixelBufferAccess                  rendered                (resultFormat, width, height, 1, renderedData.get());
232         tcu::PixelBufferAccess                  reference               (resultFormat, width, height, 1, referenceData.get());
233
234         // Setup sampler params.
235         samplerParams.sampler                   = util::createSampler(tcu::Sampler::WrapMode::REPEAT_GL, tcu::Sampler::WrapMode::REPEAT_GL,
236                                                                                                                   tcu::Sampler::FilterMode::LINEAR, tcu::Sampler::FilterMode::LINEAR, true);
237         samplerParams.samplerType               = SAMPLERTYPE_FLOAT;
238         samplerParams.lodMode                   = LODMODE_EXACT;
239         samplerParams.colorScale                = tcu::Vec4(1.0f);
240         samplerParams.colorBias                 = tcu::Vec4(0.0f);
241
242         // Compute texture coordinates.
243         computeQuadTexCoord2D(texCoords, tcu::Vec2(0.0f), tcu::Vec2(1.0f));
244
245         // Peform online rendering with Vulkan.
246         m_renderer.renderQuad(rendered, 0, texCoords.data(), samplerParams);
247
248         // Perform offline rendering with software renderer.
249         sampleTexture(reference, m_swTexture, texCoords.data(), samplerParams);
250
251         return verifyPixels(rendered, reference, samplerParams, texCoords)
252                         ? tcu::TestStatus::pass("")
253                         : tcu::TestStatus::fail("Pixels verification failed");
254 }
255
256 class SnormLinearClampTestCase : public TestCase
257 {
258 public:
259         using ParamsSp = de::SharedPtr<SnormLinearClampInstance::Params>;
260
261                                                 SnormLinearClampTestCase        (tcu::TestContext&      testCtx,
262                                                                                                          const std::string&     name,
263                                                                                                          const std::string&     description,
264                                                                                                          ParamsSp                       params)
265                 : TestCase      (testCtx, name, description)
266                 , m_params      (params)
267         {
268         }
269
270         vkt::TestInstance*      createInstance                          (vkt::Context&          context) const override
271         {
272                 return new SnormLinearClampInstance(context, m_params);
273         }
274
275         virtual void            checkSupport                            (vkt::Context&          context) const override
276         {
277                 VkFormatProperties              formatProperties;
278
279                 context.getInstanceInterface().getPhysicalDeviceFormatProperties(
280                                 context.getPhysicalDevice(),
281                                 m_params->format,
282                                 &formatProperties);
283
284                 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
285                         TCU_THROW(NotSupportedError, "Linear filtering for this image format is not supported");
286         }
287
288         virtual void            initPrograms                            (SourceCollections&     programCollection) const override
289         {
290                 initializePrograms(programCollection, glu::Precision::PRECISION_HIGHP, std::vector<Program>({PROGRAM_2D_FLOAT}), DE_NULL, glu::Precision::PRECISION_HIGHP);
291         }
292
293 private:
294         ParamsSp        m_params;
295 };
296
297 void populateUfloatNegativeValuesTests (tcu::TestCaseGroup* group)
298 {
299 #ifndef CTS_USES_VULKANSC
300         tcu::TestContext&       testCtx = group->getTestContext();
301         VkImageUsageFlags       usage   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
302
303         VkImageCreateInfo       info    =
304         {
305                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType          sType
306                 DE_NULL,                                                                // const void*              pNext
307                 0,                                                                              // VkImageCreateFlags       flags
308                 VK_IMAGE_TYPE_2D,                                               // VkImageType              imageType
309                 VK_FORMAT_B10G11R11_UFLOAT_PACK32,              // VkFormat                 format
310                 {50u, 50u, 1u},                                                 // VkExtent3D               extent
311                 1u,                                                                             // uint32_t                 mipLevels
312                 1u,                                                                             // uint32_t                 arrayLayers
313                 VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits    samples
314                 VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling            tiling
315                 usage,                                                                  // VkImageUsageFlags        usage
316                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode            sharingMode
317                 0u,                                                                             // uint32_t                 queueFamilyIndexCount
318                 DE_NULL,                                                                // const uint32_t*          pQueueFamilyIndices
319                 VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout            initialLayout
320         };
321
322         group->addChild(cts_amber::createAmberTestCase(testCtx, "b10g11r11", "", "texture/conversion/ufloat_negative_values", "b10g11r11-ufloat-pack32.amber",
323                                         std::vector<std::string>(), std::vector<VkImageCreateInfo>(1, info)));
324 #else
325         DE_UNREF(group);
326 #endif
327 }
328
329 void populateSnormClampTests (tcu::TestCaseGroup* group)
330 {
331 #ifndef CTS_USES_VULKANSC
332         tcu::TestContext&       testCtx = group->getTestContext();
333         VkImageUsageFlags       usage   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
334
335         VkImageCreateInfo       info    =
336         {
337                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType          sType
338                 DE_NULL,                                                                // const void*              pNext
339                 0,                                                                              // VkImageCreateFlags       flags
340                 VK_IMAGE_TYPE_1D,                                               // VkImageType              imageType
341                 VK_FORMAT_UNDEFINED,                                    // VkFormat                 format
342                 {1u, 1u, 1u},                                                   // VkExtent3D               extent
343                 1u,                                                                             // uint32_t                 mipLevels
344                 1u,                                                                             // uint32_t                 arrayLayers
345                 VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits    samples
346                 VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling            tiling
347                 usage,                                                                  // VkImageUsageFlags        usage
348                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode            sharingMode
349                 0u,                                                                             // uint32_t                 queueFamilyIndexCount
350                 DE_NULL,                                                                // const uint32_t*          pQueueFamilyIndices
351                 VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout            initialLayout
352         };
353
354         struct TestParams
355         {
356                 std::string testName;
357                 std::string amberFile;
358                 VkFormat        format;
359         } params[] =
360         {
361                 { "a2b10g10r10_snorm_pack32",   "a2b10g10r10-snorm-pack32.amber",       VK_FORMAT_A2B10G10R10_SNORM_PACK32      },
362                 { "a2r10g10b10_snorm_pack32",   "a2r10g10b10-snorm-pack32.amber",       VK_FORMAT_A2R10G10B10_SNORM_PACK32      },
363                 { "a8b8g8r8_snorm_pack32",              "a8b8g8r8-snorm-pack32.amber",          VK_FORMAT_A8B8G8R8_SNORM_PACK32         },
364                 { "b8g8r8a8_snorm",                             "b8g8r8a8-snorm.amber",                         VK_FORMAT_B8G8R8A8_SNORM                        },
365                 { "b8g8r8_snorm",                               "b8g8r8-snorm.amber",                           VK_FORMAT_B8G8R8_SNORM                          },
366                 { "r16g16b16a16_snorm",                 "r16g16b16a16-snorm.amber",                     VK_FORMAT_R16G16B16A16_SNORM            },
367                 { "r16g16b16_snorm",                    "r16g16b16-snorm.amber",                        VK_FORMAT_R16G16B16_SNORM                       },
368                 { "r16g16_snorm",                               "r16g16-snorm.amber",                           VK_FORMAT_R16G16_SNORM                          },
369                 { "r16_snorm",                                  "r16-snorm.amber",                                      VK_FORMAT_R16_SNORM                                     },
370                 { "r8g8b8a8_snorm",                             "r8g8b8a8-snorm.amber",                         VK_FORMAT_R8G8B8A8_SNORM                        },
371                 { "r8g8b8_snorm",                               "r8g8b8-snorm.amber",                           VK_FORMAT_R8G8B8_SNORM                          },
372                 { "r8g8_snorm",                                 "r8g8-snorm.amber",                                     VK_FORMAT_R8G8_SNORM                            },
373                 { "r8_snorm",                                   "r8-snorm.amber",                                       VK_FORMAT_R8_SNORM                                      },
374         };
375
376         for (const auto& param : params)
377         {
378                 info.format = param.format;
379                 group->addChild(cts_amber::createAmberTestCase(testCtx, param.testName.c_str(), "", "texture/conversion/snorm_clamp", param.amberFile.c_str(),
380                                                 std::vector<std::string>(), std::vector<VkImageCreateInfo>(1, info)));
381         }
382 #else
383         DE_UNREF(group);
384 #endif
385 }
386
387 void populateSnormLinearClampTests (tcu::TestCaseGroup* group)
388 {
389         struct TestParams
390         {
391                 std::string testName;
392                 VkFormat        format;
393         }
394         testParams[] =
395         {
396                 { "a2b10g10r10_snorm_pack32",   VK_FORMAT_A2B10G10R10_SNORM_PACK32      },
397                 { "a2r10g10b10_snorm_pack32",   VK_FORMAT_A2R10G10B10_SNORM_PACK32      },
398                 { "a8b8g8r8_snorm_pack32",              VK_FORMAT_A8B8G8R8_SNORM_PACK32         },
399                 { "b8g8r8a8_snorm",                             VK_FORMAT_B8G8R8A8_SNORM                        },
400                 { "b8g8r8_snorm",                               VK_FORMAT_B8G8R8_SNORM                          },
401                 { "r16g16b16a16_snorm",                 VK_FORMAT_R16G16B16A16_SNORM            },
402                 { "r16g16b16_snorm",                    VK_FORMAT_R16G16B16_SNORM                       },
403                 { "r16g16_snorm",                               VK_FORMAT_R16G16_SNORM                          },
404                 { "r16_snorm",                                  VK_FORMAT_R16_SNORM                                     },
405                 { "r8g8b8a8_snorm",                             VK_FORMAT_R8G8B8A8_SNORM                        },
406                 { "r8g8b8_snorm",                               VK_FORMAT_R8G8B8_SNORM                          },
407                 { "r8g8_snorm",                                 VK_FORMAT_R8G8_SNORM                            },
408                 { "r8_snorm",                                   VK_FORMAT_R8_SNORM                                      },
409         };
410
411         tcu::TestContext&       testCtx                         = group->getTestContext();
412         int                                     sizeMultipler           = 20;
413
414         for (const auto& testParam : testParams)
415         {
416                 const int               tw                                      = SnormLinearClampInstance::textureWidth * sizeMultipler;
417                 const int               th                                      = SnormLinearClampInstance::textureHeight * sizeMultipler;
418
419                 de::SharedPtr<SnormLinearClampInstance::Params> params(new SnormLinearClampInstance::Params{testParam.format, tw, th});
420                 group->addChild(new SnormLinearClampTestCase(testCtx, testParam.testName, {}, params));
421
422                 sizeMultipler += 2;
423         }
424 }
425
426 void populateTextureConversionTests (tcu::TestCaseGroup* group)
427 {
428         tcu::TestContext& testCtx = group->getTestContext();
429
430         group->addChild(createTestGroup(testCtx, "ufloat_negative_values", "Tests for converting negative floats to unsigned floats", populateUfloatNegativeValuesTests));
431         group->addChild(createTestGroup(testCtx, "snorm_clamp", "Tests for SNORM corner cases when smallest negative number gets clamped to -1", populateSnormClampTests));
432         group->addChild(createTestGroup(testCtx, "snorm_clamp_linear", "Tests for SNORM corner cases when negative number gets clamped to -1 after applying linear filtering", populateSnormLinearClampTests));
433 }
434
435 } // anonymous namespace
436
437 tcu::TestCaseGroup* createTextureConversionTests (tcu::TestContext& testCtx)
438 {
439         return createTestGroup(testCtx, "conversion", "Texture conversion tests.", populateTextureConversionTests);
440 }
441
442 } // texture
443 } // vkt