xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrFormatTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief YCbCr Format Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktYCbCrFormatTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktCustomInstancesDevices.hpp"
27 #include "vktTestGroupUtil.hpp"
28 #include "vktShaderExecutor.hpp"
29 #include "vktYCbCrUtil.hpp"
30 
31 #include "vkStrUtil.hpp"
32 #include "vkRef.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkMemUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkDeviceUtil.hpp"
39 #include "vkPlatform.hpp"
40 
41 #include "tcuTestLog.hpp"
42 #include "tcuVectorUtil.hpp"
43 
44 #include "deStringUtil.hpp"
45 #include "deSharedPtr.hpp"
46 #include "deUniquePtr.hpp"
47 #include "deRandom.hpp"
48 #include "deSTLUtil.hpp"
49 
50 namespace vkt
51 {
52 namespace ycbcr
53 {
54 namespace
55 {
56 
57 using namespace vk;
58 using namespace shaderexecutor;
59 
60 using de::MovePtr;
61 using de::UniquePtr;
62 using std::string;
63 using std::vector;
64 using tcu::TestLog;
65 using tcu::UVec2;
66 using tcu::Vec2;
67 using tcu::Vec4;
68 
createTestImage(const DeviceInterface & vkd,VkDevice device,VkFormat format,const UVec2 & size,VkImageCreateFlags createFlags,VkImageTiling tiling,VkImageLayout layout,uint32_t arrayLayers)69 Move<VkImage> createTestImage(const DeviceInterface &vkd, VkDevice device, VkFormat format, const UVec2 &size,
70                               VkImageCreateFlags createFlags, VkImageTiling tiling, VkImageLayout layout,
71                               uint32_t arrayLayers)
72 {
73     const VkImageCreateInfo createInfo = {
74         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
75         DE_NULL,
76         createFlags,
77         VK_IMAGE_TYPE_2D,
78         format,
79         makeExtent3D(size.x(), size.y(), 1u),
80         1u,          // mipLevels
81         arrayLayers, // arrayLayers
82         VK_SAMPLE_COUNT_1_BIT,
83         tiling,
84         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
85         VK_SHARING_MODE_EXCLUSIVE,
86         0u,
87         (const uint32_t *)DE_NULL,
88         layout,
89     };
90 
91     return createImage(vkd, device, &createInfo);
92 }
93 
createImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkSamplerYcbcrConversion conversion,uint32_t layerCount)94 Move<VkImageView> createImageView(const DeviceInterface &vkd, VkDevice device, VkImage image, VkFormat format,
95                                   VkSamplerYcbcrConversion conversion, uint32_t layerCount)
96 {
97     const VkSamplerYcbcrConversionInfo conversionInfo = {VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, DE_NULL,
98                                                          conversion};
99     const VkImageViewCreateInfo viewInfo              = {
100         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
101         &conversionInfo,
102         (VkImageViewCreateFlags)0,
103         image,
104         (layerCount > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
105         format,
106         {
107             VK_COMPONENT_SWIZZLE_IDENTITY,
108             VK_COMPONENT_SWIZZLE_IDENTITY,
109             VK_COMPONENT_SWIZZLE_IDENTITY,
110             VK_COMPONENT_SWIZZLE_IDENTITY,
111         },
112         {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, layerCount},
113     };
114 
115     return createImageView(vkd, device, &viewInfo);
116 }
117 
createDescriptorSetLayout(const DeviceInterface & vkd,VkDevice device,VkSampler sampler)118 Move<VkDescriptorSetLayout> createDescriptorSetLayout(const DeviceInterface &vkd, VkDevice device, VkSampler sampler)
119 {
120     const VkDescriptorSetLayoutBinding binding       = {0u, // binding
121                                                         VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
122                                                         1u, // descriptorCount
123                                                         VK_SHADER_STAGE_ALL, &sampler};
124     const VkDescriptorSetLayoutCreateInfo layoutInfo = {
125         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
126         DE_NULL,
127         (VkDescriptorSetLayoutCreateFlags)0u,
128         1u,
129         &binding,
130     };
131 
132     return createDescriptorSetLayout(vkd, device, &layoutInfo);
133 }
134 
createDescriptorPool(const DeviceInterface & vkd,VkDevice device,const uint32_t combinedSamplerDescriptorCount)135 Move<VkDescriptorPool> createDescriptorPool(const DeviceInterface &vkd, VkDevice device,
136                                             const uint32_t combinedSamplerDescriptorCount)
137 {
138     const VkDescriptorPoolSize poolSizes[] = {
139         {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, combinedSamplerDescriptorCount},
140     };
141     const VkDescriptorPoolCreateInfo poolInfo = {
142         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
143         DE_NULL,
144         (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
145         1u, // maxSets
146         DE_LENGTH_OF_ARRAY(poolSizes),
147         poolSizes,
148     };
149 
150     return createDescriptorPool(vkd, device, &poolInfo);
151 }
152 
createDescriptorSet(const DeviceInterface & vkd,VkDevice device,VkDescriptorPool descPool,VkDescriptorSetLayout descLayout,VkImageView imageView)153 Move<VkDescriptorSet> createDescriptorSet(const DeviceInterface &vkd, VkDevice device, VkDescriptorPool descPool,
154                                           VkDescriptorSetLayout descLayout, VkImageView imageView)
155 {
156     Move<VkDescriptorSet> descSet;
157 
158     {
159         const VkDescriptorSetAllocateInfo allocInfo = {
160             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, DE_NULL, descPool, 1u, &descLayout,
161         };
162 
163         descSet = allocateDescriptorSet(vkd, device, &allocInfo);
164     }
165 
166     {
167         const VkDescriptorImageInfo imageInfo = {
168             0xdeadbeef, // Not required to be valid. Use something invalid and not NULL
169             imageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
170         const VkWriteDescriptorSet descriptorWrite = {
171             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
172             DE_NULL,
173             *descSet,
174             0u, // dstBinding
175             0u, // dstArrayElement
176             1u, // descriptorCount
177             VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
178             &imageInfo,
179             (const VkDescriptorBufferInfo *)DE_NULL,
180             (const VkBufferView *)DE_NULL,
181         };
182 
183         vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
184     }
185 
186     return descSet;
187 }
188 
189 struct TestParameters
190 {
191     VkFormat format;
192     UVec2 size;
193     VkImageCreateFlags flags;
194     VkImageTiling tiling;
195     glu::ShaderType shaderType;
196     bool useMappedMemory;
197     bool useArrayLayers;
198 
TestParametersvkt::ycbcr::__anon566084db0111::TestParameters199     TestParameters(VkFormat format_, const UVec2 &size_, VkImageCreateFlags flags_, VkImageTiling tiling_,
200                    glu::ShaderType shaderType_, bool useMappedMemory_, bool useArrayLayers_)
201         : format(format_)
202         , size(size_)
203         , flags(flags_)
204         , tiling(tiling_)
205         , shaderType(shaderType_)
206         , useMappedMemory(useMappedMemory_)
207         , useArrayLayers(useArrayLayers_)
208     {
209     }
210 
TestParametersvkt::ycbcr::__anon566084db0111::TestParameters211     TestParameters(void)
212         : format(VK_FORMAT_UNDEFINED)
213         , flags(0u)
214         , tiling(VK_IMAGE_TILING_OPTIMAL)
215         , shaderType(glu::SHADERTYPE_LAST)
216         , useMappedMemory(false)
217         , useArrayLayers(false)
218     {
219     }
220 };
221 
getShaderSpec(const TestParameters & params)222 ShaderSpec getShaderSpec(const TestParameters &params)
223 {
224     ShaderSpec spec;
225 
226     spec.inputs.push_back(Symbol("texCoord", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
227     spec.outputs.push_back(Symbol("result", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
228 
229     if (params.useArrayLayers)
230     {
231         spec.globalDeclarations = "layout(binding = 0, set = 1) uniform highp sampler2DArray u_image;\n";
232         spec.source             = "result = texture(u_image, vec3(texCoord, 1u));\n";
233     }
234     else
235     {
236         spec.globalDeclarations = "layout(binding = 0, set = 1) uniform highp sampler2D u_image;\n";
237         spec.source             = "result = texture(u_image, texCoord);\n";
238     }
239 
240     return spec;
241 }
242 
checkSupport(Context & context,const TestParameters params)243 void checkSupport(Context &context, const TestParameters params)
244 {
245     checkImageSupport(context, params.format, params.flags, params.tiling);
246 
247     if (params.useArrayLayers)
248     {
249         if (!context.isDeviceFunctionalitySupported("VK_EXT_ycbcr_image_arrays"))
250             TCU_THROW(NotSupportedError, "VK_EXT_ycbcr_image_arrays is not supported");
251 
252         VkImageFormatProperties properties = getPhysicalDeviceImageFormatProperties(
253             context.getInstanceInterface(), context.getPhysicalDevice(), params.format, VK_IMAGE_TYPE_2D, params.tiling,
254             VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, params.flags);
255         if (properties.maxArrayLayers < 2)
256             TCU_THROW(NotSupportedError, "Image format does not support more than 1 maxArrayLayers");
257     }
258 }
259 
generateLookupCoordinates(const UVec2 & imageSize,vector<Vec2> * dst)260 void generateLookupCoordinates(const UVec2 &imageSize, vector<Vec2> *dst)
261 {
262     dst->resize(imageSize.x() * imageSize.y());
263 
264     for (uint32_t texelY = 0; texelY < imageSize.y(); ++texelY)
265         for (uint32_t texelX = 0; texelX < imageSize.x(); ++texelX)
266         {
267             const float x = ((float)texelX + 0.5f) / (float)imageSize.x();
268             const float y = ((float)texelY + 0.5f) / (float)imageSize.y();
269 
270             (*dst)[texelY * imageSize.x() + texelX] = Vec2(x, y);
271         }
272 }
273 
testFormat(Context & context,TestParameters params)274 tcu::TestStatus testFormat(Context &context, TestParameters params)
275 {
276     const DeviceInterface &vkd = context.getDeviceInterface();
277     const VkDevice device      = context.getDevice();
278 
279     const VkFormat format                    = params.format;
280     const PlanarFormatDescription formatInfo = getPlanarFormatDescription(format);
281     const UVec2 size                         = params.size;
282     const VkImageCreateFlags createFlags     = params.flags;
283     const VkImageTiling tiling               = params.tiling;
284     const bool mappedMemory                  = params.useMappedMemory;
285     const uint32_t arrayLayers               = (params.useArrayLayers) ? 2u : 1u;
286     const uint32_t arrayLayer                = arrayLayers - 1u;
287 
288     const Unique<VkImage> image(
289         createTestImage(vkd, device, format, size, createFlags, tiling,
290                         mappedMemory ? VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED, arrayLayers));
291     const vector<AllocationSp> allocations(
292         allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags,
293                                    mappedMemory ? MemoryRequirement::HostVisible : MemoryRequirement::Any));
294 
295     const VkSamplerYcbcrConversionCreateInfo conversionInfo = {
296         VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
297         DE_NULL,
298         format,
299         VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
300         VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
301         {
302             VK_COMPONENT_SWIZZLE_IDENTITY,
303             VK_COMPONENT_SWIZZLE_IDENTITY,
304             VK_COMPONENT_SWIZZLE_IDENTITY,
305             VK_COMPONENT_SWIZZLE_IDENTITY,
306         },
307         VK_CHROMA_LOCATION_MIDPOINT,
308         VK_CHROMA_LOCATION_MIDPOINT,
309         VK_FILTER_NEAREST,
310         VK_FALSE, // forceExplicitReconstruction
311     };
312     const Unique<VkSamplerYcbcrConversion> conversion(createSamplerYcbcrConversion(vkd, device, &conversionInfo));
313     const Unique<VkImageView> imageView(createImageView(vkd, device, *image, format, *conversion, arrayLayers));
314 
315     const VkSamplerYcbcrConversionInfo samplerConversionInfo = {
316         VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
317         DE_NULL,
318         *conversion,
319     };
320 
321     const VkSamplerCreateInfo samplerInfo = {
322         VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
323         &samplerConversionInfo,
324         0u,
325         VK_FILTER_NEAREST,                       // magFilter
326         VK_FILTER_NEAREST,                       // minFilter
327         VK_SAMPLER_MIPMAP_MODE_NEAREST,          // mipmapMode
328         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // addressModeU
329         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // addressModeV
330         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // addressModeW
331         0.0f,                                    // mipLodBias
332         VK_FALSE,                                // anisotropyEnable
333         1.0f,                                    // maxAnisotropy
334         VK_FALSE,                                // compareEnable
335         VK_COMPARE_OP_ALWAYS,                    // compareOp
336         0.0f,                                    // minLod
337         0.0f,                                    // maxLod
338         VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor
339         VK_FALSE,                                // unnormalizedCoords
340     };
341 
342     const VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {
343         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
344         DE_NULL,
345         params.format,
346         VK_IMAGE_TYPE_2D,
347         params.tiling,
348         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
349         params.flags,
350     };
351     VkSamplerYcbcrConversionImageFormatProperties ycbcrProperties = {
352         VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
353         DE_NULL,
354         0,
355     };
356     VkImageFormatProperties2 extProperties = {
357         VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
358         &ycbcrProperties,
359         {
360             {
361                 0, // width
362                 0, // height
363                 0, // depth
364             },
365             0u, // maxMipLevels
366             0u, // maxArrayLayers
367             0,  // sampleCounts
368             0u, // maxResourceSize
369         },
370     };
371     VkResult propsResult;
372     const CustomInstance instance(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
373     const InstanceDriver &vki(instance.getDriver());
374 
375     // Verify that a yuv image consumes at least one descriptor
376     propsResult =
377         vki.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &imageFormatInfo, &extProperties);
378 
379     TCU_CHECK(propsResult == VK_SUCCESS);
380     TCU_CHECK(ycbcrProperties.combinedImageSamplerDescriptorCount >= 1);
381 
382     const Unique<VkSampler> sampler(createSampler(vkd, device, &samplerInfo));
383 
384     const Unique<VkDescriptorSetLayout> descLayout(createDescriptorSetLayout(vkd, device, *sampler));
385     const Unique<VkDescriptorPool> descPool(
386         createDescriptorPool(vkd, device, ycbcrProperties.combinedImageSamplerDescriptorCount));
387     const Unique<VkDescriptorSet> descSet(createDescriptorSet(vkd, device, *descPool, *descLayout, *imageView));
388 
389     MultiPlaneImageData imageData(format, size);
390 
391     // Zero fill unused layer
392     if (params.useArrayLayers)
393     {
394         fillZero(&imageData);
395 
396         if (mappedMemory)
397         {
398             fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *image, allocations, imageData,
399                             (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0);
400         }
401         else
402         {
403             uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *image,
404                         imageData, (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
405                         0);
406         }
407     }
408 
409     // Prepare texture data
410     fillGradient(&imageData, Vec4(0.0f), Vec4(1.0f));
411 
412     if (mappedMemory)
413     {
414         // Fill and prepare image
415         fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *image, allocations, imageData,
416                         (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, arrayLayer);
417     }
418     else
419     {
420         // Upload and prepare image
421         uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *image,
422                     imageData, (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
423                     arrayLayer);
424     }
425 
426     {
427         vector<Vec2> texCoord;
428         vector<Vec4> result;
429         vector<Vec4> reference;
430         bool allOk = true;
431         Vec4 threshold(0.02f);
432 
433         generateLookupCoordinates(size, &texCoord);
434 
435         result.resize(texCoord.size());
436         reference.resize(texCoord.size());
437 
438         {
439             UniquePtr<ShaderExecutor> executor(
440                 createExecutor(context, params.shaderType, getShaderSpec(params), *descLayout));
441             const void *inputs[] = {texCoord[0].getPtr()};
442             void *outputs[]      = {result[0].getPtr()};
443 
444             executor->execute((int)texCoord.size(), inputs, outputs, *descSet);
445         }
446 
447         for (uint32_t channelNdx = 0; channelNdx < 4; channelNdx++)
448         {
449             if (formatInfo.hasChannelNdx(channelNdx))
450             {
451                 const tcu::ConstPixelBufferAccess channelAccess = imageData.getChannelAccess(channelNdx);
452                 const tcu::Sampler refSampler                   = mapVkSampler(samplerInfo);
453                 const tcu::Texture2DView refTexView(1u, &channelAccess);
454 
455                 for (size_t ndx = 0; ndx < texCoord.size(); ++ndx)
456                 {
457                     const Vec2 &coord          = texCoord[ndx];
458                     reference[ndx][channelNdx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f)[0];
459                 }
460             }
461             else
462             {
463                 for (size_t ndx = 0; ndx < texCoord.size(); ++ndx)
464                     reference[ndx][channelNdx] = channelNdx == 3 ? 1.0f : 0.0f;
465             }
466         }
467 
468         for (size_t ndx = 0; ndx < texCoord.size(); ++ndx)
469         {
470             if (boolAny(greaterThanEqual(abs(result[ndx] - reference[ndx]), threshold)))
471             {
472                 context.getTestContext().getLog()
473                     << TestLog::Message << "ERROR: At " << texCoord[ndx] << ": got " << result[ndx] << ", expected "
474                     << reference[ndx] << TestLog::EndMessage;
475                 allOk = false;
476             }
477         }
478 
479         if (allOk)
480             return tcu::TestStatus::pass("All samples passed");
481         else
482         {
483             const tcu::ConstPixelBufferAccess refAccess(
484                 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT),
485                 tcu::IVec3((int)size.x(), (int)size.y(), 1u), reference[0].getPtr());
486             const tcu::ConstPixelBufferAccess resAccess(
487                 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT),
488                 tcu::IVec3((int)size.x(), (int)size.y(), 1u), result[0].getPtr());
489 
490             context.getTestContext().getLog()
491                 << TestLog::Image("Result", "Result Image", resAccess, Vec4(1.0f), Vec4(0.0f))
492                 << TestLog::Image("Reference", "Reference Image", refAccess, Vec4(1.0f), Vec4(0.0f));
493 
494             return tcu::TestStatus::fail("Got invalid results");
495         }
496     }
497 }
498 
initPrograms(SourceCollections & dst,TestParameters params)499 void initPrograms(SourceCollections &dst, TestParameters params)
500 {
501     const ShaderSpec spec = getShaderSpec(params);
502 
503     generateSources(params.shaderType, spec, dst);
504 }
505 
populatePerFormatGroup(tcu::TestCaseGroup * group,VkFormat format)506 void populatePerFormatGroup(tcu::TestCaseGroup *group, VkFormat format)
507 {
508     const UVec2 size(66, 32);
509     const glu::ShaderType shaderTypes[] = {glu::SHADERTYPE_VERTEX,
510                                            glu::SHADERTYPE_FRAGMENT,
511                                            glu::SHADERTYPE_GEOMETRY,
512                                            glu::SHADERTYPE_TESSELLATION_CONTROL,
513                                            glu::SHADERTYPE_TESSELLATION_EVALUATION,
514                                            glu::SHADERTYPE_COMPUTE};
515     const struct
516     {
517         const char *name;
518         VkImageTiling value;
519     } tilings[] = {{"optimal", VK_IMAGE_TILING_OPTIMAL}, {"linear", VK_IMAGE_TILING_LINEAR}};
520 
521     for (glu::ShaderType shaderType : shaderTypes)
522         for (int tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(tilings); tilingNdx++)
523             for (int useArrayLayers = 0; useArrayLayers < 2; useArrayLayers++)
524             {
525                 const VkImageTiling tiling       = tilings[tilingNdx].value;
526                 const char *const tilingName     = tilings[tilingNdx].name;
527                 const char *const shaderTypeName = glu::getShaderTypeName(shaderType);
528                 const string name = string(shaderTypeName) + "_" + tilingName + ((useArrayLayers) ? "_array" : "");
529 
530                 addFunctionCaseWithPrograms(
531                     group, name, checkSupport, initPrograms, testFormat,
532                     TestParameters(format, size, 0u, tiling, shaderType, false, useArrayLayers));
533 
534                 if (getPlaneCount(format) > 1)
535                     addFunctionCaseWithPrograms(group, name + "_disjoint", checkSupport, initPrograms, testFormat,
536                                                 TestParameters(format, size,
537                                                                (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT, tiling,
538                                                                shaderType, false, useArrayLayers));
539 
540                 if (tiling == VK_IMAGE_TILING_LINEAR)
541                 {
542                     addFunctionCaseWithPrograms(
543                         group, name + "_mapped", checkSupport, initPrograms, testFormat,
544                         TestParameters(format, size, 0u, tiling, shaderType, true, useArrayLayers));
545 
546                     if (getPlaneCount(format) > 1)
547                         addFunctionCaseWithPrograms(
548                             group, name + "_disjoint_mapped", checkSupport, initPrograms, testFormat,
549                             TestParameters(format, size, (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT, tiling,
550                                            shaderType, true, useArrayLayers));
551                 }
552             }
553 }
554 
populateFormatGroup(tcu::TestCaseGroup * group)555 void populateFormatGroup(tcu::TestCaseGroup *group)
556 {
557     for (int formatNdx = VK_YCBCR_FORMAT_FIRST; formatNdx < VK_YCBCR_FORMAT_LAST; formatNdx++)
558     {
559         const VkFormat format   = (VkFormat)formatNdx;
560         const string formatName = de::toLower(de::toString(format).substr(10));
561 
562         group->addChild(createTestGroup<VkFormat>(group->getTestContext(), formatName, populatePerFormatGroup, format));
563     }
564 
565     for (int formatNdx = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT; formatNdx <= VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT;
566          formatNdx++)
567     {
568         const VkFormat format   = (VkFormat)formatNdx;
569         const string formatName = de::toLower(de::toString(format).substr(10));
570 
571         group->addChild(createTestGroup<VkFormat>(group->getTestContext(), formatName, populatePerFormatGroup, format));
572     }
573 }
574 
575 } // namespace
576 
createFormatTests(tcu::TestContext & testCtx)577 tcu::TestCaseGroup *createFormatTests(tcu::TestContext &testCtx)
578 {
579     return createTestGroup(testCtx, "format", populateFormatGroup);
580 }
581 
582 } // namespace ycbcr
583 } // namespace vkt
584