• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Texture color conversion tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktYCbCrConversionTests.hpp"
25 
26 #include "vktShaderExecutor.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29 #include "vktYCbCrUtil.hpp"
30 
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 
38 #include "tcuInterval.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuTexture.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "tcuVector.hpp"
43 #include "tcuVectorUtil.hpp"
44 #include "tcuFloatFormat.hpp"
45 #include "tcuFloat.hpp"
46 #include "tcuCommandLine.hpp"
47 
48 #include "deRandom.hpp"
49 #include "deSTLUtil.hpp"
50 #include "deSharedPtr.hpp"
51 
52 #include "deMath.h"
53 #include "deFloat16.h"
54 
55 #include <vector>
56 #include <iomanip>
57 
58 // \todo When defined color conversion extension is not used and conversion is performed in the shader
59 // #define FAKE_COLOR_CONVERSION
60 
61 using tcu::Vec2;
62 using tcu::Vec4;
63 
64 using tcu::UVec2;
65 using tcu::UVec4;
66 
67 using tcu::IVec2;
68 using tcu::IVec3;
69 using tcu::IVec4;
70 
71 using tcu::TestLog;
72 using tcu::FloatFormat;
73 
74 using std::vector;
75 using std::string;
76 
77 using namespace vkt::shaderexecutor;
78 
79 namespace vkt
80 {
81 namespace ycbcr
82 {
83 namespace
84 {
85 
86 template<typename T>
makeSharedPtr(vk::Move<T> move)87 inline de::SharedPtr<vk::Unique<T> > makeSharedPtr(vk::Move<T> move)
88 {
89 	return de::SharedPtr<vk::Unique<T> >(new vk::Unique<T>(move));
90 }
91 
createShaderSpec(deUint32 samplerBinding,const std::vector<vk::VkSamplerYcbcrModelConversion> & colorModels)92 ShaderSpec createShaderSpec (deUint32 samplerBinding, const std::vector<vk::VkSamplerYcbcrModelConversion>&	colorModels)
93 {
94 	ShaderSpec spec;
95 
96 	spec.inputs.push_back(Symbol("uv", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
97 	// shader with single sampler
98 	if (colorModels.size()==1)
99 	{
100 		spec.globalDeclarations	= "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=" + de::toString(samplerBinding) + ") uniform highp sampler2D u_sampler;";
101 
102 		spec.outputs.push_back(Symbol("o_color", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
103 
104 		spec.source				= "o_color = texture(u_sampler, uv);\n";
105 	}
106 	else // shader with array of samplers
107 	{
108 		spec.globalDeclarations	= "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=" + de::toString(samplerBinding) + ") uniform highp sampler2D u_sampler[" + de::toString(colorModels.size()) +  "];";
109 
110 		for (int i = 0; i < (int)colorModels.size(); i++)
111 		{
112 			spec.outputs.push_back(Symbol(string("o_color") + de::toString(i), glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
113 
114 			spec.source += string("o_color") + de::toString(i) + " = texture(u_sampler[" + de::toString(i) + "], uv);\n";
115 		}
116 	}
117 	return spec;
118 }
119 
genTexCoords(std::vector<Vec2> & coords,const UVec2 & srcSize,const UVec2 & dstSize)120 void genTexCoords (std::vector<Vec2>&	coords,
121 				   const UVec2&			srcSize,
122 				   const UVec2&			dstSize)
123 {
124 	for (deUint32 y = 0; y < dstSize.y(); y++)
125 	for (deUint32 x = 0; x < dstSize.x(); x++)
126 	{
127 		const float	fx	= (float)x;
128 		const float	fy	= (float)y;
129 
130 		const float	fw	= (float)srcSize.x();
131 		const float	fh	= (float)srcSize.y();
132 
133 		const float	s	= 1.5f * ((fx * 1.5f * fw + fx) / (1.5f * fw * 1.5f * fw)) - 0.25f;
134 		const float	t	= 1.5f * ((fy * 1.5f * fh + fy) / (1.5f * fh * 1.5f * fh)) - 0.25f;
135 
136 		coords.push_back(Vec2(s, t));
137 	}
138 }
139 
genOneToOneTexCoords(std::vector<Vec2> & coords,const UVec2 & size)140 void genOneToOneTexCoords (std::vector<Vec2>&	coords,
141 						   const UVec2&			size)
142 {
143 	for (deUint32 y = 0; y < size.y(); y++)
144 	for (deUint32 x = 0; x < size.x(); x++)
145 	{
146 		const float s = ((float)x + 0.5f) / (float)size.x();
147 		const float t = ((float)y + 0.5f) / (float)size.y();
148 
149 		coords.push_back(Vec2(s, t));
150 	}
151 }
152 
153 struct TestConfig
154 {
TestConfigvkt::ycbcr::__anoned4a6e000111::TestConfig155 	TestConfig	(glu::ShaderType						shaderType_,
156 				 vk::VkFormat							format_,
157 				 vk::VkImageTiling						imageTiling_,
158 				 vk::VkFilter							textureFilter_,
159 				 vk::VkSamplerAddressMode				addressModeU_,
160 				 vk::VkSamplerAddressMode				addressModeV_,
161 
162 				 vk::VkFilter							chromaFilter_,
163 				 vk::VkChromaLocation					xChromaOffset_,
164 				 vk::VkChromaLocation					yChromaOffset_,
165 				 bool									explicitReconstruction_,
166 				 bool									disjoint_,
167 
168 				 vk::VkSamplerYcbcrRange				colorRange_,
169 				 vk::VkSamplerYcbcrModelConversion		colorModel_,
170 				 vk::VkComponentMapping					componentMapping_,
171 				 const UVec2							srcSize_,
172 				 const UVec2							dstSize_,
173 				 deUint32								samplerBinding_)
174 		: shaderType				(shaderType_)
175 		, format					(format_)
176 		, imageTiling				(imageTiling_)
177 		, textureFilter				(textureFilter_)
178 		, addressModeU				(addressModeU_)
179 		, addressModeV				(addressModeV_)
180 
181 		, chromaFilter				(chromaFilter_)
182 		, xChromaOffset				(xChromaOffset_)
183 		, yChromaOffset				(yChromaOffset_)
184 		, explicitReconstruction	(explicitReconstruction_)
185 		, disjoint					(disjoint_)
186 
187 		, colorRange				(colorRange_)
188 		, colorModel				(colorModel_)
189 		, componentMapping			(componentMapping_)
190 		, srcSize					(srcSize_)
191 		, dstSize					(dstSize_)
192 		, samplerBinding			(samplerBinding_)
193 	{
194 	}
195 
196 	glu::ShaderType							shaderType;
197 	vk::VkFormat							format;
198 	vk::VkImageTiling						imageTiling;
199 	vk::VkFilter							textureFilter;
200 	vk::VkSamplerAddressMode				addressModeU;
201 	vk::VkSamplerAddressMode				addressModeV;
202 
203 	vk::VkFilter							chromaFilter;
204 	vk::VkChromaLocation					xChromaOffset;
205 	vk::VkChromaLocation					yChromaOffset;
206 	bool									explicitReconstruction;
207 	bool									disjoint;
208 
209 	vk::VkSamplerYcbcrRange					colorRange;
210 	vk::VkSamplerYcbcrModelConversion		colorModel;
211 	vk::VkComponentMapping					componentMapping;
212 	const UVec2								srcSize;
213 	const UVec2								dstSize;
214 	deUint32								samplerBinding;
215 };
216 
createDescriptorSetLayout(const vk::DeviceInterface & vkd,vk::VkDevice device,const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler>>> & samplers,deUint32 samplerBinding)217 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface&											vkd,
218 															   vk::VkDevice															device,
219 															   const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler> > >&		samplers,
220 															   deUint32																samplerBinding)
221 {
222 	std::vector<vk::VkSampler> sampler;
223 	for (size_t i = 0; i < samplers.size(); i++)
224 		sampler.push_back(samplers[i]->get());
225 	const vk::VkDescriptorSetLayoutBinding		layoutBindings[] =
226 	{
227 		{
228 			samplerBinding,
229 			vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
230 			(deUint32)sampler.size(),
231 			vk::VK_SHADER_STAGE_ALL,
232 			sampler.data()
233 		}
234 	};
235 	const vk::VkDescriptorSetLayoutCreateInfo	layoutCreateInfo	=
236 	{
237 		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
238 		DE_NULL,
239 
240 		0u,
241 		DE_LENGTH_OF_ARRAY(layoutBindings),
242 		layoutBindings
243 	};
244 
245 	return vk::createDescriptorSetLayout(vkd, device, &layoutCreateInfo);
246 }
247 
createDescriptorPool(const vk::DeviceInterface & vkd,vk::VkDevice device,const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler>>> & samplers,const deUint32 combinedSamplerDescriptorCount)248 vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface&											vkd,
249 													 vk::VkDevice														device,
250 													 const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler> > >&		samplers,
251 													 const deUint32														combinedSamplerDescriptorCount)
252 {
253 	const vk::VkDescriptorPoolSize			poolSizes[]					=
254 	{
255 		{ vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, (deUint32)samplers.size() * combinedSamplerDescriptorCount }
256 	};
257 	const vk::VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
258 	{
259 		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
260 		DE_NULL,
261 		vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
262 
263 		1u,
264 		DE_LENGTH_OF_ARRAY(poolSizes),
265 		poolSizes
266 	};
267 
268 	return createDescriptorPool(vkd, device, &descriptorPoolCreateInfo);
269 }
270 
createDescriptorSet(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkDescriptorPool descriptorPool,vk::VkDescriptorSetLayout layout,const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler>>> & samplers,const std::vector<de::SharedPtr<vk::Unique<vk::VkImageView>>> & imageViews,deUint32 samplerBinding)271 vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface&											vkd,
272 												   vk::VkDevice															device,
273 												   vk::VkDescriptorPool													descriptorPool,
274 												   vk::VkDescriptorSetLayout											layout,
275 												   const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler> > >&		samplers,
276 												   const std::vector<de::SharedPtr<vk::Unique<vk::VkImageView> > >&		imageViews,
277 												   deUint32																samplerBinding)
278 {
279 	const vk::VkDescriptorSetAllocateInfo		descriptorSetAllocateInfo	=
280 	{
281 		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
282 		DE_NULL,
283 
284 		descriptorPool,
285 		1u,
286 		&layout
287 	};
288 	vk::Move<vk::VkDescriptorSet>	descriptorSet	(vk::allocateDescriptorSet(vkd, device, &descriptorSetAllocateInfo));
289 	std::vector<vk::VkDescriptorImageInfo>	imageInfo;
290 	for (size_t i = 0; i < samplers.size(); i++)
291 	{
292 		const vk::VkDescriptorImageInfo	ii =
293 		{
294 			samplers[i]->get(),
295 			imageViews[i]->get(),
296 			vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
297 		};
298 		imageInfo.push_back(ii);
299 	}
300 
301 	{
302 		const vk::VkWriteDescriptorSet	writes[]	=
303 		{
304 			{
305 				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
306 				DE_NULL,
307 
308 				*descriptorSet,
309 				samplerBinding,
310 				0u,
311 				(deUint32)imageInfo.size(),
312 				vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
313 				imageInfo.data(),
314 				DE_NULL,
315 				DE_NULL
316 			}
317 		};
318 
319 		vkd.updateDescriptorSets(device, DE_LENGTH_OF_ARRAY(writes), writes, 0u, DE_NULL);
320 	}
321 
322 	return descriptorSet;
323 }
324 
createSampler(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkFilter textureFilter,vk::VkSamplerAddressMode addressModeU,vk::VkSamplerAddressMode addressModeV,vk::VkSamplerYcbcrConversion conversion)325 vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface&		vkd,
326 									   vk::VkDevice						device,
327 									   vk::VkFilter						textureFilter,
328 									   vk::VkSamplerAddressMode			addressModeU,
329 									   vk::VkSamplerAddressMode			addressModeV,
330 									   vk::VkSamplerYcbcrConversion		conversion)
331 {
332 #if !defined(FAKE_COLOR_CONVERSION)
333 	const vk::VkSamplerYcbcrConversionInfo	samplerConversionInfo	=
334 	{
335 		vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
336 		DE_NULL,
337 		conversion
338 	};
339 #else
340 	DE_UNREF(conversion);
341 #endif
342 	const vk::VkSamplerCreateInfo	createInfo	=
343 	{
344 		vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
345 #if !defined(FAKE_COLOR_CONVERSION)
346 		&samplerConversionInfo,
347 #else
348 		DE_NULL,
349 #endif
350 
351 		0u,
352 		textureFilter,
353 		textureFilter,
354 		vk::VK_SAMPLER_MIPMAP_MODE_NEAREST,
355 		addressModeU,
356 		addressModeV,
357 		vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
358 		0.0f,
359 		VK_FALSE,
360 		1.0f,
361 		VK_FALSE,
362 		vk::VK_COMPARE_OP_ALWAYS,
363 		0.0f,
364 		0.0f,
365 		vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
366 		VK_FALSE,
367 	};
368 
369 	return createSampler(vkd, device, &createInfo);
370 }
371 
createImage(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkFormat format,const UVec2 & size,bool disjoint,vk::VkImageTiling tiling)372 vk::Move<vk::VkImage> createImage (const vk::DeviceInterface&	vkd,
373 								   vk::VkDevice					device,
374 								   vk::VkFormat					format,
375 								   const UVec2&					size,
376 								   bool							disjoint,
377 								   vk::VkImageTiling			tiling)
378 {
379 	const vk::VkImageCreateInfo createInfo =
380 	{
381 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
382 		DE_NULL,
383 		disjoint ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlags)0u,
384 
385 		vk::VK_IMAGE_TYPE_2D,
386 		format,
387 		vk::makeExtent3D(size.x(), size.y(), 1u),
388 		1u,
389 		1u,
390 		vk::VK_SAMPLE_COUNT_1_BIT,
391 		tiling,
392 		vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk::VK_IMAGE_USAGE_SAMPLED_BIT,
393 		vk::VK_SHARING_MODE_EXCLUSIVE,
394 		0u,
395 		(const deUint32*)DE_NULL,
396 		vk::VK_IMAGE_LAYOUT_PREINITIALIZED,
397 	};
398 
399 	return vk::createImage(vkd, device, &createInfo);
400 }
401 
createImageView(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkImage image,vk::VkFormat format,vk::VkSamplerYcbcrConversion conversion)402 vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface&		vkd,
403 										   vk::VkDevice						device,
404 										   vk::VkImage						image,
405 										   vk::VkFormat						format,
406 										   vk::VkSamplerYcbcrConversion		conversion)
407 {
408 	// Both mappings should be equivalent: alternate between the two for different formats.
409 	const vk::VkComponentMapping	mappingA	= { vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY };
410 	const vk::VkComponentMapping	mappingB	= { vk::VK_COMPONENT_SWIZZLE_R, vk::VK_COMPONENT_SWIZZLE_G, vk::VK_COMPONENT_SWIZZLE_B, vk::VK_COMPONENT_SWIZZLE_A };
411 	const vk::VkComponentMapping&	mapping		= ((static_cast<int>(format) % 2 == 0) ? mappingA : mappingB);
412 
413 #if !defined(FAKE_COLOR_CONVERSION)
414 	const vk::VkSamplerYcbcrConversionInfo	conversionInfo	=
415 	{
416 		vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
417 		DE_NULL,
418 		conversion
419 	};
420 #else
421 	DE_UNREF(conversion);
422 #endif
423 	const vk::VkImageViewCreateInfo				viewInfo		=
424 	{
425 		vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
426 #if defined(FAKE_COLOR_CONVERSION)
427 		DE_NULL,
428 #else
429 		&conversionInfo,
430 #endif
431 		(vk::VkImageViewCreateFlags)0,
432 
433 		image,
434 		vk::VK_IMAGE_VIEW_TYPE_2D,
435 		format,
436 		mapping,
437 		{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },
438 	};
439 
440 	return vk::createImageView(vkd, device, &viewInfo);
441 }
442 
createConversion(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::VkFormat format,vk::VkSamplerYcbcrModelConversion colorModel,vk::VkSamplerYcbcrRange colorRange,vk::VkChromaLocation xChromaOffset,vk::VkChromaLocation yChromaOffset,vk::VkFilter chromaFilter,const vk::VkComponentMapping & componentMapping,bool explicitReconstruction)443 vk::Move<vk::VkSamplerYcbcrConversion> createConversion (const vk::DeviceInterface&				vkd,
444 														 vk::VkDevice							device,
445 														 vk::VkFormat							format,
446 														 vk::VkSamplerYcbcrModelConversion		colorModel,
447 														 vk::VkSamplerYcbcrRange				colorRange,
448 														 vk::VkChromaLocation					xChromaOffset,
449 														 vk::VkChromaLocation					yChromaOffset,
450 														 vk::VkFilter							chromaFilter,
451 														 const vk::VkComponentMapping&			componentMapping,
452 														 bool									explicitReconstruction)
453 {
454 	const vk::VkSamplerYcbcrConversionCreateInfo	conversionInfo	=
455 	{
456 		vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
457 		DE_NULL,
458 
459 		format,
460 		colorModel,
461 		colorRange,
462 		componentMapping,
463 		xChromaOffset,
464 		yChromaOffset,
465 		chromaFilter,
466 		explicitReconstruction ? VK_TRUE : VK_FALSE
467 	};
468 
469 	return vk::createSamplerYcbcrConversion(vkd, device, &conversionInfo);
470 }
471 
evalShader(Context & context,glu::ShaderType shaderType,const MultiPlaneImageData & imageData,const UVec2 & size,vk::VkFormat format,vk::VkImageTiling imageTiling,bool disjoint,vk::VkFilter textureFilter,vk::VkSamplerAddressMode addressModeU,vk::VkSamplerAddressMode addressModeV,const std::vector<vk::VkSamplerYcbcrModelConversion> & colorModels,vk::VkSamplerYcbcrRange colorRange,vk::VkChromaLocation xChromaOffset,vk::VkChromaLocation yChromaOffset,vk::VkFilter chromaFilter,const vk::VkComponentMapping & componentMapping,bool explicitReconstruction,const vector<Vec2> & sts,deUint32 samplerBinding,vector<vector<Vec4>> & results)472 void evalShader (Context&												context,
473 				 glu::ShaderType										shaderType,
474 				 const MultiPlaneImageData&								imageData,
475 				 const UVec2&											size,
476 				 vk::VkFormat											format,
477 				 vk::VkImageTiling										imageTiling,
478 				 bool													disjoint,
479 				 vk::VkFilter											textureFilter,
480 				 vk::VkSamplerAddressMode								addressModeU,
481 				 vk::VkSamplerAddressMode								addressModeV,
482 				 const std::vector<vk::VkSamplerYcbcrModelConversion>&	colorModels,
483 				 vk::VkSamplerYcbcrRange								colorRange,
484 				 vk::VkChromaLocation									xChromaOffset,
485 				 vk::VkChromaLocation									yChromaOffset,
486 				 vk::VkFilter											chromaFilter,
487 				 const vk::VkComponentMapping&							componentMapping,
488 				 bool													explicitReconstruction,
489 				 const vector<Vec2>&									sts,
490 				 deUint32												samplerBinding,
491 				 vector<vector<Vec4> >&									results)
492 {
493 	const vk::InstanceInterface&											vk				(context.getInstanceInterface());
494 	const vk::DeviceInterface&												vkd				(context.getDeviceInterface());
495 	const vk::VkDevice														device			(context.getDevice());
496 	std::vector<de::SharedPtr<vk::Unique<vk::VkSamplerYcbcrConversion> > >	conversions;
497 	std::vector<de::SharedPtr<vk::Unique<vk::VkSampler> > >					samplers;
498 #if !defined(FAKE_COLOR_CONVERSION)
499 	for (int i = 0; i < (int)colorModels.size(); i++)
500 	{
501 		conversions.push_back(makeSharedPtr(createConversion(vkd, device, format, colorModels[i], colorRange, xChromaOffset, yChromaOffset, chromaFilter, componentMapping, explicitReconstruction)));
502 		samplers.push_back(makeSharedPtr(createSampler(vkd, device, textureFilter, addressModeU, addressModeV, conversions[i]->get())));
503 	}
504 #else
505 	DE_UNREF(colorRange);
506 	DE_UNREF(xChromaOffset);
507 	DE_UNREF(yChromaOffset);
508 	DE_UNREF(chromaFilter);
509 	DE_UNREF(explicitReconstruction);
510 	DE_UNREF(componentMapping);
511 	samplers.push_back(makeSharedPtr(createSampler(vkd, device, textureFilter, addressModeU, addressModeV, (vk::VkSamplerYcbcrConversion)0u)));
512 #endif
513 	const vk::Unique<vk::VkImage>								image				(createImage(vkd, device, format, size, disjoint, imageTiling));
514 	const vk::MemoryRequirement									memoryRequirement	(imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
515 																					? vk::MemoryRequirement::Any
516 																					: vk::MemoryRequirement::HostVisible);
517 	const vk::VkImageCreateFlags								createFlags			(disjoint ? vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlagBits)0u);
518 	const vector<AllocationSp>									imageMemory			(allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags, memoryRequirement));
519 	std::vector<de::SharedPtr<vk::Unique<vk::VkImageView > > >	imageViews;
520 #if defined(FAKE_COLOR_CONVERSION)
521 	imageViews.push_back(makeSharedPtr(createImageView(vkd, device, *image, format, (vk::VkSamplerYcbcrConversion)0)));
522 #else
523 	for (int i = 0; i < (int)colorModels.size(); i++)
524 	{
525 		imageViews.push_back(makeSharedPtr(createImageView(vkd, device, *image, format, conversions[i]->get())));
526 	}
527 #endif
528 
529 	deUint32 combinedSamplerDescriptorCount = 1;
530 	{
531 		const vk::VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
532 		{
533 			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,	//VkStructureType		sType;
534 			DE_NULL,													//const void*			pNext;
535 			format,														//VkFormat				format;
536 			vk::VK_IMAGE_TYPE_2D,										//VkImageType			type;
537 			imageTiling,												//VkImageTiling			tiling;
538 			vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT |
539 			vk::VK_IMAGE_USAGE_SAMPLED_BIT,								//VkImageUsageFlags		usage;
540 			disjoint ?
541 			(vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_DISJOINT_BIT :
542 			(vk::VkImageCreateFlags)0u									//VkImageCreateFlags	flags;
543 		};
544 
545 		vk::VkSamplerYcbcrConversionImageFormatProperties samplerYcbcrConversionImage = {};
546 		samplerYcbcrConversionImage.sType = vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES;
547 		samplerYcbcrConversionImage.pNext = DE_NULL;
548 
549 		vk::VkImageFormatProperties2 imageFormatProperties = {};
550 		imageFormatProperties.sType = vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
551 		imageFormatProperties.pNext = &samplerYcbcrConversionImage;
552 
553 		VK_CHECK(vk.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &imageFormatInfo, &imageFormatProperties));
554 		combinedSamplerDescriptorCount = samplerYcbcrConversionImage.combinedImageSamplerDescriptorCount;
555 	}
556 
557 
558 	const vk::Unique<vk::VkDescriptorSetLayout>			layout				(createDescriptorSetLayout(vkd, device, samplers, samplerBinding));
559 	const vk::Unique<vk::VkDescriptorPool>				descriptorPool		(createDescriptorPool(vkd, device, samplers, combinedSamplerDescriptorCount));
560 	const vk::Unique<vk::VkDescriptorSet>				descriptorSet		(createDescriptorSet(vkd, device, *descriptorPool, *layout, samplers, imageViews, samplerBinding));
561 
562 	const ShaderSpec									spec				(createShaderSpec(samplerBinding, colorModels));
563 	const de::UniquePtr<ShaderExecutor>					executor			(createExecutor(context, shaderType, spec, *layout));
564 
565 	if (imageTiling == vk::VK_IMAGE_TILING_OPTIMAL)
566 		uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *image, imageData, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
567 	else
568 		fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *image, imageMemory, imageData, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
569 
570 	for(int i=0; i<(int)results.size(); i++)
571 		results[i].resize(sts.size());
572 
573 	{
574 		const void* const	inputs[]	=
575 		{
576 			&sts[0]
577 		};
578 		vector<void*> outputs;
579 		for (int i = 0; i < (int)results.size(); i++)
580 			outputs.push_back((void*)results[i].data());
581 
582 		executor->execute((int)sts.size(), inputs, outputs.data(), *descriptorSet);
583 	}
584 }
585 
logTestCaseInfo(TestLog & log,const TestConfig & config)586 void logTestCaseInfo (TestLog& log, const TestConfig& config)
587 {
588 	log << TestLog::Message << "ShaderType: " << config.shaderType << TestLog::EndMessage;
589 	log << TestLog::Message << "Format: "  << config.format << TestLog::EndMessage;
590 	log << TestLog::Message << "ImageTiling: " << config.imageTiling << TestLog::EndMessage;
591 	log << TestLog::Message << "TextureFilter: " << config.textureFilter << TestLog::EndMessage;
592 	log << TestLog::Message << "AddressModeU: " << config.addressModeU << TestLog::EndMessage;
593 	log << TestLog::Message << "AddressModeV: " << config.addressModeV << TestLog::EndMessage;
594 	log << TestLog::Message << "ChromaFilter: " << config.chromaFilter << TestLog::EndMessage;
595 	log << TestLog::Message << "XChromaOffset: " << config.xChromaOffset << TestLog::EndMessage;
596 	log << TestLog::Message << "YChromaOffset: " << config.yChromaOffset << TestLog::EndMessage;
597 	log << TestLog::Message << "ExplicitReconstruction: " << (config.explicitReconstruction ? "true" : "false") << TestLog::EndMessage;
598 	log << TestLog::Message << "Disjoint: " << (config.disjoint ? "true" : "false") << TestLog::EndMessage;
599 	log << TestLog::Message << "ColorRange: " << config.colorRange << TestLog::EndMessage;
600 	if( config.colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST )
601 		log << TestLog::Message << "ColorModel: " << config.colorModel << TestLog::EndMessage;
602 	else
603 		log << TestLog::Message << "ColorModel: array of samplers" << TestLog::EndMessage;
604 	log << TestLog::Message << "ComponentMapping: " << config.componentMapping << TestLog::EndMessage;
605 }
606 
checkSupport(Context & context,const TestConfig config)607 void checkSupport (Context& context, const TestConfig config)
608 {
609 #if !defined(FAKE_COLOR_CONVERSION)
610 	if (!context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion"))
611 		TCU_THROW(NotSupportedError, "Extension VK_KHR_sampler_ycbcr_conversion not supported");
612 
613 	{
614 		const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures	features = context.getSamplerYcbcrConversionFeatures();
615 		if (features.samplerYcbcrConversion == VK_FALSE)
616 			TCU_THROW(NotSupportedError, "samplerYcbcrConversion feature is not supported");
617 	}
618 
619 	try
620 	{
621 		const vk::VkFormatProperties	properties	(vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), config.format));
622 		const vk::VkFormatFeatureFlags	features	(config.imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
623 			? properties.optimalTilingFeatures
624 			: properties.linearTilingFeatures);
625 
626 		if ((features & (vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0)
627 			TCU_THROW(NotSupportedError, "Format doesn't support YCbCr conversions");
628 
629 		if ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0)
630 			TCU_THROW(NotSupportedError, "Format doesn't support sampling");
631 
632 		if (config.textureFilter == vk::VK_FILTER_LINEAR && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) == 0))
633 			TCU_THROW(NotSupportedError, "Format doesn't support linear texture filtering");
634 
635 		if (config.chromaFilter == vk::VK_FILTER_LINEAR && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) == 0))
636 			TCU_THROW(NotSupportedError, "Format doesn't support YCbCr linear chroma reconstruction");
637 
638 		if (config.chromaFilter != config.textureFilter && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT) == 0))
639 			TCU_THROW(NotSupportedError, "Format doesn't support different chroma and texture filters");
640 
641 		if (config.explicitReconstruction && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT) == 0))
642 			TCU_THROW(NotSupportedError, "Format doesn't support explicit chroma reconstruction");
643 
644 		if (config.disjoint && ((features & vk::VK_FORMAT_FEATURE_DISJOINT_BIT) == 0))
645 			TCU_THROW(NotSupportedError, "Format doesn't disjoint planes");
646 
647 		if (isXChromaSubsampled(config.format) && (config.xChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN) && ((features & vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT) == 0))
648 			TCU_THROW(NotSupportedError, "Format doesn't support cosited chroma samples");
649 
650 		if (isXChromaSubsampled(config.format) && (config.xChromaOffset == vk::VK_CHROMA_LOCATION_MIDPOINT) && ((features & vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT) == 0))
651 			TCU_THROW(NotSupportedError, "Format doesn't support midpoint chroma samples");
652 
653 		if (isYChromaSubsampled(config.format) && (config.yChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN) && ((features & vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT) == 0))
654 			TCU_THROW(NotSupportedError, "Format doesn't support cosited chroma samples");
655 
656 		if (isYChromaSubsampled(config.format) && (config.yChromaOffset == vk::VK_CHROMA_LOCATION_MIDPOINT) && ((features & vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT) == 0))
657 			TCU_THROW(NotSupportedError, "Format doesn't support midpoint chroma samples");
658 	}
659 	catch (const vk::Error& err)
660 	{
661 		if (err.getError() == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
662 			TCU_THROW(NotSupportedError, "Format not supported");
663 
664 		throw;
665 	}
666 #endif
667 }
668 
textureConversionTest(Context & context,const TestConfig config)669 tcu::TestStatus textureConversionTest (Context& context, const TestConfig config)
670 {
671 	const std::vector<FloatFormat>	filteringPrecision		(getPrecision(config.format));
672 	const std::vector<FloatFormat>	conversionPrecision		(getPrecision(config.format));
673 	const deUint32					subTexelPrecisionBits	(vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits.subTexelPrecisionBits);
674 	const tcu::UVec4				bitDepth				(getYCbCrBitDepth(config.format));
675 	TestLog&						log						(context.getTestContext().getLog());
676 	bool							explicitReconstruction	= config.explicitReconstruction;
677 	const UVec2						srcSize					= config.srcSize;
678 	const UVec2						dstSize					= config.dstSize;
679 	bool							isOk					= true;
680 
681 	logTestCaseInfo(log, config);
682 
683 #if !defined(FAKE_COLOR_CONVERSION)
684 	try
685 	{
686 		const vk::VkFormatProperties	properties	(vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), config.format));
687 		const vk::VkFormatFeatureFlags	features	(config.imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
688 													? properties.optimalTilingFeatures
689 													: properties.linearTilingFeatures);
690 
691 		if ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT) != 0)
692 			explicitReconstruction = true;
693 
694 		log << TestLog::Message << "FormatFeatures: " << vk::getFormatFeatureFlagsStr(features) << TestLog::EndMessage;
695 	}
696 	catch (const vk::Error& err)
697 	{
698 		if (err.getError() == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
699 			TCU_THROW(NotSupportedError, "Format not supported");
700 
701 		throw;
702 	}
703 #endif
704 
705 	{
706 		const vk::PlanarFormatDescription	planeInfo				(vk::getPlanarFormatDescription(config.format));
707 		MultiPlaneImageData					src						(config.format, srcSize);
708 
709 		deUint32							nullAccessData			(0u);
710 		ChannelAccess						nullAccess				(tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, 1u, IVec3(srcSize.x(), srcSize.y(), 1), IVec3(0, 0, 0), &nullAccessData, 0u);
711 		deUint32							nullAccessAlphaData		(~0u);
712 		ChannelAccess						nullAccessAlpha			(tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, 1u, IVec3(srcSize.x(), srcSize.y(), 1), IVec3(0, 0, 0), &nullAccessAlphaData, 0u);
713 		ChannelAccess						rChannelAccess			(planeInfo.hasChannelNdx(0) ? getChannelAccess(src, planeInfo, srcSize, 0) : nullAccess);
714 		ChannelAccess						gChannelAccess			(planeInfo.hasChannelNdx(1) ? getChannelAccess(src, planeInfo, srcSize, 1) : nullAccess);
715 		ChannelAccess						bChannelAccess			(planeInfo.hasChannelNdx(2) ? getChannelAccess(src, planeInfo, srcSize, 2) : nullAccess);
716 		ChannelAccess						aChannelAccess			(planeInfo.hasChannelNdx(3) ? getChannelAccess(src, planeInfo, srcSize, 3) : nullAccessAlpha);
717 		const bool							implicitNearestCosited	((config.chromaFilter == vk::VK_FILTER_NEAREST && !config.explicitReconstruction) &&
718 																	 (config.xChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN || config.yChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN));
719 
720 		vector<Vec2>						sts;
721 		vector<vector<Vec4> >				results;
722 		vector<vector<Vec4> >				minBounds;
723 		vector<vector<Vec4> >				minMidpointBounds;
724 		vector<vector<Vec4> >				maxBounds;
725 		vector<vector<Vec4> >				maxMidpointBounds;
726 		vector<vector<Vec4> >				uvBounds;
727 		vector<vector<IVec4> >				ijBounds;
728 
729 		for (deUint32 planeNdx = 0; planeNdx < planeInfo.numPlanes; planeNdx++)
730 			deMemset(src.getPlanePtr(planeNdx), 0u, src.getPlaneSize(planeNdx));
731 
732 		// \todo Limit values to only values that produce defined values using selected colorRange and colorModel? The verification code handles those cases already correctly.
733 		if (planeInfo.hasChannelNdx(0))
734 		{
735 			for (int y = 0; y < rChannelAccess.getSize().y(); y++)
736 			for (int x = 0; x < rChannelAccess.getSize().x(); x++)
737 				rChannelAccess.setChannel(IVec3(x, y, 0), (float)x / (float)rChannelAccess.getSize().x());
738 		}
739 
740 		if (planeInfo.hasChannelNdx(1))
741 		{
742 			for (int y = 0; y < gChannelAccess.getSize().y(); y++)
743 			for (int x = 0; x < gChannelAccess.getSize().x(); x++)
744 				gChannelAccess.setChannel(IVec3(x, y, 0), (float)y / (float)gChannelAccess.getSize().y());
745 		}
746 
747 		if (planeInfo.hasChannelNdx(2))
748 		{
749 			for (int y = 0; y < bChannelAccess.getSize().y(); y++)
750 			for (int x = 0; x < bChannelAccess.getSize().x(); x++)
751 				bChannelAccess.setChannel(IVec3(x, y, 0), (float)(x + y) / (float)(bChannelAccess.getSize().x() + bChannelAccess.getSize().y()));
752 		}
753 
754 		if (planeInfo.hasChannelNdx(3))
755 		{
756 			for (int y = 0; y < aChannelAccess.getSize().y(); y++)
757 			for (int x = 0; x < aChannelAccess.getSize().x(); x++)
758 				aChannelAccess.setChannel(IVec3(x, y, 0), (float)(x * y) / (float)(aChannelAccess.getSize().x() * aChannelAccess.getSize().y()));
759 		}
760 
761 		if (dstSize.x() > srcSize.x() && dstSize.y() > srcSize.y())
762 			genTexCoords(sts, srcSize, dstSize);
763 		else
764 			genOneToOneTexCoords(sts, dstSize);
765 
766 		std::vector< vk::VkSamplerYcbcrModelConversion> colorModels;
767 		if (config.colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST)
768 		{
769 			colorModels.push_back(config.colorModel);
770 		}
771 		else
772 		{
773 			int ycbcrModelConverionCount = std::min( (int)vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, 4 );
774 			for (int i = 0; i < ycbcrModelConverionCount; i++)
775 			{
776 				colorModels.push_back((vk::VkSamplerYcbcrModelConversion)(vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + i));
777 			}
778 		}
779 
780 		for (int i = 0; i < (int)colorModels.size(); i++)
781 		{
782 			vector<Vec4>				minBound;
783 			vector<Vec4>				minMidpointBound;
784 			vector<Vec4>				maxBound;
785 			vector<Vec4>				maxMidpointBound;
786 			vector<Vec4>				uvBound;
787 			vector<IVec4>				ijBound;
788 
789 			calculateBounds(rChannelAccess, gChannelAccess, bChannelAccess, aChannelAccess, bitDepth, sts, filteringPrecision, conversionPrecision, subTexelPrecisionBits, config.textureFilter, colorModels[i], config.colorRange, config.chromaFilter, config.xChromaOffset, config.yChromaOffset, config.componentMapping, explicitReconstruction, config.addressModeU, config.addressModeV, minBound, maxBound, uvBound, ijBound);
790 
791 			if (implicitNearestCosited)
792 			{
793 				calculateBounds(rChannelAccess, gChannelAccess, bChannelAccess, aChannelAccess, bitDepth, sts, filteringPrecision, conversionPrecision, subTexelPrecisionBits, config.textureFilter, colorModels[i], config.colorRange, config.chromaFilter, vk::VK_CHROMA_LOCATION_MIDPOINT, vk::VK_CHROMA_LOCATION_MIDPOINT, config.componentMapping, explicitReconstruction, config.addressModeU, config.addressModeV, minMidpointBound, maxMidpointBound, uvBound, ijBound);
794 			}
795 			results.push_back			(vector<Vec4>());
796 			minBounds.push_back			(minBound);
797 			minMidpointBounds.push_back	(minMidpointBound);
798 			maxBounds.push_back			(maxBound);
799 			maxMidpointBounds.push_back	(maxMidpointBound);
800 			uvBounds.push_back			(uvBound);
801 			ijBounds.push_back			(ijBound);
802 		}
803 
804 		if (vk::isYCbCrFormat(config.format))
805 		{
806 			tcu::TextureLevel	rImage	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), rChannelAccess.getSize().x(), rChannelAccess.getSize().y());
807 			tcu::TextureLevel	gImage	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), gChannelAccess.getSize().x(), gChannelAccess.getSize().y());
808 			tcu::TextureLevel	bImage	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), bChannelAccess.getSize().x(), bChannelAccess.getSize().y());
809 			tcu::TextureLevel	aImage	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), aChannelAccess.getSize().x(), aChannelAccess.getSize().y());
810 
811 			for (int y = 0; y < (int)rChannelAccess.getSize().y(); y++)
812 			for (int x = 0; x < (int)rChannelAccess.getSize().x(); x++)
813 				rImage.getAccess().setPixel(Vec4(rChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
814 
815 			for (int y = 0; y < (int)gChannelAccess.getSize().y(); y++)
816 			for (int x = 0; x < (int)gChannelAccess.getSize().x(); x++)
817 				gImage.getAccess().setPixel(Vec4(gChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
818 
819 			for (int y = 0; y < (int)bChannelAccess.getSize().y(); y++)
820 			for (int x = 0; x < (int)bChannelAccess.getSize().x(); x++)
821 				bImage.getAccess().setPixel(Vec4(bChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
822 
823 			for (int y = 0; y < (int)aChannelAccess.getSize().y(); y++)
824 			for (int x = 0; x < (int)aChannelAccess.getSize().x(); x++)
825 				aImage.getAccess().setPixel(Vec4(aChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
826 
827 			{
828 				const Vec4	scale	(1.0f);
829 				const Vec4	bias	(0.0f);
830 
831 				log << TestLog::Image("SourceImageR", "SourceImageR", rImage.getAccess(), scale, bias);
832 				log << TestLog::Image("SourceImageG", "SourceImageG", gImage.getAccess(), scale, bias);
833 				log << TestLog::Image("SourceImageB", "SourceImageB", bImage.getAccess(), scale, bias);
834 				log << TestLog::Image("SourceImageA", "SourceImageA", aImage.getAccess(), scale, bias);
835 			}
836 		}
837 		else
838 		{
839 			tcu::TextureLevel	srcImage	(vk::mapVkFormat(config.format), srcSize.x(), srcSize.y());
840 
841 			for (int y = 0; y < (int)srcSize.y(); y++)
842 			for (int x = 0; x < (int)srcSize.x(); x++)
843 			{
844 				const IVec3 pos (x, y, 0);
845 				srcImage.getAccess().setPixel(Vec4(rChannelAccess.getChannel(pos), gChannelAccess.getChannel(pos), bChannelAccess.getChannel(pos), aChannelAccess.getChannel(pos)), x, y);
846 			}
847 
848 			log << TestLog::Image("SourceImage", "SourceImage", srcImage.getAccess());
849 		}
850 
851 		evalShader(context, config.shaderType, src, srcSize, config.format, config.imageTiling, config.disjoint, config.textureFilter, config.addressModeU, config.addressModeV, colorModels, config.colorRange, config.xChromaOffset, config.yChromaOffset, config.chromaFilter, config.componentMapping, config.explicitReconstruction, sts, config.samplerBinding, results);
852 
853 		{
854 			std::vector<tcu::TextureLevel>	minImages;
855 			std::vector<tcu::TextureLevel>	maxImages;
856 			std::vector<tcu::TextureLevel>	minMidpointImages;
857 			std::vector<tcu::TextureLevel>	maxMidpointImages;
858 			std::vector<tcu::TextureLevel>	resImages;
859 			for (int i = 0; i < (int)colorModels.size(); i++)
860 			{
861 				minImages.push_back			(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
862 				maxImages.push_back			(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
863 				minMidpointImages.push_back	(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
864 				maxMidpointImages.push_back	(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
865 				resImages.push_back			(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
866 			}
867 
868 			for (int i = 0; i < (int)colorModels.size(); i++)
869 			for (int y = 0; y < (int)(dstSize.y()); y++)
870 			for (int x = 0; x < (int)(dstSize.x()); x++)
871 			{
872 				const int ndx = x + y * (int)(dstSize.x());
873 				minImages[i].getAccess().setPixel(minBounds[i][ndx], x, y);
874 				maxImages[i].getAccess().setPixel(maxBounds[i][ndx], x, y);
875 			}
876 
877 			for (int i = 0; i < (int)colorModels.size(); i++)
878 			for (int y = 0; y < (int)(dstSize.y()); y++)
879 			for (int x = 0; x < (int)(dstSize.x()); x++)
880 			{
881 				const int ndx = x + y * (int)(dstSize.x());
882 				resImages[i].getAccess().setPixel(results[i][ndx], x, y);
883 			}
884 
885 			if (implicitNearestCosited)
886 			{
887 				for (int i = 0; i < (int)colorModels.size(); i++)
888 				for (int y = 0; y < (int)(dstSize.y()); y++)
889 				for (int x = 0; x < (int)(dstSize.x()); x++)
890 				{
891 					const int ndx = x + y * (int)(dstSize.x());
892 					minMidpointImages[i].getAccess().setPixel(minMidpointBounds[i][ndx], x, y);
893 					maxMidpointImages[i].getAccess().setPixel(maxMidpointBounds[i][ndx], x, y);
894 				}
895 			}
896 
897 			for (int i = 0; i < (int)colorModels.size(); i++)
898 			{
899 				const Vec4	scale	(1.0f);
900 				const Vec4	bias	(0.0f);
901 
902 				log << TestLog::Image(string("MinBoundImage_") + de::toString(i), string("MinBoundImage_") + de::toString(i), minImages[i].getAccess(), scale, bias);
903 				log << TestLog::Image(string("MaxBoundImage_") + de::toString(i), string("MaxBoundImage_") + de::toString(i), maxImages[i].getAccess(), scale, bias);
904 
905 				if (implicitNearestCosited)
906 				{
907 					log << TestLog::Image(string("MinMidpointBoundImage_") + de::toString(i), string("MinMidpointBoundImage_") + de::toString(i), minMidpointImages[i].getAccess(), scale, bias);
908 					log << TestLog::Image(string("MaxMidpointBoundImage_") + de::toString(i), string("MaxMidpointBoundImage_") + de::toString(i), maxMidpointImages[i].getAccess(), scale, bias);
909 				}
910 
911 				log << TestLog::Image(string("ResultImage_") + de::toString(i), string("ResultImage_") + de::toString(i), resImages[i].getAccess(), scale, bias);
912 			}
913 		}
914 
915 		size_t errorCount = 0;
916 
917 		for (int i = 0; i < (int)colorModels.size(); i++)
918 		for (size_t ndx = 0; ndx < sts.size(); ndx++)
919 		{
920 			bool fail;
921 			if (implicitNearestCosited)
922 			{
923 				fail = (tcu::boolAny(tcu::lessThan(results[i][ndx], minMidpointBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxMidpointBounds[i][ndx]))) &&
924 						(tcu::boolAny(tcu::lessThan(results[i][ndx], minBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxBounds[i][ndx])));
925 			}
926 			else
927 			{
928 				fail = tcu::boolAny(tcu::lessThan(results[i][ndx], minBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxBounds[i][ndx]));
929 			}
930 
931 			if (fail)
932 			{
933 				log << TestLog::Message << "Fail: " << i << " " << sts[ndx] << " " << results[i][ndx] << TestLog::EndMessage;
934 				log << TestLog::Message << "  Min : " << minBounds[i][ndx] << TestLog::EndMessage;
935 				log << TestLog::Message << "  Max : " << maxBounds[i][ndx] << TestLog::EndMessage;
936 				log << TestLog::Message << "  Threshold: " << (maxBounds[i][ndx] - minBounds[i][ndx]) << TestLog::EndMessage;
937 				log << TestLog::Message << "  UMin : " << uvBounds[i][ndx][0] << TestLog::EndMessage;
938 				log << TestLog::Message << "  UMax : " << uvBounds[i][ndx][1] << TestLog::EndMessage;
939 				log << TestLog::Message << "  VMin : " << uvBounds[i][ndx][2] << TestLog::EndMessage;
940 				log << TestLog::Message << "  VMax : " << uvBounds[i][ndx][3] << TestLog::EndMessage;
941 				log << TestLog::Message << "  IMin : " << ijBounds[i][ndx][0] << TestLog::EndMessage;
942 				log << TestLog::Message << "  IMax : " << ijBounds[i][ndx][1] << TestLog::EndMessage;
943 				log << TestLog::Message << "  JMin : " << ijBounds[i][ndx][2] << TestLog::EndMessage;
944 				log << TestLog::Message << "  JMax : " << ijBounds[i][ndx][3] << TestLog::EndMessage;
945 
946 				if (isXChromaSubsampled(config.format))
947 				{
948 					log << TestLog::Message << "  LumaAlphaValues : " << TestLog::EndMessage;
949 					log << TestLog::Message << "    Offset : (" << ijBounds[i][ndx][0] << ", " << ijBounds[i][ndx][2] << ")" << TestLog::EndMessage;
950 
951 					for (deInt32 k = ijBounds[i][ndx][2]; k <= ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); k++)
952 					{
953 						const deInt32		wrappedK	= wrap(config.addressModeV, k, gChannelAccess.getSize().y());
954 						bool				first		= true;
955 						std::ostringstream	line;
956 
957 						for (deInt32 j = ijBounds[i][ndx][0]; j <= ijBounds[i][ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); j++)
958 						{
959 							const deInt32	wrappedJ	= wrap(config.addressModeU, j, gChannelAccess.getSize().x());
960 
961 							if (!first)
962 							{
963 								line << ", ";
964 								first = false;
965 							}
966 
967 							line << "(" << std::setfill(' ') << std::setw(5) << gChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
968 								<< ", " << std::setfill(' ') << std::setw(5) << aChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
969 						}
970 						log << TestLog::Message << "    " << line.str() << TestLog::EndMessage;
971 					}
972 
973 					{
974 						const IVec2 chromaJRange	(divFloor(ijBounds[i][ndx][0], 2) - 1, divFloor(ijBounds[i][ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0), 2) + 1);
975 						const IVec2 chromaKRange	(isYChromaSubsampled(config.format)
976 													? IVec2(divFloor(ijBounds[i][ndx][2], 2) - 1, divFloor(ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0), 2) + 1)
977 													: IVec2(ijBounds[i][ndx][2], ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0)));
978 
979 						log << TestLog::Message << "  ChromaValues : " << TestLog::EndMessage;
980 						log << TestLog::Message << "    Offset : (" << chromaJRange[0] << ", " << chromaKRange[0] << ")" << TestLog::EndMessage;
981 
982 						for (deInt32 k = chromaKRange[0]; k <= chromaKRange[1]; k++)
983 						{
984 							const deInt32		wrappedK	= wrap(config.addressModeV, k, rChannelAccess.getSize().y());
985 							bool				first		= true;
986 							std::ostringstream	line;
987 
988 							for (deInt32 j = chromaJRange[0]; j <= chromaJRange[1]; j++)
989 							{
990 								const deInt32	wrappedJ	= wrap(config.addressModeU, j, rChannelAccess.getSize().x());
991 
992 								if (!first)
993 								{
994 									line << ", ";
995 									first = false;
996 								}
997 
998 								line << "(" << std::setfill(' ') << std::setw(5) << rChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
999 									<< ", " << std::setfill(' ') << std::setw(5) << bChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
1000 							}
1001 							log << TestLog::Message << "    " << line.str() << TestLog::EndMessage;
1002 						}
1003 					}
1004 				}
1005 				else
1006 				{
1007 					log << TestLog::Message << "  Values : " << TestLog::EndMessage;
1008 					log << TestLog::Message << "    Offset : (" << ijBounds[i][ndx][0] << ", " << ijBounds[i][ndx][2] << ")" << TestLog::EndMessage;
1009 
1010 					for (deInt32 k = ijBounds[i][ndx][2]; k <= ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); k++)
1011 					{
1012 						const deInt32		wrappedK	= wrap(config.addressModeV, k, rChannelAccess.getSize().y());
1013 						bool				first		= true;
1014 						std::ostringstream	line;
1015 
1016 						for (deInt32 j = ijBounds[i][ndx][0]; j <= ijBounds[i][ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); j++)
1017 						{
1018 							const deInt32	wrappedJ	= wrap(config.addressModeU, j, rChannelAccess.getSize().x());
1019 
1020 							if (!first)
1021 							{
1022 								line << ", ";
1023 								first = false;
1024 							}
1025 
1026 							line << "(" << std::setfill(' ') << std::setw(5) << rChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
1027 								<< ", " << std::setfill(' ') << std::setw(5) << gChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
1028 								<< ", " << std::setfill(' ') << std::setw(5) << bChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
1029 								<< ", " << std::setfill(' ') << std::setw(5) << aChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
1030 						}
1031 						log << TestLog::Message << "    " << line.str() << TestLog::EndMessage;
1032 					}
1033 				}
1034 
1035 				errorCount++;
1036 				isOk = false;
1037 
1038 				if (errorCount > 30)
1039 				{
1040 					log << TestLog::Message << "Encountered " << errorCount << " errors. Omitting rest of the per result logs." << TestLog::EndMessage;
1041 					break;
1042 				}
1043 			}
1044 		}
1045 	}
1046 
1047 	if (isOk)
1048 		return tcu::TestStatus::pass("Pass");
1049 	else
1050 		return tcu::TestStatus::fail("Result comparison failed");
1051 }
1052 
1053 #if defined(FAKE_COLOR_CONVERSION)
swizzleToCompName(const char * identity,vk::VkComponentSwizzle swizzle)1054 const char* swizzleToCompName (const char* identity, vk::VkComponentSwizzle swizzle)
1055 {
1056 	switch (swizzle)
1057 	{
1058 		case vk::VK_COMPONENT_SWIZZLE_IDENTITY:	return identity;
1059 		case vk::VK_COMPONENT_SWIZZLE_R:		return "r";
1060 		case vk::VK_COMPONENT_SWIZZLE_G:		return "g";
1061 		case vk::VK_COMPONENT_SWIZZLE_B:		return "b";
1062 		case vk::VK_COMPONENT_SWIZZLE_A:		return "a";
1063 		default:
1064 			DE_FATAL("Unsupported swizzle");
1065 			return DE_NULL;
1066 	}
1067 }
1068 #endif
1069 
createTestShaders(vk::SourceCollections & dst,TestConfig config)1070 void createTestShaders (vk::SourceCollections& dst, TestConfig config)
1071 {
1072 	std::vector< vk::VkSamplerYcbcrModelConversion> colorModels;
1073 	if (config.colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST)
1074 	{
1075 		colorModels.push_back(config.colorModel);
1076 	}
1077 	else
1078 	{
1079 		int ycbcrModelConverionCount = std::min((int)vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, 4);
1080 		for (int i = 0; i < ycbcrModelConverionCount; i++)
1081 		{
1082 			colorModels.push_back((vk::VkSamplerYcbcrModelConversion)(vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + i));
1083 		}
1084 	}
1085 #if !defined(FAKE_COLOR_CONVERSION)
1086 	const ShaderSpec spec (createShaderSpec(config.samplerBinding, colorModels));
1087 
1088 	generateSources(config.shaderType, spec, dst);
1089 #else
1090 	const tcu::UVec4	bits	(getYCbCrBitDepth(config.format));
1091 	ShaderSpec			spec;
1092 
1093 	spec.globalDeclarations = "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=" + de::toString(config.samplerBinding) + ") uniform highp sampler2D u_sampler;";
1094 
1095 	spec.inputs.push_back(Symbol("uv", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
1096 	spec.outputs.push_back(Symbol("o_color", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
1097 
1098 	std::ostringstream	source;
1099 
1100 	source << "highp vec4 inputColor = texture(u_sampler, uv);\n";
1101 
1102 	source << "highp float r = inputColor." << swizzleToCompName("r", config.componentMapping.r) << ";\n";
1103 	source << "highp float g = inputColor." << swizzleToCompName("g", config.componentMapping.g) << ";\n";
1104 	source << "highp float b = inputColor." << swizzleToCompName("b", config.componentMapping.b) << ";\n";
1105 	source << "highp float a = inputColor." << swizzleToCompName("a", config.componentMapping.a) << ";\n";
1106 
1107 	switch (config.colorRange)
1108 	{
1109 		case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL:
1110 			source << "highp float cr = r - (float(" << (0x1u << (bits[0] - 0x1u)) << ") / float(" << ((0x1u << bits[0]) - 1u) << "));\n";
1111 			source << "highp float y  = g;\n";
1112 			source << "highp float cb = b - (float(" << (0x1u << (bits[2] - 0x1u)) << ") / float(" << ((0x1u << bits[2]) - 1u) << "));\n";
1113 			break;
1114 
1115 		case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW:
1116 			source << "highp float cr = (r * float(" << ((0x1u << bits[0]) - 1u) << ") - float(" << (128u * (0x1u << (bits[0] - 8))) << ")) / float(" << (224u * (0x1u << (bits[0] - 8))) << ");\n";
1117 			source << "highp float y  = (g * float(" << ((0x1u << bits[1]) - 1u) << ") - float(" << (16u * (0x1u << (bits[1] - 8))) << ")) / float(" << (219u * (0x1u << (bits[1] - 8))) << ");\n";
1118 			source << "highp float cb = (b * float(" << ((0x1u << bits[2]) - 1u) << ") - float(" << (128u * (0x1u << (bits[2] - 8))) << ")) / float(" << (224u * (0x1u << (bits[2] - 8))) << ");\n";
1119 			break;
1120 
1121 		default:
1122 			DE_FATAL("Unknown color range");
1123 	}
1124 
1125 	source << "highp vec4 color;\n";
1126 
1127 	switch (config.colorModel)
1128 	{
1129 		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY:
1130 			source << "color = vec4(r, g, b, a);\n";
1131 			break;
1132 
1133 		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY:
1134 			source << "color = vec4(cr, y, cb, a);\n";
1135 			break;
1136 
1137 		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601:
1138 			source << "color = vec4(y + 1.402 * cr, y - float(" << (0.202008 / 0.587) << ") * cb - float(" << (0.419198 / 0.587) << ") * cr, y + 1.772 * cb, a);\n";
1139 			break;
1140 
1141 		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709:
1142 			source << "color = vec4(y + 1.5748 * cr, y - float(" << (0.13397432 / 0.7152) << ") * cb - float(" << (0.33480248 / 0.7152) << ") * cr, y + 1.8556 * cb, a);\n";
1143 			break;
1144 
1145 		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020:
1146 			source << "color = vec4(y + 1.4746 * cr, (y - float(" << (0.11156702 / 0.6780) << ") * cb) - float(" << (0.38737742 / 0.6780) << ") * cr, y + 1.8814 * cb, a);\n";
1147 			break;
1148 
1149 		default:
1150 			DE_FATAL("Unknown color model");
1151 	};
1152 
1153 	source << "o_color = color;\n";
1154 
1155 	spec.source = source.str();
1156 	generateSources(config.shaderType, spec, dst);
1157 #endif
1158 }
1159 
1160 struct RangeNamePair
1161 {
1162 	const char*					name;
1163 	vk::VkSamplerYcbcrRange		value;
1164 };
1165 
1166 
1167 struct ChromaLocationNamePair
1168 {
1169 	const char*					name;
1170 	vk::VkChromaLocation		value;
1171 };
1172 
1173 // Alternate between swizzle_identity and their equivalents. Both should work.
getIdentitySwizzle(void)1174 const vk::VkComponentMapping& getIdentitySwizzle (void)
1175 {
1176 	static bool alternate = false;
1177 	static const vk::VkComponentMapping mappingA = { vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY };
1178 	static const vk::VkComponentMapping mappingB = { vk::VK_COMPONENT_SWIZZLE_R, vk::VK_COMPONENT_SWIZZLE_G, vk::VK_COMPONENT_SWIZZLE_B, vk::VK_COMPONENT_SWIZZLE_A };
1179 
1180 	const vk::VkComponentMapping& mapping = (alternate ? mappingB : mappingA);
1181 	alternate = (!alternate);
1182 	return mapping;
1183 }
1184 
1185 struct YCbCrConversionTestBuilder
1186 {
1187 	const std::vector<vk::VkFormat> noChromaSubsampledFormats =
1188 	{
1189 		vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1190 		vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1191 		vk::VK_FORMAT_R5G6B5_UNORM_PACK16,
1192 		vk::VK_FORMAT_B5G6R5_UNORM_PACK16,
1193 		vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1194 		vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1195 		vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1196 		vk::VK_FORMAT_R8G8B8_UNORM,
1197 		vk::VK_FORMAT_B8G8R8_UNORM,
1198 		vk::VK_FORMAT_R8G8B8A8_UNORM,
1199 		vk::VK_FORMAT_B8G8R8A8_UNORM,
1200 		vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1201 		vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1202 		vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1203 		vk::VK_FORMAT_R16G16B16_UNORM,
1204 		vk::VK_FORMAT_R16G16B16A16_UNORM,
1205 		vk::VK_FORMAT_R10X6_UNORM_PACK16,
1206 		vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
1207 		vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
1208 		vk::VK_FORMAT_R12X4_UNORM_PACK16,
1209 		vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
1210 		vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
1211 		vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
1212 		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
1213 		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
1214 		vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
1215 		vk::VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT,
1216 		vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT,
1217 		vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT,
1218 		vk::VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT,
1219 	};
1220 	const std::vector<vk::VkFormat> xChromaSubsampledFormats =
1221 	{
1222 		vk::VK_FORMAT_G8B8G8R8_422_UNORM,
1223 		vk::VK_FORMAT_B8G8R8G8_422_UNORM,
1224 		vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
1225 		vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
1226 
1227 		vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
1228 		vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
1229 		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
1230 		vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
1231 		vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
1232 		vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
1233 		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
1234 		vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
1235 		vk::VK_FORMAT_G16B16G16R16_422_UNORM,
1236 		vk::VK_FORMAT_B16G16R16G16_422_UNORM,
1237 		vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
1238 		vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
1239 	};
1240 	const std::vector<vk::VkFormat> xyChromaSubsampledFormats =
1241 	{
1242 		vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
1243 		vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
1244 		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
1245 		vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
1246 		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
1247 		vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
1248 		vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
1249 		vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
1250 	};
1251 	struct ColorModelStruct
1252 	{
1253 		const char* const							name;
1254 		const vk::VkSamplerYcbcrModelConversion	value;
1255 	};
1256 	const std::vector<ColorModelStruct> colorModels =
1257 	{
1258 		{ "rgb_identity",	vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY		},
1259 		{ "ycbcr_identity",	vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY	},
1260 		{ "ycbcr_709",		vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709			},
1261 		{ "ycbcr_601",		vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601			},
1262 		{ "ycbcr_2020",		vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020		}
1263 	};
1264 	const std::vector<RangeNamePair> colorRanges =
1265 	{
1266 		{ "itu_full",		vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL		},
1267 		{ "itu_narrow",		vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW	}
1268 	};
1269 	const std::vector<ChromaLocationNamePair> chromaLocations =
1270 	{
1271 		{ "cosited",		vk::VK_CHROMA_LOCATION_COSITED_EVEN	},
1272 		{ "midpoint",		vk::VK_CHROMA_LOCATION_MIDPOINT		}
1273 	};
1274 	struct TextureFilterStruct
1275 	{
1276 		const char* const	name;
1277 		vk::VkFilter		value;
1278 	};
1279 	const std::vector<TextureFilterStruct> textureFilters =
1280 	{
1281 		{ "linear",			vk::VK_FILTER_LINEAR	},
1282 		{ "nearest",		vk::VK_FILTER_NEAREST	}
1283 	};
1284 	// Used by the chroma reconstruction tests
1285 	const vk::VkSamplerYcbcrModelConversion		defaultColorModel		= vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
1286 	const vk::VkSamplerYcbcrRange				defaultColorRange		= vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
1287 	const vk::VkComponentMapping				swappedChromaSwizzle	=
1288 	{
1289 		vk::VK_COMPONENT_SWIZZLE_B,
1290 		vk::VK_COMPONENT_SWIZZLE_IDENTITY,
1291 		vk::VK_COMPONENT_SWIZZLE_R,
1292 		vk::VK_COMPONENT_SWIZZLE_IDENTITY
1293 	};
1294 	const std::vector<glu::ShaderType> shaderTypes =
1295 	{
1296 		glu::SHADERTYPE_VERTEX,
1297 		glu::SHADERTYPE_FRAGMENT,
1298 		glu::SHADERTYPE_COMPUTE
1299 	};
1300 	struct ImageTilingStruct
1301 	{
1302 		const char*			name;
1303 		vk::VkImageTiling	value;
1304 	};
1305 	const std::vector<ImageTilingStruct> imageTilings =
1306 	{
1307 		{ "tiling_linear",	vk::VK_IMAGE_TILING_LINEAR },
1308 		{ "tiling_optimal",	vk::VK_IMAGE_TILING_OPTIMAL }
1309 	};
1310 	struct SamplerBindingStruct
1311 	{
1312 		const char*			name;
1313 		deUint32			value;
1314 	};
1315 	const std::vector<SamplerBindingStruct> samplerBindings =
1316 	{
1317 		{ "binding_0",		0	},
1318 		{ "binding_7",		7	},
1319 		{ "binding_15",		15	},
1320 		{ "binding_31",		31	}
1321 	};
1322 
buildTestsvkt::ycbcr::__anoned4a6e000111::YCbCrConversionTestBuilder1323 	void buildTests(tcu::TestCaseGroup* testGroup)
1324 	{
1325 		tcu::TestContext&							testCtx(testGroup->getTestContext());
1326 		de::Random									rng(1978765638u);
1327 
1328 		// Test formats without chroma reconstruction
1329 		for (size_t formatNdx = 0; formatNdx < noChromaSubsampledFormats.size(); formatNdx++)
1330 		{
1331 			const vk::VkFormat						format(noChromaSubsampledFormats[formatNdx]);
1332 			const std::string						formatName(de::toLower(std::string(getFormatName(format)).substr(10)));
1333 			de::MovePtr<tcu::TestCaseGroup>			formatGroup(new tcu::TestCaseGroup(testCtx, formatName.c_str(), ("Tests for color conversion using format " + formatName).c_str()));
1334 			const UVec2								srcSize(isXChromaSubsampled(format) ? 12 : 7,
1335 				isYChromaSubsampled(format) ? 8 : 13);
1336 			const UVec2								dstSize(srcSize.x() + srcSize.x() / 2,
1337 				srcSize.y() + srcSize.y() / 2);
1338 
1339 			for (size_t modelNdx = 0; modelNdx < colorModels.size(); modelNdx++)
1340 			{
1341 				const char* const						colorModelName(colorModels[modelNdx].name);
1342 				const vk::VkSamplerYcbcrModelConversion	colorModel(colorModels[modelNdx].value);
1343 
1344 				if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY && getYCbCrFormatChannelCount(format) < 3)
1345 					continue;
1346 
1347 				de::MovePtr<tcu::TestCaseGroup>			colorModelGroup(new tcu::TestCaseGroup(testCtx, colorModelName, ("Tests for color model " + string(colorModelName)).c_str()));
1348 
1349 				if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
1350 				{
1351 					for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1352 					{
1353 						const char* const					textureFilterName(textureFilters[textureFilterNdx].name);
1354 						const vk::VkFilter					textureFilter(textureFilters[textureFilterNdx].value);
1355 
1356 						for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1357 						{
1358 							const vk::VkImageTiling			tiling(imageTilings[tilingNdx].value);
1359 							const char* const				tilingName(imageTilings[tilingNdx].name);
1360 							const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1361 							const vk::VkSamplerYcbcrRange	colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
1362 							const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1363 
1364 							for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1365 							{
1366 								const deUint32					samplerBinding(samplerBindings[bindingNdx].value);
1367 								string							samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1368 								const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1369 									textureFilter, chromaLocation, chromaLocation, false, false,
1370 									colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1371 
1372 								addFunctionCaseWithPrograms(colorModelGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
1373 							}
1374 						}
1375 					}
1376 				}
1377 				else
1378 				{
1379 					for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); rangeNdx++)
1380 					{
1381 						const char* const				colorRangeName(colorRanges[rangeNdx].name);
1382 						const vk::VkSamplerYcbcrRange	colorRange(colorRanges[rangeNdx].value);
1383 
1384 						// Narrow range doesn't really work with formats that have less than 8 bits
1385 						if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW)
1386 						{
1387 							const UVec4					bitDepth(getYCbCrBitDepth(format));
1388 
1389 							if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
1390 								continue;
1391 						}
1392 
1393 						de::MovePtr<tcu::TestCaseGroup>		colorRangeGroup(new tcu::TestCaseGroup(testCtx, colorRangeName, ("Tests for color range " + string(colorRangeName)).c_str()));
1394 
1395 						for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1396 						{
1397 							const char* const				textureFilterName(textureFilters[textureFilterNdx].name);
1398 							const vk::VkFilter				textureFilter(textureFilters[textureFilterNdx].value);
1399 
1400 							for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1401 							{
1402 								const vk::VkImageTiling		tiling(imageTilings[tilingNdx].value);
1403 								const char* const			tilingName(imageTilings[tilingNdx].name);
1404 								const glu::ShaderType		shaderType(rng.choose<glu::ShaderType>(shaderTypes.begin(), shaderTypes.end()));
1405 								const vk::VkChromaLocation	chromaLocation(rng.choose<ChromaLocationNamePair>(chromaLocations.begin(), chromaLocations.end()).value);
1406 								for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)								{
1407 									const deUint32				samplerBinding(samplerBindings[bindingNdx].value);
1408 									string						samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1409 									const TestConfig			config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1410 										textureFilter, chromaLocation, chromaLocation, false, false,
1411 										colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1412 
1413 									addFunctionCaseWithPrograms(colorRangeGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
1414 								}
1415 							}
1416 						}
1417 
1418 						colorModelGroup->addChild(colorRangeGroup.release());
1419 					}
1420 				}
1421 
1422 				formatGroup->addChild(colorModelGroup.release());
1423 			}
1424 
1425 			// Color conversion tests for array of samplers ( noChromaSubsampledFormats )
1426 			if (getYCbCrFormatChannelCount(format) >= 3)
1427 				buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);
1428 
1429 			testGroup->addChild(formatGroup.release());
1430 		}
1431 
1432 		// Test formats with x chroma reconstruction
1433 		for (size_t formatNdx = 0; formatNdx < xChromaSubsampledFormats.size(); formatNdx++)
1434 		{
1435 			const vk::VkFormat				format(xChromaSubsampledFormats[formatNdx]);
1436 			const std::string				formatName(de::toLower(std::string(getFormatName(format)).substr(10)));
1437 			de::MovePtr<tcu::TestCaseGroup>	formatGroup(new tcu::TestCaseGroup(testCtx, formatName.c_str(), ("Tests for color conversion using format " + formatName).c_str()));
1438 			const UVec2						srcSize(isXChromaSubsampled(format) ? 12 : 7,
1439 				isYChromaSubsampled(format) ? 8 : 13);
1440 			const UVec2						dstSize(srcSize.x() + srcSize.x() / 2,
1441 				srcSize.y() + srcSize.y() / 2);
1442 
1443 			// Color conversion tests
1444 			{
1445 				de::MovePtr<tcu::TestCaseGroup>	conversionGroup(new tcu::TestCaseGroup(testCtx, "color_conversion", ""));
1446 
1447 				for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
1448 				{
1449 					const char* const			xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
1450 					const vk::VkChromaLocation	xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
1451 
1452 					for (size_t modelNdx = 0; modelNdx < colorModels.size(); modelNdx++)
1453 					{
1454 						const char* const						colorModelName(colorModels[modelNdx].name);
1455 						const vk::VkSamplerYcbcrModelConversion	colorModel(colorModels[modelNdx].value);
1456 
1457 						if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY && getYCbCrFormatChannelCount(format) < 3)
1458 							continue;
1459 
1460 
1461 						if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
1462 						{
1463 							for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1464 							{
1465 								const vk::VkImageTiling			tiling(imageTilings[tilingNdx].value);
1466 								const char* const				tilingName(imageTilings[tilingNdx].name);
1467 								const vk::VkSamplerYcbcrRange	colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
1468 								const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1469 								const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1470 								for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1471 								{
1472 									const deUint32					samplerBinding(samplerBindings[bindingNdx].value);
1473 									string							samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1474 									const TestConfig				config(shaderType, format, tiling, vk::VK_FILTER_NEAREST, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1475 										vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, false, false,
1476 										colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1477 
1478 									addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + tilingName + "_" + xChromaOffsetName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
1479 								}
1480 							}
1481 						}
1482 						else
1483 						{
1484 							for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); rangeNdx++)
1485 							{
1486 								const char* const				colorRangeName(colorRanges[rangeNdx].name);
1487 								const vk::VkSamplerYcbcrRange	colorRange(colorRanges[rangeNdx].value);
1488 
1489 								// Narrow range doesn't really work with formats that have less than 8 bits
1490 								if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW)
1491 								{
1492 									const UVec4					bitDepth(getYCbCrBitDepth(format));
1493 
1494 									if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
1495 										continue;
1496 								}
1497 
1498 								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1499 								{
1500 									const vk::VkImageTiling		tiling(imageTilings[tilingNdx].value);
1501 									const char* const			tilingName(imageTilings[tilingNdx].name);
1502 									const glu::ShaderType		shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1503 									const vk::VkChromaLocation	yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1504 									for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1505 									{
1506 										const deUint32				samplerBinding(samplerBindings[bindingNdx].value);
1507 										string						samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1508 										const TestConfig			config(shaderType, format, tiling, vk::VK_FILTER_NEAREST, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1509 											vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, false, false,
1510 											colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1511 
1512 										addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + colorRangeName + "_" + tilingName + "_" + xChromaOffsetName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
1513 									}
1514 								}
1515 							}
1516 						}
1517 					}
1518 				}
1519 
1520 				formatGroup->addChild(conversionGroup.release());
1521 			}
1522 
1523 			// Color conversion tests for array of samplers ( xChromaSubsampledFormats )
1524 			if (getYCbCrFormatChannelCount(format) >= 3)
1525 				buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);
1526 
1527 			// Chroma reconstruction tests
1528 			{
1529 				de::MovePtr<tcu::TestCaseGroup>	reconstrucGroup(new tcu::TestCaseGroup(testCtx, "chroma_reconstruction", ""));
1530 
1531 				for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1532 				{
1533 					const char* const				textureFilterName(textureFilters[textureFilterNdx].name);
1534 					const vk::VkFilter				textureFilter(textureFilters[textureFilterNdx].value);
1535 					de::MovePtr<tcu::TestCaseGroup>	textureFilterGroup(new tcu::TestCaseGroup(testCtx, textureFilterName, textureFilterName));
1536 
1537 					for (size_t explicitReconstructionNdx = 0; explicitReconstructionNdx < 2; explicitReconstructionNdx++)
1538 					{
1539 						const bool	explicitReconstruction(explicitReconstructionNdx == 1);
1540 
1541 						for (size_t disjointNdx = 0; disjointNdx < 2; disjointNdx++)
1542 						{
1543 							const bool	disjoint(disjointNdx == 1);
1544 
1545 							for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
1546 							{
1547 								const vk::VkChromaLocation		xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
1548 								const char* const				xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
1549 
1550 								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1551 								{
1552 									const vk::VkImageTiling		tiling(imageTilings[tilingNdx].value);
1553 									const char* const			tilingName(imageTilings[tilingNdx].name);
1554 
1555 									{
1556 										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1557 										const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1558 										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1559 											vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1560 											defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1561 
1562 										addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
1563 									}
1564 
1565 									{
1566 										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1567 										const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1568 										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1569 											vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1570 											defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1571 
1572 										addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
1573 									}
1574 
1575 									if (!explicitReconstruction)
1576 									{
1577 										{
1578 											const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1579 											const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1580 											const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1581 												vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1582 												defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1583 
1584 											addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
1585 										}
1586 
1587 										{
1588 											const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1589 											const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1590 											const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1591 												vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1592 												defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1593 
1594 											addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
1595 										}
1596 									}
1597 								}
1598 							}
1599 
1600 							if (explicitReconstruction)
1601 							{
1602 								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1603 								{
1604 									const vk::VkImageTiling	tiling(imageTilings[tilingNdx].value);
1605 									const char* const		tilingName(imageTilings[tilingNdx].name);
1606 									{
1607 										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1608 										const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1609 										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1610 											vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
1611 											defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1612 
1613 										addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
1614 									}
1615 
1616 									{
1617 										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1618 										const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1619 										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1620 											vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
1621 											defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1622 
1623 										addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
1624 									}
1625 								}
1626 							}
1627 						}
1628 					}
1629 
1630 					reconstrucGroup->addChild(textureFilterGroup.release());
1631 				}
1632 
1633 				formatGroup->addChild(reconstrucGroup.release());
1634 			}
1635 
1636 			testGroup->addChild(formatGroup.release());
1637 		}
1638 
1639 		// Test formats with xy chroma reconstruction
1640 		for (size_t formatNdx = 0; formatNdx < xyChromaSubsampledFormats.size(); formatNdx++)
1641 		{
1642 			const vk::VkFormat				format(xyChromaSubsampledFormats[formatNdx]);
1643 			const std::string				formatName(de::toLower(std::string(getFormatName(format)).substr(10)));
1644 			de::MovePtr<tcu::TestCaseGroup>	formatGroup(new tcu::TestCaseGroup(testCtx, formatName.c_str(), ("Tests for color conversion using format " + formatName).c_str()));
1645 			const UVec2						srcSize(isXChromaSubsampled(format) ? 12 : 7,
1646 				isYChromaSubsampled(format) ? 8 : 13);
1647 			const UVec2						dstSize(srcSize.x() + srcSize.x() / 2,
1648 				srcSize.y() + srcSize.y() / 2);
1649 
1650 			// Color conversion tests
1651 			{
1652 				de::MovePtr<tcu::TestCaseGroup>	conversionGroup(new tcu::TestCaseGroup(testCtx, "color_conversion", ""));
1653 
1654 				for (size_t chromaOffsetNdx = 0; chromaOffsetNdx < chromaLocations.size(); chromaOffsetNdx++)
1655 				{
1656 					const char* const			chromaOffsetName(chromaLocations[chromaOffsetNdx].name);
1657 					const vk::VkChromaLocation	chromaOffset(chromaLocations[chromaOffsetNdx].value);
1658 
1659 					for (size_t modelNdx = 0; modelNdx < colorModels.size(); modelNdx++)
1660 					{
1661 						const char* const							colorModelName(colorModels[modelNdx].name);
1662 						const vk::VkSamplerYcbcrModelConversion		colorModel(colorModels[modelNdx].value);
1663 
1664 						if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY && getYCbCrFormatChannelCount(format) < 3)
1665 							continue;
1666 
1667 						if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
1668 						{
1669 							for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1670 							{
1671 								const vk::VkImageTiling				tiling(imageTilings[tilingNdx].value);
1672 								const char* const					tilingName(imageTilings[tilingNdx].name);
1673 								const vk::VkSamplerYcbcrRange		colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
1674 								const glu::ShaderType				shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1675 								for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1676 								{
1677 									const deUint32						samplerBinding(samplerBindings[bindingNdx].value);
1678 									string								samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1679 									const TestConfig					config(shaderType, format, tiling, vk::VK_FILTER_NEAREST, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1680 										vk::VK_FILTER_NEAREST, chromaOffset, chromaOffset, false, false,
1681 										colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1682 
1683 									addFunctionCaseWithPrograms(conversionGroup.get(), std::string(colorModelName) + "_" + tilingName + "_" + chromaOffsetName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
1684 								}
1685 							}
1686 						}
1687 						else
1688 						{
1689 							for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); rangeNdx++)
1690 							{
1691 								const char* const					colorRangeName(colorRanges[rangeNdx].name);
1692 								const vk::VkSamplerYcbcrRange		colorRange(colorRanges[rangeNdx].value);
1693 
1694 								// Narrow range doesn't really work with formats that have less than 8 bits
1695 								if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW)
1696 								{
1697 									const UVec4	bitDepth(getYCbCrBitDepth(format));
1698 
1699 									if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
1700 										continue;
1701 								}
1702 
1703 								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1704 								{
1705 									const vk::VkImageTiling			tiling(imageTilings[tilingNdx].value);
1706 									const char* const				tilingName(imageTilings[tilingNdx].name);
1707 									const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1708 									for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1709 									{
1710 										const deUint32					samplerBinding(samplerBindings[bindingNdx].value);
1711 										string							samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1712 										const TestConfig				config(shaderType, format, tiling, vk::VK_FILTER_NEAREST, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1713 											vk::VK_FILTER_NEAREST, chromaOffset, chromaOffset, false, false,
1714 											colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1715 
1716 										addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + colorRangeName + "_" + tilingName + "_" + chromaOffsetName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
1717 									}
1718 								}
1719 							}
1720 						}
1721 					}
1722 				}
1723 
1724 				formatGroup->addChild(conversionGroup.release());
1725 			}
1726 
1727 			// Color conversion tests for array of samplers ( xyChromaSubsampledFormats )
1728 			if (getYCbCrFormatChannelCount(format) >= 3)
1729 				buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);
1730 
1731 			// Chroma reconstruction tests
1732 			{
1733 				de::MovePtr<tcu::TestCaseGroup>	reconstrucGroup(new tcu::TestCaseGroup(testCtx, "chroma_reconstruction", ""));
1734 
1735 				for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1736 				{
1737 					const char* const				textureFilterName(textureFilters[textureFilterNdx].name);
1738 					const vk::VkFilter				textureFilter(textureFilters[textureFilterNdx].value);
1739 					de::MovePtr<tcu::TestCaseGroup>	textureFilterGroup(new tcu::TestCaseGroup(testCtx, textureFilterName, textureFilterName));
1740 
1741 					for (size_t explicitReconstructionNdx = 0; explicitReconstructionNdx < 2; explicitReconstructionNdx++)
1742 					{
1743 						const bool	explicitReconstruction(explicitReconstructionNdx == 1);
1744 
1745 						for (size_t disjointNdx = 0; disjointNdx < 2; disjointNdx++)
1746 						{
1747 							const bool	disjoint(disjointNdx == 1);
1748 
1749 							for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
1750 								for (size_t yChromaOffsetNdx = 0; yChromaOffsetNdx < chromaLocations.size(); yChromaOffsetNdx++)
1751 								{
1752 									const vk::VkChromaLocation		xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
1753 									const char* const				xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
1754 
1755 									const vk::VkChromaLocation		yChromaOffset(chromaLocations[yChromaOffsetNdx].value);
1756 									const char* const				yChromaOffsetName(chromaLocations[yChromaOffsetNdx].name);
1757 
1758 									for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1759 									{
1760 										const vk::VkImageTiling	tiling(imageTilings[tilingNdx].value);
1761 										const char* const		tilingName(imageTilings[tilingNdx].name);
1762 										{
1763 											const glu::ShaderType	shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1764 											const TestConfig		config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1765 												vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1766 												defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1767 
1768 											addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
1769 										}
1770 
1771 										{
1772 											const glu::ShaderType	shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1773 											const TestConfig		config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1774 												vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1775 												defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1776 
1777 											addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
1778 										}
1779 
1780 										if (!explicitReconstruction)
1781 										{
1782 											{
1783 												const glu::ShaderType	shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1784 												const TestConfig		config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1785 													vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1786 													defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1787 
1788 												addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
1789 											}
1790 
1791 											{
1792 												const glu::ShaderType	shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1793 												const TestConfig		config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1794 													vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1795 													defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1796 
1797 												addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
1798 											}
1799 										}
1800 									}
1801 								}
1802 
1803 							if (explicitReconstruction)
1804 							{
1805 								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1806 								{
1807 									const vk::VkImageTiling	tiling(imageTilings[tilingNdx].value);
1808 									const char* const		tilingName(imageTilings[tilingNdx].name);
1809 									{
1810 										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1811 										const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1812 										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1813 											vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
1814 											defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1815 
1816 										addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
1817 									}
1818 
1819 									{
1820 										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1821 										const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1822 										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1823 											vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
1824 											defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1825 
1826 										addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
1827 									}
1828 								}
1829 							}
1830 						}
1831 					}
1832 
1833 					reconstrucGroup->addChild(textureFilterGroup.release());
1834 				}
1835 
1836 				formatGroup->addChild(reconstrucGroup.release());
1837 			}
1838 
1839 			testGroup->addChild(formatGroup.release());
1840 		}
1841 
1842 		{
1843 			const UVec2 imageSizes[] =
1844 			{
1845 				UVec2(16, 16),
1846 				UVec2(20, 12)
1847 			};
1848 
1849 			de::MovePtr<tcu::TestCaseGroup>				oneToOneGroup(new tcu::TestCaseGroup(testCtx, "one_to_one", "Ycbcr images sampled to a frame buffer of the same dimentions."));
1850 
1851 			const vk::VkFormat							format(vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM);
1852 			const vk::VkFilter							filter(vk::VK_FILTER_NEAREST);
1853 
1854 			for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(imageSizes); sizeNdx++)
1855 			{
1856 				const UVec2								srcSize(imageSizes[sizeNdx]);
1857 
1858 				for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
1859 				{
1860 					const vk::VkChromaLocation			xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
1861 					const char* const					xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
1862 
1863 					for (size_t yChromaOffsetNdx = 0; yChromaOffsetNdx < chromaLocations.size(); yChromaOffsetNdx++)
1864 					{
1865 						const vk::VkChromaLocation		yChromaOffset(chromaLocations[yChromaOffsetNdx].value);
1866 						const char* const				yChromaOffsetName(chromaLocations[yChromaOffsetNdx].name);
1867 
1868 						for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1869 						{
1870 							const vk::VkImageTiling		tiling(imageTilings[tilingNdx].value);
1871 							const char* const			tilingName(imageTilings[tilingNdx].name);
1872 
1873 							const glu::ShaderType		shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1874 
1875 							const TestConfig			config(shaderType, format, tiling, filter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1876 								filter, xChromaOffset, yChromaOffset, false, false,
1877 								defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, srcSize, 0);
1878 							std::ostringstream			testName;
1879 							testName << string("implicit_nearest_") << srcSize.x() << "x" << srcSize.y() << "_" << tilingName << "_" << xChromaOffsetName << "_" << yChromaOffsetName;
1880 
1881 							addFunctionCaseWithPrograms(oneToOneGroup.get(), testName.str(), "", checkSupport, createTestShaders, textureConversionTest, config);
1882 						}
1883 					}
1884 				}
1885 			}
1886 
1887 			testGroup->addChild(oneToOneGroup.release());
1888 		}
1889 	}
1890 
buildArrayOfSamplersTestsvkt::ycbcr::__anoned4a6e000111::YCbCrConversionTestBuilder1891 	void buildArrayOfSamplersTests(const vk::VkFormat& format, const UVec2& srcSize, const UVec2& dstSize, de::MovePtr<tcu::TestCaseGroup>& formatGroup, tcu::TestContext& testCtx, de::Random& rng )
1892 	{
1893 		de::MovePtr<tcu::TestCaseGroup>			samplerArrayGroup(new tcu::TestCaseGroup(testCtx, "sampler_array", "Tests for array of samplers"));
1894 
1895 		for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1896 		{
1897 			const char* const					textureFilterName(textureFilters[textureFilterNdx].name);
1898 			const vk::VkFilter					textureFilter(textureFilters[textureFilterNdx].value);
1899 
1900 			for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1901 			{
1902 				const vk::VkImageTiling			tiling(imageTilings[tilingNdx].value);
1903 				const char* const				tilingName(imageTilings[tilingNdx].name);
1904 				const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(shaderTypes.begin(), shaderTypes.end()));
1905 				const vk::VkSamplerYcbcrRange	colorRange(vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL);
1906 				const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(chromaLocations.begin(), chromaLocations.end()).value);
1907 
1908 				for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1909 				{
1910 					const deUint32					samplerBinding(samplerBindings[bindingNdx].value);
1911 					string							samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1912 					// colorModel==VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST means that we want to create an array of samplers instead of a single sampler
1913 					const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1914 						textureFilter, chromaLocation, chromaLocation, false, false,
1915 						colorRange, vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1916 
1917 					addFunctionCaseWithPrograms(samplerArrayGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
1918 				}
1919 			}
1920 		}
1921 		formatGroup->addChild(samplerArrayGroup.release());
1922 	}
1923 };
1924 
initTests(tcu::TestCaseGroup * testGroup)1925 void initTests(tcu::TestCaseGroup* testGroup)
1926 {
1927 	YCbCrConversionTestBuilder testBuilder;
1928 	testBuilder.buildTests(testGroup);
1929 }
1930 
1931 } // anonymous
1932 
createConversionTests(tcu::TestContext & testCtx)1933 tcu::TestCaseGroup* createConversionTests (tcu::TestContext& testCtx)
1934 {
1935 	return createTestGroup(testCtx, "conversion", "Sampler YCbCr Conversion Tests", initTests);
1936 }
1937 
1938 } // ycbcr
1939 } // vkt
1940