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)155 Move<VkDescriptorPool> createDescriptorPool (const DeviceInterface& vkd, VkDevice device)
156 {
157 	const VkDescriptorPoolSize			poolSizes[]	=
158 	{
159 		{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	1u	},
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::__anon629950a60111::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::__anon629950a60111::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 Unique<VkSampler>					sampler					(createSampler(vkd, device, &samplerInfo));
384 
385 	const Unique<VkDescriptorSetLayout>		descLayout				(createDescriptorSetLayout(vkd, device, *sampler));
386 	const Unique<VkDescriptorPool>			descPool				(createDescriptorPool(vkd, device));
387 	const Unique<VkDescriptorSet>			descSet					(createDescriptorSet(vkd, device, *descPool, *descLayout, *imageView));
388 
389 	MultiPlaneImageData						imageData				(format, size);
390 
391 	const VkPhysicalDeviceImageFormatInfo2			imageFormatInfo	=
392 	{
393 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
394 		DE_NULL,
395 		params.format,
396 		VK_IMAGE_TYPE_2D,
397 		params.tiling,
398 		VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
399 		params.flags,
400 	};
401 	VkSamplerYcbcrConversionImageFormatProperties		ycbcrProperties =
402 	{
403 		VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
404 		DE_NULL,
405 		0,
406 	};
407 	VkImageFormatProperties2				extProperties =
408 	{
409 		VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
410 		&ycbcrProperties,
411 		{
412 			{
413 				0,	// width
414 				0,	// height
415 				0,	// depth
416 			},
417 			0u,		// maxMipLevels
418 			0u,		// maxArrayLayers
419 			0,		// sampleCounts
420 			0u,		// maxResourceSize
421 		},
422 	};
423 	VkResult				propsResult;
424 	const CustomInstance			instance	(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
425 	const InstanceDriver&			vki			(instance.getDriver());
426 
427 	// Verify that a yuv image consumes at least one descriptor
428 	propsResult = vki.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &imageFormatInfo, &extProperties);
429 
430 	TCU_CHECK(propsResult == VK_SUCCESS);
431 	TCU_CHECK(ycbcrProperties.combinedImageSamplerDescriptorCount >= 1);
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 
632 } // namespace
633 
createFormatTests(tcu::TestContext & testCtx)634 tcu::TestCaseGroup* createFormatTests (tcu::TestContext& testCtx)
635 {
636 	return createTestGroup(testCtx, "format", "YCbCr Format Tests", populateFormatGroup);
637 }
638 
639 } // ycbcr
640 } // vkt
641