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