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::__anon891997430111::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
611 const auto& instInt (context.getInstanceInterface());
612
613 {
614 const vk::VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
615 {
616 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType;
617 DE_NULL, // pNext;
618 config.format, // format;
619 vk::VK_IMAGE_TYPE_2D, // type;
620 vk::VK_IMAGE_TILING_OPTIMAL, // tiling;
621 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT |
622 vk::VK_IMAGE_USAGE_SAMPLED_BIT, // usage;
623 (vk::VkImageCreateFlags)0u // flags
624 };
625
626 vk::VkSamplerYcbcrConversionImageFormatProperties samplerYcbcrConversionImage = {};
627 samplerYcbcrConversionImage.sType = vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES;
628 samplerYcbcrConversionImage.pNext = DE_NULL;
629
630 vk::VkImageFormatProperties2 imageFormatProperties = {};
631 imageFormatProperties.sType = vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
632 imageFormatProperties.pNext = &samplerYcbcrConversionImage;
633
634 vk::VkResult result = instInt.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &imageFormatInfo, &imageFormatProperties);
635 if (result == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
636 TCU_THROW(NotSupportedError, "Format not supported.");
637 VK_CHECK(result);
638
639 // Check for plane compatible format support when the disjoint flag is being used
640 if (config.disjoint)
641 {
642 const vk::PlanarFormatDescription formatDescription = vk::getPlanarFormatDescription(config.format);
643
644 for (deUint32 channelNdx = 0; channelNdx < 4; ++channelNdx)
645 {
646 if (!formatDescription.hasChannelNdx(channelNdx))
647 continue;
648 deUint32 planeNdx = formatDescription.channels[channelNdx].planeNdx;
649 vk::VkFormat planeCompatibleFormat = getPlaneCompatibleFormat(formatDescription, planeNdx);
650
651 const vk::VkPhysicalDeviceImageFormatInfo2 planeImageFormatInfo =
652 {
653 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType;
654 DE_NULL, // pNext;
655 planeCompatibleFormat, // format;
656 vk::VK_IMAGE_TYPE_2D, // type;
657 vk::VK_IMAGE_TILING_OPTIMAL, // tiling;
658 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT |
659 vk::VK_IMAGE_USAGE_SAMPLED_BIT, // usage;
660 (vk::VkImageCreateFlags)0u // flags
661 };
662
663 vk::VkResult planesResult = instInt.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &planeImageFormatInfo, &imageFormatProperties);
664 if (planesResult == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
665 TCU_THROW(NotSupportedError, "Plane compatibile format not supported.");
666 VK_CHECK(planesResult);
667 }
668 }
669 }
670
671 if (!context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion"))
672 TCU_THROW(NotSupportedError, "Extension VK_KHR_sampler_ycbcr_conversion not supported");
673
674 {
675 const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures features = context.getSamplerYcbcrConversionFeatures();
676 if (features.samplerYcbcrConversion == VK_FALSE)
677 TCU_THROW(NotSupportedError, "samplerYcbcrConversion feature is not supported");
678 }
679
680 {
681 const vk::VkFormatProperties properties (vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), config.format));
682 const vk::VkFormatFeatureFlags features (config.imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
683 ? properties.optimalTilingFeatures
684 : properties.linearTilingFeatures);
685
686 if ((features & (vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0)
687 TCU_THROW(NotSupportedError, "Format doesn't support YCbCr conversions");
688
689 if ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0)
690 TCU_THROW(NotSupportedError, "Format doesn't support sampling");
691
692 if (config.textureFilter == vk::VK_FILTER_LINEAR && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) == 0))
693 TCU_THROW(NotSupportedError, "Format doesn't support linear texture filtering");
694
695 if (config.chromaFilter == vk::VK_FILTER_LINEAR && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) == 0))
696 TCU_THROW(NotSupportedError, "Format doesn't support YCbCr linear chroma reconstruction");
697
698 if (config.chromaFilter != config.textureFilter && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT) == 0))
699 TCU_THROW(NotSupportedError, "Format doesn't support different chroma and texture filters");
700
701 if (config.explicitReconstruction && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT) == 0))
702 TCU_THROW(NotSupportedError, "Format doesn't support explicit chroma reconstruction");
703
704 if (config.disjoint && ((features & vk::VK_FORMAT_FEATURE_DISJOINT_BIT) == 0))
705 TCU_THROW(NotSupportedError, "Format doesn't disjoint planes");
706
707 if (isXChromaSubsampled(config.format) && (config.xChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN) && ((features & vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT) == 0))
708 TCU_THROW(NotSupportedError, "Format doesn't support cosited chroma samples");
709
710 if (isXChromaSubsampled(config.format) && (config.xChromaOffset == vk::VK_CHROMA_LOCATION_MIDPOINT) && ((features & vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT) == 0))
711 TCU_THROW(NotSupportedError, "Format doesn't support midpoint chroma samples");
712
713 if (isYChromaSubsampled(config.format) && (config.yChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN) && ((features & vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT) == 0))
714 TCU_THROW(NotSupportedError, "Format doesn't support cosited chroma samples");
715
716 if (isYChromaSubsampled(config.format) && (config.yChromaOffset == vk::VK_CHROMA_LOCATION_MIDPOINT) && ((features & vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT) == 0))
717 TCU_THROW(NotSupportedError, "Format doesn't support midpoint chroma samples");
718 }
719 #endif
720 }
721
textureConversionTest(Context & context,const TestConfig config)722 tcu::TestStatus textureConversionTest (Context& context, const TestConfig config)
723 {
724 const std::vector<FloatFormat> filteringPrecision (getPrecision(config.format));
725 const std::vector<FloatFormat> conversionPrecision (getPrecision(config.format));
726 const deUint32 subTexelPrecisionBits (vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits.subTexelPrecisionBits);
727 const tcu::UVec4 bitDepth (getYCbCrBitDepth(config.format));
728 TestLog& log (context.getTestContext().getLog());
729 bool explicitReconstruction = config.explicitReconstruction;
730 const UVec2 srcSize = config.srcSize;
731 const UVec2 dstSize = config.dstSize;
732 bool isOk = true;
733 const auto& instInt (context.getInstanceInterface());
734
735 logTestCaseInfo(log, config);
736
737 #if !defined(FAKE_COLOR_CONVERSION)
738 {
739 const vk::VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
740 {
741 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType;
742 DE_NULL, // pNext;
743 config.format, // format;
744 vk::VK_IMAGE_TYPE_2D, // type;
745 vk::VK_IMAGE_TILING_OPTIMAL, // tiling;
746 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT |
747 vk::VK_IMAGE_USAGE_SAMPLED_BIT, // usage;
748 (vk::VkImageCreateFlags)0u // flags
749 };
750
751 vk::VkSamplerYcbcrConversionImageFormatProperties samplerYcbcrConversionImage = {};
752 samplerYcbcrConversionImage.sType = vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES;
753 samplerYcbcrConversionImage.pNext = DE_NULL;
754
755 vk::VkImageFormatProperties2 imageFormatProperties = {};
756 imageFormatProperties.sType = vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
757 imageFormatProperties.pNext = &samplerYcbcrConversionImage;
758
759 vk::VkResult result = instInt.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &imageFormatInfo, &imageFormatProperties);
760 if (result == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
761 TCU_THROW(NotSupportedError, "Format not supported.");
762 VK_CHECK(result);
763 }
764
765 {
766 const vk::VkFormatProperties properties (vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), config.format));
767 const vk::VkFormatFeatureFlags features (config.imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
768 ? properties.optimalTilingFeatures
769 : properties.linearTilingFeatures);
770
771 if ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT) != 0)
772 explicitReconstruction = true;
773
774 log << TestLog::Message << "FormatFeatures: " << vk::getFormatFeatureFlagsStr(features) << TestLog::EndMessage;
775 }
776 #endif
777
778 {
779 const vk::PlanarFormatDescription planeInfo (vk::getPlanarFormatDescription(config.format));
780 MultiPlaneImageData src (config.format, srcSize);
781
782 deUint32 nullAccessData (0u);
783 ChannelAccess nullAccess (tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, 1u, IVec3(srcSize.x(), srcSize.y(), 1), IVec3(0, 0, 0), &nullAccessData, 0u);
784 deUint32 nullAccessAlphaData (~0u);
785 ChannelAccess nullAccessAlpha (tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, 1u, IVec3(srcSize.x(), srcSize.y(), 1), IVec3(0, 0, 0), &nullAccessAlphaData, 0u);
786 ChannelAccess rChannelAccess (planeInfo.hasChannelNdx(0) ? getChannelAccess(src, planeInfo, srcSize, 0) : nullAccess);
787 ChannelAccess gChannelAccess (planeInfo.hasChannelNdx(1) ? getChannelAccess(src, planeInfo, srcSize, 1) : nullAccess);
788 ChannelAccess bChannelAccess (planeInfo.hasChannelNdx(2) ? getChannelAccess(src, planeInfo, srcSize, 2) : nullAccess);
789 ChannelAccess aChannelAccess (planeInfo.hasChannelNdx(3) ? getChannelAccess(src, planeInfo, srcSize, 3) : nullAccessAlpha);
790 const bool implicitNearestCosited ((config.chromaFilter == vk::VK_FILTER_NEAREST && !config.explicitReconstruction) &&
791 (config.xChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN || config.yChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN));
792
793 vector<Vec2> sts;
794 vector<vector<Vec4> > results;
795 vector<vector<Vec4> > minBounds;
796 vector<vector<Vec4> > minMidpointBounds;
797 vector<vector<Vec4> > maxBounds;
798 vector<vector<Vec4> > maxMidpointBounds;
799 vector<vector<Vec4> > uvBounds;
800 vector<vector<IVec4> > ijBounds;
801
802 for (deUint32 planeNdx = 0; planeNdx < planeInfo.numPlanes; planeNdx++)
803 deMemset(src.getPlanePtr(planeNdx), 0u, src.getPlaneSize(planeNdx));
804
805 // \todo Limit values to only values that produce defined values using selected colorRange and colorModel? The verification code handles those cases already correctly.
806 if (planeInfo.hasChannelNdx(0))
807 {
808 for (int y = 0; y < rChannelAccess.getSize().y(); y++)
809 for (int x = 0; x < rChannelAccess.getSize().x(); x++)
810 rChannelAccess.setChannel(IVec3(x, y, 0), (float)x / (float)rChannelAccess.getSize().x());
811 }
812
813 if (planeInfo.hasChannelNdx(1))
814 {
815 for (int y = 0; y < gChannelAccess.getSize().y(); y++)
816 for (int x = 0; x < gChannelAccess.getSize().x(); x++)
817 gChannelAccess.setChannel(IVec3(x, y, 0), (float)y / (float)gChannelAccess.getSize().y());
818 }
819
820 if (planeInfo.hasChannelNdx(2))
821 {
822 for (int y = 0; y < bChannelAccess.getSize().y(); y++)
823 for (int x = 0; x < bChannelAccess.getSize().x(); x++)
824 bChannelAccess.setChannel(IVec3(x, y, 0), (float)(x + y) / (float)(bChannelAccess.getSize().x() + bChannelAccess.getSize().y()));
825 }
826
827 if (planeInfo.hasChannelNdx(3))
828 {
829 for (int y = 0; y < aChannelAccess.getSize().y(); y++)
830 for (int x = 0; x < aChannelAccess.getSize().x(); x++)
831 aChannelAccess.setChannel(IVec3(x, y, 0), (float)(x * y) / (float)(aChannelAccess.getSize().x() * aChannelAccess.getSize().y()));
832 }
833
834 if (dstSize.x() > srcSize.x() && dstSize.y() > srcSize.y())
835 genTexCoords(sts, srcSize, dstSize);
836 else
837 genOneToOneTexCoords(sts, dstSize);
838
839 std::vector< vk::VkSamplerYcbcrModelConversion> colorModels;
840 if (config.colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST)
841 {
842 colorModels.push_back(config.colorModel);
843 }
844 else
845 {
846 int ycbcrModelConverionCount = std::min( (int)vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, 4 );
847 for (int i = 0; i < ycbcrModelConverionCount; i++)
848 {
849 colorModels.push_back((vk::VkSamplerYcbcrModelConversion)(vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + i));
850 }
851 }
852
853 for (int i = 0; i < (int)colorModels.size(); i++)
854 {
855 vector<Vec4> minBound;
856 vector<Vec4> minMidpointBound;
857 vector<Vec4> maxBound;
858 vector<Vec4> maxMidpointBound;
859 vector<Vec4> uvBound;
860 vector<IVec4> ijBound;
861
862 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);
863
864 if (implicitNearestCosited)
865 {
866 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);
867 }
868 results.push_back (vector<Vec4>());
869 minBounds.push_back (minBound);
870 minMidpointBounds.push_back (minMidpointBound);
871 maxBounds.push_back (maxBound);
872 maxMidpointBounds.push_back (maxMidpointBound);
873 uvBounds.push_back (uvBound);
874 ijBounds.push_back (ijBound);
875 }
876
877 if (vk::isYCbCrFormat(config.format))
878 {
879 tcu::TextureLevel rImage (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), rChannelAccess.getSize().x(), rChannelAccess.getSize().y());
880 tcu::TextureLevel gImage (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), gChannelAccess.getSize().x(), gChannelAccess.getSize().y());
881 tcu::TextureLevel bImage (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), bChannelAccess.getSize().x(), bChannelAccess.getSize().y());
882 tcu::TextureLevel aImage (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), aChannelAccess.getSize().x(), aChannelAccess.getSize().y());
883
884 for (int y = 0; y < (int)rChannelAccess.getSize().y(); y++)
885 for (int x = 0; x < (int)rChannelAccess.getSize().x(); x++)
886 rImage.getAccess().setPixel(Vec4(rChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
887
888 for (int y = 0; y < (int)gChannelAccess.getSize().y(); y++)
889 for (int x = 0; x < (int)gChannelAccess.getSize().x(); x++)
890 gImage.getAccess().setPixel(Vec4(gChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
891
892 for (int y = 0; y < (int)bChannelAccess.getSize().y(); y++)
893 for (int x = 0; x < (int)bChannelAccess.getSize().x(); x++)
894 bImage.getAccess().setPixel(Vec4(bChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
895
896 for (int y = 0; y < (int)aChannelAccess.getSize().y(); y++)
897 for (int x = 0; x < (int)aChannelAccess.getSize().x(); x++)
898 aImage.getAccess().setPixel(Vec4(aChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
899
900 {
901 const Vec4 scale (1.0f);
902 const Vec4 bias (0.0f);
903
904 log << TestLog::Image("SourceImageR", "SourceImageR", rImage.getAccess(), scale, bias);
905 log << TestLog::Image("SourceImageG", "SourceImageG", gImage.getAccess(), scale, bias);
906 log << TestLog::Image("SourceImageB", "SourceImageB", bImage.getAccess(), scale, bias);
907 log << TestLog::Image("SourceImageA", "SourceImageA", aImage.getAccess(), scale, bias);
908 }
909 }
910 else
911 {
912 tcu::TextureLevel srcImage (vk::mapVkFormat(config.format), srcSize.x(), srcSize.y());
913
914 for (int y = 0; y < (int)srcSize.y(); y++)
915 for (int x = 0; x < (int)srcSize.x(); x++)
916 {
917 const IVec3 pos (x, y, 0);
918 srcImage.getAccess().setPixel(Vec4(rChannelAccess.getChannel(pos), gChannelAccess.getChannel(pos), bChannelAccess.getChannel(pos), aChannelAccess.getChannel(pos)), x, y);
919 }
920
921 log << TestLog::Image("SourceImage", "SourceImage", srcImage.getAccess());
922 }
923
924 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);
925
926 {
927 std::vector<tcu::TextureLevel> minImages;
928 std::vector<tcu::TextureLevel> maxImages;
929 std::vector<tcu::TextureLevel> minMidpointImages;
930 std::vector<tcu::TextureLevel> maxMidpointImages;
931 std::vector<tcu::TextureLevel> resImages;
932 for (int i = 0; i < (int)colorModels.size(); i++)
933 {
934 minImages.push_back (tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
935 maxImages.push_back (tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
936 minMidpointImages.push_back (tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
937 maxMidpointImages.push_back (tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
938 resImages.push_back (tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
939 }
940
941 for (int i = 0; i < (int)colorModels.size(); i++)
942 for (int y = 0; y < (int)(dstSize.y()); y++)
943 for (int x = 0; x < (int)(dstSize.x()); x++)
944 {
945 const int ndx = x + y * (int)(dstSize.x());
946 minImages[i].getAccess().setPixel(minBounds[i][ndx], x, y);
947 maxImages[i].getAccess().setPixel(maxBounds[i][ndx], x, y);
948 }
949
950 for (int i = 0; i < (int)colorModels.size(); i++)
951 for (int y = 0; y < (int)(dstSize.y()); y++)
952 for (int x = 0; x < (int)(dstSize.x()); x++)
953 {
954 const int ndx = x + y * (int)(dstSize.x());
955 resImages[i].getAccess().setPixel(results[i][ndx], x, y);
956 }
957
958 if (implicitNearestCosited)
959 {
960 for (int i = 0; i < (int)colorModels.size(); i++)
961 for (int y = 0; y < (int)(dstSize.y()); y++)
962 for (int x = 0; x < (int)(dstSize.x()); x++)
963 {
964 const int ndx = x + y * (int)(dstSize.x());
965 minMidpointImages[i].getAccess().setPixel(minMidpointBounds[i][ndx], x, y);
966 maxMidpointImages[i].getAccess().setPixel(maxMidpointBounds[i][ndx], x, y);
967 }
968 }
969
970 for (int i = 0; i < (int)colorModels.size(); i++)
971 {
972 const Vec4 scale (1.0f);
973 const Vec4 bias (0.0f);
974
975 log << TestLog::Image(string("MinBoundImage_") + de::toString(i), string("MinBoundImage_") + de::toString(i), minImages[i].getAccess(), scale, bias);
976 log << TestLog::Image(string("MaxBoundImage_") + de::toString(i), string("MaxBoundImage_") + de::toString(i), maxImages[i].getAccess(), scale, bias);
977
978 if (implicitNearestCosited)
979 {
980 log << TestLog::Image(string("MinMidpointBoundImage_") + de::toString(i), string("MinMidpointBoundImage_") + de::toString(i), minMidpointImages[i].getAccess(), scale, bias);
981 log << TestLog::Image(string("MaxMidpointBoundImage_") + de::toString(i), string("MaxMidpointBoundImage_") + de::toString(i), maxMidpointImages[i].getAccess(), scale, bias);
982 }
983
984 log << TestLog::Image(string("ResultImage_") + de::toString(i), string("ResultImage_") + de::toString(i), resImages[i].getAccess(), scale, bias);
985 }
986 }
987
988 size_t errorCount = 0;
989
990 for (int i = 0; i < (int)colorModels.size(); i++)
991 for (size_t ndx = 0; ndx < sts.size(); ndx++)
992 {
993 bool fail;
994 if (implicitNearestCosited)
995 {
996 fail = (tcu::boolAny(tcu::lessThan(results[i][ndx], minMidpointBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxMidpointBounds[i][ndx]))) &&
997 (tcu::boolAny(tcu::lessThan(results[i][ndx], minBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxBounds[i][ndx])));
998 }
999 else
1000 {
1001 fail = tcu::boolAny(tcu::lessThan(results[i][ndx], minBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxBounds[i][ndx]));
1002 }
1003
1004 if (fail)
1005 {
1006 log << TestLog::Message << "Fail: " << i << " " << sts[ndx] << " " << results[i][ndx] << TestLog::EndMessage;
1007 log << TestLog::Message << " Min : " << minBounds[i][ndx] << TestLog::EndMessage;
1008 log << TestLog::Message << " Max : " << maxBounds[i][ndx] << TestLog::EndMessage;
1009 log << TestLog::Message << " Threshold: " << (maxBounds[i][ndx] - minBounds[i][ndx]) << TestLog::EndMessage;
1010 log << TestLog::Message << " UMin : " << uvBounds[i][ndx][0] << TestLog::EndMessage;
1011 log << TestLog::Message << " UMax : " << uvBounds[i][ndx][1] << TestLog::EndMessage;
1012 log << TestLog::Message << " VMin : " << uvBounds[i][ndx][2] << TestLog::EndMessage;
1013 log << TestLog::Message << " VMax : " << uvBounds[i][ndx][3] << TestLog::EndMessage;
1014 log << TestLog::Message << " IMin : " << ijBounds[i][ndx][0] << TestLog::EndMessage;
1015 log << TestLog::Message << " IMax : " << ijBounds[i][ndx][1] << TestLog::EndMessage;
1016 log << TestLog::Message << " JMin : " << ijBounds[i][ndx][2] << TestLog::EndMessage;
1017 log << TestLog::Message << " JMax : " << ijBounds[i][ndx][3] << TestLog::EndMessage;
1018
1019 if (isXChromaSubsampled(config.format))
1020 {
1021 log << TestLog::Message << " LumaAlphaValues : " << TestLog::EndMessage;
1022 log << TestLog::Message << " Offset : (" << ijBounds[i][ndx][0] << ", " << ijBounds[i][ndx][2] << ")" << TestLog::EndMessage;
1023
1024 for (deInt32 k = ijBounds[i][ndx][2]; k <= ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); k++)
1025 {
1026 const deInt32 wrappedK = wrap(config.addressModeV, k, gChannelAccess.getSize().y());
1027 bool first = true;
1028 std::ostringstream line;
1029
1030 for (deInt32 j = ijBounds[i][ndx][0]; j <= ijBounds[i][ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); j++)
1031 {
1032 const deInt32 wrappedJ = wrap(config.addressModeU, j, gChannelAccess.getSize().x());
1033
1034 if (!first)
1035 {
1036 line << ", ";
1037 first = false;
1038 }
1039
1040 line << "(" << std::setfill(' ') << std::setw(5) << gChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
1041 << ", " << std::setfill(' ') << std::setw(5) << aChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
1042 }
1043 log << TestLog::Message << " " << line.str() << TestLog::EndMessage;
1044 }
1045
1046 {
1047 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);
1048 const IVec2 chromaKRange (isYChromaSubsampled(config.format)
1049 ? IVec2(divFloor(ijBounds[i][ndx][2], 2) - 1, divFloor(ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0), 2) + 1)
1050 : IVec2(ijBounds[i][ndx][2], ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0)));
1051
1052 log << TestLog::Message << " ChromaValues : " << TestLog::EndMessage;
1053 log << TestLog::Message << " Offset : (" << chromaJRange[0] << ", " << chromaKRange[0] << ")" << TestLog::EndMessage;
1054
1055 for (deInt32 k = chromaKRange[0]; k <= chromaKRange[1]; k++)
1056 {
1057 const deInt32 wrappedK = wrap(config.addressModeV, k, rChannelAccess.getSize().y());
1058 bool first = true;
1059 std::ostringstream line;
1060
1061 for (deInt32 j = chromaJRange[0]; j <= chromaJRange[1]; j++)
1062 {
1063 const deInt32 wrappedJ = wrap(config.addressModeU, j, rChannelAccess.getSize().x());
1064
1065 if (!first)
1066 {
1067 line << ", ";
1068 first = false;
1069 }
1070
1071 line << "(" << std::setfill(' ') << std::setw(5) << rChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
1072 << ", " << std::setfill(' ') << std::setw(5) << bChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
1073 }
1074 log << TestLog::Message << " " << line.str() << TestLog::EndMessage;
1075 }
1076 }
1077 }
1078 else
1079 {
1080 log << TestLog::Message << " Values : " << TestLog::EndMessage;
1081 log << TestLog::Message << " Offset : (" << ijBounds[i][ndx][0] << ", " << ijBounds[i][ndx][2] << ")" << TestLog::EndMessage;
1082
1083 for (deInt32 k = ijBounds[i][ndx][2]; k <= ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); k++)
1084 {
1085 const deInt32 wrappedK = wrap(config.addressModeV, k, rChannelAccess.getSize().y());
1086 bool first = true;
1087 std::ostringstream line;
1088
1089 for (deInt32 j = ijBounds[i][ndx][0]; j <= ijBounds[i][ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); j++)
1090 {
1091 const deInt32 wrappedJ = wrap(config.addressModeU, j, rChannelAccess.getSize().x());
1092
1093 if (!first)
1094 {
1095 line << ", ";
1096 first = false;
1097 }
1098
1099 line << "(" << std::setfill(' ') << std::setw(5) << rChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
1100 << ", " << std::setfill(' ') << std::setw(5) << gChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
1101 << ", " << std::setfill(' ') << std::setw(5) << bChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
1102 << ", " << std::setfill(' ') << std::setw(5) << aChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
1103 }
1104 log << TestLog::Message << " " << line.str() << TestLog::EndMessage;
1105 }
1106 }
1107
1108 errorCount++;
1109 isOk = false;
1110
1111 if (errorCount > 30)
1112 {
1113 log << TestLog::Message << "Encountered " << errorCount << " errors. Omitting rest of the per result logs." << TestLog::EndMessage;
1114 break;
1115 }
1116 }
1117 }
1118 }
1119
1120 if (isOk)
1121 return tcu::TestStatus::pass("Pass");
1122 else
1123 return tcu::TestStatus::fail("Result comparison failed");
1124 }
1125
1126 #if defined(FAKE_COLOR_CONVERSION)
swizzleToCompName(const char * identity,vk::VkComponentSwizzle swizzle)1127 const char* swizzleToCompName (const char* identity, vk::VkComponentSwizzle swizzle)
1128 {
1129 switch (swizzle)
1130 {
1131 case vk::VK_COMPONENT_SWIZZLE_IDENTITY: return identity;
1132 case vk::VK_COMPONENT_SWIZZLE_R: return "r";
1133 case vk::VK_COMPONENT_SWIZZLE_G: return "g";
1134 case vk::VK_COMPONENT_SWIZZLE_B: return "b";
1135 case vk::VK_COMPONENT_SWIZZLE_A: return "a";
1136 default:
1137 DE_FATAL("Unsupported swizzle");
1138 return DE_NULL;
1139 }
1140 }
1141 #endif
1142
createTestShaders(vk::SourceCollections & dst,TestConfig config)1143 void createTestShaders (vk::SourceCollections& dst, TestConfig config)
1144 {
1145 std::vector< vk::VkSamplerYcbcrModelConversion> colorModels;
1146 if (config.colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST)
1147 {
1148 colorModels.push_back(config.colorModel);
1149 }
1150 else
1151 {
1152 int ycbcrModelConverionCount = std::min((int)vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, 4);
1153 for (int i = 0; i < ycbcrModelConverionCount; i++)
1154 {
1155 colorModels.push_back((vk::VkSamplerYcbcrModelConversion)(vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + i));
1156 }
1157 }
1158 #if !defined(FAKE_COLOR_CONVERSION)
1159 const ShaderSpec spec (createShaderSpec(config.samplerBinding, colorModels));
1160
1161 generateSources(config.shaderType, spec, dst);
1162 #else
1163 const tcu::UVec4 bits (getYCbCrBitDepth(config.format));
1164 ShaderSpec spec;
1165
1166 spec.globalDeclarations = "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=" + de::toString(config.samplerBinding) + ") uniform highp sampler2D u_sampler;";
1167
1168 spec.inputs.push_back(Symbol("uv", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
1169 spec.outputs.push_back(Symbol("o_color", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
1170
1171 std::ostringstream source;
1172
1173 source << "highp vec4 inputColor = texture(u_sampler, uv);\n";
1174
1175 source << "highp float r = inputColor." << swizzleToCompName("r", config.componentMapping.r) << ";\n";
1176 source << "highp float g = inputColor." << swizzleToCompName("g", config.componentMapping.g) << ";\n";
1177 source << "highp float b = inputColor." << swizzleToCompName("b", config.componentMapping.b) << ";\n";
1178 source << "highp float a = inputColor." << swizzleToCompName("a", config.componentMapping.a) << ";\n";
1179
1180 switch (config.colorRange)
1181 {
1182 case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL:
1183 source << "highp float cr = r - (float(" << (0x1u << (bits[0] - 0x1u)) << ") / float(" << ((0x1u << bits[0]) - 1u) << "));\n";
1184 source << "highp float y = g;\n";
1185 source << "highp float cb = b - (float(" << (0x1u << (bits[2] - 0x1u)) << ") / float(" << ((0x1u << bits[2]) - 1u) << "));\n";
1186 break;
1187
1188 case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW:
1189 source << "highp float cr = (r * float(" << ((0x1u << bits[0]) - 1u) << ") - float(" << (128u * (0x1u << (bits[0] - 8))) << ")) / float(" << (224u * (0x1u << (bits[0] - 8))) << ");\n";
1190 source << "highp float y = (g * float(" << ((0x1u << bits[1]) - 1u) << ") - float(" << (16u * (0x1u << (bits[1] - 8))) << ")) / float(" << (219u * (0x1u << (bits[1] - 8))) << ");\n";
1191 source << "highp float cb = (b * float(" << ((0x1u << bits[2]) - 1u) << ") - float(" << (128u * (0x1u << (bits[2] - 8))) << ")) / float(" << (224u * (0x1u << (bits[2] - 8))) << ");\n";
1192 break;
1193
1194 default:
1195 DE_FATAL("Unknown color range");
1196 }
1197
1198 source << "highp vec4 color;\n";
1199
1200 switch (config.colorModel)
1201 {
1202 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY:
1203 source << "color = vec4(r, g, b, a);\n";
1204 break;
1205
1206 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY:
1207 source << "color = vec4(cr, y, cb, a);\n";
1208 break;
1209
1210 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601:
1211 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";
1212 break;
1213
1214 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709:
1215 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";
1216 break;
1217
1218 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020:
1219 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";
1220 break;
1221
1222 default:
1223 DE_FATAL("Unknown color model");
1224 };
1225
1226 source << "o_color = color;\n";
1227
1228 spec.source = source.str();
1229 generateSources(config.shaderType, spec, dst);
1230 #endif
1231 }
1232
1233 struct RangeNamePair
1234 {
1235 const char* name;
1236 vk::VkSamplerYcbcrRange value;
1237 };
1238
1239
1240 struct ChromaLocationNamePair
1241 {
1242 const char* name;
1243 vk::VkChromaLocation value;
1244 };
1245
1246 // Alternate between swizzle_identity and their equivalents. Both should work.
getIdentitySwizzle(void)1247 const vk::VkComponentMapping& getIdentitySwizzle (void)
1248 {
1249 static bool alternate = false;
1250 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 };
1251 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 };
1252
1253 const vk::VkComponentMapping& mapping = (alternate ? mappingB : mappingA);
1254 alternate = (!alternate);
1255 return mapping;
1256 }
1257
1258 struct YCbCrConversionTestBuilder
1259 {
1260 const std::vector<vk::VkFormat> noChromaSubsampledFormats =
1261 {
1262 vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1263 vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1264 vk::VK_FORMAT_R5G6B5_UNORM_PACK16,
1265 vk::VK_FORMAT_B5G6R5_UNORM_PACK16,
1266 vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1267 vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1268 vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1269 vk::VK_FORMAT_R8G8B8_UNORM,
1270 vk::VK_FORMAT_B8G8R8_UNORM,
1271 vk::VK_FORMAT_R8G8B8A8_UNORM,
1272 vk::VK_FORMAT_B8G8R8A8_UNORM,
1273 vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1274 vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1275 vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1276 vk::VK_FORMAT_R16G16B16_UNORM,
1277 vk::VK_FORMAT_R16G16B16A16_UNORM,
1278 vk::VK_FORMAT_R10X6_UNORM_PACK16,
1279 vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
1280 vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
1281 vk::VK_FORMAT_R12X4_UNORM_PACK16,
1282 vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
1283 vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
1284 vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
1285 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
1286 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
1287 vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
1288 vk::VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT,
1289 vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT,
1290 vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT,
1291 vk::VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT,
1292 };
1293 const std::vector<vk::VkFormat> xChromaSubsampledFormats =
1294 {
1295 vk::VK_FORMAT_G8B8G8R8_422_UNORM,
1296 vk::VK_FORMAT_B8G8R8G8_422_UNORM,
1297 vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
1298 vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
1299
1300 vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
1301 vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
1302 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
1303 vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
1304 vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
1305 vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
1306 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
1307 vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
1308 vk::VK_FORMAT_G16B16G16R16_422_UNORM,
1309 vk::VK_FORMAT_B16G16R16G16_422_UNORM,
1310 vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
1311 vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
1312 };
1313 const std::vector<vk::VkFormat> xyChromaSubsampledFormats =
1314 {
1315 vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
1316 vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
1317 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
1318 vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
1319 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
1320 vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
1321 vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
1322 vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
1323 };
1324 struct ColorModelStruct
1325 {
1326 const char* const name;
1327 const vk::VkSamplerYcbcrModelConversion value;
1328 };
1329 const std::vector<ColorModelStruct> colorModels =
1330 {
1331 { "rgb_identity", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY },
1332 { "ycbcr_identity", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY },
1333 { "ycbcr_709", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 },
1334 { "ycbcr_601", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 },
1335 { "ycbcr_2020", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 }
1336 };
1337 const std::vector<RangeNamePair> colorRanges =
1338 {
1339 { "itu_full", vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL },
1340 { "itu_narrow", vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW }
1341 };
1342 const std::vector<ChromaLocationNamePair> chromaLocations =
1343 {
1344 { "cosited", vk::VK_CHROMA_LOCATION_COSITED_EVEN },
1345 { "midpoint", vk::VK_CHROMA_LOCATION_MIDPOINT }
1346 };
1347 struct TextureFilterStruct
1348 {
1349 const char* const name;
1350 vk::VkFilter value;
1351 };
1352 const std::vector<TextureFilterStruct> textureFilters =
1353 {
1354 { "linear", vk::VK_FILTER_LINEAR },
1355 { "nearest", vk::VK_FILTER_NEAREST }
1356 };
1357 // Used by the chroma reconstruction tests
1358 const vk::VkSamplerYcbcrModelConversion defaultColorModel = vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
1359 const vk::VkSamplerYcbcrRange defaultColorRange = vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
1360 const vk::VkComponentMapping swappedChromaSwizzle =
1361 {
1362 vk::VK_COMPONENT_SWIZZLE_B,
1363 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
1364 vk::VK_COMPONENT_SWIZZLE_R,
1365 vk::VK_COMPONENT_SWIZZLE_IDENTITY
1366 };
1367 const std::vector<glu::ShaderType> shaderTypes =
1368 {
1369 glu::SHADERTYPE_VERTEX,
1370 glu::SHADERTYPE_FRAGMENT,
1371 glu::SHADERTYPE_COMPUTE
1372 };
1373 struct ImageTilingStruct
1374 {
1375 const char* name;
1376 vk::VkImageTiling value;
1377 };
1378 const std::vector<ImageTilingStruct> imageTilings =
1379 {
1380 { "tiling_linear", vk::VK_IMAGE_TILING_LINEAR },
1381 { "tiling_optimal", vk::VK_IMAGE_TILING_OPTIMAL }
1382 };
1383 struct SamplerBindingStruct
1384 {
1385 const char* name;
1386 deUint32 value;
1387 };
1388 const std::vector<SamplerBindingStruct> samplerBindings =
1389 {
1390 { "binding_0", 0 },
1391 { "binding_7", 7 },
1392 { "binding_15", 15 },
1393 { "binding_31", 31 }
1394 };
1395
buildTestsvkt::ycbcr::__anon891997430111::YCbCrConversionTestBuilder1396 void buildTests(tcu::TestCaseGroup* testGroup)
1397 {
1398 tcu::TestContext& testCtx(testGroup->getTestContext());
1399 de::Random rng(1978765638u);
1400
1401 // Test formats without chroma reconstruction
1402 for (size_t formatNdx = 0; formatNdx < noChromaSubsampledFormats.size(); formatNdx++)
1403 {
1404 const vk::VkFormat format(noChromaSubsampledFormats[formatNdx]);
1405 const std::string formatName(de::toLower(std::string(getFormatName(format)).substr(10)));
1406 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName.c_str()));
1407 const UVec2 srcSize(isXChromaSubsampled(format) ? 12 : 7,
1408 isYChromaSubsampled(format) ? 8 : 13);
1409 const UVec2 dstSize(srcSize.x() + srcSize.x() / 2,
1410 srcSize.y() + srcSize.y() / 2);
1411
1412 for (size_t modelNdx = 0; modelNdx < colorModels.size(); modelNdx++)
1413 {
1414 const char* const colorModelName(colorModels[modelNdx].name);
1415 const vk::VkSamplerYcbcrModelConversion colorModel(colorModels[modelNdx].value);
1416
1417 if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY && getYCbCrFormatChannelCount(format) < 3)
1418 continue;
1419
1420 de::MovePtr<tcu::TestCaseGroup> colorModelGroup(new tcu::TestCaseGroup(testCtx, colorModelName));
1421
1422 if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
1423 {
1424 for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1425 {
1426 const char* const textureFilterName(textureFilters[textureFilterNdx].name);
1427 const vk::VkFilter textureFilter(textureFilters[textureFilterNdx].value);
1428
1429 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1430 {
1431 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1432 const char* const tilingName(imageTilings[tilingNdx].name);
1433 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1434 const vk::VkSamplerYcbcrRange colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
1435 const vk::VkChromaLocation chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1436
1437 for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1438 {
1439 const deUint32 samplerBinding(samplerBindings[bindingNdx].value);
1440 string samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1441 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1442 textureFilter, chromaLocation, chromaLocation, false, false,
1443 colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1444
1445 addFunctionCaseWithPrograms(colorModelGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, checkSupport, createTestShaders, textureConversionTest, config);
1446 }
1447 }
1448 }
1449 }
1450 else
1451 {
1452 for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); rangeNdx++)
1453 {
1454 const char* const colorRangeName(colorRanges[rangeNdx].name);
1455 const vk::VkSamplerYcbcrRange colorRange(colorRanges[rangeNdx].value);
1456
1457 // Narrow range doesn't really work with formats that have less than 8 bits
1458 if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW)
1459 {
1460 const UVec4 bitDepth(getYCbCrBitDepth(format));
1461
1462 if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
1463 continue;
1464 }
1465
1466 de::MovePtr<tcu::TestCaseGroup> colorRangeGroup(new tcu::TestCaseGroup(testCtx, colorRangeName));
1467
1468 for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1469 {
1470 const char* const textureFilterName(textureFilters[textureFilterNdx].name);
1471 const vk::VkFilter textureFilter(textureFilters[textureFilterNdx].value);
1472
1473 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1474 {
1475 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1476 const char* const tilingName(imageTilings[tilingNdx].name);
1477 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(shaderTypes.begin(), shaderTypes.end()));
1478 const vk::VkChromaLocation chromaLocation(rng.choose<ChromaLocationNamePair>(chromaLocations.begin(), chromaLocations.end()).value);
1479 for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++) {
1480 const deUint32 samplerBinding(samplerBindings[bindingNdx].value);
1481 string samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1482 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1483 textureFilter, chromaLocation, chromaLocation, false, false,
1484 colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1485
1486 addFunctionCaseWithPrograms(colorRangeGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, checkSupport, createTestShaders, textureConversionTest, config);
1487 }
1488 }
1489 }
1490
1491 colorModelGroup->addChild(colorRangeGroup.release());
1492 }
1493 }
1494
1495 formatGroup->addChild(colorModelGroup.release());
1496 }
1497
1498 // Color conversion tests for array of samplers ( noChromaSubsampledFormats )
1499 if (getYCbCrFormatChannelCount(format) >= 3)
1500 buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);
1501
1502 testGroup->addChild(formatGroup.release());
1503 }
1504
1505 // Test formats with x chroma reconstruction
1506 for (size_t formatNdx = 0; formatNdx < xChromaSubsampledFormats.size(); formatNdx++)
1507 {
1508 const vk::VkFormat format(xChromaSubsampledFormats[formatNdx]);
1509 const std::string formatName(de::toLower(std::string(getFormatName(format)).substr(10)));
1510 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName.c_str()));
1511 const UVec2 srcSize(isXChromaSubsampled(format) ? 12 : 7,
1512 isYChromaSubsampled(format) ? 8 : 13);
1513 const UVec2 dstSize(srcSize.x() + srcSize.x() / 2,
1514 srcSize.y() + srcSize.y() / 2);
1515
1516 // Color conversion tests
1517 {
1518 de::MovePtr<tcu::TestCaseGroup> conversionGroup(new tcu::TestCaseGroup(testCtx, "color_conversion"));
1519
1520 for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
1521 {
1522 const char* const xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
1523 const vk::VkChromaLocation xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
1524
1525 for (size_t modelNdx = 0; modelNdx < colorModels.size(); modelNdx++)
1526 {
1527 const char* const colorModelName(colorModels[modelNdx].name);
1528 const vk::VkSamplerYcbcrModelConversion colorModel(colorModels[modelNdx].value);
1529
1530 if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY && getYCbCrFormatChannelCount(format) < 3)
1531 continue;
1532
1533
1534 if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
1535 {
1536 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1537 {
1538 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1539 const char* const tilingName(imageTilings[tilingNdx].name);
1540 const vk::VkSamplerYcbcrRange colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
1541 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1542 const vk::VkChromaLocation yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1543 for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1544 {
1545 const deUint32 samplerBinding(samplerBindings[bindingNdx].value);
1546 string samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1547 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,
1548 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, false, false,
1549 colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1550
1551 addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + tilingName + "_" + xChromaOffsetName + samplerBindingName, checkSupport, createTestShaders, textureConversionTest, config);
1552 }
1553 }
1554 }
1555 else
1556 {
1557 for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); rangeNdx++)
1558 {
1559 const char* const colorRangeName(colorRanges[rangeNdx].name);
1560 const vk::VkSamplerYcbcrRange colorRange(colorRanges[rangeNdx].value);
1561
1562 // Narrow range doesn't really work with formats that have less than 8 bits
1563 if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW)
1564 {
1565 const UVec4 bitDepth(getYCbCrBitDepth(format));
1566
1567 if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
1568 continue;
1569 }
1570
1571 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1572 {
1573 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1574 const char* const tilingName(imageTilings[tilingNdx].name);
1575 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1576 const vk::VkChromaLocation yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1577 for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1578 {
1579 const deUint32 samplerBinding(samplerBindings[bindingNdx].value);
1580 string samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1581 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,
1582 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, false, false,
1583 colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1584
1585 addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + colorRangeName + "_" + tilingName + "_" + xChromaOffsetName + samplerBindingName, checkSupport, createTestShaders, textureConversionTest, config);
1586 }
1587 }
1588 }
1589 }
1590 }
1591 }
1592
1593 formatGroup->addChild(conversionGroup.release());
1594 }
1595
1596 // Color conversion tests for array of samplers ( xChromaSubsampledFormats )
1597 if (getYCbCrFormatChannelCount(format) >= 3)
1598 buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);
1599
1600 // Chroma reconstruction tests
1601 {
1602 de::MovePtr<tcu::TestCaseGroup> reconstrucGroup(new tcu::TestCaseGroup(testCtx, "chroma_reconstruction"));
1603
1604 for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1605 {
1606 const char* const textureFilterName(textureFilters[textureFilterNdx].name);
1607 const vk::VkFilter textureFilter(textureFilters[textureFilterNdx].value);
1608 de::MovePtr<tcu::TestCaseGroup> textureFilterGroup(new tcu::TestCaseGroup(testCtx, textureFilterName));
1609
1610 for (size_t explicitReconstructionNdx = 0; explicitReconstructionNdx < 2; explicitReconstructionNdx++)
1611 {
1612 const bool explicitReconstruction(explicitReconstructionNdx == 1);
1613
1614 for (size_t disjointNdx = 0; disjointNdx < 2; disjointNdx++)
1615 {
1616 const bool disjoint(disjointNdx == 1);
1617
1618 for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
1619 {
1620 const vk::VkChromaLocation xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
1621 const char* const xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
1622
1623 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1624 {
1625 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1626 const char* const tilingName(imageTilings[tilingNdx].name);
1627
1628 {
1629 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1630 const vk::VkChromaLocation yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1631 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1632 vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1633 defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1634
1635 addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), checkSupport, createTestShaders, textureConversionTest, config);
1636 }
1637
1638 {
1639 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1640 const vk::VkChromaLocation yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1641 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1642 vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1643 defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1644
1645 addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", checkSupport, createTestShaders, textureConversionTest, config);
1646 }
1647
1648 if (!explicitReconstruction)
1649 {
1650 {
1651 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1652 const vk::VkChromaLocation yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1653 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1654 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1655 defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1656
1657 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), checkSupport, createTestShaders, textureConversionTest, config);
1658 }
1659
1660 {
1661 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1662 const vk::VkChromaLocation yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1663 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1664 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1665 defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1666
1667 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", checkSupport, createTestShaders, textureConversionTest, config);
1668 }
1669 }
1670 }
1671 }
1672
1673 if (explicitReconstruction)
1674 {
1675 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1676 {
1677 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1678 const char* const tilingName(imageTilings[tilingNdx].name);
1679 {
1680 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1681 const vk::VkChromaLocation chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1682 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1683 vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
1684 defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1685
1686 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : ""), checkSupport, createTestShaders, textureConversionTest, config);
1687 }
1688
1689 {
1690 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1691 const vk::VkChromaLocation chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1692 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1693 vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
1694 defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1695
1696 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", checkSupport, createTestShaders, textureConversionTest, config);
1697 }
1698 }
1699 }
1700 }
1701 }
1702
1703 reconstrucGroup->addChild(textureFilterGroup.release());
1704 }
1705
1706 formatGroup->addChild(reconstrucGroup.release());
1707 }
1708
1709 testGroup->addChild(formatGroup.release());
1710 }
1711
1712 // Test formats with xy chroma reconstruction
1713 for (size_t formatNdx = 0; formatNdx < xyChromaSubsampledFormats.size(); formatNdx++)
1714 {
1715 const vk::VkFormat format(xyChromaSubsampledFormats[formatNdx]);
1716 const std::string formatName(de::toLower(std::string(getFormatName(format)).substr(10)));
1717 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName.c_str()));
1718 const UVec2 srcSize(isXChromaSubsampled(format) ? 12 : 7,
1719 isYChromaSubsampled(format) ? 8 : 13);
1720 const UVec2 dstSize(srcSize.x() + srcSize.x() / 2,
1721 srcSize.y() + srcSize.y() / 2);
1722
1723 // Color conversion tests
1724 {
1725 de::MovePtr<tcu::TestCaseGroup> conversionGroup(new tcu::TestCaseGroup(testCtx, "color_conversion"));
1726
1727 for (size_t chromaOffsetNdx = 0; chromaOffsetNdx < chromaLocations.size(); chromaOffsetNdx++)
1728 {
1729 const char* const chromaOffsetName(chromaLocations[chromaOffsetNdx].name);
1730 const vk::VkChromaLocation chromaOffset(chromaLocations[chromaOffsetNdx].value);
1731
1732 for (size_t modelNdx = 0; modelNdx < colorModels.size(); modelNdx++)
1733 {
1734 const char* const colorModelName(colorModels[modelNdx].name);
1735 const vk::VkSamplerYcbcrModelConversion colorModel(colorModels[modelNdx].value);
1736
1737 if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY && getYCbCrFormatChannelCount(format) < 3)
1738 continue;
1739
1740 if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
1741 {
1742 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1743 {
1744 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1745 const char* const tilingName(imageTilings[tilingNdx].name);
1746 const vk::VkSamplerYcbcrRange colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
1747 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1748 for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1749 {
1750 const deUint32 samplerBinding(samplerBindings[bindingNdx].value);
1751 string samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1752 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,
1753 vk::VK_FILTER_NEAREST, chromaOffset, chromaOffset, false, false,
1754 colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1755
1756 addFunctionCaseWithPrograms(conversionGroup.get(), std::string(colorModelName) + "_" + tilingName + "_" + chromaOffsetName + samplerBindingName, checkSupport, createTestShaders, textureConversionTest, config);
1757 }
1758 }
1759 }
1760 else
1761 {
1762 for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); rangeNdx++)
1763 {
1764 const char* const colorRangeName(colorRanges[rangeNdx].name);
1765 const vk::VkSamplerYcbcrRange colorRange(colorRanges[rangeNdx].value);
1766
1767 // Narrow range doesn't really work with formats that have less than 8 bits
1768 if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW)
1769 {
1770 const UVec4 bitDepth(getYCbCrBitDepth(format));
1771
1772 if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
1773 continue;
1774 }
1775
1776 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1777 {
1778 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1779 const char* const tilingName(imageTilings[tilingNdx].name);
1780 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1781 for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1782 {
1783 const deUint32 samplerBinding(samplerBindings[bindingNdx].value);
1784 string samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1785 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,
1786 vk::VK_FILTER_NEAREST, chromaOffset, chromaOffset, false, false,
1787 colorRange, colorModel, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1788
1789 addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + colorRangeName + "_" + tilingName + "_" + chromaOffsetName + samplerBindingName, checkSupport, createTestShaders, textureConversionTest, config);
1790 }
1791 }
1792 }
1793 }
1794 }
1795 }
1796
1797 formatGroup->addChild(conversionGroup.release());
1798 }
1799
1800 // Color conversion tests for array of samplers ( xyChromaSubsampledFormats )
1801 if (getYCbCrFormatChannelCount(format) >= 3)
1802 buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);
1803
1804 // Chroma reconstruction tests
1805 {
1806 de::MovePtr<tcu::TestCaseGroup> reconstrucGroup(new tcu::TestCaseGroup(testCtx, "chroma_reconstruction"));
1807
1808 for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1809 {
1810 const char* const textureFilterName(textureFilters[textureFilterNdx].name);
1811 const vk::VkFilter textureFilter(textureFilters[textureFilterNdx].value);
1812 de::MovePtr<tcu::TestCaseGroup> textureFilterGroup(new tcu::TestCaseGroup(testCtx, textureFilterName));
1813
1814 for (size_t explicitReconstructionNdx = 0; explicitReconstructionNdx < 2; explicitReconstructionNdx++)
1815 {
1816 const bool explicitReconstruction(explicitReconstructionNdx == 1);
1817
1818 for (size_t disjointNdx = 0; disjointNdx < 2; disjointNdx++)
1819 {
1820 const bool disjoint(disjointNdx == 1);
1821
1822 for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
1823 for (size_t yChromaOffsetNdx = 0; yChromaOffsetNdx < chromaLocations.size(); yChromaOffsetNdx++)
1824 {
1825 const vk::VkChromaLocation xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
1826 const char* const xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
1827
1828 const vk::VkChromaLocation yChromaOffset(chromaLocations[yChromaOffsetNdx].value);
1829 const char* const yChromaOffsetName(chromaLocations[yChromaOffsetNdx].name);
1830
1831 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1832 {
1833 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1834 const char* const tilingName(imageTilings[tilingNdx].name);
1835 {
1836 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1837 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1838 vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1839 defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1840
1841 addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), checkSupport, createTestShaders, textureConversionTest, config);
1842 }
1843
1844 {
1845 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1846 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1847 vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1848 defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1849
1850 addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", checkSupport, createTestShaders, textureConversionTest, config);
1851 }
1852
1853 if (!explicitReconstruction)
1854 {
1855 {
1856 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1857 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1858 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1859 defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1860
1861 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), checkSupport, createTestShaders, textureConversionTest, config);
1862 }
1863
1864 {
1865 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1866 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1867 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
1868 defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1869
1870 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", checkSupport, createTestShaders, textureConversionTest, config);
1871 }
1872 }
1873 }
1874 }
1875
1876 if (explicitReconstruction)
1877 {
1878 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1879 {
1880 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1881 const char* const tilingName(imageTilings[tilingNdx].name);
1882 {
1883 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1884 const vk::VkChromaLocation chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1885 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1886 vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
1887 defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, dstSize, 0);
1888
1889 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : ""), checkSupport, createTestShaders, textureConversionTest, config);
1890 }
1891
1892 {
1893 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1894 const vk::VkChromaLocation chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
1895 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1896 vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
1897 defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);
1898
1899 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", checkSupport, createTestShaders, textureConversionTest, config);
1900 }
1901 }
1902 }
1903 }
1904 }
1905
1906 reconstrucGroup->addChild(textureFilterGroup.release());
1907 }
1908
1909 formatGroup->addChild(reconstrucGroup.release());
1910 }
1911
1912 testGroup->addChild(formatGroup.release());
1913 }
1914
1915 {
1916 const UVec2 imageSizes[] =
1917 {
1918 UVec2(16, 16),
1919 UVec2(20, 12)
1920 };
1921
1922 de::MovePtr<tcu::TestCaseGroup> oneToOneGroup(new tcu::TestCaseGroup(testCtx, "one_to_one"));
1923
1924 const vk::VkFormat format(vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM);
1925 const vk::VkFilter filter(vk::VK_FILTER_NEAREST);
1926
1927 for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(imageSizes); sizeNdx++)
1928 {
1929 const UVec2 srcSize(imageSizes[sizeNdx]);
1930
1931 for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
1932 {
1933 const vk::VkChromaLocation xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
1934 const char* const xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
1935
1936 for (size_t yChromaOffsetNdx = 0; yChromaOffsetNdx < chromaLocations.size(); yChromaOffsetNdx++)
1937 {
1938 const vk::VkChromaLocation yChromaOffset(chromaLocations[yChromaOffsetNdx].value);
1939 const char* const yChromaOffsetName(chromaLocations[yChromaOffsetNdx].name);
1940
1941 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1942 {
1943 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1944 const char* const tilingName(imageTilings[tilingNdx].name);
1945
1946 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
1947
1948 const TestConfig config(shaderType, format, tiling, filter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1949 filter, xChromaOffset, yChromaOffset, false, false,
1950 defaultColorRange, defaultColorModel, getIdentitySwizzle(), srcSize, srcSize, 0);
1951 std::ostringstream testName;
1952 testName << string("implicit_nearest_") << srcSize.x() << "x" << srcSize.y() << "_" << tilingName << "_" << xChromaOffsetName << "_" << yChromaOffsetName;
1953
1954 addFunctionCaseWithPrograms(oneToOneGroup.get(), testName.str(), checkSupport, createTestShaders, textureConversionTest, config);
1955 }
1956 }
1957 }
1958 }
1959
1960 testGroup->addChild(oneToOneGroup.release());
1961 }
1962 }
1963
buildArrayOfSamplersTestsvkt::ycbcr::__anon891997430111::YCbCrConversionTestBuilder1964 void buildArrayOfSamplersTests(const vk::VkFormat& format, const UVec2& srcSize, const UVec2& dstSize, de::MovePtr<tcu::TestCaseGroup>& formatGroup, tcu::TestContext& testCtx, de::Random& rng )
1965 {
1966 de::MovePtr<tcu::TestCaseGroup> samplerArrayGroup(new tcu::TestCaseGroup(testCtx, "sampler_array"));
1967
1968 for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
1969 {
1970 const char* const textureFilterName(textureFilters[textureFilterNdx].name);
1971 const vk::VkFilter textureFilter(textureFilters[textureFilterNdx].value);
1972
1973 for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
1974 {
1975 const vk::VkImageTiling tiling(imageTilings[tilingNdx].value);
1976 const char* const tilingName(imageTilings[tilingNdx].name);
1977 const glu::ShaderType shaderType(rng.choose<glu::ShaderType>(shaderTypes.begin(), shaderTypes.end()));
1978 const vk::VkSamplerYcbcrRange colorRange(vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL);
1979 const vk::VkChromaLocation chromaLocation(rng.choose<ChromaLocationNamePair>(chromaLocations.begin(), chromaLocations.end()).value);
1980
1981 for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
1982 {
1983 const deUint32 samplerBinding(samplerBindings[bindingNdx].value);
1984 string samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
1985 // colorModel==VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST means that we want to create an array of samplers instead of a single sampler
1986 const TestConfig config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1987 textureFilter, chromaLocation, chromaLocation, false, false,
1988 colorRange, vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, getIdentitySwizzle(), srcSize, dstSize, samplerBinding);
1989
1990 addFunctionCaseWithPrograms(samplerArrayGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, checkSupport, createTestShaders, textureConversionTest, config);
1991 }
1992 }
1993 }
1994 formatGroup->addChild(samplerArrayGroup.release());
1995 }
1996 };
1997
initTests(tcu::TestCaseGroup * testGroup)1998 void initTests(tcu::TestCaseGroup* testGroup)
1999 {
2000 YCbCrConversionTestBuilder testBuilder;
2001 testBuilder.buildTests(testGroup);
2002 }
2003
2004 } // anonymous
2005
createConversionTests(tcu::TestContext & testCtx)2006 tcu::TestCaseGroup* createConversionTests (tcu::TestContext& testCtx)
2007 {
2008 return createTestGroup(testCtx, "conversion", initTests);
2009 }
2010
2011 } // ycbcr
2012 } // vkt
2013