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