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