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 ¶ms)
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